1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Qt Linguist of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include "batchtranslationdialog.h" |
30 | #include "phrase.h" |
31 | #include "messagemodel.h" |
32 | |
33 | #include <QtWidgets/QMessageBox> |
34 | #include <QtWidgets/QProgressDialog> |
35 | |
36 | QT_BEGIN_NAMESPACE |
37 | |
38 | CheckableListModel::CheckableListModel(QObject *parent) |
39 | : QStandardItemModel(parent) |
40 | { |
41 | } |
42 | |
43 | Qt::ItemFlags CheckableListModel::flags(const QModelIndex &index) const |
44 | { |
45 | Q_UNUSED(index); |
46 | return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; |
47 | } |
48 | |
49 | BatchTranslationDialog::BatchTranslationDialog(MultiDataModel *dataModel, QWidget *w) |
50 | : QDialog(w), m_model(this), m_dataModel(dataModel) |
51 | { |
52 | m_ui.setupUi(this); |
53 | connect(sender: m_ui.runButton, SIGNAL(clicked()), receiver: this, SLOT(startTranslation())); |
54 | connect(sender: m_ui.moveUpButton, SIGNAL(clicked()), receiver: this, SLOT(movePhraseBookUp())); |
55 | connect(sender: m_ui.moveDownButton, SIGNAL(clicked()), receiver: this, SLOT(movePhraseBookDown())); |
56 | |
57 | m_ui.phrasebookList->setModel(&m_model); |
58 | m_ui.phrasebookList->setSelectionBehavior(QAbstractItemView::SelectItems); |
59 | m_ui.phrasebookList->setSelectionMode(QAbstractItemView::SingleSelection); |
60 | } |
61 | |
62 | |
63 | void BatchTranslationDialog::setPhraseBooks(const QList<PhraseBook *> &phrasebooks, int modelIndex) |
64 | { |
65 | QString fn = QFileInfo(m_dataModel->srcFileName(model: modelIndex)).baseName(); |
66 | setWindowTitle(tr(s: "Batch Translation of '%1' - Qt Linguist" ).arg(a: fn)); |
67 | m_model.clear(); |
68 | m_model.insertColumn(acolumn: 0); |
69 | m_phrasebooks = phrasebooks; |
70 | m_modelIndex = modelIndex; |
71 | int count = phrasebooks.count(); |
72 | m_model.insertRows(row: 0, count); |
73 | for (int i = 0; i < count; ++i) { |
74 | QModelIndex idx(m_model.index(row: i, column: 0)); |
75 | m_model.setData(index: idx, value: phrasebooks[i]->friendlyPhraseBookName()); |
76 | int sortOrder; |
77 | if (phrasebooks[i]->language() != QLocale::C |
78 | && m_dataModel->language(model: m_modelIndex) != QLocale::C) { |
79 | if (phrasebooks[i]->language() != m_dataModel->language(model: m_modelIndex)) |
80 | sortOrder = 3; |
81 | else |
82 | sortOrder = (phrasebooks[i]->country() |
83 | == m_dataModel->model(i: m_modelIndex)->country()) ? 0 : 1; |
84 | } else { |
85 | sortOrder = 2; |
86 | } |
87 | m_model.setData(index: idx, value: sortOrder == 3 ? Qt::Unchecked : Qt::Checked, role: Qt::CheckStateRole); |
88 | m_model.setData(index: idx, value: sortOrder, role: Qt::UserRole + 1); |
89 | m_model.setData(index: idx, value: i, role: Qt::UserRole); |
90 | } |
91 | m_model.setSortRole(Qt::UserRole + 1); |
92 | m_model.sort(column: 0); |
93 | } |
94 | |
95 | void BatchTranslationDialog::startTranslation() |
96 | { |
97 | int translatedcount = 0; |
98 | QCursor oldCursor = cursor(); |
99 | setCursor(Qt::BusyCursor); |
100 | int messageCount = m_dataModel->messageCount(); |
101 | |
102 | QProgressDialog *dlgProgress; |
103 | dlgProgress = new QProgressDialog(tr(s: "Searching, please wait..." ), tr(s: "&Cancel" ), 0, messageCount, this); |
104 | dlgProgress->show(); |
105 | |
106 | int msgidx = 0; |
107 | const bool translateTranslated = m_ui.ckTranslateTranslated->isChecked(); |
108 | const bool translateFinished = m_ui.ckTranslateFinished->isChecked(); |
109 | for (MultiDataModelIterator it(m_dataModel, m_modelIndex); it.isValid(); ++it) { |
110 | if (MessageItem *m = it.current()) { |
111 | if (!m->isObsolete() |
112 | && (translateTranslated || m->translation().isEmpty()) |
113 | && (translateFinished || !m->isFinished())) { |
114 | |
115 | // Go through them in the order the user specified in the phrasebookList |
116 | for (int b = 0; b < m_model.rowCount(); ++b) { |
117 | QModelIndex idx(m_model.index(row: b, column: 0)); |
118 | QVariant checkState = m_model.data(index: idx, role: Qt::CheckStateRole); |
119 | if (checkState == Qt::Checked) { |
120 | PhraseBook *pb = m_phrasebooks[m_model.data(index: idx, role: Qt::UserRole).toInt()]; |
121 | foreach (const Phrase *ph, pb->phrases()) { |
122 | if (ph->source() == m->text()) { |
123 | m_dataModel->setTranslation(index: it, translation: ph->target()); |
124 | m_dataModel->setFinished(index: it, finished: m_ui.ckMarkFinished->isChecked()); |
125 | ++translatedcount; |
126 | goto done; // break 2; |
127 | } |
128 | } |
129 | } |
130 | } |
131 | } |
132 | } |
133 | done: |
134 | ++msgidx; |
135 | if (!(msgidx & 15)) |
136 | dlgProgress->setValue(msgidx); |
137 | qApp->processEvents(); |
138 | if (dlgProgress->wasCanceled()) |
139 | break; |
140 | } |
141 | dlgProgress->hide(); |
142 | |
143 | setCursor(oldCursor); |
144 | emit finished(); |
145 | QMessageBox::information(parent: this, title: tr(s: "Linguist batch translator" ), |
146 | text: tr(s: "Batch translated %n entries" , c: "" , n: translatedcount), button0: QMessageBox::Ok); |
147 | } |
148 | |
149 | void BatchTranslationDialog::movePhraseBookUp() |
150 | { |
151 | QModelIndexList indexes = m_ui.phrasebookList->selectionModel()->selectedIndexes(); |
152 | if (indexes.count() <= 0) return; |
153 | |
154 | QModelIndex sel = indexes[0]; |
155 | int row = sel.row(); |
156 | if (row > 0) { |
157 | QModelIndex other = m_model.index(row: row - 1, column: 0); |
158 | QMap<int, QVariant> seldata = m_model.itemData(index: sel); |
159 | m_model.setItemData(index: sel, roles: m_model.itemData(index: other)); |
160 | m_model.setItemData(index: other, roles: seldata); |
161 | m_ui.phrasebookList->selectionModel()->setCurrentIndex(index: other, command: QItemSelectionModel::ClearAndSelect); |
162 | } |
163 | } |
164 | |
165 | void BatchTranslationDialog::movePhraseBookDown() |
166 | { |
167 | QModelIndexList indexes = m_ui.phrasebookList->selectionModel()->selectedIndexes(); |
168 | if (indexes.count() <= 0) return; |
169 | |
170 | QModelIndex sel = indexes[0]; |
171 | int row = sel.row(); |
172 | if (row < m_model.rowCount() - 1) { |
173 | QModelIndex other = m_model.index(row: row + 1, column: 0); |
174 | QMap<int, QVariant> seldata = m_model.itemData(index: sel); |
175 | m_model.setItemData(index: sel, roles: m_model.itemData(index: other)); |
176 | m_model.setItemData(index: other, roles: seldata); |
177 | m_ui.phrasebookList->selectionModel()->setCurrentIndex(index: other, command: QItemSelectionModel::ClearAndSelect); |
178 | } |
179 | } |
180 | |
181 | QT_END_NAMESPACE |
182 | |