25 return settingPath(
"PhraseViewHeader");
31 m_phraseDict(phraseDict),
35 setObjectName(QLatin1String(
"phrase list view"));
37 m_phraseModel =
new PhraseModel(
this);
39 setModel(m_phraseModel);
40 setAlternatingRowColors(
true);
41 setSelectionBehavior(QAbstractItemView::SelectRows);
42 setSelectionMode(QAbstractItemView::SingleSelection);
43 setRootIsDecorated(
false);
44 setItemsExpandable(
false);
46 for (
int i = 0; i < 9; ++i) {
47 const auto key =
static_cast<Qt::Key>(
int(Qt::Key_1) + i);
48 auto shortCut =
new QShortcut(Qt::CTRL | key,
this);
49 connect(shortCut, &QShortcut::activated,
this,
50 [i,
this]() {
this->guessShortcut(i); });
53 header()->setSectionResizeMode(QHeaderView::Interactive);
54 header()->setSectionsClickable(
true);
55 header()->restoreState(QSettings().value(phraseViewHeaderKey()).toByteArray());
57 connect(
this, &QAbstractItemView::activated,
58 this, &PhraseView::selectPhrase);
63 QSettings().setValue(phraseViewHeaderKey(), header()->saveState());
69 m_doGuesses = !m_doGuesses;
75 setSourceText(m_modelIndex, m_sourceText);
81 QModelIndex index = indexAt(event->pos());
85 QMenu *contextMenu =
new QMenu(
this);
87 QAction *insertAction =
new QAction(tr(
"Insert"), contextMenu);
88 connect(insertAction, &QAction::triggered,
89 this, &PhraseView::selectCurrentPhrase);
91 QAction *editAction =
new QAction(tr(
"Edit"), contextMenu);
92 connect(editAction, &QAction::triggered,
93 this, &PhraseView::editPhrase);
94 Qt::ItemFlags isFromPhraseBook = model()->flags(index) & Qt::ItemIsEditable;
95 editAction->setEnabled(isFromPhraseBook);
97 QAction *gotoAction =
new QAction(tr(
"Go to"), contextMenu);
98 connect(gotoAction, &QAction::triggered,
99 this, &PhraseView::gotoMessageFromGuess);
100 gotoAction->setEnabled(!isFromPhraseBook);
102 contextMenu->addAction(insertAction);
103 contextMenu->addAction(editAction);
104 contextMenu->addAction(gotoAction);
106 contextMenu->exec(event->globalPos());
112 QModelIndex index = indexAt(event->pos());
113 if (!index.isValid())
116 emit phraseSelected(m_modelIndex, m_phraseModel->phrase(index)->target());
122 const auto phrases = m_phraseModel->phraseList();
123 for (
const Phrase *phrase : phrases)
124 if (phrase->shortcut() == key) {
125 emit phraseSelected(m_modelIndex, phrase->target());
130void PhraseView::selectPhrase(
const QModelIndex &index)
132 emit phraseSelected(m_modelIndex, m_phraseModel->phrase(index)->target());
137 emit phraseSelected(m_modelIndex, m_phraseModel->phrase(currentIndex())->target());
142 edit(currentIndex());
147 emit setCurrentMessageFromGuess(m_modelIndex,
148 m_phraseModel->phrase(currentIndex())->candidate());
153 m_maxCandidates = max;
154 emit showFewerGuessesAvailable(m_maxCandidates > DefaultMaxCandidates);
160 setSourceText(m_modelIndex, m_sourceText);
166 setSourceText(m_modelIndex, m_sourceText);
172 setSourceText(m_modelIndex, m_sourceText);
176 const char *text,
int maxCandidates)
190 || mtm.translation().isEmpty())
193 QString s = m->text();
195 int score = stringmatcher.getSimilarityScore(s);
197 if (candidates.size() == maxCandidates && score > scores[maxCandidates - 1])
198 candidates.removeLast();
200 Candidate cand(mtm.context(), s, mtm.comment(), mtm.translation());
203 for (i = 0; i < candidates.size(); ++i) {
204 if (score >= scores.at(i)) {
205 if (score == scores.at(i)) {
206 if (candidates.at(i) == cand)
207 goto continue_outer_loop;
213 scores.insert(i, score);
214 candidates.insert(i, cand);
225 m_modelIndex = model;
226 m_sourceText = sourceText;
227 m_phraseModel->removePhrases();
233 const auto phrases = getPhrases(model, sourceText);
234 for (Phrase *p : phrases)
235 m_phraseModel->addPhrase(p);
237 if (!sourceText.isEmpty() && m_doGuesses) {
238 const CandidateList cl = similarTextHeuristicCandidates(m_dataModel, model,
239 sourceText.toLatin1(), m_maxCandidates);
241 for (
const Candidate &candidate : cl) {
244 def = tr(
"Guess from '%1' (%2)")
245 .arg(candidate.context, QKeySequence(Qt::CTRL | (Qt::Key_0 + (n + 1)))
246 .toString(QKeySequence::NativeText));
248 def = tr(
"Guess from '%1'").arg(candidate.context);
249 Phrase *guess =
new Phrase(candidate.source, candidate.translation, def, candidate, n);
250 m_guesses.append(guess);
251 m_phraseModel->addPhrase(guess);
257QList<Phrase *>
PhraseView::getPhrases(
int model,
const QString &source)
259 QList<Phrase *> phrases;
260 const QString f = MainWindow::friendlyString(source);
261 const QStringList lookupWords = f.split(QLatin1Char(
' '));
263 for (
const QString &s : lookupWords) {
264 if (m_phraseDict->at(model).contains(s)) {
265 const auto phraseList = m_phraseDict->at(model).value(s);
266 for (Phrase *p : phraseList) {
267 if (f.contains(MainWindow::friendlyString(p->source())))
277 qDeleteAll(m_guesses);
const TranslatorMessage & message() const
MultiDataModelIterator(MultiDataModel *model, int modelNo, int contextNo=0, int messageNo=0)
MessageItem * current() const
void setMaxCandidates(const int max)
void mouseDoubleClickEvent(QMouseEvent *event) override
void setSourceText(int model, const QString &sourceText)
void contextMenuEvent(QContextMenuEvent *event) override
Combined button and popup list for selecting options.
static QT_BEGIN_NAMESPACE QString phraseViewHeaderKey()
static CandidateList similarTextHeuristicCandidates(MultiDataModel *model, int mi, const char *text, int maxCandidates)
static QT_BEGIN_NAMESPACE const int DefaultMaxCandidates
QList< Candidate > CandidateList
const int textSimilarityThreshold