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