summaryrefslogtreecommitdiffstats
path: root/win/CS/HandBrakeWPF/ViewModels
diff options
context:
space:
mode:
authorScott <[email protected]>2015-11-22 16:31:56 -0500
committerScott <[email protected]>2015-11-22 16:31:56 -0500
commitec2474b1e9024d053915f9d91cf2da84f1f4fafe (patch)
tree7c6c1821db290b5ffbb130bf7c6eac3443bf9fa8 /win/CS/HandBrakeWPF/ViewModels
parent48d1efa61ba96071ce12643f23e38a1945f2ae70 (diff)
parent9e107ee850e396044c4c80c3257a4623995b88b3 (diff)
Merge pull request #37 from sverrirs/chapters-csv-upd
Improving support for importing Chapter names via CSV file
Diffstat (limited to 'win/CS/HandBrakeWPF/ViewModels')
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs133
1 files changed, 76 insertions, 57 deletions
diff --git a/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs
index a76d24547..4815de20d 100644
--- a/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/ChaptersViewModel.cs
@@ -13,6 +13,8 @@ namespace HandBrakeWPF.ViewModels
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
+ using System.Text;
+ using System.Windows.Forms;
using Caliburn.Micro;
@@ -20,11 +22,10 @@ namespace HandBrakeWPF.ViewModels
using HandBrakeWPF.Services.Interfaces;
using HandBrakeWPF.Services.Presets.Model;
using HandBrakeWPF.Services.Scan.Model;
+ using HandBrakeWPF.Utilities.Output;
using HandBrakeWPF.ViewModels.Interfaces;
- using LumenWorks.Framework.IO.Csv;
-
- using Microsoft.Win32;
+ using Microsoft.VisualBasic.FileIO;
using ChapterMarker = HandBrakeWPF.Services.Encode.Model.Models.ChapterMarker;
using EncodeTask = HandBrakeWPF.Services.Encode.Model.EncodeTask;
@@ -94,49 +95,39 @@ namespace HandBrakeWPF.ViewModels
#region Public Methods
/// <summary>
- /// Export a CSV file.
- /// </summary>
- public void Export()
- {
- var saveFileDialog = new OpenFileDialog
- {
- Filter = "Csv File|*.csv",
- DefaultExt = "csv",
- CheckPathExists = true
- };
- bool? dialogResult = saveFileDialog.ShowDialog();
- if (dialogResult.HasValue && dialogResult.Value && !string.IsNullOrEmpty(saveFileDialog.FileName))
- {
- this.ExportChaptersToCSV(saveFileDialog.FileName);
- }
- }
-
- /// <summary>
/// Export the Chapter Markers to a CSV file
/// </summary>
- /// <param name="filename">
- /// The filename.
- /// </param>
/// <exception cref="GeneralApplicationException">
/// Thrown when exporting fails.
/// </exception>
- public void ExportChaptersToCSV(string filename)
+ public void Export()
{
- try
+ string fileName = null;
+ using (var saveFileDialog = new SaveFileDialog()
+ {
+ Filter = "Csv File|*.csv",
+ DefaultExt = "csv",
+ CheckPathExists = true,
+ OverwritePrompt = true
+ })
{
- string csv = string.Empty;
+ var dialogResult = saveFileDialog.ShowDialog();
+ fileName = saveFileDialog.FileName;
- foreach (ChapterMarker row in this.Task.ChapterNames)
+ // Exit early if the user cancelled or the filename is invalid
+ if (dialogResult != DialogResult.OK || string.IsNullOrWhiteSpace(fileName))
+ return;
+ }
+
+ try
+ {
+ using (var csv = new StreamWriter(fileName))
{
- csv += row.ChapterNumber.ToString();
- csv += ",";
- csv += row.ChapterName.Replace(",", "\\,");
- csv += Environment.NewLine;
+ foreach (ChapterMarker row in this.Task.ChapterNames)
+ {
+ csv.Write("{0},{1}{2}", row.ChapterNumber, CsvHelper.Escape(row.ChapterName), Environment.NewLine);
+ }
}
- var file = new StreamWriter(filename);
- file.Write(csv);
- file.Close();
- file.Dispose();
}
catch (Exception exc)
{
@@ -152,41 +143,69 @@ namespace HandBrakeWPF.ViewModels
/// </summary>
public void Import()
{
- var dialog = new OpenFileDialog { Filter = "CSV files (*.csv)|*.csv", CheckFileExists = true };
- bool? dialogResult = dialog.ShowDialog();
- string filename = dialog.FileName;
-
- if (!dialogResult.HasValue || !dialogResult.Value || string.IsNullOrEmpty(filename))
+ string filename = null;
+ using (var dialog = new OpenFileDialog() { Filter = "CSV files (*.csv)|*.csv", CheckFileExists = true })
{
- return;
+ var dialogResult = dialog.ShowDialog();
+ filename = dialog.FileName;
+
+ // Exit if the user didn't press the OK button or the file name is invalid
+ if (dialogResult != DialogResult.OK || string.IsNullOrWhiteSpace(filename))
+ return;
}
- IDictionary<int, string> chapterMap = new Dictionary<int, string>();
- try
+ var chapterMap = new Dictionary<int, string>();
+
+ using (TextFieldParser csv = new TextFieldParser(filename)
+ { CommentTokens = new[] { "#" }, // Comment lines
+ Delimiters = new[] { ",", "\t", ";", ":" }, // Support all of these common delimeter types
+ HasFieldsEnclosedInQuotes = true, // Assume that our data will be properly escaped
+ TextFieldType = FieldType.Delimited,
+ TrimWhiteSpace = true // Remove excess whitespace from ends of imported values
+ })
{
- using (CsvReader csv = new CsvReader(new StreamReader(filename), false))
+ while (!csv.EndOfData)
{
- while (csv.ReadNextRecord())
+ try
{
- if (csv.FieldCount == 2)
- {
- int chapter;
- int.TryParse(csv[0], out chapter);
- chapterMap[chapter] = csv[1];
- }
+ // Only read the first two columns, anything else will be ignored but will not raise an error
+ var row = csv.ReadFields();
+ if (row == null || row.Length < 2) // null condition happens if the file is somehow corrupt during reading
+ throw new MalformedLineException(Resources.ChaptersViewModel_UnableToImportChaptersLineDoesNotHaveAtLeastTwoColumns, csv.LineNumber);
+
+ int chapterNumber;
+ if (!int.TryParse(row[0], out chapterNumber))
+ throw new MalformedLineException(Resources.ChaptersViewModel_UnableToImportChaptersFirstColumnMustContainOnlyIntegerNumber, csv.LineNumber);
+
+ // Store the chapter name at the correct index
+ chapterMap[chapterNumber] = row[1]?.Trim();
+ }
+ catch (MalformedLineException mlex)
+ {
+ throw new GeneralApplicationException(
+ Resources.ChaptersViewModel_UnableToImportChaptersWarning,
+ string.Format(Resources.ChaptersViewModel_UnableToImportChaptersMalformedLineMsg, mlex.LineNumber),
+ mlex);
}
}
}
- catch (Exception)
- {
- // Do Nothing
- }
+
+ // Exit early if no chapter information was extracted
+ if (chapterMap.Count <= 0)
+ return;
// Now iterate over each chatper we have, and set it's name
foreach (ChapterMarker item in this.Task.ChapterNames)
{
string chapterName;
- item.ChapterName = chapterMap.TryGetValue(item.ChapterNumber, out chapterName) ? chapterName : string.Empty;
+
+ // If we don't have a chapter name for this chapter then
+ // fallback to the value that is already set for the chapter
+ if (!chapterMap.TryGetValue(item.ChapterNumber, out chapterName))
+ chapterName = item.ChapterName;
+
+ // Assign the chapter name unless the name is not set or only whitespace charaters
+ item.ChapterName = !string.IsNullOrWhiteSpace(chapterName) ? chapterName : string.Empty;
}
}