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 
PhraseBookBox(PhraseBook * phraseBook,QWidget * parent)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("%1[*] - Qt Linguist").arg(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(sourceLed, SIGNAL(textChanged(QString)),
72             this, SLOT(sourceChanged(QString)));
73     connect(targetLed, SIGNAL(textChanged(QString)),
74             this, SLOT(targetChanged(QString)));
75     connect(definitionLed, SIGNAL(textChanged(QString)),
76             this, SLOT(definitionChanged(QString)));
77     connect(phraseList->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
78             this, SLOT(selectionChanged()));
79     connect(newBut, SIGNAL(clicked()), this, SLOT(newPhrase()));
80     connect(removeBut, SIGNAL(clicked()), this, SLOT(removePhrase()));
81     connect(settingsBut, SIGNAL(clicked()), this, SLOT(settings()));
82     connect(saveBut, SIGNAL(clicked()), this, SLOT(save()));
83     connect(m_phraseBook, SIGNAL(modifiedChanged(bool)), this, SLOT(setWindowModified(bool)));
84 
85     sourceLed->installEventFilter(this);
86     targetLed->installEventFilter(this);
87     definitionLed->installEventFilter(this);
88 
89     foreach (Phrase *p, phraseBook->phrases())
90         phrMdl->addPhrase(p);
91 
92     phraseList->sortByColumn(0, Qt::AscendingOrder);
93 
94     enableDisable();
95 }
96 
eventFilter(QObject * obj,QEvent * event)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(phraseList, event);
111         }
112     }
113     return QDialog::eventFilter(obj, event);
114 }
115 
newPhrase()116 void PhraseBookBox::newPhrase()
117 {
118     Phrase *p = new Phrase();
119     p->setSource(NewPhrase);
120     m_phraseBook->append(p);
121     selectItem(phrMdl->addPhrase(p));
122 }
123 
removePhrase()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 
settings()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 
save()141 void PhraseBookBox::save()
142 {
143     const QString &fileName = m_phraseBook->fileName();
144     if (!m_phraseBook->save(fileName))
145         QMessageBox::warning(this,
146                              tr("Qt Linguist"),
147                              tr("Cannot save phrase book '%1'.").arg(fileName));
148 }
149 
sourceChanged(const QString & source)150 void PhraseBookBox::sourceChanged(const QString& source)
151 {
152     QModelIndex index = currentPhraseIndex();
153     if (index.isValid())
154         phrMdl->setData(phrMdl->index(index.row(), 0), source);
155 }
156 
targetChanged(const QString & target)157 void PhraseBookBox::targetChanged(const QString& target)
158 {
159     QModelIndex index = currentPhraseIndex();
160     if (index.isValid())
161         phrMdl->setData(phrMdl->index(index.row(), 1), target);
162 }
163 
definitionChanged(const QString & definition)164 void PhraseBookBox::definitionChanged(const QString& definition)
165 {
166     QModelIndex index = currentPhraseIndex();
167     if (index.isValid())
168         phrMdl->setData(phrMdl->index(index.row(), 2), definition);
169 }
170 
selectionChanged()171 void PhraseBookBox::selectionChanged()
172 {
173     enableDisable();
174 }
175 
selectItem(const QModelIndex & index)176 void PhraseBookBox::selectItem(const QModelIndex &index)
177 {
178     const QModelIndex &sortedIndex = m_sortedPhraseModel->mapFromSource(index);
179     phraseList->scrollTo(sortedIndex);
180     phraseList->setCurrentIndex(sortedIndex);
181 }
182 
enableDisable()183 void PhraseBookBox::enableDisable()
184 {
185     QModelIndex index = currentPhraseIndex();
186 
187     sourceLed->blockSignals(true);
188     targetLed->blockSignals(true);
189     definitionLed->blockSignals(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(false);
211     targetLed->blockSignals(false);
212     definitionLed->blockSignals(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 
currentPhraseIndex() const224 QModelIndex PhraseBookBox::currentPhraseIndex() const
225 {
226     return m_sortedPhraseModel->mapToSource(phraseList->currentIndex());
227 }
228 
229 QT_END_NAMESPACE
230