Merge pull request #1119 from openscad/scintilla-updates

Scintilla updates
master
Marius Kintel 2014-12-30 02:51:38 -05:00
commit bc30dca513
10 changed files with 1922 additions and 666 deletions

View File

@ -247,6 +247,7 @@ HEADERS += src/typedefs.h \
src/ProgressWidget.h \
src/parsersettings.h \
src/renderer.h \
src/settings.h \
src/rendersettings.h \
src/colormap.h \
src/ThrownTogetherRenderer.h \
@ -399,6 +400,7 @@ SOURCES += src/version_check.cc \
src/FreetypeRenderer.cc \
src/FontCache.cc \
\
src/settings.cc \
src/rendersettings.cc \
src/highlighter.cc \
src/Preferences.cc \

View File

@ -45,6 +45,55 @@ Preferences *Preferences::instance = NULL;
const char * Preferences::featurePropertyName = "FeatureProperty";
Q_DECLARE_METATYPE(Feature *);
class SettingsReader : public Settings::Visitor
{
QSettings settings;
const Value getValue(const Settings::SettingsEntry& entry, const std::string& value) const {
if (value.empty()) {
return entry.defaultValue();
}
try {
switch (entry.defaultValue().type()) {
case Value::STRING:
return Value(value);
case Value::NUMBER:
return Value(boost::lexical_cast<int>(value));
case Value::BOOL:
return Value(boost::lexical_cast<bool>(value));
default:
assert(false && "invalid value type for settings");
}
} catch (const boost::bad_lexical_cast& e) {
return entry.defaultValue();
}
}
virtual void handle(Settings::SettingsEntry& entry) const {
Settings::Settings *s = Settings::Settings::inst();
std::string key = entry.category() + "/" + entry.name();
std::string value = settings.value(QString::fromStdString(key)).toString().toStdString();
s->set(entry, getValue(entry, value));
}
};
class SettingsWriter : public Settings::Visitor
{
virtual void handle(Settings::SettingsEntry& entry) const {
Settings::Settings *s = Settings::Settings::inst();
QSettings settings;
QString key = QString::fromStdString(entry.category() + "/" + entry.name());
if (entry.is_default()) {
settings.remove(key);
} else {
Value value = s->get(entry);
settings.setValue(key, QString::fromStdString(value.toString()));
}
}
};
Preferences::Preferences(QWidget *parent) : QMainWindow(parent)
{
setupUi(this);
@ -140,6 +189,22 @@ void Preferences::init() {
#endif
this->polysetCacheSizeEdit->setValidator(validator);
this->opencsgLimitEdit->setValidator(validator);
initComboBox(this->comboBoxIndentUsing, Settings::Settings::indentStyle);
initComboBox(this->comboBoxLineWrap, Settings::Settings::lineWrap);
initComboBox(this->comboBoxLineWrapIndentationStyle, Settings::Settings::lineWrapIndentationStyle);
initComboBox(this->comboBoxLineWrapVisualizationEnd, Settings::Settings::lineWrapVisualizationEnd);
initComboBox(this->comboBoxLineWrapVisualizationStart, Settings::Settings::lineWrapVisualizationBegin);
initComboBox(this->comboBoxShowWhitespace, Settings::Settings::showWhitespace);
initComboBox(this->comboBoxTabKeyFunction, Settings::Settings::tabKeyFunction);
initSpinBox(this->spinBoxIndentationWidth, Settings::Settings::indentationWidth);
initSpinBox(this->spinBoxLineWrapIndentationIndent, Settings::Settings::lineWrapIndentation);
initSpinBox(this->spinBoxShowWhitespaceSize, Settings::Settings::showWhitespaceSize);
initSpinBox(this->spinBoxTabWidth, Settings::Settings::tabWidth);
SettingsReader settingsReader;
Settings::Settings::inst()->visit(settingsReader);
emit editorConfigChanged();
}
Preferences::~Preferences()
@ -400,13 +465,96 @@ void Preferences::on_mouseWheelZoomBox_toggled(bool state)
settings.setValue("editor/ctrlmousewheelzoom", state);
}
void
Preferences::on_launcherBox_toggled(bool state)
void Preferences::on_launcherBox_toggled(bool state)
{
QSettings settings;
settings.setValue("launcher/showOnStartup", state);
}
void Preferences::on_spinBoxIndentationWidth_valueChanged(int val)
{
Settings::Settings::inst()->set(Settings::Settings::indentationWidth, Value(val));
fireEditorConfigChanged();
}
void Preferences::on_spinBoxTabWidth_valueChanged(int val)
{
Settings::Settings::inst()->set(Settings::Settings::tabWidth, Value(val));
fireEditorConfigChanged();
}
void Preferences::on_comboBoxLineWrap_activated(int val)
{
applyComboBox(comboBoxLineWrap, val, Settings::Settings::lineWrap);
}
void Preferences::on_comboBoxLineWrapIndentationStyle_activated(int val)
{
applyComboBox(comboBoxLineWrapIndentationStyle, val, Settings::Settings::lineWrapIndentationStyle);
}
void Preferences::on_spinBoxLineWrapIndentationIndent_valueChanged(int val)
{
Settings::Settings::inst()->set(Settings::Settings::lineWrapIndentation, Value(val));
fireEditorConfigChanged();
}
void Preferences::on_comboBoxLineWrapVisualizationStart_activated(int val)
{
applyComboBox(comboBoxLineWrapVisualizationStart, val, Settings::Settings::lineWrapVisualizationBegin);
}
void Preferences::on_comboBoxLineWrapVisualizationEnd_activated(int val)
{
applyComboBox(comboBoxLineWrapVisualizationEnd, val, Settings::Settings::lineWrapVisualizationEnd);
}
void Preferences::on_comboBoxShowWhitespace_activated(int val)
{
applyComboBox(comboBoxShowWhitespace, val, Settings::Settings::showWhitespace);
}
void Preferences::on_spinBoxShowWhitespaceSize_valueChanged(int val)
{
Settings::Settings::inst()->set(Settings::Settings::showWhitespaceSize, Value(val));
fireEditorConfigChanged();
}
void Preferences::on_checkBoxAutoIndent_toggled(bool val)
{
Settings::Settings::inst()->set(Settings::Settings::autoIndent, Value(val));
fireEditorConfigChanged();
}
void Preferences::on_comboBoxIndentUsing_activated(int val)
{
applyComboBox(comboBoxIndentUsing, val, Settings::Settings::indentStyle);
}
void Preferences::on_comboBoxTabKeyFunction_activated(int val)
{
applyComboBox(comboBoxTabKeyFunction, val, Settings::Settings::tabKeyFunction);
}
void Preferences::on_checkBoxHighlightCurrentLine_toggled(bool val)
{
Settings::Settings::inst()->set(Settings::Settings::highlightCurrentLine, Value(val));
fireEditorConfigChanged();
}
void Preferences::on_checkBoxEnableBraceMatching_toggled(bool val)
{
Settings::Settings::inst()->set(Settings::Settings::enableBraceMatching, Value(val));
fireEditorConfigChanged();
}
void Preferences::fireEditorConfigChanged() const
{
SettingsWriter settingsWriter;
Settings::Settings::inst()->visit(settingsWriter);
emit editorConfigChanged();
}
void Preferences::keyPressEvent(QKeyEvent *e)
{
#ifdef Q_OS_MAC
@ -500,6 +648,68 @@ void Preferences::updateGUI()
this->undockCheckBox->setChecked(getValue("advanced/undockableWindows").toBool());
this->undockCheckBox->setEnabled(this->reorderCheckBox->isChecked());
this->launcherBox->setChecked(getValue("launcher/showOnStartup").toBool());
Settings::Settings *s = Settings::Settings::inst();
updateComboBox(this->comboBoxLineWrap, Settings::Settings::lineWrap);
updateComboBox(this->comboBoxLineWrapIndentationStyle, Settings::Settings::lineWrapIndentationStyle);
updateComboBox(this->comboBoxLineWrapVisualizationStart, Settings::Settings::lineWrapVisualizationBegin);
updateComboBox(this->comboBoxLineWrapVisualizationEnd, Settings::Settings::lineWrapVisualizationEnd);
updateComboBox(this->comboBoxShowWhitespace, Settings::Settings::showWhitespace);
updateComboBox(this->comboBoxIndentUsing, Settings::Settings::indentStyle);
updateComboBox(this->comboBoxTabKeyFunction, Settings::Settings::tabKeyFunction);
this->spinBoxIndentationWidth->setValue(s->get(Settings::Settings::indentationWidth).toDouble());
this->spinBoxTabWidth->setValue(s->get(Settings::Settings::tabWidth).toDouble());
this->spinBoxLineWrapIndentationIndent->setValue(s->get(Settings::Settings::lineWrapIndentation).toDouble());
this->spinBoxShowWhitespaceSize->setValue(s->get(Settings::Settings::showWhitespaceSize).toDouble());
this->checkBoxAutoIndent->setChecked(s->get(Settings::Settings::autoIndent).toBool());
this->checkBoxHighlightCurrentLine->setChecked(s->get(Settings::Settings::highlightCurrentLine).toBool());
this->checkBoxEnableBraceMatching->setChecked(s->get(Settings::Settings::enableBraceMatching).toBool());
}
void Preferences::initComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry)
{
comboBox->clear();
Value::VectorType vector = entry.range().toVector();
for (Value::VectorType::iterator it = vector.begin();it != vector.end();it++) {
QString val = QString::fromStdString((*it)[0].toString());
QString text = QString::fromStdString((*it)[1].toString());
comboBox->addItem(text, val);
}
}
void Preferences::initSpinBox(QSpinBox *spinBox, const Settings::SettingsEntry& entry)
{
Value::RangeType range = entry.range().toRange();
spinBox->setMinimum(range.begin_value());
spinBox->setMaximum(range.end_value());
}
void Preferences::updateComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry)
{
Settings::Settings *s = Settings::Settings::inst();
Value value = s->get(entry);
QString text = QString::fromStdString(value.toString());
int idx = comboBox->findData(text);
if (idx >= 0) {
comboBox->setCurrentIndex(idx);
} else {
Value defaultValue = entry.defaultValue();
QString defaultText = QString::fromStdString(defaultValue.toString());
int defIdx = comboBox->findData(defaultText);
if (defIdx >= 0) {
comboBox->setCurrentIndex(defIdx);
} else {
comboBox->setCurrentIndex(0);
}
}
}
void Preferences::applyComboBox(QComboBox *comboBox, int val, Settings::SettingsEntry& entry)
{
QString s = comboBox->itemData(val).toString();
Settings::Settings::inst()->set(entry, Value(s.toStdString()));
fireEditorConfigChanged();
}
void Preferences::apply() const

View File

@ -1,9 +1,11 @@
#pragma once
#include "qtgettext.h"
#include <QMainWindow>
#include <QSettings>
#include "qtgettext.h"
#include "ui_Preferences.h"
#include "settings.h"
class Preferences : public QMainWindow, public Ui::Preferences
{
@ -43,6 +45,30 @@ public slots:
void on_launcherBox_toggled(bool);
void on_editorType_editTextChanged(const QString &);
//
// editor settings
//
// Indentation
void on_checkBoxAutoIndent_toggled(bool);
void on_comboBoxIndentUsing_activated(int);
void on_spinBoxIndentationWidth_valueChanged(int);
void on_spinBoxTabWidth_valueChanged(int);
void on_comboBoxTabKeyFunction_activated(int);
void on_comboBoxShowWhitespace_activated(int);
void on_spinBoxShowWhitespaceSize_valueChanged(int);
// Line wrap
void on_comboBoxLineWrap_activated(int);
void on_comboBoxLineWrapIndentationStyle_activated(int);
void on_spinBoxLineWrapIndentationIndent_valueChanged(int);
void on_comboBoxLineWrapVisualizationStart_activated(int);
void on_comboBoxLineWrapVisualizationEnd_activated(int);
// Display
void on_checkBoxHighlightCurrentLine_toggled(bool);
void on_checkBoxEnableBraceMatching_toggled(bool);
signals:
void requestRedraw() const;
void updateMdiMode(bool mdi) const;
@ -53,6 +79,7 @@ signals:
void openCSGSettingsChanged() const;
void syntaxHighlightChanged(const QString &s) const;
void editorTypeChanged(const QString &type);
void editorConfigChanged() const;
private:
Preferences(QWidget *parent = NULL);
@ -60,8 +87,18 @@ private:
void updateGUI();
void removeDefaultSettings();
void setupFeaturesPage();
void fireEditorConfigChanged() const;
void addPrefPage(QActionGroup *group, QAction *action, QWidget *widget);
/** Initialize combobox list values from the settings range values */
void initComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry);
/** Initialize spinbox min/max values from the settings range values */
void initSpinBox(QSpinBox *spinBox, const Settings::SettingsEntry& entry);
/** Update combobox from current settings */
void updateComboBox(QComboBox *comboBox, const Settings::SettingsEntry& entry);
/** Set value from combobox to settings */
void applyComboBox(QComboBox *comboBox, int val, Settings::SettingsEntry& entry);
QSettings::SettingsMap defaultmap;
QHash<const QAction *, QWidget *> prefPages;

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,7 @@
#include "progress.h"
#include "dxfdim.h"
#include "legacyeditor.h"
#include "settings.h"
#ifdef USE_SCINTILLA_EDITOR
#include "scintillaeditor.h"
#endif
@ -192,6 +193,7 @@ MainWindow::MainWindow(const QString &filename)
#ifdef USE_SCINTILLA_EDITOR
if (useScintilla) {
editor = new ScintillaEditor(editorDockContents);
}
else
#endif
@ -199,6 +201,13 @@ MainWindow::MainWindow(const QString &filename)
Preferences::create(editor->colorSchemes());
#ifdef USE_SCINTILLA_EDITOR
if (useScintilla) {
connect(Preferences::inst(), SIGNAL(editorConfigChanged()), editor, SLOT(applySettings()));
Preferences::inst()->editorConfigChanged();
}
#endif
editorDockContents->layout()->addWidget(editor);
setCorner(Qt::TopLeftCorner, Qt::LeftDockWidgetArea);

View File

@ -6,489 +6,568 @@
#include <Qsci/qscicommandset.h>
#include "Preferences.h"
#include "PlatformUtils.h"
#include "settings.h"
class SettingsConverter {
public:
QsciScintilla::WrapMode toWrapMode(Value val);
QsciScintilla::WrapVisualFlag toLineWrapVisualization(Value val);
QsciScintilla::WrapIndentMode toLineWrapIndentationStyle(Value val);
QsciScintilla::WhitespaceVisibility toShowWhitespaces(Value val);
};
QsciScintilla::WrapMode SettingsConverter::toWrapMode(Value val)
{
std::string v = val.toString();
if (v == "Char") {
return QsciScintilla::WrapCharacter;
} else if (v == "Word") {
return QsciScintilla::WrapWord;
} else {
return QsciScintilla::WrapNone;
}
}
QsciScintilla::WrapVisualFlag SettingsConverter::toLineWrapVisualization(Value val)
{
std::string v = val.toString();
if (v == "Text") {
return QsciScintilla::WrapFlagByText;
} else if (v == "Border") {
return QsciScintilla::WrapFlagByBorder;
} else if (v == "Margin") {
return QsciScintilla::WrapFlagInMargin;
} else {
return QsciScintilla::WrapFlagNone;
}
}
QsciScintilla::WrapIndentMode SettingsConverter::toLineWrapIndentationStyle(Value val)
{
std::string v = val.toString();
if (v == "Same") {
return QsciScintilla::WrapIndentSame;
} else if (v == "Indented") {
return QsciScintilla::WrapIndentIndented;
} else {
return QsciScintilla::WrapIndentFixed;
}
}
QsciScintilla::WhitespaceVisibility SettingsConverter::toShowWhitespaces(Value val)
{
std::string v = val.toString();
if (v == "Always") {
return QsciScintilla::WsVisible;
} else if (v == "AfterIndentation") {
return QsciScintilla::WsVisibleAfterIndent;
} else {
return QsciScintilla::WsInvisible;
}
}
EditorColorScheme::EditorColorScheme(fs::path path) : path(path)
{
try {
boost::property_tree::read_json(boosty::stringy(path).c_str(), pt);
_name = QString(pt.get<std::string>("name").c_str());
_index = pt.get<int>("index");
} catch (const std::exception & e) {
PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what());
_name = "";
_index = 0;
}
try {
boost::property_tree::read_json(boosty::stringy(path).c_str(), pt);
_name = QString(pt.get<std::string>("name").c_str());
_index = pt.get<int>("index");
} catch (const std::exception & e) {
PRINTB("Error reading color scheme file '%s': %s", path.c_str() % e.what());
_name = "";
_index = 0;
}
}
EditorColorScheme::~EditorColorScheme()
{
}
bool EditorColorScheme::valid() const
{
return !_name.isEmpty();
return !_name.isEmpty();
}
const QString & EditorColorScheme::name() const
{
return _name;
return _name;
}
int EditorColorScheme::index() const
{
return _index;
return _index;
}
const boost::property_tree::ptree & EditorColorScheme::propertyTree() const
{
return pt;
return pt;
}
ScintillaEditor::ScintillaEditor(QWidget *parent) : EditorInterface(parent)
{
scintillaLayout = new QVBoxLayout(this);
qsci = new QsciScintilla(this);
scintillaLayout = new QVBoxLayout(this);
qsci = new QsciScintilla(this);
// Force EOL mode to Unix, since QTextStream will manage local EOL modes.
qsci->setEolMode(QsciScintilla::EolUnix);
// Force EOL mode to Unix, since QTextStream will manage local EOL modes.
qsci->setEolMode(QsciScintilla::EolUnix);
//
// Remapping some scintilla key binding which conflict with OpenSCAD global
// key bindings, as well as some minor scintilla bugs
//
QsciCommand *c;
//
// Remapping some scintilla key binding which conflict with OpenSCAD global
// key bindings, as well as some minor scintilla bugs
//
QsciCommand *c;
#ifdef Q_OS_MAC
// Alt-Backspace should delete left word (Alt-Delete already deletes right word)
c= qsci->standardCommands()->find(QsciCommand::DeleteWordLeft);
c->setKey(Qt::Key_Backspace | Qt::ALT);
// Alt-Backspace should delete left word (Alt-Delete already deletes right word)
c = qsci->standardCommands()->find(QsciCommand::DeleteWordLeft);
c->setKey(Qt::Key_Backspace | Qt::ALT);
#endif
// Cmd/Ctrl-T is handled by the menu
c = qsci->standardCommands()->boundTo(Qt::Key_T | Qt::CTRL);
c->setKey(0);
// Cmd/Ctrl-D is handled by the menu
c = qsci->standardCommands()->boundTo(Qt::Key_D | Qt::CTRL);
c->setKey(0);
// Ctrl-Shift-Z should redo on all platforms
c= qsci->standardCommands()->find(QsciCommand::Redo);
c->setKey(Qt::Key_Z | Qt::CTRL | Qt::SHIFT);
// Cmd/Ctrl-T is handled by the menu
c = qsci->standardCommands()->boundTo(Qt::Key_T | Qt::CTRL);
c->setKey(0);
// Cmd/Ctrl-D is handled by the menu
c = qsci->standardCommands()->boundTo(Qt::Key_D | Qt::CTRL);
c->setKey(0);
// Ctrl-Shift-Z should redo on all platforms
c = qsci->standardCommands()->find(QsciCommand::Redo);
c->setKey(Qt::Key_Z | Qt::CTRL | Qt::SHIFT);
scintillaLayout->setContentsMargins(0, 0, 0, 0);
scintillaLayout->addWidget(qsci);
scintillaLayout->setContentsMargins(0, 0, 0, 0);
scintillaLayout->addWidget(qsci);
qsci->setBraceMatching (QsciScintilla::SloppyBraceMatch);
qsci->setWrapMode(QsciScintilla::WrapCharacter);
qsci->setWrapVisualFlags(QsciScintilla::WrapFlagByBorder, QsciScintilla::WrapFlagNone, 0);
qsci->setAutoIndent(true);
qsci->indicatorDefine(QsciScintilla::RoundBoxIndicator, indicatorNumber);
qsci->markerDefine(QsciScintilla::Circle, markerNumber);
qsci->setUtf8(true);
qsci->setTabIndents(true);
qsci->setTabWidth(8);
qsci->setIndentationWidth(4);
qsci->setIndentationsUseTabs(false);
lexer = new ScadLexer(this);
qsci->setLexer(lexer);
initMargin();
qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4);
qsci->setCaretLineVisible(true);
qsci->indicatorDefine(QsciScintilla::RoundBoxIndicator, indicatorNumber);
qsci->markerDefine(QsciScintilla::Circle, markerNumber);
qsci->setUtf8(true);
qsci->setFolding(QsciScintilla::BoxedTreeFoldStyle, 4);
connect(qsci, SIGNAL(textChanged()), this, SIGNAL(contentsChanged()));
connect(qsci, SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool)));
lexer = new ScadLexer(this);
qsci->setLexer(lexer);
initMargin();
connect(qsci, SIGNAL(textChanged()), this, SIGNAL(contentsChanged()));
connect(qsci, SIGNAL(modificationChanged(bool)), this, SIGNAL(modificationChanged(bool)));
}
/**
* Apply the settings that are changeable in the preferences. This is also
* called in the event handler from the preferences.
*/
void ScintillaEditor::applySettings()
{
SettingsConverter conv;
Settings::Settings *s = Settings::Settings::inst();
qsci->setIndentationWidth(s->get(Settings::Settings::indentationWidth).toDouble());
qsci->setTabWidth(s->get(Settings::Settings::tabWidth).toDouble());
qsci->setWrapMode(conv.toWrapMode(s->get(Settings::Settings::lineWrap)));
qsci->setWrapIndentMode(conv.toLineWrapIndentationStyle(s->get(Settings::Settings::lineWrapIndentationStyle)));
qsci->setWrapVisualFlags(conv.toLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationEnd)),
conv.toLineWrapVisualization(s->get(Settings::Settings::lineWrapVisualizationBegin)),
s->get(Settings::Settings::lineWrapIndentation).toDouble());
qsci->setWhitespaceVisibility(conv.toShowWhitespaces(s->get(Settings::Settings::showWhitespace)));
qsci->setWhitespaceSize(s->get(Settings::Settings::showWhitespaceSize).toDouble());
qsci->setAutoIndent(s->get(Settings::Settings::autoIndent).toBool());
std::string indentStyle = s->get(Settings::Settings::indentStyle).toString();
qsci->setIndentationsUseTabs(indentStyle == "Tabs");
std::string tabKeyFunction = s->get(Settings::Settings::tabKeyFunction).toString();
qsci->setTabIndents(tabKeyFunction == "Indent");
qsci->setBraceMatching(s->get(Settings::Settings::enableBraceMatching).toBool() ? QsciScintilla::SloppyBraceMatch : QsciScintilla::NoBraceMatch);
qsci->setCaretLineVisible(s->get(Settings::Settings::highlightCurrentLine).toBool());
}
void ScintillaEditor::setPlainText(const QString &text)
{
qsci->setText(text);
setContentModified(false);
{
qsci->setText(text);
setContentModified(false);
}
QString ScintillaEditor::toPlainText()
{
return qsci->text();
return qsci->text();
}
void ScintillaEditor::setContentModified(bool modified)
{
// FIXME: Due to an issue with QScintilla, we need to do this on the document itself.
// FIXME: Due to an issue with QScintilla, we need to do this on the document itself.
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
qsci->SCN_SAVEPOINTLEFT();
qsci->SCN_SAVEPOINTLEFT();
#endif
qsci->setModified(modified);
qsci->setModified(modified);
}
bool ScintillaEditor::isContentModified()
{
return qsci->isModified();
return qsci->isModified();
}
void ScintillaEditor::highlightError(int error_pos)
void ScintillaEditor::highlightError(int error_pos)
{
int line, index;
qsci->lineIndexFromPosition(error_pos, &line, &index);
qsci->fillIndicatorRange(line, index, line, index+1, indicatorNumber);
qsci->markerAdd(line, markerNumber);
int line, index;
qsci->lineIndexFromPosition(error_pos, &line, &index);
qsci->fillIndicatorRange(line, index, line, index + 1, indicatorNumber);
qsci->markerAdd(line, markerNumber);
}
void ScintillaEditor::unhighlightLastError()
void ScintillaEditor::unhighlightLastError()
{
int totalLength = qsci->text().length();
int line, index;
qsci->lineIndexFromPosition(totalLength, &line, &index);
qsci->clearIndicatorRange(0, 0, line, index, indicatorNumber);
qsci->markerDeleteAll(markerNumber);
int totalLength = qsci->text().length();
int line, index;
qsci->lineIndexFromPosition(totalLength, &line, &index);
qsci->clearIndicatorRange(0, 0, line, index, indicatorNumber);
qsci->markerDeleteAll(markerNumber);
}
QColor ScintillaEditor::readColor(const boost::property_tree::ptree &pt, const std::string name, const QColor defaultColor)
{
try {
const std::string val = pt.get<std::string>(name);
return QColor(val.c_str());
} catch (std::exception e) {
return defaultColor;
}
try {
const std::string val = pt.get<std::string>(name);
return QColor(val.c_str());
} catch (std::exception e) {
return defaultColor;
}
}
std::string ScintillaEditor::readString(const boost::property_tree::ptree &pt, const std::string name, const std::string defaultValue)
{
try {
const std::string val = pt.get<std::string>(name);
return val;
} catch (std::exception e) {
return defaultValue;
}
try {
const std::string val = pt.get<std::string>(name);
return val;
} catch (std::exception e) {
return defaultValue;
}
}
int ScintillaEditor::readInt(const boost::property_tree::ptree &pt, const std::string name, const int defaultValue)
{
try {
const int val = pt.get<int>(name);
return val;
} catch (std::exception e) {
return defaultValue;
}
try {
const int val = pt.get<int>(name);
return val;
} catch (std::exception e) {
return defaultValue;
}
}
void ScintillaEditor::setColormap(const EditorColorScheme *colorScheme)
{
const boost::property_tree::ptree & pt = colorScheme->propertyTree();
const boost::property_tree::ptree & pt = colorScheme->propertyTree();
try {
QFont font = lexer->font(lexer->defaultStyle());
const QColor textColor(pt.get<std::string>("text").c_str());
const QColor paperColor(pt.get<std::string>("paper").c_str());
try {
QFont font = lexer->font(lexer->defaultStyle());
const QColor textColor(pt.get<std::string>("text").c_str());
const QColor paperColor(pt.get<std::string>("paper").c_str());
ScadLexer *l = new ScadLexer(this);
ScadLexer *l = new ScadLexer(this);
// Keywords must be set before the lexer is attached to QScintilla
// as they seem to be read and cached at attach time.
boost::optional<const boost::property_tree::ptree&> keywords = pt.get_child_optional("keywords");
if (keywords.is_initialized()) {
l->setKeywords(1, readString(keywords.get(), "keyword-set1", ""));
l->setKeywords(2, readString(keywords.get(), "keyword-set2", ""));
l->setKeywords(3, readString(keywords.get(), "keyword-set-doc", ""));
l->setKeywords(4, readString(keywords.get(), "keyword-set3", ""));
// Keywords must be set before the lexer is attached to QScintilla
// as they seem to be read and cached at attach time.
boost::optional<const boost::property_tree::ptree&> keywords = pt.get_child_optional("keywords");
if (keywords.is_initialized()) {
l->setKeywords(1, readString(keywords.get(), "keyword-set1", ""));
l->setKeywords(2, readString(keywords.get(), "keyword-set2", ""));
l->setKeywords(3, readString(keywords.get(), "keyword-set-doc", ""));
l->setKeywords(4, readString(keywords.get(), "keyword-set3", ""));
}
qsci->setLexer(l);
delete lexer;
lexer = l;
// All other properties must be set after attaching to QSCintilla so
// the editor gets the change events and updates itself to match
l->setFont(font);
l->setColor(textColor);
l->setPaper(paperColor);
const boost::property_tree::ptree& colors = pt.get_child("colors");
l->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword);
l->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2);
l->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass);
l->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number);
l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::SingleQuotedString);
l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString);
l->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator);
l->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::Comment);
l->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine);
l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentDoc);
l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentLineDoc);
l->setColor(readColor(colors, "commentdockeyword", textColor), QsciLexerCPP::CommentDocKeyword);
const boost::property_tree::ptree& caret = pt.get_child("caret");
qsci->setCaretWidth(readInt(caret, "width", 1));
qsci->setCaretForegroundColor(readColor(caret, "foreground", textColor));
qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor));
qsci->setMarkerBackgroundColor(readColor(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber);
qsci->setIndicatorForegroundColor(readColor(colors, "error-indicator", QColor(255, 0, 0, 100)), indicatorNumber);
qsci->setIndicatorOutlineColor(readColor(colors, "error-indicator-outline", QColor(255, 0, 0, 100)), indicatorNumber);
qsci->setWhitespaceBackgroundColor(readColor(colors, "whitespace-background", paperColor));
qsci->setWhitespaceForegroundColor(readColor(colors, "whitespace-foreground", textColor));
qsci->setMarginsBackgroundColor(readColor(colors, "margin-background", paperColor));
qsci->setMarginsForegroundColor(readColor(colors, "margin-foreground", textColor));
qsci->setMatchedBraceBackgroundColor(readColor(colors, "matched-brace-background", paperColor));
qsci->setMatchedBraceForegroundColor(readColor(colors, "matched-brace-foreground", textColor));
qsci->setUnmatchedBraceBackgroundColor(readColor(colors, "unmatched-brace-background", paperColor));
qsci->setUnmatchedBraceForegroundColor(readColor(colors, "unmatched-brace-foreground", textColor));
qsci->setSelectionForegroundColor(readColor(colors, "selection-foreground", paperColor));
qsci->setSelectionBackgroundColor(readColor(colors, "selection-background", textColor));
qsci->setFoldMarginColors(readColor(colors, "margin-foreground", textColor),
readColor(colors, "margin-background", paperColor));
qsci->setEdgeColor(readColor(colors, "edge", textColor));
} catch (std::exception e) {
noColor();
}
qsci->setLexer(l);
delete lexer;
lexer = l;
// All other properties must be set after attaching to QSCintilla so
// the editor gets the change events and updates itself to match
l->setFont(font);
l->setColor(textColor);
l->setPaper(paperColor);
const boost::property_tree::ptree& colors = pt.get_child("colors");
l->setColor(readColor(colors, "keyword1", textColor), QsciLexerCPP::Keyword);
l->setColor(readColor(colors, "keyword2", textColor), QsciLexerCPP::KeywordSet2);
l->setColor(readColor(colors, "keyword3", textColor), QsciLexerCPP::GlobalClass);
l->setColor(readColor(colors, "number", textColor), QsciLexerCPP::Number);
l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::SingleQuotedString);
l->setColor(readColor(colors, "string", textColor), QsciLexerCPP::DoubleQuotedString);
l->setColor(readColor(colors, "operator", textColor), QsciLexerCPP::Operator);
l->setColor(readColor(colors, "comment", textColor), QsciLexerCPP::Comment);
l->setColor(readColor(colors, "commentline", textColor), QsciLexerCPP::CommentLine);
l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentDoc);
l->setColor(readColor(colors, "commentdoc", textColor), QsciLexerCPP::CommentLineDoc);
l->setColor(readColor(colors, "commentdockeyword", textColor), QsciLexerCPP::CommentDocKeyword);
const boost::property_tree::ptree& caret = pt.get_child("caret");
qsci->setCaretWidth(readInt(caret, "width", 1));
qsci->setCaretForegroundColor(readColor(caret, "foreground", textColor));
qsci->setCaretLineBackgroundColor(readColor(caret, "line-background", paperColor));
qsci->setMarkerBackgroundColor(readColor(colors, "error-marker", QColor(255, 0, 0, 100)), markerNumber);
qsci->setIndicatorForegroundColor(readColor(colors, "error-indicator", QColor(255, 0, 0, 100)), indicatorNumber);
qsci->setIndicatorOutlineColor(readColor(colors, "error-indicator-outline", QColor(255, 0, 0, 100)), indicatorNumber);
qsci->setWhitespaceBackgroundColor(readColor(colors, "whitespace-background", paperColor));
qsci->setWhitespaceForegroundColor(readColor(colors, "whitespace-foreground", textColor));
qsci->setMarginsBackgroundColor(readColor(colors, "margin-background", paperColor));
qsci->setMarginsForegroundColor(readColor(colors, "margin-foreground", textColor));
qsci->setMatchedBraceBackgroundColor(readColor(colors, "matched-brace-background", paperColor));
qsci->setMatchedBraceForegroundColor(readColor(colors, "matched-brace-foreground", textColor));
qsci->setUnmatchedBraceBackgroundColor(readColor(colors, "unmatched-brace-background", paperColor));
qsci->setUnmatchedBraceForegroundColor(readColor(colors, "unmatched-brace-foreground", textColor));
qsci->setSelectionForegroundColor(readColor(colors, "selection-foreground", paperColor));
qsci->setSelectionBackgroundColor(readColor(colors, "selection-background", textColor));
qsci->setFoldMarginColors(readColor(colors, "margin-foreground", textColor),
readColor(colors, "margin-background", paperColor));
qsci->setEdgeColor(readColor(colors, "edge", textColor));
} catch (std::exception e) {
noColor();
}
}
void ScintillaEditor::noColor()
{
lexer->setPaper(Qt::white);
lexer->setColor(Qt::black);
qsci->setCaretWidth(2);
qsci->setCaretForegroundColor(Qt::black);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setIndicatorForegroundColor(QColor(255, 0, 0, 128), indicatorNumber);
qsci->setIndicatorOutlineColor(QColor(0, 0, 0, 255), indicatorNumber); // only alpha part is used
qsci->setCaretLineBackgroundColor(Qt::white);
qsci->setWhitespaceBackgroundColor(Qt::white);
qsci->setWhitespaceForegroundColor(Qt::black);
qsci->setMarginsBackgroundColor(Qt::white);
qsci->setMarginsForegroundColor(Qt::black);
qsci->setSelectionForegroundColor(Qt::white);
qsci->setSelectionBackgroundColor(Qt::black);
qsci->setMatchedBraceBackgroundColor(Qt::white);
qsci->setMatchedBraceForegroundColor(Qt::black);
qsci->setUnmatchedBraceBackgroundColor(Qt::white);
qsci->setUnmatchedBraceForegroundColor(Qt::black);
qsci->setMarginsBackgroundColor(Qt::lightGray);
qsci->setMarginsForegroundColor(Qt::black);
qsci->setFoldMarginColors(Qt::black, Qt::lightGray);
qsci->setEdgeColor(Qt::black);
lexer->setPaper(Qt::white);
lexer->setColor(Qt::black);
qsci->setCaretWidth(2);
qsci->setCaretForegroundColor(Qt::black);
qsci->setMarkerBackgroundColor(QColor(255, 0, 0, 100), markerNumber);
qsci->setIndicatorForegroundColor(QColor(255, 0, 0, 128), indicatorNumber);
qsci->setIndicatorOutlineColor(QColor(0, 0, 0, 255), indicatorNumber); // only alpha part is used
qsci->setCaretLineBackgroundColor(Qt::white);
qsci->setWhitespaceBackgroundColor(Qt::white);
qsci->setWhitespaceForegroundColor(Qt::black);
qsci->setMarginsBackgroundColor(Qt::white);
qsci->setMarginsForegroundColor(Qt::black);
qsci->setSelectionForegroundColor(Qt::white);
qsci->setSelectionBackgroundColor(Qt::black);
qsci->setMatchedBraceBackgroundColor(Qt::white);
qsci->setMatchedBraceForegroundColor(Qt::black);
qsci->setUnmatchedBraceBackgroundColor(Qt::white);
qsci->setUnmatchedBraceForegroundColor(Qt::black);
qsci->setMarginsBackgroundColor(Qt::lightGray);
qsci->setMarginsForegroundColor(Qt::black);
qsci->setFoldMarginColors(Qt::black, Qt::lightGray);
qsci->setEdgeColor(Qt::black);
}
void ScintillaEditor::enumerateColorSchemesInPath(ScintillaEditor::colorscheme_set_t &result_set, const fs::path path)
{
const fs::path color_schemes = path / "color-schemes" / "editor";
const fs::path color_schemes = path / "color-schemes" / "editor";
fs::directory_iterator end_iter;
if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) {
for (fs::directory_iterator dir_iter(color_schemes); dir_iter != end_iter; ++dir_iter) {
if (!fs::is_regular_file(dir_iter->status())) {
continue;
}
const fs::path path = (*dir_iter).path();
if (!(path.extension().string() == ".json")) {
continue;
}
EditorColorScheme *colorScheme = new EditorColorScheme(path);
if (colorScheme->valid()) {
result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr<EditorColorScheme>(colorScheme)));
} else {
delete colorScheme;
}
fs::directory_iterator end_iter;
if (fs::exists(color_schemes) && fs::is_directory(color_schemes)) {
for (fs::directory_iterator dir_iter(color_schemes); dir_iter != end_iter; ++dir_iter) {
if (!fs::is_regular_file(dir_iter->status())) {
continue;
}
const fs::path path = (*dir_iter).path();
if (!(path.extension().string() == ".json")) {
continue;
}
EditorColorScheme *colorScheme = new EditorColorScheme(path);
if (colorScheme->valid()) {
result_set.insert(colorscheme_set_t::value_type(colorScheme->index(), boost::shared_ptr<EditorColorScheme>(colorScheme)));
} else {
delete colorScheme;
}
}
}
}
}
ScintillaEditor::colorscheme_set_t ScintillaEditor::enumerateColorSchemes()
{
colorscheme_set_t result_set;
colorscheme_set_t result_set;
enumerateColorSchemesInPath(result_set, PlatformUtils::resourceBasePath());
enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath());
return result_set;
enumerateColorSchemesInPath(result_set, PlatformUtils::resourceBasePath());
enumerateColorSchemesInPath(result_set, PlatformUtils::userConfigPath());
return result_set;
}
QStringList ScintillaEditor::colorSchemes()
{
const colorscheme_set_t colorscheme_set = enumerateColorSchemes();
const colorscheme_set_t colorscheme_set = enumerateColorSchemes();
QStringList colorSchemes;
for (colorscheme_set_t::const_iterator it = colorscheme_set.begin();it != colorscheme_set.end();it++) {
colorSchemes << (*it).second.get()->name();
}
colorSchemes << "Off";
return colorSchemes;
QStringList colorSchemes;
for (colorscheme_set_t::const_iterator it = colorscheme_set.begin(); it != colorscheme_set.end(); it++) {
colorSchemes << (*it).second.get()->name();
}
colorSchemes << "Off";
return colorSchemes;
}
void ScintillaEditor::setHighlightScheme(const QString &name)
{
const colorscheme_set_t colorscheme_set = enumerateColorSchemes();
const colorscheme_set_t colorscheme_set = enumerateColorSchemes();
for (colorscheme_set_t::const_iterator it = colorscheme_set.begin();it != colorscheme_set.end();it++) {
const EditorColorScheme *colorScheme = (*it).second.get();
if (colorScheme->name() == name) {
setColormap(colorScheme);
return;
for (colorscheme_set_t::const_iterator it = colorscheme_set.begin(); it != colorscheme_set.end(); it++) {
const EditorColorScheme *colorScheme = (*it).second.get();
if (colorScheme->name() == name) {
setColormap(colorScheme);
return;
}
}
}
noColor();
noColor();
}
void ScintillaEditor::insert(const QString &text)
{
qsci->insert(text);
qsci->insert(text);
}
void ScintillaEditor::replaceAll(const QString &text)
{
qsci->selectAll(true);
qsci->replaceSelectedText(text);
qsci->selectAll(true);
qsci->replaceSelectedText(text);
}
void ScintillaEditor::undo()
{
qsci->undo();
qsci->undo();
}
void ScintillaEditor::redo()
{
qsci->redo();
qsci->redo();
}
void ScintillaEditor::cut()
{
qsci->cut();
qsci->cut();
}
void ScintillaEditor::copy()
{
qsci->copy();
qsci->copy();
}
void ScintillaEditor::paste()
{
qsci->paste();
{
qsci->paste();
}
void ScintillaEditor::zoomIn()
{
qsci->zoomIn();
qsci->zoomIn();
}
void ScintillaEditor::zoomOut()
void ScintillaEditor::zoomOut()
{
qsci->zoomOut();
qsci->zoomOut();
}
void ScintillaEditor::initFont(const QString& fontName, uint size)
{
QFont font(fontName, size);
font.setFixedPitch(true);
lexer->setFont(font);
QFont font(fontName, size);
font.setFixedPitch(true);
lexer->setFont(font);
}
void ScintillaEditor::initMargin()
{
QFontMetrics fontmetrics = QFontMetrics(qsci->font());
qsci->setMarginsFont(qsci->font());
qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
qsci->setMarginLineNumbers(1, true);
connect(qsci, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
QFontMetrics fontmetrics = QFontMetrics(qsci->font());
qsci->setMarginsFont(qsci->font());
qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
qsci->setMarginLineNumbers(1, true);
connect(qsci, SIGNAL(textChanged()), this, SLOT(onTextChanged()));
}
void ScintillaEditor::onTextChanged()
{
QFontMetrics fontmetrics = qsci->fontMetrics();
qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
QFontMetrics fontmetrics = qsci->fontMetrics();
qsci->setMarginWidth(1, fontmetrics.width(QString::number(qsci->lines())) + 6);
}
bool ScintillaEditor::find(const QString &expr, bool findNext, bool findBackwards)
{
int startline = -1, startindex = -1;
int startline = -1, startindex = -1;
// If findNext, start from the end of the current selection
if (qsci->hasSelectedText()) {
int lineFrom, indexFrom, lineTo, indexTo;
qsci->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
startline = !(findBackwards xor findNext) ? std::min(lineFrom, lineTo) : std::max(lineFrom, lineTo);
startindex = !(findBackwards xor findNext) ? std::min(indexFrom, indexTo) : std::max(indexFrom, indexTo);
}
// If findNext, start from the end of the current selection
if (qsci->hasSelectedText()) {
int lineFrom, indexFrom, lineTo, indexTo;
qsci->getSelection(&lineFrom, &indexFrom, &lineTo, &indexTo);
return qsci->findFirst(expr, false, false, false, true,
!findBackwards, startline, startindex);
startline = !(findBackwards xor findNext) ? std::min(lineFrom, lineTo) : std::max(lineFrom, lineTo);
startindex = !(findBackwards xor findNext) ? std::min(indexFrom, indexTo) : std::max(indexFrom, indexTo);
}
return qsci->findFirst(expr, false, false, false, true,
!findBackwards, startline, startindex);
}
void ScintillaEditor::replaceSelectedText(const QString &newText)
{
if (qsci->selectedText() != newText) qsci->replaceSelectedText(newText);
if (qsci->selectedText() != newText) qsci->replaceSelectedText(newText);
}
void ScintillaEditor::getRange(int *lineFrom, int *lineTo)
{
int indexFrom, indexTo;
if (qsci->hasSelectedText()) {
qsci->getSelection(lineFrom, &indexFrom, lineTo, &indexTo);
if (indexTo == 0) {
*lineTo = *lineTo - 1;
int indexFrom, indexTo;
if (qsci->hasSelectedText()) {
qsci->getSelection(lineFrom, &indexFrom, lineTo, &indexTo);
if (indexTo == 0) {
*lineTo = *lineTo - 1;
}
} else {
qsci->getCursorPosition(lineFrom, &indexFrom);
*lineTo = *lineFrom;
}
} else {
qsci->getCursorPosition(lineFrom, &indexFrom);
*lineTo = *lineFrom;
}
}
void ScintillaEditor::indentSelection()
{
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->indent(line);
}
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom; line <= lineTo; line++) {
qsci->indent(line);
}
}
void ScintillaEditor::unindentSelection()
{
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->unindent(line);
}
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom; line <= lineTo; line++) {
qsci->unindent(line);
}
}
void ScintillaEditor::commentSelection()
{
bool hasSelection = qsci->hasSelectedText();
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
qsci->insertAt("//", line, 0);
}
if (hasSelection) {
qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1));
}
bool hasSelection = qsci->hasSelectedText();
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom; line <= lineTo; line++) {
qsci->insertAt("//", line, 0);
}
if (hasSelection) {
qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1));
}
}
void ScintillaEditor::uncommentSelection()
{
bool hasSelection = qsci->hasSelectedText();
bool hasSelection = qsci->hasSelectedText();
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom;line <= lineTo;line++) {
QString lineText = qsci->text(line);
if (lineText.startsWith("//")) {
qsci->setSelection(line, 0, line, 2);
qsci->removeSelectedText();
int lineFrom, lineTo;
getRange(&lineFrom, &lineTo);
for (int line = lineFrom; line <= lineTo; line++) {
QString lineText = qsci->text(line);
if (lineText.startsWith("//")) {
qsci->setSelection(line, 0, line, 2);
qsci->removeSelectedText();
}
}
if (hasSelection) {
qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1));
}
}
if (hasSelection) {
qsci->setSelection(lineFrom, 0, lineTo, std::max(0, qsci->lineLength(lineTo) - 1));
}
}
QString ScintillaEditor::selectedText()
{
return qsci->selectedText();
return qsci->selectedText();
}

View File

@ -87,6 +87,7 @@ public slots:
private slots:
void onTextChanged();
void applySettings();
private:
QVBoxLayout *scintillaLayout;

139
src/settings.cc Normal file
View File

@ -0,0 +1,139 @@
#include "settings.h"
#include "printutils.h"
#include <boost/assign/std/vector.hpp>
using namespace boost::assign; // bring 'operator+=()' into scope
namespace Settings {
static std::list<SettingsEntry *> entries;
SettingsEntry::SettingsEntry(const std::string category, const std::string name, const Value range, const Value def)
: _category(category), _name(name), _value(def), _range(range), _default(def)
{
entries.push_back(this);
}
SettingsEntry::~SettingsEntry()
{
}
const std::string & SettingsEntry::category() const
{
return _category;
}
const std::string & SettingsEntry::name() const
{
return _name;
}
const Value & SettingsEntry::defaultValue() const
{
return _default;
}
const Value & SettingsEntry::range() const
{
return _range;
}
bool SettingsEntry::is_default() const
{
return _value == _default;
}
static Value value(std::string s1, std::string s2) {
Value::VectorType v;
v += Value(s1), Value(s2);
return v;
}
static Value values(std::string s1, std::string s1disp, std::string s2, std::string s2disp) {
Value::VectorType v;
v += value(s1, s1disp), value(s2, s2disp);
return v;
}
static Value values(std::string s1, std::string s1disp, std::string s2, std::string s2disp, std::string s3, std::string s3disp) {
Value::VectorType v;
v += value(s1, s1disp), value(s2, s2disp), value(s3, s3disp);
return v;
}
static Value values(std::string s1, std::string s1disp, std::string s2, std::string s2disp, std::string s3, std::string s3disp, std::string s4, std::string s4disp) {
Value::VectorType v;
v += value(s1, s1disp), value(s2, s2disp), value(s3, s3disp), value(s4, s4disp);
return v;
}
Settings *Settings::inst(bool erase)
{
static Settings *instance = new Settings;
if (erase) {
delete instance;
instance = NULL;
}
return instance;
}
Settings::Settings()
{
}
Settings::~Settings()
{
}
void Settings::visit(Visitor& visitor)
{
for (std::list<SettingsEntry *>::iterator it = entries.begin();it != entries.end();it++) {
visitor.handle(*(*it));
}
}
Value Settings::get(const SettingsEntry& entry)
{
return entry._value;
}
void Settings::set(SettingsEntry& entry, const Value val)
{
entry._value = val;
}
Visitor::Visitor()
{
}
Visitor::~Visitor()
{
}
/*
* Supported settings entry types are: bool / int and string selection
*
* String selection is used to handle comboboxes and has two values
* per config selection. The first value is used internally for both
* finding the combobox selection and for storing the value in the
* external settings file. The second value is the display value that
* can be translated.
*/
SettingsEntry Settings::indentationWidth("editor", "indentationWidth", Value(Value::RangeType(1, 16)), Value(4));
SettingsEntry Settings::tabWidth("editor", "tabWidth", Value(Value::RangeType(1, 16)), Value(8));
SettingsEntry Settings::lineWrap("editor", "lineWrap", values("None", _("None"), "Char", _("Wrap at character boundaries"), "Word", _("Wrap at word boundaries")), Value("Word"));
SettingsEntry Settings::lineWrapIndentationStyle("editor", "lineWrapIndentationStyle", values("Fixed", _("Fixed"), "Same", _("Same"), "Indented", _("Indented")), Value("Fixed"));
SettingsEntry Settings::lineWrapIndentation("editor", "lineWrapIndentation", Value(Value::RangeType(0, 999)), Value(4));
SettingsEntry Settings::lineWrapVisualizationBegin("editor", "lineWrapVisualizationBegin", values("None", _("None"), "Text", _("Text"), "Border", _("Border"), "Margin", _("Margin")), Value("None"));
SettingsEntry Settings::lineWrapVisualizationEnd("editor", "lineWrapVisualizationEnd", values("None", _("None"), "Text", _("Text"), "Border", _("Border"), "Margin", _("Margin")), Value("Border"));
SettingsEntry Settings::showWhitespace("editor", "showWhitespaces", values("Never", _("Never"), "Always", _("Always"), "AfterIndentation", _("After indentation")), Value("Never"));
SettingsEntry Settings::showWhitespaceSize("editor", "showWhitespacesSize", Value(Value::RangeType(1, 16)), Value(2));
SettingsEntry Settings::autoIndent("editor", "autoIndent", Value(true), Value(true));
SettingsEntry Settings::indentStyle("editor", "indentStyle", values("Spaces", _("Spaces"), "Tabs", _("Tabs")), Value("Spaces"));
SettingsEntry Settings::tabKeyFunction("editor", "tabKeyFunction", values("Indent", _("Indent"), "InsertTab", _("Insert Tab")), Value("Indent"));
SettingsEntry Settings::highlightCurrentLine("editor", "highlightCurrentLine", Value(true), Value(true));
SettingsEntry Settings::enableBraceMatching("editor", "enableBraceMatching", Value(true), Value(true));
}

75
src/settings.h Normal file
View File

@ -0,0 +1,75 @@
#pragma once
#include <map>
#include <list>
#include <string>
#include "value.h"
namespace Settings {
class SettingsEntry
{
private:
std::string _category;
std::string _name;
Value _value;
Value _range;
Value _default;
public:
const std::string & category() const;
const std::string & name() const;
virtual const Value & defaultValue() const;
virtual const Value & range() const;
virtual bool is_default() const;
protected:
SettingsEntry(const std::string category, const std::string name, const Value range, const Value def);
virtual ~SettingsEntry();
friend class Settings;
};
class Settings
{
public:
static SettingsEntry indentationWidth;
static SettingsEntry tabWidth;
static SettingsEntry lineWrap;
static SettingsEntry lineWrapIndentationStyle;
static SettingsEntry lineWrapIndentation;
static SettingsEntry lineWrapVisualizationBegin;
static SettingsEntry lineWrapVisualizationEnd;
static SettingsEntry showWhitespace;
static SettingsEntry showWhitespaceSize;
static SettingsEntry autoIndent;
static SettingsEntry indentStyle;
static SettingsEntry tabKeyFunction;
static SettingsEntry highlightCurrentLine;
static SettingsEntry enableBraceMatching;
static Settings *inst(bool erase = false);
void visit(class Visitor& visitor);
Value defaultValue(const SettingsEntry& entry);
Value get(const SettingsEntry& entry);
void set(SettingsEntry& entry, const Value val);
private:
Settings();
virtual ~Settings();
};
class Visitor
{
public:
Visitor();
virtual ~Visitor();
virtual void handle(SettingsEntry& entry) const = 0;
};
}

View File

@ -82,6 +82,10 @@ public:
this->end_val == other.end_val;
}
double begin_value() { return begin_val; }
double step_value() { return step_val; }
double end_value() { return end_val; }
iterator begin() { return iterator(*this, RANGE_TYPE_BEGIN); }
iterator end() { return iterator(*this, RANGE_TYPE_END); }