Verbessere die Benutzeroberfläche und die Leistung beim Laden von Übersetzungen mit Fortschrittsanzeigen und Fehlerbehandlung
This commit is contained in:
125
mainwindow.cpp
125
mainwindow.cpp
@@ -17,6 +17,8 @@
|
||||
#include <QDialogButtonBox>
|
||||
#include <QInputDialog>
|
||||
#include <QClipboard>
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
@@ -26,8 +28,10 @@
|
||||
#include <QMenu>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QProgressDialog>
|
||||
#include <QScrollArea>
|
||||
#include <QSet>
|
||||
#include <QSignalBlocker>
|
||||
#include <QScrollBar>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@@ -168,10 +172,27 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
on_translationProviderCombo_currentIndexChanged(ui->translationProviderCombo->currentIndex());
|
||||
if (configuration.contains("last-dir") && (QDir()).exists(configuration["last-dir"].toString())) {
|
||||
ui->projectDir->setText(configuration["last-dir"].toString());
|
||||
crawlProject();
|
||||
if (configuration.contains("last-language") && ui->languageCombo->findText(configuration["last-language"].toString()) >= 0) {
|
||||
ui->languageCombo->setCurrentText(configuration["last-language"].toString());
|
||||
}
|
||||
// Let the main window become visible before scanning potentially large projects.
|
||||
QTimer::singleShot(0, this, [this] {
|
||||
const QString savedLanguage = configuration.value("last-language").toString();
|
||||
QProgressDialog startupProgress(tr("Projekt wird vorbereitet …"), QString(), 0, 2, this);
|
||||
startupProgress.setWindowTitle(tr("Bitte warten"));
|
||||
startupProgress.setCancelButton(nullptr);
|
||||
startupProgress.setMinimumDuration(0);
|
||||
startupProgress.setWindowModality(Qt::ApplicationModal);
|
||||
startupProgress.show();
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
crawlProject();
|
||||
startupProgress.setValue(1);
|
||||
startupProgress.setLabelText(tr("Letzte Sprache und Übersetzungsdateien werden geladen …"));
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
if (!savedLanguage.isEmpty() && ui->languageCombo->findText(savedLanguage) >= 0) {
|
||||
const QSignalBlocker blockLanguageSelection(ui->languageCombo);
|
||||
ui->languageCombo->setCurrentText(savedLanguage);
|
||||
on_languageCombo_currentTextChanged(savedLanguage);
|
||||
}
|
||||
startupProgress.setValue(2);
|
||||
});
|
||||
}
|
||||
noConfigChange = false;
|
||||
}
|
||||
@@ -270,6 +291,7 @@ void MainWindow::crawlProject() {
|
||||
QMessageBox::information(this, tr("Information"), tr("No translations available."));
|
||||
return;
|
||||
}
|
||||
const QSignalBlocker blockLanguageSelection(ui->languageCombo);
|
||||
ui->languageCombo->clear();
|
||||
ui->languageCombo->addItems(languageDirs);
|
||||
ui->languageCombo->setCurrentIndex(-1);
|
||||
@@ -286,17 +308,39 @@ void MainWindow::on_languageCombo_currentTextChanged(const QString &selectedLang
|
||||
QString projectDir = ui->projectDir->text();
|
||||
QString languageDirPath = QDir::cleanPath(projectDir + QDir::separator() + "game" + QDir::separator() + "tl" + QDir::separator() + selectedLanguage);
|
||||
QDirIterator it(languageDirPath, QStringList() << "*.rpy", QDir::Files, QDirIterator::Subdirectories);
|
||||
QStringList filePaths;
|
||||
while (it.hasNext()) {
|
||||
QString filePath = it.next();
|
||||
filePaths.append(it.next());
|
||||
}
|
||||
|
||||
QProgressDialog progress(tr("Übersetzungsdateien werden geladen …"), QString(), 0, filePaths.size(), this);
|
||||
progress.setWindowTitle(tr("Bitte warten"));
|
||||
progress.setCancelButton(nullptr);
|
||||
progress.setMinimumDuration(0);
|
||||
progress.setWindowModality(Qt::ApplicationModal);
|
||||
progress.show();
|
||||
QApplication::setOverrideCursor(Qt::WaitCursor);
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
|
||||
for (int fileIndex = 0; fileIndex < filePaths.size(); ++fileIndex) {
|
||||
const QString &filePath = filePaths.at(fileIndex);
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
progress.setValue(fileIndex + 1);
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
continue;
|
||||
}
|
||||
QTextStream in(&file);
|
||||
QString fileContent = in.readAll();
|
||||
file.close();
|
||||
fileContentsMap[filePath] = fileContent;
|
||||
populateTreeWidgetFromMap();
|
||||
progress.setValue(fileIndex + 1);
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
}
|
||||
progress.setLabelText(tr("Übersetzungsliste wird vorbereitet …"));
|
||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
populateTreeWidgetFromMap();
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
void MainWindow::populateTreeWidgetFromMap() {
|
||||
@@ -344,22 +388,23 @@ QVector<MainWindow::TranslationItem> MainWindow::parseTextBlock(const QString& i
|
||||
lineNumber = match.captured(1).toInt();
|
||||
}
|
||||
} else if (line.startsWith(" # ") || line.startsWith(" old ")) {
|
||||
originalText = line.mid(line.indexOf("\"") + 1).trimmed();
|
||||
originalText.chop(1);
|
||||
const int firstQuote = line.indexOf('"');
|
||||
const int lastQuote = line.lastIndexOf('"');
|
||||
originalText = firstQuote >= 0 && lastQuote > firstQuote
|
||||
? line.mid(firstQuote + 1, lastQuote - firstQuote - 1)
|
||||
: QString();
|
||||
identifier = "";
|
||||
} else if ((line.startsWith(" ") && !line.startsWith(" # ")) || line.startsWith(" new ")) {
|
||||
translatedText = line.mid(4).trimmed();
|
||||
if (translatedText.startsWith("new \"")) {
|
||||
translatedText = translatedText.mid(5).trimmed();
|
||||
} else if (translatedText.startsWith("\"")) {
|
||||
translatedText = translatedText.mid(1).trimmed();
|
||||
} else {
|
||||
int firstQuoteIndex = translatedText.indexOf("\"");
|
||||
int lastQuoteIndex = translatedText.lastIndexOf("\"");
|
||||
identifier = translatedText.mid(0, firstQuoteIndex).trimmed();
|
||||
translatedText = translatedText.mid(firstQuoteIndex + 1, lastQuoteIndex - firstQuoteIndex).trimmed();
|
||||
const QString translationLine = line.startsWith(" ") ? line.mid(4) : line;
|
||||
const int firstQuote = translationLine.indexOf('"');
|
||||
const int lastQuote = translationLine.lastIndexOf('"');
|
||||
if (firstQuote < 0 || lastQuote <= firstQuote) {
|
||||
continue;
|
||||
}
|
||||
translatedText.chop(1);
|
||||
identifier = translationLine.startsWith("new ") || translationLine.startsWith('"')
|
||||
? QString()
|
||||
: translationLine.left(firstQuote).trimmed();
|
||||
translatedText = translationLine.mid(firstQuote + 1, lastQuote - firstQuote - 1);
|
||||
blocks.append(TranslationItem(lineNumber, identifier, originalText, translatedText));
|
||||
originalText.clear();
|
||||
translatedText.clear();
|
||||
@@ -382,7 +427,25 @@ void MainWindow::on_reloadTranslationsButton_clicked()
|
||||
|
||||
void MainWindow::on_reloadFilesButton_clicked()
|
||||
{
|
||||
populateTreeWidgetFromMap();
|
||||
if (ui->languageCombo->currentIndex() < 0) {
|
||||
return;
|
||||
}
|
||||
bool hasUnsavedChanges = false;
|
||||
for (int index = 0; index < ui->treeWidget->topLevelItemCount(); ++index) {
|
||||
if (ui->treeWidget->topLevelItem(index)->data(0, Qt::UserRole).toBool()) {
|
||||
hasUnsavedChanges = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasUnsavedChanges && QMessageBox::warning(
|
||||
this,
|
||||
tr("Ungespeicherte Änderungen"),
|
||||
tr("Durch das Neuladen werden ungespeicherte Änderungen verworfen. Fortfahren?"),
|
||||
QMessageBox::Yes | QMessageBox::Cancel,
|
||||
QMessageBox::Cancel) != QMessageBox::Yes) {
|
||||
return;
|
||||
}
|
||||
on_languageCombo_currentTextChanged(ui->languageCombo->currentText());
|
||||
}
|
||||
|
||||
void MainWindow::on_nextUntranslatedButton_clicked() {
|
||||
@@ -563,7 +626,9 @@ bool MainWindow::parseAndEditFile(QFile &backupFile, QTreeWidgetItem *fileItem,
|
||||
QString replacement = QString("\"%1\"").arg(replacedText.isEmpty() ? newText : replacedText);
|
||||
auto replacedBlock = block.replace(toReplace, replacement);
|
||||
content.replace(match.capturedStart(0), match.capturedLength(0), replacedBlock);
|
||||
offset = match.capturedEnd(0);
|
||||
// The replacement can have a different length. Continue after the new
|
||||
// block, otherwise later translations in this file may be skipped.
|
||||
offset = match.capturedStart(0) + replacedBlock.size();
|
||||
changed = true;
|
||||
}
|
||||
offset = 0;
|
||||
@@ -577,7 +642,7 @@ bool MainWindow::parseAndEditFile(QFile &backupFile, QTreeWidgetItem *fileItem,
|
||||
QString replacement = QString("\"%1\"").arg(replacedText.isEmpty() ? newText : replacedText);
|
||||
auto replacedBlock = block.replace(toReplace, replacement);
|
||||
content.replace(match.capturedStart(0), match.capturedLength(0), replacedBlock);
|
||||
offset = match.capturedEnd(0);
|
||||
offset = match.capturedStart(0) + replacedBlock.size();
|
||||
changed = true;
|
||||
}
|
||||
lines.append(content.split("\n"));
|
||||
@@ -988,6 +1053,7 @@ void MainWindow::showBulkTranslationDialog()
|
||||
const bool dialogUsesLibreTranslate = bulkUsesLibreTranslate;
|
||||
const QString dialogSourceLanguage = ui->deeplTranslateFrom->currentText();
|
||||
const QString dialogTargetLanguage = ui->deeplTranslateTo->currentText();
|
||||
QSet<QTreeWidgetItem *> savedBulkFiles;
|
||||
edits.reserve(bulkTranslations.size());
|
||||
QTreeWidgetItem *currentFile = nullptr;
|
||||
QVBoxLayout *fileLayout = nullptr;
|
||||
@@ -1086,9 +1152,12 @@ void MainWindow::showBulkTranslationDialog()
|
||||
scrollArea->setWidget(content);
|
||||
layout->addWidget(scrollArea);
|
||||
|
||||
auto applyTranslations = [this, &edits] {
|
||||
auto applyTranslations = [this, &edits, &savedBulkFiles] {
|
||||
for (int index = 0; index < bulkTranslations.size(); ++index) {
|
||||
QTreeWidgetItem *item = bulkTranslations[index].item;
|
||||
if (savedBulkFiles.contains(item->parent())) {
|
||||
continue;
|
||||
}
|
||||
item->setText(3, edits[index]->toPlainText());
|
||||
if (QTreeWidgetItem *parent = item->parent()) {
|
||||
parent->setData(0, Qt::UserRole, true);
|
||||
@@ -1100,7 +1169,7 @@ void MainWindow::showBulkTranslationDialog()
|
||||
int currentFileSection = 0;
|
||||
QSet<QTreeWidgetItem *> promptedFiles;
|
||||
connect(scrollArea->verticalScrollBar(), &QScrollBar::valueChanged, &dialog,
|
||||
[this, &fileSections, ¤tFileSection, &promptedFiles, applyTranslations](int scrollPosition) {
|
||||
[this, &fileSections, ¤tFileSection, &promptedFiles, &savedBulkFiles, applyTranslations](int scrollPosition) {
|
||||
int visibleFileSection = currentFileSection;
|
||||
for (int index = 0; index < fileSections.size(); ++index) {
|
||||
if (fileSections[index].first->y() <= scrollPosition + 12) {
|
||||
@@ -1113,7 +1182,8 @@ void MainWindow::showBulkTranslationDialog()
|
||||
return;
|
||||
}
|
||||
|
||||
QTreeWidgetItem *completedFile = fileSections[currentFileSection].second;
|
||||
const int completedFileSection = currentFileSection;
|
||||
QTreeWidgetItem *completedFile = fileSections[completedFileSection].second;
|
||||
currentFileSection = visibleFileSection;
|
||||
if (promptedFiles.contains(completedFile)) {
|
||||
return;
|
||||
@@ -1131,6 +1201,9 @@ void MainWindow::showBulkTranslationDialog()
|
||||
QString errorMessage;
|
||||
if (!saveFile(completedFile, errorMessage)) {
|
||||
QMessageBox::critical(this, tr("Error"), errorMessage);
|
||||
} else {
|
||||
savedBulkFiles.insert(completedFile);
|
||||
fileSections[completedFileSection].first->hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user