// This module implements the QsciLexer class. // // Copyright (c) 2007 // Riverbank Computing Limited // // This file is part of QScintilla. // // This copy of QScintilla is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2, or (at your option) any // later version. // // QScintilla is supplied in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more // details. // // You should have received a copy of the GNU General Public License along with // QScintilla; see the file LICENSE. If not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "Qsci/qscilexer.h" #include #include #include #include #include "Qsci/qsciapis.h" #include "Qsci/qsciscintilla.h" #include "Qsci/qsciscintillabase.h" // The ctor. QsciLexer::QsciLexer(QObject *parent) : QObject(parent), autoIndStyle(-1), apiSet(0) { #if defined(Q_OS_WIN) defFont = QFont("Verdana",10); #else defFont = QFont("Bitstream Vera Sans",9); #endif // Set the default fore and background colours. QPalette pal = QApplication::palette(); defColor = pal.text().color(); defPaper = pal.base().color(); // Putting this on the heap means we can keep the style getters const. style_map = new StyleDataMap; style_map->style_data_set = false; } // The dtor. QsciLexer::~QsciLexer() { delete style_map; } // Make sure the style defaults have been set. void QsciLexer::setStyleDefaults() const { if (!style_map->style_data_set) { for (int i = 0; i < 128; ++i) if (!description(i).isEmpty()) styleData(i); style_map->style_data_set = true; } } // Return a reference to a style's data, setting up the defaults if needed. QsciLexer::StyleData &QsciLexer::styleData(int style) const { StyleData &sd = style_map->style_data[style]; // See if this is a new style by checking if the colour is valid. if (!sd.color.isValid()) { sd.color = defaultColor(style); sd.paper = defaultPaper(style); sd.font = defaultFont(style); sd.eol_fill = defaultEolFill(style); } return sd; } // Set the APIs associated with the lexer. void QsciLexer::setAPIs(QsciAPIs *apis) { apiSet = apis; } // Return a pointer to the current APIs if there are any. QsciAPIs *QsciLexer::apis() const { return apiSet; } // Default implementation to return the set of fill up characters that can end // auto-completion. const char *QsciLexer::autoCompletionFillups() const { return "("; } // Default implementation to return the list of character sequences that can // separate auto-completion words. QStringList QsciLexer::autoCompletionWordSeparators() const { return QStringList(); } // Default implementation to return the list of keywords that can start a // block. const char *QsciLexer::blockStartKeyword(int *) const { return 0; } // Default implementation to return the list of characters that can start a // block. const char *QsciLexer::blockStart(int *) const { return 0; } // Default implementation to return the list of characters that can end a // block. const char *QsciLexer::blockEnd(int *) const { return 0; } // Default implementation to return the style used for braces. int QsciLexer::braceStyle() const { return -1; } // Default implementation to return the number of lines to look back when // auto-indenting. int QsciLexer::blockLookback() const { return 20; } // Default implementation to return the case sensitivity of the language. bool QsciLexer::caseSensitive() const { return true; } // Default implementation to return the characters that make up a word. const char *QsciLexer::wordCharacters() const { return 0; } // Default implementation to return the style used for whitespace. int QsciLexer::defaultStyle() const { return 0; } // Returns the foreground colour of the text for a style. QColor QsciLexer::color(int style) const { return styleData(style).color; } // Returns the background colour of the text for a style. QColor QsciLexer::paper(int style) const { return styleData(style).paper; } // Returns the font for a style. QFont QsciLexer::font(int style) const { return styleData(style).font; } // Returns the end-of-line fill for a style. bool QsciLexer::eolFill(int style) const { return styleData(style).eol_fill; } // Returns the set of keywords. const char *QsciLexer::keywords(int) const { return 0; } // Returns the default EOL fill for a style. bool QsciLexer::defaultEolFill(int) const { return false; } // Returns the default font for a style. QFont QsciLexer::defaultFont(int) const { return defaultFont(); } // Returns the default font. QFont QsciLexer::defaultFont() const { return defFont; } // Sets the default font. void QsciLexer::setDefaultFont(const QFont &f) { defFont = f; } // Returns the default text colour for a style. QColor QsciLexer::defaultColor(int) const { return defaultColor(); } // Returns the default text colour. QColor QsciLexer::defaultColor() const { return defColor; } // Sets the default text colour. void QsciLexer::setDefaultColor(const QColor &c) { defColor = c; } // Returns the default paper colour for a styles. QColor QsciLexer::defaultPaper(int) const { return defaultPaper(); } // Returns the default paper colour. QColor QsciLexer::defaultPaper() const { return defPaper; } // Sets the default paper colour. void QsciLexer::setDefaultPaper(const QColor &c) { defPaper = c; } // Read properties from the settings. bool QsciLexer::readProperties(QSettings &,const QString &) { return true; } // Refresh all properties. void QsciLexer::refreshProperties() { } // Write properties to the settings. bool QsciLexer::writeProperties(QSettings &,const QString &) const { return true; } // Restore the user settings. bool QsciLexer::readSettings(QSettings &qs,const char *prefix) { bool ok, flag, rc = true; int num; QString key; setStyleDefaults(); // Read the styles. for (int i = 0; i < 128; ++i) { // Ignore invalid styles. if (description(i).isEmpty()) continue; key.sprintf("%s/%s/style%d/",prefix,language(),i); // Read the foreground colour. ok = qs.contains(key + "color"); num = qs.value(key + "color", 0).toInt(); if (ok) emit colorChanged(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i); else rc = false; // Read the end-of-line fill. ok = qs.contains(key + "eolfill"); flag = qs.value(key + "eolfill", false).toBool(); if (ok) emit eolFillChanged(flag, i); else rc = false; // Read the font QStringList fdesc; ok = qs.contains(key + "font"); fdesc = qs.value(key + "font").toStringList(); if (ok && fdesc.count() == 5) { QFont f; f.setFamily(fdesc[0]); f.setPointSize(fdesc[1].toInt()); f.setBold(fdesc[2].toInt()); f.setItalic(fdesc[3].toInt()); f.setUnderline(fdesc[4].toInt()); emit fontChanged(f, i); } else rc = false; // Read the background colour. ok = qs.contains(key + "paper"); num = qs.value(key + "paper", 0).toInt(); if (ok) emit paperChanged(QColor((num >> 16) & 0xff, (num >> 8) & 0xff, num & 0xff), i); else rc = false; } // Read the properties. key.sprintf("%s/%s/properties/",prefix,language()); if (!readProperties(qs,key)) rc = false; refreshProperties(); // Read the rest. key.sprintf("%s/%s/",prefix,language()); ok = qs.contains(key + "autoindentstyle"); num = qs.value(key + "autoindentstyle", 0).toInt(); if (ok) autoIndStyle = num; else rc = false; return rc; } // Save the user settings. bool QsciLexer::writeSettings(QSettings &qs,const char *prefix) const { bool rc = true; QString key; setStyleDefaults(); // Write the styles. for (int i = 0; i < 128; ++i) { // Ignore invalid styles. if (description(i).isEmpty()) continue; int num; QColor c; key.sprintf("%s/%s/style%d/",prefix,language(),i); // Write the foreground colour. c = color(i); num = (c.red() << 16) | (c.green() << 8) | c.blue(); qs.setValue(key + "color", num); // Write the end-of-line fill. qs.setValue(key + "eolfill", eolFill(i)); // Write the font QStringList fdesc; QString fmt("%1"); QFont f; f = font(i); fdesc += f.family(); fdesc += fmt.arg(f.pointSize()); // The casts are for Borland. fdesc += fmt.arg((int)f.bold()); fdesc += fmt.arg((int)f.italic()); fdesc += fmt.arg((int)f.underline()); qs.setValue(key + "font", fdesc); // Write the background colour. c = paper(i); num = (c.red() << 16) | (c.green() << 8) | c.blue(); qs.setValue(key + "paper", num); } // Write the properties. key.sprintf("%s/%s/properties/",prefix,language()); if (!writeProperties(qs,key)) rc = false; // Write the rest. key.sprintf("%s/%s/",prefix,language()); qs.setValue(key + "autoindentstyle", autoIndStyle); return rc; } // Return the auto-indentation style. int QsciLexer::autoIndentStyle() { // We can't do this in the ctor because we want the virtuals to work. if (autoIndStyle < 0) autoIndStyle = (blockStartKeyword() || blockStart() || blockEnd()) ? 0 : QsciScintilla::AiMaintain; return autoIndStyle; } // Set the auto-indentation style. void QsciLexer::setAutoIndentStyle(int autoindentstyle) { autoIndStyle = autoindentstyle; } // Set the foreground colour for a style. void QsciLexer::setColor(const QColor &c, int style) { if (style >= 0) { styleData(style).color = c; emit colorChanged(c, style); } else for (int i = 0; i < 128; ++i) if (!description(i).isEmpty()) setColor(c, i); } // Set the end-of-line fill for a style. void QsciLexer::setEolFill(bool eolfill, int style) { if (style >= 0) { styleData(style).eol_fill = eolfill; emit eolFillChanged(eolfill, style); } else for (int i = 0; i < 128; ++i) if (!description(i).isEmpty()) setEolFill(eolfill, i); } // Set the font for a style. void QsciLexer::setFont(const QFont &f, int style) { if (style >= 0) { styleData(style).font = f; emit fontChanged(f, style); } else for (int i = 0; i < 128; ++i) if (!description(i).isEmpty()) setFont(f, i); } // Set the background colour for a style. void QsciLexer::setPaper(const QColor &c, int style) { if (style >= 0) { styleData(style).paper = c; emit paperChanged(c, style); } else { for (int i = 0; i < 128; ++i) if (!description(i).isEmpty()) setPaper(c, i); emit paperChanged(c, QsciScintillaBase::STYLE_DEFAULT); } }