import "GoToDialog"
import "Array"
+char * strchrmax(const char * s, int c, int max)
+{
+ int i;
+ char ch;
+ for(i = 0; i < max && (ch = s[i]); i++)
+ if(ch == c)
+ return (char *)s + i;
+ return null;
+}
+
public class SyntaxColorScheme
{
public:
bool noCaret:1, noSelect:1, tabKey:1, useTab:1, tabSel:1, allCaps:1, syntax:1, wrap:1;
// Syntax States
- bool inMultiLineComment:1, inPrep:1, escaped:1, continuedSingleLineComment:1;
+ bool inMultiLineComment:1, inPrep:1, escaped:1, continuedSingleLineComment:1, wasInMultiLine:1, continuedString:1, continuedQuotes:1;
bool recomputeSyntax:1;
bool cursorFollowsView:1;
-
+
// bool lineNumbers:1;
bool autoSize:1;
};
delete ((ArrayImpl)this).array;
}
-public:
+public:
Class type;
property uint size
{
{
if(((ArrayImpl)this).array)
{
- if(value == size)
+ if(value == size)
return;
((ArrayImpl)this).array = renew0 ((ArrayImpl)this).array byte[type.typeSize * value];
}
{
public:
subclass(UndoAction) type;
+ bool continued;
+
virtual void Undo(void * data) { type.Undo(this, data); }
virtual void Redo(void * data) { type.Redo(this, data); }
#ifdef _DEBUG
void * data;
int dontRecord;
bool insideRedo;
+ bool recordAsOne;
+ bool firstEvent;
dontRecord = 0;
{
actions.Free();
}
-
+
void Undo()
{
- dontRecord++;
- if(curAction > 0)
+ bool continued = true;
+ while(curAction > 0 && continued)
{
UndoAction action = actions[--curAction];
+ dontRecord++;
+
#ifdef _DEBUG
/*Print("Undoing: ");
action.Print(data);*/
#endif
action.Undo(data);
+ dontRecord--;
+
+ continued = curAction > 0 && actions[curAction-1].continued;
}
- dontRecord--;
}
void Redo()
{
- dontRecord++;
- insideRedo = true;
- if(curAction < count)
+ bool continued = true;
+ while(curAction < count && continued)
{
UndoAction action = actions[curAction];
+ continued = action.continued;
+ dontRecord++;
+ insideRedo = true;
+
curAction++;
#ifdef _DEBUG
/*Print("Redoing: ");
action.Print(data);*/
#endif
action.Redo(data);
+
+ insideRedo = false;
+ dontRecord--;
}
- insideRedo = false;
- dontRecord--;
}
void Record(UndoAction action)
/*Print("Recording: ");
action.Print(data);*/
#endif
+ if(recordAsOne)
+ {
+ if(!firstEvent && count > 0)
+ actions[count-1].continued = true;
+ firstEvent = false;
+ }
actions[count++] = action;
curAction = count;
else
delete action;
}
+
+ void Clear()
+ {
+ actions.Free();
+ actions.size = 8;
+ count = 0;
+ curAction = 0;
+ firstEvent = true;
+ }
};
static class AddCharAction : UndoAction
{
int y, x;
unichar ch;
- int addedSpaces, addedTabs;
+ int addedSpaces, addedTabs, xAdjustment;
type = class(AddCharAction);
void Undo(EditBox editBox)
{
- editBox.GoToPosition(null, (ch == '\n') ? (y + 1) : y, (ch == '\n') ? 0 : (x + 1));
+ editBox.GoToPosition(null, (ch == '\n') ? (y + 1) : y, (ch == '\n') ? 0 : (x + 1) - xAdjustment);
editBox.BackSpace();
if(addedTabs || addedSpaces)
- editBox.DelCh(editBox.line, y, x - (addedSpaces + addedTabs), editBox.line, y, x, false);
+ {
+ editBox.DelCh(editBox.line, y, x - xAdjustment - (addedSpaces + addedTabs), editBox.line, y, x - xAdjustment, false);
+ editBox.GoToPosition(editBox.line, y, x);
+ }
editBox.UpdateDirty();
}
{
int y1, x1, y2, x2;
char * string;
- int addedSpaces, addedTabs;
+ int addedSpaces, addedTabs, xAdjustment;
type = class(AddTextAction);
#ifdef _DEBUG
{
int y1, x1, y2, x2;
char * string;
- bool placeAfter;
+ bool placeAfter, noHighlight;
int addedSpaces;
type = class(DelTextAction);
#ifdef _DEBUG
void Print(EditBox editBox)
{
- PrintLn("DelText: y1 = ", y1, "x1 = ", x1, ", y2 = ", y2, ", x2 = ", x2, ", string = ", string, ", addedSpaces = ", addedSpaces, ", placeAfter = ", placeAfter);
+ PrintLn("DelText: y1 = ", y1, "x1 = ", x1, ", y2 = ", y2, ", x2 = ", x2, ", string = ", string, ", addedSpaces = ", addedSpaces, ", placeAfter = ", placeAfter);
}
#endif
void Undo(EditBox editBox)
if(!placeAfter)
{
editBox.GoToPosition(null, y1, x1);
- editBox.selY = y2;
- editBox.selX = x2;
+ if(!noHighlight)
+ {
+ editBox.selY = y2;
+ editBox.selX = x2;
+ }
{ int c; editBox.selLine = editBox.lines.first; for(c = 0; c < editBox.selY && editBox.selLine; c++, editBox.selLine = editBox.selLine.next); }
//editBox.SetViewToCursor(true);
editBox.DelCh(editBox.line, y1, x1 - addedSpaces, editBox.line, y1, x1, false);
}
else
- {
- editBox.selY = y1;
- editBox.selX = x1;
- { int c; editBox.selLine = editBox.lines.first; for(c = 0; c < editBox.selY && editBox.selLine; c++, editBox.selLine = editBox.selLine.next); }
+ {
+ if(!noHighlight)
+ {
+ editBox.selY = y1;
+ editBox.selX = x1;
+ }
+ { int c; editBox.selLine = editBox.lines.first; for(c = 0; c < editBox.selY && editBox.selLine; c++, editBox.selLine = editBox.selLine.next); }
//editBox.SetViewToCursor(true);
if(addedSpaces)
char * oldString;
char * newString;
bool placeAfter;
- int addedSpaces, addedTabs;
+ int addedSpaces, addedTabs, xAdjustment;
type = class(ReplaceTextAction);
#ifdef _DEBUG
void Print(EditBox editBox)
{
- PrintLn("ReplaceText: y1 = ", y1, "x1 = ", x1, ", y2 = ", y2, ", x2 = ", x2, ", y3 = ", y3, ", x3 = ", x3, ", oldString = ", oldString, ", newString = ", newString, ", addedSpaces = ", addedSpaces, ", addedTabs = ", addedTabs, ", placeAfter = ", placeAfter);
+ PrintLn("ReplaceText: y1 = ", y1, "x1 = ", x1, ", y2 = ", y2, ", x2 = ", x2, ", y3 = ", y3, ", x3 = ", x3, ", oldString = ", oldString, ", newString = ", newString, ", addedSpaces = ", addedSpaces, ", addedTabs = ", addedTabs, ", placeAfter = ", placeAfter);
}
#endif
void Undo(EditBox editBox)
/*
static class MoveTextAction : UndoAction
{
- int fy1, fx1, fy2, fx2;
+ int fy1, fx1, fy2, fx2;
int ty, tx;
type = class(MoveTextAction);
int length;
EditBox editBox;
public:
- property char * text
+ property const char * text
{
set
{
{
char * buffer;
int newSize;
-
+
// Adds '\0' byte
count = count+1;
if(y > end.y)
y -= end.y - start.y;
// Location is the last touched line
- else
+ else
{
if(x >= end.x)
{
for(c = 0, line = start.line; c<numLines; c++)
line = line.next;
y += numLines;
- //x += numLines ? end.x : (end.x - start.x);
+ //x += numLines ? end.x : (end.x - start.x);
x += end.x - start.x;
}
}
public enum EditBoxFindResult { notFound, found, wrapped };
-static char * keyWords1[] =
+static const char * keyWords1[] =
{
// C
"return","break","continue","default","switch","case","if","else","for","while", "do","long","short",
- "void", "char","int","float","double","unsigned","static", "extern", "struct", "union", "typedef","enum",
+ "void", "char","int","float","double","signed","unsigned","static", "extern", "struct", "union", "typedef","enum",
"const", "sizeof",
"#include", "#define", "#pragma", "#if", "#else", "#elif", "#ifdef", "#ifndef", "#endif", "#undef", "#line",
"__attribute__", "__stdcall", "_stdcall",
"__declspec", "goto",
"inline", "__inline__", "_inline", "__inline", "__typeof","__extension__",
"asm", "__asm", "_asm", "volatile", "#cpu", "__stdcall__",
+ "__restrict__", "__restrict", "restrict",
// eC
"class", "private", "public",
null
};
-static char * keyWords2[] =
+static const char * keyWords2[] =
{
- "defined", "warning", null
+ "defined", "warning",
+ "include", "pragma", "elif", "ifdef", "ifndef", "endif", "undef", "line",
+ null
};
-static char ** keyWords[] = { keyWords1, keyWords2 };
+static const char ** keyWords[] = { keyWords1, keyWords2 };
#define NUM_KEYWORD_GROUPS (sizeof(keyWords) / sizeof(char **))
//static int * keyLen[NUM_KEYWORD_GROUPS];
static int keyLen[NUM_KEYWORD_GROUPS][sizeof(keyWords1)];
property bool textVertScroll { property_category $"Behavior" set { style.vScroll = value; } get { return style.vScroll; } };
property bool readOnly
{
- property_category $"Behavior"
+ property_category $"Behavior"
set
{
style.readOnly = value;
property EditLine firstLine { get { return lines.first; } }; // Change these to a List<EditLine>... (this.lines[10].text)
property EditLine lastLine { get { return lines.last; } };
property EditLine line { get { return this.line; } }; // TODO: Add Set this.line = this.lines[10]
- property char * contents
+ property const char * contents
{
- property_category $"Data"
+ property_category $"Data"
set
{
if(this)
{
+ undoBuffer.Clear();
+
undoBuffer.dontRecord++;
Deselect();
DelCh(this.lines.first, 0, 0, this.lines.last, this.lineCount-1, ((EditLine)(this.lines.last)).count, true);
/* Can't implement this right now because of memory leak... Need string reference counting...
if(style.multiLine)
{
-
+
EditLine line;
int len = 0;
char * buffer = null;
if(style.multiLine)
{
-
+
EditLine line;
int len = 0;
len += lineLen;
if(line.next) buffer[len++] = '\n';
}
- buffer[len] = '\0';
+ buffer[len] = '\0';
}
return buffer;
}
return null;
}
- void SetLineText(char * text)
+ void SetLineText(const char * text)
{
if(this)
{
property Color selectionColor { set { selectionColor = value; } get { return selectionColor; } isset { return selectionColor ? true : false; } };
property Color selectionText { set { selectionText = value; } get { return selectionText; } isset { return selectionText ? true : false; } };
property SyntaxColorScheme syntaxColorScheme { set { delete colorScheme; colorScheme = value; incref colorScheme; } }
+ property bool recordUndoEvent { set { undoBuffer.recordAsOne = value; undoBuffer.firstEvent = true; } get { return undoBuffer.recordAsOne; } };
// selectionStart.line, selectionStart.column (With Set)
// selection.line1, selection.line2, selection.column1, selection.column2 (Read only)
int lineCount;
// Font Space size
Size space, large;
-
+
// Position of Caret (Not necessarily displayed position)
int x,y;
int col;
// ViewX is x offset in pixels, ViewY is y offset in lines
int viewX, viewY;
// viewLine is first displayed line
- EditLine viewLine;
+ EditLine viewLine;
// start and end of area to redraw
int startY, endY;
bool modified;
- void (* FontExtent)(Display display, Font font, char * text, int len, int * width, int * height);
+ void (* FontExtent)(Display display, Font font, const char * text, int len, int * width, int * height, int prevGlyph, int * rPrevGlyph, int * overHang);
Color backColor;
bool rightButtonDown;
MenuItem itemEditPaste
{
editMenu, $"Paste\tCtrl+V", p;
-
+
bool NotifySelect(MenuItem item, Modifiers mods)
{
if(!(style.readOnly))
{
ReplaceDialog dialog
{
- master = master,
+ master = master,
isModal = true,
searchString = searchString,
replaceString = replaceString,
void NotifyDestroyed(Window window, DialogResult result)
{
ReplaceDialog dialog = (ReplaceDialog)window;
- char * replace = dialog.replaceString;
+ const char * replace = dialog.replaceString;
if(replace)
strcpy(replaceString, replace);
strcpy(searchString, dialog.searchString);
EditBox()
{
static bool syntaxInit = false;
- if(!syntaxInit)
+ if(!syntaxInit)
{
int g,c;
syntaxInit = true;
colorScheme.keywordColors = [ blue, blue ];
}
- FontExtent = Display::FontExtent;
+ FontExtent = Display::FontExtent2;
font = fontObject;
- lines.offset = (uint)&((EditLine)0).prev;
+ lines.offset = (uint)(uintptr)&((EditLine)0).prev;
style = EditBoxBits { hScroll = true };
maxLineSize = MAXINT;
tabSize = 3;
-
+
overwrite = false;
mouseSelect = this.mouseMove = false;
line = null;
col = 0;
y = -1;
line = selLine = null;
- viewX = 0;
+ viewX = 0;
viewY = 0;
maxLength = 0;
maxLine = null;
lines.Free(EditLine::Free);
}
- void FlushBuffer(Surface surface, EditLine line, int wc, int * renderStart, int * x, int y, int numSpaces, Box box)
+ void FlushBuffer(Surface surface, EditLine line, int wc, int * renderStart, int * x, int y, int * previousGlyph, int * oh, int numSpaces, bool drawSpaces, Box box)
{
int count = wc - *renderStart;
if(count)
if(!numSpaces)
{
+ int coh;
//FontExtent(display, font, line.buffer + *renderStart, count, &w, null);
surface.TextFont(font);
- surface.TextExtent(line.buffer + *renderStart, count, &w, null);
- if(*x + w + XOFFSET > 0)
- surface.WriteText(XOFFSET + *x,y, line.buffer + *renderStart, count);
+ surface.TextExtent2(line.buffer + *renderStart, count, &w, null, *previousGlyph, null, &coh);
+
+ if(*x + w + coh + XOFFSET > 0)
+ {
+ surface.WriteText2(XOFFSET + *x,y, line.buffer + *renderStart, count, *previousGlyph, previousGlyph);
+ *oh = coh;
+ //surface.WriteText(XOFFSET + *x,y, line.buffer + *renderStart, count);
+ }
*x += w;
}
else
{
w = numSpaces; // * space.w;
- if(*x + w + XOFFSET > 0 && surface.GetTextOpacity())
- surface.Area(XOFFSET + *x - 1, y, XOFFSET + *x + w, y + space.h-1);
+ if(*x + w + XOFFSET > 0 && (drawSpaces))
+ surface.Area(XOFFSET + *x /*- 1*/ + *oh, y, XOFFSET + *x + w, y + space.h-1);
// WHATS UP WITH THIS... surface.Area(XOFFSET + *x, y, XOFFSET + *x + w, y + space.h-1);
*x += w;
- }
+ }
}
*renderStart = wc;
}
}
- int CheckColors(EditLine line, int wc, bool selection, int selX, int editX, bool *selected,
- Color selectionForeground, Color selectionBackground, Color textColor, Color *foreground, Color *background, bool *opacity, bool *overwrite)
+ bool CheckColors(EditLine line, int wc, bool selection, int selX, int editX, bool *selected,
+ Color selectionForeground, Color selectionBackground, Color textColor, Color *foreground, Color *background, bool *opacity, int *overwrite)
{
bool flush = false;
if((style.stuckCaret && wc == line.count && !line.next) ||
(!mouseMove && line == this.line && wc == editX))
{
- *overwrite = true;
+ *overwrite = 1;
flush = true;
}
}
if(style.syntax)
{
bool inMultiLineComment = reset ? false : style.inMultiLineComment;
+ bool wasInMultiLine = reset ? false : style.wasInMultiLine;
bool inString = false;
bool inQuotes = false;
bool inPrep = reset ? false : style.inPrep;
bool inSingleLineComment = false;
bool escaped = reset ? false : style.escaped;
bool continuedSingleLineComment = reset ? false : style.continuedSingleLineComment;
+ bool continuedString = reset ? false : style.continuedString;
+ bool continuedQuotes = reset ? false : style.continuedQuotes;
EditLine line = reset ? lines.first : firstLine;
// int maxBackUp = 1000, c;
if(!escaped) inPrep = false;
inSingleLineComment = continuedSingleLineComment;
escaped = false;
- inString = false;
- inQuotes = false;
+ inString = continuedString;
+ inQuotes = continuedQuotes;
firstWord = true;
for(c = 0; (ch = text[c]); c++)
{
bool wasEscaped = escaped;
bool backLastWasStar = lastWasStar;
+ bool backWasInMultiLine = wasInMultiLine;
escaped = false;
lastWasStar = false;
+ wasInMultiLine = inMultiLineComment;
if(ch == '/')
{
if(!inSingleLineComment && !inMultiLineComment && !inQuotes && !inString)
}
else if(ch == '*')
{
- if(!c || text[c-1] != '/') lastWasStar = true;
+ if(backWasInMultiLine) lastWasStar = true;
}
else if(ch == '\"' && !inSingleLineComment && !inMultiLineComment && !inQuotes)
{
else if(ch != ' ' && ch != '\t')
firstWord = false;
}
- continuedSingleLineComment = inSingleLineComment && (line.count && line.text[line.count - 1] == '\\');
+ if(line.count && line.text[line.count - 1] == '\\')
+ {
+ continuedSingleLineComment = inSingleLineComment;
+ continuedString = inString;
+ continuedQuotes = inQuotes;
+ }
+ else
+ {
+ continuedSingleLineComment = false;
+ continuedString = false;
+ continuedQuotes = false;
+ }
}
-
+
style.continuedSingleLineComment = continuedSingleLineComment;
+ style.continuedString = continuedString;
+ style.continuedQuotes = continuedQuotes;
style.inMultiLineComment = inMultiLineComment;
+ style.wasInMultiLine = wasInMultiLine;
style.inPrep = inPrep;
style.escaped = escaped;
}
}
-
+
/*void OnDrawOverChildren(Surface surface)
{
if(style.lineNumbers)
else
surface.SetBackground(Color{230, 230, 230});
surface.textOpacity = true;
-
+
sprintf(lineText,"%5u ", currentLineNumber % 100000);
if(currentLineNumber > this.lineCount)
surface.WriteText(0,i*space.h+1," ",6);
else
surface.WriteText(0,i*space.h+1,lineText,6);
-
+
currentLineNumber++;
}
}
}*/
+ static inline int countTabsExtraSpaces(char * buffer, int tabSize, int start, int end)
+ {
+ // TODO: Handle tabs position properly with UTF-8 (and everywhere else)
+ int p = 0, i, extra = 0;
+ for(i = 0; i < end; i++)
+ {
+ if(buffer[i] == '\t')
+ {
+ int t = tabSize - (p % tabSize);
+ p += t;
+ if(i >= start)
+ extra += t-1;
+ }
+ else
+ p++;
+ }
+ return extra;
+ }
+
void OnRedraw(Surface surface)
{
EditLine line;
Color textColor;
Box box;
int maxW = clientSize.w;
-
+
Color foreground, background;
bool opacity;
// Overwrite Caret Stuff
- bool overWrite = false;
- int overWriteX, overWriteY;
- byte overWriteCh;
+ int overWrite = 0;
+ int overWriteX = 0, overWriteY = 0;
+ char overWriteCh;
// ****** SYNTAX STATES ******
bool inMultiLineComment = style.inMultiLineComment;
bool inSingleLineComment = false;
bool escaped = style.escaped;
bool continuedSingleLineComment = style.continuedSingleLineComment;
+ bool continuedString = style.continuedString;
+ bool continuedQuotes = style.continuedQuotes;
+ bool wasInMultiLine = style.wasInMultiLine;
// ****** ************* ******
+ // For drawing selection background
+ EditLine selStartLine = this.y < this.selY ? this.line : this.selLine;
+ EditLine selEndLine = this.y < this.selY ? this.selLine : this.line;
+ int selStartX = this.y < this.selY || (this.y == this.selY && this.x < this.selX) ? this.x : this.selX;
+ int selEndX = this.y > this.selY || (this.y == this.selY && this.x > this.selX) ? this.x : this.selX;
+ ///////////////////////////////////
+
if(!isEnabled)
defaultTextColor = Color { 85, 85, 85 };
textColor = defaultTextColor;
if(
- Abs(selectionBackground.r - property::background.r) +
- Abs(selectionBackground.g - property::background.g) +
+ Abs(selectionBackground.r - property::background.r) +
+ Abs(selectionBackground.g - property::background.g) +
Abs(selectionBackground.b - property::background.b) < 92)
{
selectionBackground = formColor;
selX = this.selX;
}
else
- {
+ {
editX = Min(this.x,this.line.count);
selX = Min(this.selX,this.selLine.count);
}
*/
surface.SetForeground(foreground);
surface.SetBackground(background);
- surface.TextOpacity(opacity);
+ surface.TextOpacity(false);
surface.GetBox(box);
int start = 0;
Color newTextColor = textColor = defaultTextColor;
bool lineComplete = false;
-
+ int overHang = 0;
// ****** SYNTAX HIGHLIGHTING ******
bool lastWasStar = false;
+ bool trailingSpace = false;
bool firstWord = true;
if(!escaped) inPrep = false;
inSingleLineComment = continuedSingleLineComment;
escaped = false;
- inString = false;
- inQuotes = false;
+ inString = continuedString;
+ inQuotes = continuedQuotes;
// *********************************
/* === DEBUGGING TOOL FOR MAXLINE ===
surface.SetBackground(selected ? SELECTION_COLOR|0xFF000000 : BLACK|0xFF000000);
}
*/
-
+
+ // Draw Selection Background all at once here
+ if(selected || line == this.line || line == this.selLine)
+ {
+ int sx = XOFFSET + x, sy = y;
+ int tw, th;
+ int oh = 0;
+ char * buffer = line.buffer;
+ if(line != this.line && line != this.selLine)
+ {
+ if(style.freeCaret)
+ {
+ tw = clientSize.w - sx;
+ th = space.h;
+ }
+ else
+ {
+ surface.TextExtent2(buffer, line.count, &tw, &th, 0, null, &oh);
+ tw += countTabsExtraSpaces(buffer, tabSize, 0, line.count) * space.w;
+ }
+ }
+ else if(line == selStartLine)
+ {
+ int prevGlyph = 0;
+ int start = Min(line.count, selStartX);
+ int end = Min(line.count, selEndX);
+ surface.TextExtent2(buffer, start, &tw, &th, 0, &prevGlyph, null);
+ sx += tw;
+ sx += countTabsExtraSpaces(buffer, tabSize, 0, start) * space.w;
+ if(selStartX > start) sx += space.w * (selStartX - start);
+ if(style.freeCaret && line != selEndLine)
+ {
+ tw = clientSize.w - sx;
+ th = space.h;
+ }
+ else if(line != selEndLine)
+ {
+ surface.TextExtent2(buffer + start, line.count - start, &tw, &th, prevGlyph, null, &oh);
+ tw += countTabsExtraSpaces(buffer, tabSize, start, line.count) * space.w;
+ }
+ else
+ {
+ surface.TextExtent2(buffer + start, end - start, &tw, &th, prevGlyph, null, &oh);
+ tw += countTabsExtraSpaces(buffer, tabSize, start, end) * space.w;
+ end = Max(end, selStartX);
+ if(selEndX > end) { tw += space.w * (selEndX - end); th = space.h; }
+ }
+ }
+ else if(line == selEndLine)
+ {
+ int end = Min(line.count, selEndX);
+ surface.TextExtent2(buffer, end, &tw, &th, 0, null, &oh);
+ tw += countTabsExtraSpaces(buffer, tabSize, 0, end) * space.w;
+ if(selEndX - end) { tw += space.w * (selEndX - end); th = space.h; }
+ }
+ tw += oh;
+ surface.Area(sx, sy, sx + tw-1, sy + th-1);
+ }
+
if(line == this.selLine && line == this.line)
{
end = Max(line.count, this.x);
y += space.h;
lineComplete = false;
}
-
+
textColor = newTextColor;
if(!selected)
{
unichar bf = (wordLen == 1) ? line.buffer[c-1] : 0;
//if(ch == ' ' || ch == '\t' || (wordLen && (ch == '(' || ch == ')' || ch == ';' || ch == ':')) || (wordLen == 1 && line.buffer[c-1] == '('))
if(CharMatchCategories(ch, separators) || /*ch == ' ' ||*/ ch == '\t' ||
- (wordLen && !CharMatchCategories(ch, numbers|letters|marks|connector) && ch != '#' /*&& ch != '_'*/) ||
+ (wordLen && !CharMatchCategories(ch, numbers|letters|marks|connector) && ch != '#' /*&& ch != '_'*/) ||
(bf && !CharMatchCategories(bf, numbers|letters|separators|marks|connector) && bf != '#' && bf != '\t' /*&& bf != '_' && bf != ' '*/))
break;
wordLen++;
+ trailingSpace = false;
}
if(!wordLen)
{
-
+
for(; c<line.count; c++)
{
unichar ch = line.buffer[c];
if(ch == '\t' || ch == ' ')
{
cantHaveWords = true;
+ if(ch == ' ' && c == line.count-1)
+ trailingSpace = true;
if(bufferLen)
break;
}
bool backInQuotes = inQuotes;
bool backInPrep = inPrep;
bool backInSingleLineComment = inSingleLineComment;
+ bool backWasInMultiLine = wasInMultiLine;
char * word = line.buffer + c - wordLen;
int g,ccc;
escaped = false;
lastWasStar = false;
+ wasInMultiLine = inMultiLineComment;
+
// Determine Syntax Highlighting
newTextColor = defaultTextColor;
if(style.syntax)
}
else if(wordLen == 1 && word[0] == '*')
{
- if(c < 2 || word[-1] != '/')
+ if(backWasInMultiLine)
lastWasStar = true;
}
else if(!inSingleLineComment && !inMultiLineComment && !inQuotes && wordLen == 1 && word[0] == '\"')
if(!wasEscaped)
escaped = true;
}
- else if(!inQuotes && !inString && !inMultiLineComment && !inSingleLineComment && (isdigit(word[0]) || (word[0] == '.' && isdigit(word[1]))))
+ else if(x < box.right && !inQuotes && !inString && !inMultiLineComment && !inSingleLineComment && (isdigit(word[0]) || (word[0] == '.' && isdigit(word[1]))))
{
- char * dot = strchr(word, '.');
+ char * dot = word[wordLen] == '.' ? word + wordLen : (word[0] == '.' && (word == line.buffer || word[-1] == '-' || isspace(word[-1])) ? word : null);
+ bool isReal = dot != null;
char * s = null;
if(dot)
- strtod((dot == word + wordLen) ? (dot+1) : word, &s);
+ isReal = true;
+ else
+ {
+ char * exponent;
+ bool isHex = (word[0] == '0' && (word[1] == 'x' || word[1] == 'X'));
+ if(isHex)
+ {
+ exponent = strchrmax(word, 'p', wordLen);
+ if(!exponent) exponent = strchrmax(word, 'P', wordLen);
+ }
+ else
+ {
+ exponent = strchrmax(word, 'e', wordLen);
+ if(!exponent) exponent = strchrmax(word, 'E', wordLen);
+ }
+ isReal = exponent != null;
+ }
+ if(isReal)
+ strtod(word, &s); // strtod() seems to break on hex floats (e.g. 0x23e3p12, 0x1.fp3)
else
strtol(word, &s, 0);
if(s && s != word)
{
- if((dot && *s == 'f' && !isalnum(s[1]) && s[1] != '_') || (!isalpha(*s) && *s != '_'))
+ // Check suffixes
+ char ch;
+ int i;
+ int gotF = 0, gotL = 0, gotU = 0, gotI = 0;
+ bool valid = true;
+
+ for(i = 0; valid && i < 5 && (ch = s[i]) && (isalnum(ch) || ch == '_'); i++)
+ {
+ switch(ch)
+ {
+ case 'f': case 'F': gotF++; if(gotF > 1 || !isReal) valid = false; break;
+ case 'l': case 'L':
+ gotL++;
+ if(gotL > 2 || (isReal && (gotL == 2 || gotF)) || (gotL == 2 && (s[i-1] != ch)))
+ valid = false;
+ break;
+ case 'u': case 'U': gotU++; if(gotU > 1 || isReal) valid = false; break;
+ case 'i': case 'I': case 'j': case 'J': gotI++; if(gotI > 1) valid = false; break;
+ default: valid = false;
+ }
+ }
+
+ // Don't highlight numbers with too many decimal points
+ if(s[0] == '.' && isdigit(s[1]))
+ {
+ int newWordLen;
+ while(s[0] == '.' && isdigit(s[1]))
+ {
+ int newWordLen = s - word;
+ c += newWordLen - wordLen;
+ wordLen = newWordLen;
+ strtod(s, &s);
+ }
+ newWordLen = s - word;
+ c += newWordLen - wordLen;
+ wordLen = newWordLen;
+ }
+ else if(valid)
{
- int newWordLen = s + ((*s == 'f') ? 1 : 0) - word;
+ int newWordLen = s + i - word;
newTextColor = colorScheme.numberColor;
c += newWordLen - wordLen;
wordLen = newWordLen;
}
- else if(dot && dot > word && (isalpha(dot[1]) || dot[1] == '_'))
+ else if(dot && dot > word && dot < s)
newTextColor = colorScheme.numberColor;
}
}
if(firstWord)
{
inPrep = true;
- newTextColor = colorScheme.preprocessorColor;
+ newTextColor = wordLen == 1 ? colorScheme.keywordColors[1] : colorScheme.preprocessorColor;
}
}
- if(!inQuotes && !inString && !inMultiLineComment && !inSingleLineComment)
+ if(x < box.right && !inQuotes && !inString && !inMultiLineComment && !inSingleLineComment)
{
for(g = 0; g < ((inPrep && word[0] != '#') ? 2 : 1); g++)
{
- char ** keys = keyWords[g];
+ const char ** keys = keyWords[g];
int * len = keyLen[g];
for(ccc = 0; keys[ccc]; ccc++)
{
inQuotes = backInQuotes;
inPrep = backInPrep;
inSingleLineComment = backInSingleLineComment;
+ wasInMultiLine = backWasInMultiLine;
break;
}
else
}
}
}
-
+
// If we're not breaking, this can't be rendered as spacing anymore
spacing = false;
//if(!numSpaces)
{
int tw;
- FontExtent(display, font, line.buffer + start, bufferLen + wordLen, &tw, null);
+ int oh;
+ FontExtent(display, font, line.buffer + start, bufferLen + wordLen, &tw, null, 0, null, &oh);
w = tw;
}
/*else
}*/
if(x + viewX + w > maxW)
{
- c -= wordLen;
- lineComplete = true;
- break;
+ // Avoid an endless loop until we fix wrapping
+ if(c - wordLen > start)
+ {
+ c -= wordLen;
+ lineComplete = true;
+ break;
+ }
}
}
}
{
int renderStart = start;
bool flush = false;
+ bool flagTrailingSpace = false;
int numSpaces = 0;
int wc;
+ int previousGlyph = 0;
// Render checking if we need to split because of selection or to find where to draw insert caret
for(wc = start; wc < start + bufferLen; wc++)
{
flush = CheckColors(line, wc, selection, selX, editX, &selected, selectionForeground,
selectionBackground, textColor, &foreground, &background, &opacity, &overWrite);
- if(overWrite == true)
+ if(overWrite == 1)
{
overWriteCh = (wc < line.count) ? line.buffer[wc] : ' ';
if(overWriteCh == '\t') overWriteCh = ' ';
if(flush)
{
- FlushBuffer(surface, line, wc, &renderStart, &x, y, numSpaces, box);
- if(overWrite == true)
+ flagTrailingSpace = numSpaces && trailingSpace && style.syntax && start + bufferLen == line.count && line != this.line;
+ if(flagTrailingSpace) surface.SetBackground(red);
+ FlushBuffer(surface, line, wc, &renderStart, &x, y, &previousGlyph, &overHang, numSpaces, flagTrailingSpace, box);
+ if(flagTrailingSpace) surface.SetBackground(background);
+ if(overWrite == 1)
{
overWriteX = x;
overWriteY = y;
}
numSpaces = 0;
- surface.TextOpacity(opacity);
- surface.SetBackground(background);
surface.SetForeground(foreground);
flush = false;
}
}
}
- FlushBuffer(surface, line, wc, &renderStart, &x, y, numSpaces, box);
+ flagTrailingSpace = numSpaces && trailingSpace && style.syntax && start + bufferLen == line.count && line != this.line;
+ if(flagTrailingSpace) surface.SetBackground(red);
+ FlushBuffer(surface, line, wc, &renderStart, &x, y, &previousGlyph, &overHang, numSpaces, flagTrailingSpace, box);
+ if(flagTrailingSpace) surface.SetBackground(background);
start += bufferLen;
}
}
if(CheckColors(line, c, selection, selX, editX, &selected, selectionForeground,
selectionBackground, textColor, &foreground, &background, &opacity, &overWrite))
{
- if(overWrite == true)
+ if(overWrite == 1)
{
overWriteX = x;
overWriteY = y;
overWriteCh = ' ';
overWrite = 2;
}
- surface.TextOpacity(opacity);
surface.SetBackground(background);
surface.SetForeground(foreground);
}
- if(style.freeCaret && selected)
+ if(line.count && line.text[line.count - 1] == '\\')
{
- surface.SetBackground(selectionBackground);
- surface.Area(x + XOFFSET - 1,y,clientSize.w-1,y+this.space.h-1);
- // TEST: surface.Area(x + XOFFSET,y,clientSize.w-1,y+this.space.h-1);
+ continuedSingleLineComment = inSingleLineComment;
+ continuedString = inString;
+ continuedQuotes = inQuotes;
}
-
-
- /*
- if(style.freeCaret && selected)
+ else
{
- surface.SetBackground(selectionBackground);
- surface.Area(x + XOFFSET - 1,y,clientSize.w-1,y+this.space.h-1);
+ continuedSingleLineComment = false;
+ continuedString = false;
+ continuedQuotes = false;
}
- */
-
- continuedSingleLineComment = inSingleLineComment && (line.count && line.text[line.count - 1] == '\\');
y+=this.space.h;
- if(y > box.bottom) // >=clientSize.h)
+ if(y > box.bottom) // >=clientSize.h)
break;
}
void ComputeLength(EditLine line)
{
int c;
- int tabOccur = 0;
- int tabWidth;
int x = 0;
for(c = 0; c < line.count; )
len = 1;
}
else
- FontExtent(display, font, line.buffer + start, len, &w, null);
+ {
+ int oh;
+ FontExtent(display, font, line.buffer + start, len, &w, null, 0, null, &oh);
+ }
}
else
{
c++;
}
x += w;
- }
+ }
line.length = x;
if(line.length > this.maxLength)
{
if(this.selY != this.y)
DirtyAll();
- else if(this.selX != this.x) // commented out to erase caret: if(this.selX != this.x)
+ else if(this.selX != this.x) // commented out to erase caret: if(this.selX != this.x)
DirtyLine(this.y);
}
this.col = position;
}
- int DelCh(EditLine l1, int y1, int c1, EditLine l2, int y2, int c2, bool placeAfter)
+ void DelCh(EditLine l1, int y1, int c1, EditLine l2, int y2, int c2, bool placeAfter)
{
- return _DelCh(l1, y1, c1, l2, y2, c2, placeAfter, null);
+ _DelCh(l1, y1, c1, l2, y2, c2, placeAfter, true, null);
}
-
+
bool HasCommentOrEscape(EditLine line)
{
bool hadComment = strstr(line.buffer, "/*") || strstr(line.buffer, "*/");
int c;
-
+
if(!hadComment)
{
for(c = line.count-1; c >= 0; c--)
}
return hadComment;
}
-
- int _DelCh(EditLine l1, int y1, int c1, EditLine l2, int y2, int c2, bool placeAfter, int * addedSpacesPtr)
+
+ int _DelCh(EditLine l1, int y1, int c1, EditLine l2, int y2, int c2, bool placeAfter, bool highlight, int * addedSpacesPtr)
{
EditLine line = l1, next;
char * buffer;
{
byte ch = buffer[c1];
if(UTF8_IS_FIRST(ch)) break;
- c1--;
+ c1--;
extras++;
}
oldCount2 = l2.count;
{
int len;
char * string;
-
+
len = GetText(null, l1, y1, start, l2, y2, c2, false, false);
string = new char[len];
- action = DelTextAction { y1 = y1, x1 = start, y2 = y2, x2 = c2, string = string, placeAfter = placeAfter };
+ action = DelTextAction { y1 = y1, x1 = start, y2 = y2, x2 = c2, string = string, placeAfter = placeAfter, noHighlight = !highlight };
GetText(string, l1, y1, start, l2, y2, c2, false, false);
Record(action);
}
buffer = new char[line.size ? line.size : 1];
*/
buffer = new char[line.size];
- if(!buffer) return;
+ // TODO: Better handling of these allocation failures
+ if(!buffer) return extras;
CopyBytes(buffer,l2.buffer,oldCount1 + 1/*line.count + 1*//*line.size*/);
}
else
buffer = l2.buffer;
- if(!line.AdjustBuffer(newLineCount))
- return;
+ // TODO: Better handling of these allocation failures
+ if(!line.AdjustBuffer(newLineCount))
+ return extras;
#ifdef _DEBUG
/*if(newLineCount > 4000 || newLineCount < 0)
{
this.lineCount--;
delete line.buffer;
-
+
if(line == this.viewLine)
{
if(this.viewLine.next)
//this.viewY++;
style.recomputeSyntax = true;
}
- else
+ else
{
this.viewLine = this.viewLine.prev;
this.viewY--;
this.x = this.line.count;
//this.y++;
}
- else
+ else
{
this.line = this.line.prev;
this.x = this.line.count;
this.dropLine = this.dropLine.next;
this.dropX = this.dropLine.count;
}
- else
+ else
{
this.dropLine = this.dropLine.prev;
this.dropX = this.dropLine.count;
this.selLine = this.selLine.next;
this.selX = this.selLine.count;
}
- else
+ else
{
this.selLine = this.selLine.prev;
this.selX = this.selLine.count;
{
if(this.selY < this.y)
{
- _DelCh(this.selLine, this.selY, this.selX, this.line, this.y, this.x, true, addedSpacesPtr);
+ _DelCh(this.selLine, this.selY, this.selX, this.line, this.y, this.x, true, true, addedSpacesPtr);
this.x = this.selX;
this.y = this.selY;
this.line = this.selLine;
}
else if(this.selY > this.y)
{
- _DelCh(this.line, this.y, this.x, this.selLine, this.selY, this.selX, false, addedSpacesPtr);
+ _DelCh(this.line, this.y, this.x, this.selLine, this.selY, this.selX, false, true, addedSpacesPtr);
this.selX = this.x;
this.selY = this.y;
this.selLine = this.line;
}
else if(this.selX < this.x)
{
- _DelCh(this.selLine, this.selY, this.selX, this.line, this.y, this.x, true, addedSpacesPtr);
+ _DelCh(this.selLine, this.selY, this.selX, this.line, this.y, this.x, true, true, addedSpacesPtr);
this.x = this.selX;
this.y = this.selY;
this.line = this.selLine;
}
else
{
- _DelCh(this.line, this.y, this.x, this.selLine, this.selY, this.selX, false, addedSpacesPtr);
+ _DelCh(this.line, this.y, this.x, this.selLine, this.selY, this.selX, false, true, addedSpacesPtr);
this.selX = this.x;
this.selY = this.y;
this.selLine = this.line;
return false;
}
- bool AddToLine(char * stringLine, int count, bool LFComing, int * addedSpacesPtr, int * addedTabsPtr)
+ bool AddToLine(const char * stringLine, int count, bool LFComing, int * addedSpacesPtr, int * addedTabsPtr, int * xAdjustmentPtr)
{
bool hadComment = false;
// Add the line here
EditLine line = this.line;
-
+
// The purpose of this is solely to lock a max number of characters if no HSCROLLING is present
if(!style.hScroll && created)
{
{
int w;
int numBytes = 1;
- char * string;
+ const char * string;
if(c < Min(this.x, line.count))
string = line.buffer + c;
else if(c < endX)
}
else
{
+ int oh;
numBytes = UTF8_NUM_BYTES(*string);
- FontExtent(display, this.font, string, numBytes, &w, null);
+ FontExtent(display, this.font, string, numBytes, &w, null, 0, null, &oh);
}
x += w;
- if(x >= clientSize.w)
+ if(x >= clientSize.w)
{
count = c - max;
break;
{
int addedSpaces = 0;
int addedTabs = 0;
-
+ int xAdjustment = 0;
+
// Add blank spaces if EES_FREECARET
if(this.x > line.count)
{
addedSpaces = wantedPosition - position;
else
{
+ xAdjustment = wantedPosition - position;
+
// Put a first tab
addedTabs = 1;
position += this.tabSize - (position % this.tabSize);
position += (addedTabs-1) * this.tabSize;
// Finish off with spaces
addedSpaces = wantedPosition - position;
+
+ xAdjustment -= addedSpaces + addedTabs;
}
}
else
{
BufferLocation before = { this.line, this.y, this.x }, after = { this.line, this.y, this.x };
bool hasComment;
-
+
memmove(line.buffer+this.x+count, line.buffer+this.x,line.count-this.x);
CopyBytes(line.buffer + this.x + addedTabs + addedSpaces, stringLine, count);
if(addedTabs)
{
- *addedTabsPtr = addedTabs;
FillBytes(line.buffer+line.count,'\t',addedTabs);
#ifdef _DEBUG
if(addedTabs > 4000 || addedTabs < 0)
#endif
line.count += addedTabs;
}
- else if(addedTabs)
- *addedTabsPtr = 0;
+
if(addedSpaces)
{
FillBytes(line.buffer+line.count,' ',addedSpaces);
printf("Warning");
#endif
line.count += addedSpaces;
- if(addedSpacesPtr) *addedSpacesPtr = addedSpaces;
- }
- else if(addedSpacesPtr)
- *addedSpacesPtr = 0;
+ }
+
+ if(addedTabsPtr) *addedTabsPtr = addedTabs;
+ if(addedSpacesPtr) *addedSpacesPtr = addedSpaces;
+ if(xAdjustmentPtr) *xAdjustmentPtr = xAdjustment;
#ifdef _DEBUG
if(count > 4000 || count < 0)
printf("Warning");
ComputeLength(line);
ComputeColumn();
- after.x = this.x;
+ after.x = this.x;
hasComment = HasCommentOrEscape(line);
if(!undoBuffer.insideRedo)
this.x = this.line.count;
ComputeColumn();
if(deselect)
- Deselect();
+ _Deselect();
}
}
this.x = 0;
this.col = 0;
if(deselect)
- Deselect();
+ _Deselect();
}
}
// Returns true if it needs scrolling
bool FindMouse(int px, int py, int * tx, int * ty, EditLine * tline, bool half)
{
- int w;
int c;
- int x, y;
+ int y;
EditLine line;
bool needHScroll = false;
this.endY = clientSize.h-1;
//ErrorLog("DirtyEnd %d\n", y);
}
-
+
void DirtyLine(int y)
{
if(y >= this.viewY)
{
if(line)
{
- if(mouseMove || (!overwrite && !style.noCaret))
+ if(mouseMove || !style.noCaret)
{
int max = this.mouseMove ? this.dropX : this.x;
int y = this.mouseMove ? this.dropY : this.y;
len = 1;
}
else
- FontExtent(display, this.font, line.buffer + start, len, &w, null);
+ {
+ int oh;
+ FontExtent(display, this.font, line.buffer + start, len, &w, null, 0, null, &oh);
+ }
}
else
{
c++;
}
x += w;
- }
+ }
}
if(setCaret)
caretX = x;
caretY = y * this.space.h;
- SetCaret(x + XOFFSET-2, y * space.h + YOFFSET, space.h);
+ if(!overwrite)
+ SetCaret(x + XOFFSET-2, y * space.h + YOFFSET, space.h);
+ else
+ SetCaret(0, 0, 0);
}
else
SetCaret(0, 0, 0);
+ // TOFIX: Mismatch between NotifyCaretMove() and NotifyDropped() / GoToPosition()
NotifyCaretMove(master, this, y + 1, x + 1);
SelectionEnables();
while(true)
{
int start = c;
- int numBytes = 1;
int len = 1;
int w;
if(c < Min(max, line.count))
len = 1;
}
else
- FontExtent(display, font, line.buffer + start, len, &w, null);
+ {
+ int oh;
+ FontExtent(display, font, line.buffer + start, len, &w, null, 0, null, &oh);
+ }
}
- else
+ else
{
if(style.freeCaret && c < max)
w = space.w;
- else
+ else
{
if(px) *px = x;
return c;
}
c++;
}
- if(x + (((half && len == 1) ? (w / 2) : w)) >= position)
+ if(x + (((half && len == 1) ? (w / 2) : w)) >= position)
{
int lastW;
while(len > 0)
else
a--;
if(a > start)
- FontExtent(display, font, line.buffer + start, a - start, &w, null);
+ {
+ int oh;
+ FontExtent(display, font, line.buffer + start, a - start, &w, null, 0, null, &oh);
+ }
else
w = 0;
if(position > x + (half ? ((w + lastW) / 2) : lastW)) break;
if(this.x < c)
this.x = x;
else
- {
+ {
c = AdjustXPosition(line, viewX + clientSize.w - 1, false, &x, MAXINT, c);
if(this.x > c)
this.x = c;
{
int c, numLines;
EditLine oldLine = this.line;
-
+
bool selecting = this.x != this.selX || this.y != this.selY;
numLines = clientSize.h / this.space.h;
}
/*
- bool SaveFile(char * fileName)
+ bool SaveFile(const char * fileName)
{
File f = eFile_Open(fileName, FO_WRITE);
if(f)
popup = PopupMenu { master = this, menu = contextMenu,
/*
- nonClient = true, interim = false, parent = parent,
+ nonClient = true, interim = false, parent = parent,
position = { x + clientStart.x + parent.clientStart.x + position.x, y + cientStart.y + parent.sy + clientStart.y + position.y };
*/
position = { x + clientStart.x + absPosition.x - guiApp.desktop.position.x, y + clientStart.y + absPosition.y - guiApp.desktop.position.y }
this.y = y;
this.line = line;
DirtyLine(this.y);
- this.selLine = this.line;
- this.selX = this.x;
- this.selY = this.y;
- //Deselect();
+ _Deselect();
}
ComputeColumn();
}
-
+
UpdateDirty();
UpdateCaretPosition(true);
- return true;
+ // Return false because DataBoxes automatically set EditBox editor's clickThrough to true for MouseMove events
+ // ( for tool tips -- see 95ee4962c4c7bc3fe0a04aa6a4f98cacada40884)
+ return false;
}
bool OnLeftButtonUp(int x, int y, Modifiers mods)
mouseSelect = false;
wordSelect = false;
-
+
x -= XOFFSET;
-
+
ReleaseCapture();
if(!style.readOnly)
{
moveX = this.selX - this.x;
}
}
+
+ recordUndoEvent = true;
DelSel(null);
this.dropX -= moveX;
this.selX = this.x = this.dropX;
this.selY = this.y = this.dropY;
this.selLine = this.line = this.dropLine;
AddS(text);
+ recordUndoEvent = false;
+
SetViewToCursor(true);
delete text;
Modified();
this.line = line;
ComputeColumn();
DirtyLine(this.y);
- Deselect();
+ _Deselect();
UpdateDirty();
}
}
}
}
mouseMove = false;
- return true;
+ // Return false because DataBoxes automatically set EditBox editor's clickThrough to true for MouseMove events
+ // ( for tool tips -- see 95ee4962c4c7bc3fe0a04aa6a4f98cacada40884)
+ return false;
}
bool OnMouseMove(int mx, int my, Modifiers mods)
EditLine line;
bool needScroll;
- if(mods != -1 && mods.isSideEffect)
- {
- SetSelectCursor();
- return true;
+ if(mods != -1 && mods.isSideEffect)
+ {
+ SetSelectCursor();
+ return true;
}
if(style.noSelect) return true;
if(wordSelect) return true;
{
if(!needScroll)
timer.Stop();
- else
+ else
{
if(needScroll)
timer.Start();
- if(mods != -1 &&
+ if(mods != -1 &&
((style.hScroll) || (style.vScroll)))
return true;
}
{
if(FontExtent)
{
- FontExtent(display, font, " ", 1, (int *)&space.w, (int *)&space.h);
- FontExtent(display, font, "W", 1, (int *)&large.w, (int *)&large.h);
+ int oh;
+ FontExtent(display, font, " ", 1, (int *)&space.w, (int *)&space.h, 0, null, &oh);
+ FontExtent(display, font, "W", 1, (int *)&large.w, (int *)&large.h, 0, null, &oh);
space.w = Max(space.w, 1);
large.w = Max(large.w, 1);
bool OnLoadGraphics()
{
- FontExtent = Display::FontExtent;
+ FontExtent = Display::FontExtent2;
font = fontObject;
ComputeFont();
// UpdateCaretPosition(true);
int y;
bool done = false;
EditLine line = this.line;
- int c;
+ int c = 0;
for(y = this.y; y>= 0; y--)
{
- c = (y == this.y) ? (this.x-1) : line.count-1;
+ c = (y == this.y) ? (Min(this.x-1, line.count-1)) : line.count-1;
// Slow down when going on lines...
if(y != this.y) break;
else
break;
}
+
//if(this.x != 0)
{
- DelCh(line,y,c+1,this.line,this.y,this.x, true);
+ _DelCh(line, y, c+1, this.line, this.y, this.x, true, false, null);
this.x = this.selX = Min(c+1, line.count);
this.y = this.selY = y;
this.line = this.selLine = line;
SetViewToCursor(true);
Modified();
}
- // Delete word
- else if(key.ctrl)
- {
- if(this.x < this.line.count)
- {
- int i;
- int length;
- for(i = this.x; i < this.line.count; i++)
- {
- if(!IS_ALUNDER(this.line.buffer[i]))
- break;
- }
-
- for(; i < this.line.count; i++)
- {
- //Delete trailing whitespace
- if(IS_ALUNDER(this.line.buffer[i]))
- break;
- }
- DelCh(this.line, this.y, this.x, this.line, this.y, i, false);
- SetViewToCursor(true);
- Modified();
- }
- else if(this.line.next)
- {
- DelCh(this.line, this.y, this.x, this.line.next, this.y+1, 0, false);
- SetViewToCursor(true);
- Modified();
- }
- }
- else
+ else
{
- if(!(style.freeCaret))
+ EditLine line1 = this.line, line2 = this.line;
+ int x1, y1 = this.y, x2, y2 = this.y;
+ if(!style.freeCaret)
{
this.selX = this.x = Min(this.x, this.line.count);
ComputeColumn();
}
- if(this.x < this.line.count)
+ x1 = this.x;
+
+ if(x1 < line1.count)
{
- DelCh(this.line, this.y, this.x, this.line, this.y, this.x+1, false);
+ // Delete word
+ if(key.ctrl)
+ {
+ int i;
+ char * buffer = line1.buffer;
+ for(i = x1; i < line1.count; i++)
+ {
+ if(!IS_ALUNDER(buffer[i]))
+ break;
+ }
+
+ for(; i < line1.count; i++)
+ {
+ // Delete trailing whitespace
+ if(IS_ALUNDER(buffer[i]))
+ break;
+ }
+ x2 = i;
+ }
+ else
+ x2 = x1 + 1;
}
- else if(this.line.next)
+ else
{
- DelCh(this.line, this.y, this.x, this.line.next, this.y+1, 0, false);
+ // Avoid creating trailing spaces if there is no content on next line
+ line2 = line1.next;
+ y2++;
+ if(line2 && !line2.count)
+ x1 = line1.count;
+ x2 = 0;
}
+ if(line2)
+ _DelCh(line1, y1, x1, line2, y2, x2, false, false, null);
SetViewToCursor(true);
Modified();
}
bool stuffAfter = false;
char * addString;
int len = 0;
+ /*bool resetX = false;
+ int backX;*/
if(style.stuckCaret) GoToEnd(true);
if(style.readOnly) break;
else
break;
}
+
+ // Prevent adding trailing spaces if at the head of a line
+ /*if(c && c == this.x && c < this.line.count && this.x == this.selX && this.y == this.selY)
+ {
+ position = 0;
+ backX = this.x;
+ this.x = 0;
+ this.selX = 0;
+ resetX = true;
+ }*/
+
if(!line.count)
position = x;
if(this.x < this.line.count)
stuffAfter = true;
-
+
//If last character is a { indent one tab
- if(this.line.buffer[this.x - 1] == '{')
+ c = Min(x, line.count);
+ if(c > 0 && line.buffer[c - 1] == '{')
{
//Except if the next non space character is a }
bool indent = false;
int i;
- for(i = this.x; i < this.line.size; i++)
+ for(i = c; i <= this.line.count; i++) // indent will be set to true on nul terminating char
if(this.line.buffer[i] != ' ' && this.line.buffer[i] != '\t')
{
if(this.line.buffer[i] != '}')
}
addString[len] = '\0';
}
+ recordUndoEvent = true;
if(AddS(addString))
{
- if(!stuffAfter && style.freeCaret)
+ EditLine prevLine = this.line.prev;
+ if(prevLine)
+ {
+ // Nuke spaces if that is all that is left on previous line
+ int i;
+ char * buffer = prevLine.buffer;
+ for(i = 0; i < prevLine.count; i++)
+ if(buffer[i] != ' ' && buffer[i] != '\t')
+ break;
+ if(i == prevLine.count)
+ DelCh(prevLine, this.y - 1, 0, prevLine, this.y - 1, prevLine.count, false);
+ }
+ /*if(resetX)
+ {
+ this.x = this.selX = backX;
+ ComputeColumn();
+ }
+ else */if(!stuffAfter && style.freeCaret)
{
this.x = this.selX = position;
ComputeColumn();
SetViewToCursor(true);
Modified();
}
+ recordUndoEvent = false;
delete addString;
return false;
}
bool foundAlpha = false;
bool found = false;
int y = this.y;
- EditLine line, lastLine;
- int lastC, lastY;
+ EditLine line, lastLine = null;
+ int lastC = 0, lastY = 0;
for(line = this.line; (line && !found); line = line.prev, y--)
{
break;
}
}
- while(--c)
+ while(--c >= 0)
{
byte ch = line.buffer[c];
if(UTF8_IS_FIRST(ch)) break;
- }
+ }
}
- // No next word found,
+ // No next word found,
if(!found && ( this.x > 0 || (!line.count && this.x)))
{
foundAlpha = true;
{
if(x <= line.count)
{
- byte * buffer = line.buffer;
+ byte * buffer = (byte *)line.buffer;
while(--x)
{
byte ch = buffer[x];
if(UTF8_IS_FIRST(ch)) break;
- }
+ }
}
else
x--;
}
ComputeColumn();
}
- if(!shift) Deselect();
+ if(!shift) _Deselect();
SetViewToCursor(true);
//break;
return false;
{
bool foundAlpha = false;
bool found = false;
- EditLine line, lastLine;
+ EditLine line = null, lastLine = null;
int y = this.y;
- int lastC, lastY, lastNumBytes;
-
+ int lastC = 0, lastY = 0, lastNumBytes = 0;
+
for(line = this.line; (line && !found); line = line.next, y++)
{
int start = (line == this.line) ? this.x : 0;
lastY = y;
break;
}
- }
+ }
if(found)
{
DirtyLine(this.y);
break;
}
}
- // No next word found,
+ // No next word found,
if(!found && (c != this.x || line != this.line))
{
found = true;
{
if(x < line.count)
{
- byte * buffer = line.buffer;
+ byte * buffer = (byte *)line.buffer;
while(++x)
{
byte ch = buffer[x];
if(UTF8_IS_FIRST(ch)) break;
- }
+ }
}
else
x++;
}
}
}
- if(!shift) Deselect();
+ if(!shift) _Deselect();
SetViewToCursor(true);
// break;
return false;
else
{
if(style.stuckCaret) break;
-
+
if(!shift) SelDirty();
DirtyLine(this.y);
this.y--;
this.x = AdjustXPosition(line, caretX, true, null, MAXINT, 0);
}
-
+
DirtyLine(this.y);
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
SetViewToCursor(false);
len = (nextSpace - (text + textPos));
else
len = line.count - textPos;
-
+
if(textPos < line.count)
{
display.FontExtent(font, text + textPos, len, &w, null);
}
DirtyLine(this.y);
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
SetViewToCursor(false);
return false;
this.x = line.count;
DirtyLine(this.y);
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
SetViewToCursor(false);
return false;
} while(textPos < line.count);
DirtyLine(this.y);
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
SetViewToCursor(false);
return false;
}
*/
-
+
// PREVIOUS CODE
/*
if(this.line.prev)
DirtyLine(this.y);
this.x = x;
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
{
if(style.stuckCaret) break;
{
+ /*
int th = space.h;
int textPos = 0;
int sx = 0, sy = this.y * this.space.h;
int maxW = clientSize.w - sx;
char * text = line.buffer;
+ */
if(!shift) SelDirty();
DirtyLine(this.y);
-
+
if(style.wrap)
{
/*
this.x = AdjustXPosition(line, caretX, true, null, MAXINT, 0);
}
- if(!shift) Deselect();
+ DirtyLine(this.y);
+ if(!shift) _Deselect();
ComputeColumn();
- if(this.selX != this.x || this.selY != this.y)
- DirtyLine(this.y);
SetViewToCursor(false);
-
+
/*
while(!textPos || (style.freeCaret || textPos<line.count))
{
len = (nextSpace - (text + textPos));
else
len = line.count - textPos;
-
+
if(textPos < line.count)
{
display.FontExtent(font, text + textPos, len, &w, &th);
this.x--;
else
while(this.x > 0 && !UTF8_IS_FIRST(text[--this.x]));
-
+
len = this.x - startPos;
display.FontExtent(font, text + startPos, len, &x, null);
}
-
- if(!shift) Deselect();
+
+ if(!shift) _Deselect();
ComputeColumn();
SetViewToCursor(false);
this.x = line.count;
DirtyLine(this.y);
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
SetViewToCursor(false);
return false;
- }
+ }
else if(textPos >= line.count && line.next)
{
startPos = 0;
this.x = Min(this.x, line.count);
//int x = AdjustXPosition(this.line, this.line.next, true, null, MAXINT, 0);
this.y++;
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
if(this.selX != this.x || this.selY != this.y)
DirtyLine(this.y);
this.y++;
this.x = x;
- if(!shift) Deselect();
+ if(!shift) _Deselect();
ComputeColumn();
if(this.selX != this.x || this.selY != this.y)
for(c=0; line.buffer[c]; c++)
if(line.buffer[c] != ' ' && line.buffer[c] != '\t')
break;
- if(shift && (c != 0 || this.x))
+ if(overwrite || (shift && (c != 0 || this.x)))
DirtyLine(this.y);
- if(this.x != c)
+ if(this.x != c)
this.x = c;
else
this.x = 0;
}
else
{
- if(shift && this.x != 0)
+ if(overwrite || (shift && this.x != 0))
DirtyLine(this.y);
this.x = 0;
}
ComputeColumn();
}
- if(!shift) Deselect();
+ if(!shift) _Deselect();
SetViewToCursor(true);
//break;
return false;
else if(this.x != this.line.count)
{
this.x = this.line.count;
- if(shift)
+ if(overwrite || shift)
DirtyLine(this.y);
ComputeColumn();
}
- if(!shift) Deselect();
+ if(!shift) _Deselect();
SetViewToCursor(true);
//break;
return false;
Record(action);
}
memmove(line.buffer,line.buffer+lastC,line.size-lastC);
- if(!line.AdjustBuffer(line.count-lastC))
+ if(!line.AdjustBuffer(line.count-lastC))
break;
line.count-=lastC;
DirtyLine(y);
{
BufferLocation before = { line, y, 0 }, after = { line, y, 1 };
- if(!line.AdjustBuffer(line.count+1))
+ if(!line.AdjustBuffer(line.count+1))
break;
NotifyCharsAdded(master, this, &before, &after, this.pasteOperation);
BufferLocation before = { line, y, 0 }, after = { line, y, this.tabSize };
NotifyCharsAdded(master, this, &before, &after, this.pasteOperation);
- if(!line.AdjustBuffer(line.count+this.tabSize))
+ if(!line.AdjustBuffer(line.count+this.tabSize))
break;
{
{
PageDown();
DirtyAll();
- if(!shift) Deselect();
+ if(!shift) _Deselect();
SetCursorToViewX();
SetCursorToViewY();
}
{
PageUp();
DirtyAll();
- if(!shift) Deselect();
+ if(!shift) _Deselect();
SetCursorToViewX();
SetCursorToViewY();
}
Copy();
return false;
}
- else if(key.shift)
- {
- if(!(style.readOnly))
- Paste();
- return false;
- }
- else
+ else if(!style.readOnly)
{
- this.overwrite ^= 1;
- UpdateCaretPosition(true);
- if(this.overwrite)
- SetCaret(0,0,0);
- DirtyLine(this.y);
- UpdateDirty();
- NotifyOvrToggle(master, this, this.overwrite);
+ if(key.shift)
+ {
+ if(!(style.readOnly))
+ Paste();
+ return false;
+ }
+ else
+ {
+ this.overwrite ^= 1;
+ UpdateCaretPosition(true);
+ if(this.overwrite)
+ SetCaret(0,0,0);
+ DirtyLine(this.y);
+ UpdateDirty();
+ NotifyOvrToggle(master, this, this.overwrite);
+ }
}
break;
- case hotKey:
+ case hotKey:
break;
default:
-
+
switch(key)
{
case ctrlA:
//Save current view position
int tempX = this.viewX;
int tempY = this.viewY;
-
+
this.selX = 0;
this.selY = 0;
this.selLine = this.lines.first;
ComputeColumn();
DirtyAll();
SetViewToCursor(true);
-
+
//Restore previous view position
SetScrollPosition(tempX, tempY * this.space.h);
-
+
UpdateDirty();
SetSelectCursor();
SelectionEnables();
{
//Only indent back if you are exactly at one tab.
{
- bool whitespace = true;
+ //bool whitespace = true;
int i;
char * newline;
int putsize;
-
- int indentwidth;
+
+ int indentwidth = 0;
EditLine line = this.line;
-
+
//Only remove one tab if there is nothing else on the line.
for(i = 0; i < this.line.count; i++)
{
return false;
}
}
-
+
//Find opening {
i = 1;
while(i && line)
{
int pos;
-
+
indentwidth = 0;
for(pos = line.count - 1; pos >= 0; pos--)
{
}
line = line.prev;
}
-
+
//Place the } to get an undo:
PutCh(ch);
-
+
this.x = this.line.count;
this.selX = 0;
-
+
if(!style.useTab)
putsize = indentwidth;
else
putsize = indentwidth / this.tabSize + indentwidth % this.tabSize;
-
+
newline = new char[putsize+2];
newline[putsize] = '}';
newline[putsize+1] = '\0';
-
+
i = 0;
if(style.useTab)
for(; i < indentwidth / this.tabSize; i++)
newline[i] = '\t';
for(;i < putsize; i++)
newline[i] = ' ';
-
+
AddS(newline);
-
+
delete newline;
}
return false;
for(; position > this.viewY && this.viewLine.next; this.viewLine = this.viewLine.next, this.viewY++);
FigureStartSyntaxStates(oldViewLine, false);
}
-
+
if(action != setRange)
{
if(!this.mouseMove && style.cursorFollowsView && !SelSize()) SetCursorToViewY();
int numLines = clientSize.h / this.space.h;
int y;
if(Abs(this.viewY - oldViewY) < numLines)
-
-
+
+
if(this.viewY > oldViewY)
{
for(y = oldViewY; y <this.viewY; y++)
Box box { 0,0, clientSize.w-1, YOFFSET-1 };
Update(box);
}
-
+
UpdateDirty();
}
- bool _AddCh(unichar ch, int * addedSpacesPtr, int * addedTabsPtr)
+ bool _AddCh(unichar ch, int * addedSpacesPtr, int * addedTabsPtr, int * xAdjustmentPtr)
{
EditLine line;
- int length, endX;
+ int length, endX = 0;
bool result;
ReplaceTextAction replaceAction = null;
AddCharAction addCharAction = null;
- int addedSpaces = 0, addedTabs = 0;
+ int addedSpaces = 0, addedTabs = 0, xAdjustment = 0;
if(ch == '\r') return true;
- if(style.stuckCaret /*|EES_READONLY)*/ )
+ if(style.stuckCaret /*|EES_READONLY)*/ )
GoToEnd(true);
-
+
if(ch == '\n' && !(style.multiLine) && this.line) return false;
-
+
if(!undoBuffer.dontRecord)
{
if(selX != x || selY != y)
length = this.line.count - endX;
}
}
- if(!line.AdjustBuffer(length))
+ if(!line.AdjustBuffer(length))
return false;
if(this.line)
{
char string[5];
int count = UTF32toUTF8Len(&ch, 1, string, 5);
DelSel(&addedSpaces);
- result = AddToLine(string, count, false, addedSpaces ? null : &addedSpaces, &addedTabs);
+ result = AddToLine(string, count, false, addedSpaces ? null : &addedSpaces, &addedTabs, &xAdjustment);
if(addedSpacesPtr) *addedSpacesPtr = addedSpaces;
if(addedTabsPtr) *addedTabsPtr = addedTabs;
+ if(xAdjustmentPtr) *xAdjustmentPtr = xAdjustment;
}
this.selX = this.x;
this.selY = this.y;
bool AddCh(unichar ch)
{
- return _AddCh(ch, null, null);
+ return _AddCh(ch, null, null, null);
}
void Modified()
void Delete(EditLine line1, int y1, int x1, EditLine line2, int y2, int x2)
{
Deselect();
- DelCh(line1, y1, x1, line2, y2, x2, false);
+ _DelCh(line1, y1, x1, line2, y2, x2, false, false, null);
SetViewToCursor(true);
UpdateDirty();
Modified();
undoBuffer.Undo();
itemEditUndo.disabled = undoBuffer.curAction == 0;
itemEditRedo.disabled = undoBuffer.curAction == undoBuffer.count;
+
+ UpdateDirty();
+ SetSelectCursor();
+ SelectionEnables();
+
if(savedAction == undoBuffer.curAction)
{
modifiedDocument = false;
undoBuffer.Redo();
itemEditUndo.disabled = undoBuffer.curAction == 0;
itemEditRedo.disabled = undoBuffer.curAction == undoBuffer.count;
+
+ UpdateDirty();
+ SetSelectCursor();
+ SelectionEnables();
+
if(savedAction == undoBuffer.curAction)
{
modifiedDocument = false;
}
// BASIC OUTPUT
- bool AddS(char * string)
+ bool AddS(const char * string)
{
if(this)
{
bool ret = true;
- char * line;
+ const char * line;
int c, count;
- int addedSpaces = 0, addedTabs = 0;
+ int addedSpaces = 0, addedTabs = 0, xAdjustment = 0;
AddTextAction action = null;
ReplaceTextAction replaceAction = null;
this.pasteOperation = true;
- if(style.stuckCaret /*|EES_READONLY)*/ )
+ if(style.stuckCaret /*|EES_READONLY)*/ )
GoToEnd(true);
if(!undoBuffer.dontRecord)
if(!style.multiLine)
{
int i;
- char ch;
+ char ch;
for(i = 0; (ch = placeString[i]); i++)
if(ch == '\n')
{
break;
}
}
-
+
if(selX != x || selY != y)
{
char * newString;
action = AddTextAction { y1 = y, x1 = Min(this.line.count, x), string = placeString };
else
action = AddTextAction { y1 = y, x1 = x, string = placeString };
-
+
Record(action);
}
else
{
if(string[c] == '\n' || string[c] == '\r')
{
- if(!AddToLine(line,count, true, addedSpaces ? null : &addedSpaces, addedTabs ? null : &addedTabs))
+ if(!AddToLine(line, count, true, addedSpaces ? null : &addedSpaces, addedTabs ? null : &addedTabs, xAdjustment ? null : &xAdjustment))
{
ret = false;
break;
count = 0;
line = string+c+1;
/*
- if(string[c] == '\r' && *line == '\n')
+ if(string[c] == '\r' && *line == '\n')
{
line++;
c++;
// Add the line here
if(ret && count)
- if(!AddToLine(line,count,false, addedSpaces ? null : &addedSpaces, addedTabs ? null : &addedTabs))
+ if(!AddToLine(line,count,false, addedSpaces ? null : &addedSpaces, addedTabs ? null : &addedTabs, xAdjustment ? null : &xAdjustment))
{
ret = false;
}
action.x2 = x;
action.addedSpaces = addedSpaces;
action.addedTabs = addedTabs;
+ action.xAdjustment = xAdjustment;
}
else if(replaceAction)
{
replaceAction.x3 = x;
replaceAction.addedSpaces = addedSpaces;
replaceAction.addedTabs = addedTabs;
+ replaceAction.xAdjustment = xAdjustment;
}
UpdateCaretPosition(true);
void PutCh(unichar ch)
{
bool result;
-
- if((ch >= 32 /*&& ch <=126*/) || ch == '\n')
+
+ if((ch >= 32 /*&& ch <=126*/) || ch == '\n' || ch == '\t')
//if((ch >= 32) || ch == '\n')
{
- int addedSpaces = 0, addedTabs = 0;
+ int addedSpaces = 0, addedTabs = 0, xAdjustment = 0;
ReplaceTextAction replaceAction = null;
AddCharAction addCharAction = null;
}
}
undoBuffer.dontRecord++;
- result = _AddCh(ch, &addedSpaces, &addedTabs);
+ result = _AddCh(ch, &addedSpaces, &addedTabs, &xAdjustment);
if(replaceAction)
{
replaceAction.x3 = x;
replaceAction.y3 = y;
replaceAction.addedSpaces = addedSpaces;
replaceAction.addedTabs = addedTabs;
- }
+ replaceAction.addedTabs = xAdjustment;
+ }
if(addCharAction)
{
- addCharAction.x -= addedTabs * (tabSize-1);
addCharAction.addedSpaces = addedSpaces;
addCharAction.addedTabs = addedTabs;
+ addCharAction.xAdjustment = xAdjustment;
}
undoBuffer.dontRecord--;
if(ch == '\n')
}
}
- void PutS(char * string)
+ void PutS(const char * string)
{
if(this)
{
}
}
- void Printf(char * format, ...)
+ void Printf(const char * format, ...)
{
if(this)
{
}
}
- void SetContents(char * format, ...)
+ void SetContents(const char * format, ...)
{
if(this)
{
{
if(x > 0)
{
- x -= 1 + DelCh(line, y, x-1, line, y, x, true);
+ if(x > line.count)
+ x--;
+ else
+ x -= 1 + _DelCh(line, y, x-1, line, y, x, true, false, null);
Modified();
}
else if(this.line.prev)
int x = line.count;
int y = this.y;
- DelCh(line, this.y-1, x, this.line, this.y, this.x, true);
+ _DelCh(line, this.y-1, x, this.line, this.y, this.x, true, false, null);
this.line = line;
this.y = y-1;
this.x = x;
DirtyLine(c);
this.y = c;
this.line = line;
- Deselect();
+ _Deselect();
SetViewToCursor(true);
return true;
}
return false;
}
+ // NOTE: Mismatch with NotifyCaretMove() for x/y + 1
bool GoToPosition(EditLine line, int y, int x)
{
/*
this.y = y;
this.line = line;
ComputeColumn();
- Deselect();
+ _Deselect();
SetViewToCursor(true);
return true;
}
{
if(created)
{
- int w;
- int c, numLines;
+ int numLines;
EditLine line;
int x;
int checkX, checkY;
FixScrollArea();
selected = selX != this.x || selY != y;
-
+
viewX = this.viewX;
viewY = this.viewY;
}
}
- if(!dontScroll)
+ if(!dontScroll)
{
if(style.vScroll)
{
for(;dropLine && dropLine.prev && dropY >= numLines;)
{
dropLine = dropLine.prev;
- dropY--;
+ dropY--;
}
else
for(;this.line && this.line.prev && this.y >= numLines;)
{
this.line = this.line.prev;
- y--;
+ y--;
}
}
}
else
{
- EditLine oldLine = this.line;
+ //EditLine oldLine = this.line;
bool lastOne = false;
EditLine oldViewLine = this.viewLine;
bool figureSyntax = false;
{
int c, numLines;
EditLine line;
-
+
if(this.y == 0) return;
numLines = clientSize.h / this.space.h;
}
else
{
- EditLine oldLine = this.line;
-
for(c=0, line = this.line.prev; line && c<numLines; line = line.prev, c++)
{
this.line = line;
//DirtyAll();
// this.viewLine = this.viewLine.next;
// this.viewY++;
-
+
SetScrollPosition(this.viewX, (this.viewY + 1) * this.space.h);
}
}
}
nx1 = Min(x1,l1.count);
nx2 = Min(x2,l2.count);
-
+
// Find Number of Bytes Needed
size = 0;
for(line = l1; line; line = line.next)
- {
+ {
if(line == l1) start = nx1; else start = 0;
if(line == l2) end = nx2; else end = line.count;
size += end-start;
// Copy text
for(line = l1; line; line = line.next)
- {
+ {
if(line == l1) start = nx1; else start = 0;
if(line == l2) end = nx2; else end = line.count;
if(text)
{
CopyBytes(text, line.buffer + start, end - start);
text += end-start;
- }
+ }
numChars += end-start;
-
+
if(style.freeCaret && line == l2 && addSpaces)
{
if(l1 == l2)
if(text)
*(text++) = '\r';
numChars++;
- }
+ }
if(text)
*(text++) = '\n';
- numChars++;
+ numChars++;
}
// '\0' terminate Terminate
if(text)
GetText(text, line, y, x, selLine, selY, selX, addCr, true);
}
+ private void _Deselect() // This assumes marking lines as dirty is handled by the caller
+ {
+ selLine = line;
+ selX = x;
+ selY = y;
+ }
+
void Deselect()
{
SelDirty();
- this.selLine = this.line;
- this.selX = this.x;
- this.selY = this.y;
+ _Deselect();
}
// CLIPBOARD
ClipBoard clipBoard { };
if(clipBoard.Allocate(size+1))
{
- GetSel(clipBoard.memory, true);
+ GetSel(clipBoard.memory, true);
// Save clipboard
clipBoard.Save();
}
savedAction = undoBuffer.curAction;
for(line = this.lines.first; line; line = line.next)
- {
- f.Write(line.buffer, line.count,1);
+ {
+ f.Write(line.buffer, line.count, 1);
if(line.next)
{
if(cr) f.Putc('\r');
if(f)
{
char buffer[BUFFER_SIZE];
-
+
for(;;)
{
int count = f.Read(buffer, 1, BUFFER_SIZE-1);
itemEditRedo.disabled = undoBuffer.curAction == undoBuffer.count;
}
- EditBoxFindResult Find(char * text, bool matchWord, bool matchCase, bool isSearchDown)
+ EditBoxFindResult Find(const char * text, bool matchWord, bool matchCase, bool isSearchDown)
{
EditLine line;
int num;
{
char * string;
- if(!line)
+ if(!line)
{
if(isSearchDown)
{
result = wrapped;
}
}
-
+
if(isSearchDown)
string = SearchString(line.buffer, firstPass ? Min(this.x,line.count) : 0,text,matchCase,matchWord);
else
{
Select((void *)line,num,string - line.buffer,(void *)line,num,string - line.buffer + strlen(text));
return result;
- }
+ }
if(line == this.line && !firstPass) break;
if(isSearchDown)
return notFound;
}
- EditBoxFindResult FindInSelection(char * text, bool matchWord, bool matchCase, EditLine l2, int y2, int x2)
+ EditBoxFindResult FindInSelection(const char * text, bool matchWord, bool matchCase, EditLine l2, int y2, int x2)
{
EditLine line;
int y;
{
Select((void *)line,y,string - line.buffer,(void *)line,y,string - line.buffer + strlen(text));
return found;
- }
+ }
}
return notFound;
}
#endif
if(!NotifyKeyDown(master, this, key, ch))
return false;
- else
+ else
{
switch(key)
{
y++;
}
else
- break;
+ break;
}
editBox.line = editBox.selLine = line;
}
return result;
}
-
- bool Puts(char * string)
+
+ bool Puts(const char * string)
{
EditBox editBox = this.editBox;
BufferLocation start { editBox.line, editBox.y, editBox.x };
BufferLocation pos;
-
+
numBytes = 0;
editBox.AddS(string);
{
utf8Bytes[numBytes++] = ch;
utf8Bytes[numBytes] = 0;
- if(UTF8Validate(utf8Bytes))
+ if(UTF8Validate((char *)utf8Bytes))
{
editBox.AddCh(UTF8_GET_CHAR(utf8Bytes, numBytes));
numBytes = 0;
}
return true;
}
- return false;
+ return false;
}
bool Getc(char * ch)
start.AdjustDelete(pos, end);
sel.AdjustDelete(pos, end);
- editBox.DelCh(pos.line, pos.y, pos.x, end.line, end.y, end.x, true);
+ editBox._DelCh(pos.line, pos.y, pos.x, end.line, end.y, end.x, true, false, null);
}
}
};