UniversalIndentGUI 1.2.0
UiGuiHighlighter.cpp
Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines