scintillaeditview.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. #include "scintillaeditview.h"
  2. #include "common.h"
  3. #include "rgba_icons.h"
  4. #include "ccnotepad.h"
  5. #include "styleset.h"
  6. #include "qtlangset.h"
  7. #include <Scintilla.h>
  8. #include <SciLexer.h>
  9. #include <QImage>
  10. #include <Qsci/qscilexerpython.h>
  11. #include <Qsci/qscilexeravs.h>
  12. #include <Qsci/qscilexerbash.h>
  13. #include <Qsci/qscilexerbatch.h>
  14. #include <Qsci/qscilexercmake.h>
  15. #include <Qsci/qscilexercoffeescript.h>
  16. #include <Qsci/qscilexercpp.h>
  17. #include <Qsci/qscilexercsharp.h>
  18. #include <Qsci/qscilexercss.h>
  19. #include <Qsci/qscilexercustom.h>
  20. #include <Qsci/qscilexerd.h>
  21. #include <Qsci/qscilexerdiff.h>
  22. #include <Qsci/qscilexeredifact.h>
  23. #include <Qsci/qscilexerfortran.h>
  24. #include <Qsci/qscilexerfortran77.h>
  25. #include <Qsci/qscilexerhtml.h>
  26. #include <Qsci/qscilexeridl.h>
  27. #include <Qsci/qscilexerjava.h>
  28. #include <Qsci/qscilexerjavascript.h>
  29. #include <Qsci/qscilexerjson.h>
  30. #include <Qsci/qscilexerlua.h>
  31. #include <Qsci/qscilexermakefile.h>
  32. #include <Qsci/qscilexermarkdown.h>
  33. #include <Qsci/qscilexermatlab.h>
  34. #include <Qsci/qscilexeroctave.h>
  35. #include <Qsci/qscilexerpascal.h>
  36. #include <Qsci/qscilexerperl.h>
  37. #include <Qsci/qscilexerpo.h>
  38. #include <Qsci/qscilexerpostscript.h>
  39. #include <Qsci/qscilexerpov.h>
  40. #include <Qsci/qscilexerproperties.h>
  41. #include <Qsci/qscilexerpython.h>
  42. #include <Qsci/qscilexerruby.h>
  43. #include <Qsci/qscilexerspice.h>
  44. #include <Qsci/qscilexersql.h>
  45. #include <Qsci/qscilexertcl.h>
  46. #include <Qsci/qscilexertex.h>
  47. #include <Qsci/qscilexerverilog.h>
  48. #include <Qsci/qscilexervhdl.h>
  49. #include <Qsci/qscilexerxml.h>
  50. #include <Qsci/qscilexeryaml.h>
  51. #include <Qsci/qscilexergo.h>
  52. #include <Qsci/qscilexertext.h>
  53. #include <Qsci/qscilexernsis.h>
  54. #include <QScrollBar>
  55. #include <QDebug>
  56. #include <stdexcept>
  57. #include "findwin.h"
  58. // initialize the static variable
  59. #define DEFAULT_FONT_NAME "Courier New" //"Microsoft YaHei"
  60. int ScintillaEditView::s_tabLens = 4;
  61. //默认不使用tab,使用space替换
  62. bool ScintillaEditView::s_noUseTab = true;
  63. int ScintillaEditView::s_bigTextSize = 100;
  64. const int ScintillaEditView::_SC_MARGE_LINENUMBER = 0;
  65. const int ScintillaEditView::_SC_MARGE_SYBOLE = 1;
  66. const int ScintillaEditView::_SC_MARGE_FOLDER = 2;
  67. const int MAX_PRE_NEXT_TIMES = 30;
  68. //const int ScintillaEditView::_markersArray[][NB_FOLDER_STATE] = {
  69. // {SC_MARKNUM_FOLDEROPEN, SC_MARKNUM_FOLDER, SC_MARKNUM_FOLDERSUB, SC_MARKNUM_FOLDERTAIL, SC_MARKNUM_FOLDEREND, SC_MARKNUM_FOLDEROPENMID, SC_MARKNUM_FOLDERMIDTAIL},
  70. // {SC_MARK_MINUS, SC_MARK_PLUS, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY},
  71. // {SC_MARK_ARROWDOWN, SC_MARK_ARROW, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY, SC_MARK_EMPTY},
  72. // {SC_MARK_CIRCLEMINUS, SC_MARK_CIRCLEPLUS,SC_MARK_VLINE, SC_MARK_LCORNERCURVE, SC_MARK_CIRCLEPLUSCONNECTED, SC_MARK_CIRCLEMINUSCONNECTED, SC_MARK_TCORNERCURVE},
  73. // {SC_MARK_BOXMINUS, SC_MARK_BOXPLUS, SC_MARK_VLINE, SC_MARK_LCORNER, SC_MARK_BOXPLUSCONNECTED, SC_MARK_BOXMINUSCONNECTED, SC_MARK_TCORNER}
  74. //};
  75. #ifdef Q_OS_WIN
  76. LanguageName ScintillaEditView::langNames[L_EXTERNAL + 1] = {
  77. {QString("normal"), QString("Normal QString"), QString("Normal text file"), L_TXT, SCLEX_NULL},
  78. {QString("php"), QString("PHP"), QString("PHP Hypertext Preprocessor file"), L_PHP, SCLEX_HTML},
  79. {QString("c"), QString("C"), QString("C source file"), L_C, SCLEX_CPP},
  80. {QString("cpp"), QString("C++"), QString("C++ source file"), L_CPP, SCLEX_CPP},
  81. {QString("cs"), QString("C#"), QString("C# source file"), L_CS, SCLEX_CPP},
  82. {QString("objc"), QString("Objective-C"), QString("Objective-C source file"), L_OBJC, SCLEX_CPP},
  83. {QString("java"), QString("Java"), QString("Java source file"), L_JAVA, SCLEX_CPP},
  84. {QString("rc"), QString("RC"), QString("Windows Resource file"), L_RC, SCLEX_CPP},
  85. {QString("html"), QString("HTML"), QString("Hyper Text Markup Language file"), L_HTML, SCLEX_HTML},
  86. {QString("xml"), QString("XML"), QString("eXtensible Markup Language file"), L_XML, SCLEX_XML},
  87. {QString("makefile"), QString("Makefile"), QString("Makefile"), L_MAKEFILE, SCLEX_MAKEFILE},
  88. {QString("pascal"), QString("Pascal"), QString("Pascal source file"), L_PASCAL, SCLEX_PASCAL},
  89. {QString("batch"), QString("Batch"), QString("Batch file"), L_BATCH, SCLEX_BATCH},
  90. {QString("ini"), QString("ini"), QString("MS ini file"), L_INI, SCLEX_PROPERTIES},
  91. {QString("nfo"), QString("NFO"), QString("MSDOS Style/ASCII Art"), L_ASCII, SCLEX_NULL},
  92. {QString("udf"), QString("udf"), QString("User Defined language file"), L_USER, SCLEX_USER},
  93. {QString("asp"), QString("ASP"), QString("Active Server Pages script file"), L_ASP, SCLEX_HTML},
  94. {QString("sql"), QString("SQL"), QString("Structured Query Language file"), L_SQL, SCLEX_SQL},
  95. {QString("vb"), QString("Visual Basic"), QString("Visual Basic file"), L_VB, SCLEX_VB},
  96. {QString("javascript"), QString("JavaScript"), QString("JavaScript file"), L_JS, L_JAVASCRIPT},
  97. {QString("css"), QString("CSS"), QString("Cascade Style Sheets File"), L_CSS, SCLEX_CSS},
  98. {QString("perl"), QString("Perl"), QString("Perl source file"), L_PERL, SCLEX_PERL},
  99. {QString("python"), QString("Python"), QString("Python file"), L_PYTHON, SCLEX_PYTHON},
  100. {QString("lua"), QString("Lua"), QString("Lua source File"), L_LUA, SCLEX_LUA},
  101. {QString("tex"), QString("TeX"), QString("TeX file"), L_TEX, SCLEX_TEX},
  102. {QString("fortran"), QString("Fortran free form"), QString("Fortran free form source file"), L_FORTRAN, SCLEX_FORTRAN},
  103. {QString("bash"), QString("Shell"), QString("Unix script file"), L_BASH, SCLEX_BASH},
  104. {QString("actionscript"), QString("ActionScript"), QString("Flash ActionScript file"), L_FLASH, SCLEX_CPP},
  105. {QString("nsis"), QString("NSIS"), QString("Nullsoft Scriptable Install System script file"), L_NSIS, SCLEX_NSIS},
  106. {QString("tcl"), QString("TCL"), QString("Tool Command Language file"), L_TCL, SCLEX_TCL},
  107. {QString("lisp"), QString("Lisp"), QString("List Processing language file"), L_LISP, SCLEX_LISP},
  108. {QString("scheme"), QString("Scheme"), QString("Scheme file"), L_SCHEME, SCLEX_LISP},
  109. {QString("asm"), QString("Assembly"), QString("Assembly language source file"), L_ASM, SCLEX_ASM},
  110. {QString("diff"), QString("Diff"), QString("Diff file"), L_DIFF, SCLEX_DIFF},
  111. {QString("props"), QString("Properties file"), QString("Properties file"), L_PROPS, SCLEX_PROPERTIES},
  112. {QString("postscript"), QString("PostScript"), QString("PostScript file"), L_PS, SCLEX_PS},
  113. {QString("ruby"), QString("Ruby"), QString("Ruby file"), L_RUBY, SCLEX_RUBY},
  114. {QString("smalltalk"), QString("Smalltalk"), QString("Smalltalk file"), L_SMALLTALK, SCLEX_SMALLTALK},
  115. {QString("vhdl"), QString("VHDL"), QString("VHSIC Hardware Description Language file"), L_VHDL, SCLEX_VHDL},
  116. {QString("kix"), QString("KiXtart"), QString("KiXtart file"), L_KIX, SCLEX_KIX},
  117. {QString("autoit"), QString("AutoIt"), QString("AutoIt"), L_AU3, SCLEX_AU3},
  118. {QString("caml"), QString("CAML"), QString("Categorical Abstract Machine Language"), L_CAML, SCLEX_CAML},
  119. {QString("ada"), QString("Ada"), QString("Ada file"), L_ADA, SCLEX_ADA},
  120. {QString("verilog"), QString("Verilog"), QString("Verilog file"), L_VERILOG, SCLEX_VERILOG},
  121. {QString("matlab"), QString("MATLAB"), QString("MATrix LABoratory"), L_MATLAB, SCLEX_MATLAB},
  122. {QString("haskell"), QString("Haskell"), QString("Haskell"), L_HASKELL, SCLEX_HASKELL},
  123. {QString("inno"), QString("Inno Setup"), QString("Inno Setup script"), L_INNO, SCLEX_INNOSETUP},
  124. {QString("searchResult"), QString("Internal Search"), QString("Internal Search"), L_SEARCHRESULT, SCLEX_SEARCHRESULT},
  125. {QString("cmake"), QString("CMake"), QString("CMake file"), L_CMAKE, SCLEX_CMAKE},
  126. {QString("yaml"), QString("YAML"), QString("YAML Ain't Markup Language"), L_YAML, SCLEX_YAML},
  127. {QString("cobol"), QString("COBOL"), QString("COmmon Business Oriented Language"), L_COBOL, SCLEX_COBOL},
  128. {QString("gui4cli"), QString("Gui4Cli"), QString("Gui4Cli file"), L_GUI4CLI, SCLEX_GUI4CLI},
  129. {QString("d"), QString("D"), QString("D programming language"), L_D, SCLEX_D},
  130. {QString("powershell"), QString("PowerShell"), QString("Windows PowerShell"), L_POWERSHELL, SCLEX_POWERSHELL},
  131. {QString("r"), QString("R"), QString("R programming language"), L_R, SCLEX_R},
  132. {QString("jsp"), QString("JSP"), QString("JavaServer Pages script file"), L_JSP, SCLEX_HTML},
  133. {QString("coffeescript"), QString("CoffeeScript"), QString("CoffeeScript file"), L_COFFEESCRIPT, SCLEX_COFFEESCRIPT},
  134. {QString("json"), QString("json"), QString("JSON file"), L_JSON, SCLEX_JSON },
  135. {QString("javascript.js"), QString("JavaScript"), QString("JavaScript file"), L_JAVASCRIPT, SCLEX_CPP },
  136. {QString("fortran77"), QString("Fortran fixed form"), QString("Fortran fixed form source file"), L_FORTRAN_77, SCLEX_F77},
  137. {QString("baanc"), QString("BaanC"), QString("BaanC File"), L_BAANC, SCLEX_BAAN },
  138. {QString("srec"), QString("S-Record"), QString("Motorola S-Record binary data"), L_SREC, SCLEX_SREC},
  139. {QString("ihex"), QString("Intel HEX"), QString("Intel HEX binary data"), L_IHEX, SCLEX_IHEX},
  140. {QString("tehex"), QString("Tektronix extended HEX"), QString("Tektronix extended HEX binary data"), L_TEHEX, SCLEX_TEHEX},
  141. {QString("swift"), QString("Swift"), QString("Swift file"), L_SWIFT, SCLEX_CPP},
  142. {QString("asn1"), QString("ASN.1"), QString("Abstract Syntax Notation One file"), L_ASN1, SCLEX_ASN1},
  143. {QString("avs"), QString("AviSynth"), QString("AviSynth scripts files"), L_AVS, SCLEX_AVS},
  144. {QString("blitzbasic"), QString("BlitzBasic"), QString("BlitzBasic file"), L_BLITZBASIC, SCLEX_BLITZBASIC},
  145. {QString("purebasic"), QString("PureBasic"), QString("PureBasic file"), L_PUREBASIC, SCLEX_PUREBASIC},
  146. {QString("freebasic"), QString("FreeBasic"), QString("FreeBasic file"), L_FREEBASIC, SCLEX_FREEBASIC},
  147. {QString("csound"), QString("Csound"), QString("Csound file"), L_CSOUND, SCLEX_CSOUND},
  148. {QString("erlang"), QString("Erlang"), QString("Erlang file"), L_ERLANG, SCLEX_ERLANG},
  149. {QString("escript"), QString("ESCRIPT"), QString("ESCRIPT file"), L_ESCRIPT, SCLEX_ESCRIPT},
  150. {QString("forth"), QString("Forth"), QString("Forth file"), L_FORTH, SCLEX_FORTH},
  151. {QString("latex"), QString("LaTeX"), QString("LaTeX file"), L_LATEX, SCLEX_LATEX},
  152. {QString("mmixal"), QString("MMIXAL"), QString("MMIXAL file"), L_MMIXAL, SCLEX_MMIXAL},
  153. {QString("nim"), QString("Nim"), QString("Nim file"), L_NIM, SCLEX_NIMROD},
  154. {QString("nncrontab"), QString("Nncrontab"), QString("extended crontab file"), L_NNCRONTAB, SCLEX_NNCRONTAB},
  155. {QString("oscript"), QString("OScript"), QString("OScript source file"), L_OSCRIPT, SCLEX_OSCRIPT},
  156. {QString("rebol"), QString("REBOL"), QString("REBOL file"), L_REBOL, SCLEX_REBOL},
  157. {QString("registry"), QString("registry"), QString("registry file"), L_REGISTRY, SCLEX_REGISTRY},
  158. {QString("rust"), QString("Rust"), QString("Rust file"), L_RUST, SCLEX_RUST},
  159. {QString("spice"), QString("Spice"), QString("spice file"), L_SPICE, SCLEX_SPICE},
  160. {QString("txt2tags"), QString("txt2tags"), QString("txt2tags file"), L_TXT2TAGS, SCLEX_TXT2TAGS},
  161. {QString("visualprolog"), QString("Visual Prolog"), QString("Visual Prolog file"), L_VISUALPROLOG, SCLEX_VISUALPROLOG},
  162. {QString("typescript"), QString("TypeScript"), QString("TypeScript file"), L_TYPESCRIPT, SCLEX_CPP},
  163. {QString("edifact"), QString("Edifact"), QString("Edifact file"), L_EDIFACT, SCLEX_EDIFACT},
  164. {QString("markdown"), QString("Markdown"), QString("Markdown file"), L_MARKDOWN, SCLEX_MARKDOWN},
  165. {QString("octave"), QString("Octave"), QString("Octave file"), L_OCTAVE, SCLEX_OCTAVE},
  166. {QString("po"), QString("PO"), QString("PO file"), L_PO, SCLEX_PO},
  167. {QString("pov"), QString("POV"), QString("POV file"), L_POV, SCLEX_POV},
  168. {QString("avs"), QString("AVS"), QString("AVS file"), L_AVS, SCLEX_AVS},
  169. {QString("idl"), QString("IDL"), QString("IDL file"), L_IDL, SCLEX_IDL},
  170. {QString("go"), QString("GO"), QString("GO file"), L_GO, SCLEX_GO},
  171. {QString("txt"), QString("TEXT"), QString("TXT file"), L_TXT, SCLEX_TXT},
  172. {QString("ext"), QString("External"), QString("External"), L_EXTERNAL, SCLEX_NULL}
  173. };
  174. #endif
  175. ScintillaEditView::ScintillaEditView(QWidget *parent)
  176. : QsciScintilla(parent), m_NoteWin(nullptr), m_preFirstLineNum(0), m_curPos(0)
  177. {
  178. init();
  179. }
  180. ScintillaEditView::~ScintillaEditView()
  181. {
  182. releaseAllMark();
  183. }
  184. //void ScintillaEditView::resetDefaultFontStyle()
  185. //{
  186. // QFont font(DEFAULT_FONT_NAME, 11/*QsciLexer::s_defaultFontSize*/, QFont::Normal);
  187. // setFont(font);
  188. // setMarginsFont(font);
  189. // setMarginsForegroundColor(QColor(0x80, 0x80, 0x80));
  190. //}
  191. void ScintillaEditView::setNoteWidget(QWidget * win)
  192. {
  193. m_NoteWin = win;
  194. }
  195. void ScintillaEditView::updateLineNumbersMargin(bool forcedToHide) {
  196. if (forcedToHide)
  197. {
  198. execute(SCI_SETMARGINWIDTHN, _SC_MARGE_LINENUMBER, (sptr_t)0);
  199. }
  200. else
  201. {
  202. updateLineNumberWidth(0);
  203. }
  204. }
  205. //根据现有滚动条来决定是否更新屏幕线宽长度。每滚动2000个单位必须调整line宽
  206. void ScintillaEditView::autoAdjustLineWidth(int xScrollValue)
  207. {
  208. if (std::abs(xScrollValue - m_preFirstLineNum) > 400)
  209. {
  210. m_preFirstLineNum = xScrollValue;
  211. updateLineNumberWidth(1);
  212. }
  213. }
  214. void ScintillaEditView::updateLineNumberWidth(int lineNumberMarginDynamicWidth)
  215. {
  216. auto linesVisible = execute(SCI_LINESONSCREEN);
  217. if (linesVisible)
  218. {
  219. int nbDigits = 0;
  220. if(lineNumberMarginDynamicWidth != 0)
  221. {
  222. auto firstVisibleLineVis = execute(SCI_GETFIRSTVISIBLELINE);
  223. auto lastVisibleLineVis = linesVisible + firstVisibleLineVis + 1;
  224. auto lastVisibleLineDoc = execute(SCI_DOCLINEFROMVISIBLE, (long)lastVisibleLineVis);
  225. nbDigits = nbDigitsFromNbLines(lastVisibleLineDoc);
  226. nbDigits = nbDigits < 4 ? 4 : nbDigits;
  227. }
  228. else
  229. {
  230. auto nbLines = execute(SCI_GETLINECOUNT);
  231. nbDigits = nbDigitsFromNbLines(nbLines);
  232. nbDigits = nbDigits < 5 ? 5 : nbDigits;
  233. }
  234. auto pixelWidth = 6 + nbDigits * execute(SCI_TEXTWIDTH, STYLE_LINENUMBER, reinterpret_cast<sptr_t>("8"));
  235. execute(SCI_SETMARGINWIDTHN, _SC_MARGE_LINENUMBER, pixelWidth);
  236. }
  237. }
  238. void ScintillaEditView::showMargin(int whichMarge, bool willBeShowed)
  239. {
  240. if (whichMarge == _SC_MARGE_LINENUMBER)
  241. {
  242. bool forcedToHide = !willBeShowed;
  243. updateLineNumbersMargin(forcedToHide);
  244. }
  245. else
  246. {
  247. //后面再来解决像素的问题
  248. //DPIManager& dpiManager = NppParameters::getInstance()._dpiManager;
  249. int width = 3;
  250. if (whichMarge == _SC_MARGE_SYBOLE)
  251. width = 8;
  252. else if (whichMarge == _SC_MARGE_FOLDER)
  253. width = 14;
  254. execute(SCI_SETMARGINWIDTHN, whichMarge, willBeShowed ? width : 0);
  255. }
  256. }
  257. sptr_t ScintillaEditView::execute(quint32 Msg, uptr_t wParam, sptr_t lParam) const {
  258. try {
  259. return (m_pScintillaFunc) ? m_pScintillaFunc(m_pScintillaPtr, Msg, wParam, lParam) : -1;
  260. }
  261. catch (...)
  262. {
  263. return -1;
  264. }
  265. };
  266. //status : true 表示存在, false 表示不存在
  267. QsciLexer* ScintillaEditView::createLexer(int lexerId)
  268. {
  269. QsciLexer* ret = nullptr;
  270. switch (lexerId)
  271. {
  272. case L_PHP:
  273. ret = new QsciLexerHTML();
  274. ret->setLexerTag("php");
  275. break;
  276. case L_HTML:
  277. ret = new QsciLexerHTML();
  278. ret->setLexerTag("html");
  279. break;
  280. case L_ASP:
  281. ret = new QsciLexerHTML();
  282. ret->setLexerTag("asp");
  283. break;
  284. case L_JSP:
  285. ret = new QsciLexerHTML();
  286. ret->setLexerTag("jsp");
  287. break;
  288. case L_C:
  289. ret = new QsciLexerCPP();
  290. ret->setLexerTag("c");
  291. break;
  292. case L_RC:
  293. ret = new QsciLexerCPP();
  294. ret->setLexerTag("rc");
  295. break;
  296. case L_CPP:
  297. ret = new QsciLexerCPP();
  298. break;
  299. case L_OBJC:
  300. ret = new QsciLexerCPP();
  301. ret->setLexerTag("objc");
  302. break;
  303. case L_CS:
  304. ret = new QsciLexerCSharp();
  305. ret->setLexerTag("csharp");
  306. break;
  307. case L_JAVA:
  308. ret = new QsciLexerJava();
  309. ret->setLexerTag("java");
  310. break;
  311. case L_XML:
  312. ret = new QsciLexerXML();
  313. break;
  314. case L_MAKEFILE:
  315. ret = new QsciLexerMakefile();
  316. break;
  317. case L_PASCAL:
  318. ret = new QsciLexerPascal();
  319. break;
  320. case L_BATCH:
  321. ret = new QsciLexerBatch();
  322. break;
  323. case L_INI:
  324. ret = new QsciLexerProperties();
  325. ret->setLexerTag("ini");
  326. break;
  327. case L_ASCII:
  328. break;
  329. case L_USER:
  330. break;
  331. case L_SQL:
  332. ret = new QsciLexerSQL();
  333. break;
  334. case L_VB:
  335. break;
  336. case L_CSS:
  337. ret = new QsciLexerCSS();
  338. break;
  339. case L_PERL:
  340. ret = new QsciLexerPerl();
  341. break;
  342. case L_PYTHON:
  343. ret = new QsciLexerPython();
  344. break;
  345. case L_LUA:
  346. ret = new QsciLexerLua();
  347. break;
  348. case L_TEX:
  349. break;
  350. case L_FORTRAN:
  351. ret = new QsciLexerFortran();
  352. break;
  353. case L_BASH:
  354. ret = new QsciLexerBash();
  355. break;
  356. case L_FLASH:
  357. ret = new QsciLexerCPP();
  358. ret->setLexerTag("flash");
  359. break;
  360. case L_NSIS:
  361. ret = new QsciLexerNsis();
  362. break;
  363. case L_TCL:
  364. ret = new QsciLexerTCL();
  365. break;
  366. case L_LISP:
  367. break;
  368. case L_SCHEME:
  369. break;
  370. case L_ASM:
  371. break;
  372. case L_DIFF:
  373. ret = new QsciLexerDiff();
  374. break;
  375. case L_PROPS:
  376. ret = new QsciLexerProperties();
  377. break;
  378. case L_PS:
  379. break;
  380. case L_RUBY:
  381. ret = new QsciLexerRuby();
  382. break;
  383. case L_SMALLTALK:
  384. break;
  385. case L_VHDL:
  386. ret = new QsciLexerVHDL();
  387. break;
  388. case L_KIX:
  389. break;
  390. case L_AU3:
  391. break;
  392. case L_CAML:
  393. break;
  394. case L_ADA:
  395. break;
  396. case L_VERILOG:
  397. ret = new QsciLexerVerilog();
  398. break;
  399. case L_MATLAB:
  400. ret = new QsciLexerMatlab();
  401. break;
  402. case L_HASKELL:
  403. break;
  404. case L_INNO:
  405. break;
  406. case L_SEARCHRESULT:
  407. break;
  408. case L_CMAKE:
  409. ret = new QsciLexerCMake();
  410. break;
  411. case L_YAML:
  412. ret = new QsciLexerYAML();
  413. break;
  414. case L_COBOL:
  415. break;
  416. case L_GUI4CLI:
  417. break;
  418. case L_D:
  419. break;
  420. case L_POWERSHELL:
  421. break;
  422. case L_COFFEESCRIPT:
  423. ret = new QsciLexerCoffeeScript();
  424. break;
  425. case L_JSON:
  426. ret = new QsciLexerJSON();
  427. break;
  428. case L_JAVASCRIPT:
  429. ret = new QsciLexerJavaScript();
  430. ret->setLexerTag("javascript");
  431. break;
  432. case L_FORTRAN_77:
  433. ret = new QsciLexerFortran77();
  434. break;
  435. case L_BAANC:
  436. break;
  437. case L_SREC:
  438. break;
  439. case L_IHEX:
  440. break;
  441. case L_TEHEX:
  442. break;
  443. case L_SWIFT:
  444. break;
  445. case L_ASN1:
  446. break;
  447. case L_AVS:
  448. ret = new QsciLexerAVS();
  449. break;
  450. case L_BLITZBASIC:
  451. break;
  452. case L_PUREBASIC:
  453. break;
  454. case L_FREEBASIC:
  455. break;
  456. case L_CSOUND:
  457. break;
  458. case L_ERLANG:
  459. break;
  460. case L_ESCRIPT:
  461. break;
  462. case L_FORTH:
  463. break;
  464. case L_LATEX:
  465. break;
  466. case L_MMIXAL:
  467. break;
  468. case L_NIM:
  469. break;
  470. case L_NNCRONTAB:
  471. break;
  472. case L_OSCRIPT:
  473. break;
  474. case L_REBOL:
  475. break;
  476. case L_REGISTRY:
  477. break;
  478. case L_RUST:
  479. break;
  480. case L_SPICE:
  481. ret = new QsciLexerSpice();
  482. break;
  483. case L_TXT2TAGS:
  484. break;
  485. case L_VISUALPROLOG:
  486. break;
  487. case L_TYPESCRIPT:
  488. ret = new QsciLexerCPP();
  489. ret->setLexerTag("typescript");
  490. break;
  491. case L_EXTERNAL:
  492. break;
  493. case L_IDL:
  494. ret = new QsciLexerIDL();
  495. ret->setLexerTag("idl");
  496. break;
  497. case L_GO:
  498. ret = new QsciLexerGO();
  499. ret->setLexerTag("go");
  500. break;
  501. case L_TXT:
  502. ret = new QsciLexerText();
  503. ret->setLexerTag("txt");
  504. break;
  505. default:
  506. break;
  507. }
  508. if (ret != nullptr)
  509. {
  510. ret->setLexerId(lexerId);
  511. QtLangSet::readLangSettings(ret, ret->lexerTag());
  512. }
  513. return ret;
  514. }
  515. void ScintillaEditView::appendMarkRecord(FindRecords * r)
  516. {
  517. m_curMarkList.append(r);
  518. }
  519. void ScintillaEditView::releaseAllMark()
  520. {
  521. for (int i = 0; i < m_curMarkList.size(); ++i)
  522. {
  523. delete m_curMarkList.at(i);
  524. }
  525. m_curMarkList.clear();
  526. }
  527. QList<FindRecords *>& ScintillaEditView::getCurMarkRecord()
  528. {
  529. return m_curMarkList;
  530. }
  531. //调整颜色
  532. void ScintillaEditView::adjuctSkinStyle()
  533. {
  534. setFoldMarginColors(StyleSet::foldfgColor, StyleSet::foldbgColor);
  535. setMarginsBackgroundColor(StyleSet::marginsBackgroundColor);
  536. }
  537. void ScintillaEditView::setIndentGuide(bool willBeShowed)
  538. {
  539. QsciLexer* pLexer = this->lexer();
  540. if (nullptr == pLexer || (pLexer->lexerId() == L_TXT))
  541. {
  542. return;
  543. }
  544. const int docIndentMode = (pLexer->lexerId() == L_PYTHON) ? SC_IV_LOOKFORWARD : SC_IV_LOOKBOTH;
  545. execute(SCI_SETINDENTATIONGUIDES, willBeShowed ? docIndentMode : SC_IV_NONE);
  546. QsciScintilla::setIndentGuide(willBeShowed);
  547. }
  548. #if 0
  549. void ScintillaEditView::setLexer(QsciLexer * lexer)
  550. {
  551. //加个保护,只有文本模式下,才能加lexer
  552. if (lexer != nullptr)
  553. {
  554. OpenAttr openType = (OpenAttr)this->property(Open_Attr).toInt();
  555. if (Text != openType)
  556. {
  557. return;
  558. }
  559. }
  560. QsciScintilla::setLexer(lexer);
  561. }
  562. #endif
  563. void ScintillaEditView::init()
  564. {
  565. m_pScintillaFunc = (SCINTILLA_FUNC)this->SendScintillaPtrResult(SCI_GETDIRECTFUNCTION);
  566. m_pScintillaPtr = (SCINTILLA_PTR)this->SendScintillaPtrResult(SCI_GETDIRECTPOINTER);
  567. if (!m_pScintillaFunc)
  568. {
  569. throw std::runtime_error("ScintillaEditView::init : SCI_GETDIRECTFUNCTION message failed");
  570. }
  571. if (!m_pScintillaPtr)
  572. {
  573. throw std::runtime_error("ScintillaEditView::init : SCI_GETDIRECTPOINTER message failed");
  574. }
  575. //开启行号marge
  576. //markerDefine(SC_MARGIN_NUMBER,_SC_MARGE_LINENUMBER);
  577. setMarginLineNumbers(_SC_MARGE_LINENUMBER, true);
  578. //execute(SCI_SETMARGINMASKN, _SC_MARGE_FOLDER, SC_MARGIN_SYMBOL);
  579. //execute(SCI_SETMARGINMASKN, _SC_MARGE_FOLDER, SC_MASK_FOLDERS);
  580. QColor foldfgColor(StyleSet::foldfgColor);
  581. QColor foldbgColor(StyleSet::foldbgColor);//默认0xff,0xff,0xff
  582. //QColor activeFoldFgColor(0xFF, 0, 0);
  583. //通过fold发现,尽量使用qscint的功能,因为他做了大量封装和简化
  584. setFolding(BoxedTreeFoldStyle, _SC_MARGE_FOLDER);
  585. setFoldMarginColors(foldfgColor, foldbgColor);
  586. //当前fold高亮。QT下面有bug暂时不开启
  587. //execute(SCI_MARKERENABLEHIGHLIGHT, true);
  588. setMarginsBackgroundColor(StyleSet::marginsBackgroundColor); //0xea, 0xf7, 0xff //默认0xf0f0f0
  589. //execute(SCI_MARKERSETBACK, _SC_MARGE_FOLDER, 0x808080);
  590. //execute(SCI_MARKERSETBACKSELECTED, _SC_MARGE_FOLDER, 0xff0000);
  591. showMargin(_SC_MARGE_LINENUMBER, true);
  592. //行号、符号、折叠。中间符号留一个很小的间隔
  593. showMargin(_SC_MARGE_SYBOLE, true);
  594. //showMargin(_SC_MARGE_FOLDER, true);
  595. //设置选中背景色
  596. //setSelectionBackgroundColor(QColor(117, 217, 117));
  597. //开始括号匹配,比如html的<>,开启前后这类字段的匹配
  598. setBraceMatching(SloppyBraceMatch);
  599. setMatchedBraceForegroundColor(QColor(191, 141, 255));
  600. //setMatchedBraceBackgroundColor(QColor(191, 141, 255));
  601. //自动补全效果不好,不开启20211017
  602. //setAutoCompletionSource(QsciScintilla::AcsAPIs); //设置源,自动补全所有地方出现的
  603. //setAutoCompletionCaseSensitivity(true); //设置自动补全大小写敏感
  604. //setAutoCompletionThreshold(1); //设置每输入一个字符就会出现自动补全的提示
  605. //设置字体
  606. QFont font(DEFAULT_FONT_NAME, 11/*QsciLexer::s_defaultFontSize*/, QFont::Normal);
  607. setFont(font);
  608. setMarginsFont(font);
  609. //execute(SCI_SETMARGINMASKN, _SC_MARGE_SYBOLE, (1 << MARK_BOOKMARK) | (1 << MARK_HIDELINESBEGIN) | (1 << MARK_HIDELINESEND) | (1 << MARK_HIDELINESUNDERLINE));
  610. setMarginsForegroundColor(QColor(0x80, 0x80, 0x80)); //默认0x80, 0x80, 0x80
  611. execute(SCI_SETTABWIDTH, 4);
  612. //setPaper(QColor(0xfc, 0xfc, 0xfc));//这个无效
  613. //使用空格替换tab
  614. execute(SCI_SETUSETABS, !ScintillaEditView::s_noUseTab);
  615. //这个无比要设置false,否则双击后高亮单词,拷贝时会拷贝多个选择。
  616. execute(SCI_SETMULTIPLESELECTION, false);
  617. //execute(SCI_SETADDITIONALSELALPHA, 100);
  618. execute(SCI_SETMULTIPASTE, 1);
  619. execute(SCI_SETADDITIONALCARETSVISIBLE, false);
  620. //execute(SCI_SETADDITIONALSELFORE, 0);
  621. //execute(SCI_SETADDITIONALSELBACK, 0x98ff98);
  622. execute(SCI_SETSELFORE, true, 0x0);
  623. //execute(SCI_SETSELBACK, true, 0x9ACC9A);
  624. execute(SCI_SETSELBACK, true, 0x9bff9b); //0x00ffff原来的黄色
  625. //设置查找到Mark的风格。定义其前景颜色和形状
  626. execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_FOUND_STYLE, INDIC_ROUNDBOX);
  627. execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_FOUND_STYLE, 130);
  628. execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_FOUND_STYLE, false);
  629. execute(SCI_INDICSETFORE, SCE_UNIVERSAL_FOUND_STYLE, 0x00ffff);
  630. //下面这两个是HTML文件的tag高亮的表示。
  631. execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_TAGMATCH, INDIC_STRAIGHTBOX);
  632. execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_TAGMATCH, 100);
  633. execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_TAGMATCH, false);
  634. execute(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGMATCH, 0xff0080);
  635. execute(SCI_INDICSETSTYLE, SCE_UNIVERSAL_TAGATTR, INDIC_STRAIGHTBOX);
  636. execute(SCI_INDICSETALPHA, SCE_UNIVERSAL_TAGATTR, 100);
  637. execute(SCI_INDICSETUNDER, SCE_UNIVERSAL_TAGATTR, false);
  638. execute(SCI_INDICSETFORE, SCE_UNIVERSAL_TAGATTR, 0x00ffff);
  639. setCaretLineVisible(true);
  640. setCaretLineBackgroundColor(QColor(0xe8e8ff));
  641. //记住position变化。不能使用cursorPositionChanged,因为他的列考虑uft8字符,中文一个也算1个,每次列不一定相等。
  642. //要使用自定义的cursorPosChange,跟踪的是SCI_GETCURRENTPOS 的值
  643. connect(this,&QsciScintilla::cursorPosChange,this,&ScintillaEditView::slot_linePosChanged, Qt::QueuedConnection);
  644. execute(SCI_SETSCROLLWIDTH, 1);
  645. //20220226发现高亮全选如果范围过大,会导致卡死。借鉴notepad的只高亮可视化区域。但是滚动时也必须生效
  646. connect(this->verticalScrollBar(), &QScrollBar::valueChanged, this, &ScintillaEditView::slot_scrollXValueChange);
  647. connect(this, &ScintillaEditView::delayWork, this,&ScintillaEditView::slot_delayWork, Qt::QueuedConnection);
  648. }
  649. //X方向滚动条值变化后的槽函数。一旦滚动则会出发这里,发送消息给中介,让中介去同步另外一方
  650. void ScintillaEditView::slot_scrollXValueChange(int value)
  651. {
  652. slot_delayWork();
  653. autoAdjustLineWidth(value);
  654. }
  655. void ScintillaEditView::slot_linePosChanged(int /*line*/, int pos)
  656. {
  657. //避免循环触发的slot_positionChanged
  658. if (m_curPos == pos)
  659. {
  660. return;
  661. }
  662. m_prePosRecord.append(pos);
  663. if (m_prePosRecord.size() >= MAX_PRE_NEXT_TIMES)
  664. {
  665. m_prePosRecord.takeFirst();
  666. }
  667. }
  668. //回退一个位置
  669. bool ScintillaEditView::gotoPrePos()
  670. {
  671. if (m_prePosRecord.size() > 1)
  672. {
  673. int v = m_prePosRecord.takeLast();
  674. m_nextPosRecord.push_front(v);
  675. if (m_nextPosRecord.size() >= MAX_PRE_NEXT_TIMES)
  676. {
  677. m_nextPosRecord.takeLast();
  678. }
  679. int pos = m_prePosRecord.last();
  680. //下面这个函数比较坑,里面要循环Index次,每次返回的index值是不一样的。只能使用SCI_GOTOPOS可自定义的信号
  681. //setCursorPosition(pos.line, pos.index);
  682. //会循环触发slot_positionChanged
  683. this->execute(SCI_GOTOPOS, pos);
  684. m_curPos = pos;
  685. return true;
  686. }
  687. return false;
  688. }
  689. bool ScintillaEditView::gotoNextPos()
  690. {
  691. if (m_nextPosRecord.size() > 0)
  692. {
  693. int pos = m_nextPosRecord.takeFirst();
  694. m_prePosRecord.append(pos);
  695. this->execute(SCI_GOTOPOS, pos);
  696. m_curPos = pos;
  697. return true;
  698. }
  699. return false;
  700. }
  701. const int MAXLINEHIGHLIGHT = 400;
  702. void ScintillaEditView::slot_delayWork()
  703. {
  704. if (!hasSelectedText())
  705. {
  706. return;
  707. }
  708. QString word = selectedText();
  709. if (!word.isEmpty())
  710. {
  711. QVector<int>resultPos;
  712. resultPos.reserve(50);
  713. int firstLine = execute(SCI_GETFIRSTVISIBLELINE);
  714. int nbLineOnScreen = execute(SCI_LINESONSCREEN);
  715. int nbLines = std::min(nbLineOnScreen, MAXLINEHIGHLIGHT) + 1;
  716. int lastLine = firstLine + nbLines;
  717. long startPos = execute(SCI_POSITIONFROMLINE, firstLine);
  718. long endPos = execute(SCI_POSITIONFROMLINE, lastLine);
  719. if (endPos == -1)
  720. {
  721. endPos = execute(SCI_GETLENGTH);
  722. }
  723. int curpos = execute(SCI_GETCURRENTPOS);
  724. int mainSelect = 1;
  725. //struct Sci_TextToFind findOptions;
  726. ////20220226发现高亮全选如果范围过大,会导致卡死。借鉴notepad的只高亮可视化区域。但是滚动时也必须生效
  727. ////findOptions.chrg.cpMin = 0;
  728. ////findOptions.chrg.cpMax = execute(SCI_GETLENGTH);
  729. //
  730. //findOptions.chrg.cpMin = startPos;
  731. //findOptions.chrg.cpMax = endPos;
  732. //findOptions.lpstrText = wordStr.c_str();
  733. //20220422 升级高版本scint后,发现Sci_TextToFind要崩溃,替换为SCI_SEARCHINTARGET
  734. //int pos = execute(SCI_FINDTEXT, SCFIND_MATCHCASE | SCFIND_WHOLEWORD, reinterpret_cast<sptr_t>(&findOptions));
  735. //std::string wordStr = word.toStdString();
  736. QByteArray wordStr = word.toUtf8();
  737. SendScintilla(SCI_SETTARGETSTART, startPos);
  738. SendScintilla(SCI_SETTARGETEND, endPos);
  739. SendScintilla(SCI_SETSEARCHFLAGS, SCFIND_MATCHCASE|SCFIND_WHOLEWORD);
  740. long lens = wordStr.length();
  741. long pos = SendScintilla(SCI_SEARCHINTARGET, lens, wordStr.data()/*,wordStr.c_str()*/);
  742. while ((pos != -1)&&(pos < endPos))
  743. {
  744. resultPos.append(pos);
  745. if (pos <= curpos)
  746. {
  747. mainSelect = resultPos.size();
  748. }
  749. SendScintilla(SCI_SETTARGETSTART, pos + lens);
  750. SendScintilla(SCI_SETTARGETEND, endPos);
  751. pos = SendScintilla(SCI_SEARCHINTARGET, wordStr.length(), wordStr.data()/*,wordStr.c_str()*/);
  752. //findOptions.chrg.cpMin = findOptions.chrgText.cpMax;
  753. //pos = execute(SCI_FINDTEXT, SCFIND_MATCHCASE | SCFIND_WHOLEWORD, reinterpret_cast<sptr_t>(&findOptions));
  754. }
  755. for (int i = 0, size = resultPos.size(); i < size; ++i)
  756. {
  757. //execute(SCI_ADDSELECTION, resultPos.at(i), resultPos.at(i) + word.size());
  758. execute(SCI_ADDSELECTION, resultPos.at(i) + lens, resultPos.at(i) );
  759. }
  760. if (!resultPos.isEmpty())
  761. {
  762. execute(SCI_SETMAINSELECTION, mainSelect - 1);
  763. }
  764. }
  765. }
  766. void ScintillaEditView::dragEnterEvent(QDragEnterEvent* event)
  767. {
  768. //if (event->mimeData()->hasFormat("text/uri-list")) //只能打开文本文件
  769. //{
  770. // event->accept(); //可以在这个窗口部件上拖放对象
  771. //}
  772. //else
  773. //{
  774. // event->ignore();
  775. //}
  776. event->accept();
  777. }
  778. void ScintillaEditView::dropEvent(QDropEvent* e)
  779. {
  780. QList<QUrl> urls = e->mimeData()->urls();
  781. if (urls.isEmpty())
  782. return;
  783. CCNotePad* pv = dynamic_cast<CCNotePad*>(m_NoteWin);
  784. if (pv != nullptr)
  785. pv->receiveEditDrop(e);
  786. //qDebug() << ui.leftSrc->geometry() << ui.rightSrc->geometry() << QCursor::pos() << this->mapFromGlobal(QCursor::pos());
  787. }
  788. void ScintillaEditView::mouseDoubleClickEvent(QMouseEvent * e)
  789. {
  790. QsciScintilla::mouseDoubleClickEvent(e);
  791. if (hasSelectedText())
  792. {
  793. emit delayWork();
  794. }
  795. }