1 
2 /*
3  * CodeQuery
4  * Copyright (C) 2013-2017 ruben2020 https://github.com/ruben2020/
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  */
11 
12 
13 #include <QString>
14 #include <QStringList>
15 
16 #include "ScintillaEdit.h"
17 
18 #include "small_lib.h"
19 #include "fileviewer.h"
20 #include "themes.h"
21 
22 #ifdef USE_QT5
23 #define QT45_TOASCII(x) toLatin1(x)
24 #else
25 #define QT45_TOASCII(x) toAscii(x)
26 #endif
27 
28 typedef struct
29 {
30 	const char *themename;
31 	const char *defaultfgcolor;
32 	const char *defaultbgcolor;
33 	const char *currentlinebgcolor;
34 	const char *linenumfgcolor;
35 	const lexstyle *lexstyletable;
36 	const lexstyle *globallexstyletable;
37 	int lexstylesize;
38 	int globallexstylesize;
39 }langstyle;
40 
41 
42 #include "themes_gen.cpp"
43 
44 // Keywords lists below taken from langs.model.xml of Notepad++
45 
46 const char* python_keywords =
47 "and as assert break class continue def "
48 "del elif else except exec False finally "
49 "for from global if import in is lambda "
50 "None not or pass print raise return "
51 "True try while with yield async await";
52 
53 const char* ruby_keywords =
54 "ARGF ARGV BEGIN END ENV FALSE DATA NIL "
55 "RUBY_PATCHLEVEL RUBY_PLATFORM RUBY_RELEASE_DATE "
56 "RUBY_VERSION PLATFORM RELEASE_DATE STDERR STDIN "
57 "STDOUT TOPLEVEL_BINDING TRUE __ENCODING__ "
58 "__END__ __FILE__ __LINE__ alias and begin break "
59 "case class def defined? do else elsif end ensure "
60 "false for if in module next nil not or redo rescue "
61 "retry return self super then true undef "
62 "unless until when while yield";
63 
64 const char* js_keywords =
65 "abstract async await boolean break byte case catch "
66 "char class const continue debugger default delete do "
67 "double else enum export extends final finally float "
68 "for from function goto if implements import in instanceof "
69 "int interface let long native new null of package private "
70 "protected public return short static super switch synchronized "
71 "this throw throws transient try typeof var void "
72 "volatile while with true false prototype yield";
73 
74 const char* js_types =
75 "Array Date eval hasOwnProperty Infinity isFinite isNaN "
76 "isPrototypeOf Math NaN Number Object prototype "
77 "String toString undefined valueOf";
78 
79 const char* java_keywords =
80 "instanceof assert if else switch case default break goto "
81 "return for while do continue new throw throws try catch "
82 "finally this super extends implements import true false null";
83 
84 const char* java_types =
85 "package transient strictfp void char short int long double "
86 "float const static volatile byte boolean class interface "
87 "native private protected public final abstract synchronized enum";
88 
89 const char* cpp_keywords =
90 "alignof and and_eq bitand bitor break case catch compl const_cast "
91 "continue default delete do dynamic_cast else false for goto if "
92 "namespace new not not_eq nullptr operator or or_eq reinterpret_cast "
93 "return sizeof static_assert static_cast switch this "
94 "throw true try typedef typeid using while xor xor_eq NULL";
95 
96 const char* cpp_types =
97 "alignas asm auto bool char char16_t char32_t class clock_t "
98 "const constexpr decltype double enum explicit export extern "
99 "final float friend inline int int8_t int16_t int32_t int64_t "
100 "int_fast8_t int_fast16_t int_fast32_t int_fast64_t intmax_t "
101 "intptr_t long mutable noexcept override private protected "
102 "ptrdiff_t public register short signed size_t ssize_t static "
103 "struct template thread_local time_t typename uint8_t uint16_t "
104 "uint32_t uint64_t uint_fast8_t uint_fast16_t uint_fast32_t "
105 "uint_fast64_t uintmax_t uintptr_t union "
106 "unsigned virtual void volatile wchar_t";
107 
108 const char* cpp_docwords =
109 "a addindex addtogroup anchor arg attention author authors b brief "
110 "bug c callergraph callgraph category cite class code cond "
111 "copybrief copydetails copydoc copyright date def defgroup deprecated "
112 "details diafile dir docbookonly dontinclude dot dotfile e else elseif "
113 "em endcode endcond enddocbookonly enddot endhtmlonly endif endinternal "
114 "endlatexonly endlink endmanonly endmsc endparblock endrtfonly "
115 "endsecreflist enduml endverbatim endxmlonly enum example exception "
116 "extends f$ f[ f] file fn f{ f} headerfile hidecallergraph hidecallgraph "
117 "hideinitializer htmlinclude htmlonly idlexcept if ifnot image "
118 "implements include includelineno ingroup interface internal invariant "
119 "latexinclude latexonly li line link mainpage manonly memberof msc mscfile "
120 "n name namespace nosubgrouping note overload p package page par paragraph "
121 "param parblock post pre private privatesection property protected "
122 "protectedsection protocol public publicsection pure ref refitem related "
123 "relatedalso relates relatesalso remark remarks result return returns "
124 "retval rtfonly sa secreflist section see short showinitializer since "
125 "skip skipline snippet startuml struct subpage subsection subsubsection "
126 "tableofcontents test throw throws todo tparam typedef union until var "
127 "verbatim verbinclude version vhdlflow warning weakgroup xmlonly xrefitem";
128 
129 const char* go_keywords = "break default func interface select "
130 "case defer go map struct chan else goto package switch "
131 "const fallthrough if range type continue for import return var "
132 "append cap close complex copy delete imag len "
133 "make new panic print println real recover";
134 
135 const char* go_types = "true false iota nil "
136 "bool byte complex64 complex128 error float32 float64 "
137 "int int8 int16 int32 int64 rune string "
138 "uint uint8 uint16 uint32 uint64 uintptr";
139 
140 
getThemesList(void)141 QStringList themes::getThemesList(void)
142 {
143 	QStringList lst;
144 	for(int i=0; i<NUM_OF_THEMES; i++)
145 	{
146 		lst << QString::fromLatin1(themelist[i]);
147 	}
148 	return lst;
149 }
150 
setKeywords(int lang,ScintillaEdit * lexer)151 void themes::setKeywords(int lang, ScintillaEdit* lexer)
152 {
153 	int i;
154 	for (i=1; i <= 2; i++) lexer->setKeyWords(i, " ");
155 	switch(lang)
156 	{
157 		case enHighlightPython:
158 		lexer->setKeyWords(0, python_keywords);
159 		break;
160 
161 		case enHighlightJava:
162 		lexer->setKeyWords(0, java_keywords);
163 		lexer->setKeyWords(1, java_types);
164 		break;
165 
166 		case enHighlightRuby:
167 		lexer->setKeyWords(0, ruby_keywords);
168 		break;
169 
170 		case enHighlightJavascript:
171 		lexer->setKeyWords(0, js_keywords);
172 		lexer->setKeyWords(1, js_types);
173 		break;
174 
175 		case enHighlightGo:
176 		lexer->setKeyWords(0, go_keywords);
177 		lexer->setKeyWords(1, go_types);
178 		break;
179 
180 		case enHighlightCPP:
181 			// fall through
182 		default:
183 		lexer->setKeyWords(0, cpp_keywords);
184 		lexer->setKeyWords(1, cpp_types);
185 		lexer->setKeyWords(2, cpp_docwords);
186 		break;
187 	}
188 
189 }
190 
QC2SC(QColor colour)191 long themes::QC2SC(QColor colour)
192 {
193 	long retval;
194 	retval  =  (long) colour.red();
195 	retval |= ((long) colour.green()) << 8;
196 	retval |= ((long) colour.blue())  << 16;
197 	return  retval;
198 }
199 
setTheme(const QString & theme,int lang,ScintillaEdit * lexer,const QFont & fontt,QColor & curlinebgcolor,QColor & linenumbgcolor)200 void themes::setTheme(const QString& theme, int lang, ScintillaEdit* lexer, const QFont& fontt, QColor& curlinebgcolor, QColor& linenumbgcolor)
201 {
202 	langstyle *lngstyle = NULL;
203 	lexstyle *lxstyle = NULL;
204 	lexstyle *globallxstyle = NULL;
205 	int i=0;
206 	int lxstylesize=0;
207 	int globallxstylesize=0;
208 	long defbgcolor;
209 	long deffgcolor;
210 	QFont font1 = fontt;
211 	//font1.setFixedPitch(true);
212 	font1.setBold(false);
213 	font1.setItalic(false);
214 	for (i=0; i < 4; i++) lexer->setKeyWords(i, "");
215 	switch(lang)
216 	{
217 		case enHighlightCPP:
218 		lngstyle = (langstyle *) cppstyle;
219 		break;
220 
221 		case enHighlightPython:
222 		lngstyle = (langstyle *) pythonstyle;
223 		break;
224 
225 		case enHighlightJava:
226 		lngstyle = (langstyle *) javastyle;
227 		break;
228 
229 		case enHighlightRuby:
230 		lngstyle = (langstyle *) rubystyle;
231 		break;
232 
233 		case enHighlightJavascript:
234 		lngstyle = (langstyle *) cppstyle;
235 		//lngstyle = (langstyle *) javascriptstyle;
236 		break;
237 
238 		default:
239 		lngstyle = (langstyle *) cppstyle;
240 		break;
241 	}
242 	i = 0;
243 	while (lngstyle[i].lexstylesize > 0)
244 	{
245 		if (theme.compare(QString(lngstyle[i].themename)) == 0)
246 		{
247 			lxstyle = (lexstyle *) lngstyle[i].lexstyletable;
248 			globallxstyle = (lexstyle *) lngstyle[i].globallexstyletable;
249 			lxstylesize = lngstyle[i].lexstylesize;
250 			globallxstylesize = lngstyle[i].globallexstylesize;
251 			defbgcolor = QC2SC(QColor(QString("#").append(QString(lngstyle[i].defaultbgcolor))));
252 			deffgcolor = QC2SC(QColor(QString("#").append(QString(lngstyle[i].defaultfgcolor))));
253 			lexer->styleSetBack(  STYLE_DEFAULT, defbgcolor);
254 			lexer->styleSetFore(  STYLE_DEFAULT, deffgcolor);
255 			lexer->styleSetFont(  STYLE_DEFAULT, font1.family().QT45_TOASCII().data());
256 			lexer->styleSetBold(  STYLE_DEFAULT, false);
257 			lexer->styleSetItalic(STYLE_DEFAULT, false);
258 			lexer->styleClearAll();
259 			lexer->setCaretFore(deffgcolor);
260 			break;
261 		}
262 		i++;
263 	}
264 	setThemeStyle(lexer, globallxstyle, globallxstylesize, font1);
265 	setThemeStyle(lexer, lxstyle      , lxstylesize      , font1);
266 	curlinebgcolor = QColor(QString("#").append(QString(lngstyle[i].currentlinebgcolor)));
267 	linenumbgcolor = QColor(QString("#").append(QString(lngstyle[i].linenumfgcolor)));
268 }
269 
setThemeStyle(ScintillaEdit * lexer,lexstyle * lxstyle,int lxstylesize,QFont & font1)270 void themes::setThemeStyle(ScintillaEdit* lexer, lexstyle *lxstyle, int lxstylesize, QFont& font1)
271 {
272 	int i;
273 	if (lxstyle != NULL)
274 	for(i=0; i<lxstylesize; i++)
275 	{
276 		if (
277 			(lxstyle[i].styleid == 0) ||
278 			(lxstyle[i].styleid == STYLE_DEFAULT))
279 				continue;
280 		lexer->styleSetBack(lxstyle[i].styleid, QC2SC(QColor(QString("#").append(QString(lxstyle[i].bgcolor)))));
281 		lexer->styleSetFore(lxstyle[i].styleid, QC2SC(QColor(QString("#").append(QString(lxstyle[i].fgcolor)))));
282 		lexer->styleSetFont(lxstyle[i].styleid, font1.family().QT45_TOASCII().data());
283 		switch(lxstyle[i].fontstyle)
284 		{
285 			case 1:
286 				lexer->styleSetBold(lxstyle[i].styleid, true);
287 				lexer->styleSetItalic(lxstyle[i].styleid, false);
288 				break;
289 
290 			case 2:
291 				lexer->styleSetBold(lxstyle[i].styleid, false);
292 				lexer->styleSetItalic(lxstyle[i].styleid, true);
293 				break;
294 
295 			case 3:
296 				lexer->styleSetBold(lxstyle[i].styleid, true);
297 				lexer->styleSetItalic(lxstyle[i].styleid, true);
298 				break;
299 
300 			default:
301 				lexer->styleSetBold(lxstyle[i].styleid, false);
302 				lexer->styleSetItalic(lxstyle[i].styleid, false);
303 				break;
304 
305 		}
306 	}
307 }
308 
309