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 | /* TRANSLATOR PhraseBookBox |
30 | |
31 | Go to Phrase > Edit Phrase Book... The dialog that pops up is a |
32 | PhraseBookBox. |
33 | */ |
34 | |
35 | #include "phrasebookbox.h" |
36 | #include "translationsettingsdialog.h" |
37 | |
38 | #include <QtEvents> |
39 | #include <QLineEdit> |
40 | #include <QMessageBox> |
41 | #include <QHeaderView> |
42 | #include <QSortFilterProxyModel> |
43 | |
44 | QT_BEGIN_NAMESPACE |
45 | |
46 | PhraseBookBox::PhraseBookBox(PhraseBook *phraseBook, QWidget *parent) |
47 | : QDialog(parent), |
48 | m_phraseBook(phraseBook), |
49 | m_translationSettingsDialog(0) |
50 | { |
51 | |
52 | // This definition needs to be within class context for lupdate to find it |
53 | #define NewPhrase tr("(New Entry)") |
54 | |
55 | setupUi(this); |
56 | setWindowTitle(tr(s: "%1[*] - Qt Linguist" ).arg(a: m_phraseBook->friendlyPhraseBookName())); |
57 | setWindowModified(m_phraseBook->isModified()); |
58 | |
59 | phrMdl = new PhraseModel(this); |
60 | |
61 | m_sortedPhraseModel = new QSortFilterProxyModel(this); |
62 | m_sortedPhraseModel->setSortCaseSensitivity(Qt::CaseInsensitive); |
63 | m_sortedPhraseModel->setSortLocaleAware(true); |
64 | m_sortedPhraseModel->setDynamicSortFilter(true); |
65 | m_sortedPhraseModel->setSourceModel(phrMdl); |
66 | |
67 | phraseList->setModel(m_sortedPhraseModel); |
68 | phraseList->header()->setDefaultSectionSize(150); |
69 | phraseList->header()->setSectionResizeMode(QHeaderView::Interactive); |
70 | |
71 | connect(sender: sourceLed, SIGNAL(textChanged(QString)), |
72 | receiver: this, SLOT(sourceChanged(QString))); |
73 | connect(sender: targetLed, SIGNAL(textChanged(QString)), |
74 | receiver: this, SLOT(targetChanged(QString))); |
75 | connect(sender: definitionLed, SIGNAL(textChanged(QString)), |
76 | receiver: this, SLOT(definitionChanged(QString))); |
77 | connect(sender: phraseList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), |
78 | receiver: this, SLOT(selectionChanged())); |
79 | connect(sender: newBut, SIGNAL(clicked()), receiver: this, SLOT(newPhrase())); |
80 | connect(sender: removeBut, SIGNAL(clicked()), receiver: this, SLOT(removePhrase())); |
81 | connect(sender: settingsBut, SIGNAL(clicked()), receiver: this, SLOT(settings())); |
82 | connect(sender: saveBut, SIGNAL(clicked()), receiver: this, SLOT(save())); |
83 | connect(sender: m_phraseBook, SIGNAL(modifiedChanged(bool)), receiver: this, SLOT(setWindowModified(bool))); |
84 | |
85 | sourceLed->installEventFilter(filterObj: this); |
86 | targetLed->installEventFilter(filterObj: this); |
87 | definitionLed->installEventFilter(filterObj: this); |
88 | |
89 | foreach (Phrase *p, phraseBook->phrases()) |
90 | phrMdl->addPhrase(p); |
91 | |
92 | phraseList->sortByColumn(column: 0, order: Qt::AscendingOrder); |
93 | |
94 | enableDisable(); |
95 | } |
96 | |
97 | bool PhraseBookBox::eventFilter(QObject *obj, QEvent *event) |
98 | { |
99 | if (event->type() == QEvent::KeyPress && |
100 | (obj == sourceLed || obj == targetLed || obj == definitionLed)) |
101 | { |
102 | const QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); |
103 | const int key = keyEvent->key(); |
104 | |
105 | switch (key) { |
106 | case Qt::Key_Down: |
107 | case Qt::Key_Up: |
108 | case Qt::Key_PageDown: |
109 | case Qt::Key_PageUp: |
110 | return QApplication::sendEvent(receiver: phraseList, event); |
111 | } |
112 | } |
113 | return QDialog::eventFilter(obj, event); |
114 | } |
115 | |
116 | void PhraseBookBox::newPhrase() |
117 | { |
118 | Phrase *p = new Phrase(); |
119 | p->setSource(NewPhrase); |
120 | m_phraseBook->append(phrase: p); |
121 | selectItem(index: phrMdl->addPhrase(p)); |
122 | } |
123 | |
124 | void PhraseBookBox::removePhrase() |
125 | { |
126 | QModelIndex index = currentPhraseIndex(); |
127 | Phrase *phrase = phrMdl->phrase(index); |
128 | m_phraseBook->remove(phrase); |
129 | phrMdl->removePhrase(index); |
130 | delete phrase; |
131 | } |
132 | |
133 | void PhraseBookBox::settings() |
134 | { |
135 | if (!m_translationSettingsDialog) |
136 | m_translationSettingsDialog = new TranslationSettingsDialog(this); |
137 | m_translationSettingsDialog->setPhraseBook(m_phraseBook); |
138 | m_translationSettingsDialog->exec(); |
139 | } |
140 | |
141 | void PhraseBookBox::save() |
142 | { |
143 | const QString &fileName = m_phraseBook->fileName(); |
144 | if (!m_phraseBook->save(fileName)) |
145 | QMessageBox::warning(parent: this, |
146 | title: tr(s: "Qt Linguist" ), |
147 | text: tr(s: "Cannot save phrase book '%1'." ).arg(a: fileName)); |
148 | } |
149 | |
150 | void PhraseBookBox::sourceChanged(const QString& source) |
151 | { |
152 | QModelIndex index = currentPhraseIndex(); |
153 | if (index.isValid()) |
154 | phrMdl->setData(index: phrMdl->index(row: index.row(), column: 0), value: source); |
155 | } |
156 | |
157 | void PhraseBookBox::targetChanged(const QString& target) |
158 | { |
159 | QModelIndex index = currentPhraseIndex(); |
160 | if (index.isValid()) |
161 | phrMdl->setData(index: phrMdl->index(row: index.row(), column: 1), value: target); |
162 | } |
163 | |
164 | void PhraseBookBox::definitionChanged(const QString& definition) |
165 | { |
166 | QModelIndex index = currentPhraseIndex(); |
167 | if (index.isValid()) |
168 | phrMdl->setData(index: phrMdl->index(row: index.row(), column: 2), value: definition); |
169 | } |
170 | |
171 | void PhraseBookBox::selectionChanged() |
172 | { |
173 | enableDisable(); |
174 | } |
175 | |
176 | void PhraseBookBox::selectItem(const QModelIndex &index) |
177 | { |
178 | const QModelIndex &sortedIndex = m_sortedPhraseModel->mapFromSource(sourceIndex: index); |
179 | phraseList->scrollTo(index: sortedIndex); |
180 | phraseList->setCurrentIndex(sortedIndex); |
181 | } |
182 | |
183 | void PhraseBookBox::enableDisable() |
184 | { |
185 | QModelIndex index = currentPhraseIndex(); |
186 | |
187 | sourceLed->blockSignals(b: true); |
188 | targetLed->blockSignals(b: true); |
189 | definitionLed->blockSignals(b: true); |
190 | |
191 | bool indexValid = index.isValid(); |
192 | |
193 | if (indexValid) { |
194 | Phrase *p = phrMdl->phrase(index); |
195 | sourceLed->setText(p->source().simplified()); |
196 | targetLed->setText(p->target().simplified()); |
197 | definitionLed->setText(p->definition()); |
198 | } |
199 | else { |
200 | sourceLed->setText(QString()); |
201 | targetLed->setText(QString()); |
202 | definitionLed->setText(QString()); |
203 | } |
204 | |
205 | sourceLed->setEnabled(indexValid); |
206 | targetLed->setEnabled(indexValid); |
207 | definitionLed->setEnabled(indexValid); |
208 | removeBut->setEnabled(indexValid); |
209 | |
210 | sourceLed->blockSignals(b: false); |
211 | targetLed->blockSignals(b: false); |
212 | definitionLed->blockSignals(b: false); |
213 | |
214 | QWidget *f = QApplication::focusWidget(); |
215 | if (f != sourceLed && f != targetLed && f != definitionLed) { |
216 | QLineEdit *led = (sourceLed->text() == NewPhrase ? sourceLed : targetLed); |
217 | led->setFocus(); |
218 | led->selectAll(); |
219 | } else { |
220 | static_cast<QLineEdit*>(f)->selectAll(); |
221 | } |
222 | } |
223 | |
224 | QModelIndex PhraseBookBox::currentPhraseIndex() const |
225 | { |
226 | return m_sortedPhraseModel->mapToSource(proxyIndex: phraseList->currentIndex()); |
227 | } |
228 | |
229 | QT_END_NAMESPACE |
230 | |