ui: added setting for text encoding to preferences (issue #500)

* also fixed offset of source locations behind multibyte characters
This commit is contained in:
mlangkabel
2017-11-02 12:40:50 +01:00
parent 8dbfa61234
commit f027b94dd4
10 changed files with 178 additions and 23 deletions
+10
View File
@@ -117,6 +117,16 @@ void ApplicationSettings::setFontSize(int fontSize)
setValue<int>("application/font_size", fontSize);
}
std::string ApplicationSettings::getTextEncoding() const
{
return getValue<std::string>("application/text_encoding", "UTF-8");
}
void ApplicationSettings::setTextEncoding(const std::string& textEncoding)
{
setValue<std::string>("application/text_encoding", textEncoding);
}
bool ApplicationSettings::getUseAnimations() const
{
return getValue<bool>("application/use_animations", true);
+3
View File
@@ -32,6 +32,9 @@ public:
int getFontSize() const;
void setFontSize(int fontSize);
std::string getTextEncoding() const;
void setTextEncoding(const std::string& textEncoding);
FilePath getColorSchemePath() const;
void setColorSchemePath(const FilePath& colorSchemePath);
+2
View File
@@ -58,6 +58,8 @@ add_files(
qt/element/QtStatusBar.h
qt/element/QtTable.cpp
qt/element/QtTable.h
qt/element/QtTextEncodingPicker.cpp
qt/element/QtTextEncodingPicker.h
qt/element/QtTooltip.cpp
qt/element/QtTooltip.h
qt/element/QtUndoRedo.cpp
+58 -7
View File
@@ -2,6 +2,7 @@
#include <QPainter>
#include <QTextBlock>
#include <QTextCodec>
#include "data/location/SourceLocation.h"
#include "data/location/SourceLocationFile.h"
@@ -47,8 +48,15 @@ QtCodeField::QtCodeField(
displayCode.pop_back();
}
setPlainText(QString::fromUtf8(displayCode.c_str()));
QTextCodec* codec = QTextCodec::codecForName(ApplicationSettings::getInstance()->getTextEncoding().c_str());
QString convertedDisplayCode(codec->toUnicode(displayCode.c_str()));
setPlainText(convertedDisplayCode);
createLineLengthCache();
if (displayCode.size() != convertedDisplayCode.length())
{
LOG_INFO("Converting displayed code to " + codec->name().toStdString() + " resulted in offset of source locations. Correcting this now.");
createMultibyteCharacterLocationCache();
}
this->setMouseTracking(true);
@@ -333,9 +341,12 @@ void QtCodeField::createAnnotations(std::shared_ptr<SourceLocationFile> location
}
else if (startLocation->getLineNumber() <= endLineNumber)
{
annotation.start = toTextEditPosition(startLocation->getLineNumber(), startLocation->getColumnNumber() - 1);
annotation.startLine = startLocation->getLineNumber();
annotation.startCol = startLocation->getColumnNumber() - 1;
const int startLine = startLocation->getLineNumber();
const int startCol = getColumnCorrectedForMultibyteCharacters(startLine, startLocation->getColumnNumber() - 1);
annotation.start = toTextEditPosition(startLine, startCol);
annotation.startLine = startLine;
annotation.startCol = startCol;
}
else
{
@@ -351,9 +362,12 @@ void QtCodeField::createAnnotations(std::shared_ptr<SourceLocationFile> location
}
else if (endLocation->getLineNumber() >= m_startLineNumber)
{
annotation.end = toTextEditPosition(endLocation->getLineNumber(), endLocation->getColumnNumber());
annotation.endLine = endLocation->getLineNumber();
annotation.endCol = endLocation->getColumnNumber();
const int endLine = endLocation->getLineNumber();
const int endCol = getColumnCorrectedForMultibyteCharacters(endLine, endLocation->getColumnNumber());
annotation.end = toTextEditPosition(endLine, endCol);
annotation.endLine = endLine;
annotation.endCol = endCol;
}
else
{
@@ -641,3 +655,40 @@ void QtCodeField::createLineLengthCache()
m_endTextEditPosition += it.length();
}
}
void QtCodeField::createMultibyteCharacterLocationCache()
{
m_multibyteCharacterLocations.clear();
QTextCodec* codec = QTextCodec::codecForName(ApplicationSettings::getInstance()->getTextEncoding().c_str());
for (QTextBlock itLine = document()->begin(); itLine != document()->end(); itLine = itLine.next())
{
std::vector<std::pair<int, int>> columnsToOffsets;
const QString line = itLine.text();
for (int i = 0; i < line.size(); i++)
{
if (line[i].unicode() > 127)
{
int ss = codec->fromUnicode(line[i]).size();
columnsToOffsets.push_back(std::make_pair(i, ss));
}
}
m_multibyteCharacterLocations.push_back(columnsToOffsets);
}
}
int QtCodeField::getColumnCorrectedForMultibyteCharacters(const int line, int column) const
{
const int relativeLineNumber = line - m_startLineNumber;
if (relativeLineNumber < m_multibyteCharacterLocations.size())
{
for (const std::pair<int, int> m_multibyteCharacterLocation : m_multibyteCharacterLocations[relativeLineNumber])
{
if (column > m_multibyteCharacterLocation.first)
{
column -= m_multibyteCharacterLocation.second - 1;
}
}
}
return column;
}
+3
View File
@@ -105,6 +105,8 @@ private:
static std::vector<AnnotationColor> s_annotationColors;
void createLineLengthCache();
void createMultibyteCharacterLocationCache();
int getColumnCorrectedForMultibyteCharacters(const int line, int column) const;
const uint m_startLineNumber;
const std::string m_code;
@@ -114,6 +116,7 @@ private:
QtHighlighter* m_highlighter;
std::vector<int> m_lineLengths;
std::vector<std::vector<std::pair<int, int>>> m_multibyteCharacterLocations;
int m_endTextEditPosition;
};
+1 -3
View File
@@ -1,7 +1,6 @@
#include "qt/element/QtFontPicker.h"
#include <QHBoxLayout>
#include <QPainter>
#include <QFontComboBox>
QtFontPicker::QtFontPicker(QWidget *parent)
@@ -15,7 +14,7 @@ QtFontPicker::QtFontPicker(QWidget *parent)
layout->setAlignment(Qt::AlignTop);
m_box = new QFontComboBox();
m_box->setFontFilters( QFontComboBox::MonospacedFonts );
m_box->setFontFilters(QFontComboBox::MonospacedFonts);
m_box->setEditable(false);
layout->addWidget(m_box);
@@ -33,4 +32,3 @@ void QtFontPicker::setText(QString text)
{
m_box->setCurrentText(text);
}
@@ -0,0 +1,39 @@
#include "qt/element/QtTextEncodingPicker.h"
#include <QHBoxLayout>
#include <QTextCodec>
#include <QFontComboBox>
QtTextEncodingPicker::QtTextEncodingPicker(QWidget *parent)
: QWidget(parent)
{
setObjectName("picker");
QBoxLayout* layout = new QHBoxLayout();
layout->setSpacing(0);
layout->setContentsMargins(1, 1, 1, 1);
layout->setAlignment(Qt::AlignTop);
m_box = new QComboBox();
for (int mib : QTextCodec::availableMibs())
{
m_box->addItem(QTextCodec::codecForMib(mib)->name());
}
m_box->setEditable(false);
layout->addWidget(m_box);
setLayout(layout);
setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Fixed);
}
QString QtTextEncodingPicker::getText()
{
return m_box->currentText();
}
void QtTextEncodingPicker::setText(QString text)
{
m_box->setCurrentText(text);
}
@@ -0,0 +1,23 @@
#ifndef QT_TEXT_ENCODING_PICKER_H
#define QT_TEXT_ENCODING_PICKER_H
#include <QWidget>
class QComboBox;
class QtTextEncodingPicker
: public QWidget
{
Q_OBJECT
public:
QtTextEncodingPicker(QWidget *parent);
QString getText();
void setText(QString text);
private:
QComboBox* m_box;
};
#endif // QT_TEXT_ENCODING_PICKER_H
@@ -1,5 +1,7 @@
#include "qt/window/project_wizzard/QtProjectWizzardContentPreferences.h"
#include "qt/element/QtFontPicker.h"
#include "qt/element/QtTextEncodingPicker.h"
#include "qt/utility/utilityQt.h"
#include "settings/ApplicationSettings.h"
#include "utility/file/FileSystem.h"
@@ -39,17 +41,25 @@ void QtProjectWizzardContentPreferences::populate(QGridLayout* layout, int& row)
m_fontFace->setObjectName("name");
m_fontFace->setAttribute(Qt::WA_MacShowFocusRect, 0);
addLabelAndWidget("Font face", m_fontFace, layout, row);
addLabelAndWidget("Font Face", m_fontFace, layout, row);
row++;
// font size
m_fontSize = addComboBox("Font size", appSettings->getFontSizeMin(), appSettings->getFontSizeMax(), "", layout, row);
m_fontSize = addComboBox("Font Size", appSettings->getFontSizeMin(), appSettings->getFontSizeMax(), "", layout, row);
// tab width
m_tabWidth = addComboBox("Tab width", 1, 16, "", layout, row);
m_tabWidth = addComboBox("Tab Width", 1, 16, "", layout, row);
// text encoding
m_textEncoding = new QtTextEncodingPicker(this);
m_textEncoding->setObjectName("text encoding");
m_textEncoding->setAttribute(Qt::WA_MacShowFocusRect, 0);
addLabelAndWidget("Text Encoding", m_textEncoding, layout, row);
row++;
// color scheme
m_colorSchemes = addComboBox("Color scheme", 0, 0, "", layout, row);
m_colorSchemes = addComboBox("Color Scheme", "", layout, row);
for (size_t i = 0; i < m_colorSchemePaths.size(); i++)
{
m_colorSchemes->insertItem(i, m_colorSchemePaths[i].withoutExtension().fileName().c_str());
@@ -292,6 +302,8 @@ void QtProjectWizzardContentPreferences::load()
m_fontSize->setCurrentIndex(appSettings->getFontSize() - appSettings->getFontSizeMin());
m_tabWidth->setCurrentIndex(appSettings->getCodeTabWidth() - 1);
m_textEncoding->setText(QString::fromStdString(appSettings->getTextEncoding()));
FilePath colorSchemePath = appSettings->getColorSchemePath();
for (size_t i = 0; i < m_colorSchemePaths.size(); i++)
{
@@ -346,6 +358,8 @@ void QtProjectWizzardContentPreferences::save()
appSettings->setFontSize(m_fontSize->currentIndex() + appSettings->getFontSizeMin());
appSettings->setCodeTabWidth(m_tabWidth->currentIndex() + 1);
appSettings->setTextEncoding(m_textEncoding->getText().toStdString());
appSettings->setColorSchemePath(m_colorSchemePaths[m_colorSchemes->currentIndex()]);
m_oldColorSchemeIndex = -1;
@@ -578,11 +592,26 @@ QCheckBox* QtProjectWizzardContentPreferences::addCheckBox(
}
QComboBox* QtProjectWizzardContentPreferences::addComboBox(
QString label, int min, int max, QString helpText, QGridLayout* layout, int& row)
QString label, QString helpText, QGridLayout* layout, int& row)
{
QComboBox* comboBox = new QComboBox(this);
addLabelAndWidget(label, comboBox, layout, row, Qt::AlignLeft);
if (helpText.size())
{
addHelpButton(label, helpText, layout, row);
}
row++;
return comboBox;
}
QComboBox* QtProjectWizzardContentPreferences::addComboBox(
QString label, int min, int max, QString helpText, QGridLayout* layout, int& row)
{
QComboBox* comboBox = addComboBox(label, helpText, layout, row);
if (min != max)
{
for (int i = min; i <= max; i++)
@@ -591,13 +620,6 @@ QComboBox* QtProjectWizzardContentPreferences::addComboBox(
}
}
if (helpText.size())
{
addHelpButton(label, helpText, layout, row);
}
row++;
return comboBox;
}
@@ -6,12 +6,14 @@
#include <QLabel>
#include <QLineEdit>
#include "qt/element/QtFontPicker.h"
#include "qt/element/QtLocationPicker.h"
#include "qt/element/QtDirectoryListBox.h"
#include "qt/window/project_wizzard/QtProjectWizzardContent.h"
#include "utility/path_detector/CombinedPathDetector.h"
class QtFontPicker;
class QtTextEncodingPicker;
class QtProjectWizzardContentPreferences
: public QtProjectWizzardContent
{
@@ -47,12 +49,14 @@ private:
void addGap(QGridLayout* layout, int& row);
QCheckBox* addCheckBox(QString label, QString text, QString helpText, QGridLayout* layout, int& row);
QComboBox* addComboBox(QString label, QString helpText, QGridLayout* layout, int& row);
QComboBox* addComboBox(QString label, int min, int max, QString helpText, QGridLayout* layout, int& row);
QLineEdit* addLineEdit(QString label, QString helpText, QGridLayout* layout, int& row);
QtFontPicker* m_fontFace;
QComboBox* m_fontSize;
QComboBox* m_tabWidth;
QtTextEncodingPicker* m_textEncoding;
QComboBox* m_colorSchemes;
std::vector<FilePath> m_colorSchemePaths;