1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "batchtranslationdialog.h"
5#include "phrase.h"
6#include "messagemodel.h"
7
8#include <QtCore/QMap>
9#include <QtWidgets/QMessageBox>
10#include <QtWidgets/QProgressDialog>
11
12QT_BEGIN_NAMESPACE
13
14CheckableListModel::CheckableListModel(QObject *parent)
15 : QStandardItemModel(parent)
16{
17}
18
19Qt::ItemFlags CheckableListModel::flags(const QModelIndex &index) const
20{
21 Q_UNUSED(index);
22 return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
23}
24
25BatchTranslationDialog::BatchTranslationDialog(MultiDataModel *dataModel, QWidget *w)
26 : QDialog(w), m_model(this), m_dataModel(dataModel)
27{
28 m_ui.setupUi(this);
29 connect(m_ui.runButton, &QAbstractButton::clicked,
30 this, &BatchTranslationDialog::startTranslation);
31 connect(m_ui.moveUpButton, &QAbstractButton::clicked,
32 this, &BatchTranslationDialog::movePhraseBookUp);
33 connect(m_ui.moveDownButton, &QAbstractButton::clicked,
34 this, &BatchTranslationDialog::movePhraseBookDown);
35
36 m_ui.phrasebookList->setModel(&m_model);
37 m_ui.phrasebookList->setSelectionBehavior(QAbstractItemView::SelectItems);
38 m_ui.phrasebookList->setSelectionMode(QAbstractItemView::SingleSelection);
39}
40
41
42void BatchTranslationDialog::setPhraseBooks(const QList<PhraseBook *> &phrasebooks, int modelIndex)
43{
44 QString fn = QFileInfo(m_dataModel->srcFileName(model: modelIndex)).baseName();
45 setWindowTitle(tr(s: "Batch Translation of '%1' - Qt Linguist").arg(a: fn));
46 m_model.clear();
47 m_model.insertColumn(acolumn: 0);
48 m_phrasebooks = phrasebooks;
49 m_modelIndex = modelIndex;
50 int count = phrasebooks.size();
51 m_model.insertRows(row: 0, count);
52 for (int i = 0; i < count; ++i) {
53 QModelIndex idx(m_model.index(row: i, column: 0));
54 m_model.setData(index: idx, value: phrasebooks[i]->friendlyPhraseBookName());
55 int sortOrder;
56 if (phrasebooks[i]->language() != QLocale::C
57 && m_dataModel->language(model: m_modelIndex) != QLocale::C) {
58 if (phrasebooks[i]->language() != m_dataModel->language(model: m_modelIndex))
59 sortOrder = 3;
60 else
61 sortOrder = (phrasebooks[i]->territory()
62 == m_dataModel->model(i: m_modelIndex)->territory()) ? 0 : 1;
63 } else {
64 sortOrder = 2;
65 }
66 m_model.setData(index: idx, value: sortOrder == 3 ? Qt::Unchecked : Qt::Checked, role: Qt::CheckStateRole);
67 m_model.setData(index: idx, value: sortOrder, role: Qt::UserRole + 1);
68 m_model.setData(index: idx, value: i, role: Qt::UserRole);
69 }
70 m_model.setSortRole(Qt::UserRole + 1);
71 m_model.sort(column: 0);
72}
73
74void BatchTranslationDialog::startTranslation()
75{
76 int translatedcount = 0;
77 QCursor oldCursor = cursor();
78 setCursor(Qt::BusyCursor);
79 int messageCount = m_dataModel->messageCount();
80
81 QProgressDialog *dlgProgress;
82 dlgProgress = new QProgressDialog(tr("Searching, please wait..."), tr("&Cancel"), 0, messageCount, this);
83 dlgProgress->show();
84
85 int msgidx = 0;
86 const bool translateTranslated = m_ui.ckTranslateTranslated->isChecked();
87 const bool translateFinished = m_ui.ckTranslateFinished->isChecked();
88 for (MultiDataModelIterator it(m_dataModel, m_modelIndex); it.isValid(); ++it) {
89 if (MessageItem *m = it.current()) {
90 if (!m->isObsolete()
91 && (translateTranslated || m->translation().isEmpty())
92 && (translateFinished || !m->isFinished())) {
93
94 // Go through them in the order the user specified in the phrasebookList
95 for (int b = 0; b < m_model.rowCount(); ++b) {
96 QModelIndex idx(m_model.index(row: b, column: 0));
97 QVariant checkState = m_model.data(index: idx, role: Qt::CheckStateRole);
98 if (checkState == Qt::Checked) {
99 PhraseBook *pb = m_phrasebooks[m_model.data(index: idx, role: Qt::UserRole).toInt()];
100 const auto phrases = pb->phrases();
101 for (const Phrase *ph : phrases) {
102 if (ph->source() == m->text()) {
103 m_dataModel->setTranslation(index: it, translation: ph->target());
104 m_dataModel->setFinished(it, m_ui.ckMarkFinished->isChecked());
105 ++translatedcount;
106 goto done; // break 2;
107 }
108 }
109 }
110 }
111 }
112 }
113 done:
114 ++msgidx;
115 if (!(msgidx & 15))
116 dlgProgress->setValue(msgidx);
117 qApp->processEvents();
118 if (dlgProgress->wasCanceled())
119 break;
120 }
121 dlgProgress->hide();
122
123 setCursor(oldCursor);
124 emit finished();
125 QMessageBox::information(this, tr(s: "Linguist batch translator"),
126 tr(s: "Batch translated %n entries", c: "", n: translatedcount), QMessageBox::Ok);
127}
128
129void BatchTranslationDialog::movePhraseBookUp()
130{
131 QModelIndexList indexes = m_ui.phrasebookList->selectionModel()->selectedIndexes();
132 if (indexes.size() <= 0) return;
133
134 QModelIndex sel = indexes[0];
135 int row = sel.row();
136 if (row > 0) {
137 QModelIndex other = m_model.index(row: row - 1, column: 0);
138 QMap<int, QVariant> seldata = m_model.itemData(index: sel);
139 m_model.setItemData(index: sel, roles: m_model.itemData(index: other));
140 m_model.setItemData(index: other, roles: seldata);
141 m_ui.phrasebookList->selectionModel()->setCurrentIndex(other, QItemSelectionModel::ClearAndSelect);
142 }
143}
144
145void BatchTranslationDialog::movePhraseBookDown()
146{
147 QModelIndexList indexes = m_ui.phrasebookList->selectionModel()->selectedIndexes();
148 if (indexes.size() <= 0) return;
149
150 QModelIndex sel = indexes[0];
151 int row = sel.row();
152 if (row < m_model.rowCount() - 1) {
153 QModelIndex other = m_model.index(row: row + 1, column: 0);
154 QMap<int, QVariant> seldata = m_model.itemData(index: sel);
155 m_model.setItemData(index: sel, roles: m_model.itemData(index: other));
156 m_model.setItemData(index: other, roles: seldata);
157 m_ui.phrasebookList->selectionModel()->setCurrentIndex(other, QItemSelectionModel::ClearAndSelect);
158 }
159}
160
161QT_END_NAMESPACE
162

source code of qttools/src/linguist/linguist/batchtranslationdialog.cpp