From f8ad716dde7ce4637d5add317164a8fca652bd18 Mon Sep 17 00:00:00 2001 From: Brandon Desjarlais Date: Tue, 7 May 2024 09:49:40 -0500 Subject: [PATCH 1/8] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cf87439..a49dd9b 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,9 @@ For the latest and greatest you can build the [Master](https://github.com/desjar **Versions before v.5.3.1.1:** [Microsoft Visual C++ Redistributable for Visual Studio 2015, 2017, 2019, and 2022](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170) is required for the component to work, see [#16](https://github.com/desjarlais/Scintilla.NET/issues/16). -Scintilla library version = 5.4.3 +Scintilla library version = 5.5.0 -Lexilla library version = 5.3.1 +Lexilla library version = 5.3.2 ## Background For more information about the history and background information, look at the wiki [here](https://github.com/desjarlais/Scintilla.NET/wiki/Scintilla.NET-History). From 87a499db00f0fea3af4372f22a4441fff1cb5c60 Mon Sep 17 00:00:00 2001 From: Ahmet Sait Date: Tue, 7 May 2024 16:53:14 +0300 Subject: [PATCH 2/8] Simplify local NuGet script --- Scintilla.NET/Scintilla.NET.csproj | 2 +- Scintilla.NET/nupkg.ps1 | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Scintilla.NET/Scintilla.NET.csproj b/Scintilla.NET/Scintilla.NET.csproj index c2410ec..7614fc6 100644 --- a/Scintilla.NET/Scintilla.NET.csproj +++ b/Scintilla.NET/Scintilla.NET.csproj @@ -57,6 +57,6 @@ - + diff --git a/Scintilla.NET/nupkg.ps1 b/Scintilla.NET/nupkg.ps1 index a27485f..d60bb0e 100644 --- a/Scintilla.NET/nupkg.ps1 +++ b/Scintilla.NET/nupkg.ps1 @@ -1,4 +1,5 @@ param ( + [Parameter(Mandatory=$true)][string]$MSBuildProjectDirectory, [Parameter(Mandatory=$true)][string]$NuGetPackageRoot, [Parameter(Mandatory=$true)][string]$NuGetPackageSourceDir, [Parameter(Mandatory=$true)][string]$PackageOutputPath, @@ -6,6 +7,8 @@ param ( [Parameter(Mandatory=$true)][string]$PackageVersion ) +Set-Location -Path $MSBuildProjectDirectory + $PackageVersionList = $PackageVersion.Split('.') if ($PackageVersionList.Count -Eq 4 -And [int]::Parse($PackageVersionList[3]) -Eq 0) { From 2e17f622146a6d24615a1673412a356f99638197 Mon Sep 17 00:00:00 2001 From: Ahmet Sait Date: Tue, 7 May 2024 16:54:16 +0300 Subject: [PATCH 3/8] Alpha color support for markers --- Scintilla.NET/Marker.cs | 6 +++--- Scintilla.NET/NativeMethods.cs | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/Scintilla.NET/Marker.cs b/Scintilla.NET/Marker.cs index 5cfdc27..6cf1031 100644 --- a/Scintilla.NET/Marker.cs +++ b/Scintilla.NET/Marker.cs @@ -106,7 +106,7 @@ public void SetAlpha(int alpha) public void SetBackColor(Color color) { var colour = HelperMethods.ToWin32Color(color); - scintilla.DirectMessage(NativeMethods.SCI_MARKERSETBACK, new IntPtr(Index), new IntPtr(colour)); + scintilla.DirectMessage(NativeMethods.SCI_MARKERSETBACKTRANSLUCENT, new IntPtr(Index), new IntPtr(colour)); } /// @@ -116,7 +116,7 @@ public void SetBackColor(Color color) public void SetForeColor(Color color) { var colour = HelperMethods.ToWin32Color(color); - scintilla.DirectMessage(NativeMethods.SCI_MARKERSETFORE, new IntPtr(Index), new IntPtr(colour)); + scintilla.DirectMessage(NativeMethods.SCI_MARKERSETFORETRANSLUCENT, new IntPtr(Index), new IntPtr(colour)); } /// @@ -155,4 +155,4 @@ public Marker(Scintilla scintilla, int index) this.scintilla = scintilla; Index = index; } -} \ No newline at end of file +} diff --git a/Scintilla.NET/NativeMethods.cs b/Scintilla.NET/NativeMethods.cs index b582230..757df79 100644 --- a/Scintilla.NET/NativeMethods.cs +++ b/Scintilla.NET/NativeMethods.cs @@ -372,6 +372,8 @@ public static class NativeMethods public const int SCI_MARKERDEFINE = 2040; public const int SCI_MARKERSETFORE = 2041; public const int SCI_MARKERSETBACK = 2042; + public const int SCI_MARKERSETFORETRANSLUCENT = 2294; + public const int SCI_MARKERSETBACKTRANSLUCENT = 2295; public const int SCI_MARKERSETBACKSELECTED = 2292; public const int SCI_MARKERENABLEHIGHLIGHT = 2293; public const int SCI_MARKERADD = 2043; From 90a72439e449b4e23a39322401417e7eb967e7a8 Mon Sep 17 00:00:00 2001 From: Ahmet Sait Date: Tue, 7 May 2024 16:56:17 +0300 Subject: [PATCH 4/8] Make `Margins` invisible in designer --- Scintilla.NET/Scintilla.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Scintilla.NET/Scintilla.cs b/Scintilla.NET/Scintilla.cs index 2ae4c37..20cb48e 100644 --- a/Scintilla.NET/Scintilla.cs +++ b/Scintilla.NET/Scintilla.cs @@ -5128,7 +5128,8 @@ public int MainSelection /// A collection of margins. [Category("Collections")] [Description("The margins collection.")] - [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [TypeConverter(typeof(ExpandableObjectConverter))] public MarginCollection Margins { get; private set; } From cdd6ecae09be8da8fea59e45c25089194174f571 Mon Sep 17 00:00:00 2001 From: Ahmet Sait Date: Tue, 7 May 2024 16:57:23 +0300 Subject: [PATCH 5/8] Add missing indicator styles --- Scintilla.NET/IndicatorStyle.cs | 30 ++++++++++++++++++++---------- Scintilla.NET/NativeMethods.cs | 1 + 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/Scintilla.NET/IndicatorStyle.cs b/Scintilla.NET/IndicatorStyle.cs index e07b288..95d52f6 100644 --- a/Scintilla.NET/IndicatorStyle.cs +++ b/Scintilla.NET/IndicatorStyle.cs @@ -73,6 +73,11 @@ public enum IndicatorStyle /// DotBox = NativeMethods.INDIC_DOTBOX, + /// + /// A version of Squiggle that draws using a pixmap instead of as a series of line segments for performance. + /// + SquigglePixmap = NativeMethods.INDIC_SQUIGGLEPIXMAP, + // PIXMAP /// @@ -104,15 +109,20 @@ public enum IndicatorStyle /// /// A triangle below the center of the first character of the indicator range. /// - PointCharacter = NativeMethods.INDIC_POINTCHARACTER /*, + PointCharacter = NativeMethods.INDIC_POINTCHARACTER, + + /// + /// A vertical gradient between a color and alpha at top to fully transparent at bottom. + /// + Gradient = NativeMethods.INDIC_GRADIENT, - /// - /// A vertical gradient between a color and alpha at top to fully transparent at bottom. - /// - Gradient = NativeMethods.INDIC_GRADIENT, + /// + /// A vertical gradient with color and alpha in the mid-line fading to fully transparent at top and bottom. + /// + GradientCenter = NativeMethods.INDIC_GRADIENTCENTRE, - /// - /// A vertical gradient with color and alpha in the mid-line fading to fully transparent at top and bottom. - /// - GradientCenter = NativeMethods.INDIC_GRADIENTCENTRE */ -} \ No newline at end of file + /// + /// A triangle above the start of the indicator range. + /// + PointTop = NativeMethods.INDIC_POINT_TOP, +} diff --git a/Scintilla.NET/NativeMethods.cs b/Scintilla.NET/NativeMethods.cs index 757df79..02529c0 100644 --- a/Scintilla.NET/NativeMethods.cs +++ b/Scintilla.NET/NativeMethods.cs @@ -103,6 +103,7 @@ public static class NativeMethods public const int INDIC_GRADIENT = 20; public const int INDIC_GRADIENTCENTRE = 21; public const int INDIC_MAX = 31; + public const int INDIC_POINT_TOP = 22; public const int INDIC_CONTAINER = 8; // Phases From d8083578586010b976e8eb0cb17125d6f0b5d89d Mon Sep 17 00:00:00 2001 From: Ahmet Sait Date: Tue, 7 May 2024 16:58:16 +0300 Subject: [PATCH 6/8] Fix #105: Implement change history --- Scintilla.NET/ChangeHistory.cs | 34 ++++++ Scintilla.NET/FlagsEditor.cs | 161 +++++++++++++++++++++++++++ Scintilla.NET/IndicatorCollection.cs | 4 +- Scintilla.NET/Marker.cs | 26 +++++ Scintilla.NET/MarkerSymbol.cs | 12 +- Scintilla.NET/NativeMethods.cs | 41 ++++++- Scintilla.NET/Scintilla.cs | 32 ++++++ 7 files changed, 305 insertions(+), 5 deletions(-) create mode 100644 Scintilla.NET/ChangeHistory.cs create mode 100644 Scintilla.NET/FlagsEditor.cs diff --git a/Scintilla.NET/ChangeHistory.cs b/Scintilla.NET/ChangeHistory.cs new file mode 100644 index 0000000..e7f9cfa --- /dev/null +++ b/Scintilla.NET/ChangeHistory.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ScintillaNET; + +/// +/// Bit-flags for whether Scintilla should keep track of document change history and in which ways it should display the difference. +/// +[Flags] +public enum ChangeHistory : int +{ + /// + /// The default: change history turned off. + /// + Disabled = NativeMethods.SC_CHANGE_HISTORY_DISABLED, + + /// + /// Track changes to the document. + /// + Enabled = NativeMethods.SC_CHANGE_HISTORY_ENABLED, + + /// + /// Display changes in the margin using the SC_MARKNUM_HISTORY markers. + /// + Markers = NativeMethods.SC_CHANGE_HISTORY_MARKERS, + + /// + /// Display changes in the text using the INDICATOR_HISTORY indicators. + /// + Indicators = NativeMethods.SC_CHANGE_HISTORY_INDICATORS, +} diff --git a/Scintilla.NET/FlagsEditor.cs b/Scintilla.NET/FlagsEditor.cs new file mode 100644 index 0000000..7ccd921 --- /dev/null +++ b/Scintilla.NET/FlagsEditor.cs @@ -0,0 +1,161 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing.Design; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.Windows.Forms.Design; + +namespace ScintillaNET; + +internal class FlagsConverter : TypeConverter where T : struct, Enum +{ + public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) + { + return destinationType == typeof(string) || base.CanConvertTo(context, destinationType); + } + + public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) + { + return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType); + } + + public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) + { + if (value is Enum e && destinationType == typeof(string)) + { + if (Convert.ToUInt64(e) == 0) + { + return Enum.ToObject(e.GetType(), 0).ToString(); + } + StringBuilder sb = new StringBuilder(); + foreach (Enum item in Enum.GetValues(e.GetType())) + { + if (Convert.ToUInt64(item) != 0 && e.HasFlag(item)) + { + if (sb.Length > 0) + sb.Append(" | "); + sb.Append(item); + } + } + return sb.ToString(); + } + return base.ConvertTo(context, culture, value, destinationType); + } + + public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) + { + if (value is string str) + { + Type t = typeof(T); + ulong bits = 0; + var nameList = str.Split('|').Select(x => x.Trim()); + foreach (var name in nameList) + { + if (Enum.TryParse(name, out T bit)) + bits |= Convert.ToUInt64(bit); + else + throw new InvalidCastException($"Cannot convert \"{str.Replace("\"", "\\\"")}\" to {t}."); + } + return Enum.ToObject(t, bits); + } + return base.ConvertFrom(context, culture, value); + } +} + +internal class FlagsEditor : UITypeEditor +{ + public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) => UITypeEditorEditStyle.DropDown; + + public override bool IsDropDownResizable => true; + + private int inCheck = 0; + + private static ulong CombineEnumList(IEnumerable checkedList) + { + ulong bits = 0; + foreach (var item in checkedList) + { + bits |= Convert.ToUInt64(item); + } + return bits; + } + + public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) + { + if (value is Enum e && context.PropertyDescriptor.Attributes.OfType().Any()) + { + IWindowsFormsEditorService svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService)); + Type enumType = e.GetType(); + + CheckedListBox checkedListBox = new() { + Dock = DockStyle.Fill, + CheckOnClick = true, + }; + checkedListBox.ItemCheck += (object sender, ItemCheckEventArgs e) => { + if (inCheck > 0) + return; + inCheck++; + try + { + ulong bits = CombineEnumList(checkedListBox.CheckedItems); + ulong change = Convert.ToUInt64(checkedListBox.Items[e.Index]); + if (e.NewValue == CheckState.Checked) + bits |= change; + else if (e.NewValue == CheckState.Unchecked) + bits &= ~change; + Enum enumFinal = (Enum)Enum.ToObject(enumType, bits); + for (int i = 0; i < checkedListBox.Items.Count; i++) + { + Enum itemValue = (Enum)checkedListBox.Items[i]; + checkedListBox.SetItemChecked(i, enumFinal.HasFlag(itemValue)); + } + } + finally + { + inCheck--; + } + }; + inCheck++; + try + { + foreach (Enum item in Enum.GetValues(enumType)) + { + if (Convert.ToUInt64(item) != 0) + checkedListBox.Items.Add(item, e.HasFlag(item)); + } + } + finally + { + inCheck--; + } + Button okBtton = new() { + Dock = DockStyle.Bottom, + AutoSize = true, + AutoSizeMode = AutoSizeMode.GrowAndShrink, + UseVisualStyleBackColor = true, + }; + UserControl userControl = new(); + userControl.Controls.Add(checkedListBox); + userControl.Controls.Add(okBtton); + okBtton.Text = NativeMethods.GetMessageBoxString(0); // OK + okBtton.Click += (object sender, EventArgs e) => { + ulong bits = 0; + foreach (Enum item in checkedListBox.CheckedItems) + { + bits |= Convert.ToUInt64(item); + } + value = Enum.ToObject(enumType, bits); + svc.CloseDropDown(); + }; + svc.DropDownControl(userControl); + return value; + } + else + return base.EditValue(context, provider, value); + } +} diff --git a/Scintilla.NET/IndicatorCollection.cs b/Scintilla.NET/IndicatorCollection.cs index 85f147d..7953966 100644 --- a/Scintilla.NET/IndicatorCollection.cs +++ b/Scintilla.NET/IndicatorCollection.cs @@ -39,7 +39,7 @@ public int Count { get { - return (NativeMethods.INDIC_MAX + 1); + return NativeMethods.INDICATOR_MAX + 1; } } @@ -71,4 +71,4 @@ public IndicatorCollection(Scintilla scintilla) { this.scintilla = scintilla; } -} \ No newline at end of file +} diff --git a/Scintilla.NET/Marker.cs b/Scintilla.NET/Marker.cs index 6cf1031..f365d2b 100644 --- a/Scintilla.NET/Marker.cs +++ b/Scintilla.NET/Marker.cs @@ -15,6 +15,32 @@ public class Marker /// public const uint MaskAll = unchecked((uint)-1); + /// + /// An unsigned 32-bit mask of history indexes (21 through 24) where each bit cooresponds to a margin index. + /// + /// + public const uint MaskHistory = (1 << HistoryRevertedToOrigin) | (1 << HistorySaved) | (1 << HistoryModified) | (1 << HistoryRevertedToModified); + + /// + /// A change was made to this line and saved but then reverted to its original state. + /// + public const int HistoryRevertedToOrigin = NativeMethods.SC_MARKNUM_HISTORY_REVERTED_TO_ORIGIN; + + /// + /// This line was modified and saved. + /// + public const int HistorySaved = NativeMethods.SC_MARKNUM_HISTORY_SAVED; + + /// + /// This line was modified but not yet saved. + /// + public const int HistoryModified = NativeMethods.SC_MARKNUM_HISTORY_MODIFIED; + + /// + /// A change was made to this line and saved but then reverted but not to its original state. + /// + public const int HistoryRevertedToModified = NativeMethods.SC_MARKNUM_HISTORY_REVERTED_TO_MODIFIED; + /// /// An unsigned 32-bit mask of folder indexes (25 through 31) where each bit cooresponds to a margin index. /// diff --git a/Scintilla.NET/MarkerSymbol.cs b/Scintilla.NET/MarkerSymbol.cs index 02838ad..34e5377 100644 --- a/Scintilla.NET/MarkerSymbol.cs +++ b/Scintilla.NET/MarkerSymbol.cs @@ -162,5 +162,15 @@ public enum MarkerSymbol /// Bookmark = NativeMethods.SC_MARK_BOOKMARK, + /// + /// A bookmark. + /// + VerticalBookmark = NativeMethods.SC_MARK_VERTICALBOOKMARK, + + /// + /// A slim rectangular vertical bar. + /// + Bar = NativeMethods.SC_MARK_BAR, + // Character = NativeMethods.SC_MARK_CHARACTER -} \ No newline at end of file +} diff --git a/Scintilla.NET/NativeMethods.cs b/Scintilla.NET/NativeMethods.cs index 02529c0..453e74c 100644 --- a/Scintilla.NET/NativeMethods.cs +++ b/Scintilla.NET/NativeMethods.cs @@ -79,7 +79,7 @@ public static class NativeMethods // Message-only window public const int HWND_MESSAGE = (-3); - // Indicators + // Indicator styles public const int INDIC_PLAIN = 0; public const int INDIC_SQUIGGLE = 1; public const int INDIC_TT = 2; @@ -102,9 +102,26 @@ public static class NativeMethods public const int INDIC_POINTCHARACTER = 19; public const int INDIC_GRADIENT = 20; public const int INDIC_GRADIENTCENTRE = 21; - public const int INDIC_MAX = 31; public const int INDIC_POINT_TOP = 22; + + [Obsolete("Use INDICATOR_CONTAINER instead.")] public const int INDIC_CONTAINER = 8; + [Obsolete("Use INDICATOR_MAX instead.")] + public const int INDIC_MAX = 31; + + // Indicators + public const int INDICATOR_CONTAINER = 8; + public const int INDICATOR_IME = 32; + public const int INDICATOR_IME_MAX = 35; + public const int INDICATOR_HISTORY_REVERTED_TO_ORIGIN_INSERTION = 36; + public const int INDICATOR_HISTORY_REVERTED_TO_ORIGIN_DELETION = 37; + public const int INDICATOR_HISTORY_SAVED_INSERTION = 38; + public const int INDICATOR_HISTORY_SAVED_DELETION = 39; + public const int INDICATOR_HISTORY_MODIFIED_INSERTION = 40; + public const int INDICATOR_HISTORY_MODIFIED_DELETION = 41; + public const int INDICATOR_HISTORY_REVERTED_TO_MODIFIED_INSERTION = 42; + public const int INDICATOR_HISTORY_REVERTED_TO_MODIFIED_DELETION = 43; + public const int INDICATOR_MAX = 43; // Phases public const int SC_PHASES_ONE = 0; @@ -239,7 +256,13 @@ public static class NativeMethods public const int SC_MARK_UNDERLINE = 29; public const int SC_MARK_RGBAIMAGE = 30; public const int SC_MARK_BOOKMARK = 31; + public const int SC_MARK_VERTICALBOOKMARK = 32; + public const int SC_MARK_BAR = 33; public const int SC_MARK_CHARACTER = 10000; + public const int SC_MARKNUM_HISTORY_REVERTED_TO_ORIGIN = 21; + public const int SC_MARKNUM_HISTORY_SAVED = 22; + public const int SC_MARKNUM_HISTORY_MODIFIED = 23; + public const int SC_MARKNUM_HISTORY_REVERTED_TO_MODIFIED = 24; public const int SC_MARKNUM_FOLDEREND = 25; public const int SC_MARKNUM_FOLDEROPENMID = 26; public const int SC_MARKNUM_FOLDERMIDTAIL = 27; @@ -323,6 +346,12 @@ public static class NativeMethods public const int SC_ELEMENT_FOLD_LINE = 80; public const int SC_ELEMENT_HIDDEN_LINE = 81; + // Change history + public const int SC_CHANGE_HISTORY_DISABLED = 0; + public const int SC_CHANGE_HISTORY_ENABLED = 1; + public const int SC_CHANGE_HISTORY_MARKERS = 2; + public const int SC_CHANGE_HISTORY_INDICATORS = 4; + // Functions public const int SCI_START = 2000; public const int SCI_OPTIONAL_START = 3000; @@ -1003,6 +1032,8 @@ public static class NativeMethods public const int SCI_SETSELECTIONLAYER = 2763; public const int SCI_GETCARETLINELAYER = 2764; public const int SCI_SETCARETLINELAYER = 2765; + public const int SCI_SETCHANGEHISTORY = 2780; + public const int SCI_GETCHANGEHISTORY = 2781; public const int SCI_STARTRECORD = 3001; public const int SCI_STOPRECORD = 3002; public const int SCI_SETLEXER = 4001; @@ -1998,6 +2029,12 @@ public static class NativeMethods #region Functions + [DllImport(DLL_NAME_USER32, SetLastError = true)] + public static extern IntPtr MB_GetString(uint hInst); + + public static string GetMessageBoxString(uint msgId) => + Marshal.PtrToStringUni(MB_GetString(msgId)); + [DllImport(DLL_NAME_USER32, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CloseClipboard(); diff --git a/Scintilla.NET/Scintilla.cs b/Scintilla.NET/Scintilla.cs index 20cb48e..5631e42 100644 --- a/Scintilla.NET/Scintilla.cs +++ b/Scintilla.NET/Scintilla.cs @@ -3271,6 +3271,18 @@ public unsafe void ClearRepresentation(string encodedString) DirectMessage(NativeMethods.SCI_CLEARREPRESENTATION, new IntPtr(bpEncoded), IntPtr.Zero); } } + + /// + /// Clears the change history so that scintilla does not show any saved/modified markers. + /// Undo buffer is cleared but is not called. + /// + public void ClearChangeHistory() + { + EmptyUndoBuffer(); + var ch = this.ChangeHistory; + this.ChangeHistory = ChangeHistory.Disabled; + this.ChangeHistory = ch; + } #endregion Methods #region Properties @@ -4317,6 +4329,26 @@ public int CaretWidth } } + /// + /// Gets or sets whether Scintilla should keep track of document change history and in which ways it should display the difference. + /// + [Editor(typeof(FlagsEditor), typeof(UITypeEditor))] + [TypeConverter(typeof(FlagsConverter))] + [DefaultValue(ChangeHistory.Disabled)] + [Category("Change History")] + [Description("Controls whether Scintilla should keep track of document change history and in which ways it should display the difference.")] + public ChangeHistory ChangeHistory + { + get + { + return (ChangeHistory)DirectMessage(NativeMethods.SCI_GETCHANGEHISTORY).ToInt32(); + } + set + { + DirectMessage(NativeMethods.SCI_SETCHANGEHISTORY, new IntPtr((int)value)); + } + } + /// /// Gets the required creation parameters when the control handle is created. /// From 34dcd5190691604684cd2d4fe98afb790cd2764c Mon Sep 17 00:00:00 2001 From: Ahmet Sait Date: Tue, 7 May 2024 17:00:10 +0300 Subject: [PATCH 7/8] Use change history features in test app --- Scintilla.NET.TestApp/FormMain.Designer.cs | 7 +++ Scintilla.NET.TestApp/FormMain.cs | 58 +++++++++++++++++-- .../Scintilla.NET.TestApp.csproj | 1 + 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/Scintilla.NET.TestApp/FormMain.Designer.cs b/Scintilla.NET.TestApp/FormMain.Designer.cs index 138f53d..906d137 100644 --- a/Scintilla.NET.TestApp/FormMain.Designer.cs +++ b/Scintilla.NET.TestApp/FormMain.Designer.cs @@ -59,6 +59,7 @@ private void InitializeComponent() this.scintilla._ScintillaManagedDragDrop = true; this.scintilla.BorderStyle = ScintillaNET.BorderStyle.Fixed3DVisualStyles; this.scintilla.CaretLineBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(255))))); + this.scintilla.ChangeHistory = ((ScintillaNET.ChangeHistory)((ScintillaNET.ChangeHistory.Enabled | ScintillaNET.ChangeHistory.Markers))); this.scintilla.Dock = System.Windows.Forms.DockStyle.Fill; this.scintilla.FoldLineStripColor = System.Drawing.Color.Gray; this.scintilla.Font = new System.Drawing.Font("Consolas", 10.2F); @@ -68,6 +69,8 @@ private void InitializeComponent() this.scintilla.ScrollWidth = 1; this.scintilla.Size = new System.Drawing.Size(914, 426); this.scintilla.TabIndex = 2; + this.scintilla.SavePointLeft += new System.EventHandler(this.scintilla_SavePointLeft); + this.scintilla.SavePointReached += new System.EventHandler(this.scintilla_SavePointReached); this.scintilla.TextChanged += new System.EventHandler(this.scintilla_TextChanged); this.scintilla.KeyDown += new System.Windows.Forms.KeyEventHandler(this.scintilla_KeyDown); // @@ -188,6 +191,10 @@ private void InitializeComponent() this.lexersToolStripMenuItem.Size = new System.Drawing.Size(64, 24); this.lexersToolStripMenuItem.Text = "Lexers"; // + // saveFileDialog + // + this.saveFileDialog.Filter = "All Files|*.*"; + // // FormMain // this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); diff --git a/Scintilla.NET.TestApp/FormMain.cs b/Scintilla.NET.TestApp/FormMain.cs index fb8a774..d2cb6d6 100644 --- a/Scintilla.NET.TestApp/FormMain.cs +++ b/Scintilla.NET.TestApp/FormMain.cs @@ -10,14 +10,38 @@ namespace ScintillaNET.TestApp; public partial class FormMain : Form { + string baseTitle; + string? currentFileName = null; + + public string? CurrentFileName + { + get => this.currentFileName; + set + { + BaseTitle = Path.GetFileName(this.currentFileName = value); + } + } + + public string BaseTitle + { + get => this.baseTitle; + set + { + this.Text = (this.baseTitle = value) + (scintilla.Modified ? " *" : ""); + } + } + public FormMain() { InitializeComponent(); + baseTitle = this.Text; + scintilla.LexerName = "cpp"; SetScintillaStyles(scintilla); AdjustLineNumberMargin(scintilla); + AdjustMarkerMargin(scintilla); AdjustFoldMargin(scintilla); Version scintillaNetVersion = scintilla.GetType().Assembly.GetName().Version; @@ -119,6 +143,16 @@ private static void AdjustLineNumberMargin(Scintilla scintilla) maxLineNumberCharLengthMap[scintilla] = maxLineNumberCharLength; } + private static void AdjustMarkerMargin(Scintilla scintilla) + { + scintilla.Margins[1].Width = 16; + scintilla.Margins[1].Sensitive = false; + //scintilla.Markers[Marker.HistoryRevertedToModified].SetForeColor(Color.Orange); + //scintilla.Markers[Marker.HistoryRevertedToModified].SetBackColor(scintilla.Margins[1].BackColor); + //scintilla.Markers[Marker.HistoryRevertedToOrigin].SetForeColor(Color.Orange); + //scintilla.Markers[Marker.HistoryRevertedToOrigin].SetBackColor(scintilla.Margins[1].BackColor); + } + private static void AdjustFoldMargin(Scintilla scintilla) { // Instruct the lexer to calculate folding @@ -147,22 +181,28 @@ private static void AdjustFoldMargin(Scintilla scintilla) scintilla.Markers[Marker.FolderTail].Symbol = MarkerSymbol.LCorner; // Enable automatic folding - scintilla.AutomaticFold = (AutomaticFold.Show | AutomaticFold.Click | AutomaticFold.Change); + scintilla.AutomaticFold = AutomaticFold.Show | AutomaticFold.Click | AutomaticFold.Change; } private void openToolStripMenuItem_Click(object sender, EventArgs e) { if (openFileDialog.ShowDialog(this) == DialogResult.OK) { - scintilla.Text = File.ReadAllText(openFileDialog.FileName, Encoding.UTF8); + CurrentFileName = openFileDialog.FileName; + scintilla.Text = File.ReadAllText(CurrentFileName, Encoding.UTF8); + scintilla.ClearChangeHistory(); + scintilla.SetSavePoint(); } } private void saveToolStripMenuItem_Click(object sender, EventArgs e) { - if (saveFileDialog.ShowDialog(this) == DialogResult.OK) + if (CurrentFileName is null && saveFileDialog.ShowDialog(this) == DialogResult.OK) + CurrentFileName = saveFileDialog.FileName; + + if (CurrentFileName is not null) { - File.WriteAllText(saveFileDialog.FileName, scintilla.Text, Encoding.UTF8); + File.WriteAllText(CurrentFileName, scintilla.Text, Encoding.UTF8); scintilla.SetSavePoint(); } } @@ -195,4 +235,14 @@ private void scintilla_TextChanged(object sender, EventArgs e) { AdjustLineNumberMargin(scintilla); } + + private void scintilla_SavePointLeft(object sender, EventArgs e) + { + Text = BaseTitle + " *"; + } + + private void scintilla_SavePointReached(object sender, EventArgs e) + { + Text = BaseTitle; + } } diff --git a/Scintilla.NET.TestApp/Scintilla.NET.TestApp.csproj b/Scintilla.NET.TestApp/Scintilla.NET.TestApp.csproj index 6c8810d..08a1be7 100644 --- a/Scintilla.NET.TestApp/Scintilla.NET.TestApp.csproj +++ b/Scintilla.NET.TestApp/Scintilla.NET.TestApp.csproj @@ -13,6 +13,7 @@ AnyCPU app.manifest ScintillaNET.TestApp + enable From e5447080a45e7b5a01e5b67064d9b5b12b9402ea Mon Sep 17 00:00:00 2001 From: Ahmet Sait Date: Wed, 8 May 2024 10:46:16 +0300 Subject: [PATCH 8/8] Fix #94: Other TextBox carets jumping around --- Scintilla.NET/Scintilla.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Scintilla.NET/Scintilla.cs b/Scintilla.NET/Scintilla.cs index 2ae4c37..8cc827c 100644 --- a/Scintilla.NET/Scintilla.cs +++ b/Scintilla.NET/Scintilla.cs @@ -3358,7 +3358,11 @@ public bool UseRightToLeftReadingLayout exStyle &= ~WinApiHelpers.WS_EX_LAYOUTRTL; } Handle.SetWindowLongPtr(WinApiHelpers.GWL_EXSTYLE, new IntPtr(exStyle)); - DirectMessage(NativeMethods.SCI_GRABFOCUS, new IntPtr(1)); // needs focus to update + + // Workaround Scintilla mirrored rendering issue: + var wrapMode = WrapMode; + WrapMode = wrapMode == WrapMode.None ? WrapMode.Word : WrapMode.None; + WrapMode = wrapMode; } }