// -------------------------------------------------------------------------------------------------------------------- // // This file is part of the HandBrake source code - It may be used under the terms of the GNU General Public License. // // // The Chapters View Model // // -------------------------------------------------------------------------------------------------------------------- namespace HandBrakeWPF.ViewModels { using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using Caliburn.Micro; using HandBrake.ApplicationServices.Exceptions; using HandBrake.ApplicationServices.Model; using HandBrake.ApplicationServices.Model.Encoding; using HandBrake.ApplicationServices.Parsing; using HandBrakeWPF.Services.Interfaces; using HandBrakeWPF.ViewModels.Interfaces; using LumenWorks.Framework.IO.Csv; using Ookii.Dialogs.Wpf; /// /// The Chapters View Model /// public class ChaptersViewModel : ViewModelBase, IChaptersViewModel { /// /// The source chapters backing field /// private List sourceChaptersList; #region Constructors and Destructors /// /// Initializes a new instance of the class. /// /// /// The window manager. /// /// /// The user Setting Service. /// public ChaptersViewModel(IWindowManager windowManager, IUserSettingService userSettingService) { this.Task = new EncodeTask(); } #endregion #region Public Properties /// /// Gets or sets Task. /// public EncodeTask Task { get; set; } /// /// Gets or sets a value indicating whether chapter markers are enabled. /// public bool IncludeChapterMarkers { get { return this.Task.IncludeChapterMarkers; } set { this.Task.IncludeChapterMarkers = value; this.NotifyOfPropertyChange(() => this.IncludeChapterMarkers); } } #endregion #region Properties /// /// Gets or sets SourceChapterList. /// private ObservableCollection SourceChapterList { get; set; } #endregion #region Public Methods /// /// Export a CSV file. /// public void Export() { var saveFileDialog = new VistaSaveFileDialog { Filter = "Csv File|*.csv", DefaultExt = "csv", CheckPathExists = true }; saveFileDialog.ShowDialog(); if (!string.IsNullOrEmpty(saveFileDialog.FileName)) { this.ExportChaptersToCSV(saveFileDialog.FileName); } } /// /// Export the Chapter Markers to a CSV file /// /// /// The filename. /// /// /// Thrown when exporting fails. /// public void ExportChaptersToCSV(string filename) { try { string csv = string.Empty; foreach (ChapterMarker row in this.Task.ChapterNames) { csv += row.ChapterNumber.ToString(); csv += ","; csv += row.ChapterName.Replace(",", "\\,"); csv += Environment.NewLine; } var file = new StreamWriter(filename); file.Write(csv); file.Close(); file.Dispose(); } catch (Exception exc) { throw new GeneralApplicationException( "Unable to save Chapter Makrers file! ", "Chapter marker names will NOT be saved in your encode.", exc); } } /// /// Import a CSV file /// public void Import() { var dialog = new VistaOpenFileDialog { Filter = "CSV files (*.csv)|*.csv", CheckFileExists = true }; dialog.ShowDialog(); string filename = dialog.FileName; if (string.IsNullOrEmpty(filename)) { return; } IDictionary chapterMap = new Dictionary(); try { using (CsvReader csv = new CsvReader(new StreamReader(filename), false)) { while (csv.ReadNextRecord()) { if (csv.FieldCount == 2) { int chapter; int.TryParse(csv[0], out chapter); chapterMap[chapter] = csv[1]; } } } } catch (Exception) { // Do Nothing } // Now iterate over each chatper we have, and set it's name foreach (ChapterMarker item in this.Task.ChapterNames) { string chapterName; chapterMap.TryGetValue(item.ChapterNumber, out chapterName); item.ChapterName = chapterName; } } /// /// Setup this window for a new source /// /// /// The title. /// /// /// The preset. /// /// /// The task. /// public void SetSource(Title title, Preset preset, EncodeTask task) { this.Task = task; this.NotifyOfPropertyChange(() => this.Task); if (preset != null) { this.IncludeChapterMarkers = preset.Task.IncludeChapterMarkers; } this.sourceChaptersList = title.Chapters; this.SetSourceChapters(title.Chapters); } /// /// Setup this tab for the specified preset. /// /// /// The preset. /// /// /// The task. /// public void SetPreset(Preset preset, EncodeTask task) { this.Task = task; this.Task.IncludeChapterMarkers = preset.Task.IncludeChapterMarkers; this.NotifyOfPropertyChange(() => this.Task); } /// /// Update all the UI controls based on the encode task passed in. /// /// /// The task. /// public void UpdateTask(EncodeTask task) { this.Task = task; this.NotifyOfPropertyChange(() => this.Task.IncludeChapterMarkers); this.NotifyOfPropertyChange(() => this.Task.ChapterNames); } /// /// Reset Chapter Names /// public void Reset() { if (this.sourceChaptersList != null) { this.SetSourceChapters(this.sourceChaptersList); } } /// /// Set the Source Chapters List /// /// /// The source chapters. /// public void SetSourceChapters(IEnumerable sourceChapters) { // Cache the chapters in this screen this.SourceChapterList = new ObservableCollection(sourceChapters); this.Task.ChapterNames.Clear(); // Then Add new Chapter Markers. int counter = 1; foreach (Chapter chapter in this.SourceChapterList) { string chapterName = string.IsNullOrEmpty(chapter.ChapterName) ? string.Format("Chapter {0}", counter) : chapter.ChapterName; var marker = new ChapterMarker(chapter.ChapterNumber, chapterName, chapter.Duration); this.Task.ChapterNames.Add(marker); counter += 1; } } #endregion } }