8#include <QtUiPlugin/customwidget.h>
10#include <formbuilder.h>
11#include <formbuilderextra_p.h>
12#include <textbuilder_p.h>
15#include <QtWidgets/qapplication.h>
16#include <QtWidgets/qlayout.h>
17#include <QtWidgets/qwidget.h>
18#if QT_CONFIG(tabwidget)
19# include <QtWidgets/qtabwidget.h>
21#if QT_CONFIG(treewidget)
22# include <QtWidgets/qtreewidget.h>
24#if QT_CONFIG(listwidget)
25# include <QtWidgets/qlistwidget.h>
27#if QT_CONFIG(tablewidget)
28# include <QtWidgets/qtablewidget.h>
31# include <QtWidgets/qtoolbox.h>
33#if QT_CONFIG(combobox)
34# include <QtWidgets/qcombobox.h>
37#include <QtGui/qaction.h>
38#include <QtGui/qactiongroup.h>
40#include <QtCore/qdebug.h>
41#include <QtCore/qdatastream.h>
42#include <QtCore/qmap.h>
43#include <QtCore/qdir.h>
44#include <QtCore/qlibraryinfo.h>
54#ifndef QT_NO_DATASTREAM
59 out << s.qualifier() << s.value();
65 QByteArray qualifier, value;
66 in >> qualifier >> value;
67 s.setQualifier(qualifier);
73QString QUiTranslatableStringValue::translate(
const QByteArray &className,
bool idBased)
const
76 ? qtTrId(m_qualifier.constData())
77 : QCoreApplication::translate(className.constData(), m_value.constData(), m_qualifier.constData());
80#ifdef QFORMINTERNAL_NAMESPACE
81namespace QFormInternal
95 bool idBased()
const {
return m_idBased; }
100 QByteArray m_className;
105 const DomString *str = text->elementString();
108 if (str->hasAttributeNotr()) {
109 const QString notr = str->attributeNotr();
111 return QVariant::fromValue(str->text());
113 QUiTranslatableStringValue strVal;
114 strVal.setValue(str->text().toUtf8());
116 strVal.setQualifier(str->attributeId().toUtf8());
117 else if (str->hasAttributeComment())
118 strVal.setQualifier(str->attributeComment().toUtf8());
119 return QVariant::fromValue(strVal);
124 if (value.canConvert<QUiTranslatableStringValue>()) {
125 QUiTranslatableStringValue tsv = qvariant_cast<QUiTranslatableStringValue>(value);
127 return QString::fromUtf8(tsv.value().constData());
128 return QVariant::fromValue(tsv.translate(m_className, m_idBased));
130 if (value.canConvert<QString>())
131 return QVariant::fromValue(qvariant_cast<QString>(value));
137 { Qt::DisplayRole, Qt::DisplayPropertyRole },
138#if QT_CONFIG(tooltip)
139 { Qt::ToolTipRole, Qt::ToolTipPropertyRole },
141#if QT_CONFIG(statustip)
142 { Qt::StatusTipRole, Qt::StatusTipPropertyRole },
144#if QT_CONFIG(whatsthis)
145 { Qt::WhatsThisRole, Qt::WhatsThisPropertyRole },
150#if QT_CONFIG(treewidget)
151static void recursiveReTranslate(QTreeWidgetItem *item,
const QByteArray &class_name,
bool idBased)
153 const QUiItemRolePair *irs = qUiItemRoles;
155 int cnt = item->columnCount();
156 for (
int i = 0; i < cnt; ++i) {
157 for (
unsigned j = 0; irs[j].shadowRole >= 0; j++) {
158 QVariant v = item->data(i, irs[j].shadowRole);
160 QUiTranslatableStringValue tsv = qvariant_cast<QUiTranslatableStringValue>(v);
161 item->setData(i, irs[j].realRole, tsv.translate(class_name, idBased));
166 cnt = item->childCount();
167 for (
int i = 0; i < cnt; ++i)
168 recursiveReTranslate(item->child(i), class_name, idBased);
177 for (
unsigned j = 0; irs[j]
.shadowRole >= 0; j++) {
178 QVariant v = item->data(irs[j].shadowRole);
180 QUiTranslatableStringValue tsv = qvariant_cast<QUiTranslatableStringValue>(v);
181 item->setData(irs[j]
.realRole, tsv.translate(class_name, idBased));
186#if QT_CONFIG(tablewidget)
187static void reTranslateTableItem(QTableWidgetItem *item,
const QByteArray &class_name,
bool idBased)
190 reTranslateWidgetItem(item, class_name, idBased);
194#define RETRANSLATE_SUBWIDGET_PROP(mainWidget, setter, propName)
196 QVariant v = mainWidget->widget(i)->property(propName);
198 QUiTranslatableStringValue tsv = qvariant_cast<QUiTranslatableStringValue>(v);
199 mainWidget->setter(i, tsv.translate(m_className, m_idBased));
228#if QT_CONFIG(tabwidget)
231 for (
int i = 0;
i <
cnt; ++
i) {
233#if QT_CONFIG(tooltip)
236#if QT_CONFIG(whatsthis)
241#if QT_CONFIG(listwidget)
244 for (
int i = 0;
i <
cnt; ++
i)
247#if QT_CONFIG(treewidget)
252 for (
int i = 0;
i <
cnt; ++
i) {
257#if QT_CONFIG(tablewidget)
269#if QT_CONFIG(combobox)
273 for (
int i = 0;
i <
cnt; ++
i) {
282#if QT_CONFIG(toolbox)
285 for (
int i = 0;
i <
cnt; ++
i) {
287#if QT_CONFIG(tooltip)
318 return ParentClass::createWidget(className, parent, name);
323 return ParentClass::createLayout(className, parent, name);
328 return ParentClass::createAction(parent, name);
333 return ParentClass::createActionGroup(parent, name);
338 if (
QWidget *widget =
loader->createWidget(className, parent, name)) {
339 widget->setObjectName(name);
348 if (QLayout *layout =
loader->createLayout(className, parent, name)) {
349 layout->setObjectName(name);
358 if (QActionGroup *actionGroup =
loader->createActionGroup(parent, name)) {
359 actionGroup->setObjectName(name);
368 if (QAction *action =
loader->createAction(parent, name)) {
369 action->setObjectName(name);
384 bool m_idBased =
false;
388 bool idBased, QUiTranslatableStringValue *strVal)
390 if (p->kind() != DomProperty::String)
392 const DomString *dom_str = p->elementString();
395 if (dom_str->hasAttributeNotr()) {
396 const QString notr = dom_str->attributeNotr();
400 strVal->setValue(dom_str->text().toUtf8());
401 strVal->setQualifier(idBased ? dom_str->attributeId().toUtf8() : dom_str->attributeComment().toUtf8());
402 if (strVal->value().isEmpty() && strVal->qualifier().isEmpty())
404 return strVal->translate(className, idBased);
409 QFormBuilder::applyProperties(o, properties);
412 m_trwatch =
new TranslationWatcher(o, m_class, m_idBased);
414 if (properties.isEmpty())
421 for (
const DomProperty *p : properties) {
422 QUiTranslatableStringValue strVal;
423 const QString text = convertTranslatable(p, m_class, m_idBased, &strVal);
426 const QByteArray name = p->attributeName().toUtf8();
429 o->setProperty(dynname, QVariant::fromValue(strVal));
432 if (p->elementString()->text() != text)
433 o->setProperty(name, text);
436 o->installEventFilter(m_trwatch);
441 m_class = ui->elementClass().toUtf8();
443 m_idBased = ui->attributeIdbasedtr();
444 setTextBuilder(
new TranslatingTextBuilder(m_idBased, trEnabled, m_class));
445 return QFormBuilder::create(ui, parentWidget);
450 QWidget *w = QFormBuilder::create(ui_widget, parentWidget);
455#if QT_CONFIG(tabwidget)
456 }
else if (qobject_cast<QTabWidget*>(w)) {
458#if QT_CONFIG(listwidget)
459 }
else if (qobject_cast<QListWidget*>(w)) {
461#if QT_CONFIG(treewidget)
462 }
else if (qobject_cast<QTreeWidget*>(w)) {
464#if QT_CONFIG(tablewidget)
465 }
else if (qobject_cast<QTableWidget*>(w)) {
467#if QT_CONFIG(combobox)
468 }
else if (qobject_cast<QComboBox*>(w)) {
469 if (QFormBuilderExtra::isQFontComboBox(w))
472#if QT_CONFIG(toolbox)
473 }
else if (qobject_cast<QToolBox*>(w)) {
479 w->installEventFilter(m_trwatch);
483#define TRANSLATE_SUBWIDGET_PROP(mainWidget, attribute, setter, propName)
485 if (const auto *p = attributes.value(attribute)) {
486 QUiTranslatableStringValue strVal;
487 const QString text = convertTranslatable(p, m_class, m_idBased, &strVal);
488 if (!text.isEmpty()) {
490 mainWidget->widget(i)->setProperty(propName, QVariant::fromValue(strVal));
491 mainWidget->setter(i, text);
498 if (parentWidget ==
nullptr)
501 if (!ParentClass::addItem(ui_widget, widget, parentWidget))
505 const QString className = QLatin1String(parentWidget->metaObject()->className());
506 if (!d->customWidgetAddPageMethod(className).isEmpty())
510#if QT_CONFIG(tabwidget)
511 }
else if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) {
512 const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
513 const int i = tabWidget->count() - 1;
514 TRANSLATE_SUBWIDGET_PROP(tabWidget, QFormBuilderStrings::titleAttribute,
515 setTabText, PROP_TABPAGETEXT);
516#if QT_CONFIG(tooltip)
517 TRANSLATE_SUBWIDGET_PROP(tabWidget, QFormBuilderStrings::toolTipAttribute,
518 setTabToolTip, PROP_TABPAGETOOLTIP);
520#if QT_CONFIG(whatsthis)
521 TRANSLATE_SUBWIDGET_PROP(tabWidget, QFormBuilderStrings::whatsThisAttribute,
522 setTabWhatsThis, PROP_TABPAGEWHATSTHIS);
525#if QT_CONFIG(toolbox)
526 }
else if (QToolBox *toolBox = qobject_cast<QToolBox*>(parentWidget)) {
527 const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
528 const int i = toolBox->count() - 1;
529 TRANSLATE_SUBWIDGET_PROP(toolBox, QFormBuilderStrings::labelAttribute,
530 setItemText, PROP_TOOLITEMTEXT);
531#if QT_CONFIG(tooltip)
532 TRANSLATE_SUBWIDGET_PROP(toolBox, QFormBuilderStrings::toolTipAttribute,
533 setItemToolTip, PROP_TOOLITEMTOOLTIP);
541#ifdef QFORMINTERNAL_NAMESPACE
548#ifdef QFORMINTERNAL_NAMESPACE
559 if (!g_widgets()->isEmpty())
562#define DECLARE_WIDGET(a, b) g_widgets()->insert(QLatin1String(#a), true);
563#define DECLARE_LAYOUT(a, b)
565#include "widgets.table"
568#undef DECLARE_WIDGET_1
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
628
629
630QUiLoader::QUiLoader(QObject *parent)
631 : QObject(parent), d_ptr(
new QUiLoaderPrivate)
635#ifndef QT_NO_DATASTREAM
636 static int metaTypeId = 0;
638 metaTypeId = qRegisterMetaType<QUiTranslatableStringValue>(
"QUiTranslatableStringValue");
641 d->builder.loader =
this;
643#if QT_CONFIG(library)
645 const QStringList &libraryPaths = QApplication::libraryPaths();
646 for (
const QString &path : libraryPaths) {
647 QString libPath = path;
648 libPath += QDir::separator();
649 libPath += QStringLiteral(
"designer");
650 paths.append(libPath);
653 d->builder.setPluginPath(paths);
658
659
660QUiLoader::~QUiLoader() =
default;
663
664
665
666
667
668QWidget *QUiLoader::load(QIODevice *device, QWidget *parentWidget)
672 if (!device->isOpen())
673 device->open(QIODevice::ReadOnly|QIODevice::Text);
674 return d->builder.load(device, parentWidget);
678
679
680
681
682
683QStringList QUiLoader::pluginPaths()
const
685 Q_D(
const QUiLoader);
686 return d->builder.pluginPaths();
690
691
692
693
694
695void QUiLoader::clearPluginPaths()
698 d->builder.clearPluginPaths();
702
703
704
705
706
707void QUiLoader::addPluginPath(
const QString &path)
710 d->builder.addPluginPath(path);
714
715
716
717
718
719
720
721
722
723
724
725
726QWidget *QUiLoader::createWidget(
const QString &className, QWidget *parent,
const QString &name)
729 return d->builder.defaultCreateWidget(className, parent, name);
733
734
735
736
737
738
739
740
741
742
743
744QLayout *QUiLoader::createLayout(
const QString &className, QObject *parent,
const QString &name)
747 return d->builder.defaultCreateLayout(className, parent, name);
751
752
753
754
755
756
757
758
759
760
761QActionGroup *QUiLoader::createActionGroup(QObject *parent,
const QString &name)
764 return d->builder.defaultCreateActionGroup(parent, name);
768
769
770
771
772
773
774
775
776
777
778QAction *QUiLoader::createAction(QObject *parent,
const QString &name)
781 return d->builder.defaultCreateAction(parent, name);
785
786
787
788
789
790
791
792QStringList QUiLoader::availableWidgets()
const
794 Q_D(
const QUiLoader);
797 widget_map available = *g_widgets();
799 const auto &customWidgets = d->builder.customWidgets();
800 for (QDesignerCustomWidgetInterface *plugin : customWidgets)
801 available.insert(plugin->name(),
true);
803 return available.keys();
808
809
810
811
812
813
815QStringList QUiLoader::availableLayouts()
const
818#define DECLARE_WIDGET(a, b)
819#define DECLARE_LAYOUT(a, b) rc.push_back(QLatin1String(#a));
821#include "widgets.table"
829
830
831
832
833
834
836void QUiLoader::setWorkingDirectory(
const QDir &dir)
839 d->builder.setWorkingDirectory(dir);
843
844
845
846
848QDir QUiLoader::workingDirectory()
const
850 Q_D(
const QUiLoader);
851 return d->builder.workingDirectory();
854
855
856
857
858
859
860
861
863void QUiLoader::setLanguageChangeEnabled(
bool enabled)
866 d->builder.dynamicTr = enabled;
870
871
872
873
874
875
876
878bool QUiLoader::isLanguageChangeEnabled()
const
880 Q_D(
const QUiLoader);
881 return d->builder.dynamicTr;
885
886
887
888
889
890
891
892
893
894
896void QUiLoader::setTranslationEnabled(
bool enabled)
899 d->builder.trEnabled = enabled;
903
904
905
906
907
908
909
911bool QUiLoader::isTranslationEnabled()
const
913 Q_D(
const QUiLoader);
914 return d->builder.trEnabled;
918
919
920
921
922
924QString QUiLoader::errorString()
const
926 Q_D(
const QUiLoader);
927 return d->builder.errorString();
932#include "quiloader.moc"
friend class QT_PREPEND_NAMESPACE(QQmlJS::LoggerCategory)
void setupWidgetMap() const
FormBuilderPrivate builder
QVariant toNativeValue(const QVariant &value) const override
QVariant loadText(const DomProperty *icon) const override
TranslatingTextBuilder(bool idBased, bool trEnabled, const QByteArray &className)
Q_GLOBAL_STATIC(QReadWriteLock, g_updateMutex)
#define QStringLiteral(str)
const QUiItemRolePair qUiItemRoles[]
static void reTranslateWidgetItem(T *item, const QByteArray &class_name, bool idBased)
QT_BEGIN_NAMESPACE typedef QMap< QString, bool > widget_map
static QString convertTranslatable(const DomProperty *p, const QByteArray &className, bool idBased, QUiTranslatableStringValue *strVal)
#define PROP_GENERIC_PREFIX
QDataStream & operator<<(QDataStream &stream, const QImage &image)
[0]
QDataStream & operator>>(QDataStream &stream, QImage &image)