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 "formpreviewview.h"
30 #include "messagemodel.h"
31 
32 #include <quiloader.h>
33 
34 #include <QtCore/QDebug>
35 #include <QtCore/QTime>
36 
37 #include <QtWidgets/QAction>
38 #include <QtWidgets/QApplication>
39 #include <QtWidgets/QFontComboBox>
40 #include <QtWidgets/QFrame>
41 #include <QtWidgets/QGridLayout>
42 #include <QtWidgets/QListWidget>
43 #include <QtWidgets/QMdiArea>
44 #include <QtWidgets/QMdiSubWindow>
45 #include <QtWidgets/QMenu>
46 #include <QtWidgets/QStackedLayout>
47 #include <QtWidgets/QStackedWidget>
48 #include <QtWidgets/QTableWidget>
49 #include <QtWidgets/QTabWidget>
50 #include <QtWidgets/QToolBox>
51 #include <QtWidgets/QTreeWidget>
52 #include <QtWidgets/QScrollArea>
53 
54 QT_BEGIN_NAMESPACE
55 
56 #if defined(Q_CC_SUN) || defined(Q_CC_HPACC) || defined(Q_CC_XLC)
qHash(const QUiTranslatableStringValue & tsv)57 int qHash(const QUiTranslatableStringValue &tsv)
58 #else
59 static int qHash(const QUiTranslatableStringValue &tsv)
60 #endif
61 {
62     return qHash(tsv.value()) ^ qHash(tsv.qualifier());
63 }
64 
operator ==(const QUiTranslatableStringValue & tsv1,const QUiTranslatableStringValue & tsv2)65 static bool operator==(const QUiTranslatableStringValue &tsv1, const QUiTranslatableStringValue &tsv2)
66 {
67     return tsv1.value() == tsv2.value() && tsv1.qualifier() == tsv2.qualifier();
68 }
69 
70 #define INSERT_TARGET(_tsv, _type, _target, _prop) \
71     do { \
72         target.type = _type; \
73         target.target._target; \
74         target.prop._prop; \
75         (*targets)[qvariant_cast<QUiTranslatableStringValue>(_tsv)].append(target); \
76     } while (0)
77 
registerTreeItem(QTreeWidgetItem * item,TargetsHash * targets)78 static void registerTreeItem(QTreeWidgetItem *item, TargetsHash *targets)
79 {
80     const QUiItemRolePair *irs = QFormInternal::qUiItemRoles;
81 
82     int cnt = item->columnCount();
83     for (int i = 0; i < cnt; ++i) {
84         for (unsigned j = 0; irs[j].shadowRole >= 0; j++) {
85             QVariant v = item->data(i, irs[j].shadowRole);
86             if (v.isValid()) {
87                 TranslatableEntry target;
88                 target.prop.treeIndex.column = i;
89                 INSERT_TARGET(v, TranslatableTreeWidgetItem, treeWidgetItem = item, treeIndex.index = j);
90             }
91         }
92     }
93 
94     cnt = item->childCount();
95     for (int j = 0; j < cnt; ++j)
96         registerTreeItem(item->child(j), targets);
97 }
98 
99 #define REGISTER_ITEM_CORE(item, propType, targetName) \
100     const QUiItemRolePair *irs = QFormInternal::qUiItemRoles; \
101     for (unsigned j = 0; irs[j].shadowRole >= 0; j++) { \
102         QVariant v = item->data(irs[j].shadowRole); \
103         if (v.isValid()) \
104             INSERT_TARGET(v, propType, targetName = item, index = j); \
105     }
106 
registerListItem(QListWidgetItem * item,TargetsHash * targets)107 static void registerListItem(QListWidgetItem *item, TargetsHash *targets)
108 {
109     TranslatableEntry target;
110     REGISTER_ITEM_CORE(item, TranslatableListWidgetItem, listWidgetItem);
111 }
112 
registerTableItem(QTableWidgetItem * item,TargetsHash * targets)113 static void registerTableItem(QTableWidgetItem *item, TargetsHash *targets)
114 {
115     if (!item)
116         return;
117 
118     TranslatableEntry target;
119     REGISTER_ITEM_CORE(item, TranslatableTableWidgetItem, tableWidgetItem);
120 }
121 
122 #define REGISTER_SUBWIDGET_PROP(mainWidget, propType, propName) \
123     do { \
124         QVariant v = mainWidget->widget(i)->property(propName); \
125         if (v.isValid()) \
126             INSERT_TARGET(v, propType, object = mainWidget, index = i); \
127     } while (0)
128 
buildTargets(QObject * o,TargetsHash * targets)129 static void buildTargets(QObject *o, TargetsHash *targets)
130 {
131     TranslatableEntry target;
132 
133     foreach (const QByteArray &prop, o->dynamicPropertyNames()) {
134         if (prop.startsWith(PROP_GENERIC_PREFIX)) {
135             const QByteArray propName = prop.mid(sizeof(PROP_GENERIC_PREFIX) - 1);
136             INSERT_TARGET(o->property(prop),
137                 TranslatableProperty, object = o, name = qstrdup(propName.data()));
138         }
139     }
140     if (0) {
141 #ifndef QT_NO_TABWIDGET
142     } else if (QTabWidget *tabw = qobject_cast<QTabWidget*>(o)) {
143         const int cnt = tabw->count();
144         for (int i = 0; i < cnt; ++i) {
145             REGISTER_SUBWIDGET_PROP(tabw, TranslatableTabPageText, PROP_TABPAGETEXT);
146 # ifndef QT_NO_TOOLTIP
147             REGISTER_SUBWIDGET_PROP(tabw, TranslatableTabPageToolTip, PROP_TABPAGETOOLTIP);
148 # endif
149 # ifndef QT_NO_WHATSTHIS
150             REGISTER_SUBWIDGET_PROP(tabw, TranslatableTabPageWhatsThis, PROP_TABPAGEWHATSTHIS);
151 # endif
152         }
153 #endif
154 #ifndef QT_NO_TOOLBOX
155     } else if (QToolBox *toolw = qobject_cast<QToolBox*>(o)) {
156         const int cnt = toolw->count();
157         for (int i = 0; i < cnt; ++i) {
158             REGISTER_SUBWIDGET_PROP(toolw, TranslatableToolItemText, PROP_TOOLITEMTEXT);
159 # ifndef QT_NO_TOOLTIP
160             REGISTER_SUBWIDGET_PROP(toolw, TranslatableToolItemToolTip, PROP_TOOLITEMTOOLTIP);
161 # endif
162         }
163 #endif
164 #ifndef QT_NO_COMBOBOX
165     } else if (QComboBox *combow = qobject_cast<QComboBox*>(o)) {
166         if (!qobject_cast<QFontComboBox*>(o)) {
167             const int cnt = combow->count();
168             for (int i = 0; i < cnt; ++i) {
169                 const QVariant v = combow->itemData(i, Qt::DisplayPropertyRole);
170                 if (v.isValid())
171                     INSERT_TARGET(v, TranslatableComboBoxItem, comboBox = combow, index = i);
172             }
173         }
174 #endif
175 #ifndef QT_NO_LISTWIDGET
176     } else if (QListWidget *listw = qobject_cast<QListWidget*>(o)) {
177         const int cnt = listw->count();
178         for (int i = 0; i < cnt; ++i)
179             registerListItem(listw->item(i), targets);
180 #endif
181 #ifndef QT_NO_TABLEWIDGET
182     } else if (QTableWidget *tablew = qobject_cast<QTableWidget*>(o)) {
183         const int row_cnt = tablew->rowCount();
184         const int col_cnt = tablew->columnCount();
185         for (int j = 0; j < col_cnt; ++j)
186             registerTableItem(tablew->horizontalHeaderItem(j), targets);
187         for (int i = 0; i < row_cnt; ++i) {
188             registerTableItem(tablew->verticalHeaderItem(i), targets);
189             for (int j = 0; j < col_cnt; ++j)
190                 registerTableItem(tablew->item(i, j), targets);
191         }
192 #endif
193 #ifndef QT_NO_TREEWIDGET
194     } else if (QTreeWidget *treew = qobject_cast<QTreeWidget*>(o)) {
195         if (QTreeWidgetItem *item = treew->headerItem())
196             registerTreeItem(item, targets);
197         const int cnt = treew->topLevelItemCount();
198         for (int i = 0; i < cnt; ++i)
199             registerTreeItem(treew->topLevelItem(i), targets);
200 #endif
201     }
202     foreach (QObject *co, o->children())
203         buildTargets(co, targets);
204 }
205 
destroyTargets(TargetsHash * targets)206 static void destroyTargets(TargetsHash *targets)
207 {
208     for (TargetsHash::Iterator it = targets->begin(), end = targets->end(); it != end; ++it)
209         foreach (const TranslatableEntry &target, *it)
210             if (target.type == TranslatableProperty)
211                 delete target.prop.name;
212     targets->clear();
213 }
214 
retranslateTarget(const TranslatableEntry & target,const QString & text)215 static void retranslateTarget(const TranslatableEntry &target, const QString &text)
216 {
217     switch (target.type) {
218     case TranslatableProperty:
219         target.target.object->setProperty(target.prop.name, text);
220         break;
221 #ifndef QT_NO_TABWIDGET
222     case TranslatableTabPageText:
223         target.target.tabWidget->setTabText(target.prop.index, text);
224         break;
225 # ifndef QT_NO_TOOLTIP
226     case TranslatableTabPageToolTip:
227         target.target.tabWidget->setTabToolTip(target.prop.index, text);
228         break;
229 # endif
230 # ifndef QT_NO_WHATSTHIS
231     case TranslatableTabPageWhatsThis:
232         target.target.tabWidget->setTabWhatsThis(target.prop.index, text);
233         break;
234 # endif
235 #endif // QT_NO_TABWIDGET
236 #ifndef QT_NO_TOOLBOX
237     case TranslatableToolItemText:
238         target.target.toolBox->setItemText(target.prop.index, text);
239         break;
240 # ifndef QT_NO_TOOLTIP
241     case TranslatableToolItemToolTip:
242         target.target.toolBox->setItemToolTip(target.prop.index, text);
243         break;
244 # endif
245 #endif // QT_NO_TOOLBOX
246 #ifndef QT_NO_COMBOBOX
247     case TranslatableComboBoxItem:
248         target.target.comboBox->setItemText(target.prop.index, text);
249         break;
250 #endif
251 #ifndef QT_NO_LISTWIDGET
252     case TranslatableListWidgetItem:
253         target.target.listWidgetItem->setData(target.prop.index, text);
254         break;
255 #endif
256 #ifndef QT_NO_TABLEWIDGET
257     case TranslatableTableWidgetItem:
258         target.target.tableWidgetItem->setData(target.prop.index, text);
259         break;
260 #endif
261 #ifndef QT_NO_TREEWIDGET
262     case TranslatableTreeWidgetItem:
263         target.target.treeWidgetItem->setData(target.prop.treeIndex.column, target.prop.treeIndex.index, text);
264         break;
265 #endif
266     }
267 }
268 
retranslateTargets(const QList<TranslatableEntry> & targets,const QUiTranslatableStringValue & tsv,const DataModel * dataModel,const QString & className)269 static void retranslateTargets(
270     const QList<TranslatableEntry> &targets, const QUiTranslatableStringValue &tsv,
271     const DataModel *dataModel, const QString &className)
272 {
273     QString sourceText = QString::fromUtf8(tsv.value());
274     QString text;
275     if (MessageItem *msg = dataModel->findMessage(
276             className, sourceText, QString::fromUtf8(tsv.qualifier())))
277         text = msg->translation();
278     if (text.isEmpty() && !tsv.value().isEmpty())
279         text = QLatin1Char('#') + sourceText;
280 
281     foreach (const TranslatableEntry &target, targets)
282         retranslateTarget(target, text);
283 }
284 
bringToFront(QWidget * w)285 static void bringToFront(QWidget *w)
286 {
287     for (; QWidget *pw = w->parentWidget(); w = pw) {
288 #ifndef QT_NO_STACKEDWIDGET
289         if (QStackedWidget *stack = qobject_cast<QStackedWidget *>(pw)) {
290 #ifndef QT_NO_TABWIDGET
291             // Updating QTabWidget's embedded QStackedWidget does not update its
292             // QTabBar, so handle tab widgets explicitly.
293             if (QTabWidget *tab = qobject_cast<QTabWidget *>(stack->parent()))
294                 tab->setCurrentWidget(w);
295             else
296 #endif
297                 stack->setCurrentWidget(w);
298             continue;
299         }
300 #endif
301 #ifndef QT_NO_TOOLBOX
302         if (QScrollArea *sv = qobject_cast<QScrollArea *>(pw)) {
303             if (QToolBox *tb = qobject_cast<QToolBox *>(sv->parent()))
304                 tb->setCurrentWidget(w);
305         }
306 #endif
307     }
308 }
309 
highlightTreeWidgetItem(QTreeWidgetItem * item,int col,bool on)310 static void highlightTreeWidgetItem(QTreeWidgetItem *item, int col, bool on)
311 {
312     QVariant br = item->data(col, Qt::BackgroundRole + 500);
313     QVariant fr = item->data(col, Qt::ForegroundRole + 500);
314     if (on) {
315         if (!br.isValid() && !fr.isValid()) {
316             item->setData(col, Qt::BackgroundRole + 500, item->data(col, Qt::BackgroundRole));
317             item->setData(col, Qt::ForegroundRole + 500, item->data(col, Qt::ForegroundRole));
318             QPalette pal = qApp->palette();
319             item->setData(col, Qt::BackgroundRole, pal.color(QPalette::Dark));
320             item->setData(col, Qt::ForegroundRole, pal.color(QPalette::Light));
321         }
322     } else {
323         if (br.isValid() || fr.isValid()) {
324             item->setData(col, Qt::BackgroundRole, br);
325             item->setData(col, Qt::ForegroundRole, fr);
326             item->setData(col, Qt::BackgroundRole + 500, QVariant());
327             item->setData(col, Qt::ForegroundRole + 500, QVariant());
328         }
329     }
330 }
331 
332 template <class T>
highlightWidgetItem(T * item,bool on)333 static void highlightWidgetItem(T *item, bool on)
334 {
335     QVariant br = item->data(Qt::BackgroundRole + 500);
336     QVariant fr = item->data(Qt::ForegroundRole + 500);
337     if (on) {
338         if (!br.isValid() && !fr.isValid()) {
339             item->setData(Qt::BackgroundRole + 500, item->data(Qt::BackgroundRole));
340             item->setData(Qt::ForegroundRole + 500, item->data(Qt::ForegroundRole));
341             QPalette pal = qApp->palette();
342             item->setData(Qt::BackgroundRole, pal.color(QPalette::Dark));
343             item->setData(Qt::ForegroundRole, pal.color(QPalette::Light));
344         }
345     } else {
346         if (br.isValid() || fr.isValid()) {
347             item->setData(Qt::BackgroundRole, br);
348             item->setData(Qt::ForegroundRole, fr);
349             item->setData(Qt::BackgroundRole + 500, QVariant());
350             item->setData(Qt::ForegroundRole + 500, QVariant());
351         }
352     }
353 }
354 
355 #define AUTOFILL_BACKUP_PROP "_q_linguist_autoFillBackup"
356 #define PALETTE_BACKUP_PROP "_q_linguist_paletteBackup"
357 #define FONT_BACKUP_PROP "_q_linguist_fontBackup"
358 
359 static void highlightWidget(QWidget *w, bool on);
360 
highlightAction(QAction * a,bool on)361 static void highlightAction(QAction *a, bool on)
362 {
363     QVariant bak = a->property(FONT_BACKUP_PROP);
364     if (on) {
365         if (!bak.isValid()) {
366             QFont fnt = qApp->font();
367             a->setProperty(FONT_BACKUP_PROP, QVariant::fromValue(a->font().resolve(fnt)));
368             fnt.setBold(true);
369             fnt.setItalic(true);
370             a->setFont(fnt);
371         }
372     } else {
373         if (bak.isValid()) {
374             a->setFont(qvariant_cast<QFont>(bak));
375             a->setProperty(FONT_BACKUP_PROP, QVariant());
376         }
377     }
378     foreach (QWidget *w, a->associatedWidgets())
379         highlightWidget(w, on);
380 }
381 
highlightWidget(QWidget * w,bool on)382 static void highlightWidget(QWidget *w, bool on)
383 {
384     QVariant bak = w->property(PALETTE_BACKUP_PROP);
385     if (on) {
386         if (!bak.isValid()) {
387             QPalette pal = qApp->palette();
388             foreach (QObject *co, w->children())
389                 if (QWidget *cw = qobject_cast<QWidget *>(co))
390                     cw->setPalette(cw->palette().resolve(pal));
391             w->setProperty(PALETTE_BACKUP_PROP, QVariant::fromValue(w->palette().resolve(pal)));
392             w->setProperty(AUTOFILL_BACKUP_PROP, QVariant::fromValue(w->autoFillBackground()));
393             QColor col1 = pal.color(QPalette::Dark);
394             QColor col2 = pal.color(QPalette::Light);
395             pal.setColor(QPalette::Base, col1);
396             pal.setColor(QPalette::Window, col1);
397             pal.setColor(QPalette::Button, col1);
398             pal.setColor(QPalette::Text, col2);
399             pal.setColor(QPalette::WindowText, col2);
400             pal.setColor(QPalette::ButtonText, col2);
401             pal.setColor(QPalette::BrightText, col2);
402             w->setPalette(pal);
403             w->setAutoFillBackground(true);
404         }
405     } else {
406         if (bak.isValid()) {
407             w->setPalette(qvariant_cast<QPalette>(bak));
408             w->setAutoFillBackground(qvariant_cast<bool>(w->property(AUTOFILL_BACKUP_PROP)));
409             w->setProperty(PALETTE_BACKUP_PROP, QVariant());
410             w->setProperty(AUTOFILL_BACKUP_PROP, QVariant());
411         }
412     }
413     if (QMenu *m = qobject_cast<QMenu *>(w))
414         if (m->menuAction())
415             highlightAction(m->menuAction(), on);
416 }
417 
highlightTarget(const TranslatableEntry & target,bool on)418 static void highlightTarget(const TranslatableEntry &target, bool on)
419 {
420     switch (target.type) {
421     case TranslatableProperty:
422         if (QAction *a = qobject_cast<QAction *>(target.target.object)) {
423             highlightAction(a, on);
424         } else if (QWidget *w = qobject_cast<QWidget *>(target.target.object)) {
425             bringToFront(w);
426             highlightWidget(w, on);
427         }
428         break;
429 #ifndef QT_NO_COMBOBOX
430     case TranslatableComboBoxItem:
431         static_cast<QComboBox *>(target.target.object)->setCurrentIndex(target.prop.index);
432         goto frontAndHighlight;
433 #endif
434 #ifndef QT_NO_TABWIDGET
435     case TranslatableTabPageText:
436         static_cast<QTabWidget *>(target.target.object)->setCurrentIndex(target.prop.index);
437         goto frontAndHighlight;
438 # ifndef QT_NO_TOOLTIP
439     case TranslatableTabPageToolTip:
440 # endif
441 # ifndef QT_NO_WHATSTHIS
442     case TranslatableTabPageWhatsThis:
443 # endif
444 #endif // QT_NO_TABWIDGET
445 #ifndef QT_NO_TOOLBOX
446     case TranslatableToolItemText:
447 # ifndef QT_NO_TOOLTIP
448     case TranslatableToolItemToolTip:
449 # endif
450 #endif // QT_NO_TOOLBOX
451 #if !defined(QT_NO_COMBOBOX) || !defined(QT_NO_TABWIDGET)
452       frontAndHighlight:
453 #endif
454         bringToFront(static_cast<QWidget *>(target.target.object));
455         highlightWidget(static_cast<QWidget *>(target.target.object), on);
456         break;
457 #ifndef QT_NO_LISTWIDGET
458     case TranslatableListWidgetItem:
459         bringToFront(target.target.listWidgetItem->listWidget());
460         highlightWidgetItem(target.target.listWidgetItem, on);
461         break;
462 #endif
463 #ifndef QT_NO_TABLEWIDGET
464     case TranslatableTableWidgetItem:
465         bringToFront(target.target.tableWidgetItem->tableWidget());
466         highlightWidgetItem(target.target.tableWidgetItem, on);
467         break;
468 #endif
469 #ifndef QT_NO_TREEWIDGET
470     case TranslatableTreeWidgetItem:
471         bringToFront(target.target.treeWidgetItem->treeWidget());
472         highlightTreeWidgetItem(target.target.treeWidgetItem, target.prop.treeIndex.column, on);
473         break;
474 #endif
475     }
476 }
477 
highlightTargets(const QList<TranslatableEntry> & targets,bool on)478 static void highlightTargets(const QList<TranslatableEntry> &targets, bool on)
479 {
480     foreach (const TranslatableEntry &target, targets)
481         highlightTarget(target, on);
482 }
483 
FormPreviewView(QWidget * parent,MultiDataModel * dataModel)484 FormPreviewView::FormPreviewView(QWidget *parent, MultiDataModel *dataModel)
485   : QMainWindow(parent), m_form(0), m_dataModel(dataModel)
486 {
487     m_mdiSubWindow = new QMdiSubWindow;
488     m_mdiSubWindow->setWindowFlags(m_mdiSubWindow->windowFlags() & ~Qt::WindowSystemMenuHint);
489     m_mdiArea = new QMdiArea(this);
490     m_mdiArea->addSubWindow(m_mdiSubWindow);
491     setCentralWidget(m_mdiArea);
492     m_mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
493     m_mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
494 }
495 
setSourceContext(int model,MessageItem * messageItem)496 void FormPreviewView::setSourceContext(int model, MessageItem *messageItem)
497 {
498     if (model < 0 || !messageItem) {
499         m_lastModel = -1;
500         return;
501     }
502 
503     QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir();
504     QString fileName = QDir::cleanPath(dir.absoluteFilePath(messageItem->fileName()));
505     if (m_lastFormName != fileName) {
506         delete m_form;
507         m_form = 0;
508         m_lastFormName.clear();
509         m_highlights.clear();
510         destroyTargets(&m_targets);
511 
512         static QUiLoader *uiLoader;
513         if (!uiLoader) {
514             uiLoader = new QUiLoader(this);
515             uiLoader->setLanguageChangeEnabled(true);
516             uiLoader->setTranslationEnabled(false);
517         }
518 
519         QFile file(fileName);
520         if (!file.open(QIODevice::ReadOnly)) {
521             qDebug() << "CANNOT OPEN FORM" << fileName;
522             m_mdiSubWindow->hide();
523             return;
524         }
525         m_form = uiLoader->load(&file, m_mdiSubWindow);
526         if (!m_form) {
527             qDebug() << "CANNOT LOAD FORM" << fileName;
528             m_mdiSubWindow->hide();
529             return;
530         }
531         file.close();
532         buildTargets(m_form, &m_targets);
533 
534         setToolTip(fileName);
535 
536         m_form->setWindowFlags(Qt::Widget);
537         m_form->setWindowModality(Qt::NonModal);
538         m_form->setFocusPolicy(Qt::NoFocus);
539         m_form->show(); // needed, otherwide the Qt::NoFocus is not propagated.
540         m_mdiSubWindow->setWidget(m_form);
541         m_mdiSubWindow->setWindowTitle(m_form->windowTitle());
542         m_mdiSubWindow->show();
543         m_mdiArea->cascadeSubWindows();
544         m_lastFormName = fileName;
545         m_lastClassName = messageItem->context();
546         m_lastModel = -1;
547     } else {
548         highlightTargets(m_highlights, false);
549     }
550     QUiTranslatableStringValue tsv;
551     tsv.setValue(messageItem->text().toUtf8());
552     tsv.setQualifier(messageItem->comment().toUtf8());
553     m_highlights = m_targets.value(tsv);
554     if (m_lastModel != model) {
555         for (TargetsHash::Iterator it = m_targets.begin(), end = m_targets.end(); it != end; ++it)
556             retranslateTargets(*it, it.key(), m_dataModel->model(model), m_lastClassName);
557         m_lastModel = model;
558     } else {
559         retranslateTargets(m_highlights, tsv, m_dataModel->model(model), m_lastClassName);
560     }
561     highlightTargets(m_highlights, true);
562 }
563 
564 QT_END_NAMESPACE
565