UniversalIndentGUI 1.2.0
|
00001 /*************************************************************************** 00002 * Copyright (C) 2006-2012 by Thomas Schweitzer * 00003 * thomas-schweitzer(at)arcor.de * 00004 * * 00005 * This program is free software; you can redistribute it and/or modify * 00006 * it under the terms of the GNU General Public License version 2.0 as * 00007 * published by the Free Software Foundation. * 00008 * * 00009 * This program is distributed in the hope that it will be useful, * 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00012 * GNU General Public License for more details. * 00013 * * 00014 * You should have received a copy of the GNU General Public License * 00015 * along with this program in the file LICENSE.GPL; if not, write to the * 00016 * Free Software Foundation, Inc., * 00017 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00018 ***************************************************************************/ 00019 00020 #include "UiGuiHighlighter.h" 00021 00022 #include "SettingsPaths.h" 00023 00024 #include <QSettings> 00025 #include <QMenu> 00026 #include <QScrollBar> 00027 #include <QCoreApplication> 00028 00029 #include <Qsci/qsciscintilla.h> 00030 #include <Qsci/qscilexer.h> 00031 #include <Qsci/qscilexerbash.h> 00032 #include <Qsci/qscilexerbatch.h> 00033 #include <Qsci/qscilexercmake.h> 00034 #include <Qsci/qscilexercpp.h> 00035 #include <Qsci/qscilexercsharp.h> 00036 #include <Qsci/qscilexercss.h> 00037 #include <Qsci/qscilexerd.h> 00038 #include <Qsci/qscilexerdiff.h> 00039 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00040 #include <Qsci/qscilexerfortran.h> 00041 #include <Qsci/qscilexerfortran77.h> 00042 #endif 00043 #include <Qsci/qscilexerhtml.h> 00044 #include <Qsci/qscilexeridl.h> 00045 #include <Qsci/qscilexerjava.h> 00046 #include <Qsci/qscilexerjavascript.h> 00047 #include <Qsci/qscilexerlua.h> 00048 #include <Qsci/qscilexermakefile.h> 00049 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00050 #include <Qsci/qscilexerpascal.h> 00051 #endif 00052 #include <Qsci/qscilexerperl.h> 00053 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00054 #include <Qsci/qscilexerpostscript.h> 00055 #endif 00056 #include <Qsci/qscilexerpov.h> 00057 #include <Qsci/qscilexerproperties.h> 00058 #include <Qsci/qscilexerpython.h> 00059 #include <Qsci/qscilexerruby.h> 00060 #if ( QSCINTILLA_VERSION >= 0x020400 ) 00061 #include <Qsci/qscilexerspice.h> 00062 #endif 00063 #include <Qsci/qscilexersql.h> 00064 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00065 #include <Qsci/qscilexertcl.h> 00066 #endif 00067 #include <Qsci/qscilexertex.h> 00068 #if ( QSCINTILLA_VERSION >= 0x020400 ) 00069 #include <Qsci/qscilexerverilog.h> 00070 #endif 00071 #include <Qsci/qscilexervhdl.h> 00072 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00073 #include <Qsci/qscilexerxml.h> 00074 #include <Qsci/qscilexeryaml.h> 00075 #endif 00076 00078 00088 UiGuiHighlighter::UiGuiHighlighter(QsciScintilla *parent) : QObject(parent) { 00089 _qsciEditorParent = parent; 00090 00091 // Create the highlighter _settings object from the UiGuiSyntaxHighlightConfig.ini file. 00092 _settings = new QSettings(SettingsPaths::getSettingsPath() + "/UiGuiSyntaxHighlightConfig.ini", QSettings::IniFormat, this); 00093 00094 _highlightningIsOn = true; 00095 00096 _mapHighlighternameToExtension["Bash"] = QStringList() << "sh"; 00097 _mapHighlighternameToExtension["Batch"] = QStringList() << "bat"; 00098 _mapHighlighternameToExtension["CMake"] = QStringList() << "cmake"; 00099 _mapHighlighternameToExtension["C++"] = QStringList() << "c" << "h" << "cpp" << "hpp" << "cxx" << "hxx"; 00100 _mapHighlighternameToExtension["C#"] = QStringList() << "cs"; 00101 _mapHighlighternameToExtension["CSS"] = QStringList() << "css"; 00102 _mapHighlighternameToExtension["D"] = QStringList() << "d"; 00103 _mapHighlighternameToExtension["Diff"] = QStringList() << "diff"; 00104 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00105 _mapHighlighternameToExtension["Fortran"] = QStringList() << "f" << "for" << "f90"; 00106 _mapHighlighternameToExtension["Fortran77"] = QStringList() << "f77"; 00107 #endif 00108 _mapHighlighternameToExtension["HTML"] = QStringList() << "html" << "htm"; 00109 _mapHighlighternameToExtension["IDL"] = QStringList() << "idl"; 00110 _mapHighlighternameToExtension["Java"] = QStringList() << "java"; 00111 _mapHighlighternameToExtension["JavaScript"] = QStringList() << "js"; 00112 _mapHighlighternameToExtension["LUA"] = QStringList() << "lua"; 00113 _mapHighlighternameToExtension["Makefile"] = QStringList() << "makefile"; 00114 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00115 _mapHighlighternameToExtension["Pascal"] = QStringList() << "pas"; 00116 #endif 00117 _mapHighlighternameToExtension["Perl"] = QStringList() << "perl" << "pl" << "pm"; 00118 _mapHighlighternameToExtension["PHP"] = QStringList() << "php"; 00119 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00120 _mapHighlighternameToExtension["PostScript"] = QStringList() << "ps" << "eps" << "pdf" << "ai" << "fh"; 00121 #endif 00122 _mapHighlighternameToExtension["POV"] = QStringList() << "pov"; 00123 _mapHighlighternameToExtension["Ini"] = QStringList() << "ini"; 00124 _mapHighlighternameToExtension["Python"] = QStringList() << "py"; 00125 _mapHighlighternameToExtension["Ruby"] = QStringList() << "rub" << "rb"; 00126 #if ( QSCINTILLA_VERSION >= 0x020400 ) 00127 _mapHighlighternameToExtension["Spice"] = QStringList() << "cir"; 00128 #endif 00129 _mapHighlighternameToExtension["SQL"] = QStringList() << "sql"; 00130 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00131 _mapHighlighternameToExtension["TCL"] = QStringList() << "tcl"; 00132 #endif 00133 _mapHighlighternameToExtension["TeX"] = QStringList() << "tex"; 00134 #if ( QSCINTILLA_VERSION >= 0x020400 ) 00135 _mapHighlighternameToExtension["Verilog"] = QStringList() << "v" << "vh"; 00136 #endif 00137 _mapHighlighternameToExtension["VHDL"] = QStringList() << "vhdl"; 00138 _mapHighlighternameToExtension["XML"] = QStringList() << "xml"; 00139 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00140 _mapHighlighternameToExtension["YAML"] = QStringList() << "yaml"; 00141 #endif 00142 00143 _lexer = NULL; 00144 00145 // This code is only for testing. 00146 /* 00147 foreach(QStringList extensionList, _mapHighlighternameToExtension.values() ) { 00148 setLexerForExtension( extensionList.at(0) ); 00149 } 00150 */ 00151 00152 // Set default highlighter to C++ highlighter. 00153 setLexerForExtension( "cpp" ); 00154 } 00155 00156 00160 QStringList UiGuiHighlighter::getAvailableHighlighters() { 00161 return _mapHighlighternameToExtension.keys(); 00162 } 00163 00164 00168 void UiGuiHighlighter::setHighlighterByAction(QAction* highlighterAction) { 00169 QString highlighterName = highlighterAction->text(); 00170 setLexerForExtension( _mapHighlighternameToExtension[highlighterName].first() ); 00171 //TODO: This is really no nice way. How do it better? 00172 // Need to do this "text update" to update the syntax highlighting. Otherwise highlighting is wrong. 00173 int scrollPos = _qsciEditorParent->verticalScrollBar()->value(); 00174 _qsciEditorParent->setText( _qsciEditorParent->text() ); 00175 _qsciEditorParent->verticalScrollBar()->setValue(scrollPos); 00176 } 00177 00178 00182 void UiGuiHighlighter::turnHighlightOn() { 00183 _highlightningIsOn = true; 00184 _qsciEditorParent->setLexer(_lexer); 00185 readCurrentSettings(""); 00186 } 00187 00191 void UiGuiHighlighter::turnHighlightOff() { 00192 _highlightningIsOn = false; 00193 _qsciEditorParent->setLexer(); 00194 #if defined(Q_OS_WIN) || defined(Q_OS_MAC) 00195 _qsciEditorParent->setFont( QFont("Courier", 10, QFont::Normal) ); 00196 _qsciEditorParent->setMarginsFont( QFont("Courier", 10, QFont::Normal) ); 00197 #else 00198 _qsciEditorParent->setFont( QFont("Monospace", 10, QFont::Normal) ); 00199 _qsciEditorParent->setMarginsFont( QFont("Monospace", 10, QFont::Normal) ); 00200 #endif 00201 } 00202 00203 00207 //TODO: Refactor this function so that the coding style and variable names suit better. 00208 bool UiGuiHighlighter::readCurrentSettings( const char *prefix ) { 00209 bool ok, flag, rc = true; 00210 int num; 00211 QString key; 00212 00213 // Reset lists containing fonts and colors for each style 00214 _fontForStyles.clear(); 00215 _colorForStyles.clear(); 00216 00217 // Read the styles. 00218 for (int i = 0; i < 128; ++i) { 00219 // Ignore invalid styles. 00220 if ( _lexer->description(i).isEmpty() ) 00221 continue; 00222 00223 key.sprintf( "%s/%s/style%d/", prefix, _lexer->language(), i ); 00224 key.replace("+", "p"); 00225 00226 // Read the foreground color. 00227 ok = _settings->contains(key + "color"); 00228 num = _settings->value(key + "color", 0).toInt(); 00229 00230 if (ok) 00231 setColor( QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i ); 00232 else 00233 rc = false; 00234 00235 // Read the end-of-line fill. 00236 ok = _settings->contains(key + "eolfill"); 00237 flag = _settings->value(key + "eolfill", false).toBool(); 00238 00239 if (ok) 00240 _lexer->setEolFill( flag, i ); 00241 else 00242 rc = false; 00243 00244 // Read the font 00245 QStringList fdesc; 00246 00247 ok = _settings->contains(key + "font"); 00248 fdesc = _settings->value(key + "font").toStringList(); 00249 00250 if (ok && fdesc.count() == 5) { 00251 QFont f; 00252 00253 #if defined(Q_OS_WIN) || defined(Q_OS_MAC) 00254 f.setFamily(fdesc[0]); 00255 #else 00256 if ( fdesc[0].contains("courier", Qt::CaseInsensitive) ) 00257 f.setFamily("Monospace"); 00258 else 00259 f.setFamily(fdesc[0]); 00260 #endif 00261 f.setPointSize(fdesc[1].toInt()); 00262 f.setBold(fdesc[2].toInt()); 00263 f.setItalic(fdesc[3].toInt()); 00264 f.setUnderline(fdesc[4].toInt()); 00265 00266 setFont(f, i); 00267 } 00268 else 00269 rc = false; 00270 00271 // Read the background color. 00272 ok = _settings->contains(key + "paper"); 00273 num = _settings->value(key + "paper", 0).toInt(); 00274 00275 if (ok) 00276 _lexer->setPaper( QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i ); 00277 else 00278 rc = false; 00279 } 00280 00281 // Read the properties. 00282 key.sprintf( "%s/%s/properties/", prefix, _lexer->language() ); 00283 00284 _lexer->refreshProperties(); 00285 00286 return rc; 00287 } 00288 00289 00293 void UiGuiHighlighter::writeCurrentSettings( const char *prefix ) { 00294 QString key; 00295 00296 // Write the styles. 00297 for (int i = 0; i < 128; ++i) { 00298 // Ignore invalid styles. 00299 if ( _lexer->description(i).isEmpty() ) 00300 continue; 00301 00302 int num; 00303 QColor c; 00304 00305 key.sprintf( "%s/%s/style%d/", prefix, _lexer->language(), i ); 00306 key.replace("+", "p"); 00307 00308 // Write style name 00309 _settings->setValue( key + "", _lexer->description(i) ); 00310 00311 // Write the foreground color. 00312 if ( _colorForStyles.contains(i) ) { 00313 c = _colorForStyles[i]; 00314 } 00315 else { 00316 c = _lexer->color(i); 00317 } 00318 num = (c.red() << 16) | (c.green() << 8) | c.blue(); 00319 00320 _settings->setValue(key + "color", num); 00321 00322 // Write the end-of-line fill. 00323 _settings->setValue( key + "eolfill", _lexer->eolFill(i) ); 00324 00325 // Write the font 00326 QStringList fdesc; 00327 QString fmt("%1"); 00328 QFont f; 00329 00330 if ( _fontForStyles.contains(i) ) { 00331 f = _fontForStyles[i]; 00332 } 00333 else { 00334 f = _lexer->font(i); 00335 } 00336 00337 fdesc += f.family(); 00338 fdesc += fmt.arg( f.pointSize() ); 00339 00340 // The casts are for Borland. 00341 fdesc += fmt.arg( (int)f.bold() ); 00342 fdesc += fmt.arg( (int)f.italic() ); 00343 fdesc += fmt.arg( (int)f.underline() ); 00344 00345 _settings->setValue(key + "font", fdesc); 00346 00347 // Write the background color. 00348 c = _lexer->paper(i); 00349 num = (c.red() << 16) | (c.green() << 8) | c.blue(); 00350 00351 _settings->setValue(key + "paper", num); 00352 } 00353 } 00354 00355 00359 void UiGuiHighlighter::setColor(const QColor &color, int style) { 00360 _colorForStyles[style] = color; 00361 _lexer->setColor( color, style ); 00362 } 00363 00364 00368 void UiGuiHighlighter::setFont(const QFont &font, int style) { 00369 _fontForStyles[style] = font; 00370 _lexer->setFont( font, style ); 00371 } 00372 00373 00377 void UiGuiHighlighter::setLexerByName( QString lexerName ) { 00378 setLexerForExtension( _mapHighlighternameToExtension[lexerName].first() ); 00379 } 00380 00381 00385 int UiGuiHighlighter::setLexerForExtension( QString extension ) { 00386 int indexOfHighlighter = 0; 00387 extension = extension.toLower(); 00388 00389 if ( _lexer != NULL ) { 00390 writeCurrentSettings(""); 00391 delete _lexer; 00392 } 00393 00394 if ( extension == "cpp" || extension == "hpp" || extension == "c" || extension == "h" || extension == "cxx" || extension == "hxx" ) { 00395 _lexer = new QsciLexerCPP(); 00396 } 00397 else if ( extension == "sh" ) { 00398 _lexer = new QsciLexerBash(); 00399 } 00400 else if ( extension == "bat" ) { 00401 _lexer = new QsciLexerBatch(); 00402 } 00403 else if ( extension == "cmake" ) { 00404 _lexer = new QsciLexerCMake(); 00405 } 00406 else if ( extension == "cs" ) { 00407 _lexer = new QsciLexerCSharp(); 00408 } 00409 else if ( extension == "css" ) { 00410 _lexer = new QsciLexerCSS(); 00411 } 00412 else if ( extension == "d" ) { 00413 _lexer = new QsciLexerD(); 00414 } 00415 else if ( extension == "diff" ) { 00416 _lexer = new QsciLexerDiff(); 00417 } 00418 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00419 else if ( extension == "f" || extension == "for" || extension == "f90" ) { 00420 _lexer = new QsciLexerFortran(); 00421 } 00422 else if ( extension == "f77" ) { 00423 _lexer = new QsciLexerFortran77(); 00424 } 00425 #endif 00426 else if ( extension == "html" || extension == "htm" ) { 00427 _lexer = new QsciLexerHTML(); 00428 } 00429 else if ( extension == "idl" ) { 00430 _lexer = new QsciLexerIDL(); 00431 } 00432 else if ( extension == "java" ) { 00433 _lexer = new QsciLexerJava(); 00434 } 00435 else if ( extension == "js" ) { 00436 _lexer = new QsciLexerJavaScript(); 00437 } 00438 else if ( extension == "lua" ) { 00439 _lexer = new QsciLexerLua(); 00440 } 00441 else if ( extension == "makefile" ) { 00442 _lexer = new QsciLexerMakefile(); 00443 } 00444 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00445 else if ( extension == "pas" ) { 00446 _lexer = new QsciLexerPascal(); 00447 } 00448 #endif 00449 else if ( extension == "perl" || extension == "pl" || extension == "pm" ) { 00450 _lexer = new QsciLexerPerl(); 00451 } 00452 else if ( extension == "php" ) { 00453 _lexer = new QsciLexerHTML(); 00454 } 00455 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00456 else if ( extension == "ps" || extension == "eps" || extension == "pdf" || extension == "ai" || extension == "fh") { 00457 _lexer = new QsciLexerPostScript(); 00458 } 00459 #endif 00460 else if ( extension == "pov" ) { 00461 _lexer = new QsciLexerPOV(); 00462 } 00463 else if ( extension == "ini" ) { 00464 _lexer = new QsciLexerProperties(); 00465 } 00466 else if ( extension == "py" ) { 00467 _lexer = new QsciLexerPython(); 00468 } 00469 else if ( extension == "rub" || extension == "rb" ) { 00470 _lexer = new QsciLexerRuby(); 00471 } 00472 #if ( QSCINTILLA_VERSION >= 0x020400 ) 00473 else if ( extension == "spice?" ) { 00474 _lexer = new QsciLexerSpice(); 00475 } 00476 #endif 00477 else if ( extension == "sql" ) { 00478 _lexer = new QsciLexerSQL(); 00479 } 00480 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00481 else if ( extension == "tcl" ) { 00482 _lexer = new QsciLexerTCL(); 00483 } 00484 #endif 00485 else if ( extension == "tex" ) { 00486 _lexer = new QsciLexerTeX(); 00487 } 00488 #if ( QSCINTILLA_VERSION >= 0x020400 ) 00489 else if ( extension == "vlog?" ) { 00490 _lexer = new QsciLexerVerilog(); 00491 } 00492 #endif 00493 else if ( extension == "vhdl" ) { 00494 _lexer = new QsciLexerVHDL(); 00495 } 00496 else if ( extension == "xml" ) { 00497 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00498 _lexer = new QsciLexerXML(); 00499 #else 00500 _lexer = new QsciLexerHTML(); 00501 #endif 00502 } 00503 #if ( QSCINTILLA_VERSION >= 0x020300 ) 00504 else if ( extension == "yaml" ) { 00505 _lexer = new QsciLexerYAML(); 00506 } 00507 #endif 00508 else { 00509 _lexer = new QsciLexerCPP(); 00510 extension = "cpp"; 00511 } 00512 00513 // Find the index of the selected _lexer. 00514 indexOfHighlighter = 0; 00515 while ( !_mapHighlighternameToExtension.values().at(indexOfHighlighter).contains(extension) ) { 00516 indexOfHighlighter++; 00517 } 00518 00519 // Set the _lexer for the QScintilla widget. 00520 if ( _highlightningIsOn ) { 00521 _qsciEditorParent->setLexer(_lexer); 00522 } 00523 00524 // Read the _settings for the _lexer properties from file. 00525 readCurrentSettings(""); 00526 00527 return indexOfHighlighter; 00528 }