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