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) |
57 | int qHash(const QUiTranslatableStringValue &tsv) |
58 | #else |
59 | static int qHash(const QUiTranslatableStringValue &tsv) |
60 | #endif |
61 | { |
62 | return qHash(key: tsv.value()) ^ qHash(key: tsv.qualifier()); |
63 | } |
64 | |
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 | |
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(column: i, role: 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: item->child(index: 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 | |
107 | static void registerListItem(QListWidgetItem *item, TargetsHash *targets) |
108 | { |
109 | TranslatableEntry target; |
110 | REGISTER_ITEM_CORE(item, TranslatableListWidgetItem, listWidgetItem); |
111 | } |
112 | |
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 | |
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(index: 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*>(object: 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*>(object: 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*>(object: o)) { |
166 | if (!qobject_cast<QFontComboBox*>(object: o)) { |
167 | const int cnt = combow->count(); |
168 | for (int i = 0; i < cnt; ++i) { |
169 | const QVariant v = combow->itemData(index: i, role: 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*>(object: o)) { |
177 | const int cnt = listw->count(); |
178 | for (int i = 0; i < cnt; ++i) |
179 | registerListItem(item: listw->item(row: i), targets); |
180 | #endif |
181 | #ifndef QT_NO_TABLEWIDGET |
182 | } else if (QTableWidget *tablew = qobject_cast<QTableWidget*>(object: 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(item: tablew->horizontalHeaderItem(column: j), targets); |
187 | for (int i = 0; i < row_cnt; ++i) { |
188 | registerTableItem(item: tablew->verticalHeaderItem(row: i), targets); |
189 | for (int j = 0; j < col_cnt; ++j) |
190 | registerTableItem(item: tablew->item(row: i, column: j), targets); |
191 | } |
192 | #endif |
193 | #ifndef QT_NO_TREEWIDGET |
194 | } else if (QTreeWidget *treew = qobject_cast<QTreeWidget*>(object: 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(item: treew->topLevelItem(index: i), targets); |
200 | #endif |
201 | } |
202 | foreach (QObject *co, o->children()) |
203 | buildTargets(o: co, targets); |
204 | } |
205 | |
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 | |
215 | static void retranslateTarget(const TranslatableEntry &target, const QString &text) |
216 | { |
217 | switch (target.type) { |
218 | case TranslatableProperty: |
219 | target.target.object->setProperty(name: target.prop.name, value: text); |
220 | break; |
221 | #ifndef QT_NO_TABWIDGET |
222 | case TranslatableTabPageText: |
223 | target.target.tabWidget->setTabText(index: target.prop.index, text); |
224 | break; |
225 | # ifndef QT_NO_TOOLTIP |
226 | case TranslatableTabPageToolTip: |
227 | target.target.tabWidget->setTabToolTip(index: target.prop.index, tip: text); |
228 | break; |
229 | # endif |
230 | # ifndef QT_NO_WHATSTHIS |
231 | case TranslatableTabPageWhatsThis: |
232 | target.target.tabWidget->setTabWhatsThis(index: 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(index: target.prop.index, text); |
239 | break; |
240 | # ifndef QT_NO_TOOLTIP |
241 | case TranslatableToolItemToolTip: |
242 | target.target.toolBox->setItemToolTip(index: target.prop.index, toolTip: text); |
243 | break; |
244 | # endif |
245 | #endif // QT_NO_TOOLBOX |
246 | #ifndef QT_NO_COMBOBOX |
247 | case TranslatableComboBoxItem: |
248 | target.target.comboBox->setItemText(index: target.prop.index, text); |
249 | break; |
250 | #endif |
251 | #ifndef QT_NO_LISTWIDGET |
252 | case TranslatableListWidgetItem: |
253 | target.target.listWidgetItem->setData(role: target.prop.index, value: text); |
254 | break; |
255 | #endif |
256 | #ifndef QT_NO_TABLEWIDGET |
257 | case TranslatableTableWidgetItem: |
258 | target.target.tableWidgetItem->setData(role: target.prop.index, value: text); |
259 | break; |
260 | #endif |
261 | #ifndef QT_NO_TREEWIDGET |
262 | case TranslatableTreeWidgetItem: |
263 | target.target.treeWidgetItem->setData(column: target.prop.treeIndex.column, role: target.prop.treeIndex.index, value: text); |
264 | break; |
265 | #endif |
266 | } |
267 | } |
268 | |
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(str: tsv.value()); |
274 | QString text; |
275 | if (MessageItem *msg = dataModel->findMessage( |
276 | context: className, sourcetext: sourceText, comment: QString::fromUtf8(str: 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 | |
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 *>(object: 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 *>(object: 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 *>(object: pw)) { |
303 | if (QToolBox *tb = qobject_cast<QToolBox *>(object: sv->parent())) |
304 | tb->setCurrentWidget(w); |
305 | } |
306 | #endif |
307 | } |
308 | } |
309 | |
310 | static void highlightTreeWidgetItem(QTreeWidgetItem *item, int col, bool on) |
311 | { |
312 | QVariant br = item->data(column: col, role: Qt::BackgroundRole + 500); |
313 | QVariant fr = item->data(column: col, role: Qt::ForegroundRole + 500); |
314 | if (on) { |
315 | if (!br.isValid() && !fr.isValid()) { |
316 | item->setData(column: col, role: Qt::BackgroundRole + 500, value: item->data(column: col, role: Qt::BackgroundRole)); |
317 | item->setData(column: col, role: Qt::ForegroundRole + 500, value: item->data(column: col, role: Qt::ForegroundRole)); |
318 | QPalette pal = qApp->palette(); |
319 | item->setData(column: col, role: Qt::BackgroundRole, value: pal.color(cr: QPalette::Dark)); |
320 | item->setData(column: col, role: Qt::ForegroundRole, value: pal.color(cr: QPalette::Light)); |
321 | } |
322 | } else { |
323 | if (br.isValid() || fr.isValid()) { |
324 | item->setData(column: col, role: Qt::BackgroundRole, value: br); |
325 | item->setData(column: col, role: Qt::ForegroundRole, value: fr); |
326 | item->setData(column: col, role: Qt::BackgroundRole + 500, value: QVariant()); |
327 | item->setData(column: col, role: Qt::ForegroundRole + 500, value: QVariant()); |
328 | } |
329 | } |
330 | } |
331 | |
332 | template <class T> |
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(cr: QPalette::Dark)); |
343 | item->setData(Qt::ForegroundRole, pal.color(cr: 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 | |
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, value: QVariant::fromValue(value: 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>(v: bak)); |
375 | a->setProperty(FONT_BACKUP_PROP, value: QVariant()); |
376 | } |
377 | } |
378 | foreach (QWidget *w, a->associatedWidgets()) |
379 | highlightWidget(w, on); |
380 | } |
381 | |
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 *>(o: co)) |
390 | cw->setPalette(cw->palette().resolve(pal)); |
391 | w->setProperty(PALETTE_BACKUP_PROP, value: QVariant::fromValue(value: w->palette().resolve(pal))); |
392 | w->setProperty(AUTOFILL_BACKUP_PROP, value: QVariant::fromValue(value: w->autoFillBackground())); |
393 | QColor col1 = pal.color(cr: QPalette::Dark); |
394 | QColor col2 = pal.color(cr: QPalette::Light); |
395 | pal.setColor(acr: QPalette::Base, acolor: col1); |
396 | pal.setColor(acr: QPalette::Window, acolor: col1); |
397 | pal.setColor(acr: QPalette::Button, acolor: col1); |
398 | pal.setColor(acr: QPalette::Text, acolor: col2); |
399 | pal.setColor(acr: QPalette::WindowText, acolor: col2); |
400 | pal.setColor(acr: QPalette::ButtonText, acolor: col2); |
401 | pal.setColor(acr: QPalette::BrightText, acolor: col2); |
402 | w->setPalette(pal); |
403 | w->setAutoFillBackground(true); |
404 | } |
405 | } else { |
406 | if (bak.isValid()) { |
407 | w->setPalette(qvariant_cast<QPalette>(v: bak)); |
408 | w->setAutoFillBackground(qvariant_cast<bool>(v: w->property(AUTOFILL_BACKUP_PROP))); |
409 | w->setProperty(PALETTE_BACKUP_PROP, value: QVariant()); |
410 | w->setProperty(AUTOFILL_BACKUP_PROP, value: QVariant()); |
411 | } |
412 | } |
413 | if (QMenu *m = qobject_cast<QMenu *>(object: w)) |
414 | if (m->menuAction()) |
415 | highlightAction(a: m->menuAction(), on); |
416 | } |
417 | |
418 | static void highlightTarget(const TranslatableEntry &target, bool on) |
419 | { |
420 | switch (target.type) { |
421 | case TranslatableProperty: |
422 | if (QAction *a = qobject_cast<QAction *>(object: target.target.object)) { |
423 | highlightAction(a, on); |
424 | } else if (QWidget *w = qobject_cast<QWidget *>(o: 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(w: static_cast<QWidget *>(target.target.object)); |
455 | highlightWidget(w: static_cast<QWidget *>(target.target.object), on); |
456 | break; |
457 | #ifndef QT_NO_LISTWIDGET |
458 | case TranslatableListWidgetItem: |
459 | bringToFront(w: target.target.listWidgetItem->listWidget()); |
460 | highlightWidgetItem(item: target.target.listWidgetItem, on); |
461 | break; |
462 | #endif |
463 | #ifndef QT_NO_TABLEWIDGET |
464 | case TranslatableTableWidgetItem: |
465 | bringToFront(w: target.target.tableWidgetItem->tableWidget()); |
466 | highlightWidgetItem(item: target.target.tableWidgetItem, on); |
467 | break; |
468 | #endif |
469 | #ifndef QT_NO_TREEWIDGET |
470 | case TranslatableTreeWidgetItem: |
471 | bringToFront(w: target.target.treeWidgetItem->treeWidget()); |
472 | highlightTreeWidgetItem(item: target.target.treeWidgetItem, col: target.prop.treeIndex.column, on); |
473 | break; |
474 | #endif |
475 | } |
476 | } |
477 | |
478 | static void highlightTargets(const QList<TranslatableEntry> &targets, bool on) |
479 | { |
480 | foreach (const TranslatableEntry &target, targets) |
481 | highlightTarget(target, on); |
482 | } |
483 | |
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(widget: m_mdiSubWindow); |
491 | setCentralWidget(m_mdiArea); |
492 | m_mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); |
493 | m_mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); |
494 | } |
495 | |
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(path: dir.absoluteFilePath(fileName: 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(targets: &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(flags: QIODevice::ReadOnly)) { |
521 | qDebug() << "CANNOT OPEN FORM" << fileName; |
522 | m_mdiSubWindow->hide(); |
523 | return; |
524 | } |
525 | m_form = uiLoader->load(device: &file, parentWidget: m_mdiSubWindow); |
526 | if (!m_form) { |
527 | qDebug() << "CANNOT LOAD FORM" << fileName; |
528 | m_mdiSubWindow->hide(); |
529 | return; |
530 | } |
531 | file.close(); |
532 | buildTargets(o: m_form, targets: &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(targets: m_highlights, on: false); |
549 | } |
550 | QUiTranslatableStringValue tsv; |
551 | tsv.setValue(messageItem->text().toUtf8()); |
552 | tsv.setQualifier(messageItem->comment().toUtf8()); |
553 | m_highlights = m_targets.value(akey: tsv); |
554 | if (m_lastModel != model) { |
555 | for (TargetsHash::Iterator it = m_targets.begin(), end = m_targets.end(); it != end; ++it) |
556 | retranslateTargets(targets: *it, tsv: it.key(), dataModel: m_dataModel->model(i: model), className: m_lastClassName); |
557 | m_lastModel = model; |
558 | } else { |
559 | retranslateTargets(targets: m_highlights, tsv, dataModel: m_dataModel->model(i: model), className: m_lastClassName); |
560 | } |
561 | highlightTargets(targets: m_highlights, on: true); |
562 | } |
563 | |
564 | QT_END_NAMESPACE |
565 | |