ui: added setting for text encoding to preferences (issue #500)
* also fixed offset of source locations behind multibyte characters
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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
|
||||
Reference in New Issue
Block a user