mirror of https://github.com/vitalif/openscad
commit
bc30dca513
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
1428
src/Preferences.ui
1428
src/Preferences.ui
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ public slots:
|
|||
|
||||
private slots:
|
||||
void onTextChanged();
|
||||
void applySettings();
|
||||
|
||||
private:
|
||||
QVBoxLayout *scintillaLayout;
|
||||
|
|
|
@ -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));
|
||||
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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); }
|
||||
|
||||
|
|
Loading…
Reference in New Issue