mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-28 13:09:42 +00:00
Merge branch 'wizard_encodings' into 'master'
Do not use Qt streams with legacy encodings in the Wizard code Closes #7165 See merge request OpenMW/openmw!2634
This commit is contained in:
commit
1390c7ed7c
5 changed files with 63 additions and 59 deletions
|
@ -5,7 +5,10 @@
|
|||
#include <QRegularExpression>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <components/files/qtconversion.hpp>
|
||||
|
||||
Wizard::IniSettings::IniSettings() {}
|
||||
|
||||
|
@ -25,7 +28,7 @@ QStringList Wizard::IniSettings::findKeys(const QString& text)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool Wizard::IniSettings::readFile(QTextStream& stream)
|
||||
bool Wizard::IniSettings::readFile(std::ifstream& stream, ToUTF8::FromType encoding)
|
||||
{
|
||||
// Look for a square bracket, "'\\["
|
||||
// that has one or more "not nothing" in it, "([^]]+)"
|
||||
|
@ -39,10 +42,20 @@ bool Wizard::IniSettings::readFile(QTextStream& stream)
|
|||
|
||||
QString currentSection;
|
||||
|
||||
while (!stream.atEnd())
|
||||
{
|
||||
const QString line(stream.readLine());
|
||||
ToUTF8::Utf8Encoder encoder(encoding);
|
||||
|
||||
std::string legacyEncLine;
|
||||
while (std::getline(stream, legacyEncLine))
|
||||
{
|
||||
std::string_view lineBuffer = encoder.getUtf8(legacyEncLine);
|
||||
|
||||
// unify Unix-style and Windows file ending
|
||||
if (!(lineBuffer.empty()) && (lineBuffer[lineBuffer.length() - 1]) == '\r')
|
||||
{
|
||||
lineBuffer = lineBuffer.substr(0, lineBuffer.length() - 1);
|
||||
}
|
||||
|
||||
const QString line = QString::fromStdString(std::string(lineBuffer));
|
||||
if (line.isEmpty() || line.startsWith(QLatin1Char(';')))
|
||||
continue;
|
||||
|
||||
|
@ -70,7 +83,7 @@ bool Wizard::IniSettings::readFile(QTextStream& stream)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Wizard::IniSettings::writeFile(const QString& path, QTextStream& stream)
|
||||
bool Wizard::IniSettings::writeFile(const QString& path, std::ifstream& stream, ToUTF8::FromType encoding)
|
||||
{
|
||||
// Look for a square bracket, "'\\["
|
||||
// that has one or more "not nothing" in it, "([^]]+)"
|
||||
|
@ -87,10 +100,19 @@ bool Wizard::IniSettings::writeFile(const QString& path, QTextStream& stream)
|
|||
QString currentSection;
|
||||
QString buffer;
|
||||
|
||||
while (!stream.atEnd())
|
||||
{
|
||||
const QString line(stream.readLine());
|
||||
ToUTF8::Utf8Encoder encoder(encoding);
|
||||
|
||||
std::string legacyEncLine;
|
||||
while (std::getline(stream, legacyEncLine))
|
||||
{
|
||||
std::string_view lineBuffer = encoder.getUtf8(legacyEncLine);
|
||||
// unify Unix-style and Windows file ending
|
||||
if (!(lineBuffer.empty()) && (lineBuffer[lineBuffer.length() - 1]) == '\r')
|
||||
{
|
||||
lineBuffer = lineBuffer.substr(0, lineBuffer.length() - 1);
|
||||
}
|
||||
|
||||
const QString line = QString::fromStdString(std::string(lineBuffer));
|
||||
if (line.isEmpty() || line.startsWith(QLatin1Char(';')))
|
||||
{
|
||||
buffer.append(line + QLatin1String("\n"));
|
||||
|
@ -158,27 +180,13 @@ bool Wizard::IniSettings::writeFile(const QString& path, QTextStream& stream)
|
|||
}
|
||||
}
|
||||
|
||||
// Now we reopen the file, this time we write
|
||||
QFile file(path);
|
||||
|
||||
if (file.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text))
|
||||
{
|
||||
QTextStream in(&file);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
in.setCodec(stream.codec());
|
||||
#else
|
||||
in.setEncoding(stream.encoding());
|
||||
#endif
|
||||
|
||||
// Write the updated buffer to an empty file
|
||||
in << buffer;
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto iniPath = Files::pathFromQString(path);
|
||||
std::ofstream file(iniPath, std::ios::out);
|
||||
if (file.fail())
|
||||
return false;
|
||||
}
|
||||
|
||||
file << encoder.getLegacyEnc(buffer.toStdString());
|
||||
file.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <QHash>
|
||||
#include <QVariant>
|
||||
|
||||
class QTextStream;
|
||||
#include <components/to_utf8/to_utf8.hpp>
|
||||
|
||||
namespace Wizard
|
||||
{
|
||||
|
@ -30,8 +30,8 @@ namespace Wizard
|
|||
|
||||
QStringList findKeys(const QString& text);
|
||||
|
||||
bool readFile(QTextStream& stream);
|
||||
bool writeFile(const QString& path, QTextStream& stream);
|
||||
bool readFile(std::ifstream& stream, ToUTF8::FromType encoding);
|
||||
bool writeFile(const QString& path, std::ifstream& stream, ToUTF8::FromType encoding);
|
||||
|
||||
bool parseInx(const QString& path);
|
||||
|
||||
|
|
|
@ -128,15 +128,15 @@ void Wizard::InstallationPage::startInstallation()
|
|||
|
||||
if (language == QLatin1String("Polish"))
|
||||
{
|
||||
mUnshield->setIniCodec(QTextCodec::codecForName("windows-1250"));
|
||||
mUnshield->setIniEncoding(ToUTF8::FromType::WINDOWS_1250);
|
||||
}
|
||||
else if (language == QLatin1String("Russian"))
|
||||
{
|
||||
mUnshield->setIniCodec(QTextCodec::codecForName("windows-1251"));
|
||||
mUnshield->setIniEncoding(ToUTF8::FromType::WINDOWS_1251);
|
||||
}
|
||||
else
|
||||
{
|
||||
mUnshield->setIniCodec(QTextCodec::codecForName("windows-1252"));
|
||||
mUnshield->setIniEncoding(ToUTF8::FromType::WINDOWS_1252);
|
||||
}
|
||||
|
||||
mThread->start();
|
||||
|
|
|
@ -6,8 +6,10 @@
|
|||
#include <QFileInfo>
|
||||
#include <QReadLocker>
|
||||
#include <QStringList>
|
||||
#include <QTextCodec>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <components/files/qtconversion.hpp>
|
||||
|
||||
#include <apps/wizard/inisettings.hpp>
|
||||
|
||||
|
@ -23,7 +25,7 @@ Wizard::UnshieldWorker::UnshieldWorker(qint64 expectedMorrowindBsaSize, QObject*
|
|||
mDiskPath = QString();
|
||||
|
||||
// Default to Latin encoding
|
||||
mIniCodec = QTextCodec::codecForName("windows-1252");
|
||||
mIniEncoding = ToUTF8::FromType::WINDOWS_1252;
|
||||
|
||||
mInstallMorrowind = false;
|
||||
mInstallTribunal = false;
|
||||
|
@ -153,10 +155,10 @@ QString Wizard::UnshieldWorker::getDiskPath()
|
|||
return mDiskPath;
|
||||
}
|
||||
|
||||
void Wizard::UnshieldWorker::setIniCodec(QTextCodec* codec)
|
||||
void Wizard::UnshieldWorker::setIniEncoding(ToUTF8::FromType encoding)
|
||||
{
|
||||
QWriteLocker writeLock(&mLock);
|
||||
mIniCodec = codec;
|
||||
mIniEncoding = encoding;
|
||||
}
|
||||
|
||||
void Wizard::UnshieldWorker::wakeAll()
|
||||
|
@ -170,19 +172,16 @@ bool Wizard::UnshieldWorker::setupSettings()
|
|||
if (getIniPath().isEmpty())
|
||||
return false;
|
||||
|
||||
QFile file(getIniPath());
|
||||
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
const auto iniPath = Files::pathFromQString(getIniPath());
|
||||
std::ifstream file(iniPath);
|
||||
if (file.fail())
|
||||
{
|
||||
emit error(tr("Failed to open Morrowind configuration file!"),
|
||||
tr("Opening %1 failed: %2.").arg(getIniPath(), file.errorString()));
|
||||
tr("Opening %1 failed: %2.").arg(getIniPath(), strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
stream.setCodec(mIniCodec);
|
||||
|
||||
mIniSettings.readFile(stream);
|
||||
mIniSettings.readFile(file, mIniEncoding);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -192,22 +191,19 @@ bool Wizard::UnshieldWorker::writeSettings()
|
|||
if (getIniPath().isEmpty())
|
||||
return false;
|
||||
|
||||
QFile file(getIniPath());
|
||||
|
||||
if (!file.open(QIODevice::ReadWrite | QIODevice::Text))
|
||||
const auto iniPath = Files::pathFromQString(getIniPath());
|
||||
std::ifstream file(iniPath);
|
||||
if (file.fail())
|
||||
{
|
||||
emit error(tr("Failed to open Morrowind configuration file!"),
|
||||
tr("Opening %1 failed: %2.").arg(getIniPath(), file.errorString()));
|
||||
tr("Opening %1 failed: %2.").arg(getIniPath(), strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
stream.setCodec(mIniCodec);
|
||||
|
||||
if (!mIniSettings.writeFile(getIniPath(), stream))
|
||||
if (!mIniSettings.writeFile(getIniPath(), file, mIniEncoding))
|
||||
{
|
||||
emit error(tr("Failed to write Morrowind configuration file!"),
|
||||
tr("Writing to %1 failed: %2.").arg(getIniPath(), file.errorString()));
|
||||
tr("Writing to %1 failed: %2.").arg(getIniPath(), strerror(errno)));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace Wizard
|
|||
QString getPath();
|
||||
QString getIniPath();
|
||||
|
||||
void setIniCodec(QTextCodec* codec);
|
||||
void setIniEncoding(ToUTF8::FromType encoding);
|
||||
|
||||
bool setupSettings();
|
||||
|
||||
|
@ -104,7 +104,7 @@ namespace Wizard
|
|||
|
||||
IniSettings mIniSettings;
|
||||
|
||||
QTextCodec* mIniCodec;
|
||||
ToUTF8::FromType mIniEncoding;
|
||||
|
||||
QWaitCondition mWait;
|
||||
|
||||
|
|
Loading…
Reference in a new issue