1 | /* |
2 | * Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com) |
3 | * |
4 | * This program is free software: you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License as published by |
6 | * the Free Software Foundation, either version 3 of the License, or |
7 | * (at your option) any later version. |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program. If not, see <https://www.gnu.org/licenses/>. |
16 | */ |
17 | #include "colorscheme.h" |
18 | #include <QDir> |
19 | #include <QFile> |
20 | #include <QJsonArray> |
21 | #include <QJsonDocument> |
22 | #include <QJsonObject> |
23 | #include "utils.h" |
24 | #include "settings.h" |
25 | #include "qsynedit/Constants.h" |
26 | |
27 | |
28 | ColorManager * pColorManager; |
29 | ColorScheme::ColorScheme() |
30 | { |
31 | |
32 | } |
33 | |
34 | PColorScheme ColorScheme::fromJson(const QJsonObject &json) |
35 | { |
36 | PColorScheme scheme = std::make_shared<ColorScheme>(); |
37 | scheme->mItems.clear(); |
38 | for (QString key:json.keys()) { |
39 | if (json[key].isObject()) { |
40 | scheme->mItems[key]=ColorSchemeItem::fromJson(json[key].toObject()); |
41 | } |
42 | } |
43 | return scheme; |
44 | } |
45 | |
46 | void ColorScheme::toJson(QJsonObject &json) |
47 | { |
48 | for (QString key:mItems.keys()) { |
49 | PColorSchemeItem item = mItems[key]; |
50 | if (item) { |
51 | QJsonObject itemObject; |
52 | item->toJson(itemObject); |
53 | json[key] = itemObject; |
54 | } |
55 | } |
56 | } |
57 | |
58 | PColorScheme ColorScheme::load(const QString &filename) |
59 | { |
60 | QFile file(filename); |
61 | if (!file.open(QFile::ReadOnly)) { |
62 | qDebug()<<QObject::tr("Can't open file '%1' for read" ).arg(file.fileName()); |
63 | return PColorScheme(); |
64 | } |
65 | QByteArray content = file.readAll(); |
66 | QJsonParseError error; |
67 | QJsonDocument doc = QJsonDocument::fromJson(content,&error); |
68 | if (error.error!=QJsonParseError::NoError) { |
69 | qDebug()<<QObject::tr("Can't parse json file '%1' at offset %2! Error Code: %3" ) |
70 | .arg(file.fileName()).arg(error.offset).arg(error.error); |
71 | } |
72 | if (!doc.isObject()) { |
73 | qDebug()<<QObject::tr("Can't parse json file '%1' is not a color scheme config file!" ) |
74 | .arg(file.fileName()); |
75 | } |
76 | return ColorScheme::fromJson(doc.object()); |
77 | } |
78 | |
79 | void ColorScheme::addItem(const QString& name) |
80 | { |
81 | if (mItems.contains(name)) |
82 | return; |
83 | PColorSchemeItem item = std::make_shared<ColorSchemeItem>(); |
84 | mItems[name]=item; |
85 | } |
86 | |
87 | QMap<QString, PColorSchemeItem> ColorScheme::items() |
88 | { |
89 | return mItems; |
90 | } |
91 | |
92 | void ColorScheme::save(const QString &filename) |
93 | { |
94 | QFile file(filename); |
95 | QFileInfo info(filename); |
96 | info.dir().mkpath(info.dir().absolutePath()); |
97 | if (!file.open(QFile::WriteOnly)) { |
98 | throw FileError(QObject::tr("Can't open file '%1' for write" ).arg(file.fileName())); |
99 | } |
100 | QJsonObject json; |
101 | toJson(json); |
102 | QJsonDocument doc(json); |
103 | QByteArray content = doc.toJson(); |
104 | file.write(content); |
105 | } |
106 | |
107 | bool ColorScheme::bundled() const |
108 | { |
109 | return mBundled; |
110 | } |
111 | |
112 | void ColorScheme::setBundled(bool bundled) |
113 | { |
114 | mBundled = bundled; |
115 | } |
116 | |
117 | bool ColorScheme::customed() const |
118 | { |
119 | return mCustomed; |
120 | } |
121 | |
122 | void ColorScheme::setCustomed(bool customed) |
123 | { |
124 | mCustomed = customed; |
125 | } |
126 | |
127 | QString ColorScheme::preferThemeType() const |
128 | { |
129 | return mPreferThemeType; |
130 | } |
131 | |
132 | void ColorScheme::setPreferThemeType(const QString &preferThemeType) |
133 | { |
134 | mPreferThemeType = preferThemeType; |
135 | } |
136 | |
137 | ColorSchemeItem::ColorSchemeItem(): |
138 | mForeground(), |
139 | mBackground(), |
140 | mBold(false), |
141 | mItalic(false), |
142 | mUnderlined(false), |
143 | mStrikeout(false) |
144 | { |
145 | |
146 | } |
147 | |
148 | QColor ColorSchemeItem::foreground() const |
149 | { |
150 | return mForeground; |
151 | } |
152 | |
153 | void ColorSchemeItem::setForeground(const QColor &foreground) |
154 | { |
155 | mForeground = foreground; |
156 | } |
157 | |
158 | QColor ColorSchemeItem::background() const |
159 | { |
160 | return mBackground; |
161 | } |
162 | |
163 | void ColorSchemeItem::setBackground(const QColor &background) |
164 | { |
165 | mBackground = background; |
166 | } |
167 | |
168 | bool ColorSchemeItem::bold() const |
169 | { |
170 | return mBold; |
171 | } |
172 | |
173 | void ColorSchemeItem::setBold(bool bold) |
174 | { |
175 | mBold = bold; |
176 | } |
177 | |
178 | bool ColorSchemeItem::italic() const |
179 | { |
180 | return mItalic; |
181 | } |
182 | |
183 | void ColorSchemeItem::setItalic(bool italic) |
184 | { |
185 | mItalic = italic; |
186 | } |
187 | |
188 | bool ColorSchemeItem::underlined() const |
189 | { |
190 | return mUnderlined; |
191 | } |
192 | |
193 | void ColorSchemeItem::setUnderlined(bool underlined) |
194 | { |
195 | mUnderlined = underlined; |
196 | } |
197 | |
198 | bool ColorSchemeItem::strikeout() const |
199 | { |
200 | return mStrikeout; |
201 | } |
202 | |
203 | void ColorSchemeItem::setStrikeout(bool strikeout) |
204 | { |
205 | mStrikeout = strikeout; |
206 | } |
207 | |
208 | PColorSchemeItem ColorSchemeItem::fromJson(const QJsonObject &json) |
209 | { |
210 | PColorSchemeItem item = std::make_shared<ColorSchemeItem>(); |
211 | if (json.contains("foreground" ) && json["foreground" ].isString()) { |
212 | item->setForeground(json["foreground" ].toString()); |
213 | } else { |
214 | item->setForeground(QColor()); |
215 | } |
216 | if (json.contains("background" ) && json["background" ].isString()) { |
217 | item->setBackground(json["background" ].toString()); |
218 | } else { |
219 | item->setBackground(QColor()); |
220 | } |
221 | if (json.contains("bold" ) && json["bold" ].isBool()) { |
222 | item->setBold(json["bold" ].toBool()); |
223 | } else { |
224 | item->setBold(false); |
225 | } |
226 | if (json.contains("italic" ) && json["italic" ].isBool()) { |
227 | item->setItalic(json["italic" ].toBool()); |
228 | } else { |
229 | item->setItalic(false); |
230 | } |
231 | if (json.contains("underlined" ) && json["underlined" ].isBool()) { |
232 | item->setUnderlined(json["underlined" ].toBool()); |
233 | } else { |
234 | item->setUnderlined(false); |
235 | } |
236 | if (json.contains("strikeout" ) && json["strikeout" ].isBool()) { |
237 | item->setStrikeout(json["strikeout" ].toBool()); |
238 | } else { |
239 | item->setStrikeout(false); |
240 | } |
241 | return item; |
242 | } |
243 | |
244 | void ColorSchemeItem::toJson(QJsonObject &json) |
245 | { |
246 | if (mForeground.isValid()) { |
247 | json["foreground" ] = mForeground.name(QColor::HexArgb); |
248 | } else if (json.contains("foreground" )){ |
249 | json.remove("foreground" ); |
250 | } |
251 | if (mBackground.isValid()) { |
252 | json["background" ] = mBackground.name(QColor::HexArgb); |
253 | } else if (json.contains("background" )){ |
254 | json.remove("background" ); |
255 | } |
256 | json["bold" ] = mBold; |
257 | json["italic" ] = mItalic; |
258 | json["underlined" ] = mUnderlined; |
259 | json["strikeout" ] = mStrikeout; |
260 | } |
261 | |
262 | ColorManager::ColorManager() |
263 | { |
264 | mDefaultSchemeItemDefine = std::make_shared<ColorSchemeItemDefine>(); |
265 | initItemDefines(); |
266 | init(); |
267 | } |
268 | |
269 | void ColorManager::init() |
270 | { |
271 | reload(); |
272 | } |
273 | |
274 | void ColorManager::reload() |
275 | { |
276 | mSchemes.clear(); |
277 | //bundled schemes ( the lowest priority) |
278 | loadSchemesInDir(pSettings->dirs().data(Settings::Dirs::DataType::ColorScheme),true,false); |
279 | //config schemes ( higher priority) |
280 | loadSchemesInDir(pSettings->dirs().config(Settings::Dirs::DataType::ColorScheme),false,false); |
281 | //customed schemes ( highest priority) |
282 | loadSchemesInDir(pSettings->dirs().config(Settings::Dirs::DataType::ColorScheme),false,true); |
283 | } |
284 | |
285 | QStringList ColorManager::getSchemes(const QString &themeType) |
286 | { |
287 | if (themeType.isEmpty()) { |
288 | return mSchemes.keys(); |
289 | } |
290 | QStringList lst; |
291 | for (QString name:mSchemes.keys()) { |
292 | PColorScheme scheme = mSchemes[name]; |
293 | if (scheme && scheme->preferThemeType() == themeType) { |
294 | lst.append(name); |
295 | } |
296 | } |
297 | return lst; |
298 | } |
299 | |
300 | QStringList ColorManager::getDefines() |
301 | { |
302 | return mSchemeItemDefines.keys(); |
303 | } |
304 | |
305 | bool ColorManager::exists(const QString name) |
306 | { |
307 | return mSchemes.contains(name); |
308 | } |
309 | |
310 | QString ColorManager::copy(const QString &sourceName) |
311 | { |
312 | if (!mSchemes.contains(sourceName)) |
313 | return QString(); |
314 | PColorScheme sourceScheme = mSchemes[sourceName]; |
315 | QString newName = sourceName+" Copy" ; |
316 | if (mSchemes.contains(newName)) |
317 | return QString(); |
318 | // save source with the new name |
319 | QString newFilepath = generateFullPathname(newName,false,false); |
320 | sourceScheme->save(newFilepath); |
321 | // then load it to the copied |
322 | PColorScheme newScheme = ColorScheme::load(newFilepath); |
323 | newScheme->setBundled(false); |
324 | newScheme->setCustomed(false); |
325 | mSchemes[newName]=newScheme; |
326 | return newName; |
327 | } |
328 | |
329 | bool ColorManager::restoreToDefault(const QString &name) |
330 | { |
331 | PColorScheme scheme = get(name); |
332 | if (!scheme) |
333 | return false; |
334 | if (!scheme->customed()) |
335 | return false; |
336 | QString fullPath = generateFullPathname(name,scheme->bundled(),false); |
337 | PColorScheme oldScheme = ColorScheme::load(fullPath); |
338 | if (!oldScheme) |
339 | throw FileError(QObject::tr("Can't Find the color scheme file %1!" ).arg(fullPath)); |
340 | fullPath = generateFullPathname(name,scheme->bundled(),true); |
341 | QFile file(fullPath); |
342 | if (file.exists() && !file.remove()) |
343 | throw FileError(QObject::tr("Can't remove the color scheme file %1!" ).arg(fullPath)); |
344 | oldScheme->setBundled(scheme->bundled()); |
345 | oldScheme->setCustomed(false); |
346 | mSchemes[name]=oldScheme; |
347 | return true; |
348 | } |
349 | |
350 | bool ColorManager::remove(const QString &name) |
351 | { |
352 | PColorScheme scheme = get(name); |
353 | if (!scheme) |
354 | return false; |
355 | if (scheme->bundled()) |
356 | return false; |
357 | if (scheme->customed()) { |
358 | QString fullPath = generateFullPathname(name,false,true); |
359 | QFile file(fullPath); |
360 | if (!file.remove()) |
361 | throw FileError(QObject::tr("Can't remove the color scheme file %1!" ).arg(fullPath)); |
362 | } |
363 | QString fullPath = generateFullPathname(name,false,false); |
364 | QFile file(fullPath); |
365 | if (!file.remove()) |
366 | throw FileError(QObject::tr("Can't remove the color scheme file %1!" ).arg(fullPath)); |
367 | mSchemes.remove(name); |
368 | return true; |
369 | } |
370 | |
371 | QString ColorManager::generateFilename(const QString &name, bool isCustomed) |
372 | { |
373 | QString newName = name; |
374 | newName.replace(' ','_'); |
375 | if (isCustomed) |
376 | newName += EXT_PREFIX_CUSTOM; |
377 | return newName += EXT_COLOR_SCHEME; |
378 | } |
379 | |
380 | void ColorManager::loadSchemesInDir(const QString &dirName, bool isBundled, bool isCustomed) |
381 | { |
382 | QDir dir(dirName); |
383 | dir.setFilter(QDir::Files); |
384 | QFileInfoList list = dir.entryInfoList(); |
385 | QString suffix; |
386 | QString customSuffix = EXT_PREFIX_CUSTOM; |
387 | customSuffix += EXT_COLOR_SCHEME; |
388 | if (isCustomed) { |
389 | suffix = customSuffix; |
390 | } else { |
391 | suffix = EXT_COLOR_SCHEME; |
392 | } |
393 | for (int i=0;i<list.size();i++) { |
394 | QFileInfo fileInfo = list[i]; |
395 | QString name = fileInfo.fileName(); |
396 | if (name.toLower().endsWith(suffix)) { |
397 | // if (!isCustomed && name.toLower().endsWith(customSuffix)) |
398 | // continue; |
399 | name.remove(name.length()-suffix.length(),suffix.length()); |
400 | name.replace('_',' '); |
401 | if (!isValidName(name)) |
402 | continue; |
403 | PColorScheme scheme = ColorScheme::load(fileInfo.absoluteFilePath()); |
404 | if (!isCustomed) { |
405 | scheme->setBundled(isBundled); |
406 | scheme->setCustomed(false); |
407 | } else { |
408 | scheme->setBundled(false); |
409 | if (mSchemes.contains(name)) { |
410 | PColorScheme oldScheme = mSchemes[name]; |
411 | if (oldScheme) { |
412 | scheme->setBundled(oldScheme->bundled()); |
413 | } |
414 | mSchemes.remove(name); |
415 | } |
416 | scheme->setCustomed(true); |
417 | } |
418 | mSchemes[name]=scheme; |
419 | } |
420 | } |
421 | } |
422 | |
423 | void ColorManager::initItemDefines() |
424 | { |
425 | //Highlighter colors |
426 | addDefine(SYNS_AttrAssembler, |
427 | QObject::tr("Assembler" ), |
428 | QObject::tr("Syntax" ), |
429 | true,true,true); |
430 | addDefine(SYNS_AttrCharacter, |
431 | QObject::tr("Character" ), |
432 | QObject::tr("Syntax" ), |
433 | true,true,true); |
434 | addDefine(SYNS_AttrComment, |
435 | QObject::tr("Comment" ), |
436 | QObject::tr("Syntax" ), |
437 | true,true,true); |
438 | addDefine(SYNS_AttrClass, |
439 | QObject::tr("Class" ), |
440 | QObject::tr("Syntax" ), |
441 | true,true,true); |
442 | addDefine(SYNS_AttrFloat, |
443 | QObject::tr("Float" ), |
444 | QObject::tr("Syntax" ), |
445 | true,true,true); |
446 | addDefine(SYNS_AttrFunction, |
447 | QObject::tr("Function" ), |
448 | QObject::tr("Syntax" ), |
449 | true,true,true); |
450 | addDefine(SYNS_AttrGlobalVariable, |
451 | QObject::tr("Gloabal Variable" ), |
452 | QObject::tr("Syntax" ), |
453 | true,true,true); |
454 | addDefine(SYNS_AttrHexadecimal, |
455 | QObject::tr("Hexadecimal Integer" ), |
456 | QObject::tr("Syntax" ), |
457 | true,true,true); |
458 | addDefine(SYNS_AttrIdentifier, |
459 | QObject::tr("Identifier" ), |
460 | QObject::tr("Syntax" ), |
461 | true,true,true); |
462 | addDefine(SYNS_AttrIllegalChar, |
463 | QObject::tr("Illegal Char" ), |
464 | QObject::tr("Syntax" ), |
465 | true,true,true); |
466 | addDefine(SYNS_AttrLocalVariable, |
467 | QObject::tr("Local Variable" ), |
468 | QObject::tr("Syntax" ), |
469 | true,true,true); |
470 | addDefine(SYNS_AttrNumber, |
471 | QObject::tr("Integer" ), |
472 | QObject::tr("Syntax" ), |
473 | true,true,true); |
474 | addDefine(SYNS_AttrOctal, |
475 | QObject::tr("Octal Integer" ), |
476 | QObject::tr("Syntax" ), |
477 | true,true,true); |
478 | addDefine(SYNS_AttrPreprocessor, |
479 | QObject::tr("Preprocessor" ), |
480 | QObject::tr("Syntax" ), |
481 | true,true,true); |
482 | addDefine(SYNS_AttrReservedWord, |
483 | QObject::tr("Reserve Word" ), |
484 | QObject::tr("Syntax" ), |
485 | true,true,true); |
486 | addDefine(SYNS_AttrSpace, |
487 | QObject::tr("Space" ), |
488 | QObject::tr("Syntax" ), |
489 | true,true,true); |
490 | addDefine(SYNS_AttrString, |
491 | QObject::tr("String" ), |
492 | QObject::tr("Syntax" ), |
493 | true,true,true); |
494 | addDefine(SYNS_AttrStringEscapeSequences, |
495 | QObject::tr("Escape Sequences" ), |
496 | QObject::tr("Syntax" ), |
497 | true,true,true); |
498 | addDefine(SYNS_AttrSymbol, |
499 | QObject::tr("Symbol" ), |
500 | QObject::tr("Syntax" ), |
501 | true,true,true); |
502 | addDefine(SYNS_AttrVariable, |
503 | QObject::tr("Variable" ), |
504 | QObject::tr("Syntax" ), |
505 | true,true,true); |
506 | |
507 | //Brace/Bracket/Parenthesis Level 1 2 3 4 |
508 | addDefine(COLOR_SCHEME_BRACE_1, |
509 | QObject::tr("Brace/Bracket/Parenthesis Level 1" ), |
510 | QObject::tr("Syntax" ), |
511 | true,false,false); |
512 | addDefine(COLOR_SCHEME_BRACE_2, |
513 | QObject::tr("Brace/Bracket/Parenthesis Level 2" ), |
514 | QObject::tr("Syntax" ), |
515 | true,false,false); |
516 | addDefine(COLOR_SCHEME_BRACE_3, |
517 | QObject::tr("Brace/Bracket/Parenthesis Level 3" ), |
518 | QObject::tr("Syntax" ), |
519 | true,false,false); |
520 | addDefine(COLOR_SCHEME_BRACE_4, |
521 | QObject::tr("Brace/Bracket/Parenthesis Level 4" ), |
522 | QObject::tr("Syntax" ), |
523 | true,false,false); |
524 | |
525 | //Gutter colors |
526 | addDefine(COLOR_SCHEME_GUTTER, |
527 | QObject::tr("Gutter" ), |
528 | QObject::tr("Editor" ), |
529 | true,true,true); |
530 | addDefine(COLOR_SCHEME_GUTTER_ACTIVE_LINE, |
531 | QObject::tr("Gutter Active Line" ), |
532 | QObject::tr("Editor" ), |
533 | true,false,false); |
534 | //Active Line |
535 | addDefine(COLOR_SCHEME_ACTIVE_LINE, |
536 | QObject::tr("Active Line" ), |
537 | QObject::tr("Editor" ), |
538 | false,true,false); |
539 | //Breakpoint Line |
540 | addDefine(COLOR_SCHEME_BREAKPOINT, |
541 | QObject::tr("Breakpoint" ), |
542 | QObject::tr("Editor" ), |
543 | true,true,false); |
544 | //Current Debug Line |
545 | addDefine(COLOR_SCHEME_ACTIVE_BREAKPOINT, |
546 | QObject::tr("Active Breakpoint" ), |
547 | QObject::tr("Editor" ), |
548 | true,true,false); |
549 | //Fold line |
550 | addDefine(COLOR_SCHEME_FOLD_LINE, |
551 | QObject::tr("Fold Line" ), |
552 | QObject::tr("Editor" ), |
553 | true,false,false); |
554 | |
555 | addDefine(COLOR_SCHEME_SELECTION, |
556 | QObject::tr("Selection" ), |
557 | QObject::tr("Editor" ), |
558 | true,true,false); |
559 | |
560 | addDefine(COLOR_SCHEME_TEXT, |
561 | QObject::tr("Editor Text" ), |
562 | QObject::tr("Editor" ), |
563 | true,true,false); |
564 | |
565 | addDefine(COLOR_SCHEME_CURRENT_HIGHLIGHTED_WORD, |
566 | QObject::tr("Current Highlighted Word" ), |
567 | QObject::tr("Editor" ), |
568 | true,true,false); |
569 | |
570 | //Syntax Error |
571 | addDefine(COLOR_SCHEME_ERROR, |
572 | QObject::tr("Error" ), |
573 | QObject::tr("Syntax Check" ), |
574 | true,false,false); |
575 | addDefine(COLOR_SCHEME_WARNING, |
576 | QObject::tr("Warning" ), |
577 | QObject::tr("Syntax Check" ), |
578 | true,false,false); |
579 | } |
580 | |
581 | bool ColorManager::rename(const QString &oldName, const QString &newName) |
582 | { |
583 | if (mSchemes.contains(newName)) |
584 | return false; |
585 | if (!isValidName(newName)) |
586 | return false; |
587 | PColorScheme scheme = get(oldName); |
588 | if (!scheme) |
589 | return false; |
590 | if (scheme->bundled()) |
591 | return false; |
592 | if (scheme->customed()) { |
593 | QString oldfullPath = generateFullPathname(oldName,false,true); |
594 | QString fullpath = generateFullPathname(newName,false,true); |
595 | QFile oldFile(oldfullPath); |
596 | if (oldFile.exists() && !oldFile.rename(fullpath)) |
597 | throw FileError(QObject::tr("Rename file '%1' to '%2' failed!" ).arg(oldfullPath).arg(fullpath)); |
598 | } |
599 | QString oldfullPath = generateFullPathname(oldName,false,false); |
600 | QString fullpath = generateFullPathname(newName,false,false); |
601 | QFile oldFile(oldfullPath); |
602 | if (oldFile.exists() && !oldFile.rename(fullpath)) |
603 | throw FileError(QObject::tr("Rename file '%1' to '%2' failed!" ).arg(oldfullPath).arg(fullpath)); |
604 | mSchemes.remove(oldName); |
605 | mSchemes[newName] = scheme; |
606 | return true; |
607 | } |
608 | |
609 | bool ColorManager::add(const QString &name, PColorScheme scheme) |
610 | { |
611 | if (mSchemes.contains(name)) |
612 | throw FileError(QObject::tr("Scheme '%1' already exists!" ).arg(name)); |
613 | scheme->setBundled(false); |
614 | scheme->setCustomed(false); |
615 | mSchemes[name] = scheme; |
616 | saveScheme(name); |
617 | return true; |
618 | } |
619 | |
620 | PColorScheme ColorManager::get(const QString &name) |
621 | { |
622 | if (mSchemes.contains(name)) |
623 | return mSchemes[name]; |
624 | return PColorScheme(); |
625 | } |
626 | |
627 | PColorSchemeItem ColorManager::getItem(const QString &schemeName, const QString &itemName) |
628 | { |
629 | PColorScheme scheme = get(schemeName); |
630 | if (!scheme) |
631 | return PColorSchemeItem(); |
632 | if (!scheme->items().contains(itemName)) |
633 | return PColorSchemeItem(); |
634 | return scheme->items()[itemName]; |
635 | } |
636 | |
637 | bool ColorManager::isValidName(const QString &name) |
638 | { |
639 | for (QChar ch:name) { |
640 | if (!((ch == ' ') || (ch>='a' && ch<='z') || (ch>='A' && ch <= 'Z') |
641 | || (ch>='0' && ch<='9') || (ch == '-') )) |
642 | return false; |
643 | } |
644 | return true; |
645 | } |
646 | |
647 | void ColorManager::addDefine(const QString &name, const QString &displayName, const QString &group, bool hasForeground, bool hasBackground, bool hasFontStyle) |
648 | { |
649 | PColorSchemeItemDefine define = std::make_shared<ColorSchemeItemDefine>(); |
650 | define->setDisplayName(displayName); |
651 | define->setGroup(group); |
652 | define->setHasForeground(hasForeground); |
653 | define->setHasBackground(hasBackground); |
654 | define->setHasFontStyle(hasFontStyle); |
655 | mSchemeItemDefines[name]=define; |
656 | } |
657 | |
658 | bool ColorManager::removeDefine(const QString &name) |
659 | { |
660 | return mSchemeItemDefines.remove(name)==1; |
661 | } |
662 | |
663 | PColorSchemeItemDefine ColorManager::getDefine(const QString &name) |
664 | { |
665 | if (mSchemeItemDefines.contains(name)) |
666 | return mSchemeItemDefines[name]; |
667 | return PColorSchemeItemDefine(); |
668 | } |
669 | |
670 | bool ColorManager::saveScheme(const QString &name) |
671 | { |
672 | PColorScheme scheme = get(name); |
673 | if (!scheme) |
674 | return false; |
675 | QString newFilepath = generateFullPathname(name,scheme->bundled(),scheme->customed()); |
676 | scheme->save(newFilepath); |
677 | return true; |
678 | } |
679 | |
680 | void ColorManager::updateStatementColors(std::shared_ptr<QHash<StatementKind, std::shared_ptr<ColorSchemeItem> > > statementColors, const QString &schemeName) |
681 | { |
682 | PColorSchemeItem item; |
683 | item = getItem(schemeName, SYNS_AttrFunction); |
684 | if (item) { |
685 | statementColors->insert(StatementKind::skFunction,item); |
686 | statementColors->insert(StatementKind::skConstructor,item); |
687 | statementColors->insert(StatementKind::skDestructor,item); |
688 | } |
689 | item = getItem(schemeName, SYNS_AttrClass); |
690 | if (item) { |
691 | statementColors->insert(StatementKind::skClass,item); |
692 | statementColors->insert(StatementKind::skTypedef,item); |
693 | statementColors->insert(StatementKind::skAlias,item); |
694 | } |
695 | item = getItem(schemeName, SYNS_AttrIdentifier); |
696 | if (item) { |
697 | statementColors->insert(StatementKind::skEnumType,item); |
698 | statementColors->insert(StatementKind::skEnumClassType,item); |
699 | } |
700 | item = getItem(schemeName, SYNS_AttrVariable); |
701 | if (item) { |
702 | statementColors->insert(StatementKind::skVariable,item); |
703 | } |
704 | item = getItem(schemeName, SYNS_AttrLocalVariable); |
705 | if (item) { |
706 | statementColors->insert(StatementKind::skLocalVariable,item); |
707 | statementColors->insert(StatementKind::skParameter,item); |
708 | } |
709 | item = getItem(schemeName, SYNS_AttrGlobalVariable); |
710 | if (item) { |
711 | statementColors->insert(StatementKind::skGlobalVariable,item); |
712 | } |
713 | item = getItem(schemeName, SYNS_AttrPreprocessor); |
714 | if (item) { |
715 | statementColors->insert(StatementKind::skPreprocessor,item); |
716 | statementColors->insert(StatementKind::skEnum,item); |
717 | } |
718 | item = getItem(schemeName, SYNS_AttrReservedWord); |
719 | if (item) { |
720 | statementColors->insert(StatementKind::skKeyword,item); |
721 | statementColors->insert(StatementKind::skUserCodeSnippet,item); |
722 | } |
723 | item = getItem(schemeName, SYNS_AttrString); |
724 | if (item) { |
725 | statementColors->insert(StatementKind::skNamespace,item); |
726 | statementColors->insert(StatementKind::skNamespaceAlias,item); |
727 | } |
728 | } |
729 | |
730 | QString ColorManager::generateFullPathname(const QString &name, bool isBundled, bool isCustomed) |
731 | { |
732 | QString filename = generateFilename(name,isCustomed); |
733 | if (isBundled && !isCustomed) { |
734 | return includeTrailingPathDelimiter(pSettings->dirs().data(Settings::Dirs::DataType::ColorScheme))+filename; |
735 | } else { |
736 | return includeTrailingPathDelimiter(pSettings->dirs().config(Settings::Dirs::DataType::ColorScheme))+filename; |
737 | } |
738 | } |
739 | |
740 | ColorSchemeItemDefine::ColorSchemeItemDefine() |
741 | { |
742 | mHasBackground = true; |
743 | mHasForeground = true; |
744 | mHasFontStyle = true; |
745 | mGroup = QObject::tr("default" ); |
746 | } |
747 | |
748 | bool ColorSchemeItemDefine::hasBackground() const |
749 | { |
750 | return mHasBackground; |
751 | } |
752 | |
753 | void ColorSchemeItemDefine::setHasBackground(bool hasBackground) |
754 | { |
755 | mHasBackground = hasBackground; |
756 | } |
757 | |
758 | bool ColorSchemeItemDefine::hasForeground() const |
759 | { |
760 | return mHasForeground; |
761 | } |
762 | |
763 | void ColorSchemeItemDefine::setHasForeground(bool hasForeground) |
764 | { |
765 | mHasForeground = hasForeground; |
766 | } |
767 | |
768 | bool ColorSchemeItemDefine::hasFontStyle() const |
769 | { |
770 | return mHasFontStyle; |
771 | } |
772 | |
773 | void ColorSchemeItemDefine::setHasFontStyle(bool value) |
774 | { |
775 | mHasFontStyle = value; |
776 | } |
777 | |
778 | QString ColorSchemeItemDefine::group() const |
779 | { |
780 | return mGroup; |
781 | } |
782 | |
783 | void ColorSchemeItemDefine::setGroup(const QString &group) |
784 | { |
785 | mGroup = group; |
786 | } |
787 | |
788 | QString ColorSchemeItemDefine::displayName() const |
789 | { |
790 | return mDisplayName; |
791 | } |
792 | |
793 | void ColorSchemeItemDefine::setDisplayName(const QString &displayName) |
794 | { |
795 | mDisplayName = displayName; |
796 | } |
797 | |