From 128f7aeb767d5dd07d79fc9d5f55f559d50be529 Mon Sep 17 00:00:00 2001 From: Raphael Noeldner Date: Mon, 17 Feb 2020 09:30:11 +0100 Subject: [PATCH] Moving AlternateQuoting and DuplicateQuotingToEscape to FileFormat; added support for visualizing DuplicateQuotingToEscape in control Some controls in FormEditSettings have no with and where not usable --- Application/FormEditSettings.Designer.cs | 36 ++- Application/FormEditSettings.resx | 13 +- Application/FormMain.cs | 79 +++-- Application/ViewSettings.cs | 1 - Library/ClassLibraryCSV/CsvFile.cs | 49 +-- Library/ClassLibraryCSV/CsvFileReader.cs | 9 +- Library/ClassLibraryCSV/FileFormat.cs | 279 ++++++++++++------ Library/ClassLibraryCSV/ICsvFile.cs | 11 - .../CsvDataReaderPGP_FilesTest.cs | 10 +- .../CsvDataReader_FilesTest.cs | 16 +- .../ClassLibraryCSVUnitTest/CsvFileTest.cs | 2 +- Library/ClassLibraryCSVUnitTest/Helper.cs | 2 +- .../TimeZoneMappingTests.cs | 23 ++ Library/WinFormControls/QuotingControl.cs | 45 ++- Library/WinFormControls/QuotingControl.resx | 15 +- Setup/Product.wxs | 2 +- 16 files changed, 329 insertions(+), 263 deletions(-) diff --git a/Application/FormEditSettings.Designer.cs b/Application/FormEditSettings.Designer.cs index ce47ed34..2f41e353 100644 --- a/Application/FormEditSettings.Designer.cs +++ b/Application/FormEditSettings.Designer.cs @@ -30,7 +30,6 @@ private void InitializeComponent() { this.components = new System.ComponentModel.Container(); System.Windows.Forms.TableLayoutPanel tableLayoutPanelFile; - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormEditSettings)); System.Windows.Forms.TableLayoutPanel tableLayoutPanelAdvanced; System.Windows.Forms.TableLayoutPanel tableLayoutPanelPGP; System.Windows.Forms.TableLayoutPanel tableLayoutPanelBehavior; @@ -185,8 +184,9 @@ private void InitializeComponent() this.textBoxComment.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileFormatBindingSource, "CommentLine", true)); this.textBoxComment.Location = new System.Drawing.Point(111, 126); this.textBoxComment.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxComment.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxComment.Name = "textBoxComment"; - this.textBoxComment.Size = new System.Drawing.Size(51, 22); + this.textBoxComment.Size = new System.Drawing.Size(60, 22); this.textBoxComment.TabIndex = 10; // // fileFormatBindingSource @@ -213,6 +213,7 @@ private void InitializeComponent() this.textBoxFile.Dock = System.Windows.Forms.DockStyle.Top; this.textBoxFile.Location = new System.Drawing.Point(111, 2); this.textBoxFile.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxFile.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxFile.Name = "textBoxFile"; this.textBoxFile.Size = new System.Drawing.Size(648, 22); this.textBoxFile.TabIndex = 0; @@ -246,10 +247,12 @@ private void InitializeComponent() this.textBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileFormatBindingSource, "EscapeCharacter", true)); this.textBox1.Location = new System.Drawing.Point(513, 94); this.textBox1.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBox1.MinimumSize = new System.Drawing.Size(60, 0); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(69, 22); this.textBox1.TabIndex = 45; - this.toolTip.SetToolTip(this.textBox1, resources.GetString("textBox1.ToolTip")); + this.toolTip.SetToolTip(this.textBox1, "An escape character is used for escaping quotes and delimiters in the regular tex" + + "t. "); this.textBox1.TextChanged += new System.EventHandler(this.TextBoxDelimiter_TextChanged); // // label3 @@ -294,8 +297,9 @@ private void InitializeComponent() this.textBoxDelimiter.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileFormatBindingSource, "FieldDelimiter", true)); this.textBoxDelimiter.Location = new System.Drawing.Point(111, 94); this.textBoxDelimiter.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxDelimiter.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxDelimiter.Name = "textBoxDelimiter"; - this.textBoxDelimiter.Size = new System.Drawing.Size(51, 22); + this.textBoxDelimiter.Size = new System.Drawing.Size(60, 22); this.textBoxDelimiter.TabIndex = 7; this.textBoxDelimiter.TextChanged += new System.EventHandler(this.TextBoxDelimiter_TextChanged); // @@ -330,6 +334,7 @@ private void InitializeComponent() this.cboCodePage.FormattingEnabled = true; this.cboCodePage.Location = new System.Drawing.Point(111, 58); this.cboCodePage.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.cboCodePage.MinimumSize = new System.Drawing.Size(60, 0); this.cboCodePage.Name = "cboCodePage"; this.cboCodePage.Size = new System.Drawing.Size(331, 24); this.cboCodePage.TabIndex = 4; @@ -503,8 +508,9 @@ private void InitializeComponent() this.textBoxLimitRows.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileSettingBindingSource, "RecordLimit", true)); this.textBoxLimitRows.Location = new System.Drawing.Point(155, 111); this.textBoxLimitRows.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxLimitRows.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxLimitRows.Name = "textBoxLimitRows"; - this.textBoxLimitRows.Size = new System.Drawing.Size(0, 22); + this.textBoxLimitRows.Size = new System.Drawing.Size(100, 22); this.textBoxLimitRows.TabIndex = 6; this.textBoxLimitRows.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxLimitRows.Validating += new System.ComponentModel.CancelEventHandler(this.PositiveNumberValidating); @@ -529,8 +535,9 @@ private void InitializeComponent() this.textBoxNLPlaceholder.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileFormatBindingSource, "NewLinePlaceholder", true)); this.textBoxNLPlaceholder.Location = new System.Drawing.Point(155, 59); this.textBoxNLPlaceholder.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxNLPlaceholder.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxNLPlaceholder.Name = "textBoxNLPlaceholder"; - this.textBoxNLPlaceholder.Size = new System.Drawing.Size(0, 22); + this.textBoxNLPlaceholder.Size = new System.Drawing.Size(100, 22); this.textBoxNLPlaceholder.TabIndex = 4; // // textBoxDelimiterPlaceholder @@ -542,8 +549,9 @@ private void InitializeComponent() this.textBoxDelimiterPlaceholder.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileFormatBindingSource, "DelimiterPlaceholder", true)); this.textBoxDelimiterPlaceholder.Location = new System.Drawing.Point(155, 33); this.textBoxDelimiterPlaceholder.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxDelimiterPlaceholder.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxDelimiterPlaceholder.Name = "textBoxDelimiterPlaceholder"; - this.textBoxDelimiterPlaceholder.Size = new System.Drawing.Size(0, 22); + this.textBoxDelimiterPlaceholder.Size = new System.Drawing.Size(100, 22); this.textBoxDelimiterPlaceholder.TabIndex = 3; // // labelRecordLimit @@ -565,8 +573,9 @@ private void InitializeComponent() this.textBoxTextAsNull.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileSettingBindingSource, "TreatTextAsNull", true)); this.textBoxTextAsNull.Location = new System.Drawing.Point(155, 85); this.textBoxTextAsNull.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxTextAsNull.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxTextAsNull.Name = "textBoxTextAsNull"; - this.textBoxTextAsNull.Size = new System.Drawing.Size(0, 22); + this.textBoxTextAsNull.Size = new System.Drawing.Size(100, 22); this.textBoxTextAsNull.TabIndex = 5; // // buttonSkipLine @@ -600,8 +609,9 @@ private void InitializeComponent() this.textBoxSkipRows.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileSettingBindingSource, "SkipRows", true)); this.textBoxSkipRows.Location = new System.Drawing.Point(155, 2); this.textBoxSkipRows.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxSkipRows.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxSkipRows.Name = "textBoxSkipRows"; - this.textBoxSkipRows.Size = new System.Drawing.Size(0, 22); + this.textBoxSkipRows.Size = new System.Drawing.Size(100, 22); this.textBoxSkipRows.TabIndex = 0; this.textBoxSkipRows.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxSkipRows.Validating += new System.ComponentModel.CancelEventHandler(this.PositiveNumberValidating); @@ -683,7 +693,7 @@ private void InitializeComponent() this.btnPassp.Location = new System.Drawing.Point(563, 2); this.btnPassp.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); this.btnPassp.Name = "btnPassp"; - this.btnPassp.Size = new System.Drawing.Size(357, 27); + this.btnPassp.Size = new System.Drawing.Size(344, 27); this.btnPassp.TabIndex = 1; this.btnPassp.Text = "Set Default Decryption Passphrase"; this.btnPassp.UseVisualStyleBackColor = true; @@ -886,8 +896,9 @@ private void InitializeComponent() this.textBoxNumWarnings.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.fileSettingBindingSource, "NumWarnings", true)); this.textBoxNumWarnings.Location = new System.Drawing.Point(107, 152); this.textBoxNumWarnings.Margin = new System.Windows.Forms.Padding(3, 2, 3, 2); + this.textBoxNumWarnings.MinimumSize = new System.Drawing.Size(60, 0); this.textBoxNumWarnings.Name = "textBoxNumWarnings"; - this.textBoxNumWarnings.Size = new System.Drawing.Size(40, 22); + this.textBoxNumWarnings.Size = new System.Drawing.Size(60, 22); this.textBoxNumWarnings.TabIndex = 6; this.textBoxNumWarnings.TextAlign = System.Windows.Forms.HorizontalAlignment.Right; this.textBoxNumWarnings.Validating += new System.ComponentModel.CancelEventHandler(this.PositiveNumberValidating); @@ -986,7 +997,7 @@ private void InitializeComponent() this.fillGuessSettingEdit.Margin = new System.Windows.Forms.Padding(1); this.fillGuessSettingEdit.MinimumSize = new System.Drawing.Size(631, 240); this.fillGuessSettingEdit.Name = "fillGuessSettingEdit"; - this.fillGuessSettingEdit.Size = new System.Drawing.Size(631, 240); + this.fillGuessSettingEdit.Size = new System.Drawing.Size(945, 339); this.fillGuessSettingEdit.TabIndex = 101; // // tabPageWarnings @@ -1056,6 +1067,7 @@ private void InitializeComponent() // this.quotingControl.BackColor = System.Drawing.SystemColors.Control; this.quotingControl.Dock = System.Windows.Forms.DockStyle.Fill; + this.quotingControl.Font = new System.Drawing.Font("Segoe UI", 9F); this.quotingControl.IsWriteSetting = false; this.quotingControl.Location = new System.Drawing.Point(3, 2); this.quotingControl.Margin = new System.Windows.Forms.Padding(5, 6, 5, 6); diff --git a/Application/FormEditSettings.resx b/Application/FormEditSettings.resx index b6dae2d5..1cdc3560 100644 --- a/Application/FormEditSettings.resx +++ b/Application/FormEditSettings.resx @@ -123,16 +123,18 @@ 202, 17 + + 202, 17 + + + 12, 17 + 12, 17 387, 17 - - An escape character is used for escaping quotes and delimiters in the regular text. -Usage of this is often not well supported: It may lead to issues if the last character of a column matches the escape character, teh column end is not regognized. - False @@ -145,6 +147,9 @@ Usage of this is often not well supported: It may lead to issues if the last cha False + + 387, 17 + 477, 17 diff --git a/Application/FormMain.cs b/Application/FormMain.cs index dd22f65f..fb0074df 100644 --- a/Application/FormMain.cs +++ b/Application/FormMain.cs @@ -164,7 +164,7 @@ private void AttachPropertyChanged(ICsvFile fileSetting) { fileSystemWatcher.EnableRaisingEvents = m_ViewSettings.DetectFileChanges; fileSetting.PropertyChanged += FileSetting_PropertyChanged; - fileSetting.FileFormat.PropertyChanged += FileFormat_PropertyChanged; + fileSetting.FileFormat.PropertyChanged += AnyPropertyChangedReload; foreach (var col in fileSetting.ColumnCollection) col.PropertyChanged += AnyPropertyChangedReload; } @@ -225,7 +225,7 @@ private void DetachPropertyChanged(ICsvFile fileSetting) if (fileSetting != null) { fileSetting.PropertyChanged -= FileSetting_PropertyChanged; - fileSetting.FileFormat.PropertyChanged -= FileFormat_PropertyChanged; + fileSetting.FileFormat.PropertyChanged -= AnyPropertyChangedReload; foreach (var col in fileSetting.ColumnCollection) col.PropertyChanged -= AnyPropertyChangedReload; } @@ -277,7 +277,6 @@ private void Display_Activated(object sender, EventArgs e) { if (m_ConfigChanged) { - m_ConfigChanged = false; detailControl.MoveMenu(); if (_MessageBox.Show( this, @@ -286,12 +285,17 @@ private void Display_Activated(object sender, EventArgs e) MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes) + { OpenDataReader(true); + } + else + { + m_ConfigChanged = false; + } } if (m_FileChanged) { - m_FileChanged = false; if (_MessageBox.Show( this, "The displayed file has changed do you want to reload the data?", @@ -299,7 +303,14 @@ private void Display_Activated(object sender, EventArgs e) MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) == DialogResult.Yes) + { OpenDataReader(true); + } + else + { + m_FileChanged = false; + } + } } @@ -361,17 +372,6 @@ private void Display_Shown(object sender, EventArgs e) OpenDataReader(false); } - private void FileFormat_PropertyChanged(object sender, PropertyChangedEventArgs e) - { - if (e.PropertyName == nameof(FileFormat.FieldDelimiterChar) - || e.PropertyName == nameof(FileFormat.EscapeCharacterChar) - || e.PropertyName == nameof(FileFormat.CommentLine) || e.PropertyName == nameof(FileFormat.FieldQualifierChar) - || e.PropertyName == nameof(FileFormat.QuotePlaceholder) - || e.PropertyName == nameof(FileFormat.DelimiterPlaceholder) - || e.PropertyName == nameof(FileFormat.NewLinePlaceholder)) - m_ConfigChanged = true; - } - /// /// Handles the PropertyChanged event of the FileSetting control. /// @@ -379,33 +379,28 @@ private void FileFormat_PropertyChanged(object sender, PropertyChangedEventArgs /// The instance containing the event data. private void FileSetting_PropertyChanged(object sender, PropertyChangedEventArgs e) { - if (e.PropertyName == nameof(ICsvFile.AllowRowCombining) || e.PropertyName == nameof(ICsvFile.AlternateQuoting) - || e.PropertyName == nameof(ICsvFile.ByteOrderMark) - || e.PropertyName == nameof(ICsvFile.CodePageId) - || e.PropertyName - == nameof(ICsvFile.ConsecutiveEmptyRows) - || e.PropertyName == nameof(ICsvFile.DoubleDecode) - || e.PropertyName == nameof(ICsvFile.HasFieldHeader) - || e.PropertyName == nameof(ICsvFile.NumWarnings) - || e.PropertyName == nameof(ICsvFile.SkipEmptyLines) - || e.PropertyName == nameof(ICsvFile.SkipRows) - || e.PropertyName == nameof(ICsvFile.TreatLFAsSpace) - || e.PropertyName == nameof(ICsvFile.TreatNBSPAsSpace) - || e.PropertyName == nameof(ICsvFile.TreatTextAsNull) - || e.PropertyName - == nameof(ICsvFile.TreatUnknowCharaterAsSpace) - || e.PropertyName - == nameof(ICsvFile.TryToSolveMoreColumns) - || e.PropertyName - == nameof(ICsvFile.WarnDelimiterInValue) - || e.PropertyName - == nameof(ICsvFile.WarnEmptyTailingColumns) - || e.PropertyName == nameof(ICsvFile.WarnLineFeed) - || e.PropertyName == nameof(ICsvFile.WarnNBSP) - || e.PropertyName == nameof(ICsvFile.WarnQuotes) - || e.PropertyName == nameof(ICsvFile.WarnQuotesInQuotes) - || e.PropertyName == nameof(ICsvFile.WarnUnknowCharater) - || e.PropertyName == nameof(ICsvFile.FileName)) + if (e.PropertyName == nameof(ICsvFile.AllowRowCombining) + || e.PropertyName == nameof(ICsvFile.ByteOrderMark) + || e.PropertyName == nameof(ICsvFile.CodePageId) + || e.PropertyName == nameof(ICsvFile.ConsecutiveEmptyRows) + || e.PropertyName == nameof(ICsvFile.DoubleDecode) + || e.PropertyName == nameof(ICsvFile.HasFieldHeader) + || e.PropertyName == nameof(ICsvFile.NumWarnings) + || e.PropertyName == nameof(ICsvFile.SkipEmptyLines) + || e.PropertyName == nameof(ICsvFile.SkipRows) + || e.PropertyName == nameof(ICsvFile.TreatLFAsSpace) + || e.PropertyName == nameof(ICsvFile.TreatNBSPAsSpace) + || e.PropertyName == nameof(ICsvFile.TreatTextAsNull) + || e.PropertyName == nameof(ICsvFile.TreatUnknowCharaterAsSpace) + || e.PropertyName == nameof(ICsvFile.TryToSolveMoreColumns) + || e.PropertyName == nameof(ICsvFile.WarnDelimiterInValue) + || e.PropertyName == nameof(ICsvFile.WarnEmptyTailingColumns) + || e.PropertyName == nameof(ICsvFile.WarnLineFeed) + || e.PropertyName == nameof(ICsvFile.WarnNBSP) + || e.PropertyName == nameof(ICsvFile.WarnQuotes) + || e.PropertyName == nameof(ICsvFile.WarnQuotesInQuotes) + || e.PropertyName == nameof(ICsvFile.WarnUnknowCharater) + || e.PropertyName == nameof(ICsvFile.FileName)) m_ConfigChanged = true; } diff --git a/Application/ViewSettings.cs b/Application/ViewSettings.cs index a3fc756c..e0acc9db 100644 --- a/Application/ViewSettings.cs +++ b/Application/ViewSettings.cs @@ -230,7 +230,6 @@ public static void CopyConfiuration(ICsvFile csvSrc, ICsvFile csvDest) } csvDest.AllowRowCombining = csvSrc.AllowRowCombining; - csvDest.AlternateQuoting = csvSrc.AlternateQuoting; csvDest.ByteOrderMark = csvSrc.ByteOrderMark; csvDest.CodePageId = csvSrc.CodePageId; csvDest.ConsecutiveEmptyRows = csvSrc.ConsecutiveEmptyRows; diff --git a/Library/ClassLibraryCSV/CsvFile.cs b/Library/ClassLibraryCSV/CsvFile.cs index f5a332f0..cfb46ab8 100644 --- a/Library/ClassLibraryCSV/CsvFile.cs +++ b/Library/ClassLibraryCSV/CsvFile.cs @@ -88,49 +88,8 @@ public CsvFile() [XmlIgnore] public static bool UnknowCharaterReplacementSpecified => false; - /// - /// Gets or sets a value indicating whether the byte order mark should be written in Unicode files. - /// - /// true write byte order mark; otherwise, false. - [XmlAttribute] - [DefaultValue(false)] - public virtual bool AlternateQuoting - { - get => m_AlternateQuoting; - set - { - if (m_AlternateQuoting.Equals(value)) - return; - m_AlternateQuoting = value; - NotifyPropertyChanged(nameof(AlternateQuoting)); - - // If Anternate Quoting is dsiabled, enable DuplicateQuotingToEscape automatically - if (!m_AlternateQuoting && !DuplicateQuotingToEscape) - DuplicateQuotingToEscape = true; - - // If Anternate Quoting is enabled, disable DuplicateQuotingToEscape automatically - if (m_AlternateQuoting && DuplicateQuotingToEscape) - DuplicateQuotingToEscape = false; - } - } - /// - /// Gets or sets a value indicating whether the byte order mark should be written in Unicode files. - /// - /// true write byte order mark; otherwise, false. - [XmlAttribute] - [DefaultValue(true)] - public virtual bool DuplicateQuotingToEscape - { - get => m_DuplicateQuotingToEscape; - set - { - if (m_DuplicateQuotingToEscape.Equals(value)) - return; - m_DuplicateQuotingToEscape = value; - NotifyPropertyChanged(nameof(DuplicateQuotingToEscape)); - } - } + /// /// Gets or sets a value indicating whether the byte order mark should be written in Unicode files. @@ -505,8 +464,6 @@ public void CopyTo(IFileSetting other) if (!(other is ICsvFile csv)) return; csv.ByteOrderMark = m_ByteOrderMark; - csv.AlternateQuoting = m_AlternateQuoting; - csv.DuplicateQuotingToEscape = m_DuplicateQuotingToEscape; csv.DoubleDecode = m_DoubleDecode; csv.WarnQuotes = m_WarnQuotes; csv.JsonFormat = m_JsonFormat; @@ -559,9 +516,7 @@ public virtual bool Equals(ICsvFile other) return false; if (ReferenceEquals(this, other)) return true; - return m_AlternateQuoting == other.AlternateQuoting && - m_DuplicateQuotingToEscape == other.DuplicateQuotingToEscape && - m_ByteOrderMark == other.ByteOrderMark && m_CodePageId == other.CodePageId && + return m_ByteOrderMark == other.ByteOrderMark && m_CodePageId == other.CodePageId && Equals(m_CurrentEncoding, other.CurrentEncoding) && m_DoubleDecode == other.DoubleDecode && m_JsonFormat == other.JsonFormat && m_NoDelimitedFile == other.NoDelimitedFile && m_NumWarnings == other.NumWarnings && diff --git a/Library/ClassLibraryCSV/CsvFileReader.cs b/Library/ClassLibraryCSV/CsvFileReader.cs index 988689f9..4f4eec5f 100644 --- a/Library/ClassLibraryCSV/CsvFileReader.cs +++ b/Library/ClassLibraryCSV/CsvFileReader.cs @@ -823,14 +823,15 @@ private string ReadNextColumn(int columnNo, bool storeWarnings) { var peekNextChar = NextChar(); // a "" should be reagrded as " if the text is quoted - if (m_CsvFile.DuplicateQuotingToEscape && peekNextChar == m_CsvFile.FileFormat.FieldQualifierChar) + if (m_CsvFile.FileFormat.DuplicateQuotingToEscape && peekNextChar == m_CsvFile.FileFormat.FieldQualifierChar) { // double quotes within quoted string means add a quote stringBuilder.Append(m_CsvFile.FileFormat.FieldQualifierChar); m_BufferPos++; + //TODO: decide if we should have this its hard to explain but might make sense // secial handliung for "" that is not only representing a " but also closes the text peekNextChar = NextChar(); - if (m_CsvFile.AlternateQuoting && (peekNextChar == m_CsvFile.FileFormat.FieldDelimiterChar || peekNextChar == c_Cr || peekNextChar == c_Lf)) + if (m_CsvFile.FileFormat.AlternateQuoting && (peekNextChar == m_CsvFile.FileFormat.FieldDelimiterChar || peekNextChar == c_Cr || peekNextChar == c_Lf)) { postdata = true; continue; @@ -838,13 +839,13 @@ private string ReadNextColumn(int columnNo, bool storeWarnings) continue; } // a single " should be reagrded as clsoing when its followed by the delimter - if (m_CsvFile.AlternateQuoting && (peekNextChar == m_CsvFile.FileFormat.FieldDelimiterChar || peekNextChar == c_Cr || peekNextChar == c_Lf)) + if (m_CsvFile.FileFormat.AlternateQuoting && (peekNextChar == m_CsvFile.FileFormat.FieldDelimiterChar || peekNextChar == c_Cr || peekNextChar == c_Lf)) { postdata = true; continue; } // a single " should be reagrded as closing if we do not have alternate quoting - if (!m_CsvFile.AlternateQuoting) + if (!m_CsvFile.FileFormat.AlternateQuoting) { postdata = true; continue; diff --git a/Library/ClassLibraryCSV/FileFormat.cs b/Library/ClassLibraryCSV/FileFormat.cs index c54e7eea..d811f5c7 100644 --- a/Library/ClassLibraryCSV/FileFormat.cs +++ b/Library/ClassLibraryCSV/FileFormat.cs @@ -12,46 +12,103 @@ * */ -using System; -using System.ComponentModel; -using System.Diagnostics.Contracts; -using System.Xml.Serialization; - namespace CsvTools { + using System; + using System.ComponentModel; + using System.Diagnostics.Contracts; + using System.Xml.Serialization; + /// /// Setting class for a general file format /// [Serializable] #pragma warning disable CS0659 // Type overrides Object.Equals(object o) but does not override Object.GetHashCode() public class FileFormat : INotifyPropertyChanged, IEquatable, ICloneable -#pragma warning restore CS0659 // Type overrides Object.Equals(object o) but does not override Object.GetHashCode() +#pragma warning restore CS0659 { + // Type overrides Object.Equals(object o) but does not override Object.GetHashCode() + public const string cEscapeCharacterDefault = ""; + private const string c_CommentLineDefault = ""; + private const string c_DelimiterPlaceholderDefault = ""; - public const string cEscapeCharacterDefault = ""; + private const string c_FieldDelimiterDefault = ","; + private const string c_FieldQualifierDefault = "\""; + private const string c_NewLineDefault = "CRLF"; + private const string c_NewLinePlaceholderDefault = ""; + private const bool c_QualifyOnlyIfNeededDefault = true; + private const string c_QuotePlaceholderDefault = ""; + public bool m_DuplicateQuotingToEscape = true; + + private bool m_AlternateQuoting; + private string m_CommentLine = c_CommentLineDefault; + private string m_DelimiterPlaceholder = c_DelimiterPlaceholderDefault; + private string m_EscapeCharacter = cEscapeCharacterDefault; + private char m_EscapeCharacterChar = GetChar(cEscapeCharacterDefault); + private string m_FieldDelimiter = c_FieldDelimiterDefault; + private char m_FieldDelimiterChar = GetChar(c_FieldDelimiterDefault); + private string m_FieldQualifier = c_FieldQualifierDefault; + private char m_FieldQualifierChar = GetChar(c_FieldQualifierDefault); + private string m_NewLine = c_NewLineDefault; + private string m_NewLinePlaceholder = c_NewLinePlaceholderDefault; + private bool m_QualifyAlways; + private bool m_QualifyOnlyIfNeeded = c_QualifyOnlyIfNeededDefault; + private string m_QuotePlaceholder = c_QuotePlaceholderDefault; + private ValueFormat m_ValueFormat = new ValueFormat(); + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Gets or sets a value indicating whether the byte order mark should be written in Unicode files. + /// + /// true write byte order mark; otherwise, false. + [XmlAttribute] + [DefaultValue(false)] + public virtual bool AlternateQuoting + { + get => m_AlternateQuoting; + set + { + if (m_AlternateQuoting.Equals(value)) + return; + m_AlternateQuoting = value; + NotifyPropertyChanged(nameof(AlternateQuoting)); + + // If Anternate Quoting is dsiabled, enable DuplicateQuotingToEscape automatically + if (!m_AlternateQuoting && !DuplicateQuotingToEscape) + DuplicateQuotingToEscape = true; + + // If Anternate Quoting is enabled, disable DuplicateQuotingToEscape automatically + if (m_AlternateQuoting && DuplicateQuotingToEscape) + DuplicateQuotingToEscape = false; + } + } + /// /// Gets a value indicating whether column format specified. /// @@ -73,6 +130,7 @@ public virtual string CommentLine Contract.Ensures(Contract.Result() != null); return m_CommentLine; } + set { var newVal = (value ?? string.Empty).Trim(); @@ -96,6 +154,7 @@ public virtual string DelimiterPlaceholder Contract.Ensures(Contract.Result() != null); return m_DelimiterPlaceholder; } + set { var newVal = (value ?? string.Empty).Trim(); @@ -106,6 +165,24 @@ public virtual string DelimiterPlaceholder } } + /// + /// Gets or sets a value indicating whether the byte order mark should be written in Unicode files. + /// + /// true write byte order mark; otherwise, false. + [XmlAttribute] + [DefaultValue(true)] + public virtual bool DuplicateQuotingToEscape + { + get => m_DuplicateQuotingToEscape; + set + { + if (m_DuplicateQuotingToEscape.Equals(value)) + return; + m_DuplicateQuotingToEscape = value; + NotifyPropertyChanged(nameof(DuplicateQuotingToEscape)); + } + } + /// /// Gets or sets the escape character. /// @@ -151,6 +228,7 @@ public virtual string FieldDelimiter Contract.Ensures(Contract.Result() != null); return m_FieldDelimiter; } + set { var newVal = (value ?? string.Empty).Trim(StringUtils.Spaces); @@ -182,6 +260,7 @@ public virtual string FieldQualifier Contract.Ensures(Contract.Result() != null); return m_FieldQualifier; } + set { var newVal = (value ?? string.Empty).Trim(); @@ -244,6 +323,7 @@ public virtual string NewLinePlaceholder Contract.Ensures(Contract.Result() != null); return m_NewLinePlaceholder; } + set { var newVal = value ?? c_NewLinePlaceholderDefault; @@ -255,43 +335,43 @@ public virtual string NewLinePlaceholder } /// - /// Gets or sets a value indicating whether to qualify only if needed. + /// Gets or sets a value indicating whether to qualify every text even if number or empty. /// /// true if qualify only if needed; otherwise, false. [XmlAttribute] - [DefaultValue(c_QualifyOnlyIfNeededDefault)] - public virtual bool QualifyOnlyIfNeeded + [DefaultValue(false)] + public virtual bool QualifyAlways { - get => m_QualifyOnlyIfNeeded; - + get => m_QualifyAlways; set { - if (m_QualifyOnlyIfNeeded.Equals(value)) + if (m_QualifyAlways.Equals(value)) return; - m_QualifyOnlyIfNeeded = value; - if (m_QualifyOnlyIfNeeded) - QualifyAlways = false; - NotifyPropertyChanged(nameof(QualifyOnlyIfNeeded)); + m_QualifyAlways = value; + if (m_QualifyAlways) + QualifyOnlyIfNeeded = false; + NotifyPropertyChanged(nameof(QualifyAlways)); } } /// - /// Gets or sets a value indicating whether to qualify every text even if number or empty. + /// Gets or sets a value indicating whether to qualify only if needed. /// /// true if qualify only if needed; otherwise, false. [XmlAttribute] - [DefaultValue(false)] - public virtual bool QualifyAlways + [DefaultValue(c_QualifyOnlyIfNeededDefault)] + public virtual bool QualifyOnlyIfNeeded { - get => m_QualifyAlways; + get => m_QualifyOnlyIfNeeded; + set { - if (m_QualifyAlways.Equals(value)) + if (m_QualifyOnlyIfNeeded.Equals(value)) return; - m_QualifyAlways = value; - if (m_QualifyAlways) - QualifyOnlyIfNeeded = false; - NotifyPropertyChanged(nameof(QualifyAlways)); + m_QualifyOnlyIfNeeded = value; + if (m_QualifyOnlyIfNeeded) + QualifyAlways = false; + NotifyPropertyChanged(nameof(QualifyOnlyIfNeeded)); } } @@ -308,6 +388,7 @@ public virtual string QuotePlaceholder Contract.Ensures(Contract.Result() != null); return m_QuotePlaceholder; } + set { var newVal = (value ?? string.Empty).Trim(); @@ -360,70 +441,6 @@ public virtual bool ValueFormatSpecified } } - /// - /// Clones this instance into a new instance of the same type - /// - /// - public FileFormat Clone() - { - Contract.Ensures(Contract.Result() != null); - var other = new FileFormat(); - CopyTo(other); - return other; - } - - /// - /// Copies to. - /// - /// The other. - public virtual void CopyTo(FileFormat other) - { - if (other == null) - return; - - other.CommentLine = m_CommentLine; - other.DelimiterPlaceholder = m_DelimiterPlaceholder; - other.EscapeCharacter = m_EscapeCharacter; - other.FieldDelimiter = m_FieldDelimiter; - other.FieldQualifier = m_FieldQualifier; - other.NewLine = m_NewLine; - other.NewLinePlaceholder = m_NewLinePlaceholder; - other.QualifyOnlyIfNeeded = m_QualifyOnlyIfNeeded; - other.QualifyAlways = m_QualifyAlways; - other.QuotePlaceholder = m_QuotePlaceholder; - ValueFormat.CopyTo(other.ValueFormat); - } - - /// Indicates whether the current object is equal to another object of the same type. - /// An object to compare with this object. - /// - /// if the current object is equal to the parameter; otherwise, - /// . - /// - public bool Equals(FileFormat other) - { - if (other is null) - return false; - if (ReferenceEquals(this, other)) - return true; - return string.Equals(m_CommentLine, other.m_CommentLine, StringComparison.Ordinal) && - string.Equals(m_DelimiterPlaceholder, other.m_DelimiterPlaceholder, StringComparison.Ordinal) && - string.Equals(m_EscapeCharacter, other.m_EscapeCharacter, StringComparison.Ordinal) && - m_EscapeCharacterChar == other.m_EscapeCharacterChar && - string.Equals(m_FieldDelimiter, other.m_FieldDelimiter, StringComparison.Ordinal) && - m_FieldDelimiterChar == other.m_FieldDelimiterChar && - string.Equals(m_FieldQualifier, other.m_FieldQualifier, StringComparison.Ordinal) && - m_FieldQualifierChar == other.m_FieldQualifierChar && string.Equals(m_NewLine, other.m_NewLine, StringComparison.Ordinal) && - string.Equals(m_NewLinePlaceholder, other.m_NewLinePlaceholder, StringComparison.Ordinal) && - m_QualifyAlways == other.m_QualifyAlways && m_QualifyOnlyIfNeeded == other.m_QualifyOnlyIfNeeded && - string.Equals(m_QuotePlaceholder, other.m_QuotePlaceholder, StringComparison.Ordinal) && Equals(m_ValueFormat, other.m_ValueFormat); - } - - /// - /// Occurs when a property value changes. - /// - public event PropertyChangedEventHandler PropertyChanged; - /// /// Gets a char from a text /// @@ -513,11 +530,84 @@ public static string GetDescription(string inputString) } } + /// + /// Clones this instance into a new instance of the same type + /// + /// + public FileFormat Clone() + { + Contract.Ensures(Contract.Result() != null); + var other = new FileFormat(); + CopyTo(other); + return other; + } + + /// + /// Copies to. + /// + /// The other. + public virtual void CopyTo(FileFormat other) + { + if (other == null) + return; + + other.CommentLine = m_CommentLine; + other.AlternateQuoting = m_AlternateQuoting; + other.DuplicateQuotingToEscape = m_DuplicateQuotingToEscape; + other.DelimiterPlaceholder = m_DelimiterPlaceholder; + other.EscapeCharacter = m_EscapeCharacter; + other.FieldDelimiter = m_FieldDelimiter; + other.FieldQualifier = m_FieldQualifier; + other.NewLine = m_NewLine; + other.NewLinePlaceholder = m_NewLinePlaceholder; + other.QualifyOnlyIfNeeded = m_QualifyOnlyIfNeeded; + other.QualifyAlways = m_QualifyAlways; + other.QuotePlaceholder = m_QuotePlaceholder; + ValueFormat.CopyTo(other.ValueFormat); + } + + /// Indicates whether the current object is equal to another object of the same type. + /// An object to compare with this object. + /// + /// if the current object is equal to the parameter; otherwise, + /// . + /// + public bool Equals(FileFormat other) + { + if (other is null) + return false; + if (ReferenceEquals(this, other)) + return true; + return m_AlternateQuoting == other.AlternateQuoting + && m_DuplicateQuotingToEscape == other.DuplicateQuotingToEscape + && string.Equals(m_CommentLine, other.m_CommentLine, StringComparison.Ordinal) + && string.Equals(m_DelimiterPlaceholder, other.m_DelimiterPlaceholder, StringComparison.Ordinal) + && string.Equals(m_EscapeCharacter, other.m_EscapeCharacter, StringComparison.Ordinal) + && m_EscapeCharacterChar == other.m_EscapeCharacterChar + && string.Equals(m_FieldDelimiter, other.m_FieldDelimiter, StringComparison.Ordinal) + && m_FieldDelimiterChar == other.m_FieldDelimiterChar + && string.Equals(m_FieldQualifier, other.m_FieldQualifier, StringComparison.Ordinal) + && m_FieldQualifierChar == other.m_FieldQualifierChar + && string.Equals(m_NewLine, other.m_NewLine, StringComparison.Ordinal) + && string.Equals(m_NewLinePlaceholder, other.m_NewLinePlaceholder, StringComparison.Ordinal) + && m_QualifyAlways == other.m_QualifyAlways && m_QualifyOnlyIfNeeded == other.m_QualifyOnlyIfNeeded + && string.Equals(m_QuotePlaceholder, other.m_QuotePlaceholder, StringComparison.Ordinal) + && Equals(m_ValueFormat, other.m_ValueFormat); + } + + /// Determines whether the specified object is equal to the current object. + /// The object to compare with the current object. + /// + /// if the specified object is equal to the current object; otherwise, . + /// + public override bool Equals(object obj) => Equals(obj as FileFormat); + /// /// Notifies the property changed. /// /// The info. - public virtual void NotifyPropertyChanged(string info) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info)); + public virtual void NotifyPropertyChanged(string info) => + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info)); /// /// Returns a that represents this instance. @@ -544,13 +634,6 @@ private void ObjectInvariant() Contract.Invariant(m_ValueFormat != null); } - /// Determines whether the specified object is equal to the current object. - /// The object to compare with the current object. - /// - /// if the specified object is equal to the current object; otherwise, . - /// - public override bool Equals(object obj) => Equals(obj as FileFormat); - /* /// Serves as the default hash function. /// A hash code for the current object. diff --git a/Library/ClassLibraryCSV/ICsvFile.cs b/Library/ClassLibraryCSV/ICsvFile.cs index 05c39f67..6c55da23 100644 --- a/Library/ClassLibraryCSV/ICsvFile.cs +++ b/Library/ClassLibraryCSV/ICsvFile.cs @@ -32,17 +32,6 @@ public interface ICsvFile : IFileSettingPhysicalFile, IEquatable /// bool AllowRowCombining { get; set; } - /// - /// Gets or sets a value indicating whether this instance should use alternate quoting - /// - /// true if Alternate quoting should be used, false otherwise. - /// - /// Test,"This is a "Test"",OK - /// -- > This is a "Test" - /// - bool AlternateQuoting { get; set; } - - bool DuplicateQuotingToEscape { get; set; } /// /// Gets or sets a value indicating whether the byte order mark should be written in Unicode files. /// diff --git a/Library/ClassLibraryCSVUnitTest/CsvDataReaderPGP_FilesTest.cs b/Library/ClassLibraryCSVUnitTest/CsvDataReaderPGP_FilesTest.cs index d30a1650..9f813344 100644 --- a/Library/ClassLibraryCSVUnitTest/CsvDataReaderPGP_FilesTest.cs +++ b/Library/ClassLibraryCSVUnitTest/CsvDataReaderPGP_FilesTest.cs @@ -24,9 +24,9 @@ public void ReadGZip() var setting = new CsvFile { HasFieldHeader = true, - AlternateQuoting = true }; setting.FileName = "BasicCSV.txt.gz"; + setting.FileFormat.AlternateQuoting = true; setting.ColumnCollection.AddIfNew(new Column { Name = "ExamDate", @@ -60,9 +60,9 @@ public void ReadPGP() { var setting = new CsvFile { - HasFieldHeader = true, - AlternateQuoting = true + HasFieldHeader = true }; + setting.FileFormat.AlternateQuoting = true; PGPKeyStorageTestHelper.SetApplicationSetting(); setting.FileName = "BasicCSV.pgp"; setting.ColumnCollection.AddIfNew(new Column @@ -97,9 +97,9 @@ public void ReadGPG() { var setting = new CsvFile { - HasFieldHeader = true, - AlternateQuoting = true + HasFieldHeader = true }; + setting.FileFormat.AlternateQuoting = true; PGPKeyStorageTestHelper.SetApplicationSetting(); setting.FileName = "BasicCSV.pgp"; setting.ColumnCollection.AddIfNew(new Column diff --git a/Library/ClassLibraryCSVUnitTest/CsvDataReader_FilesTest.cs b/Library/ClassLibraryCSVUnitTest/CsvDataReader_FilesTest.cs index 51b69712..49b0f8c2 100644 --- a/Library/ClassLibraryCSVUnitTest/CsvDataReader_FilesTest.cs +++ b/Library/ClassLibraryCSVUnitTest/CsvDataReader_FilesTest.cs @@ -100,8 +100,9 @@ public void CsvDataReaderCancellationOnOpen() var setting = new CsvFile { HasFieldHeader = false, - AlternateQuoting = true + }; + setting.FileFormat.AlternateQuoting = true; setting.TrimmingOption = TrimmingOption.All; setting.FileName = Path.Combine(m_ApplicationDirectory, "AlternateTextQualifiers.txt"); @@ -121,11 +122,12 @@ public void AlternateTextQualifiersDoubleQuotes() { var setting = new CsvFile { - HasFieldHeader = false, - AlternateQuoting = true, - DuplicateQuotingToEscape = true + HasFieldHeader = false }; + setting.FileFormat.FieldDelimiter = ","; + setting.FileFormat.AlternateQuoting = true; + setting.FileFormat.DuplicateQuotingToEscape = true; setting.FileName = Path.Combine(m_ApplicationDirectory, "AlternateTextQualifiersDoubleQuote.txt"); using (var processDisplay = new DummyProcessDisplay()) using (var test = new CsvFileReader(setting, processDisplay)) @@ -145,10 +147,10 @@ public void AlternateTextQualifiersTrimQuoted() { var setting = new CsvFile { - HasFieldHeader = false, - AlternateQuoting = true + HasFieldHeader = false }; setting.FileFormat.FieldDelimiter = ","; + setting.FileFormat.AlternateQuoting = true; setting.TrimmingOption = TrimmingOption.All; setting.FileName = Path.Combine(m_ApplicationDirectory, "AlternateTextQualifiers.txt"); using (var processDisplay = new DummyProcessDisplay()) @@ -181,10 +183,10 @@ public void AlternateTextQualifiersTrimUnquoted() var setting = new CsvFile { HasFieldHeader = false, - AlternateQuoting = true, WarnQuotes = true }; setting.FileFormat.FieldDelimiter = ","; + setting.FileFormat.AlternateQuoting = true; setting.TrimmingOption = TrimmingOption.Unquoted; setting.FileName = Path.Combine(m_ApplicationDirectory, "AlternateTextQualifiers.txt"); diff --git a/Library/ClassLibraryCSVUnitTest/CsvFileTest.cs b/Library/ClassLibraryCSVUnitTest/CsvFileTest.cs index de1b20df..04ef0d97 100644 --- a/Library/ClassLibraryCSVUnitTest/CsvFileTest.cs +++ b/Library/ClassLibraryCSVUnitTest/CsvFileTest.cs @@ -353,7 +353,7 @@ public void Init() m_CsvFile.TemplateName = "TemplateName"; m_CsvFile.WarnLineFeed = false; Assert.IsFalse(m_CsvFile.WarnLineFeed); - m_CsvFile.AlternateQuoting = false; + m_CsvFile.FileFormat.AlternateQuoting = false; Assert.IsFalse(m_CsvFile.TreatNBSPAsSpace, "TreatNBSPAsSpace"); //Assert.IsFalse(m_CsvFile.TreatNBSPAsUnknowCharater, "TreatNBSPAsUnknowCharater"); diff --git a/Library/ClassLibraryCSVUnitTest/Helper.cs b/Library/ClassLibraryCSVUnitTest/Helper.cs index e4bc4108..c9012fbf 100644 --- a/Library/ClassLibraryCSVUnitTest/Helper.cs +++ b/Library/ClassLibraryCSVUnitTest/Helper.cs @@ -44,7 +44,7 @@ internal static CsvFile ReaderGetAllFormats(string id = "AllFormats") HasFieldHeader = true, FileFormat = {FieldDelimiter = "TAB"} }; - + var timeFld = readFile.ColumnCollection.AddIfNew(new Column { Name = "DateTime", DataType = DataType.DateTime }); Debug.Assert(timeFld != null); timeFld.DateFormat = @"dd/MM/yyyy"; diff --git a/Library/ClassLibraryCSVUnitTest/TimeZoneMappingTests.cs b/Library/ClassLibraryCSVUnitTest/TimeZoneMappingTests.cs index 0d56954d..b329b53f 100644 --- a/Library/ClassLibraryCSVUnitTest/TimeZoneMappingTests.cs +++ b/Library/ClassLibraryCSVUnitTest/TimeZoneMappingTests.cs @@ -26,6 +26,29 @@ public class TimeZoneMappingTests private readonly string tzMSK = "Europe/Moscow"; private readonly string tzPST = "America/Los_Angeles"; + [TestMethod()] + public void GetTimeZoneID() + { + Assert.AreEqual(tzCET, TimeZoneMapping.GetTimeZoneID(tzCET)); + Assert.AreEqual("Europe/Berlin", TimeZoneMapping.GetTimeZoneID("W. Europe Standard Time")); + } + + [TestMethod()] + public void GetTranstionTimes() + { + var res = TimeZoneMapping.GetTranstionTimes(tzCET, 2020); + + Assert.AreEqual(new DateTime(2020, 3, 29, 1, 0, 0, DateTimeKind.Utc), res.Item1); + Assert.AreEqual(new DateTime(2020, 10, 25, 1, 0, 0, DateTimeKind.Utc), res.Item2); + } + + [TestMethod()] + public void ConvertTimeUTC() + { + Assert.AreEqual(new DateTime(2020, 1, 2, 1, 0, 0, DateTimeKind.Utc), TimeZoneMapping.ConvertTimeUTC(new DateTime(2020, 1, 2), tzCET)); + } + + [TestMethod()] public void ConvertTime() { diff --git a/Library/WinFormControls/QuotingControl.cs b/Library/WinFormControls/QuotingControl.cs index 636c45ba..790a1249 100644 --- a/Library/WinFormControls/QuotingControl.cs +++ b/Library/WinFormControls/QuotingControl.cs @@ -53,8 +53,6 @@ public class QuotingControl : UserControl private BindingSource m_FileFormatBindingSource; - private BindingSource m_FileSettingBindingSource; - private bool m_IsWriteSetting; private Label m_Label1; @@ -125,7 +123,6 @@ public ICsvFile CsvFile if (m_CsvFile == null) return; - m_FileSettingBindingSource.DataSource = m_CsvFile; m_FileFormatBindingSource.DataSource = m_CsvFile.FileFormat; m_CsvFile.FileFormat.PropertyChanged += FormatPropertyChanged; @@ -177,7 +174,8 @@ protected override void Dispose(bool disposing) private void FormatPropertyChanged(object sender, PropertyChangedEventArgs e) { - if (e.PropertyName == nameof(FileFormat.FieldDelimiter)) + if (e.PropertyName == nameof(FileFormat.FieldDelimiter) || + e.PropertyName == nameof(FileFormat.DuplicateQuotingToEscape)) SetToolTipPlaceholder(); } @@ -191,13 +189,11 @@ private void InitializeComponent() this.m_LabelQuote = new System.Windows.Forms.Label(); this.m_LabelQuotePlaceholer = new System.Windows.Forms.Label(); this.m_TextBoxEscape = new System.Windows.Forms.TextBox(); - this.m_FileFormatBindingSource = new System.Windows.Forms.BindingSource(this.components); this.m_LabelEscapeCharacter = new System.Windows.Forms.Label(); this.m_LabelTrim = new System.Windows.Forms.Label(); this.m_TextBoxQuote = new System.Windows.Forms.TextBox(); this.m_TextBoxQuotePlaceHolder = new System.Windows.Forms.TextBox(); this.checkBoxAlternateQuoting = new System.Windows.Forms.CheckBox(); - this.m_FileSettingBindingSource = new System.Windows.Forms.BindingSource(this.components); this.m_ToolTip = new System.Windows.Forms.ToolTip(this.components); this.comboBoxTrim = new System.Windows.Forms.ComboBox(); this.checkBoxDuplicateQuotingToEscape = new System.Windows.Forms.CheckBox(); @@ -220,11 +216,11 @@ private void InitializeComponent() this.m_RichTextBox02 = new CsvTools.CSVRichTextBox(); this.checkBoxQualifyAlways = new System.Windows.Forms.CheckBox(); this.checkBoxQualifyOnlyNeeded = new System.Windows.Forms.CheckBox(); + this.m_FileFormatBindingSource = new System.Windows.Forms.BindingSource(this.components); m_Label5 = new System.Windows.Forms.Label(); - ((System.ComponentModel.ISupportInitialize)(this.m_FileFormatBindingSource)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.m_FileSettingBindingSource)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.m_ErrorProvider)).BeginInit(); this.m_TableLayoutPanel.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.m_FileFormatBindingSource)).BeginInit(); this.SuspendLayout(); // // m_Label5 @@ -272,11 +268,6 @@ private void InitializeComponent() this.m_TextBoxEscape.Size = new System.Drawing.Size(243, 22); this.m_TextBoxEscape.TabIndex = 6; // - // m_FileFormatBindingSource - // - this.m_FileFormatBindingSource.AllowNew = false; - this.m_FileFormatBindingSource.DataSource = typeof(CsvTools.FileFormat); - // // m_LabelEscapeCharacter // this.m_LabelEscapeCharacter.Anchor = System.Windows.Forms.AnchorStyles.Right; @@ -336,7 +327,7 @@ private void InitializeComponent() this.checkBoxAlternateQuoting.Anchor = System.Windows.Forms.AnchorStyles.Left; this.checkBoxAlternateQuoting.AutoSize = true; this.m_TableLayoutPanel.SetColumnSpan(this.checkBoxAlternateQuoting, 2); - this.checkBoxAlternateQuoting.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.m_FileSettingBindingSource, "AlternateQuoting", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.checkBoxAlternateQuoting.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.m_FileFormatBindingSource, "AlternateQuoting", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.checkBoxAlternateQuoting.Location = new System.Drawing.Point(388, 4); this.checkBoxAlternateQuoting.Margin = new System.Windows.Forms.Padding(4); this.checkBoxAlternateQuoting.Name = "checkBoxAlternateQuoting"; @@ -348,11 +339,6 @@ private void InitializeComponent() this.checkBoxAlternateQuoting.UseVisualStyleBackColor = true; this.checkBoxAlternateQuoting.Visible = false; // - // m_FileSettingBindingSource - // - this.m_FileSettingBindingSource.AllowNew = false; - this.m_FileSettingBindingSource.DataSource = typeof(CsvTools.CsvFile); - // // comboBoxTrim // this.comboBoxTrim.DisplayMember = "Display"; @@ -371,7 +357,7 @@ private void InitializeComponent() // checkBoxDuplicateQuotingToEscape // this.checkBoxDuplicateQuotingToEscape.AutoSize = true; - this.checkBoxDuplicateQuotingToEscape.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.m_FileSettingBindingSource, "DuplicateQuotingToEscape", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); + this.checkBoxDuplicateQuotingToEscape.DataBindings.Add(new System.Windows.Forms.Binding("Checked", this.m_FileFormatBindingSource, "DuplicateQuotingToEscape", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); this.checkBoxDuplicateQuotingToEscape.Location = new System.Drawing.Point(587, 3); this.checkBoxDuplicateQuotingToEscape.Name = "checkBoxDuplicateQuotingToEscape"; this.checkBoxDuplicateQuotingToEscape.Size = new System.Drawing.Size(146, 21); @@ -708,6 +694,11 @@ private void InitializeComponent() this.checkBoxQualifyOnlyNeeded.UseVisualStyleBackColor = true; this.checkBoxQualifyOnlyNeeded.Visible = false; // + // m_FileFormatBindingSource + // + this.m_FileFormatBindingSource.AllowNew = false; + this.m_FileFormatBindingSource.DataSource = typeof(CsvTools.FileFormat); + // // QuotingControl // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); @@ -717,11 +708,10 @@ private void InitializeComponent() this.MinimumSize = new System.Drawing.Size(829, 0); this.Name = "QuotingControl"; this.Size = new System.Drawing.Size(829, 264); - ((System.ComponentModel.ISupportInitialize)(this.m_FileFormatBindingSource)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.m_FileSettingBindingSource)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.m_ErrorProvider)).EndInit(); this.m_TableLayoutPanel.ResumeLayout(false); this.m_TableLayoutPanel.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.m_FileFormatBindingSource)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); @@ -787,7 +777,16 @@ private void SetToolTipPlaceholder() => m_RichTextBox12.Text = "Column with \nLinefeed"; } - m_RichTextBox11.Text = "Column with:" + quote + " Quote"; + if (checkBoxAlternateQuoting.Checked && !checkBoxDuplicateQuotingToEscape.Checked) + { + m_RichTextBox11.Text = "Column with:" + quote + quote + " Quote"; + } + else + { + m_RichTextBox11.Text = "Column with:" + quote + " Quote"; + } + + // richTextBox11.Quote = quote[0]; var newToolTip = m_IsWriteSetting diff --git a/Library/WinFormControls/QuotingControl.resx b/Library/WinFormControls/QuotingControl.resx index 9ec6a649..c4841569 100644 --- a/Library/WinFormControls/QuotingControl.resx +++ b/Library/WinFormControls/QuotingControl.resx @@ -120,16 +120,19 @@ False - - 17, 17 - 525, 18 - - 266, 20 + + 254, 19 - 641, 16 + 396, 17 + + + 17, 17 + + + 17, 17 \ No newline at end of file diff --git a/Setup/Product.wxs b/Setup/Product.wxs index d8a2c3bf..36c4b033 100644 --- a/Setup/Product.wxs +++ b/Setup/Product.wxs @@ -123,7 +123,7 @@ - +