source: trunk/tools/designer/src/uitools/quiloader.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 29.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation (qt-info@nokia.com)
6**
7** This file is part of the Qt Designer of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at qt-info@nokia.com.
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42
43#include "quiloader.h"
44#include "quiloader_p.h"
45#include "customwidget.h"
46
47#include <formbuilder.h>
48#include <formbuilderextra_p.h>
49#include <textbuilder_p.h>
50#include <ui4_p.h>
51
52#include <QtCore/qdebug.h>
53#include <QtGui/QAction>
54#include <QtGui/QActionGroup>
55#include <QtGui/QApplication>
56#include <QtCore/QDir>
57#include <QtCore/QLibraryInfo>
58#include <QtGui/QLayout>
59#include <QtGui/QWidget>
60#include <QtCore/QMap>
61#include <QtGui/QTabWidget>
62#include <QtGui/QTreeWidget>
63#include <QtGui/QListWidget>
64#include <QtGui/QTableWidget>
65#include <QtGui/QToolBox>
66#include <QtGui/QComboBox>
67#include <QtGui/QFontComboBox>
68
69QT_BEGIN_NAMESPACE
70
71typedef QMap<QString, bool> widget_map;
72Q_GLOBAL_STATIC(widget_map, g_widgets)
73
74class QUiLoader;
75class QUiLoaderPrivate;
76
77#ifdef QFORMINTERNAL_NAMESPACE
78namespace QFormInternal
79{
80#endif
81
82class TranslatingTextBuilder : public QTextBuilder
83{
84public:
85 TranslatingTextBuilder(bool trEnabled, const QByteArray &className) :
86 m_trEnabled(trEnabled), m_className(className) {}
87
88 virtual QVariant loadText(const DomProperty *icon) const;
89
90 virtual QVariant toNativeValue(const QVariant &value) const;
91
92private:
93 bool m_trEnabled;
94 QByteArray m_className;
95};
96
97QVariant TranslatingTextBuilder::loadText(const DomProperty *text) const
98{
99 const DomString *str = text->elementString();
100 if (!str)
101 return QVariant();
102 if (str->hasAttributeNotr()) {
103 const QString notr = str->attributeNotr();
104 if (notr == QLatin1String("true") || notr == QLatin1String("yes"))
105 return qVariantFromValue(str->text());
106 }
107 QUiTranslatableStringValue strVal;
108 strVal.setValue(str->text().toUtf8());
109 if (str->hasAttributeComment())
110 strVal.setComment(str->attributeComment().toUtf8());
111 return qVariantFromValue(strVal);
112}
113
114QVariant TranslatingTextBuilder::toNativeValue(const QVariant &value) const
115{
116 if (qVariantCanConvert<QUiTranslatableStringValue>(value)) {
117 QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(value);
118 if (!m_trEnabled)
119 return QString::fromUtf8(tsv.value().data());
120 return qVariantFromValue(
121 QApplication::translate(m_className, tsv.value(), tsv.comment(),
122 QCoreApplication::UnicodeUTF8));
123 }
124 if (qVariantCanConvert<QString>(value))
125 return qVariantFromValue(qVariantValue<QString>(value));
126 return value;
127}
128
129// This is "exported" to linguist
130const QUiItemRolePair qUiItemRoles[] = {
131 { Qt::DisplayRole, Qt::DisplayPropertyRole },
132#ifndef QT_NO_TOOLTIP
133 { Qt::ToolTipRole, Qt::ToolTipPropertyRole },
134#endif
135#ifndef QT_NO_STATUSTIP
136 { Qt::StatusTipRole, Qt::StatusTipPropertyRole },
137#endif
138#ifndef QT_NO_WHATSTHIS
139 { Qt::WhatsThisRole, Qt::WhatsThisPropertyRole },
140#endif
141 { -1 , -1 }
142};
143
144static void recursiveReTranslate(QTreeWidgetItem *item, const QByteArray &class_name)
145{
146 const QUiItemRolePair *irs = qUiItemRoles;
147
148 int cnt = item->columnCount();
149 for (int i = 0; i < cnt; ++i) {
150 for (unsigned j = 0; irs[j].shadowRole >= 0; j++) {
151 QVariant v = item->data(i, irs[j].shadowRole);
152 if (v.isValid()) {
153 QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v);
154 const QString text = QApplication::translate(class_name,
155 tsv.value(), tsv.comment(),
156 QCoreApplication::UnicodeUTF8);
157 item->setData(i, irs[j].realRole, text);
158 }
159 }
160 }
161
162 cnt = item->childCount();
163 for (int i = 0; i < cnt; ++i)
164 recursiveReTranslate(item->child(i), class_name);
165}
166
167template<typename T>
168static void reTranslateWidgetItem(T *item, const QByteArray &class_name)
169{
170 const QUiItemRolePair *irs = qUiItemRoles;
171
172 for (unsigned j = 0; irs[j].shadowRole >= 0; j++) {
173 QVariant v = item->data(irs[j].shadowRole);
174 if (v.isValid()) {
175 QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v);
176 const QString text = QApplication::translate(class_name,
177 tsv.value(), tsv.comment(),
178 QCoreApplication::UnicodeUTF8);
179 item->setData(irs[j].realRole, text);
180 }
181 }
182}
183
184static void reTranslateTableItem(QTableWidgetItem *item, const QByteArray &class_name)
185{
186 if (item)
187 reTranslateWidgetItem(item, class_name);
188}
189
190#define RETRANSLATE_SUBWIDGET_PROP(mainWidget, setter, propName) \
191 do { \
192 QVariant v = mainWidget->widget(i)->property(propName); \
193 if (v.isValid()) { \
194 QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v); \
195 const QString text = QApplication::translate(m_className, \
196 tsv.value(), tsv.comment(), \
197 QCoreApplication::UnicodeUTF8); \
198 mainWidget->setter(i, text); \
199 } \
200 } while (0)
201
202class TranslationWatcher: public QObject
203{
204 Q_OBJECT
205
206public:
207 TranslationWatcher(QObject *parent, const QByteArray &className):
208 QObject(parent),
209 m_className(className)
210 {
211 }
212
213 virtual bool eventFilter(QObject *o, QEvent *event)
214 {
215 if (event->type() == QEvent::LanguageChange) {
216 foreach (const QByteArray &prop, o->dynamicPropertyNames()) {
217 if (prop.startsWith(PROP_GENERIC_PREFIX)) {
218 const QByteArray propName = prop.mid(sizeof(PROP_GENERIC_PREFIX) - 1);
219 const QUiTranslatableStringValue tsv =
220 qVariantValue<QUiTranslatableStringValue>(o->property(prop));
221 const QString text = QApplication::translate(m_className,
222 tsv.value(), tsv.comment(),
223 QCoreApplication::UnicodeUTF8);
224 o->setProperty(propName, text);
225 }
226 }
227 if (0) {
228#ifndef QT_NO_TABWIDGET
229 } else if (QTabWidget *tabw = qobject_cast<QTabWidget*>(o)) {
230 const int cnt = tabw->count();
231 for (int i = 0; i < cnt; ++i) {
232 RETRANSLATE_SUBWIDGET_PROP(tabw, setTabText, PROP_TABPAGETEXT);
233# ifndef QT_NO_TOOLTIP
234 RETRANSLATE_SUBWIDGET_PROP(tabw, setTabToolTip, PROP_TABPAGETOOLTIP);
235# endif
236# ifndef QT_NO_WHATSTHIS
237 RETRANSLATE_SUBWIDGET_PROP(tabw, setTabWhatsThis, PROP_TABPAGEWHATSTHIS);
238# endif
239 }
240#endif
241#ifndef QT_NO_LISTWIDGET
242 } else if (QListWidget *listw = qobject_cast<QListWidget*>(o)) {
243 const int cnt = listw->count();
244 for (int i = 0; i < cnt; ++i)
245 reTranslateWidgetItem(listw->item(i), m_className);
246#endif
247#ifndef QT_NO_TREEWIDGET
248 } else if (QTreeWidget *treew = qobject_cast<QTreeWidget*>(o)) {
249 if (QTreeWidgetItem *item = treew->headerItem())
250 recursiveReTranslate(item, m_className);
251 const int cnt = treew->topLevelItemCount();
252 for (int i = 0; i < cnt; ++i) {
253 QTreeWidgetItem *item = treew->topLevelItem(i);
254 recursiveReTranslate(item, m_className);
255 }
256#endif
257#ifndef QT_NO_TABLEWIDGET
258 } else if (QTableWidget *tablew = qobject_cast<QTableWidget*>(o)) {
259 const int row_cnt = tablew->rowCount();
260 const int col_cnt = tablew->columnCount();
261 for (int j = 0; j < col_cnt; ++j)
262 reTranslateTableItem(tablew->horizontalHeaderItem(j), m_className);
263 for (int i = 0; i < row_cnt; ++i) {
264 reTranslateTableItem(tablew->verticalHeaderItem(i), m_className);
265 for (int j = 0; j < col_cnt; ++j)
266 reTranslateTableItem(tablew->item(i, j), m_className);
267 }
268#endif
269#ifndef QT_NO_COMBOBOX
270 } else if (QComboBox *combow = qobject_cast<QComboBox*>(o)) {
271 if (!qobject_cast<QFontComboBox*>(o)) {
272 const int cnt = combow->count();
273 for (int i = 0; i < cnt; ++i) {
274 const QVariant v = combow->itemData(i, Qt::DisplayPropertyRole);
275 if (v.isValid()) {
276 QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v);
277 const QString text = QApplication::translate(m_className,
278 tsv.value(), tsv.comment(),
279 QCoreApplication::UnicodeUTF8);
280 combow->setItemText(i, text);
281 }
282 }
283 }
284#endif
285#ifndef QT_NO_TOOLBOX
286 } else if (QToolBox *toolw = qobject_cast<QToolBox*>(o)) {
287 const int cnt = toolw->count();
288 for (int i = 0; i < cnt; ++i) {
289 RETRANSLATE_SUBWIDGET_PROP(toolw, setItemText, PROP_TOOLITEMTEXT);
290# ifndef QT_NO_TOOLTIP
291 RETRANSLATE_SUBWIDGET_PROP(toolw, setItemToolTip, PROP_TOOLITEMTOOLTIP);
292# endif
293 }
294#endif
295 }
296 }
297 return false;
298 }
299
300private:
301 QByteArray m_className;
302};
303
304class FormBuilderPrivate: public QFormBuilder
305{
306 friend class QT_PREPEND_NAMESPACE(QUiLoader);
307 friend class QT_PREPEND_NAMESPACE(QUiLoaderPrivate);
308 typedef QFormBuilder ParentClass;
309
310public:
311 QUiLoader *loader;
312
313 bool dynamicTr;
314 bool trEnabled;
315
316 FormBuilderPrivate(): loader(0), dynamicTr(false), trEnabled(true), m_trwatch(0) {}
317
318 QWidget *defaultCreateWidget(const QString &className, QWidget *parent, const QString &name)
319 {
320 return ParentClass::createWidget(className, parent, name);
321 }
322
323 QLayout *defaultCreateLayout(const QString &className, QObject *parent, const QString &name)
324 {
325 return ParentClass::createLayout(className, parent, name);
326 }
327
328 QAction *defaultCreateAction(QObject *parent, const QString &name)
329 {
330 return ParentClass::createAction(parent, name);
331 }
332
333 QActionGroup *defaultCreateActionGroup(QObject *parent, const QString &name)
334 {
335 return ParentClass::createActionGroup(parent, name);
336 }
337
338 virtual QWidget *createWidget(const QString &className, QWidget *parent, const QString &name)
339 {
340 if (QWidget *widget = loader->createWidget(className, parent, name)) {
341 widget->setObjectName(name);
342 return widget;
343 }
344
345 return 0;
346 }
347
348 virtual QLayout *createLayout(const QString &className, QObject *parent, const QString &name)
349 {
350 if (QLayout *layout = loader->createLayout(className, parent, name)) {
351 layout->setObjectName(name);
352 return layout;
353 }
354
355 return 0;
356 }
357
358 virtual QActionGroup *createActionGroup(QObject *parent, const QString &name)
359 {
360 if (QActionGroup *actionGroup = loader->createActionGroup(parent, name)) {
361 actionGroup->setObjectName(name);
362 return actionGroup;
363 }
364
365 return 0;
366 }
367
368 virtual QAction *createAction(QObject *parent, const QString &name)
369 {
370 if (QAction *action = loader->createAction(parent, name)) {
371 action->setObjectName(name);
372 return action;
373 }
374
375 return 0;
376 }
377
378 virtual void applyProperties(QObject *o, const QList<DomProperty*> &properties);
379 virtual QWidget *create(DomUI *ui, QWidget *parentWidget);
380 virtual QWidget *create(DomWidget *ui_widget, QWidget *parentWidget);
381 virtual bool addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget);
382
383private:
384 QByteArray m_class;
385 TranslationWatcher *m_trwatch;
386};
387
388static QString convertTranslatable(const DomProperty *p, const QByteArray &className,
389 QUiTranslatableStringValue *strVal)
390{
391 if (p->kind() != DomProperty::String)
392 return QString();
393 const DomString *dom_str = p->elementString();
394 if (!dom_str)
395 return QString();
396 if (dom_str->hasAttributeNotr()) {
397 const QString notr = dom_str->attributeNotr();
398 if (notr == QLatin1String("yes") || notr == QLatin1String("true"))
399 return QString();
400 }
401 strVal->setValue(dom_str->text().toUtf8());
402 strVal->setComment(dom_str->attributeComment().toUtf8());
403 if (strVal->value().isEmpty() && strVal->comment().isEmpty())
404 return QString();
405 return QApplication::translate(className,
406 strVal->value(), strVal->comment(),
407 QCoreApplication::UnicodeUTF8);
408}
409
410void FormBuilderPrivate::applyProperties(QObject *o, const QList<DomProperty*> &properties)
411{
412 typedef QList<DomProperty*> DomPropertyList;
413
414 QFormBuilder::applyProperties(o, properties);
415
416 if (!m_trwatch)
417 m_trwatch = new TranslationWatcher(o, m_class);
418
419 if (properties.empty())
420 return;
421
422 // Unlike string item roles, string properties are not loaded via the textBuilder
423 // (as they are "shadowed" by the property sheets in designer). So do the initial
424 // translation here.
425 bool anyTrs = false;
426 foreach (const DomProperty *p, properties) {
427 QUiTranslatableStringValue strVal;
428 const QString text = convertTranslatable(p, m_class, &strVal);
429 if (text.isEmpty())
430 continue;
431 const QByteArray name = p->attributeName().toUtf8();
432 if (dynamicTr) {
433 o->setProperty(PROP_GENERIC_PREFIX + name, qVariantFromValue(strVal));
434 anyTrs = trEnabled;
435 }
436 o->setProperty(name, text);
437 }
438 if (anyTrs)
439 o->installEventFilter(m_trwatch);
440}
441
442QWidget *FormBuilderPrivate::create(DomUI *ui, QWidget *parentWidget)
443{
444 m_class = ui->elementClass().toUtf8();
445 m_trwatch = 0;
446 setTextBuilder(new TranslatingTextBuilder(trEnabled, m_class));
447 return QFormBuilder::create(ui, parentWidget);
448}
449
450QWidget *FormBuilderPrivate::create(DomWidget *ui_widget, QWidget *parentWidget)
451{
452 QWidget *w = QFormBuilder::create(ui_widget, parentWidget);
453 if (w == 0)
454 return 0;
455
456 if (0) {
457#ifndef QT_NO_TABWIDGET
458 } else if (qobject_cast<QTabWidget*>(w)) {
459#endif
460#ifndef QT_NO_LISTWIDGET
461 } else if (qobject_cast<QListWidget*>(w)) {
462#endif
463#ifndef QT_NO_TREEWIDGET
464 } else if (qobject_cast<QTreeWidget*>(w)) {
465#endif
466#ifndef QT_NO_TABLEWIDGET
467 } else if (qobject_cast<QTableWidget*>(w)) {
468#endif
469#ifndef QT_NO_COMBOBOX
470 } else if (qobject_cast<QComboBox*>(w)) {
471 if (qobject_cast<QFontComboBox*>(w))
472 return w;
473#endif
474#ifndef QT_NO_TOOLBOX
475 } else if (qobject_cast<QToolBox*>(w)) {
476#endif
477 } else {
478 return w;
479 }
480 if (dynamicTr && trEnabled)
481 w->installEventFilter(m_trwatch);
482 return w;
483}
484
485#define TRANSLATE_SUBWIDGET_PROP(mainWidget, attribute, setter, propName) \
486 do { \
487 if (const DomProperty *p##attribute = attributes.value(strings.attribute)) { \
488 QUiTranslatableStringValue strVal; \
489 const QString text = convertTranslatable(p##attribute, m_class, &strVal); \
490 if (!text.isEmpty()) { \
491 if (dynamicTr) \
492 mainWidget->widget(i)->setProperty(propName, qVariantFromValue(strVal)); \
493 mainWidget->setter(i, text); \
494 } \
495 } \
496 } while (0)
497
498bool FormBuilderPrivate::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
499{
500 if (parentWidget == 0)
501 return true;
502
503 if (!ParentClass::addItem(ui_widget, widget, parentWidget))
504 return false;
505
506 // Check special cases. First: Custom container
507 const QString className = QLatin1String(parentWidget->metaObject()->className());
508 if (!QFormBuilderExtra::instance(this)->customWidgetAddPageMethod(className).isEmpty())
509 return true;
510
511 const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
512
513 if (0) {
514#ifndef QT_NO_TABWIDGET
515 } else if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) {
516 const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
517 const int i = tabWidget->count() - 1;
518 TRANSLATE_SUBWIDGET_PROP(tabWidget, titleAttribute, setTabText, PROP_TABPAGETEXT);
519# ifndef QT_NO_TOOLTIP
520 TRANSLATE_SUBWIDGET_PROP(tabWidget, toolTipAttribute, setTabToolTip, PROP_TABPAGETOOLTIP);
521# endif
522# ifndef QT_NO_WHATSTHIS
523 TRANSLATE_SUBWIDGET_PROP(tabWidget, whatsThisAttribute, setTabWhatsThis, PROP_TABPAGEWHATSTHIS);
524# endif
525#endif
526#ifndef QT_NO_TOOLBOX
527 } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(parentWidget)) {
528 const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
529 const int i = toolBox->count() - 1;
530 TRANSLATE_SUBWIDGET_PROP(toolBox, labelAttribute, setItemText, PROP_TOOLITEMTEXT);
531# ifndef QT_NO_TOOLTIP
532 TRANSLATE_SUBWIDGET_PROP(toolBox, toolTipAttribute, setItemToolTip, PROP_TOOLITEMTOOLTIP);
533# endif
534#endif
535 }
536
537 return true;
538}
539
540#ifdef QFORMINTERNAL_NAMESPACE
541}
542#endif
543
544class QUiLoaderPrivate
545{
546public:
547#ifdef QFORMINTERNAL_NAMESPACE
548 QFormInternal::FormBuilderPrivate builder;
549#else
550 FormBuilderPrivate builder;
551#endif
552
553 void setupWidgetMap() const;
554};
555
556void QUiLoaderPrivate::setupWidgetMap() const
557{
558 if (!g_widgets()->isEmpty())
559 return;
560
561#define DECLARE_WIDGET(a, b) g_widgets()->insert(QLatin1String(#a), true);
562#define DECLARE_LAYOUT(a, b)
563
564#include "widgets.table"
565
566#undef DECLARE_WIDGET
567#undef DECLARE_WIDGET_1
568#undef DECLARE_LAYOUT
569}
570
571/*!
572 \class QUiLoader
573 \inmodule QtUiTools
574
575 \brief The QUiLoader class enables standalone applications to
576 dynamically create user interfaces at run-time using the
577 information stored in UI files or specified in plugin paths.
578
579 In addition, you can customize or create your own user interface by
580 deriving your own loader class.
581
582 If you have a custom component or an application that embeds \QD, you can
583 also use the QFormBuilder class provided by the QtDesigner module to create
584 user interfaces from UI files.
585
586 The QUiLoader class provides a collection of functions allowing you to
587 create widgets based on the information stored in UI files (created
588 with \QD) or available in the specified plugin paths. The specified plugin
589 paths can be retrieved using the pluginPaths() function. Similarly, the
590 contents of a UI file can be retrieved using the load() function. For
591 example:
592
593 \snippet doc/src/snippets/quiloader/mywidget.cpp 0
594
595 By including the user interface in the form's resources (\c myform.qrc), we
596 ensure that it will be present at run-time:
597
598 \quotefile doc/src/snippets/quiloader/mywidget.qrc
599
600 The availableWidgets() function returns a QStringList with the class names
601 of the widgets available in the specified plugin paths. To create these
602 widgets, simply use the createWidget() function. For example:
603
604 \snippet doc/src/snippets/quiloader/main.cpp 0
605
606 To make a custom widget available to the loader, you can use the
607 addPluginPath() function; to remove all available widgets, you can call
608 the clearPluginPaths() function.
609
610 The createAction(), createActionGroup(), createLayout(), and createWidget()
611 functions are used internally by the QUiLoader class whenever it has to
612 create an action, action group, layout, or widget respectively. For that
613 reason, you can subclass the QUiLoader class and reimplement these
614 functions to intervene the process of constructing a user interface. For
615 example, you might want to have a list of the actions created when loading
616 a form or creating a custom widget.
617
618 For a complete example using the QUiLoader class, see the
619 \l{Calculator Builder Example}.
620
621 \sa QtUiTools, QFormBuilder
622*/
623
624/*!
625 Creates a form loader with the given \a parent.
626*/
627QUiLoader::QUiLoader(QObject *parent)
628 : QObject(parent), d_ptr(new QUiLoaderPrivate)
629{
630 Q_D(QUiLoader);
631
632 d->builder.loader = this;
633
634 QStringList paths;
635 foreach (const QString &path, QApplication::libraryPaths()) {
636 QString libPath = path;
637 libPath += QDir::separator();
638 libPath += QLatin1String("designer");
639 paths.append(libPath);
640 }
641
642 d->builder.setPluginPath(paths);
643}
644
645/*!
646 Destroys the loader.
647*/
648QUiLoader::~QUiLoader()
649{
650}
651
652/*!
653 Loads a form from the given \a device and creates a new widget with the
654 given \a parentWidget to hold its contents.
655
656 \sa createWidget()
657*/
658QWidget *QUiLoader::load(QIODevice *device, QWidget *parentWidget)
659{
660 Q_D(QUiLoader);
661 // QXmlStreamReader will report errors on open failure.
662 if (!device->isOpen())
663 device->open(QIODevice::ReadOnly|QIODevice::Text);
664 return d->builder.load(device, parentWidget);
665}
666
667/*!
668 Returns a list naming the paths in which the loader will search when
669 locating custom widget plugins.
670
671 \sa addPluginPath(), clearPluginPaths()
672*/
673QStringList QUiLoader::pluginPaths() const
674{
675 Q_D(const QUiLoader);
676 return d->builder.pluginPaths();
677}
678
679/*!
680 Clears the list of paths in which the loader will search when locating
681 plugins.
682
683 \sa addPluginPath(), pluginPaths()
684*/
685void QUiLoader::clearPluginPaths()
686{
687 Q_D(QUiLoader);
688 d->builder.clearPluginPaths();
689}
690
691/*!
692 Adds the given \a path to the list of paths in which the loader will search
693 when locating plugins.
694
695 \sa pluginPaths(), clearPluginPaths()
696*/
697void QUiLoader::addPluginPath(const QString &path)
698{
699 Q_D(QUiLoader);
700 d->builder.addPluginPath(path);
701}
702
703/*!
704 Creates a new widget with the given \a parent and \a name using the class
705 specified by \a className. You can use this function to create any of the
706 widgets returned by the availableWidgets() function.
707
708 The function is also used internally by the QUiLoader class whenever it
709 creates a widget. Hence, you can subclass QUiLoader and reimplement this
710 function to intervene process of constructing a user interface or widget.
711 However, in your implementation, ensure that you call QUiLoader's version
712 first.
713
714 \sa availableWidgets(), load()
715*/
716QWidget *QUiLoader::createWidget(const QString &className, QWidget *parent, const QString &name)
717{
718 Q_D(QUiLoader);
719 return d->builder.defaultCreateWidget(className, parent, name);
720}
721
722/*!
723 Creates a new layout with the given \a parent and \a name using the class
724 specified by \a className.
725
726 The function is also used internally by the QUiLoader class whenever it
727 creates a widget. Hence, you can subclass QUiLoader and reimplement this
728 function to intervene process of constructing a user interface or widget.
729 However, in your implementation, ensure that you call QUiLoader's version
730 first.
731
732 \sa createWidget(), load()
733*/
734QLayout *QUiLoader::createLayout(const QString &className, QObject *parent, const QString &name)
735{
736 Q_D(QUiLoader);
737 return d->builder.defaultCreateLayout(className, parent, name);
738}
739
740/*!
741 Creates a new action group with the given \a parent and \a name.
742
743 The function is also used internally by the QUiLoader class whenever it
744 creates a widget. Hence, you can subclass QUiLoader and reimplement this
745 function to intervene process of constructing a user interface or widget.
746 However, in your implementation, ensure that you call QUiLoader's version
747 first.
748
749 \sa createAction(), createWidget(), load()
750 */
751QActionGroup *QUiLoader::createActionGroup(QObject *parent, const QString &name)
752{
753 Q_D(QUiLoader);
754 return d->builder.defaultCreateActionGroup(parent, name);
755}
756
757/*!
758 Creates a new action with the given \a parent and \a name.
759
760 The function is also used internally by the QUiLoader class whenever it
761 creates a widget. Hence, you can subclass QUiLoader and reimplement this
762 function to intervene process of constructing a user interface or widget.
763 However, in your implementation, ensure that you call QUiLoader's version
764 first.
765
766 \sa createActionGroup(), createWidget(), load()
767*/
768QAction *QUiLoader::createAction(QObject *parent, const QString &name)
769{
770 Q_D(QUiLoader);
771 return d->builder.defaultCreateAction(parent, name);
772}
773
774/*!
775 Returns a list naming all available widgets that can be built using the
776 createWidget() function, i.e all the widgets specified within the given
777 plugin paths.
778
779 \sa pluginPaths(), createWidget()
780
781*/
782QStringList QUiLoader::availableWidgets() const
783{
784 Q_D(const QUiLoader);
785
786 d->setupWidgetMap();
787 widget_map available = *g_widgets();
788
789 foreach (QDesignerCustomWidgetInterface *plugin, d->builder.customWidgets()) {
790 available.insert(plugin->name(), true);
791 }
792
793 return available.keys();
794}
795
796
797/*!
798 \since 4.5
799 Returns a list naming all available layouts that can be built using the
800 createLayout() function
801
802 \sa createLayout()
803*/
804
805QStringList QUiLoader::availableLayouts() const
806{
807 QStringList rc;
808#define DECLARE_WIDGET(a, b)
809#define DECLARE_LAYOUT(a, b) rc.push_back(QLatin1String(#a));
810
811#include "widgets.table"
812
813#undef DECLARE_WIDGET
814#undef DECLARE_LAYOUT
815 return rc;
816}
817
818/*!
819 Sets the working directory of the loader to \a dir. The loader will look
820 for other resources, such as icons and resource files, in paths relative to
821 this directory.
822
823 \sa workingDirectory()
824*/
825
826void QUiLoader::setWorkingDirectory(const QDir &dir)
827{
828 Q_D(QUiLoader);
829 d->builder.setWorkingDirectory(dir);
830}
831
832/*!
833 Returns the working directory of the loader.
834
835 \sa setWorkingDirectory()
836*/
837
838QDir QUiLoader::workingDirectory() const
839{
840 Q_D(const QUiLoader);
841 return d->builder.workingDirectory();
842}
843
844/*!
845 \internal
846 \since 4.3
847
848 If \a enabled is true, the loader will be able to execute scripts.
849 Otherwise, execution of scripts will be disabled.
850
851 \sa isScriptingEnabled()
852*/
853
854void QUiLoader::setScriptingEnabled(bool enabled)
855{
856 Q_D(QUiLoader);
857 d->builder.setScriptingEnabled(enabled);
858}
859
860/*!
861 \internal
862 \since 4.3
863
864 Returns true if execution of scripts is enabled; returns false otherwise.
865
866 \sa setScriptingEnabled()
867*/
868
869bool QUiLoader::isScriptingEnabled() const
870{
871 Q_D(const QUiLoader);
872 return d->builder.isScriptingEnabled();
873}
874
875/*!
876 \since 4.5
877
878 If \a enabled is true, user interfaces loaded by this loader will
879 automatically retranslate themselves upon receiving a language change
880 event. Otherwise, the user interfaces will not be retranslated.
881
882 \sa isLanguageChangeEnabled()
883*/
884
885void QUiLoader::setLanguageChangeEnabled(bool enabled)
886{
887 Q_D(QUiLoader);
888 d->builder.dynamicTr = enabled;
889}
890
891/*!
892 \since 4.5
893
894 Returns true if dynamic retranslation on language change is enabled;
895 returns false otherwise.
896
897 \sa setLanguageChangeEnabled()
898*/
899
900bool QUiLoader::isLanguageChangeEnabled() const
901{
902 Q_D(const QUiLoader);
903 return d->builder.dynamicTr;
904}
905
906/*!
907 \internal
908 \since 4.5
909
910 If \a enabled is true, user interfaces loaded by this loader will be
911 translated. Otherwise, the user interfaces will not be translated.
912
913 \note This is orthogonal to languageChangeEnabled.
914
915 \sa isLanguageChangeEnabled(), setLanguageChangeEnabled()
916*/
917
918void QUiLoader::setTranslationEnabled(bool enabled)
919{
920 Q_D(QUiLoader);
921 d->builder.trEnabled = enabled;
922}
923
924/*!
925 \internal
926 \since 4.5
927
928 Returns true if translation is enabled; returns false otherwise.
929
930 \sa setTranslationEnabled()
931*/
932
933bool QUiLoader::isTranslationEnabled() const
934{
935 Q_D(const QUiLoader);
936 return d->builder.trEnabled;
937}
938
939QT_END_NAMESPACE
940
941#include "quiloader.moc"
Note: See TracBrowser for help on using the repository browser.