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 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | CheckableListModel::CheckableListModel(QObject *parent) |
15 | : QStandardItemModel(parent) |
16 | { |
17 | } |
18 | |
19 | Qt::ItemFlags CheckableListModel::flags(const QModelIndex &index) const |
20 | { |
21 | Q_UNUSED(index); |
22 | return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; |
23 | } |
24 | |
25 | BatchTranslationDialog::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 | |
42 | void 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 | |
74 | void 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 | |
129 | void 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 | |
145 | void 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 | |
161 | QT_END_NAMESPACE |
162 | |