1 #ifndef IDEEDITOR_H
2 #define IDEEDITOR_H
3
4 //#include <ide/Common/Common.h>
5 #include <CtrlLib/CtrlLib.h>
6 #include <plugin/pcre/Pcre.h>
7
8 namespace Upp {
9
10 #define LAYOUTFILE <CodeEditor/CodeEditor.lay>
11 #include <CtrlCore/lay.h>
12
13 #define IMAGEVECTOR Vector
14 #define IMAGECLASS CodeEditorImg
15 #define IMAGEFILE <CodeEditor/CodeEditor.iml>
16 #include <Draw/iml_header.h>
17
18
19 void FindWildcardMenu(Callback1<const char *> cb, Point p, bool tablf, Ctrl *owner, bool regexp);
20
21 struct LineInfoRecord {
22 int lineno;
23 String breakpoint;
24 int count;
25 int error;
26 int firstedited;
27 int edited;
28
LineInfoRecordLineInfoRecord29 LineInfoRecord() { error = 0; edited = 0; }
30 };
31
32 typedef Array<LineInfoRecord> LineInfo;
33
34 void ClearErrors(LineInfo& li);
35
36 struct LineInfoRemRecord : Moveable<LineInfoRemRecord> {
37 int firstedited;
38 int edited;
39 };
40
41 typedef Vector<LineInfoRemRecord> LineInfoRem;
42
43 void Renumber(LineInfo& lf);
44 void ClearBreakpoints(LineInfo& lf);
45 void ValidateBreakpoints(LineInfo& lf);
46
47 class CodeEditor;
48
49 class EditorBar : public FrameLeft<Ctrl> {
50 public:
51 virtual void Paint(Draw& w);
52 virtual void MouseMove(Point p, dword flags);
53 virtual void MouseLeave();
54 virtual void LeftDown(Point p, dword flags);
55 virtual void LeftDouble(Point p, dword flags);
56 virtual void RightDown(Point p, dword flags);
57 virtual void MouseWheel(Point p, int zdelta, dword keyflags);
58
59 private:
60 struct LnInfo : Moveable<LnInfo> {
61 int lineno;
62 String breakpoint;
63 int error;
64 int firstedited;
65 int edited;
66 Image icon;
67 String annotation;
68
LnInfoLnInfo69 LnInfo() { lineno = -1; error = 0; firstedited = 0; edited = 0; }
70 };
71
72 Vector<LnInfo> li;
73 LineInfoRem li_removed;
74
75 CodeEditor *editor;
76 int ptrline[2];
77 Image ptrimg[2];
78 bool bingenabled;
79 bool hilite_if_endif;
80 bool line_numbers;
81 int annotations;
82 bool ignored_next_edit;
83 int next_age;
84 int active_annotation;
85
86 String& PointBreak(int& y);
87 void sPaintImage(Draw& w, int y, int fy, const Image& img);
88
89 public:
90 Event<int> WhenBreakpoint;
91 Event<> WhenAnnotationMove;
92 Event<> WhenAnnotationClick;
93 Event<> WhenAnnotationRightClick;
94
95 void InsertLines(int i, int count);
96 void RemoveLines(int i, int count);
97 void ClearLines();
98
Scroll()99 void Scroll() { Refresh(); }
100
101 void SyncSize();
102
103 void Renumber(int linecount);
104 void ClearBreakpoints();
105 void ValidateBreakpoints();
106
107 String GetBreakpoint(int ln);
108 void SetBreakpoint(int ln, const String& s);
109 void SetEdited(int ln, int count = 1);
110 void ClearEdited();
111 void SetError(int ln, int err);
112 void ClearErrors(int ln);
113
SetEditor(CodeEditor * e)114 void SetEditor(CodeEditor *e) { editor = e; }
115
116 LineInfo GetLineInfo() const;
117 void SetLineInfo(const LineInfo& li, int total);
GetLineInfoRem()118 LineInfoRem & GetLineInfoRem() { return li_removed; }
SetLineInfoRem(LineInfoRem pick_ li)119 void SetLineInfoRem(LineInfoRem pick_ li) { li_removed = pick(li); }
120
121 void ClearAnnotations();
122 void SetAnnotation(int line, const Image& img, const String& ann);
123 String GetAnnotation(int line) const;
124
125 int GetLineNo(int lineno) const;
126 int GetNoLine(int line) const;
127
128 void SetPtr(int line, const Image& img, int i);
129 void HidePtr();
130
EnableBreakpointing(bool b)131 void EnableBreakpointing(bool b) { bingenabled = b; }
HiliteIfEndif(bool b)132 void HiliteIfEndif(bool b) { hilite_if_endif = b; Refresh(); }
133 void LineNumbers(bool b);
134 void Annotations(int width);
135
IsHiliteIfEndif()136 bool IsHiliteIfEndif() const { return hilite_if_endif; }
137
GetActiveAnnotationLine()138 int GetActiveAnnotationLine() const { return active_annotation; }
139
140 EditorBar();
141 virtual ~EditorBar();
142 };
143
144 struct IdentPos {
145 int begin;
146 int end;
147 String ident;
148 };
149
150 Array<IdentPos> GetLineIdent(const char *line);
151 Vector<Point> GetLineString(const wchar *wline, bool& is_begin, bool& is_end);
152
CharFilterCIdent(int i)153 inline int CharFilterCIdent(int i) { return IsAlNum(i) || i == '_' ? i : 0; }
iscidl(int c)154 inline bool iscidl(int c) { return iscid(c) || IsLetter(c); }
islbrkt(int c)155 inline bool islbrkt(int c) { return c == '{' || c == '[' || c == '('; }
isrbrkt(int c)156 inline bool isrbrkt(int c) { return c == '}' || c == ']' || c == ')'; }
isbrkt(int c)157 inline bool isbrkt(int c) { return islbrkt(c) || isrbrkt(c); }
158
159 struct FindReplaceDlg : FrameBottom< WithIDEFindReplaceLayout<TopWindow> > {
160 WString itext;
161 bool replacing;
162
163 virtual bool Key(dword key, int count);
164 void Setup(bool doreplace);
165 void Sync();
IsIncrementalFindReplaceDlg166 bool IsIncremental() const { return incremental.IsEnabled() && incremental; }
167
168 typedef FindReplaceDlg CLASSNAME;
169
170 FindReplaceDlg();
171 };
172
173 #include "Syntax.h"
174 #include "CSyntax.h"
175 #include "DiffSyntax.h"
176 #include "TagSyntax.h"
177 #include "LogSyntax.h"
178 #include "PythonSyntax.h"
179
180 class CodeEditor : public LineEdit, public HighlightSetup
181 {
182 friend class EditorBar;
183
184 public:
185 virtual bool Key(dword code, int count);
186 virtual void LeftDown(Point p, dword keyflags);
187 virtual void LeftDouble(Point p, dword keyflags);
188 virtual void LeftTriple(Point p, dword keyflags);
189 virtual void LeftRepeat(Point p, dword keyflags);
190 virtual void MouseMove(Point p, dword keyflags);
191 virtual Image CursorImage(Point p, dword keyflags);
192 virtual void Serialize(Stream& s);
193 virtual void MouseLeave();
194 virtual void MouseWheel(Point p, int zdelta, dword keyFlags);
195
196 protected:
197 virtual void HighlightLine(int line, Vector<LineEdit::Highlight>& h, int64 pos);
198 virtual void PreInsert(int pos, const WString& s);
199 virtual void PostInsert(int pos, const WString& s);
200 virtual void PreRemove(int pos, int size);
201 virtual void PostRemove(int pos, int size);
202 virtual void DirtyFrom(int line);
203 virtual void SelectionChanged();
204
205 virtual void ClearLines();
206 virtual void InsertLines(int line, int count);
207 virtual void RemoveLines(int line, int count);
208
209 virtual void NewScrollPos();
210
211 virtual String GetPasteText();
212
213 EditorBar bar;
214 Vector<int> line2;
215
216 struct SyntaxPos {
217 int line;
218 String data;
219
ClearSyntaxPos220 void Clear() { line = 0; data.Clear(); }
221 };
222
223 SyntaxPos syntax_cache[6];
224
225 // EditorSyntax rm_ins;
226
227 char rmb;
228 int64 highlight_bracket_pos0;
229 int64 highlight_bracket_pos;
230 bool bracket_flash;
231 int64 bracket_start;
232
233 bool barline;
234 double stat_edit_time;
235 Time last_key_time;
236
237 bool auto_enclose;
238 bool mark_lines;
239 bool check_edited;
240 bool persistent_find_replace;
241 bool do_ff_restore_pos;
242 bool withfindreplace;
243 bool wordwrap;
244
245 int ff_start_pos;
246
247 FindReplaceDlg findreplace;
248
249 enum {
250 WILDANY = 16,
251 WILDONE,
252 WILDSPACE,
253 WILDNUMBER,
254 WILDID,
255 };
256
257 struct Found {
258 int type;
259 WString text;
260 };
261
262 Array<Found> foundwild;
263 WString foundtext;
264 bool foundsel;
265 bool found, notfoundfw, notfoundbk;
266 int64 foundpos;
267 int foundsize;
268
269 enum { SEL_CHARS, SEL_WORDS, SEL_LINES };
270 int selkind;
271
272 WString illuminated;
273
274 String iwc;
275
276 String highlight;
277
278 int spellcheck_comments = 0;
279 bool wordwrap_comments = true;
280
281 struct Tip : Ctrl {
282 Value v;
283 const Display *d;
284
285 virtual void Paint(Draw& w);
286
287 Tip();
288 };
289
290 Tip tip;
291 int tippos;
292
293 int replacei;
294
295 bool search_canceled;
296 int search_time0;
297 One<Progress> search_progress;
298
299 String refresh_info; // serialized next line syntax context to detect the need of full Refresh
300
301 struct HlSt;
302
303 bool MouseSelSpecial(Point p, dword flags);
304 void InitFindReplace();
305 void CancelBracketHighlight(int64& pos);
306 void FindPrevNext(bool prev);
307 void CheckBrackets();
308 void OpenNormalFindReplace0(bool replace);
309 void OpenNormalFindReplace(bool replace);
310 void FindReplaceAddHistory();
311 void FindWildcard();
312 void ReplaceWildcard();
313 void InsertWildcard(const char *s);
314 void IncrementalFind();
315 void NotFound();
316 void NoFindError();
317 void CheckSyntaxRefresh(int64 pos, const WString& text);
318
319 void SetFound(int fi, int type, const WString& text);
320
321 int Match(const wchar *f, const wchar *s, int line, bool we, bool icase, int fi = 0);
322 WString GetWild(int type, int& i);
323 WString GetReplaceText();
324
325 bool InsertRS(int chr, int count = 1);
326
327 void IndentInsert(int chr, int count);
328
329 void ForwardWhenBreakpoint(int i);
330
331 bool ToggleSimpleComment(int &start_line, int &end_line, bool usestars = true);
332 void ToggleLineComments(bool usestars = false);
333 void ToggleStarComments();
334 void Enclose(const char *c1, const char *c2, int l = -1, int h = -1);
335 void Make(Event<String&> op);
336 void TabsOrSpaces(String& out, bool maketabs);
337 void LineEnds(String& out);
338
339 enum {
340 TIMEID_PERIODIC = Ctrl::TIMEID_COUNT,
341 TIMEID_COUNT,
342 };
343
344 void Periodic();
345
346 void StartSearchProgress(int64 l, int64 h);
347 bool SearchProgress(int line);
348 bool SearchCanceled();
349 void EndSearchProgress();
350
351 String GetRefreshInfo(int pos);
352
353 public:
354 struct MouseTip {
355 int pos;
356 Value value;
357 const Display *display;
358 Size sz;
359 };
360
361 Event<> WhenSelection;
362 Gate<MouseTip&> WhenTip;
363 Event<> WhenLeftDown;
364 Event<int64> WhenCtrlClick;
365 Event<> WhenAnnotationMove;
366 Event<> WhenAnnotationClick;
367 Event<> WhenAnnotationRightClick;
368 Event<> WhenOpenFindReplace;
369 Event<String&> WhenPaste;
370 Event<> WhenUpdate;
371 Event<int> WhenBreakpoint;
372
373 Event<const Vector<Tuple<int64, int>>&> WhenFindAll;
374
375 FrameTop<Button> topsbbutton;
376 FrameTop<Button> topsbbutton1;
377
378 static dword find_next_key;
379 static dword find_prev_key;
380 static dword replace_key;
381
382 void Clear();
383
384 void Highlight(const String& h);
GetHighlight()385 String GetHighlight() const { return highlight; }
386
387 void EscapeFindReplace();
388 void CloseFindReplace();
389 void FindReplace(bool pick_selection, bool pick_text, bool replace);
390 void FindAll();
391 bool FindFrom(int64 pos, bool back, bool block);
392 bool RegExpFind(int64 pos, bool block);
393 bool Find(bool back, bool block);
394 bool Find(bool back, bool blockreplace, bool replace);
395 void FindNext();
396 void FindPrev();
397 bool GetStringRange(int64 cursor, int64& b, int64& e) const;
GetStringRange(int64 & b,int64 & e)398 bool GetStringRange(int64& b, int64& e) const { return GetStringRange(GetCursor64(), b, e); }
399 bool FindString(bool back);
400 bool FindLangString(bool back);
401 void Replace();
402 void ReplaceAll(bool rest);
403 int BlockReplace();
404
405 void MakeTabsOrSpaces(bool tabs);
406 void MakeLineEnds();
407
408 void CopyWord();
409 void SwapChars();
410 void DuplicateLine();
411 void Put(int chr);
412 void FinishPut();
413
414 void SerializeFind(Stream& s);
IsFindOpen()415 bool IsFindOpen() const { return findreplace.IsOpen(); }
FindClose()416 void FindClose() { CloseFindReplace(); }
417
418 void Goto();
419
420 void DoFind();
421 void DoFindBack();
422
423 // void FindWord(bool back);
424 WString GetI();
425 void SetI(Ctrl *edit);
426 void PutI(WithDropChoice<EditString>& edit);
427
428 void MoveNextWord(bool sel);
429 void MovePrevWord(bool sel);
430 void MoveNextBrk(bool sel);
431 void MovePrevBrk(bool sel);
432
433 String GetWord(int64 pos);
434 String GetWord();
435
436 bool GetWordPos(int64 pos, int64& l, int64& h);
437
438 void DeleteWord();
439 void DeleteWordBack();
440 void SetLineSelection(int l, int h);
441 bool GetLineSelection(int& l, int& h);
442 void TabRight();
443 void TabLeft();
444
445 void CheckEdited(bool e = true) { check_edited = e; }
GetCheckEdited()446 bool GetCheckEdited() { return check_edited; }
447
EditorBarLayout()448 void EditorBarLayout() { bar.SyncSize(); }
449
GetLineInfo()450 LineInfo GetLineInfo() const { return bar.GetLineInfo(); }
451 void SetLineInfo(const LineInfo& lf);
GetLineInfoRem()452 LineInfoRem GetLineInfoRem() { return LineInfoRem(bar.GetLineInfoRem(), 0); }
SetLineInfoRem(LineInfoRem pick_ lf)453 void SetLineInfoRem(LineInfoRem pick_ lf) { bar.SetLineInfoRem(LineInfoRem(lf, 0)); }
GetStatEditTime()454 double GetStatEditTime() const { return stat_edit_time; }
Renumber()455 void Renumber() { bar.Renumber(GetLineCount()); }
ClearBreakpoints()456 void ClearBreakpoints() { bar.ClearBreakpoints(); }
ValidateBreakpoints()457 void ValidateBreakpoints() { bar.ValidateBreakpoints(); }
GetLineNo(int line)458 int GetLineNo(int line) const { return bar.GetLineNo(line); }
GetNoLine(int line)459 int GetNoLine(int line) const { return bar.GetNoLine(line); }
SetPtr(int line,const Image & img,int i)460 void SetPtr(int line, const Image& img, int i){ bar.SetPtr(line, img, i); }
HidePtr()461 void HidePtr() { bar.HidePtr(); }
GetBreakpoint(int line)462 String GetBreakpoint(int line) { return bar.GetBreakpoint(line); }
SetBreakpoint(int line,const String & b)463 void SetBreakpoint(int line, const String& b) { bar.SetBreakpoint(line, b); }
SetError(int line,int err)464 void SetError(int line, int err) { bar.SetError(line, err); }
465 void ClearErrors(int line = -1) { bar.ClearErrors(line); }
ClearEdited()466 void ClearEdited() { bar.ClearEdited(); }
GetUndoCount()467 int GetUndoCount() { return undo.GetCount(); }
468 void GotoLine(int line);
EnableBreakpointing()469 void EnableBreakpointing() { bar.EnableBreakpointing(true); }
DisableBreakpointing()470 void DisableBreakpointing() { bar.EnableBreakpointing(false); }
471 void Renumber2();
472 int GetLine2(int i) const;
473 void ReformatComment();
474
475 // TODO: Syntax: Remove
HiliteScope(byte b)476 void HiliteScope(byte b) { EditorSyntax::hilite_scope = b; Refresh(); }
HiliteBracket(byte b)477 void HiliteBracket(byte b) { EditorSyntax::hilite_bracket = b; Refresh(); }
HiliteIfDef(byte b)478 void HiliteIfDef(byte b) { EditorSyntax::hilite_ifdef = b; Refresh(); }
HiliteIfEndif(bool b)479 void HiliteIfEndif(bool b) { bar.HiliteIfEndif(b); }
480
ThousandsSeparator(bool b)481 void ThousandsSeparator(bool b) { thousands_separator = b; Refresh(); }
IndentSpaces(bool is)482 void IndentSpaces(bool is) { indent_spaces = is; }
IndentAmount(int ia)483 void IndentAmount(int ia) { indent_amount = ia; }
NoParenthesisIndent(bool b)484 void NoParenthesisIndent(bool b) { no_parenthesis_indent = b; }
485
SpellcheckComments(int lang)486 void SpellcheckComments(int lang) { spellcheck_comments = lang; Refresh(); }
GetSpellcheckComments()487 int GetSpellcheckComments() const { return spellcheck_comments; }
WordwrapComments(bool b)488 void WordwrapComments(bool b) { wordwrap_comments = b; }
IsWordwrapComments()489 bool IsWordwrapComments() const { return wordwrap_comments; }
490
NoFindReplace()491 void NoFindReplace() { withfindreplace = false; }
492
LineNumbers(bool b)493 void LineNumbers(bool b) { bar.LineNumbers(b); }
MarkLines(bool b)494 void MarkLines(bool b) { mark_lines = b; }
GetMarkLines()495 bool GetMarkLines() { return mark_lines; }
AutoEnclose(bool b)496 void AutoEnclose(bool b) { auto_enclose = b; }
BarLine(bool b)497 void BarLine(bool b) { barline = b; }
WordWrap(bool b)498 void WordWrap(bool b) { wordwrap = b; }
499
500 void PersistentFindReplace(bool b = true) { persistent_find_replace = b; }
IsPersistentFindReplace()501 bool IsPersistentFindReplace() const { return persistent_find_replace; }
502
503 void FindReplaceRestorePos(bool b = true) { do_ff_restore_pos = b; }
IsFindReplaceRestorePos()504 bool IsFindReplaceRestorePos() const { return do_ff_restore_pos; }
505
Annotations(int width)506 void Annotations(int width) { bar.Annotations(width); }
ClearAnnotations()507 void ClearAnnotations() { bar.ClearAnnotations(); }
SetAnnotation(int i,const Image & icon,const String & a)508 void SetAnnotation(int i, const Image& icon, const String& a) { bar.SetAnnotation(i, icon, a); }
GetAnnotation(int i)509 String GetAnnotation(int i) const { return bar.GetAnnotation(i); }
GetActiveAnnotationLine()510 int GetActiveAnnotationLine() const { return bar.GetActiveAnnotationLine(); }
511
HideBar()512 void HideBar() { bar.Hide(); }
513
514 void SyncTip();
CloseTip()515 void CloseTip() { if(tip.IsOpen()) tip.Close(); tip.d = NULL; }
516
Illuminate(const WString & text)517 void Illuminate(const WString& text) { illuminated = text; Refresh(); }
518
519 void Zoom(int d);
520
521 One<EditorSyntax> GetSyntax(int line);
522 bool IsCursorBracket(int64 pos) const;
523 bool IsMatchingBracket(int64 pos) const;
524
525 // TODO: Do we really need this ?
GetIfStack(int line)526 Vector<IfState> GetIfStack(int line) { return GetSyntax(line)->PickIfStack(); }
527
528 struct FindReplaceData {
529 String find, replace;
530 String find_list, replace_list;
531 bool wholeword, wildcards, ignorecase, samecase, regexp;
532 };
533
534 FindReplaceData GetFindReplaceData();
535 void SetFindReplaceData(const FindReplaceData& d);
536
537 typedef CodeEditor CLASSNAME;
538
539 CodeEditor();
540 virtual ~CodeEditor();
541
542 static void InitKeywords();
543 };
544
545 String ReadList(WithDropChoice<EditString>& e);
546 void WriteList(WithDropChoice<EditString>& e, const String& data);
547
548 }
549
550 #endif
551