|
@@ -770,7 +770,7 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
public TextModel WrapModel (int width, out int nRow, out int nCol, out int nStartRow, out int nStartCol,
|
|
|
- int row = 0, int col = 0, int startRow = 0, int startCol = 0, int tabWidth = 0)
|
|
|
+ int row = 0, int col = 0, int startRow = 0, int startCol = 0, int tabWidth = 0, bool preserveTrailingSpaces = true)
|
|
|
{
|
|
|
frameWidth = width;
|
|
|
|
|
@@ -791,8 +791,7 @@ namespace Terminal.Gui {
|
|
|
for (int i = 0; i < Model.Count; i++) {
|
|
|
var line = Model.GetLine (i);
|
|
|
var wrappedLines = ToListRune (
|
|
|
- TextFormatter.Format (ustring.Make (line), width,
|
|
|
- TextAlignment.Left, true, true, tabWidth));
|
|
|
+ TextFormatter.Format (ustring.Make (line), width, TextAlignment.Left, true, preserveTrailingSpaces, tabWidth));
|
|
|
int sumColWidth = 0;
|
|
|
for (int j = 0; j < wrappedLines.Count; j++) {
|
|
|
var wrapLine = wrappedLines [j];
|
|
@@ -920,12 +919,13 @@ namespace Terminal.Gui {
|
|
|
var line = GetCurrentLine (modelRow);
|
|
|
var modelCol = GetModelColFromWrappedLines (row, col);
|
|
|
|
|
|
- if (modelCol >= line.Count) {
|
|
|
+ if (modelCol > line.Count) {
|
|
|
Model.RemoveLine (modelRow);
|
|
|
RemoveAt (row, 0);
|
|
|
return false;
|
|
|
}
|
|
|
- line.RemoveAt (modelCol);
|
|
|
+ if (modelCol < line.Count)
|
|
|
+ line.RemoveAt (modelCol);
|
|
|
if (line.Count > frameWidth || (row + 1 < wrappedModelLines.Count
|
|
|
&& wrappedModelLines [row + 1].ModelLine == modelRow)) {
|
|
|
return true;
|
|
@@ -997,13 +997,43 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
public void UpdateModel (TextModel model, out int nRow, out int nCol, out int nStartRow, out int nStartCol,
|
|
|
- int row, int col, int startRow, int startCol)
|
|
|
+ int row, int col, int startRow, int startCol, bool preserveTrailingSpaces)
|
|
|
{
|
|
|
isWrapModelRefreshing = true;
|
|
|
Model = model;
|
|
|
- WrapModel (frameWidth, out nRow, out nCol, out nStartRow, out nStartCol, row, col, startRow, startCol);
|
|
|
+ WrapModel (frameWidth, out nRow, out nCol, out nStartRow, out nStartCol, row, col, startRow, startCol, tabWidth: 0, preserveTrailingSpaces);
|
|
|
isWrapModelRefreshing = false;
|
|
|
}
|
|
|
+
|
|
|
+ public int GetWrappedLineColWidth (int line, int col, WordWrapManager wrapManager)
|
|
|
+ {
|
|
|
+ if (wrappedModelLines?.Count == 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ var wModelLines = wrapManager.wrappedModelLines;
|
|
|
+ var modelLine = GetModelLineFromWrappedLines (line);
|
|
|
+ var firstLine = wrappedModelLines.IndexOf (r => r.ModelLine == modelLine);
|
|
|
+ int modelCol = 0;
|
|
|
+ int colWidthOffset = 0;
|
|
|
+ int i = firstLine;
|
|
|
+
|
|
|
+ while (modelCol < col) {
|
|
|
+ var wLine = wrappedModelLines [i];
|
|
|
+ var wLineToCompare = wModelLines [i];
|
|
|
+
|
|
|
+ if (wLine.ModelLine != modelLine || wLineToCompare.ModelLine != modelLine)
|
|
|
+ break;
|
|
|
+
|
|
|
+ modelCol += Math.Max (wLine.ColWidth, wLineToCompare.ColWidth);
|
|
|
+ colWidthOffset += wLine.ColWidth - wLineToCompare.ColWidth;
|
|
|
+ if (modelCol > col) {
|
|
|
+ modelCol += col - modelCol;
|
|
|
+ }
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+ return modelCol - colWidthOffset;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
@@ -1462,7 +1492,7 @@ namespace Terminal.Gui {
|
|
|
model.LoadString (value);
|
|
|
if (wordWrap) {
|
|
|
wrapManager = new WordWrapManager (model);
|
|
|
- model = wrapManager.WrapModel (Math.Max (Frame.Width - 2, 0), out _, out _, out _, out _);
|
|
|
+ model = wrapManager.WrapModel (frameWidth, out _, out _, out _, out _);
|
|
|
}
|
|
|
TextChanged?.Invoke ();
|
|
|
SetNeedsDisplay ();
|
|
@@ -1484,12 +1514,12 @@ namespace Terminal.Gui {
|
|
|
void WrapTextModel ()
|
|
|
{
|
|
|
if (wordWrap && wrapManager != null) {
|
|
|
- model = wrapManager.WrapModel (Math.Max (Frame.Width - 2, 0),
|
|
|
+ model = wrapManager.WrapModel (frameWidth,
|
|
|
out int nRow, out int nCol,
|
|
|
out int nStartRow, out int nStartCol,
|
|
|
currentRow, currentColumn,
|
|
|
selectionStartRow, selectionStartColumn,
|
|
|
- tabWidth);
|
|
|
+ tabWidth, preserveTrailingSpaces: !ReadOnly);
|
|
|
currentRow = nRow;
|
|
|
currentColumn = nCol;
|
|
|
selectionStartRow = nStartRow;
|
|
@@ -1498,6 +1528,8 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ int frameWidth => Math.Max (Frame.Width - (RightOffset != 0 ? 2 : 1), 0);
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// Gets or sets the top row.
|
|
|
/// </summary>
|
|
@@ -1506,7 +1538,14 @@ namespace Terminal.Gui {
|
|
|
/// <summary>
|
|
|
/// Gets or sets the left column.
|
|
|
/// </summary>
|
|
|
- public int LeftColumn { get => leftColumn; set => leftColumn = Math.Max (Math.Min (value, Maxlength - 1), 0); }
|
|
|
+ public int LeftColumn {
|
|
|
+ get => leftColumn;
|
|
|
+ set {
|
|
|
+ if (value > 0 && wordWrap)
|
|
|
+ return;
|
|
|
+ leftColumn = Math.Max (Math.Min (value, Maxlength - 1), 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/// <summary>
|
|
|
/// Gets the maximum visible length line.
|
|
@@ -1571,7 +1610,10 @@ namespace Terminal.Gui {
|
|
|
}
|
|
|
|
|
|
SetWrapModel ();
|
|
|
+ var savedCurrentColumn = CurrentColumn;
|
|
|
+ currentColumn = GetCurrentColumnReadOnyWrapModel (true);
|
|
|
var sel = GetRegion ();
|
|
|
+ currentColumn = savedCurrentColumn;
|
|
|
UpdateWrapModel ();
|
|
|
Adjust ();
|
|
|
|
|
@@ -1607,7 +1649,7 @@ namespace Terminal.Gui {
|
|
|
ResetPosition ();
|
|
|
if (wordWrap) {
|
|
|
wrapManager = new WordWrapManager (model);
|
|
|
- model = wrapManager.WrapModel (Math.Max (Frame.Width - 2, 0), out _, out _, out _, out _);
|
|
|
+ model = wrapManager.WrapModel (frameWidth, out _, out _, out _, out _);
|
|
|
} else if (!wordWrap && wrapManager != null) {
|
|
|
model = wrapManager.Model;
|
|
|
}
|
|
@@ -1637,7 +1679,7 @@ namespace Terminal.Gui {
|
|
|
public int RightOffset {
|
|
|
get => rightOffset;
|
|
|
set {
|
|
|
- if (currentColumn == GetCurrentLine ().Count && rightOffset > 0 && value == 0) {
|
|
|
+ if (!wordWrap && currentColumn == GetCurrentLine ().Count && rightOffset > 0 && value == 0) {
|
|
|
leftColumn = Math.Max (leftColumn - rightOffset, 0);
|
|
|
}
|
|
|
rightOffset = value;
|
|
@@ -1794,9 +1836,18 @@ namespace Terminal.Gui {
|
|
|
/// <param name="path">Path to the file to load.</param>
|
|
|
public bool LoadFile (string path)
|
|
|
{
|
|
|
- var res = model.LoadFile (path);
|
|
|
- ResetPosition ();
|
|
|
- SetNeedsDisplay ();
|
|
|
+ bool res;
|
|
|
+ try {
|
|
|
+ SetWrapModel ();
|
|
|
+ res = model.LoadFile (path);
|
|
|
+ ResetPosition ();
|
|
|
+ } catch (Exception) {
|
|
|
+ throw;
|
|
|
+ } finally {
|
|
|
+ UpdateWrapModel ();
|
|
|
+ SetNeedsDisplay ();
|
|
|
+ Adjust ();
|
|
|
+ }
|
|
|
return res;
|
|
|
}
|
|
|
|
|
@@ -1939,8 +1990,15 @@ namespace Terminal.Gui {
|
|
|
public bool ReadOnly {
|
|
|
get => isReadOnly;
|
|
|
set {
|
|
|
- isReadOnly = value;
|
|
|
- SetNeedsDisplay ();
|
|
|
+ if (value != isReadOnly) {
|
|
|
+ isReadOnly = value;
|
|
|
+
|
|
|
+ SetWrapModel ();
|
|
|
+ currentColumn = GetCurrentColumnReadOnyWrapModel ();
|
|
|
+ UpdateWrapModel ();
|
|
|
+ SetNeedsDisplay ();
|
|
|
+ Adjust ();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2258,7 +2316,7 @@ namespace Terminal.Gui {
|
|
|
wrapManager.UpdateModel (model, out int nRow, out int nCol,
|
|
|
out int nStartRow, out int nStartCol,
|
|
|
currentRow, currentColumn,
|
|
|
- selectionStartRow, selectionStartColumn);
|
|
|
+ selectionStartRow, selectionStartColumn, preserveTrailingSpaces: !ReadOnly);
|
|
|
currentRow = nRow;
|
|
|
currentColumn = nCol;
|
|
|
selectionStartRow = nStartRow;
|
|
@@ -2269,6 +2327,21 @@ namespace Terminal.Gui {
|
|
|
throw new InvalidOperationException ($"WordWrap settings was changed after the {currentCaller} call.");
|
|
|
}
|
|
|
|
|
|
+ int GetCurrentColumnReadOnyWrapModel (bool forcePreserveTrailingSpaces = false)
|
|
|
+ {
|
|
|
+ if (wordWrap) {
|
|
|
+ var wManager = new WordWrapManager (wrapManager.Model);
|
|
|
+ if (ReadOnly && !forcePreserveTrailingSpaces) {
|
|
|
+ wManager.WrapModel (frameWidth, out _, out _, out _, out _, preserveTrailingSpaces: false);
|
|
|
+ } else {
|
|
|
+ wManager.WrapModel (frameWidth, out _, out _, out _, out _, preserveTrailingSpaces: true);
|
|
|
+ }
|
|
|
+ var currentLine = wrapManager.GetWrappedLineColWidth (CurrentRow, CurrentColumn, wManager);
|
|
|
+ return currentLine;
|
|
|
+ }
|
|
|
+ return currentColumn;
|
|
|
+ }
|
|
|
+
|
|
|
///<inheritdoc/>
|
|
|
public override void Redraw (Rect bounds)
|
|
|
{
|
|
@@ -2542,8 +2615,8 @@ namespace Terminal.Gui {
|
|
|
leftColumn = TextModel.CalculateLeftColumn (line, leftColumn, currentColumn,
|
|
|
Frame.Width + offB.width - RightOffset, TabWidth);
|
|
|
need = true;
|
|
|
- } else if (dSize.size + RightOffset < Frame.Width + offB.width
|
|
|
- && tSize.size + RightOffset < Frame.Width + offB.width) {
|
|
|
+ } else if ((wordWrap && leftColumn > 0) || (dSize.size + RightOffset < Frame.Width + offB.width
|
|
|
+ && tSize.size + RightOffset < Frame.Width + offB.width)) {
|
|
|
leftColumn = 0;
|
|
|
need = true;
|
|
|
}
|
|
@@ -2597,7 +2670,7 @@ namespace Terminal.Gui {
|
|
|
topRow = Math.Max (idx > model.Count - 1 ? model.Count - 1 : idx, 0);
|
|
|
} else if (!wordWrap) {
|
|
|
var maxlength = model.GetMaxVisibleLine (topRow, topRow + Frame.Height + RightOffset, TabWidth);
|
|
|
- leftColumn = Math.Max (idx > maxlength - 1 ? maxlength - 1 : idx, 0);
|
|
|
+ leftColumn = Math.Max (!wordWrap && idx > maxlength - 1 ? maxlength - 1 : idx, 0);
|
|
|
}
|
|
|
SetNeedsDisplay ();
|
|
|
}
|
|
@@ -3730,6 +3803,8 @@ namespace Terminal.Gui {
|
|
|
public void Copy ()
|
|
|
{
|
|
|
SetWrapModel ();
|
|
|
+ var savedCurrentColumn = CurrentColumn;
|
|
|
+ currentColumn = GetCurrentColumnReadOnyWrapModel (true);
|
|
|
if (selecting) {
|
|
|
SetClipboard (GetRegion ());
|
|
|
copyWithoutSelection = false;
|
|
@@ -3738,6 +3813,7 @@ namespace Terminal.Gui {
|
|
|
SetClipboard (ustring.Make (currentLine));
|
|
|
copyWithoutSelection = true;
|
|
|
}
|
|
|
+ currentColumn = savedCurrentColumn;
|
|
|
UpdateWrapModel ();
|
|
|
DoNeededAction ();
|
|
|
}
|
|
@@ -4292,7 +4368,7 @@ namespace Terminal.Gui {
|
|
|
/// </summary>
|
|
|
public void ClearHistoryChanges ()
|
|
|
{
|
|
|
- historyText.Clear (Text);
|
|
|
+ historyText?.Clear (Text);
|
|
|
}
|
|
|
}
|
|
|
|