9#include <QtWidgets/QApplication>
11# ifndef QT_NO_FONTCOMBOBOX
12# include <QtWidgets/QFontComboBox>
14# include <QtWidgets/QComboBox>
17#include <QtWidgets/QFrame>
18#include <QtWidgets/QGridLayout>
19#include <QtWidgets/QListWidget>
20#include <QtWidgets/QMdiArea>
21#include <QtWidgets/QMdiSubWindow>
22#include <QtWidgets/QMenu>
23#include <QtWidgets/QStackedLayout>
24#include <QtWidgets/QStackedWidget>
25#include <QtWidgets/QTableWidget>
26#include <QtWidgets/QTabWidget>
27#include <QtWidgets/QToolBox>
28#include <QtWidgets/QTreeWidget>
29#include <QtWidgets/QScrollArea>
31#include <QtGui/QAction>
33#include <QtCore/QDebug>
34#include <QtCore/QTime>
38#if defined(Q_CC_SUN) || defined(Q_CC_HPACC) || defined(Q_CC_XLC)
39size_t qHash(
const QUiTranslatableStringValue &tsv)
44 return qHash(tsv.value()) ^ qHash(tsv.qualifier());
47static bool operator==(
const QUiTranslatableStringValue &tsv1,
const QUiTranslatableStringValue &tsv2)
49 return tsv1.value() == tsv2.value() && tsv1.qualifier() == tsv2.qualifier();
52#define INSERT_TARGET(_tsv, _type, _target, _prop)
55 target.target._target;
57 (*targets)[qvariant_cast<QUiTranslatableStringValue>(_tsv)].append(target);
62 const QUiItemRolePair *irs = QFormInternal::qUiItemRoles;
64 int cnt = item->columnCount();
65 for (
int i = 0; i < cnt; ++i) {
66 for (
unsigned j = 0; irs[j].shadowRole >= 0; j++) {
67 QVariant v = item->data(i, irs[j].shadowRole);
70 target.prop.treeIndex
.column = i;
76 cnt = item->childCount();
77 for (
int j = 0; j < cnt; ++j)
78 registerTreeItem(item->child(j), targets);
81#define REGISTER_ITEM_CORE(item, propType, targetName)
82 const QUiItemRolePair *irs = QFormInternal::qUiItemRoles;
83 for (unsigned j = 0
; irs[j].shadowRole >= 0
; j++) {
84 QVariant v = item->data(irs[j].shadowRole);
104#define REGISTER_SUBWIDGET_PROP(mainWidget, propType, propName)
106 QVariant v = mainWidget->widget(i)->property(propName);
115 const auto propNames = o->dynamicPropertyNames();
116 for (
const QByteArray &prop : propNames) {
117 if (prop.startsWith(PROP_GENERIC_PREFIX)) {
118 const QByteArray propName = prop.mid(
sizeof(PROP_GENERIC_PREFIX) - 1);
120 TranslatableProperty, object = o, name = qstrdup(propName.data()));
124#ifndef QT_NO_TABWIDGET
125 }
else if (QTabWidget *tabw = qobject_cast<QTabWidget*>(o)) {
126 const int cnt = tabw->count();
127 for (
int i = 0; i < cnt; ++i) {
129# ifndef QT_NO_TOOLTIP
132# ifndef QT_NO_WHATSTHIS
138 }
else if (QToolBox *toolw = qobject_cast<QToolBox*>(o)) {
139 const int cnt = toolw->count();
140 for (
int i = 0; i < cnt; ++i) {
142# ifndef QT_NO_TOOLTIP
147#ifndef QT_NO_COMBOBOX
148 }
else if (QComboBox *combow = qobject_cast<QComboBox*>(o)) {
149# ifndef QT_NO_FONTCOMBOBOX
150 if (!qobject_cast<QFontComboBox*>(o)) {
154 const int cnt = combow->count();
155 for (
int i = 0; i < cnt; ++i) {
156 const QVariant v = combow->itemData(i, Qt::DisplayPropertyRole);
162#ifndef QT_NO_LISTWIDGET
163 }
else if (QListWidget *listw = qobject_cast<QListWidget*>(o)) {
164 const int cnt = listw->count();
165 for (
int i = 0; i < cnt; ++i)
166 registerListItem(listw->item(i), targets);
168#ifndef QT_NO_TABLEWIDGET
169 }
else if (QTableWidget *tablew = qobject_cast<QTableWidget*>(o)) {
170 const int row_cnt = tablew->rowCount();
171 const int col_cnt = tablew->columnCount();
172 for (
int j = 0; j < col_cnt; ++j)
173 registerTableItem(tablew->horizontalHeaderItem(j), targets);
174 for (
int i = 0; i < row_cnt; ++i) {
175 registerTableItem(tablew->verticalHeaderItem(i), targets);
176 for (
int j = 0; j < col_cnt; ++j)
177 registerTableItem(tablew->item(i, j), targets);
180#ifndef QT_NO_TREEWIDGET
181 }
else if (QTreeWidget *treew = qobject_cast<QTreeWidget*>(o)) {
182 if (QTreeWidgetItem *item = treew->headerItem())
183 registerTreeItem(item, targets);
184 const int cnt = treew->topLevelItemCount();
185 for (
int i = 0; i < cnt; ++i)
186 registerTreeItem(treew->topLevelItem(i), targets);
189 for (QObject *co : o->children())
190 buildTargets(co, targets);
195 for (
const auto &targetList : std::as_const(*targets))
196 for (
const TranslatableEntry &target : targetList)
197 if (target.type == TranslatableProperty)
198 delete target.prop.name;
204 switch (target
.type) {
206 target.target.object->setProperty(target.prop
.name, text);
208#ifndef QT_NO_TABWIDGET
210 target.target.tabWidget->setTabText(target.prop
.index, text);
212# ifndef QT_NO_TOOLTIP
214 target.target.tabWidget->setTabToolTip(target.prop
.index, text);
217# ifndef QT_NO_WHATSTHIS
219 target.target.tabWidget->setTabWhatsThis(target.prop
.index, text);
225 target.target.toolBox->setItemText(target.prop
.index, text);
227# ifndef QT_NO_TOOLTIP
229 target.target.toolBox->setItemToolTip(target.prop
.index, text);
233#ifndef QT_NO_COMBOBOX
235 target.target.comboBox->setItemText(target.prop
.index, text);
238#ifndef QT_NO_LISTWIDGET
240 target.target.listWidgetItem->setData(target.prop
.index, text);
243#ifndef QT_NO_TABLEWIDGET
245 target.target.tableWidgetItem->setData(target.prop
.index, text);
248#ifndef QT_NO_TREEWIDGET
250 target.target.treeWidgetItem->setData(target.prop.treeIndex
.column,
251 target.prop.treeIndex
.index, text);
258 const QUiTranslatableStringValue &tsv,
const DataModel *dataModel,
259 const QString &className,
const QString &labelName)
261 QString sourceText = QString::fromUtf8(tsv.value());
263 if (
MessageItem *msg = dataModel->findMessage(className, labelName, sourceText,
264 QString::fromUtf8(tsv.qualifier())))
265 text = msg->translation();
266 if (text.isEmpty() && !tsv.value().isEmpty())
267 text = u'#' + sourceText;
269 for (
const TranslatableEntry &target : targets)
270 retranslateTarget(target, text);
275 for (;
QWidget *pw = w->parentWidget(); w = pw) {
276#ifndef QT_NO_STACKEDWIDGET
277 if (QStackedWidget *stack = qobject_cast<QStackedWidget *>(pw)) {
278#ifndef QT_NO_TABWIDGET
281 if (QTabWidget *tab = qobject_cast<QTabWidget *>(stack->parent()))
282 tab->setCurrentWidget(w);
285 stack->setCurrentWidget(w);
290 if (QScrollArea *sv = qobject_cast<QScrollArea *>(pw)) {
291 if (QToolBox *tb = qobject_cast<QToolBox *>(sv->parent()))
292 tb->setCurrentWidget(w);
300 QVariant br = item->data(col, Qt::BackgroundRole + 500);
301 QVariant fr = item->data(col, Qt::ForegroundRole + 500);
303 if (!br.isValid() && !fr.isValid()) {
304 item->setData(col, Qt::BackgroundRole + 500, item->data(col, Qt::BackgroundRole));
305 item->setData(col, Qt::ForegroundRole + 500, item->data(col, Qt::ForegroundRole));
306 QPalette pal = qApp->palette();
307 item->setData(col, Qt::BackgroundRole, pal.color(QPalette::Dark));
308 item->setData(col, Qt::ForegroundRole, pal.color(QPalette::Light));
311 if (br.isValid() || fr.isValid()) {
312 item->setData(col, Qt::BackgroundRole, br);
313 item->setData(col, Qt::ForegroundRole, fr);
314 item->setData(col, Qt::BackgroundRole + 500, QVariant());
315 item->setData(col, Qt::ForegroundRole + 500, QVariant());
323 QVariant br = item->data(Qt::BackgroundRole + 500);
324 QVariant fr = item->data(Qt::ForegroundRole + 500);
326 if (!br.isValid() && !fr.isValid()) {
327 item->setData(Qt::BackgroundRole + 500, item->data(Qt::BackgroundRole));
328 item->setData(Qt::ForegroundRole + 500, item->data(Qt::ForegroundRole));
329 QPalette pal = qApp->palette();
330 item->setData(Qt::BackgroundRole, pal.color(QPalette::Dark));
331 item->setData(Qt::ForegroundRole, pal.color(QPalette::Light));
334 if (br.isValid() || fr.isValid()) {
335 item->setData(Qt::BackgroundRole, br);
336 item->setData(Qt::ForegroundRole, fr);
337 item->setData(Qt::BackgroundRole + 500, QVariant());
338 item->setData(Qt::ForegroundRole + 500, QVariant());
343#define AUTOFILL_BACKUP_PROP "_q_linguist_autoFillBackup"
344#define PALETTE_BACKUP_PROP "_q_linguist_paletteBackup"
345#define FONT_BACKUP_PROP "_q_linguist_fontBackup"
353 if (!bak.isValid()) {
354 QFont fnt = qApp->font();
355 a->setProperty(
FONT_BACKUP_PROP, QVariant::fromValue(a->font().resolve(fnt)));
362 a->setFont(qvariant_cast<QFont>(bak));
366 for (QObject *o : a->associatedObjects()) {
367 if (QWidget *w = qobject_cast<QWidget *>(o))
368 highlightWidget(w, on);
376 if (!bak.isValid()) {
377 QPalette pal = qApp->palette();
378 for (QObject *co : w->children())
379 if (QWidget *cw = qobject_cast<QWidget *>(co))
380 cw->setPalette(cw->palette().resolve(pal));
383 QColor col1 = pal.color(QPalette::Dark);
384 QColor col2 = pal.color(QPalette::Light);
385 pal.setColor(QPalette::Base, col1);
386 pal.setColor(QPalette::Window, col1);
387 pal.setColor(QPalette::Button, col1);
388 pal.setColor(QPalette::Text, col2);
389 pal.setColor(QPalette::WindowText, col2);
390 pal.setColor(QPalette::ButtonText, col2);
391 pal.setColor(QPalette::BrightText, col2);
393 w->setAutoFillBackground(
true);
397 w->setPalette(qvariant_cast<QPalette>(bak));
403 if (QMenu *m = qobject_cast<QMenu *>(w))
405 highlightAction(m->menuAction(), on);
410 switch (target
.type) {
412 if (QAction *a = qobject_cast<QAction *>(target.target.object)) {
414 }
else if (
QWidget *w = qobject_cast<
QWidget *>(target.target.object)) {
419#ifndef QT_NO_COMBOBOX
421 static_cast<QComboBox *>(target.target.object)->setCurrentIndex(target.prop
.index);
422 goto frontAndHighlight;
424#ifndef QT_NO_TABWIDGET
426 static_cast<QTabWidget *>(target.target.object)->setCurrentIndex(target.prop
.index);
427 goto frontAndHighlight;
428# ifndef QT_NO_TOOLTIP
431# ifndef QT_NO_WHATSTHIS
437# ifndef QT_NO_TOOLTIP
441#if !defined(QT_NO_COMBOBOX) || !defined(QT_NO_TABWIDGET)
447#ifndef QT_NO_LISTWIDGET
449 bringToFront(target.target.listWidgetItem->listWidget());
450 highlightWidgetItem(target.target.listWidgetItem, on);
453#ifndef QT_NO_TABLEWIDGET
455 bringToFront(target.target.tableWidgetItem->tableWidget());
456 highlightWidgetItem(target.target.tableWidgetItem, on);
459#ifndef QT_NO_TREEWIDGET
461 bringToFront(target.target.treeWidgetItem->treeWidget());
462 highlightTreeWidgetItem(target.target.treeWidgetItem, target.prop.treeIndex
.column, on);
470 for (
const TranslatableEntry &target : targets)
471 highlightTarget(target, on);
475 : QMainWindow(parent), m_form(0), m_dataModel(dataModel)
477 m_mdiSubWindow =
new QMdiSubWindow;
478 m_mdiSubWindow->setWindowFlags(m_mdiSubWindow->windowFlags() & ~Qt::WindowSystemMenuHint);
479 m_mdiArea =
new QMdiArea(
this);
480 m_mdiArea->addSubWindow(m_mdiSubWindow);
481 setCentralWidget(m_mdiArea);
482 m_mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
483 m_mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
488 if (model < 0 || !messageItem) {
493 QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir();
494 QString fileName = QDir::cleanPath(dir.absoluteFilePath(messageItem->fileName()));
495 if (m_lastFormName != fileName) {
498 m_lastFormName.clear();
499 m_highlights.clear();
500 destroyTargets(&m_targets);
502 static QUiLoader *uiLoader;
504 uiLoader =
new QUiLoader(
this);
505 uiLoader->setLanguageChangeEnabled(
true);
506 uiLoader->setTranslationEnabled(
false);
509 QFile file(fileName);
510 if (!file.open(QIODevice::ReadOnly)) {
511 qDebug() <<
"CANNOT OPEN FORM" << fileName;
512 m_mdiSubWindow->hide();
515 m_form = uiLoader->load(&file, m_mdiSubWindow);
517 qDebug() <<
"CANNOT LOAD FORM" << fileName;
518 m_mdiSubWindow->hide();
522 buildTargets(m_form, &m_targets);
524 setToolTip(fileName);
526 m_form->setWindowFlags(Qt::Widget);
527 m_form->setWindowModality(Qt::NonModal);
528 m_form->setFocusPolicy(Qt::NoFocus);
530 m_mdiSubWindow->setWidget(m_form);
531 m_mdiSubWindow->setWindowTitle(m_form->windowTitle());
532 m_mdiSubWindow->show();
533 m_mdiArea->cascadeSubWindows();
534 m_lastFormName = fileName;
535 m_lastClassName = messageItem->context();
536 m_lastLabelName = messageItem->label();
539 highlightTargets(m_highlights,
false);
541 QUiTranslatableStringValue tsv;
542 tsv.setValue(messageItem->text().toUtf8());
543 tsv.setQualifier(messageItem->comment().toUtf8());
544 m_highlights = m_targets.value(tsv);
545 if (m_lastModel != model) {
546 for (
auto it = m_targets.cbegin(), end = m_targets.cend(); it != end; ++it)
547 retranslateTargets(*it, it.key(), m_dataModel->model(model), m_lastClassName,
551 retranslateTargets(m_highlights, tsv, m_dataModel->model(model), m_lastClassName,
554 highlightTargets(m_highlights,
true);
TranslatableEntryType type