Index: CodeEditor/CodeEditor.cpp =================================================================== --- CodeEditor/CodeEditor.cpp (revision 58) +++ CodeEditor/CodeEditor.cpp (working copy) @@ -17,7 +17,6 @@ if(check_edited) { bar.ClearErrors(line); - bar.SetEdited(line, 1); bar.Refresh(); } } @@ -36,6 +35,8 @@ } void CodeEditor::PostInsert(int pos, const WString& text) { + if(check_edited) + bar.SetEdited(GetLine(pos)); if(IsFullRefresh()) return; if(!ScanSyntax(GetLine(pos + text.GetLength()) + 1).MatchHilite(rm_ins)) { if(text.GetLength() == 1 && *text == '(' || *text == '[' || *text == ']' || *text == ')') @@ -56,6 +57,8 @@ } void CodeEditor::PostRemove(int pos, int size) { + if(check_edited) + bar.SetEdited(GetLine(pos)); if(IsFullRefresh()) return; if(!ScanSyntax(GetLine(pos) + 1).MatchHilite(rm_ins)) { if(rmb == '(' || rmb == '[' || rmb == ']' || rmb == ')') @@ -73,8 +76,6 @@ void CodeEditor::InsertLines(int line, int count) { bar.InsertLines(line, count); - for (int i = 0; i < count; i++) - bar.SetEdited(line + i, 1); } void CodeEditor::RemoveLines(int line, int count) { @@ -1009,6 +1010,8 @@ highlight_bracket_pos = 10; SetTimeCallback(-20, THISBACK(Periodic), TIMEID_PERIODIC); auto_enclose = false; + mark_lines = true; + check_edited = false; } CodeEditor::~CodeEditor() {} Index: CodeEditor/CodeEditor.h =================================================================== --- CodeEditor/CodeEditor.h (revision 58) +++ CodeEditor/CodeEditor.h (working copy) @@ -22,13 +22,19 @@ String breakpoint; int count; int error; + int firstedited; int edited; LineInfoRecord() { error = 0; edited = 0; } }; - typedef Array LineInfo; +struct LineInfoRemRecord : Moveable { + int firstedited; + int edited; +}; +typedef Vector LineInfoRem; + void Renumber(LineInfo& lf); void ClearBreakpoints(LineInfo& lf); void ValidateBreakpoints(LineInfo& lf); @@ -48,11 +54,14 @@ int lineno; String breakpoint; int error; + int firstedited; int edited; - LnInfo() { lineno = -1; error = 0; edited = 0; } + LnInfo() { lineno = -1; error = 0; firstedited = 0; edited = 0; } }; Vector li; + LineInfoRem li_removed; + int sy; CodeEditor *editor; int ptrline[2]; @@ -60,7 +69,9 @@ bool bingenabled; bool hilite_if_endif; bool line_numbers; - + bool ignored_next_edit; + int next_age; + String& PointBreak(int& y); void sPaintImage(Draw& w, int y, int fy, const Image& img); @@ -79,7 +90,8 @@ String GetBreakpoint(int ln); void SetBreakpoint(int ln, const String& s); - void SetEdited(int ln, int edit); + void SetEdited(int ln, int count = 1); + void ClearEdited(); void SetError(int ln, int err); void ClearErrors(int ln); @@ -87,6 +99,8 @@ LineInfo GetLineInfo() const; void SetLineInfo(const LineInfo& li, int total); + LineInfoRem & GetLineInfoRem() { return li_removed; } + void SetLineInfoRem(LineInfoRem& li) { li_removed = li; } int GetLineNo(int lineno) const; int GetNoLine(int line) const; @@ -128,6 +142,7 @@ virtual void MouseMove(Point p, dword keyflags); virtual void Serialize(Stream& s); void CheckEdited(bool e = true) { check_edited = e; } + bool GetCheckEdited() { return check_edited; } protected: virtual void HighlightLine(int line, Vector& h, int pos); @@ -222,6 +237,7 @@ Time last_key_time; bool auto_enclose; + bool mark_lines; bool check_edited; struct FindReplace : WithIDEFindReplaceLayout { @@ -391,6 +407,8 @@ LineInfo GetLineInfo() const { return bar.GetLineInfo(); } void SetLineInfo(const LineInfo& lf); + LineInfoRem GetLineInfoRem() { return LineInfoRem(bar.GetLineInfoRem(), 0); } + void SetLineInfoRem(LineInfoRem& lf) { bar.SetLineInfoRem(LineInfoRem(lf, 0)); } double GetStatEditTime() const { return stat_edit_time; } void Renumber() { bar.Renumber(GetLineCount()); } void ClearBreakpoints() { bar.ClearBreakpoints(); } @@ -403,6 +421,8 @@ void SetBreakpoint(int line, const String& b) { bar.SetBreakpoint(line, b); } void SetError(int line, int err) { bar.SetError(line, err); } void ClearErrors(int line = -1) { bar.ClearErrors(line); } + void ClearEdited() { bar.ClearEdited(); } + int GetUndoCount() { return undo.GetCount(); } void GotoLine(int line); void EnableBreakpointing() { bar.EnableBreakpointing(true); } void DisableBreakpointing() { bar.EnableBreakpointing(false); } @@ -415,6 +435,8 @@ void IndentAmount(int ia) { indent_amount = ia; } void NoParenthesisIndent(bool b) { no_parenthesis_indent = b; } void LineNumbers(bool b) { bar.LineNumbers(b); } + void MarkLines(bool b) { mark_lines = b; } + bool GetMarkLines() { return mark_lines; } void AutoEnclose(bool b) { auto_enclose = b; } void HideBar() { bar.Hide(); } Index: CodeEditor/EditorBar.cpp =================================================================== --- CodeEditor/EditorBar.cpp (revision 58) +++ CodeEditor/EditorBar.cpp (working copy) @@ -11,6 +11,7 @@ t.lineno = 0; t.count = lf[0].count; t.error = lf[0].error; + t.firstedited = lf[0].firstedited; t.edited = lf[0].edited; l += t.count; } @@ -23,6 +24,7 @@ LineInfoRecord& t = tf.Add(); t.breakpoint = r.breakpoint; t.error = r.error; + t.firstedited = r.firstedited; t.edited = r.edited; t.count = r.count; t.lineno = l; @@ -119,15 +121,16 @@ } previf = nextif; } - if(edit > 0) { + + if (editor->GetMarkLines()) { int width = CodeEditorImg::Breakpoint().GetWidth() >> 1; - w.DrawRect(0, y, width, fy, LtBlue); + if (edit) { + int age = (int)(log((double)(editor->GetUndoCount() + 1 - edit)) * 30); + w.DrawRect(0, y, width, fy, Blend(LtBlue, SColorLtFace(), min(220, age))); + } + if (err) + w.DrawRect(width, y, width, fy, err == 1 ? LtRed : (err == 2 ? Color(255, 175, 0) : Green)); } - if(err > 0) { - int width = CodeEditorImg::Breakpoint().GetWidth() >> 1; - w.DrawRect(width, y, width, fy, err == 1 ? LtRed : Color(255, 175, 0)); - } - if(!b.IsEmpty()) sPaintImage(w, y, fy, b == "1" ? CodeEditorImg::Breakpoint() : b == "\xe" ? CodeEditorImg::InvalidBreakpoint() : @@ -179,10 +182,37 @@ void EditorBar::InsertLines(int i, int count) { li.InsertN(minmax(i, 0, li.GetCount()), max(count, 0)); + if (editor->GetCheckEdited()) { + if (editor->IsUndoOp() && li_removed.GetCount() >= count) { + for (int t = 0; t < count; t++) { + li.At(i + t).firstedited = li_removed[li_removed.GetCount() - count + t].firstedited; + li[i + t].edited = li_removed[li_removed.GetCount() - count + t].edited; + } + li_removed.Drop(count); + SetEdited(i + count, 1); + ignored_next_edit = true; + } + else { + if (li[i].firstedited == 0) + li[i].firstedited = li.At(i + count).firstedited; + SetEdited(i + 1, count); + } + } Refresh(); } void EditorBar::RemoveLines(int i, int count) { + if (editor->GetCheckEdited() && !editor->IsUndoOp()) { + for (int t = i - 1; t < i + count - 1; t++) { + LineInfoRemRecord& rm = li_removed.Add(); + rm.firstedited = li[t].firstedited; + rm.edited = li[t].edited; + } + if (li.At(i + count - 1).firstedited) + next_age = li[i + count - 1].firstedited; + else + next_age = editor->GetUndoCount(); + } i = minmax(i, 0, li.GetCount()); li.Remove(i, minmax(count, 0, li.GetCount() - i)); Refresh(); @@ -191,6 +221,8 @@ void EditorBar::ClearLines() { li.Clear(); li.Shrink(); + li_removed.Clear(); + li_removed.Shrink(); Refresh(); } @@ -205,6 +237,7 @@ r.count = 1; r.breakpoint = ln.breakpoint; r.error = ln.error; + r.firstedited = ln.firstedited; r.edited = ln.edited; l = -2; } @@ -236,6 +269,7 @@ ln.lineno = l; ln.breakpoint = r.breakpoint; ln.error = r.error; + ln.firstedited = r.firstedited; ln.edited = r.edited; if(l >= 0) l++; } @@ -276,11 +310,48 @@ WhenBreakpoint(ln); } -void EditorBar::SetEdited(int ln, int edit) +void EditorBar::SetEdited(int ln, int count) { - li.At(ln).edited = edit; + if (ignored_next_edit) { + ignored_next_edit = false; + return; + } + int age = editor->GetUndoCount() + 1; + bool undo = editor->IsUndoOp(); + for (int i = 0; i < count; i++) { + if (undo) { + if (li.At(ln + i).firstedited >= age - 1) { + li[ln + i].firstedited = 0; + li[ln + i].edited = 0; + } + } + else { + if (next_age) { + li[ln + i].firstedited = next_age; + li[ln + i].edited = age; + next_age = 0; + } + else { + if (li.At(ln + i).firstedited == 0) + li[ln + i].firstedited = age; + li[ln + i].edited = age; + } + } + } + Refresh(); } +void EditorBar::ClearEdited() +{ + for (int i = 0; i < li.GetCount(); i++) { + li.At(i).firstedited = 0; + li[i].edited = 0; + } + li_removed.Clear(); + li_removed.Shrink(); + Refresh(); +} + void EditorBar::SetError(int ln, int err) { li.At(ln).error = err; @@ -288,11 +359,16 @@ void EditorBar::ClearErrors(int line) { - for(int i = 0; i < li.GetCount(); i++) { - if(li[i].error && (line < 0 || li[i].lineno == line)) { - li[i].error = 0; - } - } + int count; + if (line < 0) { + line = 0; + count = li.GetCount(); + } + else + count = line + 1; + + for(int i = line; i < count; i++) + li[i].error = 0; } int EditorBar::GetLineNo(int lineno) const { @@ -340,6 +416,8 @@ bingenabled = true; hilite_if_endif = true; line_numbers = false; + ignored_next_edit = false; + next_age = 0; } EditorBar::~EditorBar() Index: CtrlLib/Text.cpp =================================================================== --- CtrlLib/Text.cpp (revision 58) +++ CtrlLib/Text.cpp (working copy) @@ -9,6 +9,7 @@ Clear(); undoserial = 0; incundoserial = false; + undo_op = false; WhenBar = THISBACK(StdBar); charset = CHARSET_UNICODE; color[INK_NORMAL] = SColorText; @@ -458,6 +459,7 @@ void TextCtrl::Undo() { if(undo.IsEmpty()) return; + undo_op = true; int nc = 0; int s = undo.Tail().serial; while(undo.GetCount()) { @@ -485,6 +487,7 @@ ClearSelection(); PlaceCaret(nc, false); Action(); + undo_op = false; } void TextCtrl::Redo() { Index: CtrlLib/TextEdit.h =================================================================== --- CtrlLib/TextEdit.h (revision 58) +++ CtrlLib/TextEdit.h (working copy) @@ -67,6 +67,7 @@ BiArray undo; BiArray redo; int dirty; + int undo_op; byte charset; bool selclick; @@ -155,6 +156,7 @@ bool IsUndo() const { return undo.GetCount(); } bool IsRedo() const { return redo.GetCount(); } void ClearUndo() { undo.Clear(); redo.Clear(); } + bool IsUndoOp() const { return undo_op; } UndoData PickUndoData(); void SetPickUndoData(pick_ UndoData& data); Index: ide/Build.cpp =================================================================== --- ide/Build.cpp (revision 58) +++ ide/Build.cpp (working copy) @@ -570,6 +570,7 @@ ProcessEvents(); ms = msecs(); } + SetErrorEditor(); } if(ok || !stoponerrors) ok = BuildPackage(wspc, 0, build_order.GetCount(), build_order.GetCount() + 1, Index: ide/FindInFiles.cpp =================================================================== --- ide/FindInFiles.cpp (revision 58) +++ ide/FindInFiles.cpp (working copy) @@ -337,6 +337,7 @@ console << Format("%d occurrence(s) have been found.\n", n); } } + SetErrorEditor(); } void Ide::FindString(bool back) Index: ide/ide.cpp =================================================================== --- ide/ide.cpp (revision 58) +++ ide/ide.cpp (working copy) @@ -332,12 +332,12 @@ return false; } -bool Ide::FindLineError(String ln, Host& host, String &file, int &lineno, int &error) { +bool Ide::FindLineError(String ln, Host& host, String& file, int& lineno, int& error) { Vector wspc_paths; VectorMap bm = GetMethodVars(method); bool is_java = (bm.Get("BUILDER", Null) == "JDK"); const char *s = ln; - error = ln.Find("arning", 0) > 0 ? 2 : 1; + error = ln.Find("error", 0) > 0 ? 1 : (ln.Find("warning", 0) > 0 ? 2 : 3); while(*s == ' ' || *s == '\t') s++; for(; *s; s++) { @@ -478,6 +478,9 @@ void Ide::ClearErrorEditor() { + if (!mark_lines) + return; + for(int i = 0; i < filedata.GetCount(); i++) { ClearErrorEditor(filedata.GetKey(i)); } @@ -485,6 +488,9 @@ void Ide::ClearErrorEditor(String file) { + if (!mark_lines) + return; + if(file == editfile) editor.ClearErrors(); else { @@ -499,6 +505,9 @@ void Ide::SetErrorEditor() { + if (!mark_lines) + return; + bool refresh = false; String file; int lineno; Index: ide/ide.h =================================================================== --- ide/ide.h (revision 58) +++ ide/ide.h (working copy) @@ -565,10 +565,11 @@ Point columnline; LineEdit::UndoData undodata; LineInfo lineinfo; + LineInfoRem lineinforem; void Clear() { filetime = Null; editpos.Clear(); undodata.Clear(); - columnline = Null; lineinfo.Clear(); + columnline = Null; lineinfo.Clear(); lineinforem.Clear(); } }; @@ -653,6 +654,7 @@ bool header_guards; bool filetabs; bool auto_enclose; + bool mark_lines; int insert_include; int bordercolumn; Color bordercolor; @@ -784,6 +786,8 @@ void FindString(bool back); void FindNextError(); void FindPrevError(); + void ClearEditedFile(); + void ClearEditedAll(); void EditSpecial(Bar& menu); void TranslateString(); Index: ide/ide.key =================================================================== --- ide/ide.key (revision 58) +++ ide/ide.key (working copy) @@ -82,3 +82,5 @@ KEY(SWAPS, "Go to definition/declaration", K_ALT_I) KEY(JUMPS, "Go to symbol definition", K_ALT_J) //KEY(INSERTCOLOR, "Insert choosen color value.."); +KEY(CLEARMARKERSFILE, "Remove change markers in file", K_ALT_R) +KEY(CLEARMARKERSALL, "Reomve all change markers", K_SHIFT|K_ALT_R) Index: ide/ide.lay =================================================================== --- ide/ide.lay (revision 58) +++ ide/ide.lay (working copy) @@ -416,6 +416,7 @@ ITEM(Switch, insert_include, SetLabel(t_("No #include in new souces\n#include first\n#include previous")).LeftPosZ(316, 156).TopPosZ(32, 56)) ITEM(Option, header_guards, SetLabel(t_("Insert guards to new headers")).LeftPosZ(316, 164).TopPosZ(12, 15)) ITEM(Option, auto_enclose, SetLabel(t_("[ { ( \" / * enclose selection")).LeftPosZ(12, 168).TopPosZ(236, 15)) + ITEM(Option, mark_lines, SetLabel(t_("Mark lines with errors, warning and changes")).LeftPosZ(12, 256).TopPosZ(256, 15)) END_LAYOUT LAYOUT(SetupIdeLayout, 512, 248) @@ -485,3 +486,4 @@ ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(264, 64).TopPosZ(32, 24)) ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(332, 64).TopPosZ(32, 24)) END_LAYOUT + Index: ide/idebar.cpp =================================================================== --- ide/idebar.cpp (revision 58) +++ ide/idebar.cpp (working copy) @@ -131,7 +131,6 @@ (menu.*add)("Paste", CtrlImg::paste(), THISBACK(EditPaste)) .Key(K_CTRL_V) .Help("Insert text from clipboard at cursor location"); - menu.MenuSeparator(); menu.Add(AK_SPACESTOTABS, THISBACK(EditMakeTabs)) @@ -172,6 +171,14 @@ .Help("Find any ordinary string constant (\"\" - delimited)"); menu.Add(AK_FINDSTRINGBACK, THISBACK1(FindString, true)) .Help("Find any ordinary string constant (\"\" - delimited) backwards"); + if (mark_lines && menu.IsMenuBar()) { + menu.Separator(); + menu.Add(AK_CLEARMARKERSFILE, THISBACK(ClearEditedFile)) + .Help("Remove change markers in current file"); + menu.Add(AK_CLEARMARKERSALL, THISBACK(ClearEditedAll)) + .Help("Remove change markers in all files"); + menu.Separator(); + } if(menu.IsMenuBar()) menu.Add("Special", THISBACK(EditSpecial)); } Index: ide/idefile.cpp =================================================================== --- ide/idefile.cpp (revision 58) +++ ide/idefile.cpp (working copy) @@ -241,6 +241,7 @@ FileData& fd = Filedata(editfile); fd.lineinfo = editor.GetLineInfo(); + fd.lineinforem = editor.GetLineInfoRem(); fd.editpos = editor.GetEditPos(); fd.columnline = editor.GetColumnLine(fd.editpos.cursor); fd.filetime = edittime; @@ -390,6 +391,7 @@ editor.SetCursor(editor.GetColumnLinePos(fd.columnline)); editor.SetPickUndoData(fd.undodata); editor.SetLineInfo(fd.lineinfo); + editor.SetLineInfoRem(fd.lineinforem); if(ff.IsReadOnly()) editor.SetReadOnly(); } @@ -578,8 +580,10 @@ editor2.Highlight(editor.GetHighlight()); editor2.LoadHlStyles(editor.StoreHlStyles()); byte charset = editor.GetCharset(); + editor2.CheckEdited(false); editor2.Set(editor.Get(charset), charset); editor2.SetEditPosSb(editor.GetEditPos()); + editor2.CheckEdited(); IdeQuickTabs h; h.Set(tabs); tabs.Set(tabs2); @@ -662,3 +666,24 @@ editor2.topsbbutton1 <<= THISBACK(CloseSplit); } } + +void Ide::ClearEditedFile() +{ + editor.ClearEdited(); +} + +void Ide::ClearEditedAll() +{ + ClearEditedFile(); + for(int i = 0; i < filedata.GetCount(); i++) { + LineInfo li = editor.GetLineInfo(); + LineInfoRem lir = editor.GetLineInfoRem(); + FileData& fd = Filedata(filedata.GetKey(i)); + editor.SetLineInfo(fd.lineinfo); + editor.SetLineInfoRem(fd.lineinforem); + ClearEditedFile(); + fd.lineinfo = editor.GetLineInfo(); + fd.lineinforem = editor.GetLineInfoRem(); + editor.SetLineInfo(li); + } +} Index: ide/idewin.cpp =================================================================== --- ide/idewin.cpp (revision 58) +++ ide/idewin.cpp (working copy) @@ -504,7 +504,8 @@ filetabs = true; auto_enclose = false; - + mark_lines = true; + bordercolumn = 96; bordercolor = SColorFace(); Index: ide/Setup.cpp =================================================================== --- ide/Setup.cpp (revision 58) +++ ide/Setup.cpp (working copy) @@ -136,6 +136,7 @@ editor.HiliteIfEndif(hilite_if_endif); editor.LineNumbers(line_numbers); editor.AutoEnclose(auto_enclose); + editor.MarkLines(mark_lines); editor.BorderColumn(bordercolumn, bordercolor); editor.Refresh(); } @@ -213,6 +214,7 @@ (edt.header_guards, header_guards) (edt.insert_include, insert_include) (edt.auto_enclose, auto_enclose) + (edt.mark_lines, mark_lines) (edt.bordercolumn, bordercolumn) (edt.bordercolor, bordercolor) (ide.show_status_bar, show_status_bar)