- fix: Save may crash app if the encoding codec is failed to load.
- enhancement: support open and save utf-16/utf-32 BOM files. (but gcc can't compile)
This commit is contained in:
parent
d8fae209c6
commit
6072944c23
2
NEWS.md
2
NEWS.md
|
@ -2,6 +2,8 @@ Red Panda C++ Version 2.9
|
|||
|
||||
- enhancement: set caret to the corresponding line in the editor after "run"/"generate assembly"
|
||||
- fix: syntax highlighting for cpp style line comment is not correct.
|
||||
- fix: Save may crash app if the encoding codec is failed to load.
|
||||
- enhancement: support open and save utf-16/utf-32 BOM files. (but gcc can't compile)
|
||||
|
||||
Red Panda C++ Version 2.8
|
||||
|
||||
|
|
|
@ -350,6 +350,10 @@ QString Compiler::getCharsetArgument(const QByteArray& encoding,FileType fileTyp
|
|||
encodingName = systemEncodingName;
|
||||
} else if (encoding == ENCODING_UTF8_BOM) {
|
||||
encodingName = "UTF-8";
|
||||
} else if (encoding == ENCODING_UTF16_BOM) {
|
||||
encodingName = "UTF-16";
|
||||
} else if (encoding == ENCODING_UTF32_BOM) {
|
||||
encodingName = "UTF-32";
|
||||
} else {
|
||||
encodingName = encoding;
|
||||
}
|
||||
|
|
|
@ -410,6 +410,10 @@ void ProjectCompiler::writeMakeObjFilesRules(QFile &file)
|
|||
targetEncoding = defaultSystemEncoding;
|
||||
} else if (encoding == ENCODING_UTF8_BOM) {
|
||||
targetEncoding = "UTF-8";
|
||||
} else if (encoding == ENCODING_UTF16_BOM) {
|
||||
targetEncoding = "UTF-16";
|
||||
} else if (encoding == ENCODING_UTF32_BOM) {
|
||||
targetEncoding = "UTF-32";
|
||||
} else {
|
||||
targetEncoding = encoding;
|
||||
}
|
||||
|
|
|
@ -268,6 +268,7 @@ bool Editor::save(bool force, bool doReparse) {
|
|||
QThread::msleep(200);
|
||||
}
|
||||
//is this file writable;
|
||||
|
||||
pMainWindow->fileSystemWatcher()->removePath(mFilename);
|
||||
try {
|
||||
if (pSettings->editor().autoFormatWhenSaved()) {
|
||||
|
|
|
@ -519,6 +519,52 @@ bool Document::tryLoadFileByEncoding(QByteArray encodingName, QFile& file) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Document::loadUTF16BOMFile(QFile &file)
|
||||
{
|
||||
QTextCodec* codec=QTextCodec::codecForName(ENCODING_UTF16);
|
||||
if (!codec)
|
||||
return;
|
||||
file.reset();
|
||||
internalClear();
|
||||
QByteArray buf = file.readAll();
|
||||
if (buf.length()<2)
|
||||
return;
|
||||
QString text = codec->toUnicode(buf.mid(2));
|
||||
this->setText(text);
|
||||
}
|
||||
|
||||
void Document::loadUTF32BOMFile(QFile &file)
|
||||
{
|
||||
QTextCodec* codec=QTextCodec::codecForName(ENCODING_UTF32);
|
||||
if (!codec)
|
||||
return;
|
||||
file.reset();
|
||||
internalClear();
|
||||
QByteArray buf = file.readAll();
|
||||
if (buf.length()<4)
|
||||
return;
|
||||
QString text = codec->toUnicode(buf.mid(4));
|
||||
this->setText(text);
|
||||
}
|
||||
|
||||
void Document::saveUTF16File(QFile &file)
|
||||
{
|
||||
QString text=getTextStr();
|
||||
QTextCodec* codec=QTextCodec::codecForName(ENCODING_UTF16);
|
||||
if (!codec)
|
||||
return;
|
||||
file.write(codec->fromUnicode(text));
|
||||
}
|
||||
|
||||
void Document::saveUTF32File(QFile &file)
|
||||
{
|
||||
QString text=getTextStr();
|
||||
QTextCodec* codec=QTextCodec::codecForName(ENCODING_UTF32);
|
||||
if (!codec)
|
||||
return;
|
||||
file.write(codec->fromUnicode(text));
|
||||
}
|
||||
|
||||
const QFontMetrics &Document::fontMetrics() const
|
||||
{
|
||||
return mFontMetrics;
|
||||
|
@ -568,10 +614,22 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding,
|
|||
realEncoding = ENCODING_UTF8_BOM;
|
||||
line = line.mid(3);
|
||||
codec = QTextCodec::codecForName(ENCODING_UTF8);
|
||||
} 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)) {
|
||||
realEncoding = ENCODING_UTF32_BOM;
|
||||
loadUTF32BOMFile(file);
|
||||
return;
|
||||
} else if ((line.length()>=2) && ((unsigned char)line[0]==0xFF) && ((unsigned char)line[1]==0xFE)) {
|
||||
realEncoding = ENCODING_UTF16_BOM;
|
||||
loadUTF16BOMFile(file);
|
||||
return;
|
||||
} else {
|
||||
realEncoding = ENCODING_UTF8;
|
||||
codec = QTextCodec::codecForName(ENCODING_UTF8);
|
||||
}
|
||||
if (!codec)
|
||||
throw FileError(tr("Can't load codec '%1'!").arg(QString(realEncoding)));
|
||||
if (line.endsWith("\r\n")) {
|
||||
mNewlineType = NewlineType::Windows;
|
||||
} else if (line.endsWith("\n")) {
|
||||
|
@ -579,6 +637,7 @@ void Document::loadFromFile(const QString& filename, const QByteArray& encoding,
|
|||
} else if (line.endsWith("\r")) {
|
||||
mNewlineType = NewlineType::MacOld;
|
||||
}
|
||||
|
||||
internalClear();
|
||||
while (true) {
|
||||
if (line.endsWith("\r\n")) {
|
||||
|
@ -669,37 +728,55 @@ void Document::saveToFile(QFile &file, const QByteArray& encoding,
|
|||
const QByteArray& defaultEncoding, QByteArray& realEncoding)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
QTextCodec* codec;
|
||||
realEncoding = encoding;
|
||||
QString codecName = realEncoding;
|
||||
if (realEncoding == ENCODING_UTF16_BOM || realEncoding == ENCODING_UTF16) {
|
||||
codec = QTextCodec::codecForName(ENCODING_UTF16);
|
||||
codecName = ENCODING_UTF16;
|
||||
} else if (realEncoding == ENCODING_UTF32_BOM || realEncoding == ENCODING_UTF32) {
|
||||
codec = QTextCodec::codecForName(ENCODING_UTF32);
|
||||
codecName = ENCODING_UTF32;
|
||||
} else if (realEncoding == ENCODING_UTF8_BOM) {
|
||||
codec = QTextCodec::codecForName(ENCODING_UTF8);
|
||||
codecName = ENCODING_UTF8;
|
||||
} else if (realEncoding == ENCODING_SYSTEM_DEFAULT) {
|
||||
codec = QTextCodec::codecForLocale();
|
||||
codecName = realEncoding;
|
||||
} else if (realEncoding == ENCODING_AUTO_DETECT) {
|
||||
codec = QTextCodec::codecForName(defaultEncoding);
|
||||
codecName = defaultEncoding;
|
||||
} else {
|
||||
codec = QTextCodec::codecForName(realEncoding);
|
||||
}
|
||||
if (!codec)
|
||||
throw FileError(tr("Can't load codec '%1'!").arg(codecName));
|
||||
|
||||
if (!file.open(QFile::WriteOnly | QFile::Truncate))
|
||||
throw FileError(tr("Can't open file '%1' for save!").arg(file.fileName()));
|
||||
if (mLines.isEmpty())
|
||||
return;
|
||||
QTextCodec* codec;
|
||||
realEncoding = encoding;
|
||||
if (realEncoding == ENCODING_UTF8_BOM) {
|
||||
codec = QTextCodec::codecForName(ENCODING_UTF8);
|
||||
if (realEncoding == ENCODING_UTF16) {
|
||||
saveUTF16File(file);
|
||||
return;
|
||||
} else if (realEncoding == ENCODING_UTF32) {
|
||||
saveUTF32File(file);
|
||||
return;
|
||||
} if (realEncoding == ENCODING_UTF8_BOM) {
|
||||
file.putChar(0xEF);
|
||||
file.putChar(0xBB);
|
||||
file.putChar(0xBF);
|
||||
} else if (realEncoding == ENCODING_SYSTEM_DEFAULT) {
|
||||
codec = QTextCodec::codecForLocale();
|
||||
} else if (realEncoding == ENCODING_AUTO_DETECT) {
|
||||
codec = QTextCodec::codecForName(defaultEncoding);
|
||||
if (!codec)
|
||||
codec = QTextCodec::codecForLocale();
|
||||
} else {
|
||||
codec = QTextCodec::codecForName(realEncoding);
|
||||
}
|
||||
bool allAscii = true;
|
||||
QByteArray data;
|
||||
for (PDocumentLine& line:mLines) {
|
||||
QString text = line->lineText+lineBreak();
|
||||
data = codec->fromUnicode(text);
|
||||
if (allAscii) {
|
||||
allAscii = isTextAllAscii(line->lineText);
|
||||
allAscii = (data==text.toLatin1());
|
||||
}
|
||||
if (!allAscii) {
|
||||
file.write(codec->fromUnicode(line->lineText));
|
||||
} else {
|
||||
file.write(line->lineText.toLatin1());
|
||||
}
|
||||
file.write(lineBreak().toLatin1());
|
||||
if (file.write(data)!=data.size())
|
||||
throw FileError(tr("Data not correctly writed to file '%1'.").arg(file.fileName()));
|
||||
}
|
||||
if (allAscii) {
|
||||
realEncoding = ENCODING_ASCII;
|
||||
|
|
|
@ -134,6 +134,10 @@ protected:
|
|||
void internalClear();
|
||||
private:
|
||||
bool tryLoadFileByEncoding(QByteArray encodingName, QFile& file);
|
||||
void loadUTF16BOMFile(QFile& file);
|
||||
void loadUTF32BOMFile(QFile& file);
|
||||
void saveUTF16File(QFile& file);
|
||||
void saveUTF32File(QFile& file);
|
||||
|
||||
private:
|
||||
DocumentLines mLines;
|
||||
|
|
|
@ -148,7 +148,7 @@ CharsetInfoManager::CharsetInfoManager(const QString& localeName):
|
|||
mCodePages.append(std::make_shared<CharsetInfo>(1147,"IBM01147","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(1148,"IBM01148","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(1149,"IBM01149","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(1200,"utf-16","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(1200,"utf-16",tr("Unicode"),"",true));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(1201,"unicodeFFFE","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(1250,"windows-1250",tr("Central Europe"),"",true));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(1251,"windows-1251",tr("Cyrillic"),"",true));
|
||||
|
@ -176,7 +176,7 @@ CharsetInfoManager::CharsetInfoManager(const QString& localeName):
|
|||
mCodePages.append(std::make_shared<CharsetInfo>(10079,"x-mac-icelandic","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(10081,"x-mac-turkish","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(10082,"x-mac-croatian","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(12000,"utf-32","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(12000,"utf-32",tr("Unicode"),"",true));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(12001,"utf-32BE","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(20000,"x-Chinese_CNS","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(20001,"x-cp20001","","",false));
|
||||
|
@ -259,7 +259,7 @@ CharsetInfoManager::CharsetInfoManager(const QString& localeName):
|
|||
mCodePages.append(std::make_shared<CharsetInfo>(57010,"x-iscii-gu","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(57011,"x-iscii-pa","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(65000,"utf-7","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(65001,"utf-8","","",false));
|
||||
mCodePages.append(std::make_shared<CharsetInfo>(65001,"utf-8",tr("Unicode"),"",true));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ const QByteArray guessTextEncoding(const QByteArray& text){
|
|||
|
||||
bool isTextAllAscii(const QByteArray& text) {
|
||||
for (char c:text) {
|
||||
if (c<0) {
|
||||
if (c<=0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,11 @@ class QTextCodec;
|
|||
|
||||
#define ENCODING_AUTO_DETECT "AUTO"
|
||||
#define ENCODING_UTF8 "UTF-8"
|
||||
#define ENCODING_UTF16 "UTF-16"
|
||||
#define ENCODING_UTF32 "UTF-32"
|
||||
#define ENCODING_UTF8_BOM "UTF-8 BOM"
|
||||
#define ENCODING_UTF16_BOM "UTF-16 BOM"
|
||||
#define ENCODING_UTF32_BOM "UTF-32 BOM"
|
||||
#define ENCODING_SYSTEM_DEFAULT "SYSTEM"
|
||||
#define ENCODING_ASCII "ASCII"
|
||||
|
||||
|
|
Loading…
Reference in New Issue