1
#include "../lf_mforms.h"
3
#include "base/string_utilities.h"
4
#include "../lf_code_editor.h"
9
#include "base/wb_memory.h"
10
#include "base/wb_iterators.h"
12
#include "Scintilla.h"
16
#include "ScintillaWidget.h"
18
// Marker ID assignments. Markers with higher number overlay lower ones.
19
#define CE_STATEMENT_MARKER 0
20
#define CE_ERROR_MARKER 1
21
#define CE_BREAKPOINT_MARKER 2
22
#define CE_BREAKPOINT_HIT_MARKER 3
23
#define CE_CURRENT_LINE_MARKER 3
25
bool string_to_bool(const std::string& value)
27
const std::string v = base::tolower(value);
28
return v == "1" || v == "true" || v == "yes";
31
int string_to_int(const std::string& v, const int base = 10)
34
const char* start = v.c_str();
35
int ret = strtoll(start, &end, base);
36
if (!( !*end && end != start))
42
int str_color_to_int(const std::string& v)
45
size_t len = v.length();
48
size_t pos = v.find("#");
49
if (pos != std::string::npos && (pos + 7) <= len)
51
ret = string_to_int(v.substr(pos + 1, 6), 16);
57
//==============================================================================
60
//==============================================================================
62
//==============================================================================
63
//------------------------------------------------------------------------------
66
static void notify_signal(GtkWidget *w, gint wParam, gpointer lParam, mforms::gtk::CodeEditorImpl *editor)
68
SCNotification *event = reinterpret_cast<SCNotification *>(lParam);
69
editor->notify(event);
72
mforms::gtk::CodeEditorImpl::CodeEditorImpl(CodeEditor* self)
78
_sci_gtk_widget = scintilla_new();
79
_sci_gtkmm_widget = Glib::wrap(_sci_gtk_widget);
80
_sci = SCINTILLA(_sci_gtk_widget);
82
gtk_signal_connect(GTK_OBJECT(_sci_gtk_widget), SCINTILLA_NOTIFY, GTK_SIGNAL_FUNC(notify_signal), this);
83
_sci_gtkmm_widget->show();
86
//------------------------------------------------------------------------------
87
mforms::gtk::CodeEditorImpl::~CodeEditorImpl()
90
//------------------------------------------------------------------------------
91
Gtk::Widget *mforms::gtk::CodeEditorImpl::get_outer() const
93
return _sci_gtkmm_widget;
96
//--------------------------------------------------------------------------------------------------
98
* This function loads the style name map from an external file which allows us to map
99
* style names to their associated ids.
101
static void load_style_names(const std::string path, mforms::gtk::StyleNameMap *map)
103
base::FILE_scope_ptr fp = fopen(path.c_str(), "r");
108
std::string name(256, ' ');
109
std::string value(256, ' ');
113
std::string *cur = &name;
122
if (name.length() > 0 && value.length() > 0)
125
const char* start = value.c_str();
126
const int style_id = strtoll(start, &end, 10);
127
if ( !*end && end != start)
129
(*map)[name] = style_id;
144
if (isalnum(c) || c == '_')
153
//--------------------------------------------------------------------------------------------------
155
* Superordinated style map loader which controls the load_style_names function.
157
static mforms::gtk::StyleNameMap get_style_map(const std::string& language)
159
mforms::gtk::StyleNameMap ret;
161
// These are global styles and always available.
162
ret["BRACEBAD"] = STYLE_BRACEBAD;
163
ret["BRACELIGHT"] = STYLE_BRACELIGHT;
164
ret["CALLTIP"] = STYLE_CALLTIP;
165
ret["CONTROLCHAR"] = STYLE_CONTROLCHAR;
166
ret["DEFAULT"] = STYLE_DEFAULT;
167
ret["LINENUMBER"] = STYLE_LINENUMBER;
169
load_style_names(mforms::App::get()->get_resource_path("default.txt"), &ret);
170
if (language != "Null")
172
load_style_names(mforms::App::get()->get_resource_path(language + ".txt"), &ret);
178
//--------------------------------------------------------------------------------------------------
180
* Loads the configuration file for the given language and fills the given style map with the loaded
181
* style data. Every other setting (tab usage, keywords etc.) will be applied
182
* to the editor on the way. Styles need a bit more processing so the caller will take for that.
184
void mforms::gtk::CodeEditorImpl::load_language_settings(const std::string& language, mforms::gtk::CodeEditorImpl::StyleMap &sm)
186
const std::string config_file_path = mforms::App::get()->get_resource_path(language + ".xml");
187
TiXmlDocument doc(config_file_path);
190
// TODO: Print error and exit load_language_settings
195
TiXmlHandle hdoc(&doc);
198
// Check that we loaded correct xml file
199
TiXmlElement *pel = hdoc.FirstChildElement().Element();
200
if (pel->ValueStr() != "ScintillaNET")
202
fprintf(stderr, "Error, root xml node is not correct\n");
204
root = TiXmlHandle(pel);
206
// Locate child node Language with Name attribute equal to language
207
pel = root.FirstChild("Language").Element();
208
TiXmlElement *lang_el(0);
209
for (; pel; pel=pel->NextSiblingElement())
211
if (pel->Attribute("Name") == language)
221
TiXmlElement *child = lang_el->FirstChildElement("Indentation");
224
const char* attr = child->Attribute("TabWidth");
226
send_editor(SCI_SETTABWIDTH, atoi(attr));
227
attr = child->Attribute("UseSpaces");
229
send_editor(SCI_SETUSETABS, bool(atoi(attr)));
233
child = lang_el->FirstChildElement("Lexer");
236
TiXmlElement *lex_child = child->FirstChildElement("Keywords");
238
const char *kw_list = 0;
239
for (; lex_child; lex_child = lex_child->NextSiblingElement("Keywords"))
241
if (TIXML_SUCCESS != lex_child->QueryIntAttribute("List", &list_id))
243
kw_list = lex_child->GetText();
246
send_editor(SCI_SETKEYWORDS, list_id, (sptr_t)kw_list);
250
lex_child = child->FirstChildElement("Properties");
251
for (; lex_child; lex_child = lex_child->NextSiblingElement("Properties"))
253
TiXmlElement *prop = lex_child->FirstChildElement("Property");
254
const char* name = 0;
255
const char* value = 0;
256
for(; prop; prop = prop->NextSiblingElement("Property"))
258
name = prop->Attribute("Name");
259
value = prop->Attribute("Value");
260
if (name && value && strlen(name) > 0 && strlen(value) > 0)
261
send_editor(SCI_SETPROPERTY, (uptr_t)name, (sptr_t)value);
267
TiXmlElement* style = 0;
268
const char* name = 0;
269
const char* value = 0;
270
StyleNameMap style_names = get_style_map(language);
272
child = lang_el->FirstChildElement("Styles");
273
for(; child; child = child->NextSiblingElement())
275
style = child->FirstChildElement("Style");
276
for (; style; style = style->NextSiblingElement("Style"))
278
name = style->Attribute("Name");
282
StyleNameMap::iterator name_it = style_names.find(name);
283
if (name_it != style_names.end())
284
style_id = name_it->second;
289
std::string style_entry;
290
StyleMap::mapped_type &dict_for_style = sm[style_id];
292
// Number and correspondence of items must be maintained!
293
static const char *tags[] = {"ForeColor", "BackColor", "Bold", "FontName", "Italic", "Size", "Underline", 0};
294
static const int tag_id[] = {SCI_STYLESETFORE, SCI_STYLESETBACK, SCI_STYLESETBOLD, SCI_STYLESETFONT, SCI_STYLESETITALIC, SCI_STYLESETSIZE, SCI_STYLESETUNDERLINE, 0};
296
const int* ptag_id = tag_id;
297
for (const char** t = tags; *t; ++t, ++ptag_id)
299
if (TIXML_SUCCESS == style->QueryStringAttribute(*t, &style_entry))
300
dict_for_style[*tag_id] = style_entry;
303
} // for (; style; style = style->NextSiblingElement("Style"))
304
} // for(; child; child = child->NextSiblingElement())
309
//--------------------------------------------------------------------------------------------------
311
void mforms::gtk::CodeEditorImpl::language_setup(const std::string& language)
313
// In opposition to the Windows version of this implementation we do not have automatic language
314
// setup, so we have to take care for keywords and colors manually here.
315
send_editor(SCI_SETLEXERLANGUAGE, 0, (sptr_t)language.c_str());
318
load_language_settings("default", map);
319
if (language != "Null")
321
load_language_settings(language, map);
324
// Here we have styles loaded
326
for (base::const_range<StyleMap> style(map); style; ++style)
328
style_id = style->first;
332
const StyleMap::mapped_type &style_traits = style->second;
333
for (base::const_range<StyleMap::mapped_type> trait(style_traits); trait; ++trait)
335
property = trait->first;
336
value = trait->second;
340
case SCI_STYLESETFORE:
341
case SCI_STYLESETBACK:
342
send_editor(property, style_id, str_color_to_int(value));
345
case SCI_STYLESETFONT:
346
send_editor(property, style_id, (sptr_t)value.c_str());
349
case SCI_STYLESETBOLD:
350
case SCI_STYLESETITALIC:
351
case SCI_STYLESETUNDERLINE:
352
send_editor(property, style_id, string_to_bool(value));
355
case SCI_STYLESETSIZE:
356
send_editor(property, style_id, string_to_int(value));
363
//------------------------------------------------------------------------------
364
void mforms::gtk::CodeEditorImpl::setup_marker(const int marker_id, const char* icon_path, int background)
366
const std::string full_path = mforms::App::get()->get_resource_path(icon_path);
367
base::FILE_scope_ptr fp = fopen(full_path.c_str(), "r");
368
base::AutoCharArray xpm(0);
372
fseek(fp,0,SEEK_END);
373
const long size = ftell(fp);
374
fseek(fp,0,SEEK_SET);
377
xpm = base::AutoCharArray(new char[size]);
378
long items_read = fread(xpm.get(), 1, size, fp);
379
// TODO: Check for EINTR and ENOMEM
380
if (items_read != size)
381
xpm = base::AutoCharArray();
387
send_editor(SCI_MARKERDEFINE, marker_id, SC_MARK_BACKGROUND);
388
send_editor(SCI_MARKERSETBACK, marker_id, background);
389
send_editor(SCI_MARKERSETFORE, marker_id, 0xffffff);
392
send_editor(SCI_MARKERDEFINEPIXMAP, marker_id, (sptr_t)xpm.get());
395
//------------------------------------------------------------------------------
396
void mforms::gtk::CodeEditorImpl::setup_editor(const bool use_tabs, const int indentation, const std::string& lang)
398
// Some values as default before reading the config file.
399
send_editor(SCI_SETUSETABS, use_tabs ? 1 : 0);
400
send_editor(SCI_SETTABWIDTH, indentation);
401
send_editor(SCI_SETTABINDENTS, 1);
402
send_editor(SCI_SETINDENT, indentation);
404
language_setup(lang);
406
send_editor(SCI_SETCARETLINEVISIBLE, 1);
407
send_editor(SCI_SETCARETLINEBACK, 0xF8C800);
408
send_editor(SCI_SETCARETLINEBACKALPHA, 20);
410
send_editor(SCI_SETBACKSPACEUNINDENTS, 1);
411
const int guide_type = (lang == "python") ? SC_IV_LOOKFORWARD : SC_IV_LOOKBOTH;
412
send_editor(SCI_SETINDENTATIONGUIDES, guide_type);
414
// Margin: Line number style.
415
send_editor(SCI_STYLESETFORE, STYLE_LINENUMBER, 0x404040);
416
send_editor(SCI_STYLESETBACK, STYLE_LINENUMBER, 0xE0E0E0);
418
send_editor(SCI_SETMARGINTYPEN, 0, SC_MARGIN_NUMBER);
419
const int lineNumberStyleWidth = send_editor(SCI_TEXTWIDTH, STYLE_LINENUMBER, (sptr_t)"_99999");
420
send_editor(SCI_SETMARGINWIDTHN, 0, lineNumberStyleWidth);
421
send_editor(SCI_SETMARGINSENSITIVEN, 0, 1); // Make Scintilla send a notification for clicks in this margin.
424
send_editor(SCI_SETMARGINWIDTHN, 1, 16);
425
send_editor(SCI_SETMARGINSENSITIVEN, 1, 1);
427
// Margin: Indicators (folders).
428
send_editor(SCI_SETFOLDMARGINCOLOUR, 1, 0xE6E6E6);
429
send_editor(SCI_SETMARGINWIDTHN, 2, 16);
430
send_editor(SCI_SETMARGINSENSITIVEN, 2, 1);
432
send_editor(SCI_SETEOLMODE, SC_EOL_LF);
434
// Marker definitions.
435
setup_marker(CE_STATEMENT_MARKER, "editor_statement.xpm", 0x0000ff);
436
setup_marker(CE_ERROR_MARKER, "editor_error.xpm", 0x32de2e);
437
setup_marker(CE_BREAKPOINT_MARKER, "editor_breakpoint.xpm", 0xa9443e);
438
setup_marker(CE_BREAKPOINT_HIT_MARKER, "editor_breakpoint_hit.xpm", 0xa9443e);
439
setup_marker(CE_CURRENT_LINE_MARKER, "editor_current_pos.xpm", 0xa9443e);
442
send_editor(SCI_SETMARGINWIDTHN, 2, 16);
443
send_editor(SCI_SETMARGINMASKN, 2, SC_MASK_FOLDERS);
444
send_editor(SCI_SETMARGINSENSITIVEN, 2, 1);
445
send_editor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_BOXMINUS);
446
send_editor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_BOXPLUS);
447
send_editor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE);
448
send_editor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNER);
449
send_editor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_BOXPLUSCONNECTED);
450
send_editor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_BOXMINUSCONNECTED);
451
send_editor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNER);
452
for (int n= 25; n < 32; ++n) // Markers 25..31 are reserved for folding.
454
send_editor(SCI_MARKERSETFORE, n, 0xffffff);
455
send_editor(SCI_MARKERSETBACK, n, 0x404040);
458
// Init markers & indicators for highlighting of syntax errors.
459
send_editor(SCI_INDICSETFORE, 0, 0xD01921);
460
send_editor(SCI_INDICSETUNDER, 0, 1);
461
send_editor(SCI_INDICSETSTYLE, 0, INDIC_SQUIGGLE);
464
//------------------------------------------------------------------------------
465
bool mforms::gtk::CodeEditorImpl::create(CodeEditor* self)
467
return new mforms::gtk::CodeEditorImpl(self);
470
//------------------------------------------------------------------------------
471
void mforms::gtk::CodeEditorImpl::set_text(CodeEditor* self, const std::string& text)
473
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
475
const int pos = ce->send_editor(SCI_GETCURRENTPOS);
476
ce->send_editor(SCI_SETTEXT, 0, (sptr_t)text.c_str());
477
ce->send_editor(SCI_GOTOPOS, pos);
478
ce->send_editor(SCI_SCROLLCARET);
481
//------------------------------------------------------------------------------
482
const std::string mforms::gtk::CodeEditorImpl::get_text(CodeEditor* self, bool selection_only)
484
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
487
const int length = ce->send_editor(SCI_GETLENGTH);
490
buffer = new char[length+1];
493
ce->send_editor(SCI_GETTEXT, length+1, (sptr_t)buffer);
494
//send_editor(SCI_SETSAVEPOINT); // TODO: Check if we should tell sci that document is unmodified
503
const std::string ret = buffer ? buffer : "";
508
//------------------------------------------------------------------------------
509
void mforms::gtk::CodeEditorImpl::get_selection(CodeEditor* self, int &start, int &length)
511
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
513
start = ce->send_editor(SCI_GETSELECTIONSTART);
514
length = ce->send_editor(SCI_GETSELECTIONEND);
517
//------------------------------------------------------------------------------
518
void mforms::gtk::CodeEditorImpl::set_selection(CodeEditor* self, int start, int length)
520
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
522
ce->send_editor(SCI_SETSELECTIONSTART, start);
523
ce->send_editor(SCI_SETSELECTIONEND, start + length);
526
//------------------------------------------------------------------------------
527
bool mforms::gtk::CodeEditorImpl::get_range_of_line(CodeEditor* self, int line, int &start, int &length)
529
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
531
const int lstart = ce->send_editor(SCI_POSITIONFROMLINE, line);
534
length = ce->send_editor(SCI_LINELENGTH, line);
539
//------------------------------------------------------------------------------
540
void mforms::gtk::CodeEditorImpl::set_language(CodeEditor* self, SyntaxHighlighterLanguage language)
542
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
548
case mforms::LanguageCpp:
549
ce->setup_editor(false, 2, "cpp"); // Currently string based. Will later use enum.
552
case mforms::LanguageLua:
553
ce->setup_editor(true, 4, "lua");
556
case mforms::LanguagePython:
557
ce->setup_editor(true, 4, "python");
560
case mforms::LanguageMySQL:
561
ce->setup_editor(false, 2, "mysql");
565
ce->setup_editor(false, 2, "Null");
570
//------------------------------------------------------------------------------
571
void mforms::gtk::CodeEditorImpl::set_read_only(CodeEditor* self, bool flag)
573
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
576
ce->send_editor(SCI_SETREADONLY, flag);
580
//------------------------------------------------------------------------------
581
void mforms::gtk::CodeEditorImpl::show_markup(CodeEditor* self, LineMarkup markup, int line)
583
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
586
// The marker mask contains one bit for each set marker (0..31).
587
unsigned int marker_mask = ce->send_editor(SCI_MARKERGET, line);
588
unsigned int new_marker_mask = 0;
589
if ((markup & mforms::LineMarkupStatement) != 0)
591
unsigned int mask = 1 << CE_STATEMENT_MARKER;
592
if ((marker_mask & mask) != mask)
593
new_marker_mask |= mask;
595
if ((markup & mforms::LineMarkupError) != 0)
597
unsigned int mask = 1 << CE_ERROR_MARKER;
598
if ((marker_mask & mask) != mask)
599
new_marker_mask |= mask;
601
if ((markup & mforms::LineMarkupBreakpoint) != 0)
603
unsigned int mask = 1 << CE_BREAKPOINT_MARKER;
604
if ((marker_mask & mask) != mask)
605
new_marker_mask |= mask;
607
if ((markup & mforms::LineMarkupBreakpointHit) != 0)
609
unsigned int mask = 1 << CE_BREAKPOINT_HIT_MARKER;
610
if ((marker_mask & mask) != mask)
611
new_marker_mask |= mask;
613
if ((markup & mforms::LineMarkupCurrent) != 0)
615
unsigned int mask = 1 << CE_CURRENT_LINE_MARKER;
616
if ((marker_mask & mask) != mask)
617
new_marker_mask |= mask;
620
ce->send_editor(SCI_MARKERADDSET, line, new_marker_mask);
624
//------------------------------------------------------------------------------
625
void mforms::gtk::CodeEditorImpl::remove_markup(CodeEditor* self, LineMarkup markup, int line)
627
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
630
if (markup == mforms::LineMarkupAll)
631
ce->send_editor(SCI_MARKERDELETEALL, line);
634
if ((markup & mforms::LineMarkupStatement) != 0)
635
ce->send_editor(SCI_MARKERDELETE, line, CE_STATEMENT_MARKER);
636
if ((markup & mforms::LineMarkupError) != 0)
637
ce->send_editor(SCI_MARKERDELETE, line, CE_ERROR_MARKER);
638
if ((markup & mforms::LineMarkupBreakpoint) != 0)
639
ce->send_editor(SCI_MARKERDELETE, line, CE_BREAKPOINT_MARKER);
640
if ((markup & mforms::LineMarkupBreakpointHit) != 0)
641
ce->send_editor(SCI_MARKERDELETE, line, CE_BREAKPOINT_HIT_MARKER);
642
if ((markup & mforms::LineMarkupCurrent) != 0)
643
ce->send_editor(SCI_MARKERDELETE, line, CE_CURRENT_LINE_MARKER);
648
//------------------------------------------------------------------------------
649
int mforms::gtk::CodeEditorImpl::line_count(CodeEditor* self)
652
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
654
ret = ce->send_editor(SCI_GETLINECOUNT);
658
//------------------------------------------------------------------------------
659
void mforms::gtk::CodeEditorImpl::set_font(CodeEditor* self, const std::string &fontDescription)
661
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
668
if (base::parse_font_description(fontDescription, name, size, bold, italic))
670
if (!name.empty() && name[0] != '!')
672
ce->send_editor(SCI_STYLESETFONT, STYLE_DEFAULT, (sptr_t)name.c_str());
673
ce->send_editor(SCI_STYLESETSIZE, STYLE_DEFAULT, size);
674
ce->send_editor(SCI_STYLESETBOLD, STYLE_DEFAULT, bold);
675
ce->send_editor(SCI_STYLESETITALIC, STYLE_DEFAULT, italic);
680
//------------------------------------------------------------------------------
683
void mforms::gtk::CodeEditorImpl::notify(SCNotification *event)
685
switch (event->nmhdr.code)
689
const int mod_type = event->modificationType;
690
if (mod_type & SC_MOD_INSERTTEXT || mod_type & SC_MOD_DELETETEXT)
694
//_background_action_timer_conn.disconnect();
695
//_background_action_timer_conn= Glib::signal_timeout().connect(
696
// sigc::mem_fun(this, &SqlEditorFE::on_background_action_timer),
697
// 2000); //! get value from wb options
698
_owner->text_changed(event->line, event->linesAdded);
700
// if (mod_type & SC_MOD_CHANGEFOLD)
701
// fold_changed(event->line, event->foldLevelNow, event->foldLevelPrev);
705
case SCN_MARGINCLICK:
707
int line = send_editor(SCI_LINEFROMPOSITION, event->position);
708
if (event->margin == 2)
710
// Click on the folder margin. Toggle the current line if possible.
711
send_editor(SCI_TOGGLEFOLD, line);
713
_owner->gutter_clicked(event->margin, line, (mforms::ModifierKey)event->modifiers);
722
//------------------------------------------------------------------------------
723
void mforms::gtk::CodeEditorImpl::show_gutter(CodeEditor* self, bool on)
725
CodeEditorImpl* ce = self->get_data<CodeEditorImpl>();
730
const int width = ce->send_editor(SCI_TEXTWIDTH, STYLE_LINENUMBER, (sptr_t)"_99999");
731
ce->send_editor(SCI_SETMARGINWIDTHN, 0, width);
732
ce->send_editor(SCI_SETMARGINSENSITIVEN, 0, true);
733
ce->send_editor(SCI_SETMARGINWIDTHN, 1, 16);
734
ce->send_editor(SCI_SETMARGINSENSITIVEN, 1, true);
735
ce->send_editor(SCI_SETMARGINWIDTHN, 2, 16);
736
ce->send_editor(SCI_SETMARGINSENSITIVEN, 2, true);
738
//scintilla->Styles[Constants::STYLE_LINENUMBER]->ForeColor = Color::FromArgb(64, 64, 64);
739
//scintilla->Styles[Constants::STYLE_LINENUMBER]->BackColor = Color::FromArgb(220, 220, 220);
740
//scintilla->Margins->FoldMarginColor = Color::FromArgb(230, 230, 230);
745
ce->send_editor(SCI_SETMARGINWIDTHN, 0, 0);
746
ce->send_editor(SCI_SETMARGINWIDTHN, 1, 0);
747
ce->send_editor(SCI_SETMARGINWIDTHN, 2, 0);
753
//------------------------------------------------------------------------------
754
void mforms::gtk::CodeEditorImpl::init()
756
::mforms::ControlFactory *f = ::mforms::ControlFactory::get_instance();
758
f->_code_editor_impl.create = mforms::gtk::CodeEditorImpl::create;
759
f->_code_editor_impl.set_text = mforms::gtk::CodeEditorImpl::set_text;
760
f->_code_editor_impl.get_text = mforms::gtk::CodeEditorImpl::get_text;
761
f->_code_editor_impl.get_selection = mforms::gtk::CodeEditorImpl::get_selection;
762
f->_code_editor_impl.set_selection = mforms::gtk::CodeEditorImpl::set_selection;
763
f->_code_editor_impl.get_range_of_line = mforms::gtk::CodeEditorImpl::get_range_of_line;
764
f->_code_editor_impl.set_language = mforms::gtk::CodeEditorImpl::set_language;
765
f->_code_editor_impl.set_read_only = mforms::gtk::CodeEditorImpl::set_read_only;
766
f->_code_editor_impl.show_markup = mforms::gtk::CodeEditorImpl::show_markup;
767
f->_code_editor_impl.remove_markup = mforms::gtk::CodeEditorImpl::remove_markup;
768
f->_code_editor_impl.line_count = mforms::gtk::CodeEditorImpl::line_count;
769
f->_code_editor_impl.set_font = mforms::gtk::CodeEditorImpl::set_font;
770
f->_code_editor_impl.show_gutter = mforms::gtk::CodeEditorImpl::show_gutter;