Linux Qt 6 port (#490)

* initial Qt 6 port

* move arch linux package to Qt 6

* minor fix
This commit is contained in:
Cyano Hao 2024-09-29 20:01:14 +08:00 committed by GitHub
parent 2e8f043f3f
commit b9f36558ba
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
42 changed files with 558 additions and 173 deletions

View File

@ -1,6 +1,6 @@
# General Development Notes
Red Panda C++ need Qt 5.15 to build.
Red Panda C++ need Qt 5.15 or 6.7+ to build.
Recommended development environments:
1. Visual Studio Code.

View File

@ -1,6 +1,6 @@
# 通用开发说明
小熊猫C++ 需要 Qt 5.15。
小熊猫C++ 需要 Qt 5.15 或 6.7+
推荐开发环境:
1. Visual Studio Code。

View File

@ -25,7 +25,6 @@
#include <QFileInfo>
#include <QProcess>
#include <QString>
#include <QTextCodec>
#include <QTime>
#include <QApplication>
#include "../editor.h"

View File

@ -18,7 +18,6 @@
#include "compilermanager.h"
#include <QFile>
#include <QFileInfo>
#include <QTextCodec>
StdinCompiler::StdinCompiler(const QString &filename,const QByteArray& encoding, const QString& content, bool onlyCheckSyntax):
Compiler(filename, onlyCheckSyntax),
@ -98,9 +97,9 @@ QByteArray StdinCompiler::pipedText()
if (mEncoding == ENCODING_ASCII)
return mContent.toLatin1();
QTextCodec* codec = QTextCodec::codecForName(mEncoding);
if (codec) {
return codec->fromUnicode(mContent);
TextEncoder encoder(mEncoding);
if (encoder.isValid()) {
return encoder.encodeUnchecked(mContent);
} else {
return mContent.toLocal8Bit();
}

View File

@ -17,7 +17,6 @@
#include <QFile>
#include <QMessageBox>
#include <QProgressDialog>
#include <QTextCodec>
#include <qsynedit/document.h>
#include "cpprefacter.h"
#include "mainwindow.h"

View File

@ -2542,11 +2542,8 @@ QVariant MemoryModel::data(const QModelIndex &index, int role) const
if (role == Qt::DisplayRole) {
if (col==line->datas.count()) {
QString s;
foreach (unsigned char ch, line->datas) {
if (ch<' ' || ch>=128)
s+='.';
else
s+=ch;
for (char ch : line->datas) {
s += isAsciiPrint(ch) ? ch : '.';
}
return s;
} else

View File

@ -18,7 +18,6 @@
#include <QtCore/QFileInfo>
#include <QFont>
#include <QTextCodec>
#include <QVariant>
#include <QWheelEvent>
#include <QGuiApplication>
@ -30,7 +29,6 @@
#include <QPrinter>
#include <QPrintDialog>
#include <QTextDocument>
#include <QTextCodec>
#include <QScrollBar>
#include <QScreen>
#include <memory>
@ -4230,7 +4228,7 @@ void Editor::updateFunctionTip(bool showTip)
return;
QChar ch=lastNonSpaceChar(currentLine,currentChar);
if (ch!="(" && ch!=",")
if (ch!='(' && ch!=',')
return;
QSynedit::PTokenAttribute attr;

View File

@ -59,7 +59,11 @@ class WindowLogoutEventFilter : public QAbstractNativeEventFilter {
// QAbstractNativeEventFilter interface
public:
#if QT_VERSION_MAJOR >= 6
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override;
#else
bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;
#endif
};
#ifndef WM_DPICHANGED
@ -124,7 +128,12 @@ HWND getPreviousInstance() {
return NULL;
}
bool WindowLogoutEventFilter::nativeEventFilter(const QByteArray & /*eventType*/, void *message, long *result){
#if QT_VERSION_MAJOR >= 6
bool WindowLogoutEventFilter::nativeEventFilter(const QByteArray & /*eventType*/, void *message, qintptr *result)
#else
bool WindowLogoutEventFilter::nativeEventFilter(const QByteArray & /*eventType*/, void *message, long *result)
#endif
{
MSG * pMsg = static_cast<MSG *>(message);
switch(pMsg->message) {
case WM_QUERYENDSESSION:

View File

@ -17,7 +17,6 @@
#include <QGuiApplication>
#include <QClipboard>
#include <QMessageBox>
#include <QTextCodec>
#include <QCloseEvent>
#include <QComboBox>
#include <QDesktopServices>
@ -45,6 +44,7 @@
#include <QUuid>
#include <QScrollBar>
#include <QTextDocumentFragment>
#include <QActionGroup>
#include "mainwindow.h"
#include "ui_mainwindow.h"
@ -1733,7 +1733,7 @@ Editor* MainWindow::openFile(QString filename, bool activate, QTabWidget* page)
}
bool inProject = (mProject && unit);
QByteArray encoding = unit ? unit->encoding() :
(pSettings->editor().autoDetectFileEncoding()? ENCODING_AUTO_DETECT : pSettings->editor().defaultEncoding());
(pSettings->editor().autoDetectFileEncoding() ? QByteArray(ENCODING_AUTO_DETECT) : pSettings->editor().defaultEncoding());
Project * pProject = (inProject?mProject.get():nullptr);
if (pProject && encoding==ENCODING_PROJECT)
encoding=pProject->options().encoding;
@ -3449,7 +3449,7 @@ void MainWindow::loadLastOpens()
}
bool inProject = (mProject && unit);
QByteArray encoding = unit ? unit->encoding() :
(pSettings->editor().autoDetectFileEncoding()? ENCODING_AUTO_DETECT : pSettings->editor().defaultEncoding());
(pSettings->editor().autoDetectFileEncoding()? QByteArray(ENCODING_AUTO_DETECT) : pSettings->editor().defaultEncoding());
Project* pProject = (inProject?mProject.get():nullptr);
if (pProject && encoding==ENCODING_PROJECT)
encoding=pProject->options().encoding;
@ -6349,7 +6349,7 @@ void MainWindow::on_actionConvert_to_ANSI_triggered()
return;
if (QMessageBox::warning(this,tr("Confirm Convertion"),
tr("The editing file will be saved using %1 encoding. <br />This operation can't be reverted. <br />Are you sure to continue?")
.arg(QString(QTextCodec::codecForLocale()->name())),
.arg(QString(TextEncoder::encoderForSystem().name())),
QMessageBox::Yes, QMessageBox::No)!=QMessageBox::Yes)
return;
editor->convertToEncoding(ENCODING_SYSTEM_DEFAULT);

View File

@ -17,7 +17,6 @@
#include "cpppreprocessor.h"
#include <QFile>
#include <QTextCodec>
#include <QDebug>
#include <QMessageBox>
#include "../utils.h"

View File

@ -113,7 +113,7 @@ private:
}
static bool isBlankChar(const QChar& ch) {
return (ch<=32) && (ch>0);
return (ch.unicode() <= 32) && (ch.unicode() > 0);
}
// static bool isOperatorChar(const QChar& ch) {

View File

@ -16,6 +16,7 @@
*/
#include "project.h"
#include "editor.h"
#include "qt_utils/utils.h"
#include "utils.h"
#include "systemconsts.h"
#include "editorlist.h"
@ -31,7 +32,6 @@
#include <QFileDialog>
#include <QFileInfo>
#include <QMessageBox>
#include <QTextCodec>
#include <QMessageBox>
#include <QDirIterator>
#include <QMimeDatabase>
@ -255,7 +255,7 @@ void Project::open()
if (newUnit->encoding()!=ENCODING_UTF16_BOM &&
newUnit->encoding()!=ENCODING_UTF8_BOM &&
newUnit->encoding()!=ENCODING_UTF32_BOM &&
QTextCodec::codecForName(newUnit->encoding())==nullptr) {
!isEncodingAvailable(newUnit->encoding())) {
newUnit->setEncoding(ENCODING_PROJECT);
}
newUnit->setRealEncoding(ini.GetValue(groupName, "RealEncoding",ENCODING_ASCII));
@ -944,11 +944,9 @@ bool Project::assignTemplate(const std::shared_ptr<ProjectTemplate> aTemplate, b
updateCompilerSetting();
mOptions.icon = aTemplate->icon();
QTextCodec* codec=QTextCodec::codecForName(mOptions.encoding);
if (!codec)
if (!isEncodingAvailable(mOptions.encoding))
mOptions.encoding=ENCODING_SYSTEM_DEFAULT;
codec=QTextCodec::codecForName(mOptions.execEncoding);
if (!codec)
if (!isEncodingAvailable(mOptions.execEncoding))
mOptions.execEncoding=ENCODING_SYSTEM_DEFAULT;
// Copy icon to project directory
@ -2611,7 +2609,7 @@ QVariant ProjectModel::data(const QModelIndex &index, int role) const
if (p->isUnit) {
PProjectUnit unit = p->pUnit.lock();
if (unit)
icon = mIconProvider->icon(unit->fileName());
icon = mIconProvider->icon(QFileInfo(unit->fileName()));
} else {
if (p == mProject->rootNode().get()) {
#ifdef ENABLE_VCS

View File

@ -16,7 +16,6 @@
*/
#include "settings.h"
#include <QApplication>
#include <QTextCodec>
#include <algorithm>
#include "utils.h"
#include "utils/escape.h"

View File

@ -28,7 +28,6 @@
#include <QImageWriter>
#include <QImageWriter>
#include <QMessageBox>
#include <QTextCodec>
ProjectGeneralWidget::ProjectGeneralWidget(const QString &name, const QString &group, QWidget *parent) :
SettingsWidget(name,group,parent),

View File

@ -20,7 +20,6 @@
#include <QSet>
#include <QString>
#include <QStringList>
#include <QTextCodec>
SystemConsts* pSystemConsts;
@ -44,28 +43,7 @@ SystemConsts::SystemConsts(): mDefaultFileFilters()
mCodecNames.append(ENCODING_SYSTEM_DEFAULT);
mCodecNames.append(ENCODING_UTF8);
mCodecNames.append(ENCODING_UTF8_BOM);
QStringList codecNames;
QSet<QByteArray> codecAlias;
codecAlias.insert("system");
codecAlias.insert("utf-8");
foreach (const QByteArray& name, QTextCodec::availableCodecs()){
QByteArray lname = name.toLower();
if (lname.startsWith("cp"))
continue;
if (codecAlias.contains(lname))
continue;
codecNames.append(lname);
codecAlias.insert(lname);
QTextCodec* codec = QTextCodec::codecForName(name);
if (codec) {
foreach (const QByteArray& alias, codec->aliases()) {
codecAlias.insert(alias.toLower());
}
}
}
std::sort(codecNames.begin(),codecNames.end());
mCodecNames.append(codecNames);
mCodecNames.append(availableEncodings());
mDefaultFileNameFilters.append("*.c");
mDefaultFileNameFilters.append("*.cpp");

View File

@ -227,4 +227,12 @@ bool osSupportsUtf8Manifest();
bool applicationIsUtf8(const QString &path);
#endif
#if QT_VERSION_MAJOR >= 6
// for xml.name() == "tag"
inline bool operator==(QStringView a, const char *b)
{
return a.compare(b);
}
#endif
#endif // UTILS_H

View File

@ -115,7 +115,11 @@ void ColorEdit::mouseReleaseEvent(QMouseEvent *)
}
}
#if QT_VERSION_MAJOR >= 6
void ColorEdit::enterEvent(QEnterEvent *)
#else
void ColorEdit::enterEvent(QEvent *)
#endif
{
setCursor(Qt::PointingHandCursor);
}

View File

@ -37,7 +37,11 @@ public:
QSize sizeHint() const override;
void paintEvent(QPaintEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
#if QT_VERSION_MAJOR >= 6
void enterEvent(QEnterEvent *event) override;
#else
void enterEvent(QEvent *event) override;
#endif
void leaveEvent(QEvent *event) override;
QSize minimumSizeHint() const override;
};

View File

@ -19,6 +19,7 @@
#include <QHBoxLayout>
#include <QPushButton>
#include <QDebug>
#include <qt_utils/utils.h>
FunctionTooltipWidget::FunctionTooltipWidget(QWidget *parent) :
QFrame{parent, Qt::ToolTip | Qt::WindowStaysOnTopHint | Qt::WindowDoesNotAcceptFocus},

View File

@ -33,7 +33,11 @@ void LabelWithMenu::mousePressEvent(QMouseEvent *event)
event->accept();
}
#if QT_VERSION_MAJOR >= 6
void LabelWithMenu::enterEvent(QEnterEvent *event)
#else
void LabelWithMenu::enterEvent(QEvent *event)
#endif
{
mCursor = cursor();
setCursor(Qt::PointingHandCursor);

View File

@ -31,7 +31,11 @@ protected:
// QWidget interface
protected:
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void enterEvent(QEnterEvent *event) override;
#else
void enterEvent(QEvent *event) override;
#endif
void leaveEvent(QEvent *event) override;
private:

View File

@ -51,6 +51,9 @@ struct RowColumn {
struct LineChar {
int ch;
int line;
LineChar() = default;
constexpr LineChar(qsizetype ch_, qsizetype line_) : ch(ch_), line(line_) {}
};
class QConsole;

View File

@ -35,6 +35,13 @@ protected:
QListView::resizeEvent(event);
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
void initViewItemOption(QStyleOptionViewItem *option) const override
{
QListView::initViewItemOption(option);
option->showDecorationSelected = true;
}
#else
QStyleOptionViewItem viewOptions() const override
{
QStyleOptionViewItem option = QListView::viewOptions();
@ -43,6 +50,7 @@ protected:
// option.font = combo->font();
return option;
}
#endif
void paintEvent(QPaintEvent *e) override
{
@ -59,7 +67,11 @@ protected:
menuOpt.checkType = QStyleOptionMenuItem::NotCheckable;
menuOpt.menuRect = e->rect();
menuOpt.maxIconWidth = 0;
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
menuOpt.reservedShortcutWidth = 0;
#else
menuOpt.tabWidth = 0;
#endif
QPainter p(viewport());
combo->style()->drawControl(QStyle::CE_MenuEmptyArea, &menuOpt, &p, this);
}

View File

@ -3,7 +3,7 @@
## 传统 Unix 方式(`./configure``make``make install`
- 安装支持 C++17 的 GCC≥ 7或 Clang≥ 6
- 安装 Qt 5.15 Base、SVG、Tools 模块,包括库和开发文件。
- 安装 Qt 5.15 或 6.7+ Base、SVG、Tools 模块,包括库和开发文件。
- 如果使用静态版本的 Qt 编译,还要安装 fcitx5-qt。
- 安装 astyle 以便在小熊猫 C++ 中对代码进行重新排版。

View File

@ -3,7 +3,7 @@
## Traditional Unix Way (`./configure``make``make install`)
- Install recent version of GCC (≥ 7) or Clang (≥ 6) that supports C++17.
- Install Qt 5.15 Base, SVG and Tools modules, including both libraries and development files.
- Install Qt 5.15 or 6.7+ Base, SVG and Tools modules, including both libraries and development files.
- Optionally install fcitx5-qt for building with static Qt library.
- Install astyle for code formatting in Red Panda C++.

View File

@ -18,12 +18,12 @@
#include "qt_utils/utils.h"
#include <QDataStream>
#include <QFile>
#include <QTextCodec>
#include <QTextStream>
#include <QMutexLocker>
#include <stdexcept>
#include <QMessageBox>
#include <cmath>
#include <optional>
#include "qt_utils/charsetinfo.h"
#include <QDateTime>
#include <QDebug>
@ -498,12 +498,11 @@ void Document::insertLines(int index, int numLines)
bool Document::tryLoadFileByEncoding(QByteArray encodingName, QFile& file) {
QTextCodec* codec = QTextCodec::codecForName(encodingName);
if (!codec)
TextDecoder decoder(encodingName);
if (!decoder.isValid())
return false;
file.reset();
internalClear();
QTextCodec::ConverterState state;
while (true) {
if (file.atEnd()){
break;
@ -516,10 +515,9 @@ bool Document::tryLoadFileByEncoding(QByteArray encodingName, QFile& file) {
} else if (line.endsWith("\n")){
line.remove(line.length()-1,1);
}
QString newLine = codec->toUnicode(line.constData(),line.length(),&state);
if (state.invalidChars>0) {
auto [ok, newLine] = decoder.decode(line);
if (!ok) {
return false;
break;
}
addItem(newLine);
}
@ -528,46 +526,46 @@ bool Document::tryLoadFileByEncoding(QByteArray encodingName, QFile& file) {
void Document::loadUTF16BOMFile(QFile &file)
{
QTextCodec* codec=QTextCodec::codecForName(ENCODING_UTF16);
if (!codec)
TextDecoder decoder = TextDecoder::decoderForUtf16();
if (!decoder.isValid())
return;
file.reset();
internalClear();
QByteArray buf = file.readAll();
if (buf.length()<2)
return;
QString text = codec->toUnicode(buf.mid(2));
QString text = decoder.decodeUnchecked(buf.mid(2));
this->setText(text);
}
void Document::loadUTF32BOMFile(QFile &file)
{
QTextCodec* codec=QTextCodec::codecForName(ENCODING_UTF32);
if (!codec)
TextDecoder decoder = TextDecoder::decoderForUtf32();
if (!decoder.isValid())
return;
file.reset();
internalClear();
QByteArray buf = file.readAll();
if (buf.length()<4)
return;
QString text = codec->toUnicode(buf.mid(4));
QString text = decoder.decodeUnchecked(buf.mid(4));
this->setText(text);
}
void Document::saveUTF16File(QFile &file, QTextCodec* codec)
void Document::saveUTF16File(QFile &file, TextEncoder &encoder)
{
if (!codec)
if (!encoder.isValid())
return;
QString text=getTextStr();
file.write(codec->fromUnicode(text));
file.write(encoder.encodeUnchecked(text));
}
void Document::saveUTF32File(QFile &file, QTextCodec* codec)
void Document::saveUTF32File(QFile &file, TextEncoder &encoder)
{
if (!codec)
if (!encoder.isValid())
return;
QString text=getTextStr();
file.write(codec->fromUnicode(text));
file.write(encoder.encodeUnchecked(text));
}
void Document::setTabSize(int newTabSize)
@ -606,15 +604,14 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding,
return;
}
QByteArray line = file.readLine();
QTextCodec* codec;
QTextCodec::ConverterState state;
std::optional<TextDecoder> decoder;
bool needReread = false;
bool allAscii = true;
//test for BOM
if ((line.length()>=3) && ((unsigned char)line[0]==0xEF) && ((unsigned char)line[1]==0xBB) && ((unsigned char)line[2]==0xBF) ) {
realEncoding = ENCODING_UTF8_BOM;
line = line.mid(3);
codec = QTextCodec::codecForName(ENCODING_UTF8);
decoder = TextDecoder::decoderForUtf8();
} else if ((line.length()>=4) && ((unsigned char)line[0]==0xFF) && ((unsigned char)line[1]==0xFE)
&& ((unsigned char)line[2]==0x00)
&& ((unsigned char)line[3]==0x00)) {
@ -627,9 +624,9 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding,
return;
} else {
realEncoding = ENCODING_UTF8;
codec = QTextCodec::codecForName(ENCODING_UTF8);
decoder = TextDecoder::decoderForUtf8();
}
if (!codec)
if (!decoder.has_value())
throw FileError(tr("Can't load codec '%1'!").arg(QString(realEncoding)));
if (line.endsWith("\r\n")) {
mNewlineType = NewlineType::Windows;
@ -656,8 +653,8 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding,
if (allAscii) {
addItem(QString::fromLatin1(line));
} else {
QString newLine = codec->toUnicode(line.constData(),line.length(),&state);
if (state.invalidChars>0) {
auto [ok, newLine] = decoder->decode(line);
if (!ok) {
needReread = true;
break;
}
@ -703,13 +700,16 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding,
realEncoding = pCharsetInfoManager->getDefaultSystemEncoding();
}
file.reset();
QTextStream textStream(&file);
QByteArray data = file.readAll();
QString text;
QTextStream textStream(&text);
if (realEncoding == ENCODING_UTF8_BOM) {
textStream.setAutoDetectUnicode(true);
textStream.setCodec(ENCODING_UTF8);
text = QString::fromUtf8(data);
} else {
textStream.setAutoDetectUnicode(false);
textStream.setCodec(realEncoding);
TextDecoder decoder(realEncoding);
text = decoder.decodeUnchecked(data);
}
QString line;
internalClear();
@ -731,28 +731,28 @@ void Document::saveToFile(QFile &file, const QByteArray& encoding,
const QByteArray& defaultEncoding, QByteArray& realEncoding)
{
QMutexLocker locker(&mMutex);
QTextCodec* codec;
std::optional<TextEncoder> encoder;
realEncoding = encoding;
QString codecName = realEncoding;
if (realEncoding == ENCODING_UTF16_BOM || realEncoding == ENCODING_UTF16) {
codec = QTextCodec::codecForName(ENCODING_UTF16);
encoder = TextEncoder::encoderForUtf16();
codecName = ENCODING_UTF16;
} else if (realEncoding == ENCODING_UTF32_BOM || realEncoding == ENCODING_UTF32) {
codec = QTextCodec::codecForName(ENCODING_UTF32);
encoder = TextEncoder::encoderForUtf32();
codecName = ENCODING_UTF32;
} else if (realEncoding == ENCODING_UTF8_BOM) {
codec = QTextCodec::codecForName(ENCODING_UTF8);
encoder = TextEncoder::encoderForUtf8();
codecName = ENCODING_UTF8;
} else if (realEncoding == ENCODING_SYSTEM_DEFAULT) {
codec = QTextCodec::codecForLocale();
encoder = TextEncoder::encoderForSystem();
codecName = realEncoding;
} else if (realEncoding == ENCODING_AUTO_DETECT) {
codec = QTextCodec::codecForName(defaultEncoding);
encoder = TextEncoder(defaultEncoding);
codecName = defaultEncoding;
} else {
codec = QTextCodec::codecForName(realEncoding);
encoder = TextEncoder(realEncoding);
}
if (!codec)
if (!encoder.has_value() || !encoder->isValid())
throw FileError(tr("Can't load codec '%1'!").arg(codecName));
if (!file.open(QFile::WriteOnly | QFile::Truncate))
@ -760,10 +760,10 @@ void Document::saveToFile(QFile &file, const QByteArray& encoding,
if (mLines.isEmpty())
return;
if (realEncoding == ENCODING_UTF16) {
saveUTF16File(file,codec);
saveUTF16File(file, encoder.value());
return;
} else if (realEncoding == ENCODING_UTF32) {
saveUTF32File(file,codec);
saveUTF32File(file, encoder.value());
return;
} if (realEncoding == ENCODING_UTF8_BOM) {
file.putChar(0xEF);
@ -774,7 +774,7 @@ void Document::saveToFile(QFile &file, const QByteArray& encoding,
QByteArray data;
for (PDocumentLine& line:mLines) {
QString text = line->lineText()+lineBreak();
data = codec->fromUnicode(text);
data = encoder->encodeUnchecked(text);
if (allAscii) {
allAscii = (data==text.toLatin1());
}
@ -784,10 +784,10 @@ void Document::saveToFile(QFile &file, const QByteArray& encoding,
if (allAscii) {
realEncoding = ENCODING_ASCII;
} else if (realEncoding == ENCODING_SYSTEM_DEFAULT) {
if (QString(codec->name()).compare("System",Qt::CaseInsensitive)==0) {
if (encoder->name().compare("System",Qt::CaseInsensitive)==0) {
realEncoding = pCharsetInfoManager->getDefaultSystemEncoding();
} else {
realEncoding = codec->name();
realEncoding = encoder->name();
}
}
}

View File

@ -647,8 +647,8 @@ private:
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
void loadUTF16BOMFile(QFile& file);
void loadUTF32BOMFile(QFile& file);
void saveUTF16File(QFile& file, QTextCodec* codec);
void saveUTF32File(QFile& file, QTextCodec* codec);
void saveUTF16File(QFile& file, TextEncoder &encoder);
void saveUTF32File(QFile& file, TextEncoder &encoder);
private:
DocumentLines mLines;

View File

@ -21,7 +21,7 @@
#include <QGuiApplication>
#include <QMimeData>
#include <QPalette>
#include <QTextCodec>
#include <qt_utils/utils.h>
namespace QSynedit {
@ -131,8 +131,9 @@ void Exporter::saveToFile(const QString &filename)
void Exporter::writeToStream(QIODevice &stream)
{
QTextCodec *codec=getCodec();
if (stream.write(codec->fromUnicode(mText))<0) {
TextEncoder encoder = getEncoder();
auto [ok, encoded] = encoder.encode(mText);
if (ok && stream.write(encoded) < 0) {
throw FileError(QObject::tr("Failed to write data."));
}
}
@ -274,12 +275,14 @@ int Exporter::getBufferSize() const
return mText.size();
}
QTextCodec * Exporter::getCodec() const {
QTextCodec* codec = QTextCodec::codecForName(mCharset);
if (codec == nullptr)
codec = QTextCodec::codecForLocale();
return codec;
TextEncoder Exporter::getEncoder() const {
TextEncoder encoder(mCharset);
if (encoder.isValid())
return encoder;
else
return TextEncoder::encoderForSystem();
}
void Exporter::insertData(int pos, const QString &text)
{
if (!text.isEmpty()) {
@ -339,8 +342,9 @@ void Exporter::setTokenAttribute(PTokenAttribute attri)
QByteArray Exporter::buffer() const
{
QTextCodec* codec = getCodec();
return codec->fromUnicode(mText);
TextEncoder encoder = getEncoder();
auto [_, encoded] = encoder.encode(mText);
return encoded;
}
const QString &Exporter::text() const

View File

@ -242,7 +242,7 @@ protected:
*/
virtual void setTokenAttribute(PTokenAttribute attri);
QTextCodec *getCodec() const;
TextEncoder getEncoder() const;
private:
QString mText;
bool mFirstAttribute;

View File

@ -16,6 +16,7 @@
*/
#include "gutter.h"
#include "algorithm"
#include <qt_utils/utils.h>
namespace QSynedit {

View File

@ -30,9 +30,9 @@ EditKeyStroke::EditKeyStroke()
QKeySequence EditKeyStroke::keySequence() const
{
if (mKey2 == 0) {
return QKeySequence(mKey + mKeyModifiers);
return QKeySequence(mKey | mKeyModifiers);
} else {
return QKeySequence(mKey + mKeyModifiers, mKey2+mKeyModifiers2);
return QKeySequence(mKey | mKeyModifiers, mKey2 | mKeyModifiers2);
}
}

View File

@ -309,7 +309,7 @@ void ASMSyntaxer::SpaceProc()
mRun++;
if (mLine[mRun] == 0 || mLine[mRun] == '\r' || mLine[mRun] == '\n')
break;
if (mLine[mRun] > 32)
if (!isLexicalSpace(mLine[mRun]))
break;
}
if (mRun>=mStringLen)
@ -1696,7 +1696,7 @@ void ASMSyntaxer::next()
NumberProc();
} else if (isIdentStartChar(mLine[mRun])) {
IdentProc(IdentPrefix::None);
} else if (mLine[mRun]<=32) {
} else if (isLexicalSpace(mLine[mRun])) {
SpaceProc();
} else {
UnknownProc();

View File

@ -16,6 +16,7 @@
*/
#include "cpp.h"
#include "../constants.h"
#include "qt_utils/utils.h"
#include <QFont>
#include <QDebug>
@ -1069,7 +1070,7 @@ void CppSyntaxer::procSpace()
{
mRun += 1;
mTokenId = TokenId::Space;
while (mRun<mLineSize && mLine[mRun]>=1 && mLine[mRun]<=32)
while (mRun < mLineSize && isLexicalSpace(mLine[mRun]))
mRun+=1;
if (mRun>=mLineSize) {
mRange.hasTrailingSpaces = true;

View File

@ -846,7 +846,7 @@ void GLSLSyntaxer::spaceProc()
{
mRun += 1;
mTokenId = TokenId::Space;
while (mLine[mRun]>=1 && mLine[mRun]<=32)
while (isLexicalSpace(mLine[mRun]))
mRun+=1;
mRange.state = RangeState::rsUnknown;
if (mRun>=mLineSize)

View File

@ -16,6 +16,7 @@
*/
#include "lua.h"
#include "../constants.h"
#include "qt_utils/utils.h"
#include <QFont>
#include <QDebug>
@ -587,7 +588,7 @@ void LuaSyntaxer::spaceProc()
{
mRun += 1;
mTokenId = TokenId::Space;
while (mRun<mLineSize && mLine[mRun]>=1 && mLine[mRun]<=32)
while (mRun<mLineSize && isLexicalSpace(mLine[mRun]))
mRun+=1;
if (mRun>=mLineSize) {
mRange.hasTrailingSpaces = true;

View File

@ -200,7 +200,7 @@ MakefileSyntaxer::MakefileSyntaxer()
void MakefileSyntaxer::procSpace()
{
mTokenID = TokenId::Space;
while (mLine[mRun]!=0 && mLine[mRun]<=32)
while (mLine[mRun]!=0 && mLine[mRun] <= ' ')
mRun++;
if (mRun>=mStringLen)
mHasTrailingSpaces = true;

View File

@ -46,6 +46,10 @@ enum class ProgrammingLanguage {
struct BufferCoord {
int ch;
int line;
BufferCoord() = default;
constexpr BufferCoord(qsizetype ch_, qsizetype line_) : ch(ch_), line(line_) {}
bool operator==(const BufferCoord& coord);
bool operator>=(const BufferCoord& coord);
bool operator>(const BufferCoord& coord);

View File

@ -21,8 +21,6 @@
#include <QSet>
#ifdef Q_OS_WIN
#include <windows.h>
#else
#include <langinfo.h>
#endif
CharsetInfoManager* pCharsetInfoManager;
@ -37,7 +35,7 @@ QByteArray CharsetInfoManager::getDefaultSystemEncoding()
}
return "unknown";
#else
return QByteArray(nl_langinfo(CODESET));
return "UTF-8";
#endif
}

View File

@ -23,7 +23,6 @@
#include <QProcess>
#include <QProcessEnvironment>
#include <QString>
#include <QTextCodec>
#include <QtGlobal>
#include <QDebug>
#include <QStyleFactory>
@ -33,6 +32,8 @@
#include <QScreen>
#include <QDirIterator>
#include <QTextEdit>
#include "charsetinfo.h"
#ifdef Q_OS_WIN
#include <QDirIterator>
#include <QFont>
@ -40,7 +41,12 @@
#include <QMimeDatabase>
#include <windows.h>
#endif
#include "charsetinfo.h"
#if QT_VERSION_MAJOR >= 6
# include <QStringConverter>
#else
# include <QTextCodec>
#endif
BaseError::BaseError(const QString &reason):
mReason(reason)
@ -64,7 +70,7 @@ FileError::FileError(const QString &reason): BaseError(reason)
}
const QByteArray guessTextEncoding(const QByteArray& text){
QString guessTextEncoding(const QByteArray& text){
bool allAscii;
int ii;
int size;
@ -253,14 +259,16 @@ QByteArray toByteArray(const QString &s)
QString fromByteArray(const QByteArray &s)
{
QTextCodec* codec = QTextCodec::codecForName(ENCODING_UTF8);
QTextCodec::ConverterState state;
if (!codec)
return QString(s);
QString tmp = codec->toUnicode(s,s.length(),&state);
if (state.invalidChars>0)
tmp = QString::fromLocal8Bit(s);
return tmp;
#ifdef Q_OS_WIN
TextDecoder decoder = TextDecoder::decoderForUtf8();
auto [ok, result] = decoder.decode(s);
if (ok)
return result;
else
return QString::fromLocal8Bit(s);
#else
return QString::fromUtf8(s);
#endif
}
QStringList readStreamToLines(QTextStream *stream)
@ -282,37 +290,13 @@ void readStreamToLines(QTextStream *stream,
}
}
QStringList readFileToLines(const QString& fileName, QTextCodec* codec)
{
QFile file(fileName);
if (file.open(QFile::ReadOnly)) {
QTextStream stream(&file);
stream.setCodec(codec);
stream.setAutoDetectUnicode(false);
return readStreamToLines(&stream);
}
return QStringList();
}
void readFileToLines(const QString &fileName, QTextCodec *codec, LineProcessFunc lineFunc)
{
QFile file(fileName);
if (file.open(QFile::ReadOnly)) {
QTextStream stream(&file);
stream.setCodec(codec);
stream.setAutoDetectUnicode(false);
readStreamToLines(&stream, lineFunc);
}
}
static QStringList tryLoadFileByEncoding(QByteArray encodingName, QFile& file, bool* isOk) {
QStringList result;
*isOk = false;
QTextCodec* codec = QTextCodec::codecForName(encodingName);
if (!codec)
TextDecoder decoder(encodingName);
if (!decoder.isValid())
return result;
file.reset();
QTextCodec::ConverterState state;
while (true) {
if (file.atEnd()){
break;
@ -325,8 +309,8 @@ static QStringList tryLoadFileByEncoding(QByteArray encodingName, QFile& file, b
} else if (line.endsWith("\n")){
line.remove(line.length()-1,1);
}
QString newLine = codec->toUnicode(line.constData(),line.length(),&state);
if (state.invalidChars>0) {
auto [ok, newLine] = decoder.decode(line);
if (!ok) {
return QStringList();
}
result.append(newLine);
@ -355,12 +339,12 @@ QStringList readFileToLines(const QString &fileName)
}
QList<PCharsetInfo> charsets = pCharsetInfoManager->findCharsetByLocale(pCharsetInfoManager->localeName());
if (!charsets.isEmpty()) {
QSet<QByteArray> encodingSet;
QSet<QString> encodingSet;
for (int i=0;i<charsets.size();i++) {
encodingSet.insert(charsets[i]->name);
}
encodingSet.remove(realEncoding);
foreach (const QByteArray& encodingName,encodingSet) {
foreach (const QString& encodingName,encodingSet) {
if (encodingName == ENCODING_UTF8)
continue;
result = tryLoadFileByEncoding("UTF-8",file,&ok);
@ -765,3 +749,273 @@ const QChar *getNullTerminatedStringData(const QString &str)
}
return result;
}
TextEncoder::TextEncoder(const char *name)
{
#if QT_VERSION_MAJOR >= 6
mEncoder = QStringEncoder(name, QStringConverter::Flag::Stateless);
#else
mCodec = QTextCodec::codecForName(name);
#endif
}
TextEncoder::TextEncoder(const QByteArray &name) :
TextEncoder(name.data())
{
}
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
TextEncoder::TextEncoder(QStringEncoder &&encoder)
{
mEncoder = std::move(encoder);
}
#endif
bool TextEncoder::isValid() const
{
#if QT_VERSION_MAJOR >= 6
return mEncoder.isValid();
#else
return mCodec != nullptr;
#endif
}
QByteArray TextEncoder::name() const
{
#if QT_VERSION_MAJOR >= 6
return mEncoder.name();
#else
return mCodec->name();
#endif
}
std::pair<bool, QByteArray> TextEncoder::encode(const QString &text)
{
if (!isValid())
return {false, QByteArray()};
QByteArray result;
#if QT_VERSION_MAJOR >= 6
result = mEncoder(text);
if (mEncoder.hasError()) {
mEncoder.resetState();
return {false, QByteArray()};
}
#else
QTextCodec::ConverterState state;
result = mCodec->fromUnicode(text.constData(), text.length(), &state);
if (state.invalidChars > 0)
return {false, QByteArray()};
#endif
return {true, result};
}
QByteArray TextEncoder::encodeUnchecked(const QString &text)
{
if (!isValid())
return QByteArray();
#if QT_VERSION_MAJOR >= 6
QByteArray result = mEncoder(text);
if (mEncoder.hasError())
mEncoder.resetState();
return result;
#else
return mCodec->fromUnicode(text);
#endif
}
TextEncoder TextEncoder::encoderForUtf8()
{
#if QT_VERSION_MAJOR >= 6
return QStringEncoder(QStringConverter::Utf8, QStringConverter::Flag::Stateless);
#else
return TextEncoder(ENCODING_UTF8);
#endif
}
TextEncoder TextEncoder::encoderForUtf16()
{
#if QT_VERSION_MAJOR >= 6
return QStringEncoder(QStringConverter::Utf16, QStringConverter::Flag::Stateless);
#else
return TextEncoder(ENCODING_UTF16);
#endif
}
TextEncoder TextEncoder::encoderForUtf32()
{
#if QT_VERSION_MAJOR >= 6
return QStringEncoder(QStringConverter::Utf32, QStringConverter::Flag::Stateless);
#else
return TextEncoder(ENCODING_UTF32);
#endif
}
TextEncoder TextEncoder::encoderForSystem()
{
#ifdef Q_OS_WIN
# if QT_VERSION_MAJOR >= 6
return QStringEncoder(QStringConverter::System, QStringConverter::Flag::Stateless);
# else
return TextEncoder(ENCODING_SYSTEM_DEFAULT);
# endif
#else
return encoderForUtf8();
#endif
}
TextDecoder::TextDecoder(const char *name)
{
#if QT_VERSION_MAJOR >= 6
mDecoder = QStringDecoder(name, QStringConverter::Flag::Stateless);
#else
mCodec = QTextCodec::codecForName(name);
#endif
}
TextDecoder::TextDecoder(const QByteArray &name) :
TextDecoder(name.data())
{
}
#if QT_VERSION_MAJOR >= 6
TextDecoder::TextDecoder(QStringDecoder &&decoder)
{
mDecoder = std::move(decoder);
}
#endif
bool TextDecoder::isValid() const
{
#if QT_VERSION_MAJOR >= 6
return mDecoder.isValid();
#else
return mCodec != nullptr;
#endif
}
QByteArray TextDecoder::name() const
{
#if QT_VERSION_MAJOR >= 6
return mDecoder.name();
#else
return mCodec->name();
#endif
}
std::pair<bool, QString> TextDecoder::decode(const QByteArray &text)
{
if (!isValid())
return {false, QString()};
QString result;
#if QT_VERSION_MAJOR >= 6
result = mDecoder(text);
if (mDecoder.hasError()) {
mDecoder.resetState();
return {false, QString()};
}
#else
QTextCodec::ConverterState state;
result = mCodec->toUnicode(text.constData(), text.length(), &state);
if (state.invalidChars > 0)
return {false, QString()};
#endif
return {true, result};
}
QString TextDecoder::decodeUnchecked(const QByteArray &text)
{
if (!isValid())
return QString();
#if QT_VERSION_MAJOR >= 6
QString result = mDecoder(text);
if (mDecoder.hasError())
mDecoder.resetState();
return result;
#else
return mCodec->toUnicode(text);
#endif
}
TextDecoder TextDecoder::decoderForUtf8()
{
#if QT_VERSION_MAJOR >= 6
return QStringDecoder(QStringConverter::Utf8, QStringConverter::Flag::Stateless);
#else
return TextDecoder(ENCODING_UTF8);
#endif
}
TextDecoder TextDecoder::decoderForUtf16()
{
#if QT_VERSION_MAJOR >= 6
return QStringDecoder(QStringConverter::Utf16, QStringConverter::Flag::Stateless);
#else
return TextDecoder(ENCODING_UTF16);
#endif
}
TextDecoder TextDecoder::decoderForUtf32()
{
#if QT_VERSION_MAJOR >= 6
return QStringDecoder(QStringConverter::Utf32, QStringConverter::Flag::Stateless);
#else
return TextDecoder(ENCODING_UTF32);
#endif
}
TextDecoder TextDecoder::decoderForSystem()
{
#ifdef Q_OS_WIN
# if QT_VERSION_MAJOR >= 6
return QStringDecoder(QStringConverter::System, QStringConverter::Flag::Stateless);
# else
return TextDecoder(ENCODING_SYSTEM_DEFAULT);
# endif
#else
return decoderForUtf8();
#endif
}
const QStringList &availableEncodings() {
static bool initialized = false;
static QStringList encodings;
if (initialized)
return encodings;
#if QT_VERSION_MAJOR >= 6
for (const QString &name : QStringConverter::availableCodecs()) {
QString lname = name.toLower();
if (lname.startsWith("cp"))
continue;
if (lname == "locale" || lname == "utf-8")
continue;
encodings.append(name);
}
#else
QSet<QByteArray> codecAlias = {"system", "utf-8"};
for (const QByteArray &name : QTextCodec::availableCodecs()) {
QByteArray lname = name.toLower();
if (lname.startsWith("cp"))
continue;
if (codecAlias.contains(lname))
continue;
encodings.append(name);
codecAlias.insert(lname);
QTextCodec *codec = QTextCodec::codecForName(name);
if (codec != nullptr) {
for (const QByteArray &alias : codec->aliases())
codecAlias.insert(alias.toLower());
}
}
#endif
std::sort(encodings.begin(), encodings.end());
initialized = true;
return encodings;
}
bool isEncodingAvailable(const QByteArray &encoding)
{
TextEncoder encoder(encoding);
return encoder.isValid();
}

View File

@ -26,9 +26,15 @@
#include <QThread>
#include <QProcessEnvironment>
#if QT_VERSION_MAJOR >= 6
# include <QStringEncoder>
# include <QStringDecoder>
#else
class QTextCodec;
#endif
class QByteArray;
class QTextStream;
class QTextCodec;
#define ENCODING_AUTO_DETECT "AUTO"
#define ENCODING_UTF8 "UTF-8"
@ -67,7 +73,7 @@ public:
};
/* text processing utils */
const QByteArray guessTextEncoding(const QByteArray& text);
QString guessTextEncoding(const QByteArray& text);
const QChar *getNullTerminatedStringData(const QString& str);
@ -109,9 +115,7 @@ void readStreamToLines(QTextStream* stream, LineProcessFunc lineFunc);
* @param codec
* @return
*/
QStringList readFileToLines(const QString& fileName, QTextCodec* codec);
QStringList readFileToLines(const QString& fileName);
void readFileToLines(const QString& fileName, QTextCodec* codec, LineProcessFunc lineFunc);
QByteArray readFileToByteArray(const QString& fileName);
@ -204,4 +208,108 @@ finally(F&& f) noexcept
return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
std::forward<F>(f));
}
class TextEncoder {
public:
explicit TextEncoder(const char *name);
explicit TextEncoder(const QByteArray &name);
TextEncoder(const TextEncoder &other) = delete;
TextEncoder(TextEncoder &&other) noexcept = default;
TextEncoder &operator=(const TextEncoder &other) = delete;
TextEncoder &operator=(TextEncoder &&other) noexcept = default;
~TextEncoder() = default;
#if QT_VERSION_MAJOR >= 6
private:
TextEncoder(QStringEncoder &&encoder);
#endif
public:
bool isValid() const;
QByteArray name() const;
std::pair<bool, QByteArray> encode(const QString &text);
QByteArray encodeUnchecked(const QString &text);
public:
static TextEncoder encoderForUtf8();
static TextEncoder encoderForUtf16();
static TextEncoder encoderForUtf32();
static TextEncoder encoderForSystem();
private:
#if QT_VERSION_MAJOR >= 6
QStringEncoder mEncoder;
#else
QTextCodec *mCodec;
#endif
};
class TextDecoder {
public:
explicit TextDecoder(const char *name);
explicit TextDecoder(const QByteArray &name);
TextDecoder(const TextDecoder &other) = delete;
TextDecoder(TextDecoder &&other) noexcept = default;
TextDecoder &operator=(const TextDecoder &other) = delete;
TextDecoder &operator=(TextDecoder &&other) noexcept = default;
~TextDecoder() = default;
#if QT_VERSION_MAJOR >= 6
private:
TextDecoder(QStringDecoder &&decoder);
#endif
public:
bool isValid() const;
QByteArray name() const;
std::pair<bool, QString> decode(const QByteArray &text);
QString decodeUnchecked(const QByteArray &text);
public:
static TextDecoder decoderForUtf8();
static TextDecoder decoderForUtf16();
static TextDecoder decoderForUtf32();
static TextDecoder decoderForSystem();
private:
#if QT_VERSION_MAJOR >= 6
QStringDecoder mDecoder;
#else
QTextCodec *mCodec;
#endif
};
const QStringList &availableEncodings();
bool isEncodingAvailable(const QByteArray &encoding);
#if QT_VERSION_MAJOR >= 6
namespace std {
constexpr inline int max(int a, qsizetype b) {
return max<int>(a, b);
}
constexpr inline int max(qsizetype a, int b) {
return max<int>(a, b);
}
constexpr inline int min(int a, qsizetype b) {
return min<int>(a, b);
}
constexpr inline int min(qsizetype a, int b) {
return min<int>(a, b);
}
}
#endif
inline bool isAsciiPrint(int c)
{
return c >= 32 && c <= 126;
}
inline bool isLexicalSpace(QChar c)
{
return c.unicode() >= 1 && c.unicode() <= 32;
}
#endif // UTILS_H

View File

@ -11,7 +11,7 @@ pacman -Syu --noconfirm --needed base-devel git
useradd -m builduser
echo 'builduser ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/builduser
echo "MAKEFLAGS=-j$(($(nproc)+1))" >>/etc/makepkg.conf
echo "MAKEFLAGS=-j$(($(nproc)+1))" >>/etc/makepkg.conf.d/jobs.conf
su builduser -c "git config --global --add safe.directory $PWD"
su builduser -c ./packages/archlinux/buildpkg.sh

View File

@ -6,8 +6,8 @@ pkgdesc='A fast, lightweight, open source, and cross platform C++ IDE (developme
arch=('i686' 'pentium4' 'x86_64' 'arm' 'armv6h' 'armv7h' 'aarch64' 'riscv64')
url="https://github.com/royqh1979/$_pkgname"
license=('GPL3')
depends=(qt5-base qt5-svg gcc gdb astyle)
makedepends=(qt5-tools imagemagick librsvg)
depends=(qt6-base qt6-svg gcc gdb astyle)
makedepends=(qt6-tools imagemagick librsvg)
optdepends=(
'clang: C/C++ compiler (alternative)'
)
@ -29,7 +29,7 @@ prepare() {
build() {
mkdir redpanda-build
cd redpanda-build
qmake \
qmake6 \
PREFIX='/usr' \
LIBEXECDIR='/usr/lib' \
"$srcdir/$_pkgname/Red_Panda_CPP.pro"