Click here to Skip to main content
15,885,278 members
Articles / Desktop Programming / WPF

Use LINQ to Create Music Playlists – Revisited

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
27 Apr 2009CPOL4 min read 23.8K   420   12  
A re-write of a previous article. Still using LINQ, but incorporating much more in this iteration 2 version.
using System;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Forms;
using System.Windows.Media;
using PlaylistCreatorFP;

namespace PlaylistCreatorUI
{
    /// <summary>
    /// Interaction logic for WindowMain.xaml
    /// </summary>
    public partial class WindowMain : WindowBase
    {
        const string DEFAULT_PLAYLIST_FILENAME = "!PlayList.m3u";
        const string DEFAULT_REMOVE_EXT = "m3u";
        const string DEFAULT_AUDIO_EXT = "mp3";

        private PCEngine _pcEngine;
        public PCEngine PcEngine
        {
            get
            {
                if (_pcEngine == null)
                {
                    _pcEngine = new PCEngine();
                    _pcEngine.SendMessage += new MessageEventHandler(_pcEngine_SendMessage);
                    _pcEngine.ErrorOccured += new PlaylistCreatorFP.ErrorEventHandler(_pcEngine_ErrorOccured);
                }
                return _pcEngine;
            }
        }

        DateTime _dtStart;
        DateTime _dtEnd;

        void _pcEngine_ErrorOccured(object sender, PlaylistCreatorErrorEventArgs e)
        {
            _bw.ReportProgress((int)MessageTypes.Error, e.ErrorMessage);
        }

        void _pcEngine_SendMessage(object sender, PlaylistCreatorMessageEventArgs e)
        {
            _bw.ReportProgress((int)MessageTypes.Message, e.MessageText);
        }

        private Popup _popValidationError;
        private BackgroundWorker _bw;

        private string _audioFilesPath;
        private string _removeFileExtension;
        private string _audioTypeExtensions;
        private string _audioPlaylistFilename;
        private bool _removePlaylists;

        public WindowMain()
        {
            InitializeComponent();
            tbAudioFilesPath.Focus();

            tbPlayListFilename.Text = DEFAULT_PLAYLIST_FILENAME;
            tbRemoveExt.Text = DEFAULT_REMOVE_EXT;
            tbAudioTypes.Text = DEFAULT_AUDIO_EXT;
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnProcess_Click(object sender, RoutedEventArgs e)
        {
            if (!ValidateInput())
                return;

            _dtStart = DateTime.Now;

            LockForm(false);

            InitBW();
            _bw.RunWorkerAsync();
        }

        private void btBrowseAudioFilePath_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            try
            {
                if (!string.IsNullOrEmpty(tbAudioFilesPath.Text.Trim()))
                {
                    fbd.SelectedPath = tbAudioFilesPath.Text.Trim();
                }
            }
            catch (Exception) { }
            if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                tbAudioFilesPath.Text = fbd.SelectedPath;
            }
        }
        private bool ValidateInput()
        {
            // Audio file path
            _audioFilesPath = tbAudioFilesPath.Text.Trim();
            string audioPathLabel = lbAudioFilesPath.Content.ToString().Replace(":", "");
            if (string.IsNullOrEmpty(_audioFilesPath))
            {
                PopValidationError(tbAudioFilesPath, string.Format("No {0} specified", audioPathLabel));
                tbAudioFilesPath.Focus();
                return false;
            }
            if (!Directory.Exists(_audioFilesPath))
            {
                PopValidationError(tbAudioFilesPath, string.Format("Specified {0} does exist", audioPathLabel));
                tbAudioFilesPath.Focus();
                return false;
            }

            // Playlist filename
            _audioPlaylistFilename = tbPlayListFilename.Text.Trim();
            string playListLabel = lbPlayListFilename.Content.ToString().Replace(":", "");
            if (string.IsNullOrEmpty(_audioPlaylistFilename))
            {
                PopValidationError(tbPlayListFilename, string.Format("{0} can't be empty", playListLabel));
                tbPlayListFilename.Text = DEFAULT_PLAYLIST_FILENAME;
                tbPlayListFilename.Focus();
                tbPlayListFilename.SelectAll();
                return false;
            }
            if (_audioPlaylistFilename.Split(System.IO.Path.GetInvalidFileNameChars()).Count() > 1)
            {
                PopValidationError(tbPlayListFilename, string.Format("{0} contains illegal characters", playListLabel));
                tbPlayListFilename.Focus();
                tbPlayListFilename.SelectAll();
                return false;
            }

            // Remove existing playlist extension
            _removeFileExtension = tbRemoveExt.Text.Trim();
            _removePlaylists = (bool)ckbxRemoveM3uFiles.IsChecked;
            if (_removePlaylists)
            {
                if (string.IsNullOrEmpty(_removeFileExtension))
                {
                    PopValidationError(tbRemoveExt, "No Remove Extention specified");
                    tbRemoveExt.Text = DEFAULT_REMOVE_EXT;
                    tbRemoveExt.SelectAll();
                    tbRemoveExt.Focus();
                    return false;
                }
                if (_removeFileExtension.Split(System.IO.Path.GetInvalidFileNameChars()).Count() > 1)
                {
                    PopValidationError(tbRemoveExt, "Remove Extention {0} contains illegal characters");
                    tbRemoveExt.Focus();
                    tbRemoveExt.SelectAll();
                    return false;
                }
            }

            // Audio types
            _audioTypeExtensions = tbAudioTypes.Text.Trim();
            if (string.IsNullOrEmpty(_audioTypeExtensions))
            {
                PopValidationError(tbAudioTypes,
                    string.Format("{0} can't be empty", lbAudioTypes.Content.ToString().Replace(":", "")));
                tbAudioTypes.Text = DEFAULT_AUDIO_EXT;
                tbAudioTypes.Focus();
                tbAudioTypes.SelectAll();
                return false;
            }
            else
            {
                foreach (string ext in _audioTypeExtensions.Split(new char[] { ',' }))
                {
                    if (string.IsNullOrEmpty(ext))
                    {
                        PopValidationError(tbAudioTypes,
                            string.Format("{0} contains empy elements", lbAudioTypes.Content.ToString().Replace(":", "")));
                        tbAudioTypes.Focus();
                        return false;
                    }
                    if (ext.Trim().Split(System.IO.Path.GetInvalidFileNameChars()).Count() > 1)
                    {
                        PopValidationError(tbAudioTypes,
                            string.Format("{0} contains illegal characters", ext.Trim()));
                        tbAudioTypes.Focus();
                        return false;
                    }
                }
            }

            return true;
        }
        private void PopValidationError(UIElement elem, string message)
        {
            if (_popValidationError == null)
            {
                _popValidationError = new Popup()
                {
                    PopupAnimation = PopupAnimation.Fade,
                    Placement = PlacementMode.Bottom,
                    VerticalOffset = 3,
                    StaysOpen = false
                };
            }

            TextBlock tb = new TextBlock()
            {
                Foreground = Brushes.Wheat,
                Background = Brushes.Red,
                Text = message,
                Padding = new Thickness(5)
            };

            _popValidationError.Child = tb;
            _popValidationError.PlacementTarget = elem;

            _popValidationError.IsOpen = true;
            elem.Focus();
        }
        private void LockForm(bool enable)
        {
            tbAudioFilesPath.IsEnabled
                = btBrowseAudioFilePath.IsEnabled
                = tbPlayListFilename.IsEnabled
                = tbAudioTypes.IsEnabled
                = ckbxRemoveM3uFiles.IsEnabled
                = tbRemoveExt.IsEnabled
                = btnProcess.IsEnabled
                = enable;
        }
        private void AddStatusMessage(MessageTypes mtype, string message)
        {
            ListBoxItem lbi = new ListBoxItem();
            switch (mtype)
            {
                case MessageTypes.Message:
                    lbi.Content = message;
                    break;

                case MessageTypes.Error:
                    TextBlock tb = new TextBlock()
                    {
                        Foreground = Brushes.White,
                        Background = Brushes.Red,
                        Text = message
                    };
                    lbi.Content = tb;
                    break;

                default:
                    break;
            }
            lstBxStatus.Items.Add(lbi);
            lstBxStatus.ScrollIntoView(lbi);
        }

        #region Background Worker

        private void InitBW()
        {
            if (_bw == null)
            {
                _bw = new BackgroundWorker()
                {
                    WorkerReportsProgress = true,
                    WorkerSupportsCancellation = true
                };
                _bw.DoWork += new DoWorkEventHandler(_bw_DoWork);
                _bw.ProgressChanged += new ProgressChangedEventHandler(_bw_ProgressChanged);
                _bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_bw_RunWorkerCompleted);
            }
        }
        private void _bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _dtEnd = DateTime.Now;
            TimeSpan ts = _dtEnd - _dtStart;
            AddStatusMessage(MessageTypes.Message,
                string.Format(
                    "Finished!  That took {0} minute{1} and {2} second{3}",
                    ts.Minutes,
                    ts.Minutes == 1 ? "" : "s",
                    ts.Seconds,
                    ts.Seconds == 1 ? "" : "s"
                    )
                );

            LockForm(true);
        }
        private void _bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            AddStatusMessage((MessageTypes)e.ProgressPercentage, e.UserState.ToString());
        }
        private void _bw_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                _bw.ReportProgress((int)MessageTypes.Message, "Searching for audio files...");
                PcEngine.SearchDisk(_audioFilesPath, _audioTypeExtensions, _removePlaylists, _removeFileExtension);

                _bw.ReportProgress((int)MessageTypes.Message, "Building playlists...");
                PcEngine.CreatePlayLists(_audioPlaylistFilename);
            }
            catch (Exception ex)
            {
                _bw.ReportProgress((int)MessageTypes.Error, ex.Message);
            }
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
Dave has been working in the software industry for a few years now. Having graduated with his BS in Computer Science & Engineering from the University of Toledo in 2002, Dave enjoys learning about new technologies and likes to apply new programming methods to solve age-old challenges. In his spare time he is addicted to movies (sci-fi, horror, anything good!) and spending time with family and friends. Dave also harbors a secret desire to make it big in the film/music industry—here’s lookin’ at you, kid! ;o)

Comments and Discussions