SF.net SVN: geany:[4723] trunk
eht16 at users.sourceforge.net
eht16 at xxxxx
Sun Mar 7 10:31:52 UTC 2010
Revision: 4723
http://geany.svn.sourceforge.net/geany/?rev=4723&view=rev
Author: eht16
Date: 2010-03-07 10:31:51 +0000 (Sun, 07 Mar 2010)
Log Message:
-----------
Update Scintilla to version 2.03.
Modified Paths:
--------------
trunk/scintilla/AutoComplete.cxx
trunk/scintilla/CallTip.cxx
trunk/scintilla/CallTip.h
trunk/scintilla/CellBuffer.cxx
trunk/scintilla/CharClassify.cxx
trunk/scintilla/CharClassify.h
trunk/scintilla/Document.cxx
trunk/scintilla/Document.h
trunk/scintilla/DocumentAccessor.h
trunk/scintilla/Editor.cxx
trunk/scintilla/Editor.h
trunk/scintilla/ExternalLexer.cxx
trunk/scintilla/ExternalLexer.h
trunk/scintilla/KeyWords.cxx
trunk/scintilla/LexAda.cxx
trunk/scintilla/LexCaml.cxx
trunk/scintilla/LexCmake.cxx
trunk/scintilla/LexHTML.cxx
trunk/scintilla/LexHaskell.cxx
trunk/scintilla/LexNsis.cxx
trunk/scintilla/LexOthers.cxx
trunk/scintilla/LexPython.cxx
trunk/scintilla/LexSQL.cxx
trunk/scintilla/Makefile.am
trunk/scintilla/PerLine.cxx
trunk/scintilla/PlatGTK.cxx
trunk/scintilla/PositionCache.cxx
trunk/scintilla/PositionCache.h
trunk/scintilla/PropSet.cxx
trunk/scintilla/RESearch.cxx
trunk/scintilla/SVector.h
trunk/scintilla/ScintillaBase.cxx
trunk/scintilla/ScintillaBase.h
trunk/scintilla/ScintillaGTK.cxx
trunk/scintilla/Style.cxx
trunk/scintilla/Style.h
trunk/scintilla/StyleContext.h
trunk/scintilla/ViewStyle.cxx
trunk/scintilla/ViewStyle.h
trunk/scintilla/include/KeyWords.h
trunk/scintilla/include/Platform.h
trunk/scintilla/include/PropSet.h
trunk/scintilla/include/SciLexer.h
trunk/scintilla/include/Scintilla.h
trunk/scintilla/include/Scintilla.iface
trunk/scintilla/include/WindowAccessor.h
trunk/scintilla/makefile.win32
trunk/scintilla/scintilla_changes.patch
trunk/wscript
Added Paths:
-----------
trunk/scintilla/PropSetSimple.h
trunk/scintilla/Selection.cxx
trunk/scintilla/Selection.h
Modified: trunk/scintilla/AutoComplete.cxx
===================================================================
--- trunk/scintilla/AutoComplete.cxx 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/AutoComplete.cxx 2010-03-07 10:31:51 UTC (rev 4723)
@@ -11,7 +11,7 @@
#include "Platform.h"
-#include "PropSet.h"
+#include "CharClassify.h"
#include "AutoComplete.h"
#ifdef SCI_NAMESPACE
Modified: trunk/scintilla/CallTip.cxx
===================================================================
--- trunk/scintilla/CallTip.cxx 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/CallTip.cxx 2010-03-07 10:31:51 UTC (rev 4723)
@@ -254,11 +254,9 @@
const char *faceName, int size,
int codePage_, int characterSet, Window &wParent) {
clickPlace = 0;
- if (val)
- delete []val;
+ delete []val;
+ val = 0;
val = new char[strlen(defn) + 1];
- if (!val)
- return PRectangle();
strcpy(val, defn);
codePage = codePage_;
Surface *surfaceMeasure = Surface::Allocate();
Modified: trunk/scintilla/CallTip.h
===================================================================
--- trunk/scintilla/CallTip.h 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/CallTip.h 2010-03-07 10:31:51 UTC (rev 4723)
@@ -27,8 +27,8 @@
bool useStyleCallTip; // if true, STYLE_CALLTIP should be used
// Private so CallTip objects can not be copied
- CallTip(const CallTip &) {}
- CallTip &operator=(const CallTip &) { return *this; }
+ CallTip(const CallTip &);
+ CallTip &operator=(const CallTip &);
void DrawChunk(Surface *surface, int &x, const char *s,
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw);
Modified: trunk/scintilla/CellBuffer.cxx
===================================================================
--- trunk/scintilla/CellBuffer.cxx 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/CellBuffer.cxx 2010-03-07 10:31:51 UTC (rev 4723)
@@ -71,6 +71,7 @@
position = 0;
data = 0;
lenData = 0;
+ mayCoalesce = false;
}
Action::~Action() {
@@ -150,8 +151,6 @@
// Run out of undo nodes so extend the array
int lenActionsNew = lenActions * 2;
Action *actionsNew = new Action[lenActionsNew];
- if (!actionsNew)
- return;
for (int act = 0; act <= currentAction; act++)
actionsNew[act].Grab(&actions[act]);
delete []actions;
Modified: trunk/scintilla/CharClassify.cxx
===================================================================
--- trunk/scintilla/CharClassify.cxx 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/CharClassify.cxx 2010-03-07 10:31:51 UTC (rev 4723)
@@ -5,6 +5,7 @@
// Copyright 2006 by Neil Hodgson <neilh at scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
+#include <stdlib.h>
#include <ctype.h>
#include "CharClassify.h"
@@ -41,3 +42,37 @@
}
}
}
+
+int CompareCaseInsensitive(const char *a, const char *b) {
+ while (*a && *b) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ }
+ // Either *a or *b is nul
+ return *a - *b;
+}
+
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
+ while (*a && *b && len) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ len--;
+ }
+ if (len == 0)
+ return 0;
+ else
+ // Either *a or *b is nul
+ return *a - *b;
+}
Modified: trunk/scintilla/CharClassify.h
===================================================================
--- trunk/scintilla/CharClassify.h 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/CharClassify.h 2010-03-07 10:31:51 UTC (rev 4723)
@@ -2,7 +2,7 @@
/** @file CharClassify.h
** Character classifications used by Document and RESearch.
**/
-// Copyright 2006 by Neil Hodgson <neilh at scintilla.org>
+// Copyright 2006-2009 by Neil Hodgson <neilh at scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef CHARCLASSIFY_H
@@ -22,4 +22,16 @@
enum { maxChar=256 };
unsigned char charClass[maxChar]; // not type cc to save space
};
+
+// These functions are implemented because each platform calls them something different.
+int CompareCaseInsensitive(const char *a, const char *b);
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
+
+inline char MakeUpperCase(char ch) {
+ if (ch < 'a' || ch > 'z')
+ return ch;
+ else
+ return static_cast<char>(ch - 'a' + 'A');
+}
+
#endif
Modified: trunk/scintilla/Document.cxx
===================================================================
--- trunk/scintilla/Document.cxx 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/Document.cxx 2010-03-07 10:31:51 UTC (rev 4723)
@@ -217,6 +217,10 @@
return LineEnd(LineFromPosition(position));
}
+bool Document::IsLineEndPosition(int position) const {
+ return LineEnd(LineFromPosition(position)) == position;
+}
+
int Document::VCHomePosition(int position) const {
int line = LineFromPosition(position);
int startPosition = LineStart(line);
@@ -757,10 +761,9 @@
CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
- BeginUndoAction();
+ UndoGroup ug(this);
DeleteChars(thisLineStart, indentPos - thisLineStart);
InsertCString(thisLineStart, linebuf);
- EndUndoAction();
}
}
@@ -801,8 +804,8 @@
int Document::FindColumn(int line, int column) {
int position = LineStart(line);
- int columnCurrent = 0;
if ((line >= 0) && (line < LinesTotal())) {
+ int columnCurrent = 0;
while ((columnCurrent < column) && (position < Length())) {
char ch = cb.CharAt(position);
if (ch == '\t') {
@@ -867,7 +870,7 @@
}
void Document::ConvertLineEnds(int eolModeSet) {
- BeginUndoAction();
+ UndoGroup ug(this);
for (int pos = 0; pos < Length(); pos++) {
if (cb.CharAt(pos) == '\r') {
@@ -902,7 +905,6 @@
}
}
- EndUndoAction();
}
bool Document::IsWhiteLine(int line) const {
@@ -1065,16 +1067,6 @@
return IsWordStartAt(start) && IsWordEndAt(end);
}
-// The comparison and case changing functions here assume ASCII
-// or extended ASCII such as the normal Windows code page.
-
-static inline char MakeUpperCase(char ch) {
- if (ch < 'a' || ch > 'z')
- return ch;
- else
- return static_cast<char>(ch - 'a' + 'A');
-}
-
static inline char MakeLowerCase(char ch) {
if (ch < 'A' || ch > 'Z')
return ch;
@@ -1374,8 +1366,6 @@
return false;
}
WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers + 1];
- if (!pwNew)
- return false;
for (int j = 0; j < lenWatchers; j++)
pwNew[j] = watchers[j];
pwNew[lenWatchers].watcher = watcher;
@@ -1396,8 +1386,6 @@
lenWatchers = 0;
} else {
WatcherWithUserData *pwNew = new WatcherWithUserData[lenWatchers];
- if (!pwNew)
- return false;
for (int j = 0; j < lenWatchers - 1; j++) {
pwNew[j] = (j < i) ? watchers[j] : watchers[j + 1];
}
@@ -1758,8 +1746,6 @@
}
}
substituted = new char[lenResult + 1];
- if (!substituted)
- return 0;
char *o = substituted;
for (int j = 0; j < *length; j++) {
if (text[j] == '\\') {
Modified: trunk/scintilla/Document.h
===================================================================
--- trunk/scintilla/Document.h 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/Document.h 2010-03-07 10:31:51 UTC (rev 4723)
@@ -239,6 +239,7 @@
int LineStart(int line) const;
int LineEnd(int line) const;
int LineEndPosition(int position) const;
+ bool IsLineEndPosition(int position) const;
int VCHomePosition(int position) const;
int SetLevel(int line, int level);
@@ -319,6 +320,27 @@
void NotifyModified(DocModification mh);
};
+class UndoGroup {
+ Document *pdoc;
+ bool groupNeeded;
+public:
+ UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
+ pdoc(pdoc_), groupNeeded(groupNeeded_) {
+ if (groupNeeded) {
+ pdoc->BeginUndoAction();
+ }
+ }
+ ~UndoGroup() {
+ if (groupNeeded) {
+ pdoc->EndUndoAction();
+ }
+ }
+ bool Needed() const {
+ return groupNeeded;
+ }
+};
+
+
/**
* To optimise processing of document modifications by DocWatchers, a hint is passed indicating the
* scope of the change.
Modified: trunk/scintilla/DocumentAccessor.h
===================================================================
--- trunk/scintilla/DocumentAccessor.h 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/DocumentAccessor.h 2010-03-07 10:31:51 UTC (rev 4723)
@@ -14,14 +14,15 @@
/**
*/
+
class DocumentAccessor : public Accessor {
// Private so DocumentAccessor objects can not be copied
- DocumentAccessor(const DocumentAccessor &source) : Accessor(), props(source.props) {}
- DocumentAccessor &operator=(const DocumentAccessor &) { return *this; }
+ DocumentAccessor(const DocumentAccessor &source);
+ DocumentAccessor &operator=(const DocumentAccessor &);
protected:
Document *pdoc;
- PropSet &props;
+ PropertyGet &props;
WindowID id;
int lenDoc;
@@ -37,7 +38,7 @@
void Fill(int position);
public:
- DocumentAccessor(Document *pdoc_, PropSet &props_, WindowID id_=0) :
+ DocumentAccessor(Document *pdoc_, PropertyGet &props_, WindowID id_=0) :
Accessor(), pdoc(pdoc_), props(props_), id(id_),
lenDoc(-1), validLen(0), chFlags(0), chWhile(0),
startSeg(0), startPosStyling(0),
Modified: trunk/scintilla/Editor.cxx
===================================================================
--- trunk/scintilla/Editor.cxx 2010-03-05 18:07:41 UTC (rev 4722)
+++ trunk/scintilla/Editor.cxx 2010-03-07 10:31:51 UTC (rev 4723)
@@ -10,6 +10,18 @@
#include <stdio.h>
#include <ctype.h>
+#include <string>
+#include <vector>
+#include <algorithm>
+
+// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
+// FindText to FindTextA which makes calls here to Document::FindText fail.
+#ifdef __BORLANDC__
+#ifdef FindText
+#undef FindText
+#endif
+#endif
+
#include "Platform.h"
#include "Scintilla.h"
@@ -28,6 +40,7 @@
#include "CharClassify.h"
#include "Decoration.h"
#include "Document.h"
+#include "Selection.h"
#include "PositionCache.h"
#include "Editor.h"
@@ -108,18 +121,14 @@
ptMouseLast.y = 0;
inDragDrop = ddNone;
dropWentOutside = false;
- posDrag = invalidPosition;
- posDrop = invalidPosition;
+ posDrag = SelectionPosition(invalidPosition);
+ posDrop = SelectionPosition(invalidPosition);
selectionType = selChar;
lastXChosen = 0;
lineAnchor = 0;
originalAnchorPos = 0;
- selType = selStream;
- moveExtendsSelection = false;
- xStartSelect = 0;
- xEndSelect = 0;
primarySelection = true;
caretXPolicy = CARET_SLOP | CARET_EVEN;
@@ -139,6 +148,11 @@
verticalScrollBarVisible = true;
endAtLastLine = true;
caretSticky = false;
+ multipleSelection = false;
+ additionalSelectionTyping = false;
+ additionalCaretsBlink = true;
+ additionalCaretsVisible = true;
+ virtualSpaceOptions = SCVS_NONE;
pixmapLine = Surface::Allocate();
pixmapSelMargin = Surface::Allocate();
@@ -146,9 +160,6 @@
pixmapIndentGuide = Surface::Allocate();
pixmapIndentGuideHighlight = Surface::Allocate();
- currentPos = 0;
- anchor = 0;
-
targetStart = 0;
targetEnd = 0;
searchFlags = 0;
@@ -227,10 +238,6 @@
palette.Release();
llc.Invalidate(LineLayout::llInvalid);
posCache.Clear();
- if (selType == selRectangle) {
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
- }
}
void Editor::InvalidateStyleRedraw() {
@@ -263,6 +270,7 @@
wrapAddIndent = vs.aveCharWidth; // must indent to show start visual
}
SetScrollBars();
+ SetRectangularRange();
}
}
@@ -328,7 +336,7 @@
class AutoLineLayout {
LineLayoutCache &llc;
LineLayout *ll;
- AutoLineLayout &operator=(const AutoLineLayout &) { return * this; }
+ AutoLineLayout &operator=(const AutoLineLayout &);
public:
AutoLineLayout(LineLayoutCache &llc_, LineLayout *ll_) : llc(llc_), ll(ll_) {}
~AutoLineLayout() {
@@ -347,98 +355,25 @@
}
};
-#ifdef SCI_NAMESPACE
-namespace Scintilla {
-#endif
-
-/**
- * Allows to iterate through the lines of a selection.
- * Althought it can be called for a stream selection, in most cases
- * it is inefficient and it should be used only for
- * a rectangular or a line selection.
- */
-class SelectionLineIterator {
-private:
- Editor *ed;
- int line; ///< Current line within the iteration.
- bool forward; ///< True if iterating by increasing line number, false otherwise.
- int selStart, selEnd; ///< Positions of the start and end of the selection relative to the start of the document.
- int minX, maxX; ///< Left and right of selection rectangle.
-
-public:
- int lineStart, lineEnd; ///< Line numbers, first and last lines of the selection.
- int startPos, endPos; ///< Positions of the beginning and end of the selection on the current line.
-
- void Reset() {
- if (forward) {
- line = lineStart;
- } else {
- line = lineEnd;
- }
+SelectionPosition Editor::ClampPositionIntoDocument(SelectionPosition sp) const {
+ if (sp.Position() < 0) {
+ return SelectionPosition(0);
+ } else if (sp.Position() > pdoc->Length()) {
+ return SelectionPosition(pdoc->Length());
+ } else {
+ // If not at end of line then set offset to 0
+ if (!pdoc->IsLineEndPosition(sp.Position()))
+ sp.SetVirtualSpace(0);
+ return sp;
}
-
- SelectionLineIterator(Editor *ed_, bool forward_ = true) : line(0), startPos(0), endPos(0) {
- ed = ed_;
- forward = forward_;
- selStart = ed->SelectionStart();
- selEnd = ed->SelectionEnd();
- lineStart = ed->pdoc->LineFromPosition(selStart);
- lineEnd = ed->pdoc->LineFromPosition(selEnd);
- // Left of rectangle
- minX = Platform::Minimum(ed->xStartSelect, ed->xEndSelect);
- // Right of rectangle
- maxX = Platform::Maximum(ed->xStartSelect, ed->xEndSelect);
- Reset();
- }
- ~SelectionLineIterator() {}
-
- void SetAt(int line) {
- if (line < lineStart || line > lineEnd) {
- startPos = endPos = INVALID_POSITION;
- } else {
- if (ed->selType == ed->selRectangle) {
- // Measure line and return character closest to minX
- startPos = ed->PositionFromLineX(line, minX);
- // Measure line and return character closest to maxX
- endPos = ed->PositionFromLineX(line, maxX);
- } else if (ed->selType == ed->selLines) {
- startPos = ed->pdoc->LineStart(line);
- endPos = ed->pdoc->LineStart(line + 1);
- } else { // Stream selection, here only for completion
- if (line == lineStart) {
- startPos = selStart;
- } else {
- startPos = ed->pdoc->LineStart(line);
- }
- if (line == lineEnd) {
- endPos = selEnd;
- } else {
- endPos = ed->pdoc->LineStart(line + 1);
- }
- }
- }
- }
- bool Iterate() {
- SetAt(line);
- if (forward) {
- line++;
- } else {
- line--;
- }
- return startPos != INVALID_POSITION;
- }
-};
-
-#ifdef SCI_NAMESPACE
}
-#endif
-Point Editor::LocationFromPosition(int pos) {
+Point Editor::LocationFromPosition(SelectionPosition pos) {
Point pt;
RefreshStyleData();
- if (pos == INVALID_POSITION)
+ if (pos.Position() == INVALID_POSITION)
return pt;
- int line = pdoc->LineFromPosition(pos);
+ int line = pdoc->LineFromPosition(pos.Position());
int lineVisible = cs.DisplayFromDoc(line);
//Platform::DebugPrintf("line=%d\n", line);
AutoSurface surface(this);
@@ -449,7 +384,7 @@
pt.x = 0;
unsigned int posLineStart = pdoc->LineStart(line);
LayoutLine(line, surface, vs, ll, wrapWidth);
- int posInLine = pos - posLineStart;
+ int posInLine = pos.Position() - posLineStart;
// In case of very long line put x at arbitrary large position
if (posInLine > ll->maxLineLength) {
pt.x = ll->positions[ll->maxLineLength] - ll->positions[ll->LineStart(ll->lines)];
@@ -470,14 +405,24 @@
}
pt.x += vs.fixedColumnWidth - xOffset;
}
+ pt.x += pos.VirtualSpace() * static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
return pt;
}
+Point Editor::LocationFromPosition(int pos) {
+ return LocationFromPosition(SelectionPosition(pos));
+}
+
int Editor::XFromPosition(int pos) {
Point pt = LocationFromPosition(pos);
return pt.x - vs.fixedColumnWidth + xOffset;
}
+int Editor::XFromPosition(SelectionPosition sp) {
+ Point pt = LocationFromPosition(sp);
+ return pt.x - vs.fixedColumnWidth + xOffset;
+}
+
int Editor::LineFromLocation(Point pt) {
return cs.DocFromDisplay(pt.y / vs.lineHeight + topLine);
}
@@ -487,16 +432,16 @@
posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
}
-int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) {
+SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition, bool virtualSpace) {
RefreshStyleData();
if (canReturnInvalid) {
PRectangle rcClient = GetTextRectangle();
if (!rcClient.Contains(pt))
- return INVALID_POSITION;
+ return SelectionPosition(INVALID_POSITION);
if (pt.x < vs.fixedColumnWidth)
- return INVALID_POSITION;
+ return SelectionPosition(INVALID_POSITION);
if (pt.y < 0)
- return INVALID_POSITION;
+ return SelectionPosition(INVALID_POSITION);
}
pt.x = pt.x - vs.fixedColumnWidth + xOffset;
int visibleLine = pt.y / vs.lineHeight + topLine;
@@ -507,11 +452,11 @@
visibleLine = 0;
int lineDoc = cs.DocFromDisplay(visibleLine);
if (canReturnInvalid && (lineDoc < 0))
- return INVALID_POSITION;
+ return SelectionPosition(INVALID_POSITION);
if (lineDoc >= pdoc->LinesTotal())
- return canReturnInvalid ? INVALID_POSITION : pdoc->Length();
+ return SelectionPosition(canReturnInvalid ? INVALID_POSITION : pdoc->Length());
unsigned int posLineStart = pdoc->LineStart(lineDoc);
- int retVal = canReturnInvalid ? INVALID_POSITION : static_cast<int>(posLineStart);
+ SelectionPosition retVal(canReturnInvalid ? INVALID_POSITION : static_cast<int>(posLineStart));
AutoSurface surface(this);
AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
if (surface && ll) {
@@ -531,29 +476,38 @@
while (i < lineEnd) {
if (charPosition) {
if ((pt.x + subLineStart) < (ll->positions[i + 1])) {
- return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+ return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
}
} else {
if ((pt.x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
- return pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+ return SelectionPosition(pdoc->MovePositionOutsideChar(i + posLineStart, 1));
}
}
i++;
}
- if (canReturnInvalid) {
+ if (virtualSpace) {
+ const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+ int spaceOffset = (pt.x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) /
+ spaceWidth;
+ return SelectionPosition(lineEnd + posLineStart, spaceOffset);
+ } else if (canReturnInvalid) {
if (pt.x < (ll->positions[lineEnd] - subLineStart)) {
- return pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1);
+ return SelectionPosition(pdoc->MovePositionOutsideChar(lineEnd + posLineStart, 1));
}
} else {
- return lineEnd + posLineStart;
+ return SelectionPosition(lineEnd + posLineStart);
}
}
if (!canReturnInvalid)
- return ll->numCharsInLine + posLineStart;
+ return SelectionPosition(ll->numCharsInLine + posLineStart);
}
return retVal;
}
+int Editor::PositionFromLocation(Point pt, bool canReturnInvalid, bool charPosition) {
+ return SPositionFromLocation(pt, canReturnInvalid, charPosition, false).Position();
+}
+
/**
* Find the document position corresponding to an x coordinate on a particular document line.
* Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
@@ -569,7 +523,7 @@
if (surface && ll) {
unsigned int posLineStart = pdoc->LineStart(lineDoc);
LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
- retVal = ll->numCharsInLine + posLineStart;
+ retVal = ll->numCharsBeforeEOL + posLineStart;
int subLine = 0;
int lineStart = ll->LineStart(subLine);
int lineEnd = ll->LineLastVisible(subLine);
@@ -592,6 +546,45 @@
}
/**
+ * Find the document position corresponding to an x coordinate on a particular document line.
+ * Ensure is between whole characters when document is in multi-byte or UTF-8 mode.
+ */
+SelectionPosition Editor::SPositionFromLineX(int lineDoc, int x) {
+ RefreshStyleData();
+ if (lineDoc >= pdoc->LinesTotal())
+ return SelectionPosition(pdoc->Length());
+ //Platform::DebugPrintf("Position of (%d,%d) line = %d top=%d\n", pt.x, pt.y, line, topLine);
+ AutoSurface surface(this);
+ AutoLineLayout ll(llc, RetrieveLineLayout(lineDoc));
+ int retVal = 0;
+ if (surface && ll) {
+ unsigned int posLineStart = pdoc->LineStart(lineDoc);
+ LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
+ int subLine = 0;
+ int lineStart = ll->LineStart(subLine);
+ int lineEnd = ll->LineLastVisible(subLine);
+ int subLineStart = ll->positions[lineStart];
+
+ if (ll->wrapIndent != 0) {
+ if (lineStart != 0) // Wrapped
+ x -= ll->wrapIndent;
+ }
+ int i = ll->FindBefore(x + subLineStart, lineStart, lineEnd);
+ while (i < lineEnd) {
+ if ((x + subLineStart) < ((ll->positions[i] + ll->positions[i + 1]) / 2)) {
+ retVal = pdoc->MovePositionOutsideChar(i + posLineStart, 1);
+ return SelectionPosition(retVal);
+ }
+ i++;
+ }
+ const int spaceWidth = static_cast<int>(vs.styles[ll->EndLineStyle()].spaceWidth);
+ int spaceOffset = (x + subLineStart - ll->positions[lineEnd] + spaceWidth / 2) / spaceWidth;
+ return SelectionPosition(lineEnd + posLineStart, spaceOffset);
+ }
+ return SelectionPosition(retVal);
+}
+
+/**
* If painting then abandon the painting because a wider redraw is needed.
* @return true if calling code should stop drawing.
*/
@@ -676,80 +669,125 @@
}
int Editor::CurrentPosition() {
- return currentPos;
+ return sel.MainCaret();
}
bool Editor::SelectionEmpty() {
- return anchor == currentPos;
+ return sel.Empty();
}
-int Editor::SelectionStart() {
- return Platform::Minimum(currentPos, anchor);
+SelectionPosition Editor::SelectionStart() {
+ return sel.RangeMain().Start();
}
-int Editor::SelectionEnd() {
- return Platform::Maximum(currentPos, anchor);
+SelectionPosition Editor::SelectionEnd() {
+ return sel.RangeMain().End();
}
void Editor::SetRectangularRange() {
- if (selType == selRectangle) {
- xStartSelect = XFromPosition(anchor);
- xEndSelect = XFromPosition(currentPos);
+ if (sel.IsRectangular()) {
+ int xAnchor = XFromPosition(sel.Rectangular().anchor);
+ int xCaret = XFromPosition(sel.Rectangular().caret);
+ if (sel.selType == Selection::selThin) {
+ xCaret = xAnchor;
+ }
+ int lineAnchor = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
+ int lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position());
+ int increment = (lineCaret > lineAnchor) ? 1 : -1;
+ for (int line=lineAnchor; line != lineCaret+increment; line += increment) {
+ SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
+ if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
+ range.ClearVirtualSpace();
+ if (line == lineAnchor)
+ sel.SetSelection(range);
+ else
+ sel.AddSelection(range);
+ }
}
}
-void Editor::InvalidateSelection(int currentPos_, int anchor_, bool invalidateWholeSelection) {
- if (anchor != anchor_ || selType == selRectangle) {
+void Editor::ThinRectangularRange() {
+ if (sel.IsRectangular()) {
+ sel.selType = Selection::selThin;
+ if (sel.Rectangular().caret < sel.Rectangular().anchor) {
+ sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).caret, sel.Range(0).anchor);
+ } else {
+ sel.Rectangular() = SelectionRange(sel.Range(sel.Count()-1).anchor, sel.Range(0).caret);
+ }
+ SetRectangularRange();
+ }
+}
+
+void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSelection) {
+ if (sel.Count() > 1 || !(sel.RangeMain().anchor == newMain.anchor) || sel.IsRectangular()) {
invalidateWholeSelection = true;
}
- int firstAffected = currentPos;
+ int firstAffected = Platform::Minimum(sel.RangeMain().Start().Position(), newMain.Start().Position());
+ // +1 for lastAffected ensures caret repainted
+ int lastAffected = Platform::Maximum(newMain.caret.Position()+1, newMain.anchor.Position());
+ lastAffected = Platform::Maximum(lastAffected, sel.RangeMain().End().Position());
if (invalidateWholeSelection) {
- if (firstAffected > anchor)
- firstAffected = anchor;
- if (firstAffected > anchor_)
- firstAffected = anchor_;
+ for (size_t r=0; r<sel.Count(); r++) {
+ firstAffected = Platform::Minimum(firstAffected, sel.Range(r).caret.Position());
+ firstAffected = Platform::Minimum(firstAffected, sel.Range(r).anchor.Position());
+ lastAffected = Platform::Maximum(lastAffected, sel.Range(r).caret.Position()+1);
+ lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
+ }
}
- if (firstAffected > currentPos_)
- firstAffected = currentPos_;
- int lastAffected = currentPos;
- if (invalidateWholeSelection) {
- if (lastAffected < anchor)
- lastAffected = anchor;
- if (lastAffected < anchor_)
- lastAffected = anchor_;
- }
- if (lastAffected < (currentPos_ + 1)) // +1 ensures caret repainted
- lastAffected = (currentPos_ + 1);
needUpdateUI = true;
InvalidateRange(firstAffected, lastAffected);
}
-void Editor::SetSelection(int currentPos_, int anchor_) {
- currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);
- anchor_ = pdoc->ClampPositionIntoDocument(anchor_);
- if ((currentPos != currentPos_) || (anchor != anchor_)) {
- InvalidateSelection(currentPos_, anchor_, true);
- currentPos = currentPos_;
- anchor = anchor_;
+void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) {
+ SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_),
+ ClampPositionIntoDocument(anchor_));
+ if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
+ InvalidateSelection(rangeNew);
}
+ sel.RangeMain() = rangeNew;
SetRectangularRange();
ClaimSelection();
}
+void Editor::SetSelection(int currentPos_, int anchor_) {
+ SetSelection(SelectionPosition(currentPos_), SelectionPosition(anchor_));
+}
+
+// Just move the caret on the main selection
+void Editor::SetSelection(SelectionPosition currentPos_) {
+ currentPos_ = ClampPositionIntoDocument(currentPos_);
+ if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) {
+ InvalidateSelection(SelectionRange(currentPos_));
+ }
+ if (sel.IsRectangular()) {
+ sel.Rectangular() =
+ SelectionRange(SelectionPosition(currentPos_), sel.Rectangular().anchor);
+ SetRectangularRange();
+ } else {
+ sel.RangeMain() =
+ SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor);
+ }
+ ClaimSelection();
+}
+
void Editor::SetSelection(int currentPos_) {
- currentPos_ = pdoc->ClampPositionIntoDocument(currentPos_);
- if (currentPos != currentPos_) {
- InvalidateSelection(currentPos_, anchor, false);
- currentPos = currentPos_;
+ SetSelection(SelectionPosition(currentPos_));
+}
+
+void Editor::SetEmptySelection(SelectionPosition currentPos_) {
+ SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_));
+ if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
+ InvalidateSelection(rangeNew);
}
+ sel.Clear();
+ sel.RangeMain() = rangeNew;
SetRectangularRange();
ClaimSelection();
+
}
void Editor::SetEmptySelection(int currentPos_) {
- selType = selStream;
- moveExtendsSelection = false;
- SetSelection(currentPos_, currentPos_);
+ SetEmptySelection(SelectionPosition(currentPos_));
}
bool Editor::RangeContainsProtected(int start, int end) const {
@@ -769,54 +807,59 @@
}
bool Editor::SelectionContainsProtected() {
- // DONE, but untested...: make support rectangular selection
- bool scp = false;
- if (selType == selStream) {
- scp = RangeContainsProtected(anchor, currentPos);
- } else {
- SelectionLineIterator lineIterator(this);
- while (lineIterator.Iterate()) {
- if (RangeContainsProtected(lineIterator.startPos, lineIterator.endPos)) {
- scp = true;
- break;
- }
+ for (size_t r=0; r<sel.Count(); r++) {
+ if (RangeContainsProtected(sel.Range(r).Start().Position(),
+ sel.Range(r).End().Position())) {
+ return true;
}
}
- return scp;
+ return false;
}
/**
* Asks document to find a good position and then moves out of any invisible positions.
*/
int Editor::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) const {
- pos = pdoc->MovePositionOutsideChar(pos, moveDir, checkLineEnd);
+ return MovePositionOutsideChar(SelectionPosition(pos), moveDir, checkLineEnd).Position();
+}
+
+SelectionPosition Editor::MovePositionOutsideChar(SelectionPosition pos, int moveDir, bool checkLineEnd) const {
+ int posMoved = pdoc->MovePositionOutsideChar(pos.Position(), moveDir, checkLineEnd);
+ if (posMoved != pos.Position())
+ pos.SetPosition(posMoved);
if (vs.ProtectionActive()) {
int mask = pdoc->stylingBitsMask;
if (moveDir > 0) {
- if ((pos > 0) && vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()) {
- while ((pos < pdoc->Length()) &&
- (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()))
- pos++;
+ if ((pos.Position() > 0) && vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected()) {
+ while ((pos.Position() < pdoc->Length()) &&
+ (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected()))
+ pos.Add(1);
}
} else if (moveDir < 0) {
- if (vs.styles[pdoc->StyleAt(pos) & mask].IsProtected()) {
- while ((pos > 0) &&
- (vs.styles[pdoc->StyleAt(pos - 1) & mask].IsProtected()))
- pos--;
+ if (vs.styles[pdoc->StyleAt(pos.Position()) & mask].IsProtected()) {
+ while ((pos.Position() > 0) &&
+ (vs.styles[pdoc->StyleAt(pos.Position() - 1) & mask].IsProtected()))
+ pos.Add(-1);
}
}
}
return pos;
}
-int Editor::MovePositionTo(int newPos, selTypes sel, bool ensureVisible) {
- int delta = newPos - currentPos;
- newPos = pdoc->ClampPositionIntoDocument(newPos);
+int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) {
+ int delta = newPos.Position() - sel.MainCaret();
+ newPos = ClampPositionIntoDocument(newPos);
newPos = MovePositionOutsideChar(newPos, delta);
- if (sel != noSel) {
- selType = sel;
+ if (!sel.IsRectangular() && (selt == Selection::selRectangle)) {
+ // Switching to rectangular
+ SelectionRange rangeMain = sel.RangeMain();
+ sel.Clear();
+ sel.Rectangular() = rangeMain;
}
- if (sel != noSel || moveExtendsSelection) {
+ if (selt != Selection::noSel) {
+ sel.selType = selt;
+ }
+ if (selt != Selection::noSel || sel.MoveExtends()) {
SetSelection(newPos);
} else {
SetEmptySelection(newPos);
@@ -828,10 +871,14 @@
return 0;
}
-int Editor::MovePositionSoVisible(int pos, int moveDir) {
- pos = pdoc->ClampPositionIntoDocument(pos);
+int Editor::MovePositionTo(int newPos, Selection::selTypes selt, bool ensureVisible) {
+ return MovePositionTo(SelectionPosition(newPos), selt, ensureVisible);
+}
+
+SelectionPosition Editor::MovePositionSoVisible(SelectionPosition pos, int moveDir) {
+ pos = ClampPositionIntoDocument(pos);
pos = MovePositionOutsideChar(pos, moveDir);
- int lineDoc = pdoc->LineFromPosition(pos);
+ int lineDoc = pdoc->LineFromPosition(pos.Position());
if (cs.GetVisible(lineDoc)) {
return pos;
} else {
@@ -839,20 +886,28 @@
if (moveDir > 0) {
// lineDisplay is already line before fold as lines in fold use display line of line after fold
lineDisplay = Platform::Clamp(lineDisplay, 0, cs.LinesDisplayed());
- return pdoc->LineStart(cs.DocFromDisplay(lineDisplay));
+ return SelectionPosition(pdoc->LineStart(cs.DocFromDisplay(lineDisplay)));
} else {
lineDisplay = Platform::Clamp(lineDisplay - 1, 0, cs.LinesDisplayed());
- return pdoc->LineEnd(cs.DocFromDisplay(lineDisplay));
+ return SelectionPosition(pdoc->LineEnd(cs.DocFromDisplay(lineDisplay)));
}
}
}
+SelectionPosition Editor::MovePositionSoVisible(int pos, int moveDir) {
+ return MovePositionSoVisible(SelectionPosition(pos), moveDir);
+}
+
+Point Editor::PointMainCaret() {
+ return LocationFromPosition(sel.Range(sel.Main()).caret);
+}
+
/**
* Choose the x position that the caret will try to stick to
* as it moves up and down.
*/
void Editor::SetLastXChosen() {
- Point pt = LocationFromPosition(currentPos);
+ Point pt = PointMainCaret();
lastXChosen = pt.x;
}
@@ -897,16 +952,16 @@
void Editor::MoveCaretInsideView(bool ensureVisible) {
PRectangle rcClient = GetTextRectangle();
- Point pt = LocationFromPosition(currentPos);
+ Point pt = PointMainCaret();
if (pt.y < rcClient.top) {
- MovePositionTo(PositionFromLocation(
+ MovePositionTo(SPositionFromLocation(
Point(lastXChosen, rcClient.top)),
- noSel, ensureVisible);
+ Selection::noSel, ensureVisible);
} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
- MovePositionTo(PositionFromLocation(
+ MovePositionTo(SPositionFromLocation(
Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
- noSel, ensureVisible);
+ Selection::noSel, ensureVisible);
}
}
@@ -978,14 +1033,14 @@
//Platform::DebugPrintf("EnsureCaretVisible %d %s\n", xOffset, useMargin ? " margin" : " ");
PRectangle rcClient = GetTextRectangle();
//int rcClientFullWidth = rcClient.Width();
- int posCaret = currentPos;
- if (posDrag >= 0) {
+ SelectionPosition posCaret = sel.RangeMain().caret;
+ if (posDrag.IsValid()) {
posCaret = posDrag;
}
Point pt = LocationFromPosition(posCaret);
Point ptBottomCaret = pt;
ptBottomCaret.y += vs.lineHeight - 1;
- int lineCaret = DisplayFromPosition(posCaret);
+ int lineCaret = DisplayFromPosition(posCaret.Position());
bool bSlop, bStrict, bJump, bEven;
// Vertical positioning
@@ -1222,10 +1277,13 @@
}
void Editor::InvalidateCaret() {
- if (posDrag >= 0)
- InvalidateRange(posDrag, posDrag + 1);
- else
- InvalidateRange(currentPos, currentPos + 1);
+ if (posDrag.IsValid()) {
+ InvalidateRange(posDrag.Position(), posDrag.Position() + 1);
+ } else {
+ for (size_t r=0; r<sel.Count(); r++) {
+ InvalidateRange(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1);
+ }
+ }
UpdateSystemCaret();
}
@@ -1255,14 +1313,14 @@
LayoutLine(lineToWrap, surface, vs, ll, wrapWidth);
linesWrapped = ll->lines;
}
- return cs.SetHeight(lineToWrap, linesWrapped +
+ return cs.SetHeight(lineToWrap, linesWrapped +
(vs.annotationVisible ? pdoc->AnnotationLines(lineToWrap) : 0));
}
// Check if wrapping needed and perform any needed wrapping.
// fullwrap: if true, all lines which need wrapping will be done,
// in this single call.
-// priorityWrapLineStart: If greater than zero, all lines starting from
+// priorityWrapLineStart: If greater than or equal to zero, all lines starting from
// here to 1 page + 100 lines past will be wrapped (even if there are
// more lines under wrapping process in idle).
// If it is neither fullwrap, nor priorityWrap, then 1 page + 100 lines will be
@@ -1294,7 +1352,7 @@
if (wrapWidth != LineLayout::wrapWidthInfinite) {
wrapWidth = LineLayout::wrapWidthInfinite;
for (int lineDoc = 0; lineDoc < pdoc->LinesTotal(); lineDoc++) {
- cs.SetHeight(lineDoc, 1 +
+ cs.SetHeight(lineDoc, 1 +
(vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0));
}
wrapOccurred = true;
@@ -1368,7 +1426,7 @@
void Editor::LinesJoin() {
if (!RangeContainsProtected(targetStart, targetEnd)) {
- pdoc->BeginUndoAction();
+ UndoGroup ug(pdoc);
bool prevNonWS = true;
for (int pos = targetStart; pos < targetEnd; pos++) {
if (IsEOLChar(pdoc->CharAt(pos))) {
@@ -1383,7 +1441,6 @@
prevNonWS = pdoc->CharAt(pos) != ' ';
}
}
- pdoc->EndUndoAction();
}
}
@@ -1406,7 +1463,7 @@
int lineStart = pdoc->LineFromPosition(targetStart);
int lineEnd = pdoc->LineFromPosition(targetEnd);
const char *eol = StringFromEOLMode(pdoc->eolMode);
- pdoc->BeginUndoAction();
+ UndoGroup ug(pdoc);
for (int line = lineStart; line <= lineEnd; line++) {
AutoSurface surface(this);
AutoLineLayout ll(llc, RetrieveLineLayout(line));
@@ -1421,7 +1478,6 @@
}
lineEnd = pdoc->LineFromPosition(targetEnd);
}
- pdoc->EndUndoAction();
}
}
@@ -1483,7 +1539,7 @@
return widthMax;
}
-void DrawStyledText(Surface *surface, ViewStyle &vs, int styleOffset, PRectangle rcText, int ascent,
+void DrawStyledText(Surface *surface, ViewStyle &vs, int styleOffset, PRectangle rcText, int ascent,
const StyledText &st, size_t start, size_t length) {
if (st.multipleStyles) {
@@ -1700,13 +1756,13 @@
if (firstSubLine) {
const StyledText stMargin = pdoc->MarginStyledText(lineDoc);
if (stMargin.text && ValidStyledText(vs, vs.marginStyleOffset, stMargin)) {
- surface->FillRectangle(rcMarker,
+ surface->FillRectangle(rcMarker,
vs.styles[stMargin.StyleAt(0)+vs.marginStyleOffset].back.allocated);
if (vs.ms[margin].style == SC_MARGIN_RTEXT) {
int width = WidestLineWidth(surface, vs, vs.marginStyleOffset, stMargin);
rcMarker.left = rcMarker.right - width - 3;
}
- DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent,
+ DrawStyledText(surface, vs, vs.marginStyleOffset, rcMarker, rcMarker.top + vs.maxAscent,
stMargin, 0, stMargin.length);
}
}
@@ -1757,7 +1813,7 @@
int posLineStart = pdoc->LineStart(lineNumber);
int posLineEnd = pdoc->LineStart(lineNumber + 1);
PLATFORM_ASSERT(posLineEnd >= posLineStart);
- int lineCaret = pdoc->LineFromPosition(currentPos);
+ int lineCaret = pdoc->LineFromPosition(sel.MainCaret());
return llc.Retrieve(lineNumber, lineCaret,
posLineEnd - posLineStart, pdoc->GetStyleClock(),
LinesOnScreen() + 1, pdoc->LinesTotal());
@@ -1884,6 +1940,7 @@
ll->widthLine = LineLayout::wrapWidthInfinite;
ll->lines = 1;
int numCharsInLine = 0;
+ int numCharsBeforeEOL = 0;
if (vstyle.edgeState == EDGE_BACKGROUND) {
ll->edgeColumn = pdoc->FindColumn(line, theEdge);
if (ll->edgeColumn >= posLineStart) {
@@ -1910,6 +1967,8 @@
else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
ll->chars[numCharsInLine] = static_cast<char>(tolower(chDoc));
numCharsInLine++;
+ if (!IsEOLChar(chDoc))
+ numCharsBeforeEOL++;
}
}
ll->xHighlightGuide = 0;
@@ -1992,6 +2051,7 @@
ll->positions[startseg] += 2;
}
ll->numCharsInLine = numCharsInLine;
+ ll->numCharsBeforeEOL = numCharsBeforeEOL;
ll->validity = LineLayout::llPositions;
}
// Hard to cope when too narrow, so just assume there is space
@@ -2072,16 +2132,22 @@
}
}
-ColourAllocated Editor::SelectionBackground(ViewStyle &vsDraw) {
- return primarySelection ? vsDraw.selbackground.allocated : vsDraw.selbackground2.allocated;
+ColourAllocated Editor::SelectionBackground(ViewStyle &vsDraw, bool main) {
+ return main ?
+ (primarySelection ? vsDraw.selbackground.allocated : vsDraw.selbackground2.allocated) :
+ vsDraw.selAdditionalBackground.allocated;
}
ColourAllocated Editor::TextBackground(ViewStyle &vsDraw, bool overrideBackground,
- ColourAllocated background, bool inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
- if (inSelection) {
+ ColourAllocated background, int inSelection, bool inHotspot, int styleMain, int i, LineLayout *ll) {
+ if (inSelection == 1) {
if (vsDraw.selbackset && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
- return SelectionBackground(vsDraw);
+ return SelectionBackground(vsDraw, true);
}
+ } else if (inSelection == 2) {
+ if (vsDraw.selbackset && (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA)) {
+ return SelectionBackground(vsDraw, false);
+ }
} else {
if ((vsDraw.edgeState == EDGE_BACKGROUND) &&
(i >= ll->edgeColumn) &&
@@ -2183,35 +2249,103 @@
bool overrideBackground, ColourAllocated background,
bool drawWrapMarkEnd, ColourAllocated wrapColour) {
- int styleMask = pdoc->stylingBitsMask;
+ const int posLineStart = pdoc->LineStart(line);
+ const int styleMask = pdoc->stylingBitsMask;
PRectangle rcSegment = rcLine;
+ const bool lastSubLine = subLine == (ll->lines - 1);
+ int virtualSpace = 0;
+ if (lastSubLine) {
+ const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ virtualSpace = sel.VirtualSpaceFor(pdoc->LineEnd(line)) * spaceWidth;
+ }
+
// Fill in a PRectangle representing the end of line characters
+
int xEol = ll->positions[lineEnd] - subLineStart;
- rcSegment.left = xEol + xStart;
- rcSegment.right = xEol + vsDraw.aveCharWidth + xStart;
- int posLineEnd = pdoc->LineStart(line + 1);
- bool eolInSelection = (subLine == (ll->lines - 1)) &&
- (posLineEnd > ll->selStart) && (posLineEnd <= ll->selEnd) && (ll->selStart != ll->selEnd);
- if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
- surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
+ // Fill the virtual space and show selections within it
+ if (virtualSpace) {
+ rcSegment.left = xEol + xStart;
+ rcSegment.right = xEol + xStart + virtualSpace;
+ surface->FillRectangle(rcSegment, overrideBackground ? background : vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ if (!hideSelection && ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA))) {
+ SelectionSegment virtualSpaceRange(SelectionPosition(pdoc->LineEnd(line)), SelectionPosition(pdoc->LineEnd(line), sel.VirtualSpaceFor(pdoc->LineEnd(line))));
+ for (size_t r=0; r<sel.Count(); r++) {
+ int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+ if (alpha == SC_ALPHA_NOALPHA) {
+ SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+ if (!portion.Empty()) {
+ const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+ rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+ rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+ rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+ surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, r == sel.Main()));
+ }
+ }
+ }
+ }
+ }
+
+ int posAfterLineEnd = pdoc->LineStart(line + 1);
+ int eolInSelection = (subLine == (ll->lines - 1)) ? sel.InSelectionForEOL(posAfterLineEnd) : 0;
+ int alpha = (eolInSelection == 1) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+
+ // Draw the [CR], [LF], or [CR][LF] blobs if visible line ends are on
+ int blobsWidth = 0;
+ if (lastSubLine) {
+ for (int eolPos=ll->numCharsBeforeEOL; eolPos<ll->numCharsInLine; eolPos++) {
+ rcSegment.left = xStart + ll->positions[eolPos] - subLineStart + virtualSpace;
+ rcSegment.right = xStart + ll->positions[eolPos+1] - subLineStart + virtualSpace;
+ blobsWidth += rcSegment.Width();
+ const char *ctrlChar = ControlCharacterString(ll->chars[eolPos]);
+ int inSelection = 0;
+ bool inHotspot = false;
+ int styleMain = ll->styles[eolPos];
+ ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, eolPos, ll);
+ ColourAllocated textFore = vsDraw.styles[styleMain].fore.allocated;
+ if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1)) {
+ if (alpha == SC_ALPHA_NOALPHA) {
+ surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
+ } else {
+ surface->FillRectangle(rcSegment, textBack);
+ SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
+ }
+ } else {
+ surface->FillRectangle(rcSegment, textBack);
+ }
+ DrawTextBlob(surface, vsDraw, rcSegment, ctrlChar, textBack, textFore, twoPhaseDraw);
+ }
+ }
+
+ // Draw the eol-is-selected rectangle
+ rcSegment.left = xEol + xStart + virtualSpace + blobsWidth;
+ rcSegment.right = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
+
+ if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+ surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
} else {
if (overrideBackground) {
surface->FillRectangle(rcSegment, background);
+ } else if (line < pdoc->LinesTotal() - 1) {
+ surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ } else if (vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].eolFilled) {
+ surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
} else {
- surface->FillRectangle(rcSegment, vsDraw.styles[ll->styles[ll->numCharsInLine] & styleMask].back.allocated);
+ surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
}
- if (eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha != SC_ALPHA_NOALPHA)) {
- SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+ if (!hideSelection && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+ SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
}
}
- rcSegment.left = xEol + vsDraw.aveCharWidth + xStart;
+ // Fill the remainder of the line
+ rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
rcSegment.right = rcLine.right;
- if (vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha == SC_ALPHA_NOALPHA)) {
- surface->FillRectangle(rcSegment, SelectionBackground(vsDraw));
+ if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
+ surface->FillRectangle(rcSegment, SelectionBackground(vsDraw, eolInSelection == 1));
} else {
if (overrideBackground) {
surface->FillRectangle(rcSegment, background);
@@ -2220,8 +2354,8 @@
} else {
surface->FillRectangle(rcSegment, vsDraw.styles[STYLE_DEFAULT].back.allocated);
}
- if (vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (vsDraw.selAlpha != SC_ALPHA_NOALPHA)) {
- SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+ if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha != SC_ALPHA_NOALPHA)) {
+ SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, eolInSelection == 1), alpha);
}
}
@@ -2229,7 +2363,7 @@
PRectangle rcPlace = rcSegment;
if (wrapVisualFlagsLocation & SC_WRAPVISUALFLAGLOC_END_BY_TEXT) {
- rcPlace.left = xEol + xStart;
+ rcPlace.left = xEol + xStart + virtualSpace;
rcPlace.right = rcPlace.left + vsDraw.aveCharWidth;
} else {
// draw left of the right text margin, to avoid clipping by the current clip rect
@@ -2336,11 +2470,11 @@
}
PRectangle rcText = rcSegment;
if (vs.annotationVisible == ANNOTATION_BOXED) {
- surface->FillRectangle(rcText,
+ surface->FillRectangle(rcText,
vsDraw.styles[stAnnotation.StyleAt(start) + vsDraw.annotationStyleOffset].back.allocated);
rcText.left += vsDraw.spaceWidth;
}
- DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent,
+ DrawStyledText(surface, vsDraw, vsDraw.annotationStyleOffset, rcText, rcText.top + vsDraw.maxAscent,
stAnnotation, start, lengthAnnotation);
if (vs.annotationVisible == ANNOTATION_BOXED) {
surface->MoveTo(rcSegment.left, rcSegment.top);
@@ -2350,7 +2484,7 @@
if (subLine == ll->lines){
surface->MoveTo(rcSegment.left, rcSegment.top);
surface->LineTo(rcSegment.right, rcSegment.top);
- }
+ }
if (subLine == ll->lines+annotationLines-1) {
surface->MoveTo(rcSegment.left, rcSegment.bottom - 1);
surface->LineTo(rcSegment.right, rcSegment.bottom - 1);
@@ -2427,6 +2561,9 @@
if (subLine < ll->lines) {
lineStart = ll->LineStart(subLine);
lineEnd = ll->LineStart(subLine + 1);
+ if (subLine == ll->lines - 1) {
+ lineEnd = ll->numCharsBeforeEOL;
+ }
}
ColourAllocated wrapColour = vsDraw.styles[STYLE_DEFAULT].fore.allocated;
@@ -2478,10 +2615,15 @@
}
}
+ bool selBackDrawn = vsDraw.selbackset &&
+ ((vsDraw.selAlpha == SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha == SC_ALPHA_NOALPHA));
+
// Does not take margin into account but not significant
int xStartVisible = subLineStart - xStart;
- BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
+ ll->psel = &sel;
+
+ BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible, selBackDrawn);
int next = bfBack.First();
// Background drawing loop
@@ -2502,7 +2644,7 @@
rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
int styleMain = ll->styles[i];
- bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+ const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
if (ll->chars[i] == '\t') {
@@ -2571,7 +2713,8 @@
inIndentation = subLine == 0; // Do not handle indentation except on first subline.
// Foreground drawing loop
- BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible);
+ BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible,
+ ((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset));
next = bfFore.First();
while (next < lineEnd) {
@@ -2595,9 +2738,9 @@
if (vsDraw.hotspotForegroundSet)
textFore = vsDraw.hotspotForeground.allocated;
}
- bool inSelection = (iDoc >= ll->selStart) && (iDoc < ll->selEnd) && (ll->selStart != ll->selEnd);
+ const int inSelection = hideSelection ? 0 : sel.CharacterInSelection(iDoc);
if (inSelection && (vsDraw.selforeset)) {
- textFore = vsDraw.selforeground.allocated;
+ textFore = (inSelection == 1) ? vsDraw.selforeground.allocated : vsDraw.selAdditionalForeground.allocated;
}
bool inHotspot = (ll->hsStart != -1) && (iDoc >= ll->hsStart) && (iDoc < ll->hsEnd);
ColourAllocated textBack = TextBackground(vsDraw, overrideBackground, background, inSelection, inHotspot, styleMain, i, ll);
@@ -2679,8 +2822,8 @@
surface->FillRectangle(rcSpace, textBack);
}
PRectangle rcDot(xmid + xStart - subLineStart, rcSegment.top + vsDraw.lineHeight / 2, 0, 0);
- rcDot.right = rcDot.left + 1;
- rcDot.bottom = rcDot.top + 1;
+ rcDot.right = rcDot.left + vs.whitespaceSize;
+ rcDot.bottom = rcDot.top + vs.whitespaceSize;
surface->FillRectangle(rcDot, textFore);
}
}
@@ -2718,6 +2861,8 @@
if ((vsDraw.viewIndentationGuides == ivLookForward || vsDraw.viewIndentationGuides == ivLookBoth)
&& (subLine == 0)) {
int indentSpace = pdoc->GetLineIndentation(line);
+ int xStartText = ll->positions[pdoc->GetLineIndentPosition(line) - posLineStart];
+
// Find the most recent line with some text
int lineLastWithText = line;
@@ -2725,6 +2870,7 @@
lineLastWithText--;
}
if (lineLastWithText < line) {
+ xStartText = 100000; // Don't limit to visible indentation on empty line
// This line is empty, so use indentation of last line with text
int indentLastWithText = pdoc->GetLineIndentation(lineLastWithText);
int isFoldHeader = pdoc->GetLevel(lineLastWithText) & SC_FOLDLEVELHEADERFLAG;
@@ -2754,8 +2900,10 @@
for (int indentPos = pdoc->IndentSize(); indentPos < indentSpace; indentPos += pdoc->IndentSize()) {
int xIndent = indentPos * vsDraw.spaceWidth;
- DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
- (ll->xHighlightGuide == xIndent));
+ if (xIndent < xStartText) {
+ DrawIndentGuide(surface, lineVisible, vsDraw.lineHeight, xIndent + xStart, rcSegment,
+ (ll->xHighlightGuide == xIndent));
+ }
}
}
@@ -2767,16 +2915,29 @@
xStart, subLine, subLineStart, overrideBackground, background,
drawWrapMarkEnd, wrapColour);
}
- if ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) && (ll->selStart >= 0) && (ll->selEnd >= 0)) {
- int startPosSel = (ll->selStart < posLineStart) ? posLineStart : ll->selStart;
- int endPosSel = (ll->selEnd < (lineEnd + posLineStart)) ? ll->selEnd : (lineEnd + posLineStart);
- if (startPosSel < endPosSel) {
- rcSegment.left = xStart + ll->positions[startPosSel - posLineStart] - subLineStart;
- rcSegment.right = xStart + ll->positions[endPosSel - posLineStart] - subLineStart;
- rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
- rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
- SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw), vsDraw.selAlpha);
+ if (!hideSelection && ((vsDraw.selAlpha != SC_ALPHA_NOALPHA) || (vsDraw.selAdditionalAlpha != SC_ALPHA_NOALPHA))) {
+ // For each selection draw
+ int virtualSpaces = 0;
+ if (subLine == (ll->lines - 1)) {
+ virtualSpaces = sel.VirtualSpaceFor(pdoc->LineEnd(line));
}
+ SelectionPosition posStart(posLineStart);
+ SelectionPosition posEnd(posLineStart + lineEnd, virtualSpaces);
+ SelectionSegment virtualSpaceRange(posStart, posEnd);
+ for (size_t r=0; r<sel.Count(); r++) {
+ int alpha = (r == sel.Main()) ? vsDraw.selAlpha : vsDraw.selAdditionalAlpha;
+ if (alpha != SC_ALPHA_NOALPHA) {
+ SelectionSegment portion = sel.Range(r).Intersect(virtualSpaceRange);
+ if (!portion.Empty()) {
+ const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ rcSegment.left = xStart + ll->positions[portion.start.Position() - posLineStart] - subLineStart + portion.start.VirtualSpace() * spaceWidth;
+ rcSegment.right = xStart + ll->positions[portion.end.Position() - posLineStart] - subLineStart + portion.end.VirtualSpace() * spaceWidth;
+ rcSegment.left = Platform::Maximum(rcSegment.left, rcLine.left);
+ rcSegment.right = Platform::Minimum(rcSegment.right, rcLine.right);
+ SimpleAlphaRectangle(surface, rcSegment, SelectionBackground(vsDraw, r == sel.Main()), alpha);
+ }
+ }
+ }
}
// Draw any translucent whole line states
@@ -2809,7 +2970,8 @@
}
}
-void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine, int xStart, int offset, int posCaret, PRectangle rcCaret) {
+void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
+ int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour) {
int lineStart = ll->LineStart(subLine);
int posBefore = posCaret;
@@ -2868,7 +3030,7 @@
surface->DrawTextClipped(rcCaret, vsDraw.styles[styleMain].font,
rcCaret.top + vsDraw.maxAscent, ll->chars + offsetFirstChar,
numCharsToDraw, vsDraw.styles[styleMain].back.allocated,
- vsDraw.caretcolour.allocated);
+ caretColour);
}
void Editor::RefreshPixMaps(Surface *surfaceWindow) {
@@ -2937,6 +3099,89 @@
}
}
+void Editor::DrawCarets(Surface *surface, ViewStyle &vsDraw, int lineDoc, int xStart,
+ PRectangle rcLine, LineLayout *ll, int subLine) {
+ // When drag is active it is the only caret drawn
+ bool drawDrag = posDrag.IsValid();
+ if (hideSelection && !drawDrag)
+ return;
+ const int posLineStart = pdoc->LineStart(lineDoc);
+ // For each selection draw
+ for (size_t r=0; (r<sel.Count()) || drawDrag; r++) {
+ const bool mainCaret = r == sel.Main();
+ const SelectionPosition posCaret = (drawDrag ? posDrag : sel.Range(r).caret);
+ const int offset = posCaret.Position() - posLineStart;
+ const int spaceWidth = static_cast<int>(vsDraw.styles[ll->EndLineStyle()].spaceWidth);
+ const int virtualOffset = posCaret.VirtualSpace() * spaceWidth;
+ if (ll->InLine(offset, subLine) && offset <= ll->numCharsBeforeEOL) {
+ int xposCaret = ll->positions[offset] + virtualOffset - ll->positions[ll->LineStart(subLine)];
+ if (ll->wrapIndent != 0) {
+ int lineStart = ll->LineStart(subLine);
+ if (lineStart != 0) // Wrapped
+ xposCaret += ll->wrapIndent;
+ }
+ bool caretBlinkState = (caret.active && caret.on) || (!additionalCaretsBlink && !mainCaret);
+ bool caretVisibleState = additionalCaretsVisible || mainCaret;
+ if ((xposCaret >= 0) && (vsDraw.caretWidth > 0) && (vsDraw.caretStyle != CARETSTYLE_INVISIBLE) &&
+ ((posDrag.IsValid()) || (caretBlinkState && caretVisibleState))) {
+ bool caretAtEOF = false;
+ bool caretAtEOL = false;
+ bool drawBlockCaret = false;
+ int widthOverstrikeCaret;
+ int caretWidthOffset = 0;
+ PRectangle rcCaret = rcLine;
+
+ if (posCaret.Position() == pdoc->Length()) { // At end of document
+ caretAtEOF = true;
+ widthOverstrikeCaret = vsDraw.aveCharWidth;
+ } else if ((posCaret.Position() - posLineStart) >= ll->numCharsInLine) { // At end of line
+ caretAtEOL = true;
+ widthOverstrikeCaret = vsDraw.aveCharWidth;
+ } else {
+ widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset];
+ }
+ if (widthOverstrikeCaret < 3) // Make sure its visible
+ widthOverstrikeCaret = 3;
+
+ if (xposCaret > 0)
+ caretWidthOffset = 1; // Move back so overlaps both character cells.
+ xposCaret += xStart;
+ if (posDrag.IsValid()) {
+ /* Dragging text, use a line caret */
+ rcCaret.left = xposCaret - caretWidthOffset;
+ rcCaret.right = rcCaret.left + vsDraw.caretWidth;
+ } else if (inOverstrike) {
+ /* Overstrike (insert mode), use a modified bar caret */
+ rcCaret.top = rcCaret.bottom - 2;
+ rcCaret.left = xposCaret + 1;
+ rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1;
+ } else if (vsDraw.caretStyle == CARETSTYLE_BLOCK) {
+ /* Block caret */
+ rcCaret.left = xposCaret;
+ if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) {
+ drawBlockCaret = true;
+ rcCaret.right = xposCaret + widthOverstrikeCaret;
+ } else {
+ rcCaret.right = xposCaret + vsDraw.aveCharWidth;
+ }
+ } else {
+ /* Line caret */
+ rcCaret.left = xposCaret - caretWidthOffset;
+ rcCaret.right = rcCaret.left + vsDraw.caretWidth;
+ }
+ ColourAllocated caretColour = mainCaret ? vsDraw.caretcolour.allocated : vsDraw.additionalCaretColour.allocated;
+ if (drawBlockCaret) {
+ DrawBlockCaret(surface, vsDraw, ll, subLine, xStart, offset, posCaret.Position(), rcCaret, caretColour);
+ } else {
+ surface->FillRectangle(rcCaret, caretColour);
+ }
+ }
+ }
+ if (drawDrag)
+ break;
+ }
+}
+
void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
//Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
// paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
@@ -2989,7 +3234,7 @@
// lines first).
int startLineToWrap = cs.DocFromDisplay(topLine) - 5;
if (startLineToWrap < 0)
- startLineToWrap = -1;
+ startLineToWrap = 0;
if (WrapLines(false, startLineToWrap)) {
// The wrapping process has changed the height of some lines so
// abandon this paint for a complete repaint.
@@ -3036,10 +3281,10 @@
int visibleLine = topLine + screenLinePaintFirst;
- int posCaret = currentPos;
- if (posDrag >= 0)
+ SelectionPosition posCaret = sel.RangeMain().caret;
+ if (posDrag.IsValid())
posCaret = posDrag;
- int lineCaret = pdoc->LineFromPosition(posCaret);
+ int lineCaret = pdoc->LineFromPosition(posCaret.Position());
// Remove selection margin from drawing area so text will not be drawn
// on it in unbuffered mode.
@@ -3055,7 +3300,6 @@
//ElapsedTime etWhole;
int lineDocPrevious = -1; // Used to avoid laying out one document line multiple times
AutoLineLayout ll(llc, 0);
- SelectionLineIterator lineIterator(this);
while (visibleLine < cs.LinesDisplayed() && yposScreen < rcArea.bottom) {
int lineDoc = cs.DocFromDisplay(visibleLine);
@@ -3069,8 +3313,6 @@
//ElapsedTime et;
if (lineDoc != lineDocPrevious) {
ll.Set(0);
- // For rectangular selection this accesses the layout cache so should be after layout returned.
- lineIterator.SetAt(lineDoc);
ll.Set(RetrieveLineLayout(lineDoc));
LayoutLine(lineDoc, surface, vs, ll, wrapWidth);
lineDocPrevious = lineDoc;
@@ -3078,17 +3320,8 @@
//durLayout += et.Duration(true);
if (ll) {
- if (selType == selStream) {
- ll->selStart = SelectionStart();
- ll->selEnd = SelectionEnd();
- } else {
- ll->selStart = lineIterator.startPos;
- ll->selEnd = lineIterator.endPos;
- }
ll->containsCaret = lineDoc == lineCaret;
if (hideSelection) {
- ll->selStart = -1;
- ll->selEnd = -1;
ll->containsCaret = false;
}
@@ -3132,78 +3365,17 @@
}
}
- // Draw the Caret
- if (lineDoc == lineCaret) {
- int offset = Platform::Minimum(posCaret - rangeLine.start, ll->maxLineLength);
- if (ll->InLine(offset, subLine)) {
- int xposCaret = ll->positions[offset] - ll->positions[ll->LineStart(subLine)] + xStart;
+ DrawCarets(surface, vs, lineDoc, xStart, rcLine, ll, subLine);
- if (ll->wrapIndent != 0) {
- int lineStart = ll->LineStart(subLine);
- if (lineStart != 0) // Wrapped
- xposCaret += ll->wrapIndent;
- }
- if ((xposCaret >= 0) && (vs.caretWidth > 0) && (vs.caretStyle != CARETSTYLE_INVISIBLE) &&
- ((posDrag >= 0) || (caret.active && caret.on))) {
- bool caretAtEOF = false;
- bool caretAtEOL = false;
- bool drawBlockCaret = false;
- int widthOverstrikeCaret;
- int caretWidthOffset = 0;
- PRectangle rcCaret = rcLine;
-
- if (posCaret == pdoc->Length()) { // At end of document
- caretAtEOF = true;
- widthOverstrikeCaret = vs.aveCharWidth;
- } else if ((posCaret - rangeLine.start) >= ll->numCharsInLine) { // At end of line
- caretAtEOL = true;
- widthOverstrikeCaret = vs.aveCharWidth;
- } else {
- widthOverstrikeCaret = ll->positions[offset + 1] - ll->positions[offset];
- }
- if (widthOverstrikeCaret < 3) // Make sure its visible
- widthOverstrikeCaret = 3;
-
- if (offset > ll->LineStart(subLine))
- caretWidthOffset = 1; // Move back so overlaps both character cells.
- if (posDrag >= 0) {
- /* Dragging text, use a line caret */
- rcCaret.left = xposCaret - caretWidthOffset;
- rcCaret.right = rcCaret.left + vs.caretWidth;
- } else if (inOverstrike) {
- /* Overstrike (insert mode), use a modified bar caret */
- rcCaret.top = rcCaret.bottom - 2;
- rcCaret.left = xposCaret + 1;
- rcCaret.right = rcCaret.left + widthOverstrikeCaret - 1;
- } else if (vs.caretStyle == CARETSTYLE_BLOCK) {
- /* Block caret */
- rcCaret.left = xposCaret;
- if (!caretAtEOL && !caretAtEOF && (ll->chars[offset] != '\t') && !(IsControlCharacter(ll->chars[offset]))) {
- drawBlockCaret = true;
- rcCaret.right = xposCaret + widthOverstrikeCaret;
- } else {
- rcCaret.right = xposCaret + vs.aveCharWidth;
- }
- } else {
- /* Line caret */
- rcCaret.left = xposCaret - caretWidthOffset;
- rcCaret.right = rcCaret.left + vs.caretWidth;
- }
- if (drawBlockCaret) {
- DrawBlockCaret(surface, vs, ll, subLine, xStart, offset, posCaret, rcCaret);
- } else {
- surface->FillRectangle(rcCaret, vs.caretcolour.allocated);
- }
- }
- }
- }
-
if (bufferedDraw) {
Point from(vs.fixedColumnWidth, 0);
PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen,
rcClient.right, yposScreen + vs.lineHeight);
surfaceWindow->Copy(rcCopyArea, from, *pixmapLine);
}
+
+ lineWidthMaxSeen = Platform::Maximum(
+ lineWidthMaxSeen, ll->positions[ll->numCharsInLine]);
//durCopy += et.Duration(true);
}
@@ -3214,8 +3386,6 @@
yposScreen += vs.lineHeight;
visibleLine++;
- lineWidthMaxSeen = Platform::Maximum(
- lineWidthMaxSeen, ll->positions[ll->numCharsInLine]);
//gdk_flush();
}
ll.Set(0);
@@ -3298,6 +3468,7 @@
vsPrint.selbackset = false;
vsPrint.selforeset = false;
vsPrint.selAlpha = SC_ALPHA_NOALPHA;
+ vsPrint.selAdditionalAlpha = SC_ALPHA_NOALPHA;
vsPrint.whitespaceBackgroundSet = false;
vsPrint.whitespaceForegroundSet = false;
vsPrint.showCaretLineBackground = false;
@@ -3375,8 +3546,6 @@
LineLayout ll(8000);
LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint);
- ll.selStart = -1;
- ll.selEnd = -1;
ll.containsCaret = false;
PRectangle rcLine;
@@ -3499,6 +3668,15 @@
}
}
+int Editor::InsertSpace(int position, unsigned int spaces) {
+ if (spaces > 0) {
+ std::string spaceText(spaces, ' ');
+ pdoc->InsertString(position, spaceText.c_str(), spaces);
+ position += spaces;
+ }
+ return position;
+}
+
void Editor::AddChar(char ch) {
char s[2];
s[0] = ch;
@@ -3506,63 +3684,60 @@
AddCharUTF(s, 1);
}
+void Editor::FilterSelections() {
+ if (!additionalSelectionTyping && (sel.Count() > 1)) {
+ SelectionRange rangeOnly = sel.RangeMain();
+ InvalidateSelection(rangeOnly, true);
+ sel.SetSelection(rangeOnly);
+ }
+}
+
// AddCharUTF inserts an array of bytes which may or may not be in UTF-8.
void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
- bool wasSelection = currentPos != anchor;
- if(wasSelection && selType == selRectangle ) {
- int startPos;
- int endPos;
-
- int c1 = pdoc->GetColumn(currentPos);
- int c2 = pdoc->GetColumn(anchor);
- int offset = c1 < c2 ? c1 : c2;
-
- pdoc->BeginUndoAction();
- SelectionLineIterator lineIterator(this, false);
- while (lineIterator.Iterate()) {
- startPos = lineIterator.startPos;
- endPos = lineIterator.endPos;
-
- if(pdoc->GetColumn(endPos) >= offset){
- unsigned int chars = endPos - startPos;
- if (0 != chars) {
- pdoc->DeleteChars(startPos, chars);
- }
- pdoc->InsertString(startPos, s, len);
- }
- }
- anchor += len;
- currentPos += len;
- SetRectangularRange();
- pdoc->EndUndoAction();
-
- } else {
- ClearSelection();
- bool charReplaceAction = false;
- if (inOverstrike && !wasSelection && !RangeContainsProtected(currentPos, currentPos + 1)) {
- if (currentPos < (pdoc->Length())) {
- if (!IsEOLChar(pdoc->CharAt(currentPos))) {
- charReplaceAction = true;
- pdoc->BeginUndoAction();
- pdoc->DelChar(currentPos);
+ FilterSelections();
+ {
+ UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty() || inOverstrike);
+ for (size_t r=0; r<sel.Count(); r++) {
+ if (!RangeContainsProtected(sel.Range(r).Start().Position(),
+ sel.Range(r).End().Position())) {
+ int positionInsert = sel.Range(r).Start().Position();
+ if (!sel.Range(r).Empty()) {
+ if (sel.Range(r).Length()) {
+ pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
+ sel.Range(r).ClearVirtualSpace();
+ } else {
+ // Range is all virtual so collapse to start of virtual space
+ sel.Range(r).MinimizeVirtualSpace();
+ }
+ } else if (inOverstrike) {
+ if (positionInsert < pdoc->Length()) {
+ if (!IsEOLChar(pdoc->CharAt(positionInsert))) {
+ pdoc->DelChar(positionInsert);
+ sel.Range(r).ClearVirtualSpace();
+ }
+ }
}
+ positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
+ if (pdoc->InsertString(positionInsert, s, len)) {
+ sel.Range(r).caret.SetPosition(positionInsert + len);
+ sel.Range(r).anchor.SetPosition(positionInsert + len);
+ }
+ sel.Range(r).ClearVirtualSpace();
+ // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
+ if (wrapState != eWrapNone) {
+ AutoSurface surface(this);
+ if (surface) {
+ WrapOneLine(surface, pdoc->LineFromPosition(positionInsert));
+ }
+ }
}
}
- if (pdoc->InsertString(currentPos, s, len)) {
- SetEmptySelection(currentPos + len);
- }
- if (charReplaceAction) {
- pdoc->EndUndoAction();
- }
}
- // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
if (wrapState != eWrapNone) {
- AutoSurface surface(this);
- if (surface) {
- WrapOneLine(surface, pdoc->LineFromPosition(currentPos));
- }
SetScrollBars();
}
+ ThinRectangularRange();
+ // If in wrap mode rewrap current line so EnsureCaretVisible has accurate information
EnsureCaretVisible();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
@@ -3606,48 +3781,44 @@
}
NotifyChar(byte);
}
+
+ if (recordingMacro) {
+ NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(s));
+ }
}
void Editor::ClearSelection() {
- if (!SelectionContainsProtected()) {
- int startPos = SelectionStart();
- if (selType == selStream) {
- unsigned int chars = SelectionEnd() - startPos;
- if (0 != chars) {
- pdoc->BeginUndoAction();
- pdoc->DeleteChars(startPos, chars);
- pdoc->EndUndoAction();
+ if (!sel.IsRectangular())
+ FilterSelections();
+ UndoGroup ug(pdoc);
+ for (size_t r=0; r<sel.Count(); r++) {
+ if (!sel.Range(r).Empty()) {
+ if (!RangeContainsProtected(sel.Range(r).Start().Position(),
+ sel.Range(r).End().Position())) {
+ pdoc->DeleteChars(sel.Range(r).Start().Position(),
+ sel.Range(r).Length());
+ sel.Range(r) = sel.Range(r).Start();
}
- } else {
- pdoc->BeginUndoAction();
- SelectionLineIterator lineIterator(this, false);
- while (lineIterator.Iterate()) {
- startPos = lineIterator.startPos;
- unsigned int chars = lineIterator.endPos - startPos;
- if (0 != chars) {
- pdoc->DeleteChars(startPos, chars);
- }
- }
- pdoc->EndUndoAction();
- selType = selStream;
}
- SetEmptySelection(startPos);
}
+ ThinRectangularRange();
+ sel.RemoveDuplicates();
+ ClaimSelection();
}
void Editor::ClearAll() {
- pdoc->BeginUndoAction();
- if (0 != pdoc->Length()) {
- pdoc->DeleteChars(0, pdoc->Length());
+ {
+ UndoGroup ug(pdoc);
+ if (0 != pdoc->Length()) {
+ pdoc->DeleteChars(0, pdoc->Length());
+ }
+ if (!pdoc->IsReadOnly()) {
+ cs.Clear();
+ pdoc->AnnotationClearAll();
+ pdoc->MarginClearAll();
+ }
}
- if (!pdoc->IsReadOnly()) {
- cs.Clear();
- pdoc->AnnotationClearAll();
- pdoc->MarginClearAll();
- }
- pdoc->EndUndoAction();
- anchor = 0;
- currentPos = 0;
+ sel.Clear();
SetTopLine(0);
SetVerticalScrollPos();
InvalidateStyleRedraw();
@@ -3684,15 +3855,20 @@
}
}
-void Editor::PasteRectangular(int pos, const char *ptr, int len) {
+void Editor::PasteRectangular(SelectionPosition pos, const char *ptr, int len) {
if (pdoc->IsReadOnly() || SelectionContainsProtected()) {
return;
}
- currentPos = pos;
- int xInsert = XFromPosition(currentPos);
- int line = pdoc->LineFromPosition(currentPos);
+ sel.Clear();
+ sel.RangeMain() = SelectionRange(pos);
+ int line = pdoc->LineFromPosition(sel.MainCaret());
+ UndoGroup ug(pdoc);
+ sel.RangeMain().caret = SelectionPosition(
+ InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+ int xInsert = XFromPosition(sel.RangeMain().caret);
bool prevCr = false;
- pdoc->BeginUndoAction();
+ while ((len > 0) && IsEOLChar(ptr[len-1]))
+ len--;
for (int i = 0; i < len; i++) {
if (IsEOLChar(ptr[i])) {
if ((ptr[i] == '\r') || (!prevCr))
@@ -3704,21 +3880,20 @@
pdoc->InsertChar(pdoc->Length(), '\n');
}
// Pad the end of lines with spaces if required
- currentPos = PositionFromLineX(line, xInsert);
- if ((XFromPosition(currentPos) < xInsert) && (i + 1 < len)) {
- while (XFromPosition(currentPos) < xInsert) {
- pdoc->InsertChar(currentPos, ' ');
- currentPos++;
+ sel.RangeMain().caret.SetPosition(PositionFromLineX(line, xInsert));
+ if ((XFromPosition(sel.MainCaret()) < xInsert) && (i + 1 < len)) {
+ while (XFromPosition(sel.MainCaret()) < xInsert) {
+ pdoc->InsertChar(sel.MainCaret(), ' ');
+ sel.RangeMain().caret.Add(1);
}
}
prevCr = ptr[i] == '\r';
} else {
- pdoc->InsertString(currentPos, ptr + i, 1);
- currentPos++;
+ pdoc->InsertString(sel.MainCaret(), ptr + i, 1);
+ sel.RangeMain().caret.Add(1);
prevCr = false;
}
}
- pdoc->EndUndoAction();
SetEmptySelection(pos);
}
@@ -3727,44 +3902,33 @@
}
void Editor::Clear() {
- bool wasSelection = currentPos != anchor;
- if(wasSelection && selType == selRectangle ) {
- int startPos;
- int endPos;
-
- int c1 = pdoc->GetColumn(currentPos);
- int c2 = pdoc->GetColumn(anchor);
- int offset = c1 < c2 ? c1 : c2;
-
- pdoc->BeginUndoAction();
- SelectionLineIterator lineIterator(this, false);
- while (lineIterator.Iterate()) {
- startPos = lineIterator.startPos;
- endPos = lineIterator.endPos;
-
- if(pdoc->GetColumn(endPos) >= offset){
- unsigned int chars = endPos - startPos;
- if (0 != chars) {
- pdoc->DeleteChars(startPos, chars);
- } else
- pdoc->DelChar(startPos);
- }
- }
- SetRectangularRange();
- pdoc->EndUndoAction();
-
- } else if (currentPos == anchor) {
- if (!RangeContainsProtected(currentPos, currentPos + 1)) {
- DelChar();
+ UndoGroup ug(pdoc);
+ // If multiple selections, don't delete EOLS
+ if (sel.Empty()) {
+ for (size_t r=0; r<sel.Count(); r++) {
+ if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
+ if (sel.Range(r).Start().VirtualSpace()) {
+ if (sel.Range(r).anchor < sel.Range(r).caret)
+ sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).anchor.Position(), sel.Range(r).anchor.VirtualSpace()));
+ else
+ sel.Range(r) = SelectionPosition(InsertSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace()));
+ }
+ if ((sel.Count() == 1) || !IsEOLChar(pdoc->CharAt(sel.Range(r).caret.Position()))) {
+ pdoc->DelChar(sel.Range(r).caret.Position());
+ sel.Range(r).ClearVirtualSpace();
+ } // else multiple selection so don't eat line ends
+ } else {
+ sel.Range(r).ClearVirtualSpace();
+ }
}
} else {
ClearSelection();
}
- if( !wasSelection )
- SetEmptySelection(currentPos);
+ sel.RemoveDuplicates();
}
void Editor::SelectAll() {
+ sel.Clear();
SetSelection(0, pdoc->Length());
Redraw();
}
@@ -3789,65 +3953,54 @@
}
void Editor::DelChar() {
- if (!RangeContainsProtected(currentPos, currentPos + 1)) {
- pdoc->DelChar(currentPos);
+ if (!RangeContainsProtected(sel.MainCaret(), sel.MainCaret() + 1)) {
+ pdoc->DelChar(sel.MainCaret());
}
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
}
void Editor::DelCharBack(bool allowLineStartDeletion) {
- bool wasSelection = currentPos != anchor;
- if(wasSelection && selType == selRectangle ) {
- int startPos;
- int endPos;
-
- int c1 = pdoc->GetColumn(currentPos);
- int c2 = pdoc->GetColumn(anchor);
- int offset = c1 < c2 ? c1 : c2;
-
- pdoc->BeginUndoAction();
- SelectionLineIterator lineIterator(this, false);
- while (lineIterator.Iterate()) {
- startPos = lineIterator.startPos;
- endPos = lineIterator.endPos;
-
- if(pdoc->GetColumn(endPos) >= offset){
- unsigned int chars = endPos - startPos;
- if (0 != chars) {
- pdoc->DeleteChars(startPos, chars);
- } else
- pdoc->DelCharBack(startPos);
- }
- }
- SetRectangularRange();
- pdoc->EndUndoAction();
-
- } else if (currentPos == anchor) {
- if (!RangeContainsProtected(currentPos - 1, currentPos)) {
- int lineCurrentPos = pdoc->LineFromPosition(currentPos);
- if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != currentPos)) {
- if (pdoc->GetColumn(currentPos) <= pdoc->GetLineIndentation(lineCurrentPos) &&
- pdoc->GetColumn(currentPos) > 0 && pdoc->backspaceUnindents) {
- pdoc->BeginUndoAction();
- int indentation = pdoc->GetLineIndentation(lineCurrentPos);
- int indentationStep = pdoc->IndentSize();
- if (indentation % indentationStep == 0) {
- pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
- } else {
- pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+ if (!sel.IsRectangular())
+ FilterSelections();
+ if (sel.IsRectangular())
+ allowLineStartDeletion = false;
+ UndoGroup ug(pdoc, (sel.Count() > 1) || !sel.Empty());
+ if (sel.Empty()) {
+ for (size_t r=0; r<sel.Count(); r++) {
+ if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
+ if (sel.Range(r).caret.VirtualSpace()) {
+ sel.Range(r).caret.SetVirtualSpace(sel.Range(r).caret.VirtualSpace() - 1);
+ sel.Range(r).anchor.SetVirtualSpace(sel.Range(r).caret.VirtualSpace());
+ } else {
+ int lineCurrentPos = pdoc->LineFromPosition(sel.Range(r).caret.Position());
+ if (allowLineStartDeletion || (pdoc->LineStart(lineCurrentPos) != sel.Range(r).caret.Position())) {
+ if (pdoc->GetColumn(sel.Range(r).caret.Position()) <= pdoc->GetLineIndentation(lineCurrentPos) &&
+ pdoc->GetColumn(sel.Range(r).caret.Position()) > 0 && pdoc->backspaceUnindents) {
+ UndoGroup ugInner(pdoc, !ug.Needed());
+ int indentation = pdoc->GetLineIndentation(lineCurrentPos);
+ int indentationStep = pdoc->IndentSize();
+ if (indentation % indentationStep == 0) {
+ pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
+ } else {
+ pdoc->SetLineIndentation(lineCurrentPos, indentation - (indentation % indentationStep));
+ }
+ // SetEmptySelection
+ sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos),
+ pdoc->GetLineIndentPosition(lineCurrentPos));
+ } else {
+ pdoc->DelCharBack(sel.Range(r).caret.Position());
+ }
}
- SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
- pdoc->EndUndoAction();
- } else {
- pdoc->DelCharBack(currentPos);
}
+ } else {
+ sel.Range(r).ClearVirtualSpace();
}
}
} else {
ClearSelection();
- SetEmptySelection(currentPos);
}
+ sel.RemoveDuplicates();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
}
@@ -3870,12 +4023,6 @@
scn.nmhdr.code = SCN_CHARADDED;
scn.ch = ch;
NotifyParent(scn);
- if (recordingMacro) {
- char txt[2];
- txt[0] = static_cast<char>(ch);
- txt[1] = '\0';
- NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(txt));
- }
}
void Editor::NotifySavePoint(bool isSavePoint) {
@@ -4072,13 +4219,11 @@
} else {
// Move selection and brace highlights
if (mh.modificationType & SC_MOD_INSERTTEXT) {
- currentPos = MovePositionForInsertion(currentPos, mh.position, mh.length);
- anchor = MovePositionForInsertion(anchor, mh.position, mh.length);
+ sel.MovePositions(true, mh.position, mh.length);
braces[0] = MovePositionForInsertion(braces[0], mh.position, mh.length);
braces[1] = MovePositionForInsertion(braces[1], mh.position, mh.length);
} else if (mh.modificationType & SC_MOD_DELETETEXT) {
- currentPos = MovePositionForDeletion(currentPos, mh.position, mh.length);
- anchor = MovePositionForDeletion(anchor, mh.position, mh.length);
+ sel.MovePositions(false, mh.position, mh.length);
braces[0] = MovePositionForDeletion(braces[0], mh.position, mh.length);
braces[1] = MovePositionForDeletion(braces[1], mh.position, mh.length);
}
@@ -4310,11 +4455,11 @@
* If stuttered = true and not already at first/last row, move to first/last row of window.
* If stuttered = true and already at first/last row, scroll as normal.
*/
-void Editor::PageMove(int direction, selTypes sel, bool stuttered) {
+void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) {
int topLineNew, newPos;
// I consider only the caretYSlop, and ignore the caretYPolicy-- is that a problem?
- int currentLine = pdoc->LineFromPosition(currentPos);
+ int currentLine = pdoc->LineFromPosition(sel.MainCaret());
int topStutterLine = topLine + caretYSlop;
int bottomStutterLine =
pdoc->LineFromPosition(PositionFromLocation(
@@ -4330,7 +4475,7 @@
newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * (LinesToScroll() - caretYSlop)));
} else {
- Point pt = LocationFromPosition(currentPos);
+ Point pt = LocationFromPosition(sel.MainCaret());
topLineNew = Platform::Clamp(
topLine + direction * LinesToScroll(), 0, MaxScrollPos());
@@ -4340,39 +4485,29 @@
if (topLineNew != topLine) {
SetTopLine(topLineNew);
- MovePositionTo(newPos, sel);
+ MovePositionTo(SelectionPosition(newPos), selt);
Redraw();
SetVerticalScrollPos();
} else {
- MovePositionTo(newPos, sel);
+ MovePositionTo(SelectionPosition(newPos), selt);
}
}
void Editor::ChangeCaseOfSelection(bool makeUpperCase) {
- pdoc->BeginUndoAction();
- int startCurrent = currentPos;
- int startAnchor = anchor;
- if (selType == selStream) {
- pdoc->ChangeCase(Range(SelectionStart(), SelectionEnd()),
- makeUpperCase);
- SetSelection(startCurrent, startAnchor);
- } else {
- SelectionLineIterator lineIterator(this, false);
- while (lineIterator.Iterate()) {
- pdoc->ChangeCase(
- Range(lineIterator.startPos, lineIterator.endPos),
- makeUpperCase);
- }
- // Would be nicer to keep the rectangular selection but this is complex
- SetEmptySelection(startCurrent);
+ UndoGroup ug(pdoc);
+ for (size_t r=0; r<sel.Count(); r++) {
+ SelectionRange current = sel.Range(r);
+ pdoc->ChangeCase(Range(current.Start().Position(), current.End().Position()),
+ makeUpperCase);
+ // Automatic movement cuts off last character so reset to exactly the same as it was.
+ sel.Range(r) = current;
}
- pdoc->EndUndoAction();
}
void Editor::LineTranspose() {
- int line = pdoc->LineFromPosition(currentPos);
+ int line = pdoc->LineFromPosition(sel.MainCaret());
if (line > 0) {
- pdoc->BeginUndoAction();
+ UndoGroup ug(pdoc);
int startPrev = pdoc->LineStart(line - 1);
int endPrev = pdoc->LineEnd(line - 1);
int start = pdoc->LineStart(line);
@@ -4385,37 +4520,54 @@
pdoc->DeleteChars(startPrev, len1);
pdoc->InsertString(startPrev, line2, len2);
pdoc->InsertString(start - len1 + len2, line1, len1);
- MovePositionTo(start - len1 + len2);
+ MovePositionTo(SelectionPosition(start - len1 + len2));
delete []line1;
delete []line2;
- pdoc->EndUndoAction();
}
}
void Editor::Duplicate(bool forLine) {
- int start = SelectionStart();
- int end = SelectionEnd();
- if (start == end) {
+ if (sel.Empty()) {
forLine = true;
}
+ UndoGroup ug(pdoc, sel.Count() > 1);
+ SelectionPosition last;
+ const char *eol = "";
+ int eolLen = 0;
if (forLine) {
- int line = pdoc->LineFromPosition(currentPos);
- start = pdoc->LineStart(line);
- end = pdoc->LineEnd(line);
+ eol = StringFromEOLMode(pdoc->eolMode);
+ eolLen = istrlen(eol);
}
- char *text = CopyRange(start, end);
- if (forLine) {
- const char *eol = StringFromEOLMode(pdoc->eolMode);
- pdoc->InsertCString(end, eol);
- pdoc->InsertString(end + istrlen(eol), text, end - start);
- } else {
- pdoc->InsertString(end, text, end - start);
+ for (size_t r=0; r<sel.Count(); r++) {
+ SelectionPosition start = sel.Range(r).Start();
+ SelectionPosition end = sel.Range(r).End();
+ if (forLine) {
+ int line = pdoc->LineFromPosition(sel.Range(r).caret.Position());
+ start = SelectionPosition(pdoc->LineStart(line));
+ end = SelectionPosition(pdoc->LineEnd(line));
+ }
+ char *text = CopyRange(start.Position(), end.Position());
+ if (forLine)
+ pdoc->InsertString(end.Position(), eol, eolLen);
+ pdoc->InsertString(end.Position() + eolLen, text, SelectionRange(end, start).Length());
+ delete []text;
}
- delete []text;
+ if (sel.Count() && sel.IsRectangular()) {
+ SelectionPosition last = sel.Last();
+ if (forLine) {
+ int line = pdoc->LineFromPosition(last.Position());
+ last = SelectionPosition(last.Position() + pdoc->LineStart(line+1) - pdoc->LineStart(line));
+ }
+ if (sel.Rectangular().anchor > sel.Rectangular().caret)
+ sel.Rectangular().anchor = last;
+ else
+ sel.Rectangular().caret = last;
+ SetRectangularRange();
+ }
}
void Editor::CancelModes() {
- moveExtendsSelection = false;
+ sel.SetMoveExtends(false);
}
void Editor::NewLine() {
@@ -4426,10 +4578,16 @@
} else if (pdoc->eolMode == SC_EOL_CR) {
eol = "\r";
} // else SC_EOL_LF -> "\n" already set
- if (pdoc->InsertCString(currentPos, eol)) {
- SetEmptySelection(currentPos + istrlen(eol));
+ if (pdoc->InsertCString(sel.MainCaret(), eol)) {
+ SetEmptySelection(sel.MainCaret() + istrlen(eol));
while (*eol) {
NotifyChar(*eol);
+ if (recordingMacro) {
+ char txt[2];
+ txt[0] = *eol;
+ txt[1] = '\0';
+ NotifyMacroRecord(SCI_REPLACESEL, 0, reinterpret_cast<sptr_t>(txt));
+ }
eol++;
}
}
@@ -4440,41 +4598,50 @@
ShowCaretAtCurrentPosition();
}
-void Editor::CursorUpOrDown(int direction, selTypes sel) {
- Point pt = LocationFromPosition(currentPos);
- int lineDoc = pdoc->LineFromPosition(currentPos);
+void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) {
+ SelectionPosition caretToUse = sel.Range(sel.Main()).caret;
+ if (sel.IsRectangular()) {
+ if (selt == Selection::noSel) {
+ caretToUse = (direction > 0) ? sel.Limits().end : sel.Limits().start;
+ } else {
+ caretToUse = sel.Rectangular().caret;
+ }
+ }
+ Point pt = LocationFromPosition(caretToUse);
+ int lineDoc = pdoc->LineFromPosition(caretToUse.Position());
Point ptStartLine = LocationFromPosition(pdoc->LineStart(lineDoc));
int subLine = (pt.y - ptStartLine.y) / vs.lineHeight;
int commentLines = vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0;
- int posNew = PositionFromLocation(
- Point(lastXChosen, pt.y + direction * vs.lineHeight));
+ SelectionPosition posNew = SPositionFromLocation(
+ Point(lastXChosen, pt.y + direction * vs.lineHeight), false, false, UserVirtualSpace());
if ((direction > 0) && (subLine >= (cs.GetHeight(lineDoc) - 1 - commentLines))) {
- posNew = PositionFromLocation(
- Point(lastXChosen, pt.y + (commentLines + 1) * vs.lineHeight));
+ posNew = SPositionFromLocation(
+ Point(lastXChosen, pt.y + (commentLines + 1) * vs.lineHeight), false, false, UserVirtualSpace());
}
if (direction < 0) {
// Line wrapping may lead to a location on the same line, so
// seek back if that is the case.
// There is an equivalent case when moving down which skips
// over a line but as that does not trap the user it is fine.
- Point ptNew = LocationFromPosition(posNew);
- while ((posNew > 0) && (pt.y == ptNew.y)) {
- posNew--;
- ptNew = LocationFromPosition(posNew);
+ Point ptNew = LocationFromPosition(posNew.Position());
+ while ((posNew.Position() > 0) && (pt.y == ptNew.y)) {
+ posNew.Add(- 1);
+ posNew.SetVirtualSpace(0);
+ ptNew = LocationFromPosition(posNew.Position());
}
}
- MovePositionTo(posNew, sel);
+ MovePositionTo(posNew, selt);
}
-void Editor::ParaUpOrDown(int direction, selTypes sel) {
- int lineDoc, savedPos = currentPos;
+void Editor::ParaUpOrDown(int direction, Selection::selTypes selt) {
+ int lineDoc, savedPos = sel.MainCaret();
do {
- MovePositionTo(direction > 0 ? pdoc->ParaDown(currentPos) : pdoc->ParaUp(currentPos), sel);
- lineDoc = pdoc->LineFromPosition(currentPos);
+ MovePositionTo(SelectionPosition(direction > 0 ? pdoc->ParaDown(sel.MainCaret()) : pdoc->ParaUp(sel.MainCaret())), selt);
+ lineDoc = pdoc->LineFromPosition(sel.MainCaret());
if (direction > 0) {
- if (currentPos >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
- if (sel == noSel) {
- MovePositionTo(pdoc->LineEndPosition(savedPos));
+ if (sel.MainCaret() >= pdoc->Length() && !cs.GetVisible(lineDoc)) {
+ if (selt == Selection::noSel) {
+ MovePositionTo(SelectionPosition(pdoc->LineEndPosition(savedPos)));
}
break;
}
@@ -4520,16 +4687,16 @@
CursorUpOrDown(1);
break;
case SCI_LINEDOWNEXTEND:
- CursorUpOrDown(1, selStream);
+ CursorUpOrDown(1, Selection::selStream);
break;
case SCI_LINEDOWNRECTEXTEND:
- CursorUpOrDown(1, selRectangle);
+ CursorUpOrDown(1, Selection::selRectangle);
break;
case SCI_PARADOWN:
ParaUpOrDown(1);
break;
case SCI_PARADOWNEXTEND:
- ParaUpOrDown(1, selStream);
+ ParaUpOrDown(1, Selection::selStream);
break;
case SCI_LINESCROLLDOWN:
ScrollTo(topLine + 1);
@@ -4539,144 +4706,182 @@
CursorUpOrDown(-1);
break;
case SCI_LINEUPEXTEND:
- CursorUpOrDown(-1, selStream);
+ CursorUpOrDown(-1, Selection::selStream);
break;
case SCI_LINEUPRECTEXTEND:
- CursorUpOrDown(-1, selRectangle);
+ CursorUpOrDown(-1, Selection::selRectangle);
break;
case SCI_PARAUP:
ParaUpOrDown(-1);
break;
case SCI_PARAUPEXTEND:
- ParaUpOrDown(-1, selStream);
+ ParaUpOrDown(-1, Selection::selStream);
break;
case SCI_LINESCROLLUP:
ScrollTo(topLine - 1);
MoveCaretInsideView(false);
break;
case SCI_CHARLEFT:
- if (SelectionEmpty() || moveExtendsSelection) {
- MovePositionTo(MovePositionSoVisible(currentPos - 1, -1));
+ if (SelectionEmpty() || sel.MoveExtends()) {
+ if ((sel.Count() == 1) && pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+ SelectionPosition spCaret = sel.RangeMain().caret;
+ spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+ MovePositionTo(spCaret);
+ } else {
+ MovePositionTo(MovePositionSoVisible(
+ SelectionPosition((sel.LimitsForRectangularElseMain().start).Position() - 1), -1));
+ }
} else {
- MovePositionTo(SelectionStart());
+ MovePositionTo(sel.LimitsForRectangularElseMain().start);
}
SetLastXChosen();
break;
case SCI_CHARLEFTEXTEND:
- MovePositionTo(MovePositionSoVisible(currentPos - 1, -1), selStream);
+ if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+ SelectionPosition spCaret = sel.RangeMain().caret;
+ spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+ MovePositionTo(spCaret, Selection::selStream);
+ } else {
+ MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selStream);
+ }
SetLastXChosen();
break;
case SCI_CHARLEFTRECTEXTEND:
- MovePositionTo(MovePositionSoVisible(currentPos - 1, -1), selRectangle);
+ if (pdoc->IsLineEndPosition(sel.MainCaret()) && sel.RangeMain().caret.VirtualSpace()) {
+ SelectionPosition spCaret = sel.RangeMain().caret;
+ spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
+ MovePositionTo(spCaret, Selection::selRectangle);
+ } else {
+ MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1), -1), Selection::selRectangle);
+ }
SetLastXChosen();
break;
case SCI_CHARRIGHT:
- if (SelectionEmpty() || moveExtendsSelection) {
- MovePositionTo(MovePositionSoVisible(currentPos + 1, 1));
+ if (SelectionEmpty() || sel.MoveExtends()) {
+ if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+ SelectionPosition spCaret = sel.RangeMain().caret;
+ spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+ MovePositionTo(spCaret);
+ } else {
+ MovePositionTo(MovePositionSoVisible(
+ SelectionPosition((sel.LimitsForRectangularElseMain().end).Position() + 1), 1));
+ }
} else {
- MovePositionTo(SelectionEnd());
+ MovePositionTo(sel.LimitsForRectangularElseMain().end);
}
SetLastXChosen();
break;
case SCI_CHARRIGHTEXTEND:
- MovePositionTo(MovePositionSoVisible(currentPos + 1, 1), selStream);
+ if ((virtualSpaceOptions & SCVS_USERACCESSIBLE) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+ SelectionPosition spCaret = sel.RangeMain().caret;
+ spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+ MovePositionTo(spCaret, Selection::selStream);
+ } else {
+ MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selStream);
+ }
SetLastXChosen();
break;
case SCI_CHARRIGHTRECTEXTEND:
- MovePositionTo(MovePositionSoVisible(currentPos + 1, 1), selRectangle);
+ if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) && pdoc->IsLineEndPosition(sel.MainCaret())) {
+ SelectionPosition spCaret = sel.RangeMain().caret;
+ spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
+ MovePositionTo(spCaret, Selection::selRectangle);
+ } else {
+ MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1), 1), Selection::selRectangle);
+ }
SetLastXChosen();
break;
case SCI_WORDLEFT:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, -1), -1));
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1));
SetLastXChosen();
break;
case SCI_WORDLEFTEXTEND:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, -1), -1), selStream);
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), -1), -1), Selection::selStream);
SetLastXChosen();
break;
case SCI_WORDRIGHT:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, 1), 1));
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1));
SetLastXChosen();
break;
case SCI_WORDRIGHTEXTEND:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(currentPos, 1), 1), selStream);
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordStart(sel.MainCaret(), 1), 1), Selection::selStream);
SetLastXChosen();
break;
case SCI_WORDLEFTEND:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, -1), -1));
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1));
SetLastXChosen();
break;
case SCI_WORDLEFTENDEXTEND:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, -1), -1), selStream);
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), -1), -1), Selection::selStream);
SetLastXChosen();
break;
case SCI_WORDRIGHTEND:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, 1), 1));
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1));
SetLastXChosen();
break;
case SCI_WORDRIGHTENDEXTEND:
- MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(currentPos, 1), 1), selStream);
+ MovePositionTo(MovePositionSoVisible(pdoc->NextWordEnd(sel.MainCaret(), 1), 1), Selection::selStream);
SetLastXChosen();
break;
case SCI_HOME:
- MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)));
+ MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
SetLastXChosen();
break;
case SCI_HOMEEXTEND:
- MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)), selStream);
+ MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selStream);
SetLastXChosen();
break;
case SCI_HOMERECTEXTEND:
- MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(currentPos)), selRectangle);
+ MovePositionTo(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())), Selection::selRectangle);
SetLastXChosen();
break;
case SCI_LINEEND:
- MovePositionTo(pdoc->LineEndPosition(currentPos));
+ MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()));
SetLastXChosen();
break;
case SCI_LINEENDEXTEND:
- MovePositionTo(pdoc->LineEndPosition(currentPos), selStream);
+ MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selStream);
SetLastXChosen();
break;
case SCI_LINEENDRECTEXTEND:
- MovePositionTo(pdoc->LineEndPosition(currentPos), selRectangle);
+ MovePositionTo(pdoc->LineEndPosition(sel.MainCaret()), Selection::selRectangle);
SetLastXChosen();
break;
case SCI_HOMEWRAP: {
- int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
- if (currentPos <= homePos)
- homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
+ SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+ if (sel.RangeMain().caret <= homePos)
+ homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
MovePositionTo(homePos);
SetLastXChosen();
}
break;
case SCI_HOMEWRAPEXTEND: {
- int homePos = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
- if (currentPos <= homePos)
- homePos = pdoc->LineStart(pdoc->LineFromPosition(currentPos));
- MovePositionTo(homePos, selStream);
+ SelectionPosition homePos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+ if (sel.RangeMain().caret <= homePos)
+ homePos = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(sel.MainCaret())));
+ MovePositionTo(homePos, Selection::selStream);
SetLastXChosen();
}
break;
case SCI_LINEENDWRAP: {
- int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
- int realEndPos = pdoc->LineEndPosition(currentPos);
+ SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1);
+ SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret()));
if (endPos > realEndPos // if moved past visible EOLs
- || currentPos >= endPos) // if at end of display line already
+ || sel.RangeMain().caret >= endPos) // if at end of display line already
endPos = realEndPos;
MovePositionTo(endPos);
SetLastXChosen();
}
break;
case SCI_LINEENDWRAPEXTEND: {
- int endPos = MovePositionSoVisible(StartEndDisplayLine(currentPos, false), 1);
- int realEndPos = pdoc->LineEndPosition(currentPos);
+ SelectionPosition endPos = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), false), 1);
+ SelectionPosition realEndPos = SelectionPosition(pdoc->LineEndPosition(sel.MainCaret()));
if (endPos > realEndPos // if moved past visible EOLs
- || currentPos >= endPos) // if at end of display line already
+ || sel.RangeMain().caret >= endPos) // if at end of display line already
endPos = realEndPos;
- MovePositionTo(endPos, selStream);
+ MovePositionTo(endPos, Selection::selStream);
SetLastXChosen();
}
break;
@@ -4685,7 +4890,7 @@
SetLastXChosen();
break;
case SCI_DOCUMENTSTARTEXTEND:
- MovePositionTo(0, selStream);
+ MovePositionTo(0, Selection::selStream);
SetLastXChosen();
break;
case SCI_DOCUMENTEND:
@@ -4693,38 +4898,38 @@
SetLastXChosen();
break;
case SCI_DOCUMENTENDEXTEND:
- MovePositionTo(pdoc->Length(), selStream);
+ MovePositionTo(pdoc->Length(), Selection::selStream);
SetLastXChosen();
break;
case SCI_STUTTEREDPAGEUP:
- PageMove(-1, noSel, true);
+ PageMove(-1, Selection::noSel, true);
break;
case SCI_STUTTEREDPAGEUPEXTEND:
- PageMove(-1, selStream, true);
+ PageMove(-1, Selection::selStream, true);
break;
case SCI_STUTTEREDPAGEDOWN:
- PageMove(1, noSel, true);
+ PageMove(1, Selection::noSel, true);
break;
case SCI_STUTTEREDPAGEDOWNEXTEND:
- PageMove(1, selStream, true);
+ PageMove(1, Selection::selStream, true);
break;
case SCI_PAGEUP:
PageMove(-1);
break;
case SCI_PAGEUPEXTEND:
- PageMove(-1, selStream);
+ PageMove(-1, Selection::selStream);
break;
case SCI_PAGEUPRECTEXTEND:
- PageMove(-1, selRectangle);
+ PageMove(-1, Selection::selRectangle);
break;
case SCI_PAGEDOWN:
PageMove(1);
break;
case SCI_PAGEDOWNEXTEND:
- PageMove(1, selStream);
+ PageMove(1, Selection::selStream);
break;
case SCI_PAGEDOWNRECTEXTEND:
- PageMove(1, selRectangle);
+ PageMove(1, Selection::selRectangle);
break;
case SCI_EDITTOGGLEOVERTYPE:
inOverstrike = !inOverstrike;
@@ -4773,21 +4978,21 @@
AddChar('\f');
break;
case SCI_VCHOME:
- MovePositionTo(pdoc->VCHomePosition(currentPos));
+ MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()));
SetLastXChosen();
break;
case SCI_VCHOMEEXTEND:
- MovePositionTo(pdoc->VCHomePosition(currentPos), selStream);
+ MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selStream);
SetLastXChosen();
break;
case SCI_VCHOMERECTEXTEND:
- MovePositionTo(pdoc->VCHomePosition(currentPos), selRectangle);
+ MovePositionTo(pdoc->VCHomePosition(sel.MainCaret()), Selection::selRectangle);
SetLastXChosen();
break;
case SCI_VCHOMEWRAP: {
- int homePos = pdoc->VCHomePosition(currentPos);
- int viewLineStart = MovePositionSoVisible(StartEndDisplayLine(currentPos, true), -1);
- if ((viewLineStart < currentPos) && (viewLineStart > homePos))
+ SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret()));
+ SelectionPosition viewLineStart = MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+ if ((viewLineStart < sel.RangeMain().caret) && (viewLineStart > homePos))
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Commits
mailing list