source: branches/4.5.1/tools/designer/src/uitools/quiloader.cpp

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

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 28.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information (qt-info@nokia.com)
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** 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 are unsure which license is appropriate for your use, please
37** contact the sales department at qt-sales@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->verticalHeaderItem(j), m_className);
263 for (int i = 0; i < row_cnt; ++i) {
264 reTranslateTableItem(tablew->horizontalHeaderItem(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 allows standalone applications dynamically
576 create user interfaces at run-time using the information stored in
577 .ui files or specified plugin paths.
578
579 In addition, you can customize of creating an user interface by
580 deriving your own loader class.
581
582 If you have a custom component or an application that embeds Qt
583 Designer, you can also use the QFormBuilder class provided by the
584 QtDesigner module to create user interfaces from .ui files.
585
586 The QUiLoader class provides a collection of functions that allows
587 you to create widgets based on the information stored in \c .ui
588 files (created with Qt Designer) or available in the specified
589 plugin paths. The specified plugin paths can be retrieved using
590 the pluginPaths() function. You can retrieve the contents of an \c
591 .ui file using the load() function. For 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),
596 we 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
601 class names of the widgets available in the specified plugin
602 paths. You can create any of these widgets using the
603 createWidget() function. For example:
604
605 \snippet doc/src/snippets/quiloader/main.cpp 0
606
607 You can make a custom widget available to the loader using the
608 addPluginPath() function, and you can remove all the available widgets
609 by calling the clearPluginPaths() function.
610
611 The createAction(), createActionGroup(), createLayout() and
612 createWidget() functions are used internally by the QUiLoader class
613 whenever it has to create an action, action group, layout or
614 widget respectively. For that reason, you can subclass the QUiLoader
615 class and reimplement these functions to intervene the process of
616 constructing an user interface. For example, you might want to
617 create a list of the actions created when loading a form or
618 creating a custom widget.
619
620 For a complete example using the QUiLoader class, see the \l
621 {designer/calculatorbuilder}{Calculator Builder} example.
622
623 \sa QtUiTools, QFormBuilder
624*/
625
626/*!
627 Creates a form loader with the given \a parent.
628*/
629QUiLoader::QUiLoader(QObject *parent)
630 : QObject(parent), d_ptr(new QUiLoaderPrivate)
631{
632 Q_D(QUiLoader);
633
634 d->builder.loader = this;
635
636 QStringList paths;
637 foreach (const QString &path, QApplication::libraryPaths()) {
638 QString libPath = path;
639 libPath += QDir::separator();
640 libPath += QLatin1String("designer");
641 paths.append(libPath);
642 }
643
644 d->builder.setPluginPath(paths);
645}
646
647/*!
648 Destroys the loader.
649*/
650QUiLoader::~QUiLoader()
651{
652 delete d_ptr;
653}
654
655/*!
656 Loads a form from the given \a device and creates a new widget with the given
657 \a parentWidget to hold its contents.
658
659 \sa createWidget()
660*/
661QWidget *QUiLoader::load(QIODevice *device, QWidget *parentWidget)
662{
663 Q_D(QUiLoader);
664 // QXmlStreamReader will report errors on open failure.
665 if (!device->isOpen())
666 device->open(QIODevice::ReadOnly|QIODevice::Text);
667 return d->builder.load(device, parentWidget);
668}
669
670/*!
671 Returns a list naming the paths the loader searches when locating
672 custom widget plugins.
673
674 \sa addPluginPath(), clearPluginPaths()
675*/
676QStringList QUiLoader::pluginPaths() const
677{
678 Q_D(const QUiLoader);
679 return d->builder.pluginPaths();
680}
681
682/*!
683 Clears the list of paths the loader searches when locating
684 plugins.
685
686 \sa addPluginPath(), pluginPaths()
687*/
688void QUiLoader::clearPluginPaths()
689{
690 Q_D(QUiLoader);
691 d->builder.clearPluginPaths();
692}
693
694/*!
695 Adds the given \a path to the list of paths the loader searches
696 when locating plugins.
697
698 \sa pluginPaths(), clearPluginPaths()
699*/
700void QUiLoader::addPluginPath(const QString &path)
701{
702 Q_D(QUiLoader);
703 d->builder.addPluginPath(path);
704}
705
706/*!
707 Creates a new widget with the given \a parent and \a name
708 using the class specified by \a className. You can use this
709 function to create any of the widgets returned by the
710 availableWidgets() function.
711
712 The function is also used internally by the QUiLoader class whenever
713 it has to create a widget. For that reason, you can subclass the
714 QUiLoader class and reimplement this function to intervene in the
715 process of constructing a user interface or widget.
716
717 \sa availableWidgets(), load()
718*/
719QWidget *QUiLoader::createWidget(const QString &className, QWidget *parent, const QString &name)
720{
721 Q_D(QUiLoader);
722 return d->builder.defaultCreateWidget(className, parent, name);
723}
724
725/*!
726 Creates a new layout with the given \a parent and \a name
727 using the class specified by \a className.
728
729 The function is used internally by the QUiLoader class whenever it
730 has to create a layout. For that reason, you can subclass the
731 QUiLoader class and reimplement this function to intervene the
732 process of constructing an user interface or widget.
733
734 \sa createWidget(), load()
735*/
736QLayout *QUiLoader::createLayout(const QString &className, QObject *parent, const QString &name)
737{
738 Q_D(QUiLoader);
739 return d->builder.defaultCreateLayout(className, parent, name);
740}
741
742/*!
743 Creates a new action group with the given \a parent and \a name.
744
745 The function is used internally by the QUiLoader class whenever it
746 has to create an action group. For that reason, you can subclass
747 the QUiLoader class and reimplement this function to intervene the
748 process of constructing an user interface or widget.
749
750 \sa createAction(), createWidget(), load()
751 */
752QActionGroup *QUiLoader::createActionGroup(QObject *parent, const QString &name)
753{
754 Q_D(QUiLoader);
755 return d->builder.defaultCreateActionGroup(parent, name);
756}
757
758/*!
759 Creates a new action with the given \a parent and \a name.
760
761 The function is used internally by the QUiLoader class whenever it
762 has to create an action. For that reason, you can subclass the
763 QUiLoader class and reimplement this function to intervene the
764 process of constructing an user interface or widget.
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 the available widgets that can be built
776 using the createWidget() function, i.e all the widgets specified
777 within the given 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 Returns a list naming the available layouts that can be built
799 using the createLayout() function
800
801 \sa createLayout()
802 \since 4.5
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
820 looks for other resources, such as icons and resource files,
821 in paths relative to 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 Sets whether the execution of scripts is enabled to \a enabled.
846 \since 4.3
847 \internal
848*/
849
850void QUiLoader::setScriptingEnabled(bool enabled)
851{
852 Q_D(QUiLoader);
853 d->builder.setScriptingEnabled(enabled);
854}
855
856/*!
857 Returns whether the execution of scripts is enabled.
858 \sa setScriptingEnabled()
859 \since 4.3
860 \internal
861*/
862
863bool QUiLoader::isScriptingEnabled() const
864{
865 Q_D(const QUiLoader);
866 return d->builder.isScriptingEnabled();
867}
868
869/*!
870 Sets whether user interfaces loaded by this loader automatically
871 retranslate themselves upon receiving a language change event or not,
872 depending on \a enabled.
873
874 \since 4.5
875*/
876
877void QUiLoader::setLanguageChangeEnabled(bool enabled)
878{
879 Q_D(QUiLoader);
880 d->builder.dynamicTr = enabled;
881}
882
883/*!
884 Returns whether dynamic retranslation on language change is enabled.
885 \sa setLanguageChangeEnabled()
886 \since 4.5
887*/
888
889bool QUiLoader::isLanguageChangeEnabled() const
890{
891 Q_D(const QUiLoader);
892 return d->builder.dynamicTr;
893}
894
895/*!
896 \internal
897
898 Sets whether user interfaces loaded by this loader are translated
899 at all. Note that this is orthogonal to languageChangeEnabled.
900
901 \since 4.5
902*/
903
904void QUiLoader::setTranslationEnabled(bool enabled)
905{
906 Q_D(QUiLoader);
907 d->builder.trEnabled = enabled;
908}
909
910/*!
911 \internal
912
913 Returns whether translation is enabled.
914 \sa setTranslationEnabled()
915
916 \since 4.5
917*/
918
919bool QUiLoader::isTranslationEnabled() const
920{
921 Q_D(const QUiLoader);
922 return d->builder.trEnabled;
923}
924
925QT_END_NAMESPACE
926
927#include "quiloader.moc"
Note: See TracBrowser for help on using the repository browser.