From 6cf7689069ff37a9ed7db4e1e05d66725a3df520 Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Mon, 18 May 2020 19:40:50 -0700 Subject: [PATCH 1/9] Massive overhaul to add support for command line. Progress tracking can now route through an interface (console and progress window are the available implementations). Command line can drive exports. Still plenty to do but it should be functional for rough testing. --- .../CommandLineEnumerations.cs} | 13 +- .../CommandLine/CommandLineExporterBase.cs | 190 +++++++++++++++ .../Card/CommandLine/CommandLineProcessor.cs | 151 ++++++++++++ CardMaker/Card/CommandLine/ConsoleLogger.cs | 45 ++++ .../CommandLine/ImageCommandLineExporter.cs | 65 ++++++ .../CommandLine/PDFCommandLineExporter.cs | 62 +++++ CardMaker/Card/Deck.cs | 120 +++++----- CardMaker/Card/Export/CardExportBase.cs | 33 ++- CardMaker/Card/Export/CompilerCardExporter.cs | 23 +- .../Card/Export/FileCardClipboardExporter.cs | 25 +- CardMaker/Card/Export/FileCardExporter.cs | 91 +++++--- .../Card/Export/FileCardExporterFactory.cs | 44 ++-- .../Card/Export/FileCardSingleExporter.cs | 30 +-- CardMaker/Card/Export/PdfSharpExporter.cs | 73 ++++-- CardMaker/Card/Import/CSVReferenceReader.cs | 13 +- CardMaker/Card/Import/ExcelReferenceReader.cs | 12 +- .../Card/Import/GoogleReferenceReader.cs | 22 +- CardMaker/Card/Import/ReferenceReader.cs | 17 +- .../Card/Import/ReferenceReaderFactory.cs | 45 ++-- .../Card/Translation/InceptTranslator.cs | 2 +- CardMaker/CardMaker.csproj | 16 +- CardMaker/CardMakerBuild.cs | 2 +- CardMaker/CardMaker_Mono.csproj | 28 ++- CardMaker/Data/CardMakerConstants.cs | 7 + CardMaker/Data/CardMakerInstance.cs | 7 + .../Events/Managers/GoogleAuthManager.cs | 1 - CardMaker/Events/Managers/LayoutManager.cs | 2 +- CardMaker/Forms/CardMakerMDI.cs | 50 ++-- CardMaker/Forms/MDIIssues.cs | 13 +- CardMaker/Forms/MDILogger.cs | 4 +- CardMaker/Forms/ProjectManagerUI.cs | 13 +- CardMaker/Program.cs | 39 +++- .../Google/Sheets/GoogleSpreadsheetBrowser.cs | 72 +++--- CardMaker/Support/IO/Logger.cs | 8 +- .../Progress/ConsoleProgressReporter.cs | 202 ++++++++++++++++ .../ConsoleProgressReporterFactory.cs | 42 ++++ .../Support/Progress/IProgressReporter.cs | 109 +++++++++ .../Progress/ProgressReporterFactory.cs | 50 ++++ .../Support/Progress/ProgressReporterProxy.cs | 63 +++++ .../WaitDialogLineProgressReporterFactory.cs | 53 +++++ CardMaker/Support/UI/WaitDialog.cs | 48 +++- CardMaker/Support/Util/CommandLineParser.cs | 217 ++++++++++++++++++ .../UnitTest/DeckObject/ElementOverride.cs | 5 + .../DeckObject/InceptStringTranslation.cs | 5 + .../DeckObject/JavaScriptStringTranslation.cs | 5 + .../Test/UnitTest/DeckObject/TestDeck.cs | 6 + CardMaker/bin/Release/Card_Maker.odt | Bin 47568 -> 49790 bytes 47 files changed, 1808 insertions(+), 335 deletions(-) rename CardMaker/Card/{Export/ICardExporter.cs => CommandLine/CommandLineEnumerations.cs} (84%) create mode 100644 CardMaker/Card/CommandLine/CommandLineExporterBase.cs create mode 100644 CardMaker/Card/CommandLine/CommandLineProcessor.cs create mode 100644 CardMaker/Card/CommandLine/ConsoleLogger.cs create mode 100644 CardMaker/Card/CommandLine/ImageCommandLineExporter.cs create mode 100644 CardMaker/Card/CommandLine/PDFCommandLineExporter.cs create mode 100644 CardMaker/Support/Progress/ConsoleProgressReporter.cs create mode 100644 CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs create mode 100644 CardMaker/Support/Progress/IProgressReporter.cs create mode 100644 CardMaker/Support/Progress/ProgressReporterFactory.cs create mode 100644 CardMaker/Support/Progress/ProgressReporterProxy.cs create mode 100644 CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs create mode 100644 CardMaker/Support/Util/CommandLineParser.cs diff --git a/CardMaker/Card/Export/ICardExporter.cs b/CardMaker/Card/CommandLine/CommandLineEnumerations.cs similarity index 84% rename from CardMaker/Card/Export/ICardExporter.cs rename to CardMaker/Card/CommandLine/CommandLineEnumerations.cs index 6d86caa9..febb8dc7 100644 --- a/CardMaker/Card/Export/ICardExporter.cs +++ b/CardMaker/Card/CommandLine/CommandLineEnumerations.cs @@ -22,10 +22,17 @@ // SOFTWARE. //////////////////////////////////////////////////////////////////////////////// -namespace CardMaker.Card.Export +namespace CardMaker.Card.CommandLine { - public interface ICardExporter + public enum CommandLineArg { - void ExportThread(); + CardIndices, + ExportFormat, + ExportPath, + GoogleCredential, + LayoutNames, + LayoutIndices, + PageOrientation, + ProjectPath } } diff --git a/CardMaker/Card/CommandLine/CommandLineExporterBase.cs b/CardMaker/Card/CommandLine/CommandLineExporterBase.cs new file mode 100644 index 00000000..d8e6a72c --- /dev/null +++ b/CardMaker/Card/CommandLine/CommandLineExporterBase.cs @@ -0,0 +1,190 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Drawing.Imaging; +using System.Linq; +using CardMaker.Card.Export; +using CardMaker.Data; +using CardMaker.Events.Managers; +using PdfSharp; +using Support.Util; + +namespace CardMaker.Card.CommandLine +{ + public abstract class CommandLineExporterBase + { + public CommandLineParser CommandLineParser { get; set; } + + public abstract bool Validate(); + public abstract bool Export(); + + /// + /// Gets the layout indices + /// + /// The layout indices specified on the command line (defaults to all) + protected int[] GetLayoutIndices() + { + var arrayLayoutNames = CommandLineParser.GetStringArgs(CommandLineArg.LayoutNames); + // get the indices of the layouts by name + if (null != arrayLayoutNames) + { + var idx = 0; + var dictionaryLayoutNameToLayout = + ProjectManager.Instance.LoadedProject.Layout.ToDictionary(layout => layout.Name.ToUpper(), layout => idx++); +#warning Might be nice to alert/log if they specify a bad layout name + return arrayLayoutNames + .Where(sLayoutName => dictionaryLayoutNameToLayout.ContainsKey(sLayoutName.ToUpper())) + .Select(sLayoutName => dictionaryLayoutNameToLayout[sLayoutName.ToUpper()]).ToArray(); + } + + // default to all layouts + return Enumerable.Range(0, ProjectManager.Instance.LoadedProject.Layout.Length).ToArray(); + } + + /// + /// Gets the card indices specified on the command line + /// + /// The indices specified on the command line (defaults to all) + public int[] GetCardIndices() + { + var sCardIndices = CommandLineParser.GetStringArg(CommandLineArg.CardIndices); + var listCardIndices = new List(); + if (null != sCardIndices) + { + var arrayRanges = sCardIndices.Split(new [] {','}, StringSplitOptions.RemoveEmptyEntries); + foreach (var sRange in arrayRanges) + { + var arrayEntries = sRange.Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries); + int nStart; + int nEnd; + // NOTE: all of the inputs are cardId (1 based) -- converted to 0 based internally + switch (arrayEntries.Length) + { + case 1: + if (int.TryParse(arrayEntries[0], out nStart)) + { + listCardIndices.Add(nStart - 1); + } + else + { +#warning should error + } + break; + case 2: + if (int.TryParse(arrayEntries[0], out nStart) && int.TryParse(arrayEntries[1], out nEnd)) + { + listCardIndices.AddRange(Enumerable.Range(nStart - 1, (nEnd - nStart) + 1)); + } + else + { +#warning should error + } + break; + default: +#warning should error + // error + break; + } + } + + return listCardIndices.ToArray(); + } + + return null; + } + + /// + /// Loads the Google credentials from the command line + /// + public void ConfigureGoogleCredential() + { + var sGoogleCredential = CommandLineParser.GetStringArg(CommandLineArg.GoogleCredential); + if (null != sGoogleCredential) + { + CardMakerInstance.GoogleAccessToken = sGoogleCredential; + CardMakerInstance.GoogleCredentialsInvalid = false; + } + } + + /// + /// Gets the export path (and deals with some windows quote hacks) + /// + /// Flag indicating if the desired path is a folder + /// The path specified or null. + protected string GetExportPath(bool bFolder) + { + var sRawPath = CommandLineParser.GetStringArg(CommandLineArg.ExportPath); + if (!bFolder) + { + return sRawPath; + } + if (-1 != sRawPath.IndexOf("/") && !sRawPath.EndsWith("/")) + { + return sRawPath + "/"; + } + if (-1 != sRawPath.IndexOf("\\")) + { + // this is a garbage fix thanks to the bizarre world of quotes + if (sRawPath.EndsWith("\"")) + { + sRawPath = sRawPath.Substring(0, sRawPath.Length - 1); + } + if (!sRawPath.EndsWith("\\")) + { + return sRawPath + "\\"; + } + } + + return sRawPath; + } + + /// + /// Gets the page orientation from the command line (PDF specific) + /// + /// The page orientation (default: portrait) + protected PageOrientation GetPageOrientation() + { + PageOrientation ePageOrientation; + return PageOrientation.TryParse(CommandLineParser.GetStringArg(CommandLineArg.PageOrientation), true, + out ePageOrientation) + ? ePageOrientation + : PageOrientation.Portrait; + } + + /// + /// Gets the image format from the command line + /// + /// The image format (default: png) + protected ImageFormat GetImageFormat() + { + var sExportFormat = CommandLineParser.GetStringArg(CommandLineArg.ExportFormat); + ImageFormat eImageFormat; + return FileCardExporterFactory.AllowedImageFormatDictionary.TryGetValue(sExportFormat.ToUpper(), out eImageFormat) + ? eImageFormat + : ImageFormat.Png; + } + } +} diff --git a/CardMaker/Card/CommandLine/CommandLineProcessor.cs b/CardMaker/Card/CommandLine/CommandLineProcessor.cs new file mode 100644 index 00000000..82fdb20b --- /dev/null +++ b/CardMaker/Card/CommandLine/CommandLineProcessor.cs @@ -0,0 +1,151 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.IO; +using CardMaker.Card.Export; +using CardMaker.Data; +using CardMaker.Events.Managers; +using Support.IO; +using Support.Progress; +using Support.UI; +using Support.Util; + +namespace CardMaker.Card.CommandLine +{ + public class CommandLineProcessor + { + private static readonly Dictionary dictionaryExporterType = new Dictionary() + { + { "PDF", typeof(PDFCommandLineExporter) }, + }; + + private CommandLineParser m_zCommandLineParser; + + static CommandLineProcessor() + { + foreach (var sImageFormatName in FileCardExporterFactory.AllowedImageFormatNames) + { + dictionaryExporterType.Add(sImageFormatName.ToUpper(), typeof(ImageCommandLineExporter)); + } + } + + /// + /// + /// + /// The parser to use within this processor + public CommandLineProcessor(CommandLineParser zCommandLineParser) + { + m_zCommandLineParser = zCommandLineParser; + } + + /// + /// Processes the command line + /// + /// + /// true if the command line was processed, false otherwise (load the UI) + public bool Process() + { + // detect if just a project file path is specified (normal UI load) + if (IsProjectLoadOnly()) + { + return false; + } + // Switch all progress reporting over to the command line + CardMakerInstance.ProgressReporterFactory = new ConsoleProgressReporterFactory(); + Logger.InitLogger(new ConsoleLogger(), false); + + if (!LoadProject() || !PerformExport()) + { + Environment.Exit(1); + } + return true; + } + + /// + /// Performs an export operation (determining what to do) + /// + /// true on success, false otherwise + private bool PerformExport() + { + Type typeExporter; + var sExportFormat = m_zCommandLineParser.GetStringArg(CommandLineArg.ExportFormat.ToString(), string.Empty) + .ToUpper(); + if (dictionaryExporterType.TryGetValue(sExportFormat, out typeExporter)) + { + var zExporter = (CommandLineExporterBase) Activator.CreateInstance(typeExporter); + zExporter.CommandLineParser = m_zCommandLineParser; + if (!zExporter.Validate()) + { + return false; + } + zExporter.ConfigureGoogleCredential(); + + return zExporter.Export(); + } + + return false; + } + + /// + /// Loads the project specified on the command line + /// + /// true on success, false otherwise + private bool LoadProject() + { + CardMakerInstance.CommandLineProjectFile = m_zCommandLineParser.GetStringArg(CommandLineArg.ProjectPath); ; + try + { + ProjectManager.Instance.OpenProject(CardMakerInstance.CommandLineProjectFile); + } + catch (Exception ex) + { + Logger.AddLogLine("Failed to load project: {0}".FormatString(CardMakerInstance.CommandLineProjectFile)); + Logger.AddLogLine(ex.ToString()); + return false; + } + return true; + } + + /// + /// Determines if the command line consists only of a project file path + /// + /// true if this is a project only command line, false otherwise + private bool IsProjectLoadOnly() + { + if (m_zCommandLineParser.GetArgCount() == 1) + { + var sFilePath = m_zCommandLineParser.GetStringArg(string.Empty); + if (File.Exists(sFilePath)) + { + CardMakerInstance.CommandLineProjectFile = sFilePath; + } + // if there's only one arg (the blank one) assume UI mode. + return true; + } + return false; + } + } +} diff --git a/CardMaker/Card/CommandLine/ConsoleLogger.cs b/CardMaker/Card/CommandLine/ConsoleLogger.cs new file mode 100644 index 00000000..343f3add --- /dev/null +++ b/CardMaker/Card/CommandLine/ConsoleLogger.cs @@ -0,0 +1,45 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; +using Support.IO; + +namespace CardMaker.Card.CommandLine +{ + public class ConsoleLogger : ILogger + { + public void AddLogLines(string[] arrayLines) + { + foreach (var sLine in arrayLines) + { + Console.WriteLine(sLine); + } + } + + public void ClearLog() + { + // no opp + } + } +} diff --git a/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs b/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs new file mode 100644 index 00000000..ffacec72 --- /dev/null +++ b/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs @@ -0,0 +1,65 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; +using CardMaker.Card.Export; +using CardMaker.Data; +using Support.IO; +using Support.UI; + +namespace CardMaker.Card.CommandLine +{ + public class ImageCommandLineExporter : CommandLineExporterBase + { + public override bool Validate() + { + return true; + } + + public override bool Export() + { + var sExportPath = GetExportPath(true); +#warning is page orientation saved on the layout? + var zFileCardExporter = new FileCardExporter(GetLayoutIndices(), sExportPath, null, 0, GetImageFormat()) + { + ExportCardIndices = GetCardIndices() + }; + zFileCardExporter.ProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( + "PDF Export - {0}".FormatString(sExportPath), + new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA , ProgressName.CARD }, + zFileCardExporter.ExportThread); + try + { + zFileCardExporter.ProgressReporter.StartProcessing(null); + return true; + } + catch (Exception e) + { + Logger.AddLogLine(e.Message); + Logger.AddLogLine(e.StackTrace); + return false; + } + } + } +} diff --git a/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs b/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs new file mode 100644 index 00000000..4947b996 --- /dev/null +++ b/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs @@ -0,0 +1,62 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; +using CardMaker.Card.Export; +using CardMaker.Data; +using Support.IO; +using Support.UI; + +namespace CardMaker.Card.CommandLine +{ + class PDFCommandLineExporter : CommandLineExporterBase + { + public override bool Validate() + { + return true; + } + + public override bool Export() + { + var sExportPath = GetExportPath(false); +#warning is page orientation saved on the layout? + var zFileCardExporter = new PdfSharpExporter(GetLayoutIndices(), sExportPath, GetPageOrientation()); + zFileCardExporter.ProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( + "PDF Export - {0}".FormatString(sExportPath), + new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA, ProgressName.CARD }, + zFileCardExporter.ExportThread); + try + { + zFileCardExporter.ProgressReporter.StartProcessing(null); + return true; + } + catch (Exception e) + { + Logger.AddLogLine(e.Message); + Logger.AddLogLine(e.StackTrace); + return false; + } + } + } +} diff --git a/CardMaker/Card/Deck.cs b/CardMaker/Card/Deck.cs index 72693e25..eeb7a95c 100644 --- a/CardMaker/Card/Deck.cs +++ b/CardMaker/Card/Deck.cs @@ -32,6 +32,7 @@ using CardMaker.Events.Managers; using CardMaker.XML; using Support.IO; +using Support.Progress; using Support.UI; #if MONO_BUILD @@ -40,10 +41,12 @@ namespace CardMaker.Card { +#warning Create Deck Reader so the progress and loading isn't in this class public class Deck { public const string DEFINES_DATA_POSTFIX = "_defines"; + protected ProgressReporterProxy m_zReporterProxy; protected int m_nCardIndex = -1; protected int m_nCardPrintIndex; @@ -120,9 +123,9 @@ protected void ReadData(object zRefData) } catch (Exception ex) { - Logger.AddLogLine("Failed to read data file(s). " + ex.Message); - WaitDialog.Instance.ThreadSuccess = false; - WaitDialog.Instance.CloseWaitDialog(); + ReadDataCore(null); + m_zReporterProxy.AddIssue("Failed to read data file(s). " + ex.Message); + m_zReporterProxy.Shutdown(); } } @@ -141,18 +144,18 @@ private void ReadDataCore(object zRefData) } else { - WaitDialog.Instance.ProgressReset(0, 0, zReferenceData.Length * 2 + 1, 0); + m_zReporterProxy.ProgressReset(0, zReferenceData.Length * 2 + 1, 0); for(int nIdx = 0; nIdx < zReferenceData.Length; nIdx++) { var zReference = zReferenceData[nIdx]; var listRefLines = new List>(); - zRefReader = ReferenceReaderFactory.GetReader(zReference); + zRefReader = ReferenceReaderFactory.GetReader(zReference, m_zReporterProxy.ProgressReporter); if (zRefReader == null) { listLines.Clear(); - Logger.AddLogLine($"Failed to load reference: {zReference.RelativePath}"); + m_zReporterProxy.AddIssue($"Failed to load reference: {zReference.RelativePath}"); break; } // 0 index is always the default reference in the case of multi load @@ -163,16 +166,14 @@ private void ReadDataCore(object zRefData) zRefReader.GetProjectDefineData(zReference, listDefineLines); if (listDefineLines.Count == 0) { - Logger.AddLogLine( - "No defines found for project file: {0}".FormatString( - ProjectManager.Instance.ProjectFilePath)); + m_zReporterProxy.AddIssue("No defines found for project file: {0}".FormatString(ProjectManager.Instance.ProjectFilePath)); } } else { - Logger.AddLogLine("No defines loaded for project -- project not yet saved."); + m_zReporterProxy.AddIssue("No defines loaded for project -- project not yet saved."); } - WaitDialog.Instance.ProgressStep(0); + m_zReporterProxy.ProgressStep(); } zRefReader.GetReferenceData(zReference, listRefLines); @@ -182,18 +183,17 @@ private void ReadDataCore(object zRefData) listRefLines.RemoveAt(0); } listLines.AddRange(listRefLines); - WaitDialog.Instance.ProgressStep(0); + m_zReporterProxy.ProgressStep(); var nPriorCount = listDefineLines.Count; zRefReader.GetDefineData(zReference, listDefineLines); if (listDefineLines.Count == nPriorCount) { - Logger.AddLogLine( - "No defines found for reference: {0}".FormatString(zReference.RelativePath)); + m_zReporterProxy.AddIssue("No defines found for reference: {0}".FormatString(zReference.RelativePath)); } zRefReader.FinalizeReferenceLoad(); - WaitDialog.Instance.ProgressStep(0); + m_zReporterProxy.ProgressStep(); } } @@ -234,7 +234,7 @@ protected void ProcessLines(List> listLines, else { IssueManager.Instance.FireAddIssueEvent("Duplicate column found in: " + sReferencePath + "::" + "Column [" + nIdx + "]: " + sKey); - Logger.AddLogLine("Duplicate column found in: " + sReferencePath + "::" + "Column [" + nIdx + "]: " + sKey); + m_zReporterProxy.AddIssue("Duplicate column found in: " + sReferencePath + "::" + "Column [" + nIdx + "]: " + sKey); } } @@ -262,7 +262,7 @@ protected void ProcessLines(List> listLines, Dictionary dictionaryOverrides = dictionaryElementOverrides[sElementName]; if (dictionaryOverrides.ContainsKey(sElementItemOverride)) { - Logger.AddLogLine("Duplicate override found: {0}".FormatString(sElementItemOverride)); + m_zReporterProxy.AddIssue("Duplicate override found: {0}".FormatString(sElementItemOverride)); } dictionaryOverrides[sElementItemOverride] = dictionaryColumnNames[sKey]; } @@ -392,15 +392,15 @@ protected void ProcessLines(List> listLines, string sVal; if (dictionaryDefines.TryGetValue(sKey.ToLower(), out sVal)) { - string sMsg = "Duplicate define found: " + sKey; + var sMsg = "Duplicate define found: " + sKey; IssueManager.Instance.FireAddIssueEvent(sMsg); - Logger.AddLogLine(sMsg); + m_zReporterProxy.AddIssue(sMsg); } else if (dictionaryColumnNames.TryGetValue(sKey.ToLower(), out nIdx)) { - string sMsg = "Overlapping column name and define found in: " + sReferencePath + "::" + "Column [" + nIdx + "]: " + sKey; + var sMsg = "Overlapping column name and define found in: " + sReferencePath + "::" + "Column [" + nIdx + "]: " + sKey; IssueManager.Instance.FireAddIssueEvent(sMsg); - Logger.AddLogLine(sMsg); + m_zReporterProxy.AddIssue(sMsg); } else { @@ -415,8 +415,7 @@ protected void ProcessLines(List> listLines, #if MONO_BUILD Thread.Sleep(100); #endif - WaitDialog.Instance.ThreadSuccess = true; - WaitDialog.Instance.CloseWaitDialog(); + m_zReporterProxy.Shutdown(); } /// @@ -425,21 +424,21 @@ protected void ProcessLines(List> listLines, /// private void ReadDefaultProjectDefinitions(List> listDefineLines) { - WaitDialog.Instance.ProgressReset(0, 0, 2, 0); + m_zReporterProxy.ProgressReset(0, 2, 0); ReferenceReader zRefReader; if (ReferenceType.Google == ProjectManager.Instance.LoadedProjectDefaultDefineReferenceType) { - zRefReader = ReferenceReaderFactory.GetDefineReader(ReferenceType.Google); + zRefReader = ReferenceReaderFactory.GetDefineReader(ReferenceType.Google, m_zReporterProxy.ProgressReporter); zRefReader?.GetProjectDefineData(null, listDefineLines); } - WaitDialog.Instance.ProgressStep(0); + m_zReporterProxy.ProgressStep(); // always attempt to load the local if nothing was pulled from google if (0 == listDefineLines.Count) { - zRefReader = ReferenceReaderFactory.GetDefineReader(ReferenceType.CSV); + zRefReader = ReferenceReaderFactory.GetDefineReader(ReferenceType.CSV, m_zReporterProxy.ProgressReporter); zRefReader?.GetProjectDefineData(null, listDefineLines); } - WaitDialog.Instance.ProgressStep(0); + m_zReporterProxy.ProgressStep(); } public ElementString TranslateString(string sRawString, DeckLine zDeckLine, ProjectLayoutElement zElement, bool bPrint, string sCacheSuffix = "") @@ -527,7 +526,6 @@ public void ResetDeckCache() #endregion #region Markup Cache - public void AddCachedMarkup(string sElementName, FormattedTextDataCache zFormattedData) { m_zTranslator.AddCachedMarkup(sElementName, zFormattedData); @@ -539,22 +537,18 @@ public void ResetMarkupCache(string sElementName) } #endregion - #region Layout Set - public void SetAndLoadLayout(ProjectLayout zLayout, bool bExporting) + public void SetAndLoadLayout(ProjectLayout zLayout, bool bExporting, ProgressReporterProxy zReporterProxy) { EmptyReference = false; CardLayout = zLayout; ResetPrintCardIndex(); - - var bReferenceFound = false; + ProjectLayoutReference[] zReferenceData = null; if (null != CardLayout.Reference) { - ProjectLayoutReference[] zReferenceData = null; - if (CardLayout.combineReferences) { var listReferences = new List(); @@ -588,41 +582,43 @@ public void SetAndLoadLayout(ProjectLayout zLayout, bool bExporting) } } } - var zWait = new WaitDialog( - 1, - ReadData, - zReferenceData, - "Loading Data", - null, - 400); -#warning this needs to be pulled into a deck loader - CardMakerInstance.ApplicationForm.InvokeAction(() => zWait.ShowDialog(CardMakerInstance.ApplicationForm)); - if (!bExporting) + } + InitiateReferenceRead(zReporterProxy, zReferenceData); + + if (!bExporting) + { + if (CardMakerInstance.GoogleCredentialsInvalid) { - if (CardMakerInstance.GoogleCredentialsInvalid) - { - CardMakerInstance.GoogleCredentialsInvalid = false; - GoogleAuthManager.Instance.FireGoogleAuthCredentialsErrorEvent( - () => LayoutManager.Instance.InitializeActiveLayout()); - } + CardMakerInstance.GoogleCredentialsInvalid = false; + GoogleAuthManager.Instance.FireGoogleAuthCredentialsErrorEvent( + () => LayoutManager.Instance.InitializeActiveLayout()); } - bReferenceFound = zWait.ThreadSuccess; } + } - if (!bReferenceFound) + private void InitiateReferenceRead(ProgressReporterProxy zReporterProxy, ProjectLayoutReference[] arrayProjectLayoutReferences) + { + if (zReporterProxy != null) + { + m_zReporterProxy = zReporterProxy; + ReadData(arrayProjectLayoutReferences); + } + else { - // setup the placeholder single card - var zWait = new WaitDialog( - 1, + var zProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( + "Loading Reference Data", + new string[] { ProgressName.REFERENCE_DATA }, ReadData, - null, - "Loading Data", - null, - 400) + arrayProjectLayoutReferences + ); + zProgressReporter.CancelButtonVisible = false; + m_zReporterProxy = new ProgressReporterProxy() { - CancelButtonVisibile = false + ProgressIndex = 0, // known from above + ProgressReporter = zProgressReporter, + ProxyOwnsReporter = true }; - CardMakerInstance.ApplicationForm.InvokeAction(() => zWait.ShowDialog(CardMakerInstance.ApplicationForm)); + CardMakerInstance.ApplicationForm.InvokeAction(() => zProgressReporter.StartProcessing(CardMakerInstance.ApplicationForm)); } } diff --git a/CardMaker/Card/Export/CardExportBase.cs b/CardMaker/Card/Export/CardExportBase.cs index cbb81642..2033e6e8 100644 --- a/CardMaker/Card/Export/CardExportBase.cs +++ b/CardMaker/Card/Export/CardExportBase.cs @@ -23,25 +23,29 @@ //////////////////////////////////////////////////////////////////////////////// using System.Drawing; +using System.Linq; +using CardMaker.Data; using CardMaker.Events.Managers; using CardMaker.XML; +using Support.Progress; namespace CardMaker.Card.Export { public abstract class CardExportBase { protected Bitmap m_zExportCardBuffer; - protected ProjectLayout m_zLastLayout = null; - - protected int ExportLayoutStartIndex { get; private set; } - protected int ExportLayoutEndIndex { get; private set; } - + protected int[] ExportLayoutIndices { get; private set; } protected CardRenderer CardRenderer { get; } + + public IProgressReporter ProgressReporter { get; set; } - protected CardExportBase(int nLayoutStartIndex, int nLayoutEndIndex) + protected CardExportBase(int nLayoutStartIndex, int nLayoutEndIndex) : this(Enumerable.Range(nLayoutStartIndex, nLayoutEndIndex - nLayoutStartIndex).ToArray()) { - ExportLayoutStartIndex = nLayoutStartIndex; - ExportLayoutEndIndex = nLayoutEndIndex; + } + + protected CardExportBase(int[] arrayExportLayoutIndices) + { + ExportLayoutIndices = arrayExportLayoutIndices; CardRenderer = new CardRenderer { CurrentDeck = new Deck() @@ -56,7 +60,13 @@ protected void ChangeExportLayoutIndex(int nIdx) { // based on the currently loaded project get the layout based on the index var zLayout = ProjectManager.Instance.LoadedProject.Layout[nIdx]; - CurrentDeck.SetAndLoadLayout(zLayout ?? CurrentDeck.CardLayout, true); + CurrentDeck.SetAndLoadLayout(zLayout ?? CurrentDeck.CardLayout, true, + new ProgressReporterProxy() + { + ProgressIndex = ProgressReporter.GetProgressIndex(ProgressName.REFERENCE_DATA), + ProgressReporter = ProgressReporter, + ProxyOwnsReporter = false + }); } protected Deck CurrentDeck => CardRenderer.CurrentDeck; @@ -101,5 +111,10 @@ protected void ProcessRotateExport(Bitmap zBuffer, ProjectLayout zLayout, bool p break; } } + + /// + /// The primary entry point for the export processing + /// + public abstract void ExportThread(); } } diff --git a/CardMaker/Card/Export/CompilerCardExporter.cs b/CardMaker/Card/Export/CompilerCardExporter.cs index dc2405b1..331adb34 100644 --- a/CardMaker/Card/Export/CompilerCardExporter.cs +++ b/CardMaker/Card/Export/CompilerCardExporter.cs @@ -23,6 +23,7 @@ //////////////////////////////////////////////////////////////////////////////// using System.Drawing; +using CardMaker.Data; using CardMaker.Events.Managers; using Support.UI; @@ -31,22 +32,26 @@ namespace CardMaker.Card.Export /// /// This is an exporter used to scan the project for errors /// - public class CompilerCardExporter : CardExportBase, ICardExporter + public class CompilerCardExporter : CardExportBase { public CompilerCardExporter(int nLayoutStartIndex, int nLayoutEndIndex) : base(nLayoutStartIndex, nLayoutEndIndex) { } - public void ExportThread() + public override void ExportThread() { - WaitDialog zWait = WaitDialog.Instance; - for (int nIdx = ExportLayoutStartIndex; nIdx < ExportLayoutEndIndex; nIdx++) + var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); + var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); + + ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); + foreach (var nIdx in ExportLayoutIndices) { IssueManager.Instance.FireChangeCardInfoEvent(nIdx, 1); IssueManager.Instance.FireChangeElementEvent(string.Empty); +#warning there's no progress reporter ChangeExportLayoutIndex(nIdx); - zWait.ProgressReset(1, 0, CurrentDeck.CardCount, 0); + ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); UpdateBufferBitmap(CurrentDeck.CardLayout.width, CurrentDeck.CardLayout.height); var zGraphics = Graphics.FromImage(m_zExportCardBuffer); @@ -56,12 +61,12 @@ public void ExportThread() IssueManager.Instance.FireChangeCardInfoEvent(nIdx, nCardIdx + 1); CurrentDeck.CardPrintIndex = nCardIdx; CardRenderer.DrawPrintLineToGraphics(zGraphics); - zWait.ProgressStep(1); + ProgressReporter.ProgressStep(progressCardIdx); } - zWait.ProgressStep(0); + ProgressReporter.ProgressStep(progressLayoutIdx); } - zWait.ThreadSuccess = true; - zWait.CloseWaitDialog(); + ProgressReporter.ThreadSuccess = true; + ProgressReporter.Shutdown(); } } } diff --git a/CardMaker/Card/Export/FileCardClipboardExporter.cs b/CardMaker/Card/Export/FileCardClipboardExporter.cs index 3f33176b..758bc93f 100644 --- a/CardMaker/Card/Export/FileCardClipboardExporter.cs +++ b/CardMaker/Card/Export/FileCardClipboardExporter.cs @@ -32,7 +32,7 @@ namespace CardMaker.Card.Export { - public class FileCardClipboardExporter : CardExportBase, ICardExporter + public class FileCardClipboardExporter : CardExportBase { private readonly int m_nImageExportIndex; @@ -42,13 +42,14 @@ public FileCardClipboardExporter(int nLayoutStartIndex, int nLayoutEndIdx, int n m_nImageExportIndex = nImageExportIndex; } - public void ExportThread() + public override void ExportThread() { - var zWait = WaitDialog.Instance; + var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); + var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); - zWait.ProgressReset(0, 0, ExportLayoutEndIndex - ExportLayoutStartIndex, 0); - ChangeExportLayoutIndex(ExportLayoutStartIndex); - zWait.ProgressReset(1, 0, CurrentDeck.CardCount, 0); + ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); + ChangeExportLayoutIndex(ExportLayoutIndices[0]); + ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); UpdateBufferBitmap(CurrentDeck.CardLayout.width, CurrentDeck.CardLayout.height); @@ -62,7 +63,7 @@ public void ExportThread() CardRenderer.DrawPrintLineToGraphics(zGraphics, 0, 0, !CurrentDeck.CardLayout.exportTransparentBackground); m_zExportCardBuffer.SetResolution(CurrentDeck.CardLayout.dpi, CurrentDeck.CardLayout.dpi); - zWait.ProgressStep(1); + ProgressReporter.ProgressStep(progressLayoutIdx); try { @@ -75,15 +76,15 @@ public void ExportThread() catch (Exception) { Logger.AddLogLine("Error copying layout image to clipboard."); - zWait.ThreadSuccess = false; - zWait.CloseWaitDialog(); + ProgressReporter.ThreadSuccess = false; + ProgressReporter.Shutdown(); return; } - zWait.ProgressStep(0); + ProgressReporter.ProgressStep(progressCardIdx); - zWait.ThreadSuccess = true; - zWait.CloseWaitDialog(); + ProgressReporter.ThreadSuccess = true; + ProgressReporter.Shutdown(); } } } diff --git a/CardMaker/Card/Export/FileCardExporter.cs b/CardMaker/Card/Export/FileCardExporter.cs index 469b3cc1..b0a24754 100644 --- a/CardMaker/Card/Export/FileCardExporter.cs +++ b/CardMaker/Card/Export/FileCardExporter.cs @@ -27,22 +27,30 @@ using System.Drawing.Imaging; using System.Globalization; using System.IO; +using System.Linq; using CardMaker.Data; +using CardMaker.XML; using Support.IO; -using Support.UI; namespace CardMaker.Card.Export { - public class FileCardExporter : CardExportBase, ICardExporter + public class FileCardExporter : CardExportBase { private readonly string m_sExportFolder; private readonly string m_sOverrideStringFormat; private readonly ImageFormat m_eImageFormat; private readonly int m_nSkipStitchIndex; + public int[] ExportCardIndices { get; set; } - public FileCardExporter(int nLayoutStartIndex, int nLayoutEndIdx, string sExportFolder, string sOverrideStringFormat, int - nSkipStitchIndex, System.Drawing.Imaging.ImageFormat eImageFormat) - : base(nLayoutStartIndex, nLayoutEndIdx) + public FileCardExporter(int nLayoutStartIndex, int nLayoutEndIdx, string sExportFolder, string sOverrideStringFormat, int nSkipStitchIndex, ImageFormat eImageFormat) + : this(Enumerable.Range(nLayoutStartIndex, (nLayoutEndIdx - nLayoutStartIndex) + 1).ToArray(), sExportFolder, sOverrideStringFormat, nSkipStitchIndex, eImageFormat) + { + + } + + public FileCardExporter(int[] arrayExportLayoutIndices, string sExportFolder, string sOverrideStringFormat, int + nSkipStitchIndex, ImageFormat eImageFormat) + : base(arrayExportLayoutIndices) { if (!sExportFolder.EndsWith(Path.DirectorySeparatorChar.ToString(CultureInfo.InvariantCulture))) { @@ -56,22 +64,23 @@ public FileCardExporter(int nLayoutStartIndex, int nLayoutEndIdx, string sExport m_eImageFormat = eImageFormat; } - public void ExportThread() + public override void ExportThread() { - var zWait = WaitDialog.Instance; + var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); + var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); - zWait.ProgressReset(0, 0, ExportLayoutEndIndex - ExportLayoutStartIndex, 0); - for (var nIdx = ExportLayoutStartIndex; nIdx < ExportLayoutEndIndex; nIdx++) + ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); + foreach (var nIdx in ExportLayoutIndices) { ChangeExportLayoutIndex(nIdx); if (CurrentDeck.EmptyReference) { // empty reference layouts are not exported - zWait.ProgressStep(0); + ProgressReporter.ProgressStep(progressLayoutIdx); continue; } var nPadSize = CurrentDeck.CardCount.ToString(CultureInfo.InvariantCulture).Length; - zWait.ProgressReset(1, 0, CurrentDeck.CardCount, 0); + ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); var exportWidth = CurrentDeck.CardLayout.exportWidth == 0 ? CurrentDeck.CardLayout.width : CurrentDeck.CardLayout.exportWidth; @@ -89,9 +98,10 @@ public void ExportThread() UpdateBufferBitmap(exportWidth, exportHeight); var zGraphics = Graphics.FromImage(m_zExportCardBuffer); - var nCardIdx = 0; - do + var arrayCardIndices = GetCardIndicesArray(CurrentDeck); + for(var nCardArrayIdx = 0; nCardArrayIdx < arrayCardIndices.Length; nCardArrayIdx++) { + var nCardId = arrayCardIndices[nCardArrayIdx]; var nX = 0; var nY = 0; var nCardsExportedInImage = 0; @@ -101,12 +111,13 @@ public void ExportThread() do { CurrentDeck.ResetDeckCache(); - CurrentDeck.CardPrintIndex = nCardIdx++; + // HACK - the printcard index is 0 based but all other uses of nCardId are 1 based (so ++ it!) + CurrentDeck.CardPrintIndex = nCardId++; nCardsExportedInImage++; CardRenderer.DrawPrintLineToGraphics(zGraphics, nX, nY, !CurrentDeck.CardLayout.exportTransparentBackground); m_zExportCardBuffer.SetResolution(CurrentDeck.CardLayout.dpi, CurrentDeck.CardLayout.dpi); - zWait.ProgressStep(1); + ProgressReporter.ProgressStep(progressCardIdx); int nMoveCount = 1; if (m_nSkipStitchIndex > 0) @@ -140,25 +151,25 @@ public void ExportThread() { break; } - } while (nCardIdx < CurrentDeck.CardCount); + } while (nCardArrayIdx < CurrentDeck.CardCount); string sFileName; - // NOTE: nCardIdx at this point is 1 more than the actual index ... how convenient for export file names... + // NOTE: nCardId at this point is 1 more than the actual index ... how convenient for export file names... if (!string.IsNullOrEmpty(m_sOverrideStringFormat)) { // check for the super override - sFileName = CurrentDeck.TranslateFileNameString(m_sOverrideStringFormat, nCardIdx, nPadSize); + sFileName = CurrentDeck.TranslateFileNameString(m_sOverrideStringFormat, nCardId, nPadSize); } else if (!string.IsNullOrEmpty(CurrentDeck.CardLayout.exportNameFormat)) { // check for the per layout override - sFileName = CurrentDeck.TranslateFileNameString(CurrentDeck.CardLayout.exportNameFormat, nCardIdx, nPadSize); + sFileName = CurrentDeck.TranslateFileNameString(CurrentDeck.CardLayout.exportNameFormat, nCardId, nPadSize); } else // default { - sFileName = CurrentDeck.CardLayout.Name + "_" + (nCardIdx).ToString(CultureInfo.InvariantCulture).PadLeft(nPadSize, '0'); + sFileName = CurrentDeck.CardLayout.Name + "_" + (nCardId).ToString(CultureInfo.InvariantCulture).PadLeft(nPadSize, '0'); } try { @@ -169,20 +180,42 @@ public void ExportThread() m_eImageFormat); ProcessRotateExport(m_zExportCardBuffer, CurrentDeck.CardLayout, true); } - catch (Exception) + catch (Exception ex) { - Logger.AddLogLine("Invalid Filename or IO error: " + sFileName); - zWait.ThreadSuccess = false; - zWait.CloseWaitDialog(); + ProgressReporter.AddIssue("Invalid Filename or IO error: " + sFileName + " :: " + ex.Message); + ProgressReporter.ThreadSuccess = false; + ProgressReporter.Shutdown(); return; } - - } while (nCardIdx < CurrentDeck.CardCount); - zWait.ProgressStep(0); + } + ProgressReporter.ProgressSet(progressCardIdx, 0); + ProgressReporter.ProgressStep(progressLayoutIdx); } - zWait.ThreadSuccess = true; - zWait.CloseWaitDialog(); + ProgressReporter.ThreadSuccess = true; + ProgressReporter.Shutdown(); + } + + /// + /// Gets the array of indices to export + /// + /// The deck to use if no indices are specified + /// Array of card indices to export + private int[] GetCardIndicesArray(Deck zDeck) + { + if (ExportCardIndices != null) + { + if (ExportCardIndices.Any(i => i >= zDeck.CardCount || i < 0)) + { + throw new Exception("Invalid card indices specified."); + } + + return ExportCardIndices; + } + else + { + return Enumerable.Range(0, zDeck.CardCount).ToArray(); + } } /// diff --git a/CardMaker/Card/Export/FileCardExporterFactory.cs b/CardMaker/Card/Export/FileCardExporterFactory.cs index b582604f..aecfe148 100644 --- a/CardMaker/Card/Export/FileCardExporterFactory.cs +++ b/CardMaker/Card/Export/FileCardExporterFactory.cs @@ -23,6 +23,7 @@ //////////////////////////////////////////////////////////////////////////////// using System; +using System.Collections.Generic; using System.Drawing.Imaging; using System.IO; using System.Linq; @@ -46,7 +47,7 @@ enum ExportOptionKey StitchSkipIndex, } - private static readonly ImageFormat[] s_arrayAllowedFormats = + public static readonly ImageFormat[] AllowedImageFormats = { ImageFormat.Bmp, ImageFormat.Emf, @@ -59,14 +60,17 @@ enum ExportOptionKey ImageFormat.Wmf }; - private static readonly string[] s_arrayAllowedFormatNames = s_arrayAllowedFormats.Select(zFormat => zFormat.ToString()).ToArray(); + public static readonly string[] AllowedImageFormatNames = AllowedImageFormats.Select(zFormat => zFormat.ToString()).ToArray(); - public static ICardExporter BuildFileCardExporter(bool bExportAllLayouts) + public static readonly Dictionary AllowedImageFormatDictionary = + AllowedImageFormats.ToDictionary(zFormat => zFormat.ToString().ToUpper(), zFormat => zFormat); + + public static CardExportBase BuildFileCardExporter(bool bExportAllLayouts) { return bExportAllLayouts ? BuildProjectExporter() : BuildLayoutExporter(); } - private static ICardExporter BuildProjectExporter() + private static CardExportBase BuildProjectExporter() { var zQuery = new QueryPanelDialog("Export to Images", 750, false); zQuery.SetIcon(Properties.Resources.CardMakerIcon); @@ -74,7 +78,7 @@ private static ICardExporter BuildProjectExporter() var sDefinition = ProjectManager.Instance.LoadedProject.exportNameFormat; // default to the project level definition var nDefaultFormatIndex = GetLastFormatIndex(); - zQuery.AddPullDownBox("Format", s_arrayAllowedFormatNames, nDefaultFormatIndex, ExportOptionKey.Format); + zQuery.AddPullDownBox("Format", AllowedImageFormatNames, nDefaultFormatIndex, ExportOptionKey.Format); zQuery.AddCheckBox("Override Layout File Name Formats", false, ExportOptionKey.NameFormatOverride); zQuery.AddNumericBox("Stitch Skip Index", CardMakerSettings.ExportStitchSkipIndex, 0, 65535, 1, 0, ExportOptionKey.StitchSkipIndex); zQuery.AddTextBox("File Name Format (optional)", sDefinition ?? string.Empty, false, ExportOptionKey.NameFormat); @@ -100,18 +104,18 @@ private static ICardExporter BuildProjectExporter() ProjectManager.Instance.LoadedProject.lastExportPath = sFolder; var nStartLayoutIdx = 0; - var nEndLayoutIdx = ProjectManager.Instance.LoadedProject.Layout.Length; + var nEndLayoutIdx = ProjectManager.Instance.LoadedProject.Layout.Length - 1; var bOverrideLayout = false; bOverrideLayout = zQuery.GetBool(ExportOptionKey.NameFormatOverride); - CardMakerSettings.IniManager.SetValue(IniSettings.LastImageExportFormat, s_arrayAllowedFormatNames[zQuery.GetIndex(ExportOptionKey.Format)]); + CardMakerSettings.IniManager.SetValue(IniSettings.LastImageExportFormat, AllowedImageFormatNames[zQuery.GetIndex(ExportOptionKey.Format)]); CardMakerSettings.ExportStitchSkipIndex = (int)zQuery.GetDecimal(ExportOptionKey.StitchSkipIndex); return new FileCardExporter(nStartLayoutIdx, nEndLayoutIdx, sFolder, bOverrideLayout ? zQuery.GetString(ExportOptionKey.NameFormat) : null, - CardMakerSettings.ExportStitchSkipIndex, s_arrayAllowedFormats[zQuery.GetIndex(ExportOptionKey.Format)]); + CardMakerSettings.ExportStitchSkipIndex, AllowedImageFormats[zQuery.GetIndex(ExportOptionKey.Format)]); } - private static ICardExporter BuildLayoutExporter() + private static CardExportBase BuildLayoutExporter() { var zQuery = new QueryPanelDialog("Export to Images", 750, false); zQuery.SetIcon(Properties.Resources.CardMakerIcon); @@ -120,7 +124,7 @@ private static ICardExporter BuildLayoutExporter() var nDefaultFormatIndex = GetLastFormatIndex(); - zQuery.AddPullDownBox("Format", s_arrayAllowedFormatNames, nDefaultFormatIndex, ExportOptionKey.Format); + zQuery.AddPullDownBox("Format", AllowedImageFormatNames, nDefaultFormatIndex, ExportOptionKey.Format); zQuery.AddNumericBox("Stitch Skip Index", CardMakerSettings.ExportStitchSkipIndex, 0, 65535, 1, 0, ExportOptionKey.StitchSkipIndex); zQuery.AddTextBox("File Name Format (optional)", sDefinition ?? string.Empty, false, ExportOptionKey.NameFormat); zQuery.AddFolderBrowseBox("Output Folder", @@ -150,14 +154,14 @@ private static ICardExporter BuildLayoutExporter() return null; } - CardMakerSettings.IniManager.SetValue(IniSettings.LastImageExportFormat, s_arrayAllowedFormatNames[zQuery.GetIndex(ExportOptionKey.Format)]); + CardMakerSettings.IniManager.SetValue(IniSettings.LastImageExportFormat, AllowedImageFormatNames[zQuery.GetIndex(ExportOptionKey.Format)]); CardMakerSettings.ExportStitchSkipIndex = (int)zQuery.GetDecimal(ExportOptionKey.StitchSkipIndex); - return new FileCardExporter(nLayoutIndex, nLayoutIndex + 1, sFolder, zQuery.GetString(ExportOptionKey.NameFormat), - CardMakerSettings.ExportStitchSkipIndex, s_arrayAllowedFormats[zQuery.GetIndex(ExportOptionKey.Format)]); + return new FileCardExporter(nLayoutIndex, nLayoutIndex, sFolder, zQuery.GetString(ExportOptionKey.NameFormat), + CardMakerSettings.ExportStitchSkipIndex, AllowedImageFormats[zQuery.GetIndex(ExportOptionKey.Format)]); } - public static ICardExporter BuildImageExporter() + public static CardExportBase BuildImageExporter() { var zQuery = new QueryPanelDialog("Export Image", 750, false); zQuery.SetIcon(Properties.Resources.CardMakerIcon); @@ -165,7 +169,7 @@ public static ICardExporter BuildImageExporter() var sDefinition = LayoutManager.Instance.ActiveLayout.exportNameFormat; var nDefaultFormatIndex = GetLastFormatIndex(); - zQuery.AddPullDownBox("Format", s_arrayAllowedFormatNames, nDefaultFormatIndex, ExportOptionKey.Format); + zQuery.AddPullDownBox("Format", AllowedImageFormatNames, nDefaultFormatIndex, ExportOptionKey.Format); zQuery.AddTextBox("File Name Format (optional)", sDefinition ?? string.Empty, false, ExportOptionKey.NameFormat); zQuery.AddFolderBrowseBox("Output Folder", Directory.Exists(ProjectManager.Instance.LoadedProject.lastExportPath) ? ProjectManager.Instance.LoadedProject.lastExportPath : string.Empty, @@ -194,13 +198,13 @@ public static ICardExporter BuildImageExporter() return null; } - CardMakerSettings.IniManager.SetValue(IniSettings.LastImageExportFormat, s_arrayAllowedFormatNames[zQuery.GetIndex(ExportOptionKey.Format)]); + CardMakerSettings.IniManager.SetValue(IniSettings.LastImageExportFormat, AllowedImageFormatNames[zQuery.GetIndex(ExportOptionKey.Format)]); return new FileCardSingleExporter(nLayoutIndex, nLayoutIndex + 1, sFolder, zQuery.GetString(ExportOptionKey.NameFormat), - s_arrayAllowedFormats[zQuery.GetIndex(ExportOptionKey.Format)], LayoutManager.Instance.ActiveDeck.CardIndex); + AllowedImageFormats[zQuery.GetIndex(ExportOptionKey.Format)], LayoutManager.Instance.ActiveDeck.CardIndex); } - public static ICardExporter BuildImageClipboardExporter() + public static CardExportBase BuildImageClipboardExporter() { var nLayoutIndex = ProjectManager.Instance.GetLayoutIndex(LayoutManager.Instance.ActiveLayout); if (-1 == nLayoutIndex) @@ -217,9 +221,9 @@ private static int GetLastFormatIndex() if (lastImageFormat != string.Empty) { - for (var nIdx = 0; nIdx < s_arrayAllowedFormatNames.Length; nIdx++) + for (var nIdx = 0; nIdx < AllowedImageFormatNames.Length; nIdx++) { - if (s_arrayAllowedFormatNames[nIdx].Equals(lastImageFormat)) + if (AllowedImageFormatNames[nIdx].Equals(lastImageFormat)) { return nIdx; } diff --git a/CardMaker/Card/Export/FileCardSingleExporter.cs b/CardMaker/Card/Export/FileCardSingleExporter.cs index fa423570..dc18c0c4 100644 --- a/CardMaker/Card/Export/FileCardSingleExporter.cs +++ b/CardMaker/Card/Export/FileCardSingleExporter.cs @@ -33,7 +33,8 @@ namespace CardMaker.Card.Export { - public class FileCardSingleExporter : CardExportBase, ICardExporter +#warning Can this share with FileCardExporter? Seems like a likely dupe... + public class FileCardSingleExporter : CardExportBase { private readonly string m_sExportFolder; private readonly string m_sOverrideStringFormat; @@ -55,14 +56,15 @@ public FileCardSingleExporter(int nLayoutStartIndex, int nLayoutEndIdx, string s m_nImageExportIndex = nImageExportIndex; } - public void ExportThread() + public override void ExportThread() { - var zWait = WaitDialog.Instance; + var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); + var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); - zWait.ProgressReset(0, 0, ExportLayoutEndIndex - ExportLayoutStartIndex, 0); - ChangeExportLayoutIndex(ExportLayoutStartIndex); + ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); + ChangeExportLayoutIndex(ExportLayoutIndices[0]); var nPadSize = CurrentDeck.CardCount.ToString(CultureInfo.InvariantCulture).Length; - zWait.ProgressReset(1, 0, CurrentDeck.CardCount, 0); + ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); UpdateBufferBitmap(CurrentDeck.CardLayout.width, CurrentDeck.CardLayout.height); @@ -76,7 +78,7 @@ public void ExportThread() CardRenderer.DrawPrintLineToGraphics(zGraphics, 0, 0, !CurrentDeck.CardLayout.exportTransparentBackground); m_zExportCardBuffer.SetResolution(CurrentDeck.CardLayout.dpi, CurrentDeck.CardLayout.dpi); - zWait.ProgressStep(1); + ProgressReporter.ProgressStep(progressCardIdx); string sFileName; @@ -105,18 +107,18 @@ public void ExportThread() m_eImageFormat); ProcessRotateExport(m_zExportCardBuffer, CurrentDeck.CardLayout, true); } - catch (Exception) + catch (Exception e) { - Logger.AddLogLine("Invalid Filename or IO error: " + sFileName); - zWait.ThreadSuccess = false; - zWait.CloseWaitDialog(); + ProgressReporter.AddIssue("Invalid Filename or IO error: {0} {1}".FormatString(sFileName, e.Message)); + ProgressReporter.ThreadSuccess = false; + ProgressReporter.Shutdown(); return; } - zWait.ProgressStep(0); + ProgressReporter.ProgressStep(progressLayoutIdx); - zWait.ThreadSuccess = true; - zWait.CloseWaitDialog(); + ProgressReporter.ThreadSuccess = true; + ProgressReporter.Shutdown(); } } } diff --git a/CardMaker/Card/Export/PdfSharpExporter.cs b/CardMaker/Card/Export/PdfSharpExporter.cs index c445d4c2..f195fbcc 100644 --- a/CardMaker/Card/Export/PdfSharpExporter.cs +++ b/CardMaker/Card/Export/PdfSharpExporter.cs @@ -26,6 +26,7 @@ using System.Collections.Generic; using System.Drawing; using System.IO; +using System.Linq; using System.Windows.Forms; using CardMaker.Data; using CardMaker.XML; @@ -61,9 +62,13 @@ public class PdfSharpExporter : CardExportBase private readonly PageOrientation m_ePageOrientation = PageOrientation.Portrait; - public PdfSharpExporter(int nLayoutStartIndex, int nLayoutEndIndex, string sExportFile, string sPageOrientation) : base(nLayoutStartIndex, nLayoutEndIndex) + public PdfSharpExporter(int nLayoutStartIndex, int nLayoutEndIndex, string sExportFile, string sPageOrientation) : + this(Enumerable.Range(nLayoutStartIndex, nLayoutEndIndex - nLayoutStartIndex).ToArray(), sExportFile, sPageOrientation) + { + } + + public PdfSharpExporter(int[] arrayLayoutIndices, string sExportFile, string sPageOrientation) : base(arrayLayoutIndices) { - m_sExportFile = sExportFile; try { @@ -71,16 +76,22 @@ public PdfSharpExporter(int nLayoutStartIndex, int nLayoutEndIndex, string sExpo } catch (Exception) { - Logger.AddLogLine(sPageOrientation + " is an unknow page orientation."); + ProgressReporter.AddIssue(sPageOrientation + " is an unknow page orientation."); } m_zDocument = new PdfDocument(); AddPage(); } - public void ExportThread() + public PdfSharpExporter(int[] arrayLayoutIndices, string sExportFile, PageOrientation ePageOrientation) : base(arrayLayoutIndices) { - var zWait = WaitDialog.Instance; + m_sExportFile = sExportFile; + m_ePageOrientation = ePageOrientation; + m_zDocument = new PdfDocument(); + AddPage(); + } + public override void ExportThread() + { if (File.Exists(m_sExportFile)) { try @@ -89,13 +100,13 @@ public void ExportThread() } catch (Exception) { - Logger.AddLogLine("Failed to delete PDF before export."); + ProgressReporter.AddIssue("Failed to delete PDF before export: {0}".FormatString(m_sExportFile)); } if (File.Exists(m_sExportFile)) { - DisplayError(zWait.Owner); - zWait.CloseWaitDialog(); + DisplayError(); + ProgressReporter.Shutdown(); return; } } @@ -104,18 +115,21 @@ public void ExportThread() Bitmap zBuffer = null; #endif - zWait.ProgressReset(0, 0, ExportLayoutEndIndex - ExportLayoutStartIndex, 0); - for (var nIdx = ExportLayoutStartIndex; nIdx < ExportLayoutEndIndex; nIdx++) + var progressLayoutIdx = ProgressReporter.GetProgressIndex(ProgressName.LAYOUT); + var progressCardIdx = ProgressReporter.GetProgressIndex(ProgressName.CARD); + + ProgressReporter.ProgressReset(progressLayoutIdx, 0, ExportLayoutIndices.Length, 0); + foreach (var nIdx in ExportLayoutIndices) { ChangeExportLayoutIndex(nIdx); if (CurrentDeck.EmptyReference) { // empty reference layouts are not exported - zWait.ProgressStep(0); + ProgressReporter.ProgressStep(progressLayoutIdx); continue; } - zWait.ProgressReset(1, 0, CurrentDeck.CardCount, 0); + ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); var rectCrop = CurrentDeck.CardLayout.getExportCropDefinition(); @@ -201,9 +215,10 @@ public void ExportThread() nNextExportIndex++; - zWait.ProgressStep(1); + ProgressReporter.ProgressStep(progressCardIdx); } - zWait.ProgressStep(0); + ProgressReporter.ProgressSet(progressCardIdx, 0); + ProgressReporter.ProgressStep(progressLayoutIdx); } #if !MONO_BUILD @@ -213,16 +228,15 @@ public void ExportThread() try { m_zDocument.Save(m_sExportFile); - zWait.ThreadSuccess = true; + ProgressReporter.ThreadSuccess = true; } catch (Exception ex) { - Logger.AddLogLine("Error saving PDF (is it open?) " + ex.Message); - DisplayError(zWait.Owner, ex.Message); - zWait.ThreadSuccess = false; + DisplayError(ex.Message); + ProgressReporter.ThreadSuccess = false; } - zWait.CloseWaitDialog(); + ProgressReporter.Shutdown(); } /// @@ -472,12 +486,25 @@ private static Bitmap createExportBuffer(ProjectLayout zLayout, Rectangle rectCr /// /// Shows the read-only error (assumes the file is open in a viewer) /// - private void DisplayError(Form zWaitForm, string extraMessage = "") + private void DisplayError(string extraMessage = "") { - zWaitForm.InvokeAction(() => + var sMsg = "{0}The destination file may be open in a PDF viewer. Please close it before exporting." + .FormatString( + (string.IsNullOrWhiteSpace(extraMessage) + ? "" + : extraMessage + " -- " + )); + if (null != CardMakerInstance.ApplicationForm) { - MessageBox.Show(zWaitForm.Owner, extraMessage + Environment.NewLine + "The destination file may be open in a PDF viewer. Please close it before exporting.", "PDF Write Error", MessageBoxButtons.OK, MessageBoxIcon.Error); - }); + CardMakerInstance.ApplicationForm.InvokeAction(() => + { + MessageBox.Show(CardMakerInstance.ApplicationForm, sMsg, "PDF Write Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + }); + } + else + { + ProgressReporter.AddIssue(sMsg); + } } } } diff --git a/CardMaker/Card/Import/CSVReferenceReader.cs b/CardMaker/Card/Import/CSVReferenceReader.cs index 3b0c24f7..f10fa917 100644 --- a/CardMaker/Card/Import/CSVReferenceReader.cs +++ b/CardMaker/Card/Import/CSVReferenceReader.cs @@ -67,7 +67,7 @@ public void GetData(string sPath, List> listData, bool bLogNotFound if (bLogNotFound) { var sMsg = "CSV File not found: " + sCombinedPath; - Logger.AddLogLine(sMsg); + ProgressReporter.AddIssue(sMsg); IssueManager.Instance.FireAddIssueEvent(sMsg); } return; @@ -96,12 +96,12 @@ public void GetData(string sPath, List> listData, bool bLogNotFound } } - public void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData) + public override void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData) { GetData(ReferencePath, listReferenceData, true, 0); } - public void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) + public override void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) { if (null == ProjectManager.Instance.ProjectFilePath) { @@ -117,14 +117,9 @@ public void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) + public override void GetDefineData(ProjectLayoutReference zReference, List> listDefineData) { GetData(ReferencePath, listDefineData, false, 1, Deck.DEFINES_DATA_POSTFIX); } - - public void FinalizeReferenceLoad() - { - - } } } diff --git a/CardMaker/Card/Import/ExcelReferenceReader.cs b/CardMaker/Card/Import/ExcelReferenceReader.cs index 1cee29e8..5d6b15a8 100644 --- a/CardMaker/Card/Import/ExcelReferenceReader.cs +++ b/CardMaker/Card/Import/ExcelReferenceReader.cs @@ -49,8 +49,6 @@ public ExcelReferenceReader(ProjectLayoutReference zReference) ReferencePath = zReference.RelativePath; } - public void FinalizeReferenceLoad() { } - public void GetData(ExcelSpreadsheetReference zReference, List> listData, bool bRemoveFirstRow, string sNameAppend = "") { var sSpreadsheetName = zReference.SpreadsheetFile; @@ -78,7 +76,7 @@ public void GetData(ExcelSpreadsheetReference zReference, List> lis if (worksheet == null) { - Logger.AddLogLine("Missing sheet from Excel Spreadsheet." + "[" + sSpreadsheetName + "," + sSheetName + "]"); + ProgressReporter.AddIssue("Missing sheet from Excel Spreadsheet." + "[" + sSpreadsheetName + "," + sSheetName + "]"); return; } @@ -103,7 +101,7 @@ public void GetData(ExcelSpreadsheetReference zReference, List> lis if (listExcelData.Count == 0) { - Logger.AddLogLine("Failed to load any data from Excel Spreadsheet." + "[" + sSpreadsheetName + "," + sSheetName + "]"); + ProgressReporter.AddIssue("Failed to load any data from Excel Spreadsheet." + "[" + sSpreadsheetName + "," + sSheetName + "]"); } else { @@ -116,12 +114,12 @@ public void GetData(ExcelSpreadsheetReference zReference, List> lis } } - public void GetDefineData(ProjectLayoutReference zReference, List> listDefineData) + public override void GetDefineData(ProjectLayoutReference zReference, List> listDefineData) { GetData(ExcelSpreadsheetReference.parse(ReferencePath), listDefineData, true, Deck.DEFINES_DATA_POSTFIX); } - public void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) + public override void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) { if (null == ProjectManager.Instance.ProjectFilePath) { @@ -133,7 +131,7 @@ public void GetProjectDefineData(ProjectLayoutReference zReference, List> listReferenceData) + public override void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData) { GetData(ExcelSpreadsheetReference.parse(ReferencePath), listReferenceData, false); } diff --git a/CardMaker/Card/Import/GoogleReferenceReader.cs b/CardMaker/Card/Import/GoogleReferenceReader.cs index d1644bc6..6ebe87d3 100644 --- a/CardMaker/Card/Import/GoogleReferenceReader.cs +++ b/CardMaker/Card/Import/GoogleReferenceReader.cs @@ -101,7 +101,7 @@ private void LoadCache() } else { - Logger.AddLogLine("Failed to read cache file: {0}".FormatString(sLocalCacheFile)); + ProgressReporter.AddIssue("Failed to read cache file: {0}".FormatString(sLocalCacheFile)); } } @@ -118,7 +118,7 @@ public void GetData(GoogleSpreadsheetReference zReference, List> li List> listCacheData; if (!CardMakerInstance.ForceDataCacheRefresh && m_dictionaryDataCache.TryGetValue(sCacheKey, out listCacheData)) { - Logger.AddLogLine("Loading {0} from local cache".FormatString(sCacheKey)); + ProgressReporter.AddIssue("Loading {0} from local cache".FormatString(sCacheKey)); listData.AddRange(listCacheData); return; } @@ -134,7 +134,7 @@ public void GetData(GoogleSpreadsheetReference zReference, List> li var zGoogleSpreadsheet = new GoogleSpreadsheet(CardMakerInstance.GoogleInitializerFactory); if (string.IsNullOrWhiteSpace(zReference.SpreadsheetId)) { - Logger.AddLogLine("WARNING: The reference {0}.{1} is missing the Spreadsheet ID. Please reconfigure this reference." + ProgressReporter.AddIssue("WARNING: The reference {0}.{1} is missing the Spreadsheet ID. Please reconfigure this reference." .FormatString(zReference.SpreadsheetName, zReference.SheetName)); listGoogleData = zGoogleSpreadsheet.GetSheetContentsBySpreadsheetName(sSpreadsheetName, sSheetName); } @@ -145,17 +145,17 @@ public void GetData(GoogleSpreadsheetReference zReference, List> li } catch (GoogleApiException e) { - Logger.AddLogLine("Google Spreadsheet access exception: " + e.Message); + ProgressReporter.AddIssue("Google Spreadsheet access exception: " + e.Message); bAuthorizationError = GoogleApi.IsAuthorizationError(e); } catch (Exception e) { - Logger.AddLogLine("General exception: " + e.Message); + ProgressReporter.AddIssue("General exception: " + e.Message); listGoogleData = null; } if (null == listGoogleData) { - Logger.AddLogLine("Failed to load any data from Google Spreadsheet." + "[" + sSpreadsheetName + "," + sSheetName + "]" + (bAuthorizationError ? " Google reported a problem with your credentials." : String.Empty)); + ProgressReporter.AddIssue("Failed to load any data from Google Spreadsheet." + "[" + sSpreadsheetName + "," + sSheetName + "]" + (bAuthorizationError ? " Google reported a problem with your credentials." : String.Empty)); } else { @@ -174,12 +174,12 @@ public void GetData(GoogleSpreadsheetReference zReference, List> li } } - public void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData) + public override void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData) { GetData(GoogleSpreadsheetReference.parse(ReferencePath), listReferenceData, false); } - public void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) + public override void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) { if (null == ProjectManager.Instance.ProjectFilePath) { @@ -189,7 +189,7 @@ public void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData) + public override void GetDefineData(ProjectLayoutReference zReference, List> listDefineData) { GetData(GoogleSpreadsheetReference.parse(ReferencePath), listDefineData, true, Deck.DEFINES_DATA_POSTFIX); } @@ -210,7 +210,7 @@ private string GetCacheKey(string sReference, string sNameAppend = "") return sReference + "::" + sNameAppend; } - public void FinalizeReferenceLoad() + public override void FinalizeReferenceLoad() { if (!m_bCacheUpdated || !CardMakerSettings.EnableGoogleCache) { @@ -233,7 +233,7 @@ public void FinalizeReferenceLoad() listCacheItems, CardMakerConstants.XML_ENCODING)) { - Logger.AddLogLine("Failed to write cache file: {0}".FormatString(sLocalCacheFile)); + ProgressReporter.AddIssue("Failed to write cache file: {0}".FormatString(sLocalCacheFile)); } } } diff --git a/CardMaker/Card/Import/ReferenceReader.cs b/CardMaker/Card/Import/ReferenceReader.cs index 6b3370c6..133fdd1a 100644 --- a/CardMaker/Card/Import/ReferenceReader.cs +++ b/CardMaker/Card/Import/ReferenceReader.cs @@ -24,20 +24,25 @@ using System.Collections.Generic; using CardMaker.XML; +using Support.Progress; namespace CardMaker.Card.Import { - public interface ReferenceReader + public abstract class ReferenceReader { - string ReferencePath { get; } + public string ReferencePath { get; } + public IProgressReporter ProgressReporter { get; set; } - void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData); - void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData); - void GetDefineData(ProjectLayoutReference zReference, List> listDefineData); + public abstract void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData); + public abstract void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData); + public abstract void GetDefineData(ProjectLayoutReference zReference, List> listDefineData); /// /// Called to signify that all references have been loaded /// - void FinalizeReferenceLoad(); + public virtual void FinalizeReferenceLoad() + { + + } } } diff --git a/CardMaker/Card/Import/ReferenceReaderFactory.cs b/CardMaker/Card/Import/ReferenceReaderFactory.cs index 225ed547..e059271e 100644 --- a/CardMaker/Card/Import/ReferenceReaderFactory.cs +++ b/CardMaker/Card/Import/ReferenceReaderFactory.cs @@ -24,42 +24,61 @@ using CardMaker.Data; using CardMaker.XML; +using Support.Progress; namespace CardMaker.Card.Import { public static class ReferenceReaderFactory - { - public static ReferenceReader GetReader(ProjectLayoutReference zReference) + { +#warning unify these lookups in both methods... static type dictionary or something... this is bleh + public static ReferenceReader GetReader(ProjectLayoutReference zReference, IProgressReporter zProgressReporter) { if (zReference == null) { return null; } + + ReferenceReader zReader = null; + if (zReference.RelativePath.StartsWith(GoogleSpreadsheetReference.GOOGLE_REFERENCE + GoogleSpreadsheetReference.GOOGLE_REFERENCE_SPLIT_CHAR)) { - var zReader = new GoogleReferenceReader(zReference); - return CardMakerInstance.GoogleCredentialsInvalid ? null : zReader; + zReader = new GoogleReferenceReader(zReference); + } + if (zReference.RelativePath.StartsWith(ExcelSpreadsheetReference.EXCEL_REFERENCE + + ExcelSpreadsheetReference.EXCEL_REFERENCE_SPLIT_CHAR)) + { + zReader = new ExcelReferenceReader(zReference); } - if (zReference.RelativePath.StartsWith(ExcelSpreadsheetReference.EXCEL_REFERENCE + - ExcelSpreadsheetReference.EXCEL_REFERENCE_SPLIT_CHAR)) - { - return new ExcelReferenceReader(zReference); + if (zReader == null) + { + zReader = new CSVReferenceReader(zReference); } - return new CSVReferenceReader(zReference); + + zReader.ProgressReporter = zProgressReporter; + return zReader; } - public static ReferenceReader GetDefineReader(ReferenceType eReferenceType) + public static ReferenceReader GetDefineReader(ReferenceType eReferenceType, IProgressReporter zProgressReporter) { + ReferenceReader zReferenceReader = null; switch (eReferenceType) { case ReferenceType.CSV: - return new CSVReferenceReader(); + zReferenceReader = new CSVReferenceReader(); + break; case ReferenceType.Google: - return new GoogleReferenceReader(); + zReferenceReader = new GoogleReferenceReader(); + break; case ReferenceType.Excel: - return new ExcelReferenceReader(); + zReferenceReader = new ExcelReferenceReader(); + break; + } + + if (zReferenceReader == null) + { + zReferenceReader.ProgressReporter = zProgressReporter; } return null; } diff --git a/CardMaker/Card/Translation/InceptTranslator.cs b/CardMaker/Card/Translation/InceptTranslator.cs index 82d3e581..95347299 100644 --- a/CardMaker/Card/Translation/InceptTranslator.cs +++ b/CardMaker/Card/Translation/InceptTranslator.cs @@ -458,7 +458,7 @@ private static string TranslateMatch(Match zMatch, ProjectLayoutElement zElement private static void LogTranslation(ProjectLayoutElement zElement, string sOut) { var sLog = "Translate[{0}] {1}".FormatString(zElement.name, sOut); -#if DEBUG +#if DEBUG && FALSE System.Diagnostics.Debug.WriteLine(sLog); #else if (CardMakerSettings.LogInceptTranslation) diff --git a/CardMaker/CardMaker.csproj b/CardMaker/CardMaker.csproj index 95a9e404..3f1b8480 100644 --- a/CardMaker/CardMaker.csproj +++ b/CardMaker/CardMaker.csproj @@ -6,7 +6,7 @@ 9.0.21022 2.0 {49AB3FC5-596A-4B33-963C-C16E1862AF16} - WinExe + Exe Properties CardMaker CardMaker @@ -164,6 +164,12 @@ + + + + + + @@ -197,7 +203,6 @@ - @@ -362,6 +367,12 @@ + + + + + + Form @@ -387,6 +398,7 @@ Form + diff --git a/CardMaker/CardMakerBuild.cs b/CardMaker/CardMakerBuild.cs index 1062e210..bb4f5a3b 100644 --- a/CardMaker/CardMakerBuild.cs +++ b/CardMaker/CardMakerBuild.cs @@ -31,7 +31,7 @@ public static class CardMakerBuild public static string GetBuildSuffix() { #if UNSTABLE - return "[UNSTABLE] V.A10"; + return "[UNSTABLE] V.A11"; #else return string.Empty; #endif diff --git a/CardMaker/CardMaker_Mono.csproj b/CardMaker/CardMaker_Mono.csproj index c8138f76..6a37ad52 100644 --- a/CardMaker/CardMaker_Mono.csproj +++ b/CardMaker/CardMaker_Mono.csproj @@ -102,6 +102,7 @@ ..\packages\log4net.2.0.3\lib\net40-full\log4net.dll + ..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll @@ -151,6 +152,7 @@ + ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll @@ -162,6 +164,12 @@ + + + + + + @@ -195,7 +203,6 @@ - @@ -275,7 +282,9 @@ Form - + + ExcelSheetSelectionDialog.cs + @@ -358,6 +367,12 @@ + + + + + + Form @@ -383,6 +398,7 @@ Form + @@ -397,7 +413,9 @@ Designer CardMakerMDI.cs - + + ExcelSheetSelectionDialog.cs + GoogleCredentialsDialog.cs @@ -449,7 +467,9 @@ RGBColorSelectDialog.cs - + + Designer + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/CardMaker/Data/CardMakerConstants.cs b/CardMaker/Data/CardMakerConstants.cs index 66f8a4ab..d9c2c88b 100644 --- a/CardMaker/Data/CardMakerConstants.cs +++ b/CardMaker/Data/CardMakerConstants.cs @@ -46,4 +46,11 @@ public static class CardMakerConstants {SheetsService.Scope.SpreadsheetsReadonly, DriveService.Scope.DriveReadonly}; } + + public static class ProgressName + { + public const string REFERENCE_DATA = "Reference Data"; + public const string LAYOUT = "Layout"; + public const string CARD = "Card"; + } } diff --git a/CardMaker/Data/CardMakerInstance.cs b/CardMaker/Data/CardMakerInstance.cs index 37762471..64b88bcc 100644 --- a/CardMaker/Data/CardMakerInstance.cs +++ b/CardMaker/Data/CardMakerInstance.cs @@ -27,6 +27,7 @@ using System.IO; using System.Windows.Forms; using Support.Google; +using Support.Progress; namespace CardMaker.Data { @@ -99,6 +100,11 @@ public static string GoogleAccessToken /// public static GoogleInitializerFactory GoogleInitializerFactory { get; set; } + /// + /// General ProgressReporterFactory + /// + public static ProgressReporterFactory ProgressReporterFactory { get; set; } + /// /// The project file indicated on the command line (first argument) /// @@ -149,6 +155,7 @@ static CardMakerInstance() GoogleCredentialsInvalid = false; GoogleInitializerFactory = new GoogleInitializerFactory(CardMakerConstants.APPLICATION_NAME, CardMakerConstants.GOOGLE_CLIENT_ID, CardMakerConstants.GOOGLE_SCOPES); GoogleAccessToken = null; + ProgressReporterFactory = new WaitDialogProgressReporterFactory(); ProcessingUserAction = false; Random = new Random(); } diff --git a/CardMaker/Events/Managers/GoogleAuthManager.cs b/CardMaker/Events/Managers/GoogleAuthManager.cs index b92b68a5..b3f59d1e 100644 --- a/CardMaker/Events/Managers/GoogleAuthManager.cs +++ b/CardMaker/Events/Managers/GoogleAuthManager.cs @@ -102,7 +102,6 @@ public static void UpdateGoogleAuth(Form parentForm, Action zSuccessAction = nul { case DialogResult.OK: CardMakerInstance.GoogleAccessToken = zDialog.GoogleAccessToken; - Logger.AddLogLine("Updated Google Credentials"); zSuccessAction?.Invoke(); break; default: diff --git a/CardMaker/Events/Managers/LayoutManager.cs b/CardMaker/Events/Managers/LayoutManager.cs index 2fe3e4c2..eb447550 100644 --- a/CardMaker/Events/Managers/LayoutManager.cs +++ b/CardMaker/Events/Managers/LayoutManager.cs @@ -172,7 +172,7 @@ public void InitializeActiveLayout() { ActiveDeck = new Deck(); - ActiveDeck.SetAndLoadLayout(ActiveLayout, false); + ActiveDeck.SetAndLoadLayout(ActiveLayout, false, null); } LayoutLoaded?.Invoke(this, new LayoutEventArgs(ActiveLayout, ActiveDeck)); diff --git a/CardMaker/Forms/CardMakerMDI.cs b/CardMaker/Forms/CardMakerMDI.cs index 2da34d9b..ffc8e029 100644 --- a/CardMaker/Forms/CardMakerMDI.cs +++ b/CardMaker/Forms/CardMakerMDI.cs @@ -31,9 +31,9 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Windows.Forms; using CardMaker.Card.Export; -using CardMaker.Card.Shapes; using CardMaker.Card.Translation; using CardMaker.Data; using CardMaker.Events.Args; @@ -42,6 +42,7 @@ using CardMaker.XML; using PdfSharp; using Support.IO; +using Support.Progress; using Support.UI; using LayoutEventArgs = CardMaker.Events.Args.LayoutEventArgs; @@ -82,9 +83,6 @@ private void CardMakerMDI_Load(object sender, EventArgs e) // logger should be available before the other dialogs var zLoggerForm = SetupMDIForm(new MDILogger(), true); - // always before any dialogs - ShapeManager.Init(); - ProjectManager.Instance.ProjectOpened += Project_Opened; ProjectManager.Instance.ProjectUpdated += Project_Updated; @@ -107,7 +105,6 @@ private void CardMakerMDI_Load(object sender, EventArgs e) SetupMDIForm(new MDIIssues(), false); SetupMDIForm(new MDIDefines(), false); - // populate the windows menu foreach (var zChild in MdiChildren) { @@ -208,19 +205,6 @@ private void CardMakerMDI_Load(object sender, EventArgs e) } LayoutTemplateManager.Instance.LoadLayoutTemplates(CardMakerInstance.StartupPath); - RestoreReplacementChars(); - - var zGraphics = CreateGraphics(); - try - { - CardMakerInstance.ApplicationDPI = zGraphics.DpiX; - } - finally - { - zGraphics.Dispose(); - } - - // load the specified project from the command line if (!string.IsNullOrEmpty(CardMakerInstance.CommandLineProjectFile)) { @@ -814,15 +798,13 @@ private void ExportViaPDFSharp(bool bExportAllLayouts) } var zFileCardExporter = new PdfSharpExporter(nStartLayoutIdx, nEndLayoutIdx, m_sPdfExportLastFile, zQuery.GetString(ORIENTATION)); - - var zWait = new WaitDialog( - 2, - zFileCardExporter.ExportThread, + var zWait = CardMakerInstance.ProgressReporterFactory.CreateReporter( "Export", - new string[] { "Layout", "Card" }, - 450); + new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA, ProgressName.CARD }, + zFileCardExporter.ExportThread); #if true - zWait.ShowDialog(this); + zFileCardExporter.ProgressReporter = zWait; + zWait.StartProcessing(this); #else zFileCardExporter.ExportThread(); #endif @@ -835,7 +817,7 @@ private void ExportViaPDFSharp(bool bExportAllLayouts) } } - private void ExportImages(ICardExporter zFileCardExporter) + private void ExportImages(CardExportBase zFileCardExporter) { if (null == zFileCardExporter) { @@ -843,21 +825,19 @@ private void ExportImages(ICardExporter zFileCardExporter) } #if true - var zWait = new WaitDialog( - 2, - zFileCardExporter.ExportThread, + var zWait = CardMakerInstance.ProgressReporterFactory.CreateReporter( "Export", - new string[] { "Layout", "Card" }, - 450); - zWait.ShowDialog(this); + new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA, ProgressName.CARD }, + zFileCardExporter.ExportThread); + zFileCardExporter.ProgressReporter = zWait; + zWait.StartProcessing(this); #else // non threaded zFileCardExporter.ExportThread(); #endif } - - - private void RestoreReplacementChars() +#warning move to a more central location + public static void RestoreReplacementChars() { string[] arrayReplacementChars = CardMakerSettings.IniManager.GetValue(IniSettings.ReplacementChars, string.Empty).Split(new char[] { CardMakerConstants.CHAR_FILE_SPLIT }); if (arrayReplacementChars.Length == FilenameTranslator.DISALLOWED_FILE_CHARS_ARRAY.Length) diff --git a/CardMaker/Forms/MDIIssues.cs b/CardMaker/Forms/MDIIssues.cs index 77c92e93..39a8522f 100644 --- a/CardMaker/Forms/MDIIssues.cs +++ b/CardMaker/Forms/MDIIssues.cs @@ -27,6 +27,7 @@ using System.Globalization; using System.Windows.Forms; using CardMaker.Card.Export; +using CardMaker.Data; using CardMaker.Events.Args; using CardMaker.Events.Managers; using Support.UI; @@ -57,13 +58,13 @@ void Refresh_Requested(object sender, IssueRefreshEventArgs args) ClearIssues(); m_bTrackIssues = true; - var zWait = new WaitDialog( - 2, - new CompilerCardExporter(0, ProjectManager.Instance.LoadedProject.Layout.Length).ExportThread, + var compilerExporter = new CompilerCardExporter(0, ProjectManager.Instance.LoadedProject.Layout.Length); + var progressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( "Compile", - new string[] { "Layout", "Card" }, - 450); - zWait.ShowDialog(ParentForm); + new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA, ProgressName.CARD }, + compilerExporter.ExportThread); + compilerExporter.ProgressReporter = progressReporter; + progressReporter.StartProcessing(ParentForm); m_bTrackIssues = false; Show(); diff --git a/CardMaker/Forms/MDILogger.cs b/CardMaker/Forms/MDILogger.cs index a656ba90..80a27cc7 100644 --- a/CardMaker/Forms/MDILogger.cs +++ b/CardMaker/Forms/MDILogger.cs @@ -30,7 +30,7 @@ namespace CardMaker.Forms { - public partial class MDILogger : Form, LoggerI + public partial class MDILogger : Form, ILogger { public MDILogger() { @@ -80,7 +80,7 @@ private void clearToolStripMenuItem_Click(object sender, EventArgs e) #endregion - #region LoggerI + #region ILogger public void AddLogLines(string[] arrayLines) { diff --git a/CardMaker/Forms/ProjectManagerUI.cs b/CardMaker/Forms/ProjectManagerUI.cs index 627b5a37..231a0e5a 100644 --- a/CardMaker/Forms/ProjectManagerUI.cs +++ b/CardMaker/Forms/ProjectManagerUI.cs @@ -31,12 +31,15 @@ using CardMaker.Events.Managers; using CardMaker.XML; using Support.IO; +using Support.Progress; using Support.UI; namespace CardMaker.Forms { public partial class ProjectManagerUI : Form { + private IProgressReporter m_zProgressReporter; + public ProjectManagerUI() { InitializeComponent(); @@ -84,8 +87,8 @@ private void UpdateProjects() { if (Directory.Exists(txtFolder.Text)) { - var zWait = new WaitDialog(0, UpdateThread, "Scanning Directory", new string[] { string.Empty }, 300); - zWait.ShowDialog(this); + m_zProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter("Scanning Directory", new string[] { string.Empty }, UpdateThread); + m_zProgressReporter.StartProcessing(this); } } @@ -94,7 +97,7 @@ private void UpdateProjects() /// private void UpdateThread() { - WaitDialog.Instance.SetStatusText("Scanning for Projects..."); + m_zProgressReporter.SetStatusText("Scanning for Projects..."); var arrayProjects = Directory.GetFiles(txtFolder.Text, "*.cmp", SearchOption.AllDirectories); foreach (string sProject in arrayProjects) { @@ -114,8 +117,8 @@ private void UpdateThread() listViewProjects.InvokeAction(() => listViewProjects.Items.Add(zItem)); } } - WaitDialog.Instance.ThreadSuccess = true; - WaitDialog.Instance.CloseWaitDialog(); + m_zProgressReporter.ThreadSuccess = true; + m_zProgressReporter.Shutdown(); } } } diff --git a/CardMaker/Program.cs b/CardMaker/Program.cs index f3934cf2..0abacef2 100644 --- a/CardMaker/Program.cs +++ b/CardMaker/Program.cs @@ -23,10 +23,14 @@ //////////////////////////////////////////////////////////////////////////////// using System; -using System.IO; using System.Windows.Forms; +using CardMaker.Card.CommandLine; +using CardMaker.Card.Shapes; +using CardMaker.Card.Translation; using CardMaker.Data; using CardMaker.Forms; +using Support.IO; +using Support.Util; namespace CardMaker { @@ -40,16 +44,33 @@ static void Main(string[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - // load the project file if it is specified as the first argument - if (null != args && 0 < args.Length) + + Initialize(); + var commandLineProcessor = new CommandLineProcessor(new CommandLineParser().Parse(args)); + if (!commandLineProcessor.Process()) + { + Application.Run(new CardMakerMDI()); + } + } + + /// + /// Cross application initialization of components. + /// + static void Initialize() + { + ShapeManager.Init(); + CardMakerMDI.RestoreReplacementChars(); + + var zForm = new Form(); + var zGraphics = zForm.CreateGraphics(); + try + { + CardMakerInstance.ApplicationDPI = zGraphics.DpiX; + } + finally { - string sFullPath = Path.GetFullPath(args[0]); - if (File.Exists(sFullPath)) - { - CardMakerInstance.CommandLineProjectFile = sFullPath; - } + zGraphics.Dispose(); } - Application.Run(new CardMakerMDI()); } } } \ No newline at end of file diff --git a/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs b/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs index a81484aa..ffd28b12 100644 --- a/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs +++ b/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs @@ -26,7 +26,9 @@ using System.Collections.Generic; using System.Threading; using System.Windows.Forms; +using CardMaker.Data; using Support.IO; +using Support.Progress; using Support.UI; namespace Support.Google.Sheets @@ -35,6 +37,7 @@ public partial class GoogleSpreadsheetBrowser : Form { private readonly bool m_bRequireSheetSelect; + private IProgressReporter m_zProgressReporter; private List m_listGoogleSheets; private GoogleSpreadsheet m_zGoogleSpreadsheet; public GoogleSheetInfo SelectedSpreadsheet => listViewSpreadsheets.SelectedItems.Count == 0 ? null : (GoogleSheetInfo)listViewSpreadsheets.SelectedItems[0].Tag; @@ -73,43 +76,44 @@ private void txtFilter_TextChanged(object sender, EventArgs e) private void GoogleSpreadsheetBrowser_Load(object sender, EventArgs e) { - var zWait = new WaitDialog(1, - () => - { - var listGoogleSheets = PerformSpreadsheetRetrieve( - () => m_zGoogleSpreadsheet.GetSpreadsheetList(), - () => listViewSpreadsheets.InvokeAction(() => listViewSpreadsheets.Clear())); + m_zProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( + "Getting Google Spreadsheets...", + new string[] {""}, + PerformSheetLookup); + m_zProgressReporter.StartProcessing(this); + } - if (null == listGoogleSheets) - { - this.InvokeAction( - () => MessageBox.Show(this, "Failed to access Google Spreadsheets", "Access Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)); - this.InvokeAction(Close); - WaitDialog.Instance.CloseWaitDialog(); - return; - } + protected void PerformSheetLookup() + { + var listGoogleSheets = PerformSpreadsheetRetrieve( + () => m_zGoogleSpreadsheet.GetSpreadsheetList(), + () => listViewSpreadsheets.InvokeAction(() => listViewSpreadsheets.Clear())); - m_listGoogleSheets = listGoogleSheets; - var listNewItems = new List(); - foreach (var entry in listGoogleSheets) - { - var zLvi = new ListViewItem(entry.Name) - { - Tag = entry - }; - listNewItems.Add(zLvi); - } - listViewSpreadsheets.InvokeAction(() => - { - listViewSpreadsheets.Items.AddRange(listNewItems.ToArray()); - }); + if (null == listGoogleSheets) + { + this.InvokeAction( + () => MessageBox.Show(this, "Failed to access Google Spreadsheets", "Access Failed", MessageBoxButtons.OK, MessageBoxIcon.Error)); + this.InvokeAction(Close); + m_zProgressReporter.Shutdown(); + return; + } - WaitDialog.Instance.CloseWaitDialog(); - }, - "Getting Google Spreadsheets...", - null, - 400); - zWait.ShowDialog(this); + m_listGoogleSheets = listGoogleSheets; + var listNewItems = new List(); + foreach (var entry in listGoogleSheets) + { + var zLvi = new ListViewItem(entry.Name) + { + Tag = entry + }; + listNewItems.Add(zLvi); + } + listViewSpreadsheets.InvokeAction(() => + { + listViewSpreadsheets.Items.AddRange(listNewItems.ToArray()); + }); + + m_zProgressReporter.Shutdown(); } private void listViewSpreadsheets_Resize(object sender, EventArgs e) diff --git a/CardMaker/Support/IO/Logger.cs b/CardMaker/Support/IO/Logger.cs index 76400516..421cfb3d 100644 --- a/CardMaker/Support/IO/Logger.cs +++ b/CardMaker/Support/IO/Logger.cs @@ -28,7 +28,7 @@ namespace Support.IO { - public interface LoggerI + public interface ILogger { void AddLogLines(string[] arrayLines); void ClearLog(); @@ -36,7 +36,7 @@ public interface LoggerI public static class Logger { - private static LoggerI s_iLogger; + private static ILogger s_iLogger; private static readonly string s_sLogFile = Application.StartupPath + Path.DirectorySeparatorChar + Path.GetFileNameWithoutExtension(Application.ExecutablePath) + ".log"; private static bool m_bLogToFile; @@ -47,9 +47,9 @@ public static class Logger /// /// The logger must be initialized through this method. /// - /// An object implementing the LoggerI interface. + /// An object implementing the ILogger interface. /// Flag indicating whether to log the output or not. - public static void InitLogger(LoggerI iLogger, bool bLogToFile) + public static void InitLogger(ILogger iLogger, bool bLogToFile) { s_iLogger = iLogger; m_bLogToFile = bLogToFile; diff --git a/CardMaker/Support/Progress/ConsoleProgressReporter.cs b/CardMaker/Support/Progress/ConsoleProgressReporter.cs new file mode 100644 index 00000000..a30ec4a7 --- /dev/null +++ b/CardMaker/Support/Progress/ConsoleProgressReporter.cs @@ -0,0 +1,202 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Collections.Generic; +using System.Threading; + +namespace Support.Progress +{ + /// + /// Command Line progress reporter (console based wait dialog) + /// + class ConsoleProgressReporter : IProgressReporter + { + private const int PROGRESS_WIDTH = 20; + private readonly ThreadStart m_zThreadStart; + private readonly ParameterizedThreadStart m_zParameterizedThreadStart; + private readonly object m_zParamObject; + private readonly string m_sTitle; + private List m_listProgressLines; + private List m_listIssues = new List(); + private Dictionary m_dictionaryProgressIndex = new Dictionary(); + private bool m_bRendered = false; + private int m_nConsoleRenderLine; + + public ConsoleProgressReporter(string sTitle, string[] arrayDescriptions, ThreadStart zThreadStart) + { + m_sTitle = sTitle; + m_zThreadStart = zThreadStart; + InitializeProgressLines(arrayDescriptions); + } + + public ConsoleProgressReporter(string sTitle, string[] arrayDescriptions, ParameterizedThreadStart zThreadStart, object zParamObject) + { + m_sTitle = sTitle; + m_zParameterizedThreadStart = zThreadStart; + m_zParamObject = zParamObject; + InitializeProgressLines(arrayDescriptions); + } + + public bool ThreadSuccess { get; set; } + + public bool Canceled { get; set; } + + public bool CancelButtonVisible { get; set; } + + public int GetProgressCount() + { + return m_listProgressLines.Count; + } + + public int GetProgressIndex(string sProgressName) + { + int nIdx; + return m_dictionaryProgressIndex.TryGetValue(sProgressName, out nIdx) ? nIdx : -1; + } + + public void SetStatusText(string sText) + { + Console.WriteLine(sText); + } + + public void ProgressReset(int nProgressBar, int nMin, int nMax, int nStartVal) + { + m_listProgressLines[nProgressBar].Min = nMin; + m_listProgressLines[nProgressBar].Max = nMax; + m_listProgressLines[nProgressBar].Value = nStartVal; + Render(); + } + + public void ProgressSet(int nProgressBar, int nValue) + { + m_listProgressLines[nProgressBar].Value = nValue; + Render(); + } + + public void ProgressStep(int nProgressBar) + { + m_listProgressLines[nProgressBar].Value = Math.Min(m_listProgressLines[nProgressBar].Max, m_listProgressLines[nProgressBar].Value + 1); + Render(); + } + + public int ProgressGet(int nProgressBar) + { + return m_listProgressLines[nProgressBar].Value; + } + + public void StartProcessing(object initializationObject) + { + if (m_zThreadStart != null) + { + m_zThreadStart(); + } + else if (m_zParameterizedThreadStart != null) + { + m_zParameterizedThreadStart(m_zParamObject); + } + } + + public void AddIssue(string sIssue) + { + m_listIssues.Add(sIssue); + } + + public void Shutdown() + { + if (m_listIssues.Count > 0) + { + Console.WriteLine("Issues:"); + m_listIssues.ForEach(i => Console.WriteLine(i)); + } + } + + /// + /// Initializes the ProgressLine objects based on the passed in array of descriptions + /// + /// The descriptions to apply to each line + private void InitializeProgressLines(string[] arrayDescriptions) + { + m_listProgressLines = new List(arrayDescriptions.Length); + for(var nIdx = 0; nIdx< arrayDescriptions.Length; nIdx++) + { + m_dictionaryProgressIndex[arrayDescriptions[nIdx]] = nIdx; + m_listProgressLines.Add(new ProgressLine(arrayDescriptions[nIdx])); + } + } + + /// + /// Renders the current state of the reporter (has to jump the cursor around the console) + /// + private void Render() + { + if (m_bRendered) + { + // clear all the lines starting with the render point + for (var nConsoleLine = m_nConsoleRenderLine; nConsoleLine < m_listProgressLines.Count + 1; nConsoleLine++) + { + Console.SetCursorPosition(0, nConsoleLine); + Console.Write("".PadRight(Console.WindowWidth)); + } + Console.SetCursorPosition(0, m_nConsoleRenderLine); + } + else + { + m_nConsoleRenderLine = Console.CursorTop; + m_bRendered = true; + } + //Thread.Sleep(500); + Console.WriteLine(m_sTitle.PadRight(Console.WindowWidth, ' ')); + m_listProgressLines.ForEach(zLine => + { + var nScaledValue = (int)((((float)zLine.Value - (float)zLine.Min) / (float)zLine.Max) * (float)PROGRESS_WIDTH); + Console.WriteLine("[" + ("".PadRight(nScaledValue, '+')).PadRight(PROGRESS_WIDTH, ' ') + "] " + zLine.Description); + }); + } + } + + /// + /// Tracks the state of an individual sub progress status + /// + internal class ProgressLine + { + public string Description { get; set; } + public int Min { get; set; } + public int Max { get; set; } + public int Value { get; set; } + + public ProgressLine(string sDescription) : this(sDescription, 0, 100, 0) + { + + } + + public ProgressLine(string sDescription, int nMin, int nMax, int nInitialValue) + { + Description = sDescription; + Min = nMin; + Max = nMax; + Value = nInitialValue; + } + } +} diff --git a/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs b/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs new file mode 100644 index 00000000..db68910a --- /dev/null +++ b/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs @@ -0,0 +1,42 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System.Threading; + +namespace Support.Progress +{ + public class ConsoleProgressReporterFactory : ProgressReporterFactory + { + public IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, ThreadStart zThreadStart) + { + return new ConsoleProgressReporter(sTitle, arrayDescriptions, zThreadStart); + } + + public IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, + ParameterizedThreadStart zThreadStart, object zParamObject) + { + return new ConsoleProgressReporter(sTitle, arrayDescriptions, zThreadStart, zParamObject); + } + } +} diff --git a/CardMaker/Support/Progress/IProgressReporter.cs b/CardMaker/Support/Progress/IProgressReporter.cs new file mode 100644 index 00000000..c4013d02 --- /dev/null +++ b/CardMaker/Support/Progress/IProgressReporter.cs @@ -0,0 +1,109 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +namespace Support.Progress +{ + public interface IProgressReporter + { + /// + /// Flag indicating the success/failure of the associated thread. + /// + bool ThreadSuccess { get; set; } + + /// + /// Flag indicating the cancel state of the reporter + /// + bool Canceled { get; set; } + + /// + /// Controls the visibility of the cancel button + /// + bool CancelButtonVisible { get; set; } + + /// + /// Gets the number of progress sub statuses + /// + /// + int GetProgressCount(); + + /// + /// Gets the index of the given progress + /// + /// The name to lookup + /// The index or -1 if not found + int GetProgressIndex(string sProgressName); + + /// + /// Sets the status text + /// + /// + void SetStatusText(string sText); + + /// + /// Resets the specified progress bar. + /// + /// The progress bar to reset (0 based) + /// The minimum value to set on the progress bar + /// The maximum value to set on the progress bar + /// The starting value to set on the progress bar + void ProgressReset(int nProgressBar, int nMin, int nMax, int nStartVal); + + /// + /// Sets the value on the specified progress bar. + /// + /// The progress bar to set (0 based) + /// The value to set + void ProgressSet(int nProgressBar, int nValue); + + /// + /// Steps the value on the specified progress bar. + /// + /// The progress bar to step (0 based) + void ProgressStep(int nProgressBar); + + /// + /// Gets the value of the specified progress bar. + /// + /// The progress bar to get (0 based) + /// + int ProgressGet(int nProgressBar); + + /// + /// Initiates the underlying processing + /// + /// The object to pass to the underlying reporter + void StartProcessing(object initializationObject); + + /// + /// Adds an issue for the reporter to process as necessary. + /// + /// + void AddIssue(string sIssue); + + /// + /// Shuts down the reporter as necessary. + /// + void Shutdown(); + } +} diff --git a/CardMaker/Support/Progress/ProgressReporterFactory.cs b/CardMaker/Support/Progress/ProgressReporterFactory.cs new file mode 100644 index 00000000..62605fb7 --- /dev/null +++ b/CardMaker/Support/Progress/ProgressReporterFactory.cs @@ -0,0 +1,50 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System.Threading; + +namespace Support.Progress +{ + public interface ProgressReporterFactory + { + /// + /// Creates a progress reporter. + /// + /// The title of the process to report + /// Descriptions of the sub statuses + /// The thread entry point to execute + /// The progress reporter + IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, ThreadStart zThreadStart); + + /// + /// Creates a progress reporter. + /// + /// The title of the process to report + /// Descriptions of the sub statuses + /// The thread entry point to execute + /// The parameter to pass into the thread for execution + /// The progress reporter + IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, ParameterizedThreadStart zThreadStart, object zParamObject); + } +} diff --git a/CardMaker/Support/Progress/ProgressReporterProxy.cs b/CardMaker/Support/Progress/ProgressReporterProxy.cs new file mode 100644 index 00000000..cd63c891 --- /dev/null +++ b/CardMaker/Support/Progress/ProgressReporterProxy.cs @@ -0,0 +1,63 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +namespace Support.Progress +{ + /// + /// Wrapper for a ProgressReporter narrowed to a single Progress Index. + /// Allows for nested ProgressReporting + /// + public class ProgressReporterProxy + { + public int ProgressIndex { get; set; } + public IProgressReporter ProgressReporter { get; set; } + public bool ProxyOwnsReporter { get; set; } + + public void ProgressReset(int nMin, int nMax, int nStartVal) + { + ProgressReporter.ProgressReset(ProgressIndex, nMin, nMax, nStartVal); + } + + public void AddIssue(string sIssue) + { + ProgressReporter.AddIssue(sIssue); + } + + public void ProgressStep() + { + ProgressReporter.ProgressStep(ProgressIndex); + } + + /// + /// Shuts down the underlying ProgressReporter if this is the owner + /// + public void Shutdown() + { + if (ProxyOwnsReporter) + { + ProgressReporter.Shutdown(); + } + } + } +} diff --git a/CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs b/CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs new file mode 100644 index 00000000..f3c8091b --- /dev/null +++ b/CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs @@ -0,0 +1,53 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System.Threading; +using Support.UI; + +namespace Support.Progress +{ + /// + /// WaitDialog based Progress Reporter factory. + /// + public class WaitDialogProgressReporterFactory : ProgressReporterFactory + { + public int Width { get; set; } + + public WaitDialogProgressReporterFactory() + { + Width = 400; + } + + public IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, ThreadStart zThreadStart) + { + return new WaitDialog(arrayDescriptions.Length, zThreadStart, sTitle, arrayDescriptions, Width); + } + + public IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, + ParameterizedThreadStart zThreadStart, object zParamObject) + { + return new WaitDialog(arrayDescriptions.Length, zThreadStart, zParamObject, sTitle, arrayDescriptions, Width); + } + } +} diff --git a/CardMaker/Support/UI/WaitDialog.cs b/CardMaker/Support/UI/WaitDialog.cs index 36df5a47..4b6831fb 100644 --- a/CardMaker/Support/UI/WaitDialog.cs +++ b/CardMaker/Support/UI/WaitDialog.cs @@ -23,13 +23,16 @@ //////////////////////////////////////////////////////////////////////////////// using System; +using System.Collections.Generic; using System.Drawing; using System.Threading; using System.Windows.Forms; +using Support.IO; +using Support.Progress; namespace Support.UI { - class WaitDialog : Form + class WaitDialog : Form, IProgressReporter { private static WaitDialog m_zWaitDialog; private Thread m_zThread; @@ -38,6 +41,7 @@ class WaitDialog : Form private readonly object m_zParamObject; private ProgressBar[] m_arrayProgressBars; private string[] m_arrayDescriptions; + private Dictionary m_dictionaryProgressIndex = new Dictionary(); private Button btnCancel; private Label lblStatus; @@ -80,7 +84,18 @@ public WaitDialog(int nProgressBarCount, ParameterizedThreadStart zThreadStart, /// /// Flag indicating the cancel state of the WaitDialog /// - public bool Canceled { get; private set; } + public bool Canceled { get; set; } + + public int GetProgressCount() + { + return m_arrayDescriptions.Length; + } + + public int GetProgressIndex(string sProgressName) + { + int nIdx; + return m_dictionaryProgressIndex.TryGetValue(sProgressName, out nIdx) ? nIdx : -1; + } /// /// Sets up the basic controls @@ -95,7 +110,12 @@ private void Initialize(int nProgressBarCount, string sTitle, string[] arrayDesc if (nProgressBarCount == arrayDescriptions?.Length) { m_arrayDescriptions = arrayDescriptions; + for (var nIdx = 0; nIdx < arrayDescriptions.Length; nIdx++) + { + m_dictionaryProgressIndex[arrayDescriptions[nIdx]] = nIdx; + } } + m_zWaitDialog = this; // @@ -195,7 +215,7 @@ private void AddProgressBars(int nProgressBarCount) /// /// Controls the visibility of the cancel button /// - public bool CancelButtonVisibile + public bool CancelButtonVisible { get { return btnCancel.Visible; } set { btnCancel.Visible = value; } @@ -291,6 +311,28 @@ public int ProgressGet(int nProgressBar) return m_arrayProgressBars[nProgressBar].Value; } + public void StartProcessing(object initializationObject) + { + if (initializationObject is IWin32Window) + { + ShowDialog((IWin32Window) initializationObject); + } + else + { + throw new Exception("The input parameter must be of type IWin32Window."); + } + } + + public void AddIssue(string sIssue) + { + Logger.AddLogLine(sIssue); + } + + public void Shutdown() + { + CloseWaitDialog(); + } + /// /// Used in place of the Close method to avoid threading issues /// diff --git a/CardMaker/Support/Util/CommandLineParser.cs b/CardMaker/Support/Util/CommandLineParser.cs new file mode 100644 index 00000000..b9a4764a --- /dev/null +++ b/CardMaker/Support/Util/CommandLineParser.cs @@ -0,0 +1,217 @@ +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2019 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; +using System.Reflection; +using System.Collections.Generic; +using System.Text; + +namespace Support.Util +{ + /// + /// Summary description for CommandLineParser. + /// + public class CommandLineParser + { + private readonly Dictionary> s_dictionaryArgs = new Dictionary>(); + + /// + /// Private constructor (static class) + /// + public CommandLineParser(){} + + /// + /// Parse the command line into a Hashtable. Arguments are space delimited. + /// Examples: + /// -x filename (would associate the "filename" with -x) + /// -y (simply flags -y as part of the command line) + /// + /// + public CommandLineParser Parse(string[] args) + { + var nIdx = 0; + // sort out the command line into a dictionary of lists + var listArgumentValues = new List(); + // initialize a dumping ground for no arg params + AddArgument(string.Empty, listArgumentValues); + while (nIdx < args.Length) + { + if (args[nIdx].StartsWith("-")) + { + listArgumentValues = new List(); + AddArgument(args[nIdx].ToUpper().Substring(1), listArgumentValues); + } + else + { + listArgumentValues.Add(args[nIdx]); + } + nIdx++; + } + + return this; + } + + /// + /// Adds the specified argument to the argument table if it has not been previously defined. + /// + /// Argument string + /// Argument value + private void AddArgument(string sArg, List listArgumentValues) + { + if (s_dictionaryArgs.ContainsKey(sArg)) + { + s_dictionaryArgs.Remove(sArg); + } + s_dictionaryArgs.Add(sArg, listArgumentValues); + } + + /// + /// Gets the value associated with the argument or the supplied default + /// + /// The argument to get + /// The default value to get if the argument is not specified + /// + public string GetStringArg(string sArg, string sDefault) + { + string sReturn = GetStringArg(sArg); + if (null == sReturn) + { + return sDefault; + } + return sReturn; + } + + /// + /// + /// + /// + /// + public string GetStringArg(Enum eArg) + { + return GetStringArg(eArg.ToString()); + } + + /// + /// Gets the value associated with the argument. + /// + /// The argument to get the value of. + /// + public string GetStringArg(string sArg) + { + string sKey = sArg.ToUpper(); + if (s_dictionaryArgs.ContainsKey(sKey)) + { + if (null == s_dictionaryArgs[sKey]) + { + return string.Empty; + } + StringBuilder zBuilder = new StringBuilder(); + foreach(string sValue in s_dictionaryArgs[sKey]) + { + zBuilder.Append(sValue + " "); + } + return zBuilder.ToString().Trim(); + } + return null; + } + + /// + /// Gets the arguments associated with an option as an array + /// + /// + /// + public string[] GetStringArgs(Enum eArg) + { + return GetStringArgs(eArg.ToString()); + } + + /// + /// Gets the arguments associated with an option as an array + /// + /// + /// + public string[] GetStringArgs(string sArg) + { + string sKey = sArg.ToUpper(); + if (s_dictionaryArgs.ContainsKey(sKey)) + { + return s_dictionaryArgs[sKey].ToArray(); + } + return null; + } + + /// + /// Gets whether the argument was specified on the command line. + /// + /// + /// + public bool GetFlagArg(Enum eArg) + { + return GetFlagArg(eArg.ToString()); + } + + /// + /// Gets whether the argument was specified on the command line. + /// + /// + /// + public bool GetFlagArg(string sArg) + { + return s_dictionaryArgs.ContainsKey(sArg.ToUpper()); + } + + /// + /// Gets the number of arguments from the command line + /// + /// The number of command line arguments(pairs) + public int GetArgCount() + { + return s_dictionaryArgs.Count; + } + + /// + /// Wrapper for printing the usage of the application. + /// + /// Usage string + public static void PrintUsage(string sUsage) + { + Console.WriteLine("[" + Assembly.GetExecutingAssembly().ManifestModule.ToString() + " Command Line] " + + Assembly.GetExecutingAssembly().GetName().Version); + Console.WriteLine(sUsage); + } + + + /// + /// Debugging to see what the args are + /// + public void PrintArgs() + { + foreach (var sKey in s_dictionaryArgs.Keys) + { + Console.WriteLine(sKey + " [" + GetStringArg(sKey) + "]"); + } + } + + } +} diff --git a/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs b/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs index e0411cac..2d28f3b6 100644 --- a/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs +++ b/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs @@ -25,6 +25,8 @@ using CardMaker.XML; using NUnit.Framework; using System.Collections.Generic; +using Moq; +using Support.Progress; namespace UnitTest.DeckObject { @@ -33,11 +35,14 @@ internal class ElementOverride { private TestDeck _testDeck; private ProjectLayoutElement _testElement; + private Mock _mockProgressReporterProxy; [SetUp] public void Setup() { + _mockProgressReporterProxy = new Mock(); _testDeck = new TestDeck(); + _testDeck.SetProgressReporterProxy(_mockProgressReporterProxy.Object); _testElement = new ProjectLayoutElement("testElement"); } diff --git a/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs b/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs index f27c949c..392d548c 100644 --- a/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs +++ b/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs @@ -28,6 +28,8 @@ using System; using System.Collections.Generic; using CardMaker.Data; +using Moq; +using Support.Progress; using Support.UI; namespace UnitTest.DeckObject @@ -41,11 +43,14 @@ internal class InceptStringTranslation private TestDeck _testDeck; private DeckLine _testLine; private ProjectLayoutElement _testElement; + private Mock _mockProgressReporterProxy; [SetUp] public void Setup() { + _mockProgressReporterProxy = new Mock(); _testDeck = new TestDeck(); + _testDeck.SetProgressReporterProxy(_mockProgressReporterProxy.Object); _testLine = new DeckLine(new List()); _testElement = new ProjectLayoutElement(TEST_ELEMENT_NAME); } diff --git a/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs b/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs index 6e1ef14a..6e86d985 100644 --- a/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs +++ b/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs @@ -29,6 +29,8 @@ using System.Collections.Generic; using CardMaker.Data; using CardMaker.Events.Managers; +using Moq; +using Support.Progress; namespace UnitTest.DeckObject { @@ -42,13 +44,16 @@ internal class JavaScriptStringTranslation private TestDeck _testDeck; private DeckLine _testLine; private ProjectLayoutElement _testElement; + private Mock _mockProgressReporterProxy; [SetUp] public void Setup() { // JavaScriptTranslator uses a few settings from the project file ProjectManager.Instance.OpenProject(null); + _mockProgressReporterProxy = new Mock(); _testDeck = new TestDeck(new JavaScriptTranslatorFactory()); + _testDeck.SetProgressReporterProxy(_mockProgressReporterProxy.Object); _testLine = new DeckLine(new List()); _testElement = new ProjectLayoutElement(TEST_ELEMENT_NAME); } diff --git a/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs b/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs index 5eb9c67f..a13ebc1c 100644 --- a/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs +++ b/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs @@ -26,6 +26,7 @@ using CardMaker.XML; using System.Collections.Generic; using CardMaker.Card.Translation; +using Support.Progress; namespace UnitTest.DeckObject { @@ -70,5 +71,10 @@ public void SetDisallowedCharReplacement(char c, string replacement) { FilenameTranslator.CharReplacement[c] = replacement; } + + public void SetProgressReporterProxy(ProgressReporterProxy zProgressReporterProxy) + { + m_zReporterProxy = zProgressReporterProxy; + } } } diff --git a/CardMaker/bin/Release/Card_Maker.odt b/CardMaker/bin/Release/Card_Maker.odt index a2eab84badc968ef24fe928ae239ed53b8345b5f..f20c132bb88a6262f7035fdcb4dc9071abeec29f 100644 GIT binary patch delta 42360 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 W`(=K*`mct}l~~zI1k>5^5B5J}HcHe0 delta 40053 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 W&EBW_UuA?RLBEF_0jvHW?7sli93rm( From f9ef5e1af6df21a48859bfaba05ce0235bcc1c45 Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Mon, 18 May 2020 19:56:03 -0700 Subject: [PATCH 2/9] Updated copyright year. --- CardMaker/Card/CardCanvas.cs | 2 +- CardMaker/Card/CardPathUtil.cs | 2 +- CardMaker/Card/CardRenderer.cs | 2 +- CardMaker/Card/CommandLine/CommandLineEnumerations.cs | 2 +- CardMaker/Card/CommandLine/CommandLineExporterBase.cs | 2 +- CardMaker/Card/CommandLine/CommandLineProcessor.cs | 2 +- CardMaker/Card/CommandLine/ConsoleLogger.cs | 2 +- CardMaker/Card/CommandLine/ImageCommandLineExporter.cs | 2 +- CardMaker/Card/CommandLine/PDFCommandLineExporter.cs | 2 +- CardMaker/Card/Deck.cs | 2 +- CardMaker/Card/DeckLine.cs | 2 +- CardMaker/Card/DrawFormattedText.cs | 2 +- CardMaker/Card/DrawGraphic.cs | 2 +- CardMaker/Card/DrawTextGraphics.cs | 2 +- CardMaker/Card/DrawTextTextRenderer.cs | 2 +- CardMaker/Card/ElementString.cs | 2 +- CardMaker/Card/Export/CardExportBase.cs | 2 +- CardMaker/Card/Export/CompilerCardExporter.cs | 2 +- CardMaker/Card/Export/FileCardClipboardExporter.cs | 2 +- CardMaker/Card/Export/FileCardExporter.cs | 2 +- CardMaker/Card/Export/FileCardExporterFactory.cs | 2 +- CardMaker/Card/Export/FileCardSingleExporter.cs | 2 +- CardMaker/Card/Export/PdfSharpExporter.cs | 2 +- CardMaker/Card/FontLoader.cs | 2 +- CardMaker/Card/FormattedText/Alignment/AlignmentController.cs | 2 +- .../FormattedText/Alignment/HorizontalAlignmentProcessor.cs | 2 +- .../Alignment/HorizontalCenterAlignmentProcessor.cs | 2 +- .../Alignment/HorizontalJustifiedAlignmentProcessor.cs | 2 +- .../FormattedText/Alignment/HorizontalLeftAlignmentProcessor.cs | 2 +- .../Alignment/HorizontalRightAlignmentProcessor.cs | 2 +- .../Card/FormattedText/Alignment/VerticalAlignmentProcessor.cs | 2 +- .../FormattedText/Alignment/VerticalBottomAlignmentProcessor.cs | 2 +- .../FormattedText/Alignment/VerticalMiddleAlignmentProcessor.cs | 2 +- .../FormattedText/Alignment/VerticalTopAlignmentProcessor.cs | 2 +- CardMaker/Card/FormattedText/FormattedTextData.cs | 2 +- CardMaker/Card/FormattedText/FormattedTextDataCache.cs | 2 +- CardMaker/Card/FormattedText/FormattedTextParser.cs | 2 +- CardMaker/Card/FormattedText/FormattedTextProcessData.cs | 2 +- CardMaker/Card/FormattedText/Markup/AlignCenterMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/AlignLeftMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/AlignRightMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/BackgroundImageMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/BaseAlignMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/CloseTagMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/FontColorMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/FontMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/FontSizeMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/FontStyleMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/ImageMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/LineSpaceMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/MarkupBase.cs | 2 +- CardMaker/Card/FormattedText/Markup/MarkupUtil.cs | 2 +- CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs | 2 +- CardMaker/Card/FormattedText/Markup/NewlineMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/PixelMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/PushMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/TextMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/XDrawOffsetMarkup.cs | 2 +- CardMaker/Card/FormattedText/Markup/YDrawOffsetMarkup.cs | 2 +- CardMaker/Card/IDrawFormattedText.cs | 2 +- CardMaker/Card/IDrawGraphic.cs | 2 +- CardMaker/Card/IDrawText.cs | 2 +- CardMaker/Card/IInlineBackgroundElementProcessor.cs | 2 +- CardMaker/Card/ImageCache.cs | 2 +- CardMaker/Card/Import/CSVReferenceReader.cs | 2 +- CardMaker/Card/Import/ExcelReferenceReader.cs | 2 +- CardMaker/Card/Import/GoogleReferenceReader.cs | 2 +- CardMaker/Card/Import/GoogleSpreadsheetReference.cs | 2 +- CardMaker/Card/Import/ReferenceReader.cs | 2 +- CardMaker/Card/Import/ReferenceReaderFactory.cs | 2 +- CardMaker/Card/InlineBackgroundElementProcessor.cs | 2 +- CardMaker/Card/MeasurementUtil.cs | 2 +- CardMaker/Card/Render/BackgroundColorElementRenderProcessor.cs | 2 +- CardMaker/Card/Render/BorderElementRenderProcessor.cs | 2 +- CardMaker/Card/Render/IElementRenderProcessor.cs | 2 +- CardMaker/Card/Render/InlineElementRenderProcessor.cs | 2 +- CardMaker/Card/Render/InputElementRenderProcessor.cs | 2 +- CardMaker/Card/Render/TransformElementRenderProcessor.cs | 2 +- CardMaker/Card/Render/TypeElementRenderProcessor.cs | 2 +- CardMaker/Card/Shapes/AbstractShape.cs | 2 +- CardMaker/Card/Shapes/Definitions/EllipseShape.cs | 2 +- CardMaker/Card/Shapes/Definitions/GridShape.cs | 2 +- CardMaker/Card/Shapes/Definitions/RectShape.cs | 2 +- CardMaker/Card/Shapes/Definitions/RoundedRectShape.cs | 2 +- CardMaker/Card/Shapes/Definitions/TriangleShape.cs | 2 +- CardMaker/Card/Shapes/IShapeRenderer.cs | 2 +- CardMaker/Card/Shapes/ShapeInfo.cs | 2 +- CardMaker/Card/Shapes/ShapeManager.cs | 2 +- CardMaker/Card/Translation/FilenameTranslator.cs | 2 +- CardMaker/Card/Translation/ITranslatorFactory.cs | 2 +- CardMaker/Card/Translation/InceptTranslator.cs | 2 +- CardMaker/Card/Translation/JavaScriptTranslator.cs | 2 +- CardMaker/Card/Translation/JavascriptHostFunctions.cs | 2 +- CardMaker/Card/Translation/TranslatorBase.cs | 2 +- CardMaker/Card/Translation/TranslatorFactory.cs | 2 +- CardMaker/CardMakerBuild.cs | 2 +- CardMaker/Data/CardMakerConstants.cs | 2 +- CardMaker/Data/CardMakerInstance.cs | 2 +- CardMaker/Data/CardMakerSettings.cs | 2 +- CardMaker/Data/ElementPosition.cs | 2 +- CardMaker/Data/Enumerations.cs | 2 +- CardMaker/Data/LayoutTemplateManager.cs | 2 +- CardMaker/Events/Args/DeckChangeEventArgs.cs | 2 +- CardMaker/Events/Args/ElementEventArgs.cs | 2 +- CardMaker/Events/Args/ExportEventArgs.cs | 2 +- CardMaker/Events/Args/GoogleAuthEventArgs.cs | 2 +- CardMaker/Events/Args/IssueCardInfoEventArgs.cs | 2 +- CardMaker/Events/Args/IssueElementEventArgs.cs | 2 +- CardMaker/Events/Args/IssueMessageEventArgs.cs | 2 +- CardMaker/Events/Args/IssueRefreshEventArgs.cs | 2 +- CardMaker/Events/Args/LayoutElementNumericAdjustEventArgs.cs | 2 +- CardMaker/Events/Args/LayoutEventArgs.cs | 2 +- CardMaker/Events/Args/ProjectEventArgs.cs | 2 +- CardMaker/Events/Managers/AutoSaveManager.cs | 2 +- CardMaker/Events/Managers/ElementManager.cs | 2 +- CardMaker/Events/Managers/ExportManager.cs | 2 +- CardMaker/Events/Managers/GoogleAuthManager.cs | 2 +- CardMaker/Events/Managers/IssueManager.cs | 2 +- CardMaker/Events/Managers/LayoutManager.cs | 2 +- CardMaker/Events/Managers/ProjectManager.cs | 2 +- CardMaker/Forms/CardMakerMDI.Designer.cs | 2 +- CardMaker/Forms/CardMakerMDI.cs | 2 +- CardMaker/Forms/Dialogs/ProjectSettingsDialog.cs | 2 +- CardMaker/Forms/FormUtils.cs | 2 +- CardMaker/Forms/GoogleCredentialsDialog.Designer.cs | 2 +- CardMaker/Forms/GoogleCredentialsDialog.cs | 2 +- CardMaker/Forms/MDICanvas.Designer.cs | 2 +- CardMaker/Forms/MDICanvas.cs | 2 +- CardMaker/Forms/MDIDefines.Designer.cs | 2 +- CardMaker/Forms/MDIDefines.cs | 2 +- CardMaker/Forms/MDIElementControl.Designer.cs | 2 +- CardMaker/Forms/MDIElementControl.cs | 2 +- CardMaker/Forms/MDIIssues.Designer.cs | 2 +- CardMaker/Forms/MDIIssues.cs | 2 +- CardMaker/Forms/MDILayoutControl.Designer.cs | 2 +- CardMaker/Forms/MDILayoutControl.cs | 2 +- CardMaker/Forms/MDILogger.Designer.cs | 2 +- CardMaker/Forms/MDILogger.cs | 2 +- CardMaker/Forms/MDIProject.Designer.cs | 2 +- CardMaker/Forms/MDIProject.cs | 2 +- CardMaker/Forms/ProjectManagerUI.Designer.cs | 2 +- CardMaker/Forms/ProjectManagerUI.cs | 2 +- CardMaker/Program.cs | 2 +- CardMaker/Properties/AssemblyInfo.cs | 2 +- CardMaker/Support/Google/GoogleApi.cs | 2 +- CardMaker/Support/Google/GoogleInitializerFactory.cs | 2 +- CardMaker/Support/Google/Sheets/GoogleSheetInfo.cs | 2 +- CardMaker/Support/Google/Sheets/GoogleSpreadsheet.cs | 2 +- .../Support/Google/Sheets/GoogleSpreadsheetBrowser.Designer.cs | 2 +- CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs | 2 +- CardMaker/Support/IO/CSVFile.cs | 2 +- CardMaker/Support/IO/INIManager.cs | 2 +- CardMaker/Support/IO/IOUtils.cs | 2 +- CardMaker/Support/IO/Logger.cs | 2 +- CardMaker/Support/IO/SerializationUtils.cs | 2 +- CardMaker/Support/Progress/ConsoleProgressReporter.cs | 2 +- CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs | 2 +- CardMaker/Support/Progress/IProgressReporter.cs | 2 +- CardMaker/Support/Progress/ProgressReporterFactory.cs | 2 +- CardMaker/Support/Progress/ProgressReporterProxy.cs | 2 +- .../Support/Progress/WaitDialogLineProgressReporterFactory.cs | 2 +- CardMaker/Support/UI/AbstractDirtyForm.cs | 2 +- CardMaker/Support/UI/Extensions.cs | 2 +- CardMaker/Support/UI/ListViewAssist.cs | 2 +- CardMaker/Support/UI/ListViewDoubleBuffer.cs | 2 +- CardMaker/Support/UI/ListViewItemComparer.cs | 2 +- CardMaker/Support/UI/PanelEx.cs | 2 +- CardMaker/Support/UI/QueryPanel.cs | 2 +- CardMaker/Support/UI/QueryPanelDialog.cs | 2 +- CardMaker/Support/UI/RGBColorSelectDialog.Designer.cs | 2 +- CardMaker/Support/UI/RGBColorSelectDialog.cs | 2 +- CardMaker/Support/UI/UserAction.cs | 2 +- CardMaker/Support/UI/WaitDialog.cs | 2 +- CardMaker/Support/UI/Win32.cs | 2 +- CardMaker/Support/Util/CommandLineParser.cs | 2 +- CardMaker/Support/Util/ParseUtil.cs | 2 +- CardMaker/Support/Util/TimeMeasure.cs | 2 +- CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs | 2 +- CardMaker/Test/UnitTest/DeckObject/FormattedText.cs | 2 +- CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs | 2 +- .../UnitTest/DeckObject/InlineBackgroundElementProcessorTest.cs | 2 +- .../Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs | 2 +- .../Test/UnitTest/DeckObject/JavaScriptTranslatorFactory.cs | 2 +- CardMaker/Test/UnitTest/DeckObject/TestDeck.cs | 2 +- CardMaker/Test/UnitTest/Support/Util/ParseUtilTest.cs | 2 +- CardMaker/XML/LayoutTemplate.cs | 2 +- CardMaker/XML/Project.cs | 2 +- CardMaker/XML/ProjectLayout.cs | 2 +- CardMaker/XML/ProjectLayoutElement.cs | 2 +- CardMaker/XML/ProjectLayoutReference.cs | 2 +- 192 files changed, 192 insertions(+), 192 deletions(-) diff --git a/CardMaker/Card/CardCanvas.cs b/CardMaker/Card/CardCanvas.cs index 7cf531b8..9e7c1538 100644 --- a/CardMaker/Card/CardCanvas.cs +++ b/CardMaker/Card/CardCanvas.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CardPathUtil.cs b/CardMaker/Card/CardPathUtil.cs index db56ba9f..99ebb1e7 100644 --- a/CardMaker/Card/CardPathUtil.cs +++ b/CardMaker/Card/CardPathUtil.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CardRenderer.cs b/CardMaker/Card/CardRenderer.cs index 5aa33fc7..c2e1f250 100644 --- a/CardMaker/Card/CardRenderer.cs +++ b/CardMaker/Card/CardRenderer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CommandLine/CommandLineEnumerations.cs b/CardMaker/Card/CommandLine/CommandLineEnumerations.cs index febb8dc7..b6c079a2 100644 --- a/CardMaker/Card/CommandLine/CommandLineEnumerations.cs +++ b/CardMaker/Card/CommandLine/CommandLineEnumerations.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CommandLine/CommandLineExporterBase.cs b/CardMaker/Card/CommandLine/CommandLineExporterBase.cs index d8e6a72c..2600961a 100644 --- a/CardMaker/Card/CommandLine/CommandLineExporterBase.cs +++ b/CardMaker/Card/CommandLine/CommandLineExporterBase.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CommandLine/CommandLineProcessor.cs b/CardMaker/Card/CommandLine/CommandLineProcessor.cs index 82fdb20b..41c5d62b 100644 --- a/CardMaker/Card/CommandLine/CommandLineProcessor.cs +++ b/CardMaker/Card/CommandLine/CommandLineProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CommandLine/ConsoleLogger.cs b/CardMaker/Card/CommandLine/ConsoleLogger.cs index 343f3add..abfaaf8d 100644 --- a/CardMaker/Card/CommandLine/ConsoleLogger.cs +++ b/CardMaker/Card/CommandLine/ConsoleLogger.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs b/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs index ffacec72..ac48775e 100644 --- a/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs +++ b/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs b/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs index 4947b996..aed3764b 100644 --- a/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs +++ b/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Deck.cs b/CardMaker/Card/Deck.cs index eeb7a95c..cb7df42b 100644 --- a/CardMaker/Card/Deck.cs +++ b/CardMaker/Card/Deck.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/DeckLine.cs b/CardMaker/Card/DeckLine.cs index 763f93c7..c740785b 100644 --- a/CardMaker/Card/DeckLine.cs +++ b/CardMaker/Card/DeckLine.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/DrawFormattedText.cs b/CardMaker/Card/DrawFormattedText.cs index e9579cf5..dfce4762 100644 --- a/CardMaker/Card/DrawFormattedText.cs +++ b/CardMaker/Card/DrawFormattedText.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/DrawGraphic.cs b/CardMaker/Card/DrawGraphic.cs index 00b7373f..89294e53 100644 --- a/CardMaker/Card/DrawGraphic.cs +++ b/CardMaker/Card/DrawGraphic.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/DrawTextGraphics.cs b/CardMaker/Card/DrawTextGraphics.cs index 508ab5e6..216ec5fc 100644 --- a/CardMaker/Card/DrawTextGraphics.cs +++ b/CardMaker/Card/DrawTextGraphics.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/DrawTextTextRenderer.cs b/CardMaker/Card/DrawTextTextRenderer.cs index 5367d296..dd2358e2 100644 --- a/CardMaker/Card/DrawTextTextRenderer.cs +++ b/CardMaker/Card/DrawTextTextRenderer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/ElementString.cs b/CardMaker/Card/ElementString.cs index eae21a09..29c8fd71 100644 --- a/CardMaker/Card/ElementString.cs +++ b/CardMaker/Card/ElementString.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Export/CardExportBase.cs b/CardMaker/Card/Export/CardExportBase.cs index 2033e6e8..33602669 100644 --- a/CardMaker/Card/Export/CardExportBase.cs +++ b/CardMaker/Card/Export/CardExportBase.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Export/CompilerCardExporter.cs b/CardMaker/Card/Export/CompilerCardExporter.cs index 331adb34..3e6e91e7 100644 --- a/CardMaker/Card/Export/CompilerCardExporter.cs +++ b/CardMaker/Card/Export/CompilerCardExporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Export/FileCardClipboardExporter.cs b/CardMaker/Card/Export/FileCardClipboardExporter.cs index 758bc93f..ee3757ff 100644 --- a/CardMaker/Card/Export/FileCardClipboardExporter.cs +++ b/CardMaker/Card/Export/FileCardClipboardExporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Export/FileCardExporter.cs b/CardMaker/Card/Export/FileCardExporter.cs index b0a24754..f9ba3db7 100644 --- a/CardMaker/Card/Export/FileCardExporter.cs +++ b/CardMaker/Card/Export/FileCardExporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Export/FileCardExporterFactory.cs b/CardMaker/Card/Export/FileCardExporterFactory.cs index aecfe148..7a864a52 100644 --- a/CardMaker/Card/Export/FileCardExporterFactory.cs +++ b/CardMaker/Card/Export/FileCardExporterFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Export/FileCardSingleExporter.cs b/CardMaker/Card/Export/FileCardSingleExporter.cs index dc18c0c4..73bdcded 100644 --- a/CardMaker/Card/Export/FileCardSingleExporter.cs +++ b/CardMaker/Card/Export/FileCardSingleExporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Export/PdfSharpExporter.cs b/CardMaker/Card/Export/PdfSharpExporter.cs index f195fbcc..d8ddbb70 100644 --- a/CardMaker/Card/Export/PdfSharpExporter.cs +++ b/CardMaker/Card/Export/PdfSharpExporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FontLoader.cs b/CardMaker/Card/FontLoader.cs index 3ab58fe6..aa735d6a 100644 --- a/CardMaker/Card/FontLoader.cs +++ b/CardMaker/Card/FontLoader.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/AlignmentController.cs b/CardMaker/Card/FormattedText/Alignment/AlignmentController.cs index 70161458..ec56a885 100644 --- a/CardMaker/Card/FormattedText/Alignment/AlignmentController.cs +++ b/CardMaker/Card/FormattedText/Alignment/AlignmentController.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/HorizontalAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/HorizontalAlignmentProcessor.cs index ca8a9f04..e0d47fdd 100644 --- a/CardMaker/Card/FormattedText/Alignment/HorizontalAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/HorizontalAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/HorizontalCenterAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/HorizontalCenterAlignmentProcessor.cs index 3706d789..ac6cbc73 100644 --- a/CardMaker/Card/FormattedText/Alignment/HorizontalCenterAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/HorizontalCenterAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/HorizontalJustifiedAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/HorizontalJustifiedAlignmentProcessor.cs index bd99dc30..9ca20587 100644 --- a/CardMaker/Card/FormattedText/Alignment/HorizontalJustifiedAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/HorizontalJustifiedAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/HorizontalLeftAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/HorizontalLeftAlignmentProcessor.cs index 472979ae..9b1d97d0 100644 --- a/CardMaker/Card/FormattedText/Alignment/HorizontalLeftAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/HorizontalLeftAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/HorizontalRightAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/HorizontalRightAlignmentProcessor.cs index ff1db720..86203c92 100644 --- a/CardMaker/Card/FormattedText/Alignment/HorizontalRightAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/HorizontalRightAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/VerticalAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/VerticalAlignmentProcessor.cs index 4d1a91cf..acaaf106 100644 --- a/CardMaker/Card/FormattedText/Alignment/VerticalAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/VerticalAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/VerticalBottomAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/VerticalBottomAlignmentProcessor.cs index 0351cf61..581a23ff 100644 --- a/CardMaker/Card/FormattedText/Alignment/VerticalBottomAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/VerticalBottomAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/VerticalMiddleAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/VerticalMiddleAlignmentProcessor.cs index 9c18bb46..762864a3 100644 --- a/CardMaker/Card/FormattedText/Alignment/VerticalMiddleAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/VerticalMiddleAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Alignment/VerticalTopAlignmentProcessor.cs b/CardMaker/Card/FormattedText/Alignment/VerticalTopAlignmentProcessor.cs index c43ec2fe..99bde92f 100644 --- a/CardMaker/Card/FormattedText/Alignment/VerticalTopAlignmentProcessor.cs +++ b/CardMaker/Card/FormattedText/Alignment/VerticalTopAlignmentProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/FormattedTextData.cs b/CardMaker/Card/FormattedText/FormattedTextData.cs index d2671482..43539622 100644 --- a/CardMaker/Card/FormattedText/FormattedTextData.cs +++ b/CardMaker/Card/FormattedText/FormattedTextData.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/FormattedTextDataCache.cs b/CardMaker/Card/FormattedText/FormattedTextDataCache.cs index d5a44581..e89a3609 100644 --- a/CardMaker/Card/FormattedText/FormattedTextDataCache.cs +++ b/CardMaker/Card/FormattedText/FormattedTextDataCache.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/FormattedTextParser.cs b/CardMaker/Card/FormattedText/FormattedTextParser.cs index 9a8bb64a..390700cd 100644 --- a/CardMaker/Card/FormattedText/FormattedTextParser.cs +++ b/CardMaker/Card/FormattedText/FormattedTextParser.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/FormattedTextProcessData.cs b/CardMaker/Card/FormattedText/FormattedTextProcessData.cs index ac3e5363..e519fe76 100644 --- a/CardMaker/Card/FormattedText/FormattedTextProcessData.cs +++ b/CardMaker/Card/FormattedText/FormattedTextProcessData.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/AlignCenterMarkup.cs b/CardMaker/Card/FormattedText/Markup/AlignCenterMarkup.cs index f625248d..92755230 100644 --- a/CardMaker/Card/FormattedText/Markup/AlignCenterMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/AlignCenterMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/AlignLeftMarkup.cs b/CardMaker/Card/FormattedText/Markup/AlignLeftMarkup.cs index 643c418d..4d7c562c 100644 --- a/CardMaker/Card/FormattedText/Markup/AlignLeftMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/AlignLeftMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/AlignRightMarkup.cs b/CardMaker/Card/FormattedText/Markup/AlignRightMarkup.cs index 622feb0b..b94e09db 100644 --- a/CardMaker/Card/FormattedText/Markup/AlignRightMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/AlignRightMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs b/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs index 37dbc132..642e88b1 100644 --- a/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/BackgroundImageMarkup.cs b/CardMaker/Card/FormattedText/Markup/BackgroundImageMarkup.cs index 1f5d160f..722fbae8 100644 --- a/CardMaker/Card/FormattedText/Markup/BackgroundImageMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/BackgroundImageMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/BaseAlignMarkup.cs b/CardMaker/Card/FormattedText/Markup/BaseAlignMarkup.cs index b5d07fb3..cf9c28fd 100644 --- a/CardMaker/Card/FormattedText/Markup/BaseAlignMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/BaseAlignMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/CloseTagMarkup.cs b/CardMaker/Card/FormattedText/Markup/CloseTagMarkup.cs index 8a2a018c..a8f698a4 100644 --- a/CardMaker/Card/FormattedText/Markup/CloseTagMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/CloseTagMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/FontColorMarkup.cs b/CardMaker/Card/FormattedText/Markup/FontColorMarkup.cs index 967f9d52..90d7ff2a 100644 --- a/CardMaker/Card/FormattedText/Markup/FontColorMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/FontColorMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/FontMarkup.cs b/CardMaker/Card/FormattedText/Markup/FontMarkup.cs index 261abcf8..94c8aac9 100644 --- a/CardMaker/Card/FormattedText/Markup/FontMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/FontMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/FontSizeMarkup.cs b/CardMaker/Card/FormattedText/Markup/FontSizeMarkup.cs index 75c4f2c5..20eb409d 100644 --- a/CardMaker/Card/FormattedText/Markup/FontSizeMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/FontSizeMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/FontStyleMarkup.cs b/CardMaker/Card/FormattedText/Markup/FontStyleMarkup.cs index 577ada3a..38d9b5c8 100644 --- a/CardMaker/Card/FormattedText/Markup/FontStyleMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/FontStyleMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/ImageMarkup.cs b/CardMaker/Card/FormattedText/Markup/ImageMarkup.cs index 6d62a677..27237cb5 100644 --- a/CardMaker/Card/FormattedText/Markup/ImageMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/ImageMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/LineSpaceMarkup.cs b/CardMaker/Card/FormattedText/Markup/LineSpaceMarkup.cs index 084267dd..9eed0bf7 100644 --- a/CardMaker/Card/FormattedText/Markup/LineSpaceMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/LineSpaceMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/MarkupBase.cs b/CardMaker/Card/FormattedText/Markup/MarkupBase.cs index 69ec73fb..77aab60e 100644 --- a/CardMaker/Card/FormattedText/Markup/MarkupBase.cs +++ b/CardMaker/Card/FormattedText/Markup/MarkupBase.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/MarkupUtil.cs b/CardMaker/Card/FormattedText/Markup/MarkupUtil.cs index 9aea3cd8..7e7b6754 100644 --- a/CardMaker/Card/FormattedText/Markup/MarkupUtil.cs +++ b/CardMaker/Card/FormattedText/Markup/MarkupUtil.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs b/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs index bc79b53a..f70a9c87 100644 --- a/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs +++ b/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/NewlineMarkup.cs b/CardMaker/Card/FormattedText/Markup/NewlineMarkup.cs index 1c61524e..ce4f497a 100644 --- a/CardMaker/Card/FormattedText/Markup/NewlineMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/NewlineMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs b/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs index 7d5b1f40..32fc5f3d 100644 --- a/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/PushMarkup.cs b/CardMaker/Card/FormattedText/Markup/PushMarkup.cs index 6ab27f25..9ee6bd0b 100644 --- a/CardMaker/Card/FormattedText/Markup/PushMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/PushMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs b/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs index 192e2345..8180451d 100644 --- a/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/TextMarkup.cs b/CardMaker/Card/FormattedText/Markup/TextMarkup.cs index 4cd795f2..a3b53bd5 100644 --- a/CardMaker/Card/FormattedText/Markup/TextMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/TextMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/XDrawOffsetMarkup.cs b/CardMaker/Card/FormattedText/Markup/XDrawOffsetMarkup.cs index c15a6f93..604981c4 100644 --- a/CardMaker/Card/FormattedText/Markup/XDrawOffsetMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/XDrawOffsetMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/FormattedText/Markup/YDrawOffsetMarkup.cs b/CardMaker/Card/FormattedText/Markup/YDrawOffsetMarkup.cs index 091b60df..1d50040c 100644 --- a/CardMaker/Card/FormattedText/Markup/YDrawOffsetMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/YDrawOffsetMarkup.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/IDrawFormattedText.cs b/CardMaker/Card/IDrawFormattedText.cs index c05a2b97..343ceee0 100644 --- a/CardMaker/Card/IDrawFormattedText.cs +++ b/CardMaker/Card/IDrawFormattedText.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/IDrawGraphic.cs b/CardMaker/Card/IDrawGraphic.cs index 1f85d630..3ae71487 100644 --- a/CardMaker/Card/IDrawGraphic.cs +++ b/CardMaker/Card/IDrawGraphic.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/IDrawText.cs b/CardMaker/Card/IDrawText.cs index dcb47428..e298733d 100644 --- a/CardMaker/Card/IDrawText.cs +++ b/CardMaker/Card/IDrawText.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/IInlineBackgroundElementProcessor.cs b/CardMaker/Card/IInlineBackgroundElementProcessor.cs index e19f3c29..7eb4b7b7 100644 --- a/CardMaker/Card/IInlineBackgroundElementProcessor.cs +++ b/CardMaker/Card/IInlineBackgroundElementProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/ImageCache.cs b/CardMaker/Card/ImageCache.cs index 04bb3735..76f09054 100644 --- a/CardMaker/Card/ImageCache.cs +++ b/CardMaker/Card/ImageCache.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Import/CSVReferenceReader.cs b/CardMaker/Card/Import/CSVReferenceReader.cs index f10fa917..358aa420 100644 --- a/CardMaker/Card/Import/CSVReferenceReader.cs +++ b/CardMaker/Card/Import/CSVReferenceReader.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Import/ExcelReferenceReader.cs b/CardMaker/Card/Import/ExcelReferenceReader.cs index 5d6b15a8..2c20924f 100644 --- a/CardMaker/Card/Import/ExcelReferenceReader.cs +++ b/CardMaker/Card/Import/ExcelReferenceReader.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Import/GoogleReferenceReader.cs b/CardMaker/Card/Import/GoogleReferenceReader.cs index 6ebe87d3..1b8b6363 100644 --- a/CardMaker/Card/Import/GoogleReferenceReader.cs +++ b/CardMaker/Card/Import/GoogleReferenceReader.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Import/GoogleSpreadsheetReference.cs b/CardMaker/Card/Import/GoogleSpreadsheetReference.cs index 43312f35..ae4a37a9 100644 --- a/CardMaker/Card/Import/GoogleSpreadsheetReference.cs +++ b/CardMaker/Card/Import/GoogleSpreadsheetReference.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Import/ReferenceReader.cs b/CardMaker/Card/Import/ReferenceReader.cs index 133fdd1a..bc2622c2 100644 --- a/CardMaker/Card/Import/ReferenceReader.cs +++ b/CardMaker/Card/Import/ReferenceReader.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Import/ReferenceReaderFactory.cs b/CardMaker/Card/Import/ReferenceReaderFactory.cs index e059271e..78ddffac 100644 --- a/CardMaker/Card/Import/ReferenceReaderFactory.cs +++ b/CardMaker/Card/Import/ReferenceReaderFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/InlineBackgroundElementProcessor.cs b/CardMaker/Card/InlineBackgroundElementProcessor.cs index 2bc8bc4c..57c73132 100644 --- a/CardMaker/Card/InlineBackgroundElementProcessor.cs +++ b/CardMaker/Card/InlineBackgroundElementProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/MeasurementUtil.cs b/CardMaker/Card/MeasurementUtil.cs index 36348d5d..25747f72 100644 --- a/CardMaker/Card/MeasurementUtil.cs +++ b/CardMaker/Card/MeasurementUtil.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Render/BackgroundColorElementRenderProcessor.cs b/CardMaker/Card/Render/BackgroundColorElementRenderProcessor.cs index 354e905e..774ad2e9 100644 --- a/CardMaker/Card/Render/BackgroundColorElementRenderProcessor.cs +++ b/CardMaker/Card/Render/BackgroundColorElementRenderProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Render/BorderElementRenderProcessor.cs b/CardMaker/Card/Render/BorderElementRenderProcessor.cs index 4675d632..484b02c7 100644 --- a/CardMaker/Card/Render/BorderElementRenderProcessor.cs +++ b/CardMaker/Card/Render/BorderElementRenderProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Render/IElementRenderProcessor.cs b/CardMaker/Card/Render/IElementRenderProcessor.cs index 2fa979d0..0f5d8d4e 100644 --- a/CardMaker/Card/Render/IElementRenderProcessor.cs +++ b/CardMaker/Card/Render/IElementRenderProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Render/InlineElementRenderProcessor.cs b/CardMaker/Card/Render/InlineElementRenderProcessor.cs index db9acc5d..e5c3fdb8 100644 --- a/CardMaker/Card/Render/InlineElementRenderProcessor.cs +++ b/CardMaker/Card/Render/InlineElementRenderProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Render/InputElementRenderProcessor.cs b/CardMaker/Card/Render/InputElementRenderProcessor.cs index f6df6eb8..bec08234 100644 --- a/CardMaker/Card/Render/InputElementRenderProcessor.cs +++ b/CardMaker/Card/Render/InputElementRenderProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Render/TransformElementRenderProcessor.cs b/CardMaker/Card/Render/TransformElementRenderProcessor.cs index d0be1d34..25d732b8 100644 --- a/CardMaker/Card/Render/TransformElementRenderProcessor.cs +++ b/CardMaker/Card/Render/TransformElementRenderProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Render/TypeElementRenderProcessor.cs b/CardMaker/Card/Render/TypeElementRenderProcessor.cs index ce0f4aa9..380b2de7 100644 --- a/CardMaker/Card/Render/TypeElementRenderProcessor.cs +++ b/CardMaker/Card/Render/TypeElementRenderProcessor.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/AbstractShape.cs b/CardMaker/Card/Shapes/AbstractShape.cs index 7f25db11..4515edec 100644 --- a/CardMaker/Card/Shapes/AbstractShape.cs +++ b/CardMaker/Card/Shapes/AbstractShape.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/Definitions/EllipseShape.cs b/CardMaker/Card/Shapes/Definitions/EllipseShape.cs index 6f9a0280..3ebae7b2 100644 --- a/CardMaker/Card/Shapes/Definitions/EllipseShape.cs +++ b/CardMaker/Card/Shapes/Definitions/EllipseShape.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/Definitions/GridShape.cs b/CardMaker/Card/Shapes/Definitions/GridShape.cs index 6eb3e5d7..5998d13d 100644 --- a/CardMaker/Card/Shapes/Definitions/GridShape.cs +++ b/CardMaker/Card/Shapes/Definitions/GridShape.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/Definitions/RectShape.cs b/CardMaker/Card/Shapes/Definitions/RectShape.cs index 68a75827..5f5b8dc9 100644 --- a/CardMaker/Card/Shapes/Definitions/RectShape.cs +++ b/CardMaker/Card/Shapes/Definitions/RectShape.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/Definitions/RoundedRectShape.cs b/CardMaker/Card/Shapes/Definitions/RoundedRectShape.cs index 78358548..123aa184 100644 --- a/CardMaker/Card/Shapes/Definitions/RoundedRectShape.cs +++ b/CardMaker/Card/Shapes/Definitions/RoundedRectShape.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/Definitions/TriangleShape.cs b/CardMaker/Card/Shapes/Definitions/TriangleShape.cs index eb6cd979..80a6bbbc 100644 --- a/CardMaker/Card/Shapes/Definitions/TriangleShape.cs +++ b/CardMaker/Card/Shapes/Definitions/TriangleShape.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/IShapeRenderer.cs b/CardMaker/Card/Shapes/IShapeRenderer.cs index a5101c8a..909616d5 100644 --- a/CardMaker/Card/Shapes/IShapeRenderer.cs +++ b/CardMaker/Card/Shapes/IShapeRenderer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/ShapeInfo.cs b/CardMaker/Card/Shapes/ShapeInfo.cs index 7c046583..7fe805aa 100644 --- a/CardMaker/Card/Shapes/ShapeInfo.cs +++ b/CardMaker/Card/Shapes/ShapeInfo.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Shapes/ShapeManager.cs b/CardMaker/Card/Shapes/ShapeManager.cs index fc7efab2..e39a7af3 100644 --- a/CardMaker/Card/Shapes/ShapeManager.cs +++ b/CardMaker/Card/Shapes/ShapeManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Translation/FilenameTranslator.cs b/CardMaker/Card/Translation/FilenameTranslator.cs index c56724a1..d2a65a7b 100644 --- a/CardMaker/Card/Translation/FilenameTranslator.cs +++ b/CardMaker/Card/Translation/FilenameTranslator.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Translation/ITranslatorFactory.cs b/CardMaker/Card/Translation/ITranslatorFactory.cs index 49ae31e7..7e8a4dbd 100644 --- a/CardMaker/Card/Translation/ITranslatorFactory.cs +++ b/CardMaker/Card/Translation/ITranslatorFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Translation/InceptTranslator.cs b/CardMaker/Card/Translation/InceptTranslator.cs index 95347299..92bc6d30 100644 --- a/CardMaker/Card/Translation/InceptTranslator.cs +++ b/CardMaker/Card/Translation/InceptTranslator.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Translation/JavaScriptTranslator.cs b/CardMaker/Card/Translation/JavaScriptTranslator.cs index ef0eb8d3..385b31e6 100644 --- a/CardMaker/Card/Translation/JavaScriptTranslator.cs +++ b/CardMaker/Card/Translation/JavaScriptTranslator.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Translation/JavascriptHostFunctions.cs b/CardMaker/Card/Translation/JavascriptHostFunctions.cs index 0752ed13..6aec5700 100644 --- a/CardMaker/Card/Translation/JavascriptHostFunctions.cs +++ b/CardMaker/Card/Translation/JavascriptHostFunctions.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Translation/TranslatorBase.cs b/CardMaker/Card/Translation/TranslatorBase.cs index 543b46f3..8f407ec0 100644 --- a/CardMaker/Card/Translation/TranslatorBase.cs +++ b/CardMaker/Card/Translation/TranslatorBase.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Card/Translation/TranslatorFactory.cs b/CardMaker/Card/Translation/TranslatorFactory.cs index 1fe1b14f..35cf0750 100644 --- a/CardMaker/Card/Translation/TranslatorFactory.cs +++ b/CardMaker/Card/Translation/TranslatorFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/CardMakerBuild.cs b/CardMaker/CardMakerBuild.cs index bb4f5a3b..b1e6f9dd 100644 --- a/CardMaker/CardMakerBuild.cs +++ b/CardMaker/CardMakerBuild.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Data/CardMakerConstants.cs b/CardMaker/Data/CardMakerConstants.cs index d9c2c88b..5d9297c6 100644 --- a/CardMaker/Data/CardMakerConstants.cs +++ b/CardMaker/Data/CardMakerConstants.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Data/CardMakerInstance.cs b/CardMaker/Data/CardMakerInstance.cs index 64b88bcc..8c4e9093 100644 --- a/CardMaker/Data/CardMakerInstance.cs +++ b/CardMaker/Data/CardMakerInstance.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Data/CardMakerSettings.cs b/CardMaker/Data/CardMakerSettings.cs index 808af746..9853a4d0 100644 --- a/CardMaker/Data/CardMakerSettings.cs +++ b/CardMaker/Data/CardMakerSettings.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Data/ElementPosition.cs b/CardMaker/Data/ElementPosition.cs index 62516a97..ed6f6d27 100644 --- a/CardMaker/Data/ElementPosition.cs +++ b/CardMaker/Data/ElementPosition.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Data/Enumerations.cs b/CardMaker/Data/Enumerations.cs index b609b414..501e08ee 100644 --- a/CardMaker/Data/Enumerations.cs +++ b/CardMaker/Data/Enumerations.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Data/LayoutTemplateManager.cs b/CardMaker/Data/LayoutTemplateManager.cs index 0d00a4de..7fa92aaf 100644 --- a/CardMaker/Data/LayoutTemplateManager.cs +++ b/CardMaker/Data/LayoutTemplateManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/DeckChangeEventArgs.cs b/CardMaker/Events/Args/DeckChangeEventArgs.cs index b285f731..0f22eefb 100644 --- a/CardMaker/Events/Args/DeckChangeEventArgs.cs +++ b/CardMaker/Events/Args/DeckChangeEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/ElementEventArgs.cs b/CardMaker/Events/Args/ElementEventArgs.cs index a49b9886..abd0982a 100644 --- a/CardMaker/Events/Args/ElementEventArgs.cs +++ b/CardMaker/Events/Args/ElementEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/ExportEventArgs.cs b/CardMaker/Events/Args/ExportEventArgs.cs index d3179492..65a94eab 100644 --- a/CardMaker/Events/Args/ExportEventArgs.cs +++ b/CardMaker/Events/Args/ExportEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/GoogleAuthEventArgs.cs b/CardMaker/Events/Args/GoogleAuthEventArgs.cs index 99609baa..9e2d1787 100644 --- a/CardMaker/Events/Args/GoogleAuthEventArgs.cs +++ b/CardMaker/Events/Args/GoogleAuthEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/IssueCardInfoEventArgs.cs b/CardMaker/Events/Args/IssueCardInfoEventArgs.cs index fbc687b2..5028d23b 100644 --- a/CardMaker/Events/Args/IssueCardInfoEventArgs.cs +++ b/CardMaker/Events/Args/IssueCardInfoEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/IssueElementEventArgs.cs b/CardMaker/Events/Args/IssueElementEventArgs.cs index fbb4e9fe..2cf3fbf5 100644 --- a/CardMaker/Events/Args/IssueElementEventArgs.cs +++ b/CardMaker/Events/Args/IssueElementEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/IssueMessageEventArgs.cs b/CardMaker/Events/Args/IssueMessageEventArgs.cs index 60b6eda4..c1fa5be5 100644 --- a/CardMaker/Events/Args/IssueMessageEventArgs.cs +++ b/CardMaker/Events/Args/IssueMessageEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/IssueRefreshEventArgs.cs b/CardMaker/Events/Args/IssueRefreshEventArgs.cs index 351be2e8..f38f1941 100644 --- a/CardMaker/Events/Args/IssueRefreshEventArgs.cs +++ b/CardMaker/Events/Args/IssueRefreshEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/LayoutElementNumericAdjustEventArgs.cs b/CardMaker/Events/Args/LayoutElementNumericAdjustEventArgs.cs index ebb4d0c6..3dd36909 100644 --- a/CardMaker/Events/Args/LayoutElementNumericAdjustEventArgs.cs +++ b/CardMaker/Events/Args/LayoutElementNumericAdjustEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/LayoutEventArgs.cs b/CardMaker/Events/Args/LayoutEventArgs.cs index 8542d8e8..931ca975 100644 --- a/CardMaker/Events/Args/LayoutEventArgs.cs +++ b/CardMaker/Events/Args/LayoutEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Args/ProjectEventArgs.cs b/CardMaker/Events/Args/ProjectEventArgs.cs index 45f7e755..ec768e4f 100644 --- a/CardMaker/Events/Args/ProjectEventArgs.cs +++ b/CardMaker/Events/Args/ProjectEventArgs.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Managers/AutoSaveManager.cs b/CardMaker/Events/Managers/AutoSaveManager.cs index 62bf4482..990f66a8 100644 --- a/CardMaker/Events/Managers/AutoSaveManager.cs +++ b/CardMaker/Events/Managers/AutoSaveManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Managers/ElementManager.cs b/CardMaker/Events/Managers/ElementManager.cs index 7ae47112..15bc773c 100644 --- a/CardMaker/Events/Managers/ElementManager.cs +++ b/CardMaker/Events/Managers/ElementManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Managers/ExportManager.cs b/CardMaker/Events/Managers/ExportManager.cs index 541946dd..de9a2a62 100644 --- a/CardMaker/Events/Managers/ExportManager.cs +++ b/CardMaker/Events/Managers/ExportManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Managers/GoogleAuthManager.cs b/CardMaker/Events/Managers/GoogleAuthManager.cs index b3f59d1e..c043ff74 100644 --- a/CardMaker/Events/Managers/GoogleAuthManager.cs +++ b/CardMaker/Events/Managers/GoogleAuthManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Managers/IssueManager.cs b/CardMaker/Events/Managers/IssueManager.cs index dd9b0b85..8f7bf2ec 100644 --- a/CardMaker/Events/Managers/IssueManager.cs +++ b/CardMaker/Events/Managers/IssueManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Managers/LayoutManager.cs b/CardMaker/Events/Managers/LayoutManager.cs index eb447550..17809710 100644 --- a/CardMaker/Events/Managers/LayoutManager.cs +++ b/CardMaker/Events/Managers/LayoutManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Events/Managers/ProjectManager.cs b/CardMaker/Events/Managers/ProjectManager.cs index 88546dab..d7b26415 100644 --- a/CardMaker/Events/Managers/ProjectManager.cs +++ b/CardMaker/Events/Managers/ProjectManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/CardMakerMDI.Designer.cs b/CardMaker/Forms/CardMakerMDI.Designer.cs index 60c1a1ab..d7dd29d3 100644 --- a/CardMaker/Forms/CardMakerMDI.Designer.cs +++ b/CardMaker/Forms/CardMakerMDI.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/CardMakerMDI.cs b/CardMaker/Forms/CardMakerMDI.cs index ffc8e029..9f99b7e7 100644 --- a/CardMaker/Forms/CardMakerMDI.cs +++ b/CardMaker/Forms/CardMakerMDI.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/Dialogs/ProjectSettingsDialog.cs b/CardMaker/Forms/Dialogs/ProjectSettingsDialog.cs index 23dcd5ef..e80f0f90 100644 --- a/CardMaker/Forms/Dialogs/ProjectSettingsDialog.cs +++ b/CardMaker/Forms/Dialogs/ProjectSettingsDialog.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/FormUtils.cs b/CardMaker/Forms/FormUtils.cs index 41973680..87622085 100644 --- a/CardMaker/Forms/FormUtils.cs +++ b/CardMaker/Forms/FormUtils.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/GoogleCredentialsDialog.Designer.cs b/CardMaker/Forms/GoogleCredentialsDialog.Designer.cs index c178f137..c50ee0e6 100644 --- a/CardMaker/Forms/GoogleCredentialsDialog.Designer.cs +++ b/CardMaker/Forms/GoogleCredentialsDialog.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/GoogleCredentialsDialog.cs b/CardMaker/Forms/GoogleCredentialsDialog.cs index 7282d895..9c6a4d0f 100644 --- a/CardMaker/Forms/GoogleCredentialsDialog.cs +++ b/CardMaker/Forms/GoogleCredentialsDialog.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDICanvas.Designer.cs b/CardMaker/Forms/MDICanvas.Designer.cs index 598c028d..f69742a3 100644 --- a/CardMaker/Forms/MDICanvas.Designer.cs +++ b/CardMaker/Forms/MDICanvas.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDICanvas.cs b/CardMaker/Forms/MDICanvas.cs index e91224ce..f771e299 100644 --- a/CardMaker/Forms/MDICanvas.cs +++ b/CardMaker/Forms/MDICanvas.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIDefines.Designer.cs b/CardMaker/Forms/MDIDefines.Designer.cs index e969aef4..2476efb4 100644 --- a/CardMaker/Forms/MDIDefines.Designer.cs +++ b/CardMaker/Forms/MDIDefines.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIDefines.cs b/CardMaker/Forms/MDIDefines.cs index efe742b3..f0bbdb56 100644 --- a/CardMaker/Forms/MDIDefines.cs +++ b/CardMaker/Forms/MDIDefines.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIElementControl.Designer.cs b/CardMaker/Forms/MDIElementControl.Designer.cs index e5d7715a..db8c4b0e 100644 --- a/CardMaker/Forms/MDIElementControl.Designer.cs +++ b/CardMaker/Forms/MDIElementControl.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIElementControl.cs b/CardMaker/Forms/MDIElementControl.cs index 3eb23d8f..705c98ec 100644 --- a/CardMaker/Forms/MDIElementControl.cs +++ b/CardMaker/Forms/MDIElementControl.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIIssues.Designer.cs b/CardMaker/Forms/MDIIssues.Designer.cs index 8ee46fa7..8d4d1594 100644 --- a/CardMaker/Forms/MDIIssues.Designer.cs +++ b/CardMaker/Forms/MDIIssues.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIIssues.cs b/CardMaker/Forms/MDIIssues.cs index 39a8522f..b249ccb0 100644 --- a/CardMaker/Forms/MDIIssues.cs +++ b/CardMaker/Forms/MDIIssues.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDILayoutControl.Designer.cs b/CardMaker/Forms/MDILayoutControl.Designer.cs index 5c7fcc1c..26a9350e 100644 --- a/CardMaker/Forms/MDILayoutControl.Designer.cs +++ b/CardMaker/Forms/MDILayoutControl.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDILayoutControl.cs b/CardMaker/Forms/MDILayoutControl.cs index e568e6a2..bc7d17c9 100644 --- a/CardMaker/Forms/MDILayoutControl.cs +++ b/CardMaker/Forms/MDILayoutControl.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDILogger.Designer.cs b/CardMaker/Forms/MDILogger.Designer.cs index e83d907a..4b9b8467 100644 --- a/CardMaker/Forms/MDILogger.Designer.cs +++ b/CardMaker/Forms/MDILogger.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDILogger.cs b/CardMaker/Forms/MDILogger.cs index 80a27cc7..bc679e93 100644 --- a/CardMaker/Forms/MDILogger.cs +++ b/CardMaker/Forms/MDILogger.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIProject.Designer.cs b/CardMaker/Forms/MDIProject.Designer.cs index ea8b1e19..0e82e91d 100644 --- a/CardMaker/Forms/MDIProject.Designer.cs +++ b/CardMaker/Forms/MDIProject.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/MDIProject.cs b/CardMaker/Forms/MDIProject.cs index 912ff4ae..cedfa3ea 100644 --- a/CardMaker/Forms/MDIProject.cs +++ b/CardMaker/Forms/MDIProject.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/ProjectManagerUI.Designer.cs b/CardMaker/Forms/ProjectManagerUI.Designer.cs index 4732945f..f0228aa9 100644 --- a/CardMaker/Forms/ProjectManagerUI.Designer.cs +++ b/CardMaker/Forms/ProjectManagerUI.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Forms/ProjectManagerUI.cs b/CardMaker/Forms/ProjectManagerUI.cs index 231a0e5a..d025153c 100644 --- a/CardMaker/Forms/ProjectManagerUI.cs +++ b/CardMaker/Forms/ProjectManagerUI.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Program.cs b/CardMaker/Program.cs index 0abacef2..cbcd17f1 100644 --- a/CardMaker/Program.cs +++ b/CardMaker/Program.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Properties/AssemblyInfo.cs b/CardMaker/Properties/AssemblyInfo.cs index 057d5f1e..21dbe1ee 100644 --- a/CardMaker/Properties/AssemblyInfo.cs +++ b/CardMaker/Properties/AssemblyInfo.cs @@ -9,7 +9,7 @@ [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("NHMK")] [assembly: AssemblyProduct("Card Maker")] -[assembly: AssemblyCopyright("Copyright © NHMK 2019")] +[assembly: AssemblyCopyright("Copyright © NHMK 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/CardMaker/Support/Google/GoogleApi.cs b/CardMaker/Support/Google/GoogleApi.cs index 8017d5e1..3f3afc99 100644 --- a/CardMaker/Support/Google/GoogleApi.cs +++ b/CardMaker/Support/Google/GoogleApi.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Google/GoogleInitializerFactory.cs b/CardMaker/Support/Google/GoogleInitializerFactory.cs index fdea1278..69c7ea3f 100644 --- a/CardMaker/Support/Google/GoogleInitializerFactory.cs +++ b/CardMaker/Support/Google/GoogleInitializerFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Google/Sheets/GoogleSheetInfo.cs b/CardMaker/Support/Google/Sheets/GoogleSheetInfo.cs index 8ab3cf8a..45b5b7df 100644 --- a/CardMaker/Support/Google/Sheets/GoogleSheetInfo.cs +++ b/CardMaker/Support/Google/Sheets/GoogleSheetInfo.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Google/Sheets/GoogleSpreadsheet.cs b/CardMaker/Support/Google/Sheets/GoogleSpreadsheet.cs index e7f50c1c..b95530d9 100644 --- a/CardMaker/Support/Google/Sheets/GoogleSpreadsheet.cs +++ b/CardMaker/Support/Google/Sheets/GoogleSpreadsheet.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.Designer.cs b/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.Designer.cs index e0bef9dd..d444041e 100644 --- a/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.Designer.cs +++ b/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs b/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs index ffd28b12..1e132f91 100644 --- a/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs +++ b/CardMaker/Support/Google/Sheets/GoogleSpreadsheetBrowser.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/IO/CSVFile.cs b/CardMaker/Support/IO/CSVFile.cs index e92553fe..ba920950 100644 --- a/CardMaker/Support/IO/CSVFile.cs +++ b/CardMaker/Support/IO/CSVFile.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/IO/INIManager.cs b/CardMaker/Support/IO/INIManager.cs index 0e7536b2..6957ab10 100644 --- a/CardMaker/Support/IO/INIManager.cs +++ b/CardMaker/Support/IO/INIManager.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/IO/IOUtils.cs b/CardMaker/Support/IO/IOUtils.cs index 8cd3bdc3..bca81ffe 100644 --- a/CardMaker/Support/IO/IOUtils.cs +++ b/CardMaker/Support/IO/IOUtils.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/IO/Logger.cs b/CardMaker/Support/IO/Logger.cs index 421cfb3d..bbdac98f 100644 --- a/CardMaker/Support/IO/Logger.cs +++ b/CardMaker/Support/IO/Logger.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/IO/SerializationUtils.cs b/CardMaker/Support/IO/SerializationUtils.cs index fc3eca83..c2fdb073 100644 --- a/CardMaker/Support/IO/SerializationUtils.cs +++ b/CardMaker/Support/IO/SerializationUtils.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Progress/ConsoleProgressReporter.cs b/CardMaker/Support/Progress/ConsoleProgressReporter.cs index a30ec4a7..4b818402 100644 --- a/CardMaker/Support/Progress/ConsoleProgressReporter.cs +++ b/CardMaker/Support/Progress/ConsoleProgressReporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs b/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs index db68910a..2279a757 100644 --- a/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs +++ b/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Progress/IProgressReporter.cs b/CardMaker/Support/Progress/IProgressReporter.cs index c4013d02..d552e3a5 100644 --- a/CardMaker/Support/Progress/IProgressReporter.cs +++ b/CardMaker/Support/Progress/IProgressReporter.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Progress/ProgressReporterFactory.cs b/CardMaker/Support/Progress/ProgressReporterFactory.cs index 62605fb7..3ea70cb0 100644 --- a/CardMaker/Support/Progress/ProgressReporterFactory.cs +++ b/CardMaker/Support/Progress/ProgressReporterFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Progress/ProgressReporterProxy.cs b/CardMaker/Support/Progress/ProgressReporterProxy.cs index cd63c891..dbe4d87e 100644 --- a/CardMaker/Support/Progress/ProgressReporterProxy.cs +++ b/CardMaker/Support/Progress/ProgressReporterProxy.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs b/CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs index f3c8091b..669483e7 100644 --- a/CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs +++ b/CardMaker/Support/Progress/WaitDialogLineProgressReporterFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/AbstractDirtyForm.cs b/CardMaker/Support/UI/AbstractDirtyForm.cs index 5cdffed6..ea0f8085 100644 --- a/CardMaker/Support/UI/AbstractDirtyForm.cs +++ b/CardMaker/Support/UI/AbstractDirtyForm.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/Extensions.cs b/CardMaker/Support/UI/Extensions.cs index 044ebfb8..80a8b44c 100644 --- a/CardMaker/Support/UI/Extensions.cs +++ b/CardMaker/Support/UI/Extensions.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/ListViewAssist.cs b/CardMaker/Support/UI/ListViewAssist.cs index cac3a4b8..b051e656 100644 --- a/CardMaker/Support/UI/ListViewAssist.cs +++ b/CardMaker/Support/UI/ListViewAssist.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/ListViewDoubleBuffer.cs b/CardMaker/Support/UI/ListViewDoubleBuffer.cs index a36cebb7..5fac6f24 100644 --- a/CardMaker/Support/UI/ListViewDoubleBuffer.cs +++ b/CardMaker/Support/UI/ListViewDoubleBuffer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/ListViewItemComparer.cs b/CardMaker/Support/UI/ListViewItemComparer.cs index 22c740cc..71b227f5 100644 --- a/CardMaker/Support/UI/ListViewItemComparer.cs +++ b/CardMaker/Support/UI/ListViewItemComparer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/PanelEx.cs b/CardMaker/Support/UI/PanelEx.cs index 5871071b..81f99995 100644 --- a/CardMaker/Support/UI/PanelEx.cs +++ b/CardMaker/Support/UI/PanelEx.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/QueryPanel.cs b/CardMaker/Support/UI/QueryPanel.cs index 298d3fd6..277754bd 100644 --- a/CardMaker/Support/UI/QueryPanel.cs +++ b/CardMaker/Support/UI/QueryPanel.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/QueryPanelDialog.cs b/CardMaker/Support/UI/QueryPanelDialog.cs index f84487dd..aaaeeed5 100644 --- a/CardMaker/Support/UI/QueryPanelDialog.cs +++ b/CardMaker/Support/UI/QueryPanelDialog.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/RGBColorSelectDialog.Designer.cs b/CardMaker/Support/UI/RGBColorSelectDialog.Designer.cs index 5e0fcca0..d4eedc79 100644 --- a/CardMaker/Support/UI/RGBColorSelectDialog.Designer.cs +++ b/CardMaker/Support/UI/RGBColorSelectDialog.Designer.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/RGBColorSelectDialog.cs b/CardMaker/Support/UI/RGBColorSelectDialog.cs index f80aab15..ca345b37 100644 --- a/CardMaker/Support/UI/RGBColorSelectDialog.cs +++ b/CardMaker/Support/UI/RGBColorSelectDialog.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/UserAction.cs b/CardMaker/Support/UI/UserAction.cs index a2d89910..f4f01401 100644 --- a/CardMaker/Support/UI/UserAction.cs +++ b/CardMaker/Support/UI/UserAction.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/WaitDialog.cs b/CardMaker/Support/UI/WaitDialog.cs index 4b6831fb..d65c8f21 100644 --- a/CardMaker/Support/UI/WaitDialog.cs +++ b/CardMaker/Support/UI/WaitDialog.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/UI/Win32.cs b/CardMaker/Support/UI/Win32.cs index 4bd6e822..82c791c8 100644 --- a/CardMaker/Support/UI/Win32.cs +++ b/CardMaker/Support/UI/Win32.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Util/CommandLineParser.cs b/CardMaker/Support/Util/CommandLineParser.cs index b9a4764a..c5dcf0b8 100644 --- a/CardMaker/Support/Util/CommandLineParser.cs +++ b/CardMaker/Support/Util/CommandLineParser.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Util/ParseUtil.cs b/CardMaker/Support/Util/ParseUtil.cs index c10bad62..adc4ba36 100644 --- a/CardMaker/Support/Util/ParseUtil.cs +++ b/CardMaker/Support/Util/ParseUtil.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Support/Util/TimeMeasure.cs b/CardMaker/Support/Util/TimeMeasure.cs index d1e94b87..af8fb60c 100644 --- a/CardMaker/Support/Util/TimeMeasure.cs +++ b/CardMaker/Support/Util/TimeMeasure.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs b/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs index 2d28f3b6..f90eda13 100644 --- a/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs +++ b/CardMaker/Test/UnitTest/DeckObject/ElementOverride.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/DeckObject/FormattedText.cs b/CardMaker/Test/UnitTest/DeckObject/FormattedText.cs index 89a14477..994d670e 100644 --- a/CardMaker/Test/UnitTest/DeckObject/FormattedText.cs +++ b/CardMaker/Test/UnitTest/DeckObject/FormattedText.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs b/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs index 392d548c..2d72b005 100644 --- a/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs +++ b/CardMaker/Test/UnitTest/DeckObject/InceptStringTranslation.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/DeckObject/InlineBackgroundElementProcessorTest.cs b/CardMaker/Test/UnitTest/DeckObject/InlineBackgroundElementProcessorTest.cs index 821949e0..f2ab49c8 100644 --- a/CardMaker/Test/UnitTest/DeckObject/InlineBackgroundElementProcessorTest.cs +++ b/CardMaker/Test/UnitTest/DeckObject/InlineBackgroundElementProcessorTest.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs b/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs index 6e86d985..9cfb6689 100644 --- a/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs +++ b/CardMaker/Test/UnitTest/DeckObject/JavaScriptStringTranslation.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/DeckObject/JavaScriptTranslatorFactory.cs b/CardMaker/Test/UnitTest/DeckObject/JavaScriptTranslatorFactory.cs index 28a0e9cd..2c76ff4e 100644 --- a/CardMaker/Test/UnitTest/DeckObject/JavaScriptTranslatorFactory.cs +++ b/CardMaker/Test/UnitTest/DeckObject/JavaScriptTranslatorFactory.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs b/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs index a13ebc1c..094b06c1 100644 --- a/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs +++ b/CardMaker/Test/UnitTest/DeckObject/TestDeck.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/Test/UnitTest/Support/Util/ParseUtilTest.cs b/CardMaker/Test/UnitTest/Support/Util/ParseUtilTest.cs index 887901ed..e1ef092b 100644 --- a/CardMaker/Test/UnitTest/Support/Util/ParseUtilTest.cs +++ b/CardMaker/Test/UnitTest/Support/Util/ParseUtilTest.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/XML/LayoutTemplate.cs b/CardMaker/XML/LayoutTemplate.cs index 98ae7a84..e441a496 100644 --- a/CardMaker/XML/LayoutTemplate.cs +++ b/CardMaker/XML/LayoutTemplate.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/XML/Project.cs b/CardMaker/XML/Project.cs index 2a9f4ffd..a110a045 100644 --- a/CardMaker/XML/Project.cs +++ b/CardMaker/XML/Project.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/XML/ProjectLayout.cs b/CardMaker/XML/ProjectLayout.cs index cb9a13bf..ce54cde4 100644 --- a/CardMaker/XML/ProjectLayout.cs +++ b/CardMaker/XML/ProjectLayout.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/XML/ProjectLayoutElement.cs b/CardMaker/XML/ProjectLayoutElement.cs index d757008a..82625671 100644 --- a/CardMaker/XML/ProjectLayoutElement.cs +++ b/CardMaker/XML/ProjectLayoutElement.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal diff --git a/CardMaker/XML/ProjectLayoutReference.cs b/CardMaker/XML/ProjectLayoutReference.cs index 68432898..40fb1eb1 100644 --- a/CardMaker/XML/ProjectLayoutReference.cs +++ b/CardMaker/XML/ProjectLayoutReference.cs @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // The MIT License (MIT) // -// Copyright (c) 2019 Tim Stair +// Copyright (c) 2020 Tim Stair // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal From b5a37783976bf736c3693d384279f07e64c9b587 Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Tue, 19 May 2020 09:20:10 -0700 Subject: [PATCH 3/9] Quick fix for hiding console and loading refs. --- CardMaker/Card/Import/ReferenceReaderFactory.cs | 4 ++-- CardMaker/CardMakerBuild.cs | 2 +- CardMaker/Program.cs | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CardMaker/Card/Import/ReferenceReaderFactory.cs b/CardMaker/Card/Import/ReferenceReaderFactory.cs index 78ddffac..5afb6715 100644 --- a/CardMaker/Card/Import/ReferenceReaderFactory.cs +++ b/CardMaker/Card/Import/ReferenceReaderFactory.cs @@ -76,11 +76,11 @@ public static ReferenceReader GetDefineReader(ReferenceType eReferenceType, IPro break; } - if (zReferenceReader == null) + if (zReferenceReader != null) { zReferenceReader.ProgressReporter = zProgressReporter; } - return null; + return zReferenceReader; } } } diff --git a/CardMaker/CardMakerBuild.cs b/CardMaker/CardMakerBuild.cs index b1e6f9dd..4ea1e3ee 100644 --- a/CardMaker/CardMakerBuild.cs +++ b/CardMaker/CardMakerBuild.cs @@ -31,7 +31,7 @@ public static class CardMakerBuild public static string GetBuildSuffix() { #if UNSTABLE - return "[UNSTABLE] V.A11"; + return "[UNSTABLE] V.A11-1"; #else return string.Empty; #endif diff --git a/CardMaker/Program.cs b/CardMaker/Program.cs index cbcd17f1..ded2aa2f 100644 --- a/CardMaker/Program.cs +++ b/CardMaker/Program.cs @@ -26,10 +26,9 @@ using System.Windows.Forms; using CardMaker.Card.CommandLine; using CardMaker.Card.Shapes; -using CardMaker.Card.Translation; using CardMaker.Data; using CardMaker.Forms; -using Support.IO; +using Support.UI; using Support.Util; namespace CardMaker @@ -49,6 +48,9 @@ static void Main(string[] args) var commandLineProcessor = new CommandLineProcessor(new CommandLineParser().Parse(args)); if (!commandLineProcessor.Process()) { +#if !MONO_BUILD + Win32.ShowConsole(Application.ExecutablePath, false); +#endif Application.Run(new CardMakerMDI()); } } From 91e52e6385b32a440b3fb63a2ac4714650b11f99 Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Tue, 19 May 2020 13:53:23 -0700 Subject: [PATCH 4/9] More changes around command line validation. --- .../CommandLine/CommandLineExporterBase.cs | 45 ++++- .../Card/CommandLine/CommandLineProcessor.cs | 25 ++- CardMaker/Card/CommandLine/CommandLineUtil.cs | 41 ++++ .../CommandLine/ImageCommandLineExporter.cs | 30 +-- .../CommandLine/PDFCommandLineExporter.cs | 29 +-- CardMaker/Card/Export/FileCardExporter.cs | 1 - .../Card/Import/ReferenceReaderFactory.cs | 179 +++++++++--------- CardMaker/CardMaker.csproj | 1 + CardMaker/CardMaker_Mono.csproj | 3 +- CardMaker/Program.cs | 5 +- 10 files changed, 204 insertions(+), 155 deletions(-) create mode 100644 CardMaker/Card/CommandLine/CommandLineUtil.cs diff --git a/CardMaker/Card/CommandLine/CommandLineExporterBase.cs b/CardMaker/Card/CommandLine/CommandLineExporterBase.cs index 2600961a..5ea8d1d3 100644 --- a/CardMaker/Card/CommandLine/CommandLineExporterBase.cs +++ b/CardMaker/Card/CommandLine/CommandLineExporterBase.cs @@ -30,6 +30,7 @@ using CardMaker.Data; using CardMaker.Events.Managers; using PdfSharp; +using Support.UI; using Support.Util; namespace CardMaker.Card.CommandLine @@ -37,9 +38,33 @@ namespace CardMaker.Card.CommandLine public abstract class CommandLineExporterBase { public CommandLineParser CommandLineParser { get; set; } - - public abstract bool Validate(); - public abstract bool Export(); + public CommandLineUtil CommandLineUtil { get; set; } + protected string Description { get; set; } + + public abstract CardExportBase CreateExporter(); + + /// + /// Performs the export action + /// + /// true on success, false otherwise + public bool Export() + { + var zFileCardExporter = CreateExporter(); + zFileCardExporter.ProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( + Description, + new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA, ProgressName.CARD }, + zFileCardExporter.ExportThread); + try + { + zFileCardExporter.ProgressReporter.StartProcessing(null); + return true; + } + catch (Exception e) + { + CommandLineUtil.ExitWithError("Export failed. " + e); + return false; + } + } /// /// Gets the layout indices @@ -54,7 +79,12 @@ protected int[] GetLayoutIndices() var idx = 0; var dictionaryLayoutNameToLayout = ProjectManager.Instance.LoadedProject.Layout.ToDictionary(layout => layout.Name.ToUpper(), layout => idx++); -#warning Might be nice to alert/log if they specify a bad layout name + var listMissingLayout = arrayLayoutNames + .Where(sLayoutName => !dictionaryLayoutNameToLayout.ContainsKey(sLayoutName.ToUpper())).ToList(); + if (listMissingLayout.Count > 0) + { + CommandLineUtil.ExitWithError("Invalid layout names specified: " + string.Join(",", listMissingLayout.ToArray())); + } return arrayLayoutNames .Where(sLayoutName => dictionaryLayoutNameToLayout.ContainsKey(sLayoutName.ToUpper())) .Select(sLayoutName => dictionaryLayoutNameToLayout[sLayoutName.ToUpper()]).ToArray(); @@ -90,7 +120,7 @@ public int[] GetCardIndices() } else { -#warning should error + CommandLineUtil.ExitWithError("Invalid Card Index: " + sRange); } break; case 2: @@ -100,12 +130,11 @@ public int[] GetCardIndices() } else { -#warning should error + CommandLineUtil.ExitWithError("Invalid Card Index Range: " + sRange); } break; default: -#warning should error - // error + CommandLineUtil.ExitWithError("Invalid Card Index Range: " + sRange); break; } } diff --git a/CardMaker/Card/CommandLine/CommandLineProcessor.cs b/CardMaker/Card/CommandLine/CommandLineProcessor.cs index 41c5d62b..ebb1d948 100644 --- a/CardMaker/Card/CommandLine/CommandLineProcessor.cs +++ b/CardMaker/Card/CommandLine/CommandLineProcessor.cs @@ -37,6 +37,8 @@ namespace CardMaker.Card.CommandLine { public class CommandLineProcessor { + public CommandLineUtil CommandLineUtil { get; set; } + private static readonly Dictionary dictionaryExporterType = new Dictionary() { { "PDF", typeof(PDFCommandLineExporter) }, @@ -52,6 +54,11 @@ static CommandLineProcessor() } } + protected CommandLineProcessor() + { + CommandLineUtil = new CommandLineUtil(); + } + /// /// /// @@ -97,14 +104,14 @@ private bool PerformExport() { var zExporter = (CommandLineExporterBase) Activator.CreateInstance(typeExporter); zExporter.CommandLineParser = m_zCommandLineParser; - if (!zExporter.Validate()) - { - return false; - } + zExporter.CommandLineUtil = CommandLineUtil; zExporter.ConfigureGoogleCredential(); - return zExporter.Export(); } + else + { + CommandLineUtil.ExitWithError("Invalid export format specified: " + sExportFormat); + } return false; } @@ -116,14 +123,18 @@ private bool PerformExport() private bool LoadProject() { CardMakerInstance.CommandLineProjectFile = m_zCommandLineParser.GetStringArg(CommandLineArg.ProjectPath); ; + if (!File.Exists(CardMakerInstance.CommandLineProjectFile)) + { + CommandLineUtil.ExitWithError("Project file does not exist: " + CardMakerInstance.CommandLineProjectFile); + } + try { ProjectManager.Instance.OpenProject(CardMakerInstance.CommandLineProjectFile); } catch (Exception ex) { - Logger.AddLogLine("Failed to load project: {0}".FormatString(CardMakerInstance.CommandLineProjectFile)); - Logger.AddLogLine(ex.ToString()); + Logger.AddLogLine("Failed to load project: {0}--{1}".FormatString(CardMakerInstance.CommandLineProjectFile, ex.ToString())); return false; } return true; diff --git a/CardMaker/Card/CommandLine/CommandLineUtil.cs b/CardMaker/Card/CommandLine/CommandLineUtil.cs new file mode 100644 index 00000000..6f1a8b4d --- /dev/null +++ b/CardMaker/Card/CommandLine/CommandLineUtil.cs @@ -0,0 +1,41 @@ +/////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2020 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using System; + +namespace CardMaker.Card.CommandLine +{ + public class CommandLineUtil + { + /// + /// Exits the application with the error specified + /// + /// The error to report on exit + public void ExitWithError(string sError) + { + Console.WriteLine(sError); + Environment.Exit(1); + } + } +} diff --git a/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs b/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs index ac48775e..df7a9662 100644 --- a/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs +++ b/CardMaker/Card/CommandLine/ImageCommandLineExporter.cs @@ -22,44 +22,22 @@ // SOFTWARE. //////////////////////////////////////////////////////////////////////////////// -using System; using CardMaker.Card.Export; -using CardMaker.Data; -using Support.IO; using Support.UI; namespace CardMaker.Card.CommandLine { public class ImageCommandLineExporter : CommandLineExporterBase { - public override bool Validate() - { - return true; - } - - public override bool Export() + public override CardExportBase CreateExporter() { var sExportPath = GetExportPath(true); -#warning is page orientation saved on the layout? - var zFileCardExporter = new FileCardExporter(GetLayoutIndices(), sExportPath, null, 0, GetImageFormat()) + var eImageFormat = GetImageFormat(); + Description = "{0} Export - {1}".FormatString(eImageFormat.ToString(), sExportPath); + return new FileCardExporter(GetLayoutIndices(), sExportPath, null, 0, eImageFormat) { ExportCardIndices = GetCardIndices() }; - zFileCardExporter.ProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( - "PDF Export - {0}".FormatString(sExportPath), - new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA , ProgressName.CARD }, - zFileCardExporter.ExportThread); - try - { - zFileCardExporter.ProgressReporter.StartProcessing(null); - return true; - } - catch (Exception e) - { - Logger.AddLogLine(e.Message); - Logger.AddLogLine(e.StackTrace); - return false; - } } } } diff --git a/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs b/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs index aed3764b..7a2b5170 100644 --- a/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs +++ b/CardMaker/Card/CommandLine/PDFCommandLineExporter.cs @@ -22,41 +22,18 @@ // SOFTWARE. //////////////////////////////////////////////////////////////////////////////// -using System; using CardMaker.Card.Export; -using CardMaker.Data; -using Support.IO; using Support.UI; namespace CardMaker.Card.CommandLine { class PDFCommandLineExporter : CommandLineExporterBase { - public override bool Validate() - { - return true; - } - - public override bool Export() + public override CardExportBase CreateExporter() { var sExportPath = GetExportPath(false); -#warning is page orientation saved on the layout? - var zFileCardExporter = new PdfSharpExporter(GetLayoutIndices(), sExportPath, GetPageOrientation()); - zFileCardExporter.ProgressReporter = CardMakerInstance.ProgressReporterFactory.CreateReporter( - "PDF Export - {0}".FormatString(sExportPath), - new string[] { ProgressName.LAYOUT, ProgressName.REFERENCE_DATA, ProgressName.CARD }, - zFileCardExporter.ExportThread); - try - { - zFileCardExporter.ProgressReporter.StartProcessing(null); - return true; - } - catch (Exception e) - { - Logger.AddLogLine(e.Message); - Logger.AddLogLine(e.StackTrace); - return false; - } + Description = "PDF Export - {0}".FormatString(sExportPath); + return new PdfSharpExporter(GetLayoutIndices(), sExportPath, GetPageOrientation()); } } } diff --git a/CardMaker/Card/Export/FileCardExporter.cs b/CardMaker/Card/Export/FileCardExporter.cs index f9ba3db7..dd305899 100644 --- a/CardMaker/Card/Export/FileCardExporter.cs +++ b/CardMaker/Card/Export/FileCardExporter.cs @@ -29,7 +29,6 @@ using System.IO; using System.Linq; using CardMaker.Data; -using CardMaker.XML; using Support.IO; namespace CardMaker.Card.Export diff --git a/CardMaker/Card/Import/ReferenceReaderFactory.cs b/CardMaker/Card/Import/ReferenceReaderFactory.cs index 5afb6715..dbc6e8fa 100644 --- a/CardMaker/Card/Import/ReferenceReaderFactory.cs +++ b/CardMaker/Card/Import/ReferenceReaderFactory.cs @@ -1,86 +1,95 @@ -//////////////////////////////////////////////////////////////////////////////// -// The MIT License (MIT) -// -// Copyright (c) 2020 Tim Stair -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -//////////////////////////////////////////////////////////////////////////////// - -using CardMaker.Data; -using CardMaker.XML; -using Support.Progress; - -namespace CardMaker.Card.Import -{ - public static class ReferenceReaderFactory +//////////////////////////////////////////////////////////////////////////////// +// The MIT License (MIT) +// +// Copyright (c) 2020 Tim Stair +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +//////////////////////////////////////////////////////////////////////////////// + +using CardMaker.Data; +using CardMaker.XML; +using Support.Progress; + +namespace CardMaker.Card.Import +{ + public static class ReferenceReaderFactory { -#warning unify these lookups in both methods... static type dictionary or something... this is bleh - public static ReferenceReader GetReader(ProjectLayoutReference zReference, IProgressReporter zProgressReporter) - { - if (zReference == null) - { - return null; - } - - ReferenceReader zReader = null; - - if (zReference.RelativePath.StartsWith(GoogleSpreadsheetReference.GOOGLE_REFERENCE + - GoogleSpreadsheetReference.GOOGLE_REFERENCE_SPLIT_CHAR)) - { - zReader = new GoogleReferenceReader(zReference); - } - if (zReference.RelativePath.StartsWith(ExcelSpreadsheetReference.EXCEL_REFERENCE + - ExcelSpreadsheetReference.EXCEL_REFERENCE_SPLIT_CHAR)) - { - zReader = new ExcelReferenceReader(zReference); - } - - if (zReader == null) - { - zReader = new CSVReferenceReader(zReference); - } - - zReader.ProgressReporter = zProgressReporter; - return zReader; - } - - public static ReferenceReader GetDefineReader(ReferenceType eReferenceType, IProgressReporter zProgressReporter) - { - ReferenceReader zReferenceReader = null; - switch (eReferenceType) - { - case ReferenceType.CSV: - zReferenceReader = new CSVReferenceReader(); - break; - case ReferenceType.Google: - zReferenceReader = new GoogleReferenceReader(); - break; - case ReferenceType.Excel: - zReferenceReader = new ExcelReferenceReader(); - break; - } - - if (zReferenceReader != null) - { - zReferenceReader.ProgressReporter = zProgressReporter; - } - return zReferenceReader; - } - } -} + /// + /// Gets the reference reader based on the reference relative path. + /// NOTE: this uses a constructor that passes in the reference + /// + /// The reference to get the reader for + /// ProgressReporter for the Reader to use + /// Reference reader (defaults to CSV) + public static ReferenceReader GetReader(ProjectLayoutReference zReference, IProgressReporter zProgressReporter) + { + if (zReference == null) + { + return null; + } + ReferenceReader zReferenceReader = null; + if (zReference.RelativePath.StartsWith(GoogleSpreadsheetReference.GOOGLE_REFERENCE + + GoogleSpreadsheetReference.GOOGLE_REFERENCE_SPLIT_CHAR)) + { + zReferenceReader = new GoogleReferenceReader(zReference); + } + if (zReference.RelativePath.StartsWith(ExcelSpreadsheetReference.EXCEL_REFERENCE + + ExcelSpreadsheetReference.EXCEL_REFERENCE_SPLIT_CHAR)) + { + zReferenceReader = new ExcelReferenceReader(zReference); + } + if (null == zReferenceReader) + { + zReferenceReader = new CSVReferenceReader(zReference); + } + + zReferenceReader.ProgressReporter = zProgressReporter; + return zReferenceReader; + } + + /// + /// Gets the reference reader based on the type + /// + /// The type of reference to get the reader for + /// ProgressReporter for the Reader to use + /// Reference reader (defaults to null) + public static ReferenceReader GetDefineReader(ReferenceType eReferenceType, IProgressReporter zProgressReporter) + { + ReferenceReader zReferenceReader = null; + switch (eReferenceType) + { + case ReferenceType.CSV: + zReferenceReader = new CSVReferenceReader(); + break; + case ReferenceType.Google: + zReferenceReader = new GoogleReferenceReader(); + break; + case ReferenceType.Excel: + zReferenceReader = new ExcelReferenceReader(); + break; + } + + if (zReferenceReader != null) + { + zReferenceReader.ProgressReporter = zProgressReporter; + } + return zReferenceReader; + } + } +} diff --git a/CardMaker/CardMaker.csproj b/CardMaker/CardMaker.csproj index 3f1b8480..5bb4c553 100644 --- a/CardMaker/CardMaker.csproj +++ b/CardMaker/CardMaker.csproj @@ -167,6 +167,7 @@ + diff --git a/CardMaker/CardMaker_Mono.csproj b/CardMaker/CardMaker_Mono.csproj index 6a37ad52..8ad6c0b5 100644 --- a/CardMaker/CardMaker_Mono.csproj +++ b/CardMaker/CardMaker_Mono.csproj @@ -167,6 +167,7 @@ + @@ -549,4 +550,4 @@ - + \ No newline at end of file diff --git a/CardMaker/Program.cs b/CardMaker/Program.cs index ded2aa2f..a039e19c 100644 --- a/CardMaker/Program.cs +++ b/CardMaker/Program.cs @@ -45,7 +45,10 @@ static void Main(string[] args) Application.SetCompatibleTextRenderingDefault(false); Initialize(); - var commandLineProcessor = new CommandLineProcessor(new CommandLineParser().Parse(args)); + var commandLineProcessor = new CommandLineProcessor(new CommandLineParser().Parse(args)) + { + CommandLineUtil = new CommandLineUtil() + }; if (!commandLineProcessor.Process()) { #if !MONO_BUILD From 59cf694fcc059668b50618602b7aad7ac42213a7 Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Tue, 19 May 2020 14:48:54 -0700 Subject: [PATCH 5/9] Warning fixes and one undo fix. --- CardMaker/Card/DrawTextTextRenderer.cs | 5 ++++- CardMaker/Card/Export/CompilerCardExporter.cs | 1 - CardMaker/Card/Export/FileCardSingleExporter.cs | 2 -- .../Card/FormattedText/FormattedTextParser.cs | 2 +- .../Markup/BackgroundColorMarkup.cs | 2 -- CardMaker/Card/Import/CSVReferenceReader.cs | 2 -- CardMaker/Card/Import/ExcelReferenceReader.cs | 5 ----- CardMaker/Card/Import/GoogleReferenceReader.cs | 2 -- CardMaker/Card/Import/ReferenceReader.cs | 2 +- .../Card/InlineBackgroundElementProcessor.cs | 17 ----------------- CardMaker/Forms/MDIElementControl.cs | 14 ++++++++++---- CardMaker/Forms/MDILayoutControl.cs | 2 +- 12 files changed, 17 insertions(+), 39 deletions(-) diff --git a/CardMaker/Card/DrawTextTextRenderer.cs b/CardMaker/Card/DrawTextTextRenderer.cs index dd2358e2..2b7d4e2d 100644 --- a/CardMaker/Card/DrawTextTextRenderer.cs +++ b/CardMaker/Card/DrawTextTextRenderer.cs @@ -35,6 +35,9 @@ namespace CardMaker.Card { + /// + /// This is an UNUSED renderer + /// public class DrawTextTextRenderer : IDrawText { public void DrawText(Graphics zGraphics, ProjectLayoutElement zElement, string sInput) @@ -175,8 +178,8 @@ public void DrawText(Graphics zGraphics, ProjectLayoutElement zElement, string s // TODO: https://stackoverflow.com/questions/18838037/drawing-text-to-a-bitmap-with-textrenderer -#warning too bad this makes the font look terrible #if false +// too bad this makes the font look terrible var image = new Bitmap(zElement.width, zElement.height, PixelFormat.Format32bppArgb); // create memory buffer from desktop handle that supports alpha channel diff --git a/CardMaker/Card/Export/CompilerCardExporter.cs b/CardMaker/Card/Export/CompilerCardExporter.cs index 3e6e91e7..104f6fda 100644 --- a/CardMaker/Card/Export/CompilerCardExporter.cs +++ b/CardMaker/Card/Export/CompilerCardExporter.cs @@ -49,7 +49,6 @@ public override void ExportThread() { IssueManager.Instance.FireChangeCardInfoEvent(nIdx, 1); IssueManager.Instance.FireChangeElementEvent(string.Empty); -#warning there's no progress reporter ChangeExportLayoutIndex(nIdx); ProgressReporter.ProgressReset(progressCardIdx, 0, CurrentDeck.CardCount, 0); diff --git a/CardMaker/Card/Export/FileCardSingleExporter.cs b/CardMaker/Card/Export/FileCardSingleExporter.cs index 73bdcded..1f025005 100644 --- a/CardMaker/Card/Export/FileCardSingleExporter.cs +++ b/CardMaker/Card/Export/FileCardSingleExporter.cs @@ -28,12 +28,10 @@ using System.Globalization; using System.IO; using CardMaker.Data; -using Support.IO; using Support.UI; namespace CardMaker.Card.Export { -#warning Can this share with FileCardExporter? Seems like a likely dupe... public class FileCardSingleExporter : CardExportBase { private readonly string m_sExportFolder; diff --git a/CardMaker/Card/FormattedText/FormattedTextParser.cs b/CardMaker/Card/FormattedText/FormattedTextParser.cs index 390700cd..012fa74f 100644 --- a/CardMaker/Card/FormattedText/FormattedTextParser.cs +++ b/CardMaker/Card/FormattedText/FormattedTextParser.cs @@ -115,7 +115,7 @@ public static List GetMarkups(string sInput) var zMarkupTypeToSeek = MarkupUtil.GetMarkupType(sTagName); if (null != zMarkupTypeToSeek) { -#warning no markup stack support... + // NOTE: There is no support for nested stacked markups like asdas (if this matters...) for (int nMarkup = listMarkups.Count - 1; nMarkup > -1; nMarkup--) { if (listMarkups[nMarkup].GetType() == zMarkupTypeToSeek) diff --git a/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs b/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs index 642e88b1..63d3c6ab 100644 --- a/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/BackgroundColorMarkup.cs @@ -50,8 +50,6 @@ protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, Form var fMarkupXOffset = 0f; var fMarkupYOffset = 0f; - var fMarkupHeightAdjust = 0f; - var fMarkupYWidthAdjust = 0f; m_fAdditionalVerticalPixels = 0f; if (arrayComponents.Length > 0) diff --git a/CardMaker/Card/Import/CSVReferenceReader.cs b/CardMaker/Card/Import/CSVReferenceReader.cs index 358aa420..831832c9 100644 --- a/CardMaker/Card/Import/CSVReferenceReader.cs +++ b/CardMaker/Card/Import/CSVReferenceReader.cs @@ -34,8 +34,6 @@ namespace CardMaker.Card.Import { public class CSVReferenceReader : ReferenceReader { - public string ReferencePath { get; } - public CSVReferenceReader() { } public CSVReferenceReader(ProjectLayoutReference zReference) diff --git a/CardMaker/Card/Import/ExcelReferenceReader.cs b/CardMaker/Card/Import/ExcelReferenceReader.cs index 2c20924f..891924bb 100644 --- a/CardMaker/Card/Import/ExcelReferenceReader.cs +++ b/CardMaker/Card/Import/ExcelReferenceReader.cs @@ -22,14 +22,11 @@ // SOFTWARE. //////////////////////////////////////////////////////////////////////////////// -using System; using System.Collections.Generic; using System.IO; using CardMaker.Events.Managers; using CardMaker.XML; using ClosedXML.Excel; -using Support.IO; -using System.Runtime.InteropServices; namespace CardMaker.Card.Import { @@ -40,8 +37,6 @@ class ExcelReferenceReader : ReferenceReader // SheetName to Variables private readonly Dictionary>> m_dictionaryDataCache = new Dictionary>>(); - public string ReferencePath { get; } - public ExcelReferenceReader() { /* Intentionally do nothing */ } public ExcelReferenceReader(ProjectLayoutReference zReference) diff --git a/CardMaker/Card/Import/GoogleReferenceReader.cs b/CardMaker/Card/Import/GoogleReferenceReader.cs index 1b8b6363..2c2a5eb7 100644 --- a/CardMaker/Card/Import/GoogleReferenceReader.cs +++ b/CardMaker/Card/Import/GoogleReferenceReader.cs @@ -50,8 +50,6 @@ public class GoogleCacheItem private bool m_bCacheUpdated; - public string ReferencePath { get; } - public GoogleReferenceReader() { LoadCache(); diff --git a/CardMaker/Card/Import/ReferenceReader.cs b/CardMaker/Card/Import/ReferenceReader.cs index bc2622c2..d7dfe9ee 100644 --- a/CardMaker/Card/Import/ReferenceReader.cs +++ b/CardMaker/Card/Import/ReferenceReader.cs @@ -30,7 +30,7 @@ namespace CardMaker.Card.Import { public abstract class ReferenceReader { - public string ReferencePath { get; } + public string ReferencePath { get; protected set; } public IProgressReporter ProgressReporter { get; set; } public abstract void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData); diff --git a/CardMaker/Card/InlineBackgroundElementProcessor.cs b/CardMaker/Card/InlineBackgroundElementProcessor.cs index 57c73132..c614dee4 100644 --- a/CardMaker/Card/InlineBackgroundElementProcessor.cs +++ b/CardMaker/Card/InlineBackgroundElementProcessor.cs @@ -29,7 +29,6 @@ using CardMaker.Card.Shapes; using CardMaker.Data; using CardMaker.XML; -using DocumentFormat.OpenXml.Office2010.ExcelAc; using Support.Util; #warning these methods need a lot of cleanup... so much goofy duplication @@ -38,22 +37,6 @@ namespace CardMaker.Card { public class InlineBackgroundElementProcessor : IInlineBackgroundElementProcessor { - // 1 2 3 - private static readonly Regex regexGraphicBG = new Regex(@"(#bggraphic::)(.+?)(#)", RegexOptions.Compiled); - // #bggraphic:[image path]:[x offset]:[y offset]:[width adjust]:[height adjust]:[lock aspect ratio]:[tile size]:[horizontal align]:[vertical align]# - // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 - private static readonly Regex regexGraphicExtendedBG = new Regex(@"(#bggraphic::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(#)", RegexOptions.Compiled); - - // 1 2 3 4 5 - private static readonly Regex regexShapeBG = new Regex(@"(#bgshape::)(.+?)(::)(.+?)(#)", RegexOptions.Compiled); - - // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 - private static readonly Regex regexShapeExtendedBG = new Regex(@"(#bgshape::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(#)", RegexOptions.Compiled); - - // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 - private static readonly Regex regexShapeExtendedOpacityBG = new Regex(@"(#bgshape::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(::)(.+?)(#)", RegexOptions.Compiled); - - // TODO: lists of prioritized matches with methods to call for each match private List>> listGraphicProcessingPairs = new List>>() { diff --git a/CardMaker/Forms/MDIElementControl.cs b/CardMaker/Forms/MDIElementControl.cs index 705c98ec..8b7117e1 100644 --- a/CardMaker/Forms/MDIElementControl.cs +++ b/CardMaker/Forms/MDIElementControl.cs @@ -538,9 +538,15 @@ private void btnSetSizeToImage_Click(object sender, EventArgs e) } if (null != zBmp) { -#warning -- this is 2 events, not 1 (in the case of undo) - numericElementW.Value = zBmp.Width; - numericElementH.Value = zBmp.Height; + var nWidth = zElement.width; + var nHeight = zElement.height; + Action actionResizeImage = bRedo => + { + zElement.width = bRedo ? zBmp.Width : nWidth; + zElement.height = bRedo ? zBmp.Height : nHeight; + LayoutManager.Instance.FireLayoutUpdatedEvent(true); + }; + UserAction.PushAction(actionResizeImage, true); } } } @@ -560,13 +566,13 @@ private void listViewElementColumns_MouseClick(object sender, MouseEventArgs e) m_zContextMenu.Items.Add("Add Reference to [" + columnText + "] column", null, (osender, ea) => { + // TODO: move this logic into the translator classes and get the current translator from the current deck object if (TranslatorType.Incept == ProjectManager.Instance.LoadedProjectTranslatorType) { InsertVariableText("@[" + columnText + "]"); } else if(TranslatorType.JavaScript == ProjectManager.Instance.LoadedProjectTranslatorType) { -#warning this is a bit of a hack, this kind of logic should be handled by the translator InsertVariableText(columnText.StartsWith("~") ? columnText.Substring(1) : columnText); } }); diff --git a/CardMaker/Forms/MDILayoutControl.cs b/CardMaker/Forms/MDILayoutControl.cs index bc7d17c9..5ce74590 100644 --- a/CardMaker/Forms/MDILayoutControl.cs +++ b/CardMaker/Forms/MDILayoutControl.cs @@ -107,7 +107,7 @@ void Layout_Updated(object sender, LayoutEventArgs args) void Element_Selected(object sender, ElementEventArgs args) { - if (null != args.Elements && args.Elements.Count == 1) + if (null != args.Elements && args.Elements.Count == 1 && args.Elements[0] != null) { ChangeSelectedElement(args.Elements[0].name); } From e9eb69f22b1cb090a077a801c67608aab870577a Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Sat, 23 May 2020 06:04:54 -0700 Subject: [PATCH 6/9] Fix for the google token time initialization. --- CardMaker/CardMakerBuild.cs | 2 +- CardMaker/Support/Google/GoogleInitializerFactory.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CardMaker/CardMakerBuild.cs b/CardMaker/CardMakerBuild.cs index 4ea1e3ee..1aec09de 100644 --- a/CardMaker/CardMakerBuild.cs +++ b/CardMaker/CardMakerBuild.cs @@ -31,7 +31,7 @@ public static class CardMakerBuild public static string GetBuildSuffix() { #if UNSTABLE - return "[UNSTABLE] V.A11-1"; + return "[UNSTABLE] V.A11-2"; #else return string.Empty; #endif diff --git a/CardMaker/Support/Google/GoogleInitializerFactory.cs b/CardMaker/Support/Google/GoogleInitializerFactory.cs index 69c7ea3f..e05f4565 100644 --- a/CardMaker/Support/Google/GoogleInitializerFactory.cs +++ b/CardMaker/Support/Google/GoogleInitializerFactory.cs @@ -69,7 +69,7 @@ public BaseClientService.Initializer CreateInitializer() { AccessToken = AccessToken, ExpiresInSeconds = TokenExpirationSeconds, - Issued = DateTime.UtcNow + Issued = DateTime.Now }; var zUserCredential = new UserCredential(zAuthCodeFlow, Environment.UserName, zTokenResponse); From 44f1650afa85fe93982fa0248b317fcca490f804 Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Sat, 6 Jun 2020 18:09:30 -0700 Subject: [PATCH 7/9] Fixed/improved some long standing issues. Google authentication flows for adding references and updating the project define are no longer interrupted if the credentials are unset. Also changed reference loading to be multi-threaded/faster! --- CardMaker/Card/Deck.cs | 83 ++++++++++++------- CardMaker/Card/Import/ReferenceReader.cs | 15 ++++ .../Events/Managers/GoogleAuthManager.cs | 4 +- CardMaker/bin/Release/History.txt | 2 + 4 files changed, 72 insertions(+), 32 deletions(-) diff --git a/CardMaker/Card/Deck.cs b/CardMaker/Card/Deck.cs index cb7df42b..775505cd 100644 --- a/CardMaker/Card/Deck.cs +++ b/CardMaker/Card/Deck.cs @@ -24,6 +24,8 @@ using System; using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using System.Windows.Forms; using CardMaker.Card.FormattedText; using CardMaker.Card.Import; @@ -135,6 +137,7 @@ private void ReadDataCore(object zRefData) var listLines = new List>(); var listDefineLines = new List>(); + var listReferenceDefineLines = new List>(); ReferenceReader zRefReader = null; @@ -144,6 +147,7 @@ private void ReadDataCore(object zRefData) } else { + // 2 per reference + 1 for the project wide defines m_zReporterProxy.ProgressReset(0, zReferenceData.Length * 2 + 1, 0); for(int nIdx = 0; nIdx < zReferenceData.Length; nIdx++) @@ -158,45 +162,64 @@ private void ReadDataCore(object zRefData) m_zReporterProxy.AddIssue($"Failed to load reference: {zReference.RelativePath}"); break; } - // 0 index is always the default reference in the case of multi load + + var listReferenceActions = new List(); + + // 0 index is always the default project reference in the case of multi load + // only load it once if (nIdx == 0) { - if (!string.IsNullOrEmpty(ProjectManager.Instance.ProjectFilePath)) - { - zRefReader.GetProjectDefineData(zReference, listDefineLines); - if (listDefineLines.Count == 0) + listReferenceActions.Add(Task.Factory.StartNew( + () => { - m_zReporterProxy.AddIssue("No defines found for project file: {0}".FormatString(ProjectManager.Instance.ProjectFilePath)); - } - } - else - { - m_zReporterProxy.AddIssue("No defines loaded for project -- project not yet saved."); - } - m_zReporterProxy.ProgressStep(); + if (!string.IsNullOrEmpty(ProjectManager.Instance.ProjectFilePath)) + { + zRefReader.GetProjectDefineData(zReference, listDefineLines); + if (listDefineLines.Count == 0) + { + m_zReporterProxy.AddIssue("No defines found for project file: {0}".FormatString(ProjectManager.Instance.ProjectFilePath)); + } + } + else + { + m_zReporterProxy.AddIssue("No defines loaded for project -- project not yet saved."); + } + m_zReporterProxy.ProgressStep(); + + })); } - zRefReader.GetReferenceData(zReference, listRefLines); + listReferenceActions.Add(Task.Factory.StartNew( + () => + { + zRefReader.GetReferenceData(zReference, listRefLines); + m_zReporterProxy.ProgressStep(); + })); + + listReferenceActions.Add(Task.Factory.StartNew( + () => + { + zRefReader.GetDefineData(zReference, listReferenceDefineLines); + m_zReporterProxy.ProgressStep(); + })); + + Task.WaitAll(listReferenceActions.ToArray()); + + // check if there are existing lines (from prior references) and remove the column header from the latest ref data if (listLines.Count > 0 && listRefLines.Count > 0) { - // remove the columns row from any non-zero index references listRefLines.RemoveAt(0); } listLines.AddRange(listRefLines); - m_zReporterProxy.ProgressStep(); - - var nPriorCount = listDefineLines.Count; - zRefReader.GetDefineData(zReference, listDefineLines); - if (listDefineLines.Count == nPriorCount) - { - m_zReporterProxy.AddIssue("No defines found for reference: {0}".FormatString(zReference.RelativePath)); - } zRefReader.FinalizeReferenceLoad(); m_zReporterProxy.ProgressStep(); } } + // Note: the readers trim out the first line for defines data + listDefineLines.AddRange(listReferenceDefineLines); + ProcessLines( listLines, listDefineLines, @@ -456,14 +479,14 @@ public void ResetTranslationCache(ProjectLayoutElement zElement) m_zTranslator.ResetTranslationCache(zElement); } - #region Cache +#region Cache public FormattedTextDataCache GetCachedMarkup(string sElementName) { return m_zTranslator.GetCachedMarkup(sElementName); } - #endregion +#endregion public ProjectLayoutElement GetOverrideElement(ProjectLayoutElement zElement, DeckLine zDeckLine, bool bExport) { @@ -510,7 +533,7 @@ public void PopulateListViewWithElementColumns(ListView listView) } } - #region Cache General +#region Cache General public void ResetDeckCache() { @@ -523,9 +546,9 @@ public void ResetDeckCache() m_zTranslator.ResetMarkupCache(); } - #endregion +#endregion - #region Markup Cache +#region Markup Cache public void AddCachedMarkup(string sElementName, FormattedTextDataCache zFormattedData) { m_zTranslator.AddCachedMarkup(sElementName, zFormattedData); @@ -535,9 +558,9 @@ public void ResetMarkupCache(string sElementName) { m_zTranslator.ResetMarkupCache(sElementName); } - #endregion +#endregion - #region Layout Set +#region Layout Set public void SetAndLoadLayout(ProjectLayout zLayout, bool bExporting, ProgressReporterProxy zReporterProxy) { EmptyReference = false; diff --git a/CardMaker/Card/Import/ReferenceReader.cs b/CardMaker/Card/Import/ReferenceReader.cs index d7dfe9ee..fa02bfca 100644 --- a/CardMaker/Card/Import/ReferenceReader.cs +++ b/CardMaker/Card/Import/ReferenceReader.cs @@ -33,8 +33,23 @@ public abstract class ReferenceReader public string ReferencePath { get; protected set; } public IProgressReporter ProgressReporter { get; set; } + /// + /// Reads the reference data into the specified list + /// + /// The reference meta data + /// The list to append public abstract void GetReferenceData(ProjectLayoutReference zReference, List> listReferenceData); + /// + /// Reads the project define data into the specified list + /// + /// The reference meta data + /// The list to append public abstract void GetProjectDefineData(ProjectLayoutReference zReference, List> listDefineData); + /// + /// Reads the reference define data into the specified list + /// + /// The reference meta data + /// The list to append public abstract void GetDefineData(ProjectLayoutReference zReference, List> listDefineData); /// diff --git a/CardMaker/Events/Managers/GoogleAuthManager.cs b/CardMaker/Events/Managers/GoogleAuthManager.cs index c043ff74..ef61ea94 100644 --- a/CardMaker/Events/Managers/GoogleAuthManager.cs +++ b/CardMaker/Events/Managers/GoogleAuthManager.cs @@ -71,7 +71,7 @@ public void FireGoogleAuthCredentialsErrorEvent(Action zSuccessAction = null, Ac #endregion /// - /// Checks if the google credentials are set. + /// Checks if the google credentials are set. This will result in a prompt for the user (via event). /// /// true if the credentials are set, false otherwise public static bool CheckGoogleCredentials(Form parentForm) @@ -87,7 +87,7 @@ public static bool CheckGoogleCredentials(Form parentForm) return false; } Instance.FireGoogleAuthUpdateRequestedEvent(); - return false; + return !string.IsNullOrEmpty(CardMakerInstance.GoogleAccessToken); } return true; } diff --git a/CardMaker/bin/Release/History.txt b/CardMaker/bin/Release/History.txt index 70800a85..4b4c6396 100644 --- a/CardMaker/bin/Release/History.txt +++ b/CardMaker/bin/Release/History.txt @@ -1,6 +1,8 @@ Card Maker Version History -------------------------- 1.1.0.0 +- When adding a Google reference the prompt will not disrupt the add reference process. +- Reference loading is now multi-threaded so you don't have to wait as long! - Additional override for background shapes allowing for custom opacity - Added ability to select alpha in the color selection dialog. - Border render on exports is now controlled per layout instead of at the application level. From c444640ea53b1311381fb6f1219c2b59880a11cb Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Mon, 8 Jun 2020 16:41:36 -0700 Subject: [PATCH 8/9] Changes to pixel and push markups. They now render in the debug mode. Also likely fixed an issue. Now there is a sample in the included sample project for easy verification. --- .../FormattedText/FormattedTextDataCache.cs | 2 ++ .../Card/FormattedText/Markup/MarkupBase.cs | 6 ++++ .../FormattedText/Markup/MarkupValueBase.cs | 12 +++++++ .../Card/FormattedText/Markup/PixelMarkup.cs | 33 +++++++++++++++++-- .../Card/FormattedText/Markup/PushMarkup.cs | 28 +++++++++++++++- .../Card/FormattedText/Markup/SpaceMarkup.cs | 12 ++++--- .../bin/Release/Sample/sample_project.cmp | 13 ++++++++ 7 files changed, 97 insertions(+), 9 deletions(-) diff --git a/CardMaker/Card/FormattedText/FormattedTextDataCache.cs b/CardMaker/Card/FormattedText/FormattedTextDataCache.cs index e89a3609..242a459c 100644 --- a/CardMaker/Card/FormattedText/FormattedTextDataCache.cs +++ b/CardMaker/Card/FormattedText/FormattedTextDataCache.cs @@ -37,6 +37,8 @@ public class FormattedTextDataCache typeof(BackgroundColorMarkup), typeof(BackgroundImageMarkup), typeof(ImageMarkup), + typeof(PushMarkup), + typeof(PixelMarkup), typeof(SpaceMarkup), typeof(TextMarkup) }; diff --git a/CardMaker/Card/FormattedText/Markup/MarkupBase.cs b/CardMaker/Card/FormattedText/Markup/MarkupBase.cs index 77aab60e..22e5ea5d 100644 --- a/CardMaker/Card/FormattedText/Markup/MarkupBase.cs +++ b/CardMaker/Card/FormattedText/Markup/MarkupBase.cs @@ -92,6 +92,12 @@ public virtual bool PostProcessMarkupRectangle(ProjectLayoutElement zElement, Li public virtual void CloseMarkup(FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { } + /// + /// Renders the given markup + /// + /// The element being rendered + /// The Graphics to draw to + /// true if the markup was rendered, false if not (due to space or other issues) public virtual bool Render(ProjectLayoutElement zElement, Graphics zGraphics) { return true; diff --git a/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs b/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs index f70a9c87..2076fd6e 100644 --- a/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs +++ b/CardMaker/Card/FormattedText/Markup/MarkupValueBase.cs @@ -23,6 +23,9 @@ //////////////////////////////////////////////////////////////////////////////// +using System.Drawing; +using CardMaker.Data; + namespace CardMaker.Card.FormattedText.Markup { public abstract class MarkupValueBase : MarkupBase @@ -34,5 +37,14 @@ protected MarkupValueBase(string sVariable) { m_sVariable = sVariable; } + + protected void RenderDebugBackground(Graphics zGraphics, Brush zBrush, float fXOffset, float fYOffset) + { + // draw border (debugging) + if (CardMakerInstance.DrawFormattedTextBorder) + { + zGraphics.FillRectangle(zBrush, TargetRect.X + fXOffset, TargetRect.Y + fYOffset, TargetRect.Width, TargetRect.Height); + } + } } } \ No newline at end of file diff --git a/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs b/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs index 32fc5f3d..155e22b6 100644 --- a/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/PixelMarkup.cs @@ -23,6 +23,7 @@ //////////////////////////////////////////////////////////////////////////////// using System; +using System.Collections.Generic; using System.Drawing; using CardMaker.XML; @@ -30,6 +31,11 @@ namespace CardMaker.Card.FormattedText.Markup { public class PixelMarkup : MarkupValueBase { + private float m_fXOffset; + private float m_fYOffset; + + public override bool Aligns => true; + private PixelMarkup() { } @@ -40,6 +46,9 @@ public PixelMarkup(string sVariable) : base(sVariable) protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { + m_fXOffset = zProcessData.CurrentXOffset; + m_fYOffset = zProcessData.CurrentYOffset; + var arrayComponents = m_sVariable.Split(new char[] { ';' }); if (1 > arrayComponents.Length) { @@ -69,9 +78,27 @@ protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, Form } } - zProcessData.CurrentX = Math.Max(0, Math.Min(nX, zElement.width)); - zProcessData.CurrentY = Math.Max(0, Math.Min(nY, zElement.height)); - return false; + nX = Math.Max(0, Math.Min(nX, zElement.width)); + nY = Math.Max(0, Math.Min(nY, zElement.height)); + + TargetRect = new RectangleF(zProcessData.CurrentX, zProcessData.CurrentY, + Math.Max(0, nX - zProcessData.CurrentX), + Math.Max(0, nY - zProcessData.CurrentY)); + + zProcessData.CurrentX = nX; + zProcessData.CurrentY = nY; + return true; + } + + public override bool PostProcessMarkupRectangle(ProjectLayoutElement zElement, List listAllMarkups, int nMarkup) + { + return true; + } + + public override bool Render(ProjectLayoutElement zElement, Graphics zGraphics) + { + RenderDebugBackground(zGraphics, Brushes.DeepSkyBlue, m_fXOffset, m_fYOffset); + return true; } } } diff --git a/CardMaker/Card/FormattedText/Markup/PushMarkup.cs b/CardMaker/Card/FormattedText/Markup/PushMarkup.cs index 9ee6bd0b..d155d066 100644 --- a/CardMaker/Card/FormattedText/Markup/PushMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/PushMarkup.cs @@ -22,6 +22,8 @@ // SOFTWARE. //////////////////////////////////////////////////////////////////////////////// +using System; +using System.Collections.Generic; using System.Drawing; using CardMaker.XML; @@ -29,6 +31,11 @@ namespace CardMaker.Card.FormattedText.Markup { public class PushMarkup : MarkupValueBase { + private float m_fXOffset; + private float m_fYOffset; + + public override bool Aligns => true; + private PushMarkup() { } @@ -39,6 +46,9 @@ public PushMarkup(string sVariable) : base(sVariable) protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { + m_fXOffset = zProcessData.CurrentXOffset; + m_fYOffset = zProcessData.CurrentYOffset; + var arrayComponents = m_sVariable.Split(new char[] { ';' }); if (1 > arrayComponents.Length) { @@ -60,14 +70,30 @@ protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, Form } } + TargetRect = new RectangleF(zProcessData.CurrentX, zProcessData.CurrentY, + Math.Max(0, nXPush), + Math.Max(0, nYPush)); + zProcessData.CurrentX += nXPush; zProcessData.CurrentY += nYPush; + if (zProcessData.CurrentX > zElement.width) { zProcessData.MoveToNextLine(zElement); } - return false; + return true; + } + + public override bool PostProcessMarkupRectangle(ProjectLayoutElement zElement, List listAllMarkups, int nMarkup) + { + return true; + } + + public override bool Render(ProjectLayoutElement zElement, Graphics zGraphics) + { + RenderDebugBackground(zGraphics, Brushes.DeepSkyBlue, m_fXOffset, m_fYOffset); + return true; } } } diff --git a/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs b/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs index 8180451d..58ce13e3 100644 --- a/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs +++ b/CardMaker/Card/FormattedText/Markup/SpaceMarkup.cs @@ -31,6 +31,9 @@ namespace CardMaker.Card.FormattedText.Markup { public class SpaceMarkup : MarkupValueBase { + private float m_fXOffset; + private float m_fYOffset; + public bool Optional { get; } public override bool Aligns => true; @@ -50,6 +53,9 @@ public SpaceMarkup(bool bOptional) : base("1") protected override bool ProcessMarkupHandler(ProjectLayoutElement zElement, FormattedTextData zData, FormattedTextProcessData zProcessData, Graphics zGraphics) { + m_fXOffset = zProcessData.CurrentXOffset; + m_fYOffset = zProcessData.CurrentYOffset; + int nSpaces; if (!int.TryParse(m_sVariable, out nSpaces)) { @@ -87,11 +93,7 @@ public override bool PostProcessMarkupRectangle(ProjectLayoutElement zElement, L public override bool Render(ProjectLayoutElement zElement, Graphics zGraphics) { - // draw border (debugging) - if (CardMakerInstance.DrawFormattedTextBorder) - { - zGraphics.FillRectangle(Optional ? Brushes.DarkBlue : Brushes.DeepSkyBlue, TargetRect.X, TargetRect.Y, TargetRect.Width, TargetRect.Height); - } + RenderDebugBackground(zGraphics, Optional ? Brushes.DarkBlue : Brushes.DeepSkyBlue, m_fXOffset, m_fYOffset); return true; } } diff --git a/CardMaker/bin/Release/Sample/sample_project.cmp b/CardMaker/bin/Release/Sample/sample_project.cmp index 8b958248..025eee71 100644 --- a/CardMaker/bin/Release/Sample/sample_project.cmp +++ b/CardMaker/bin/Release/Sample/sample_project.cmp @@ -120,6 +120,19 @@ false 0 + + + + + 0 + false + false + 0 + 0 + 1 + false + 0 + Incept C:\ ##_#L From 7f043c9bfbee8ea6051e47bc915bac21352e5ca5 Mon Sep 17 00:00:00 2001 From: Tim Stair Date: Tue, 9 Jun 2020 19:33:13 -0700 Subject: [PATCH 9/9] Added command line test and related tweaks. --- .../Card/CommandLine/CommandLineProcessor.cs | 14 ++- .../Card/Translation/TranslatorFactory.cs | 3 +- CardMaker/Program.cs | 25 +++- .../Progress/ConsoleProgressReporter.cs | 4 + .../ConsoleProgressReporterFactory.cs | 13 +- .../UnitTest/CommandLine/CommandLineTest.cs | 117 ++++++++++++++++++ CardMaker/Test/UnitTest/UnitTest.csproj | 4 +- 7 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 CardMaker/Test/UnitTest/CommandLine/CommandLineTest.cs diff --git a/CardMaker/Card/CommandLine/CommandLineProcessor.cs b/CardMaker/Card/CommandLine/CommandLineProcessor.cs index ebb1d948..fe27e457 100644 --- a/CardMaker/Card/CommandLine/CommandLineProcessor.cs +++ b/CardMaker/Card/CommandLine/CommandLineProcessor.cs @@ -39,6 +39,8 @@ public class CommandLineProcessor { public CommandLineUtil CommandLineUtil { get; set; } + private ProgressReporterFactory m_zProgressReporterFactory; + private static readonly Dictionary dictionaryExporterType = new Dictionary() { { "PDF", typeof(PDFCommandLineExporter) }, @@ -63,25 +65,27 @@ protected CommandLineProcessor() /// /// /// The parser to use within this processor - public CommandLineProcessor(CommandLineParser zCommandLineParser) + public CommandLineProcessor(CommandLineParser zCommandLineParser, ProgressReporterFactory zProgressReporterFactory) { m_zCommandLineParser = zCommandLineParser; + m_zProgressReporterFactory = zProgressReporterFactory; } /// /// Processes the command line /// - /// /// true if the command line was processed, false otherwise (load the UI) public bool Process() { // detect if just a project file path is specified (normal UI load) - if (IsProjectLoadOnly()) + if (ShouldLaunchGUI()) { return false; } // Switch all progress reporting over to the command line - CardMakerInstance.ProgressReporterFactory = new ConsoleProgressReporterFactory(); + CardMakerInstance.ProgressReporterFactory = m_zProgressReporterFactory == null + ? new ConsoleProgressReporterFactory() + : m_zProgressReporterFactory; Logger.InitLogger(new ConsoleLogger(), false); if (!LoadProject() || !PerformExport()) @@ -144,7 +148,7 @@ private bool LoadProject() /// Determines if the command line consists only of a project file path /// /// true if this is a project only command line, false otherwise - private bool IsProjectLoadOnly() + private bool ShouldLaunchGUI() { if (m_zCommandLineParser.GetArgCount() == 1) { diff --git a/CardMaker/Card/Translation/TranslatorFactory.cs b/CardMaker/Card/Translation/TranslatorFactory.cs index 35cf0750..76fcec27 100644 --- a/CardMaker/Card/Translation/TranslatorFactory.cs +++ b/CardMaker/Card/Translation/TranslatorFactory.cs @@ -43,7 +43,8 @@ public TranslatorBase GetTranslator(Dictionary dictionaryColumnName eTranslator = TranslatorType.Incept; } - Logger.AddLogLine("Deck Translator: {0}".FormatString(eTranslator.ToString())); + // not a critical log message... + //Logger.AddLogLine("Deck Translator: {0}".FormatString(eTranslator.ToString())); switch (eTranslator) { diff --git a/CardMaker/Program.cs b/CardMaker/Program.cs index a039e19c..b85cb51c 100644 --- a/CardMaker/Program.cs +++ b/CardMaker/Program.cs @@ -28,24 +28,37 @@ using CardMaker.Card.Shapes; using CardMaker.Data; using CardMaker.Forms; +using Support.Progress; using Support.UI; using Support.Util; namespace CardMaker { - static class Program + public static class Program { + // this is primarily here for the functional tests of the command line (repeating them breaks things) + static Program() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Initialize(); + } + /// /// The main entry point for the application. /// [STAThread] - static void Main(string[] args) + public static void Main(string[] args) { - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); + MainEntry(new ConsoleProgressReporterFactory(), args); + } - Initialize(); - var commandLineProcessor = new CommandLineProcessor(new CommandLineParser().Parse(args)) + public static void MainEntry(ProgressReporterFactory zProgressReporterFactory, + string[] args) + { + var commandLineProcessor = new CommandLineProcessor( + new CommandLineParser().Parse(args), + zProgressReporterFactory) { CommandLineUtil = new CommandLineUtil() }; diff --git a/CardMaker/Support/Progress/ConsoleProgressReporter.cs b/CardMaker/Support/Progress/ConsoleProgressReporter.cs index 4b818402..ed7626b4 100644 --- a/CardMaker/Support/Progress/ConsoleProgressReporter.cs +++ b/CardMaker/Support/Progress/ConsoleProgressReporter.cs @@ -33,6 +33,8 @@ namespace Support.Progress /// class ConsoleProgressReporter : IProgressReporter { + public bool WriteToConsole { get; set; } + private const int PROGRESS_WIDTH = 20; private readonly ThreadStart m_zThreadStart; private readonly ParameterizedThreadStart m_zParameterizedThreadStart; @@ -151,6 +153,8 @@ private void InitializeProgressLines(string[] arrayDescriptions) /// private void Render() { + if(!WriteToConsole) return; + if (m_bRendered) { // clear all the lines starting with the render point diff --git a/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs b/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs index 2279a757..5062d4fe 100644 --- a/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs +++ b/CardMaker/Support/Progress/ConsoleProgressReporterFactory.cs @@ -28,15 +28,24 @@ namespace Support.Progress { public class ConsoleProgressReporterFactory : ProgressReporterFactory { + public bool WriteToConsole { get; set; } + public IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, ThreadStart zThreadStart) { - return new ConsoleProgressReporter(sTitle, arrayDescriptions, zThreadStart); + return new ConsoleProgressReporter(sTitle, arrayDescriptions, zThreadStart) + { + WriteToConsole = WriteToConsole + }; } public IProgressReporter CreateReporter(string sTitle, string[] arrayDescriptions, ParameterizedThreadStart zThreadStart, object zParamObject) { - return new ConsoleProgressReporter(sTitle, arrayDescriptions, zThreadStart, zParamObject); + return new ConsoleProgressReporter(sTitle, arrayDescriptions, zThreadStart, zParamObject) + { + WriteToConsole = WriteToConsole + }; + } } } diff --git a/CardMaker/Test/UnitTest/CommandLine/CommandLineTest.cs b/CardMaker/Test/UnitTest/CommandLine/CommandLineTest.cs new file mode 100644 index 00000000..a2bca516 --- /dev/null +++ b/CardMaker/Test/UnitTest/CommandLine/CommandLineTest.cs @@ -0,0 +1,117 @@ +using System; +using System.IO; +using CardMaker; +using CardMaker.XML; +using Moq; +using NUnit.Framework; +using Support.Progress; +using UnitTest.DeckObject; + +namespace UnitTest.CommandLine +{ + + [TestFixture] + internal class CommandLineTest + { + private const string UnitTestFolder = @"unit_test_temp\"; + private const string ProjectFile = @"bin\Release\Sample\sample_project.cmp"; + private const string PdfFile = "unit_test.pdf"; + private string m_sProjectRoot = string.Empty; + private string m_sTestTemp = string.Empty; + + + [SetUp] + public void Setup() + { + m_sProjectRoot = + Directory.GetParent( + Path.GetDirectoryName(Path.GetDirectoryName( + TestContext.CurrentContext.TestDirectory))).Parent.FullName; + m_sTestTemp = Path.Combine(m_sProjectRoot, UnitTestFolder); + + if (Directory.Exists(m_sTestTemp)) + { + Directory.Delete(m_sTestTemp, true); + } + Directory.CreateDirectory(m_sTestTemp); + } + + [TearDown] + public void TearDown() + { + Directory.Delete(m_sTestTemp, true); + } + + [Test] + public void ExecutePDFExport() + { + var sProjectFile = Path.Combine(m_sProjectRoot, ProjectFile); + var sPdfExport = Path.Combine(m_sTestTemp, PdfFile); + var args = new string[] + { + "-projectPath", sProjectFile, + "-exportFormat", "pdf", + "-exportPath", sPdfExport + }; + Program.MainEntry( + new ConsoleProgressReporterFactory() + { + WriteToConsole = false + }, + args); + Assert.IsTrue(File.Exists(sPdfExport)); + } + + [Test] + public void ExecutePNGExport() + { + var sProjectFile = Path.Combine(m_sProjectRoot, ProjectFile); + var args = new string[] + { + "-projectPath", sProjectFile, + "-exportFormat", "png", + "-exportPath", m_sTestTemp + }; + Program.MainEntry( + new ConsoleProgressReporterFactory() + { + WriteToConsole = false + }, + args); + // just verifying the first layout + AssertFileRangeExistence(m_sTestTemp, "Default_", ".png", 1, 18); + } + + [Test] + public void ExecuteRangePNGExport() + { + var sProjectFile = Path.Combine(m_sProjectRoot, ProjectFile); + var args = new string[] + { + "-projectPath", sProjectFile, + "-exportFormat", "png", + "-exportPath", m_sTestTemp, + "-layoutNames", "Default", + "-cardIndices", "3-10" + }; + Program.MainEntry( + new ConsoleProgressReporterFactory() + { + WriteToConsole = false + }, + args); + // just verifying the first layout + AssertFileRangeExistence(m_sTestTemp, "Default_", ".png", 3, 10); + } + + private void AssertFileRangeExistence(string sPath, string sPrefix, string sSuffix, int nStart, int nEnd) + { + var nPad = nEnd.ToString().Length; + for (var nIdx = nStart; nIdx <= nEnd; nIdx++) + { + var path = Path.Combine(sPath, sPrefix + nIdx.ToString().PadLeft(nPad, '0') + sSuffix); + Assert.IsTrue(File.Exists(path)); + } + } + } +} diff --git a/CardMaker/Test/UnitTest/UnitTest.csproj b/CardMaker/Test/UnitTest/UnitTest.csproj index 5d0007f1..62e0e91d 100644 --- a/CardMaker/Test/UnitTest/UnitTest.csproj +++ b/CardMaker/Test/UnitTest/UnitTest.csproj @@ -76,6 +76,7 @@ + @@ -97,6 +98,7 @@ + @@ -136,4 +138,4 @@ COPY "$(SolutionDir)\3rdParty\ClearScript\v8*" "$(TargetDir)" --> - + \ No newline at end of file