diff options
author | Lars Knoll <lars.knoll@nokia.com> | 2009-03-23 09:18:55 (GMT) |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2009-03-23 09:18:55 (GMT) |
commit | e5fcad302d86d316390c6b0f62759a067313e8a9 (patch) | |
tree | c2afbf6f1066b6ce261f14341cf6d310e5595bc1 /tools/designer/src/uitools | |
download | Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.zip Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.gz Qt-e5fcad302d86d316390c6b0f62759a067313e8a9.tar.bz2 |
Long live Qt 4.5!
Diffstat (limited to 'tools/designer/src/uitools')
-rw-r--r-- | tools/designer/src/uitools/quiloader.cpp | 927 | ||||
-rw-r--r-- | tools/designer/src/uitools/quiloader.h | 102 | ||||
-rw-r--r-- | tools/designer/src/uitools/quiloader_p.h | 109 | ||||
-rw-r--r-- | tools/designer/src/uitools/uitools.pro | 41 |
4 files changed, 1179 insertions, 0 deletions
diff --git a/tools/designer/src/uitools/quiloader.cpp b/tools/designer/src/uitools/quiloader.cpp new file mode 100644 index 0000000..d3d1d54 --- /dev/null +++ b/tools/designer/src/uitools/quiloader.cpp @@ -0,0 +1,927 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include "quiloader.h" +#include "quiloader_p.h" +#include "customwidget.h" + +#include <formbuilder.h> +#include <formbuilderextra_p.h> +#include <textbuilder_p.h> +#include <ui4_p.h> + +#include <QtCore/qdebug.h> +#include <QtGui/QAction> +#include <QtGui/QActionGroup> +#include <QtGui/QApplication> +#include <QtCore/QDir> +#include <QtCore/QLibraryInfo> +#include <QtGui/QLayout> +#include <QtGui/QWidget> +#include <QtCore/QMap> +#include <QtGui/QTabWidget> +#include <QtGui/QTreeWidget> +#include <QtGui/QListWidget> +#include <QtGui/QTableWidget> +#include <QtGui/QToolBox> +#include <QtGui/QComboBox> +#include <QtGui/QFontComboBox> + +QT_BEGIN_NAMESPACE + +typedef QMap<QString, bool> widget_map; +Q_GLOBAL_STATIC(widget_map, g_widgets) + +class QUiLoader; +class QUiLoaderPrivate; + +#ifdef QFORMINTERNAL_NAMESPACE +namespace QFormInternal +{ +#endif + +class TranslatingTextBuilder : public QTextBuilder +{ +public: + TranslatingTextBuilder(bool trEnabled, const QByteArray &className) : + m_trEnabled(trEnabled), m_className(className) {} + + virtual QVariant loadText(const DomProperty *icon) const; + + virtual QVariant toNativeValue(const QVariant &value) const; + +private: + bool m_trEnabled; + QByteArray m_className; +}; + +QVariant TranslatingTextBuilder::loadText(const DomProperty *text) const +{ + const DomString *str = text->elementString(); + if (!str) + return QVariant(); + if (str->hasAttributeNotr()) { + const QString notr = str->attributeNotr(); + if (notr == QLatin1String("true") || notr == QLatin1String("yes")) + return qVariantFromValue(str->text()); + } + QUiTranslatableStringValue strVal; + strVal.setValue(str->text().toUtf8()); + if (str->hasAttributeComment()) + strVal.setComment(str->attributeComment().toUtf8()); + return qVariantFromValue(strVal); +} + +QVariant TranslatingTextBuilder::toNativeValue(const QVariant &value) const +{ + if (qVariantCanConvert<QUiTranslatableStringValue>(value)) { + QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(value); + if (!m_trEnabled) + return QString::fromUtf8(tsv.value().data()); + return qVariantFromValue( + QApplication::translate(m_className, tsv.value(), tsv.comment(), + QCoreApplication::UnicodeUTF8)); + } + if (qVariantCanConvert<QString>(value)) + return qVariantFromValue(qVariantValue<QString>(value)); + return value; +} + +// This is "exported" to linguist +const QUiItemRolePair qUiItemRoles[] = { + { Qt::DisplayRole, Qt::DisplayPropertyRole }, +#ifndef QT_NO_TOOLTIP + { Qt::ToolTipRole, Qt::ToolTipPropertyRole }, +#endif +#ifndef QT_NO_STATUSTIP + { Qt::StatusTipRole, Qt::StatusTipPropertyRole }, +#endif +#ifndef QT_NO_WHATSTHIS + { Qt::WhatsThisRole, Qt::WhatsThisPropertyRole }, +#endif + { -1 , -1 } +}; + +static void recursiveReTranslate(QTreeWidgetItem *item, const QByteArray &class_name) +{ + const QUiItemRolePair *irs = qUiItemRoles; + + int cnt = item->columnCount(); + for (int i = 0; i < cnt; ++i) { + for (unsigned j = 0; irs[j].shadowRole >= 0; j++) { + QVariant v = item->data(i, irs[j].shadowRole); + if (v.isValid()) { + QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v); + const QString text = QApplication::translate(class_name, + tsv.value(), tsv.comment(), + QCoreApplication::UnicodeUTF8); + item->setData(i, irs[j].realRole, text); + } + } + } + + cnt = item->childCount(); + for (int i = 0; i < cnt; ++i) + recursiveReTranslate(item->child(i), class_name); +} + +template<typename T> +static void reTranslateWidgetItem(T *item, const QByteArray &class_name) +{ + const QUiItemRolePair *irs = qUiItemRoles; + + for (unsigned j = 0; irs[j].shadowRole >= 0; j++) { + QVariant v = item->data(irs[j].shadowRole); + if (v.isValid()) { + QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v); + const QString text = QApplication::translate(class_name, + tsv.value(), tsv.comment(), + QCoreApplication::UnicodeUTF8); + item->setData(irs[j].realRole, text); + } + } +} + +static void reTranslateTableItem(QTableWidgetItem *item, const QByteArray &class_name) +{ + if (item) + reTranslateWidgetItem(item, class_name); +} + +#define RETRANSLATE_SUBWIDGET_PROP(mainWidget, setter, propName) \ + do { \ + QVariant v = mainWidget->widget(i)->property(propName); \ + if (v.isValid()) { \ + QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v); \ + const QString text = QApplication::translate(m_className, \ + tsv.value(), tsv.comment(), \ + QCoreApplication::UnicodeUTF8); \ + mainWidget->setter(i, text); \ + } \ + } while (0) + +class TranslationWatcher: public QObject +{ + Q_OBJECT + +public: + TranslationWatcher(QObject *parent, const QByteArray &className): + QObject(parent), + m_className(className) + { + } + + virtual bool eventFilter(QObject *o, QEvent *event) + { + if (event->type() == QEvent::LanguageChange) { + foreach (const QByteArray &prop, o->dynamicPropertyNames()) { + if (prop.startsWith(PROP_GENERIC_PREFIX)) { + const QByteArray propName = prop.mid(sizeof(PROP_GENERIC_PREFIX) - 1); + const QUiTranslatableStringValue tsv = + qVariantValue<QUiTranslatableStringValue>(o->property(prop)); + const QString text = QApplication::translate(m_className, + tsv.value(), tsv.comment(), + QCoreApplication::UnicodeUTF8); + o->setProperty(propName, text); + } + } + if (0) { +#ifndef QT_NO_TABWIDGET + } else if (QTabWidget *tabw = qobject_cast<QTabWidget*>(o)) { + const int cnt = tabw->count(); + for (int i = 0; i < cnt; ++i) { + RETRANSLATE_SUBWIDGET_PROP(tabw, setTabText, PROP_TABPAGETEXT); +# ifndef QT_NO_TOOLTIP + RETRANSLATE_SUBWIDGET_PROP(tabw, setTabToolTip, PROP_TABPAGETOOLTIP); +# endif +# ifndef QT_NO_WHATSTHIS + RETRANSLATE_SUBWIDGET_PROP(tabw, setTabWhatsThis, PROP_TABPAGEWHATSTHIS); +# endif + } +#endif +#ifndef QT_NO_LISTWIDGET + } else if (QListWidget *listw = qobject_cast<QListWidget*>(o)) { + const int cnt = listw->count(); + for (int i = 0; i < cnt; ++i) + reTranslateWidgetItem(listw->item(i), m_className); +#endif +#ifndef QT_NO_TREEWIDGET + } else if (QTreeWidget *treew = qobject_cast<QTreeWidget*>(o)) { + if (QTreeWidgetItem *item = treew->headerItem()) + recursiveReTranslate(item, m_className); + const int cnt = treew->topLevelItemCount(); + for (int i = 0; i < cnt; ++i) { + QTreeWidgetItem *item = treew->topLevelItem(i); + recursiveReTranslate(item, m_className); + } +#endif +#ifndef QT_NO_TABLEWIDGET + } else if (QTableWidget *tablew = qobject_cast<QTableWidget*>(o)) { + const int row_cnt = tablew->rowCount(); + const int col_cnt = tablew->columnCount(); + for (int j = 0; j < col_cnt; ++j) + reTranslateTableItem(tablew->verticalHeaderItem(j), m_className); + for (int i = 0; i < row_cnt; ++i) { + reTranslateTableItem(tablew->horizontalHeaderItem(i), m_className); + for (int j = 0; j < col_cnt; ++j) + reTranslateTableItem(tablew->item(i, j), m_className); + } +#endif +#ifndef QT_NO_COMBOBOX + } else if (QComboBox *combow = qobject_cast<QComboBox*>(o)) { + if (!qobject_cast<QFontComboBox*>(o)) { + const int cnt = combow->count(); + for (int i = 0; i < cnt; ++i) { + const QVariant v = combow->itemData(i, Qt::DisplayPropertyRole); + if (v.isValid()) { + QUiTranslatableStringValue tsv = qVariantValue<QUiTranslatableStringValue>(v); + const QString text = QApplication::translate(m_className, + tsv.value(), tsv.comment(), + QCoreApplication::UnicodeUTF8); + combow->setItemText(i, text); + } + } + } +#endif +#ifndef QT_NO_TOOLBOX + } else if (QToolBox *toolw = qobject_cast<QToolBox*>(o)) { + const int cnt = toolw->count(); + for (int i = 0; i < cnt; ++i) { + RETRANSLATE_SUBWIDGET_PROP(toolw, setItemText, PROP_TOOLITEMTEXT); +# ifndef QT_NO_TOOLTIP + RETRANSLATE_SUBWIDGET_PROP(toolw, setItemToolTip, PROP_TOOLITEMTOOLTIP); +# endif + } +#endif + } + } + return false; + } + +private: + QByteArray m_className; +}; + +class FormBuilderPrivate: public QFormBuilder +{ + friend class QT_PREPEND_NAMESPACE(QUiLoader); + friend class QT_PREPEND_NAMESPACE(QUiLoaderPrivate); + typedef QFormBuilder ParentClass; + +public: + QUiLoader *loader; + + bool dynamicTr; + bool trEnabled; + + FormBuilderPrivate(): loader(0), dynamicTr(false), trEnabled(true), m_trwatch(0) {} + + QWidget *defaultCreateWidget(const QString &className, QWidget *parent, const QString &name) + { + return ParentClass::createWidget(className, parent, name); + } + + QLayout *defaultCreateLayout(const QString &className, QObject *parent, const QString &name) + { + return ParentClass::createLayout(className, parent, name); + } + + QAction *defaultCreateAction(QObject *parent, const QString &name) + { + return ParentClass::createAction(parent, name); + } + + QActionGroup *defaultCreateActionGroup(QObject *parent, const QString &name) + { + return ParentClass::createActionGroup(parent, name); + } + + virtual QWidget *createWidget(const QString &className, QWidget *parent, const QString &name) + { + if (QWidget *widget = loader->createWidget(className, parent, name)) { + widget->setObjectName(name); + return widget; + } + + return 0; + } + + virtual QLayout *createLayout(const QString &className, QObject *parent, const QString &name) + { + if (QLayout *layout = loader->createLayout(className, parent, name)) { + layout->setObjectName(name); + return layout; + } + + return 0; + } + + virtual QActionGroup *createActionGroup(QObject *parent, const QString &name) + { + if (QActionGroup *actionGroup = loader->createActionGroup(parent, name)) { + actionGroup->setObjectName(name); + return actionGroup; + } + + return 0; + } + + virtual QAction *createAction(QObject *parent, const QString &name) + { + if (QAction *action = loader->createAction(parent, name)) { + action->setObjectName(name); + return action; + } + + return 0; + } + + virtual void applyProperties(QObject *o, const QList<DomProperty*> &properties); + virtual QWidget *create(DomUI *ui, QWidget *parentWidget); + virtual QWidget *create(DomWidget *ui_widget, QWidget *parentWidget); + virtual bool addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget); + +private: + QByteArray m_class; + TranslationWatcher *m_trwatch; +}; + +static QString convertTranslatable(const DomProperty *p, const QByteArray &className, + QUiTranslatableStringValue *strVal) +{ + if (p->kind() != DomProperty::String) + return QString(); + const DomString *dom_str = p->elementString(); + if (!dom_str) + return QString(); + if (dom_str->hasAttributeNotr()) { + const QString notr = dom_str->attributeNotr(); + if (notr == QLatin1String("yes") || notr == QLatin1String("true")) + return QString(); + } + strVal->setValue(dom_str->text().toUtf8()); + strVal->setComment(dom_str->attributeComment().toUtf8()); + if (strVal->value().isEmpty() && strVal->comment().isEmpty()) + return QString(); + return QApplication::translate(className, + strVal->value(), strVal->comment(), + QCoreApplication::UnicodeUTF8); +} + +void FormBuilderPrivate::applyProperties(QObject *o, const QList<DomProperty*> &properties) +{ + typedef QList<DomProperty*> DomPropertyList; + + QFormBuilder::applyProperties(o, properties); + + if (!m_trwatch) + m_trwatch = new TranslationWatcher(o, m_class); + + if (properties.empty()) + return; + + // Unlike string item roles, string properties are not loaded via the textBuilder + // (as they are "shadowed" by the property sheets in designer). So do the initial + // translation here. + bool anyTrs = false; + foreach (const DomProperty *p, properties) { + QUiTranslatableStringValue strVal; + const QString text = convertTranslatable(p, m_class, &strVal); + if (text.isEmpty()) + continue; + const QByteArray name = p->attributeName().toUtf8(); + if (dynamicTr) { + o->setProperty(PROP_GENERIC_PREFIX + name, qVariantFromValue(strVal)); + anyTrs = trEnabled; + } + o->setProperty(name, text); + } + if (anyTrs) + o->installEventFilter(m_trwatch); +} + +QWidget *FormBuilderPrivate::create(DomUI *ui, QWidget *parentWidget) +{ + m_class = ui->elementClass().toUtf8(); + m_trwatch = 0; + setTextBuilder(new TranslatingTextBuilder(trEnabled, m_class)); + return QFormBuilder::create(ui, parentWidget); +} + +QWidget *FormBuilderPrivate::create(DomWidget *ui_widget, QWidget *parentWidget) +{ + QWidget *w = QFormBuilder::create(ui_widget, parentWidget); + if (w == 0) + return 0; + + if (0) { +#ifndef QT_NO_TABWIDGET + } else if (qobject_cast<QTabWidget*>(w)) { +#endif +#ifndef QT_NO_LISTWIDGET + } else if (qobject_cast<QListWidget*>(w)) { +#endif +#ifndef QT_NO_TREEWIDGET + } else if (qobject_cast<QTreeWidget*>(w)) { +#endif +#ifndef QT_NO_TABLEWIDGET + } else if (qobject_cast<QTableWidget*>(w)) { +#endif +#ifndef QT_NO_COMBOBOX + } else if (qobject_cast<QComboBox*>(w)) { + if (qobject_cast<QFontComboBox*>(w)) + return w; +#endif +#ifndef QT_NO_TOOLBOX + } else if (qobject_cast<QToolBox*>(w)) { +#endif + } else { + return w; + } + if (dynamicTr && trEnabled) + w->installEventFilter(m_trwatch); + return w; +} + +#define TRANSLATE_SUBWIDGET_PROP(mainWidget, attribute, setter, propName) \ + do { \ + if (const DomProperty *p##attribute = attributes.value(strings.attribute)) { \ + QUiTranslatableStringValue strVal; \ + const QString text = convertTranslatable(p##attribute, m_class, &strVal); \ + if (!text.isEmpty()) { \ + if (dynamicTr) \ + mainWidget->widget(i)->setProperty(propName, qVariantFromValue(strVal)); \ + mainWidget->setter(i, text); \ + } \ + } \ + } while (0) + +bool FormBuilderPrivate::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget) +{ + if (parentWidget == 0) + return true; + + if (!ParentClass::addItem(ui_widget, widget, parentWidget)) + return false; + + // Check special cases. First: Custom container + const QString className = QLatin1String(parentWidget->metaObject()->className()); + if (!QFormBuilderExtra::instance(this)->customWidgetAddPageMethod(className).isEmpty()) + return true; + + const QFormBuilderStrings &strings = QFormBuilderStrings::instance(); + + if (0) { +#ifndef QT_NO_TABWIDGET + } else if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) { + const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute()); + const int i = tabWidget->count() - 1; + TRANSLATE_SUBWIDGET_PROP(tabWidget, titleAttribute, setTabText, PROP_TABPAGETEXT); +# ifndef QT_NO_TOOLTIP + TRANSLATE_SUBWIDGET_PROP(tabWidget, toolTipAttribute, setTabToolTip, PROP_TABPAGETOOLTIP); +# endif +# ifndef QT_NO_WHATSTHIS + TRANSLATE_SUBWIDGET_PROP(tabWidget, whatsThisAttribute, setTabWhatsThis, PROP_TABPAGEWHATSTHIS); +# endif +#endif +#ifndef QT_NO_TOOLBOX + } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(parentWidget)) { + const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute()); + const int i = toolBox->count() - 1; + TRANSLATE_SUBWIDGET_PROP(toolBox, labelAttribute, setItemText, PROP_TOOLITEMTEXT); +# ifndef QT_NO_TOOLTIP + TRANSLATE_SUBWIDGET_PROP(toolBox, toolTipAttribute, setItemToolTip, PROP_TOOLITEMTOOLTIP); +# endif +#endif + } + + return true; +} + +#ifdef QFORMINTERNAL_NAMESPACE +} +#endif + +class QUiLoaderPrivate +{ +public: +#ifdef QFORMINTERNAL_NAMESPACE + QFormInternal::FormBuilderPrivate builder; +#else + FormBuilderPrivate builder; +#endif + + void setupWidgetMap() const; +}; + +void QUiLoaderPrivate::setupWidgetMap() const +{ + if (!g_widgets()->isEmpty()) + return; + +#define DECLARE_WIDGET(a, b) g_widgets()->insert(QLatin1String(#a), true); +#define DECLARE_LAYOUT(a, b) + +#include "widgets.table" + +#undef DECLARE_WIDGET +#undef DECLARE_WIDGET_1 +#undef DECLARE_LAYOUT +} + +/*! + \class QUiLoader + \inmodule QtUiTools + + \brief The QUiLoader class allows standalone applications dynamically + create user interfaces at run-time using the information stored in + .ui files or specified plugin paths. + + In addition, you can customize of creating an user interface by + deriving your own loader class. + + If you have a custom component or an application that embeds Qt + Designer, you can also use the QFormBuilder class provided by the + QtDesigner module to create user interfaces from .ui files. + + The QUiLoader class provides a collection of functions that allows + you to create widgets based on the information stored in \c .ui + files (created with Qt Designer) or available in the specified + plugin paths. The specified plugin paths can be retrieved using + the pluginPaths() function. You can retrieve the contents of an \c + .ui file using the load() function. For example: + + \snippet doc/src/snippets/quiloader/mywidget.cpp 0 + + By including the user interface in the form's resources (\c myform.qrc), + we ensure that it will be present at run-time: + + \quotefile doc/src/snippets/quiloader/mywidget.qrc + + The availableWidgets() function returns a QStringList with the + class names of the widgets available in the specified plugin + paths. You can create any of these widgets using the + createWidget() function. For example: + + \snippet doc/src/snippets/quiloader/main.cpp 0 + + You can make a custom widget available to the loader using the + addPluginPath() function, and you can remove all the available widgets + by calling the clearPluginPaths() function. + + The createAction(), createActionGroup(), createLayout() and + createWidget() functions are used internally by the QUiLoader class + whenever it has to create an action, action group, layout or + widget respectively. For that reason, you can subclass the QUiLoader + class and reimplement these functions to intervene the process of + constructing an user interface. For example, you might want to + create a list of the actions created when loading a form or + creating a custom widget. + + For a complete example using the QUiLoader class, see the \l + {designer/calculatorbuilder}{Calculator Builder} example. + + \sa QtUiTools, QFormBuilder +*/ + +/*! + Creates a form loader with the given \a parent. +*/ +QUiLoader::QUiLoader(QObject *parent) + : QObject(parent), d_ptr(new QUiLoaderPrivate) +{ + Q_D(QUiLoader); + + d->builder.loader = this; + + QStringList paths; + foreach (const QString &path, QApplication::libraryPaths()) { + QString libPath = path; + libPath += QDir::separator(); + libPath += QLatin1String("designer"); + paths.append(libPath); + } + + d->builder.setPluginPath(paths); +} + +/*! + Destroys the loader. +*/ +QUiLoader::~QUiLoader() +{ + delete d_ptr; +} + +/*! + Loads a form from the given \a device and creates a new widget with the given + \a parentWidget to hold its contents. + + \sa createWidget() +*/ +QWidget *QUiLoader::load(QIODevice *device, QWidget *parentWidget) +{ + Q_D(QUiLoader); + // QXmlStreamReader will report errors on open failure. + if (!device->isOpen()) + device->open(QIODevice::ReadOnly|QIODevice::Text); + return d->builder.load(device, parentWidget); +} + +/*! + Returns a list naming the paths the loader searches when locating + custom widget plugins. + + \sa addPluginPath(), clearPluginPaths() +*/ +QStringList QUiLoader::pluginPaths() const +{ + Q_D(const QUiLoader); + return d->builder.pluginPaths(); +} + +/*! + Clears the list of paths the loader searches when locating + plugins. + + \sa addPluginPath(), pluginPaths() +*/ +void QUiLoader::clearPluginPaths() +{ + Q_D(QUiLoader); + d->builder.clearPluginPaths(); +} + +/*! + Adds the given \a path to the list of paths the loader searches + when locating plugins. + + \sa pluginPaths(), clearPluginPaths() +*/ +void QUiLoader::addPluginPath(const QString &path) +{ + Q_D(QUiLoader); + d->builder.addPluginPath(path); +} + +/*! + Creates a new widget with the given \a parent and \a name + using the class specified by \a className. You can use this + function to create any of the widgets returned by the + availableWidgets() function. + + The function is also used internally by the QUiLoader class whenever + it has to create a widget. For that reason, you can subclass the + QUiLoader class and reimplement this function to intervene in the + process of constructing a user interface or widget. + + \sa availableWidgets(), load() +*/ +QWidget *QUiLoader::createWidget(const QString &className, QWidget *parent, const QString &name) +{ + Q_D(QUiLoader); + return d->builder.defaultCreateWidget(className, parent, name); +} + +/*! + Creates a new layout with the given \a parent and \a name + using the class specified by \a className. + + The function is used internally by the QUiLoader class whenever it + has to create a layout. For that reason, you can subclass the + QUiLoader class and reimplement this function to intervene the + process of constructing an user interface or widget. + + \sa createWidget(), load() +*/ +QLayout *QUiLoader::createLayout(const QString &className, QObject *parent, const QString &name) +{ + Q_D(QUiLoader); + return d->builder.defaultCreateLayout(className, parent, name); +} + +/*! + Creates a new action group with the given \a parent and \a name. + + The function is used internally by the QUiLoader class whenever it + has to create an action group. For that reason, you can subclass + the QUiLoader class and reimplement this function to intervene the + process of constructing an user interface or widget. + + \sa createAction(), createWidget(), load() + */ +QActionGroup *QUiLoader::createActionGroup(QObject *parent, const QString &name) +{ + Q_D(QUiLoader); + return d->builder.defaultCreateActionGroup(parent, name); +} + +/*! + Creates a new action with the given \a parent and \a name. + + The function is used internally by the QUiLoader class whenever it + has to create an action. For that reason, you can subclass the + QUiLoader class and reimplement this function to intervene the + process of constructing an user interface or widget. + + \sa createActionGroup(), createWidget(), load() +*/ +QAction *QUiLoader::createAction(QObject *parent, const QString &name) +{ + Q_D(QUiLoader); + return d->builder.defaultCreateAction(parent, name); +} + +/*! + Returns a list naming the available widgets that can be built + using the createWidget() function, i.e all the widgets specified + within the given plugin paths. + + \sa pluginPaths(), createWidget() + +*/ +QStringList QUiLoader::availableWidgets() const +{ + Q_D(const QUiLoader); + + d->setupWidgetMap(); + widget_map available = *g_widgets(); + + foreach (QDesignerCustomWidgetInterface *plugin, d->builder.customWidgets()) { + available.insert(plugin->name(), true); + } + + return available.keys(); +} + + +/*! + Returns a list naming the available layouts that can be built + using the createLayout() function + + \sa createLayout() + \since 4.5 +*/ + +QStringList QUiLoader::availableLayouts() const +{ + QStringList rc; +#define DECLARE_WIDGET(a, b) +#define DECLARE_LAYOUT(a, b) rc.push_back(QLatin1String(#a)); + +#include "widgets.table" + +#undef DECLARE_WIDGET +#undef DECLARE_LAYOUT + return rc; +} + +/*! + Sets the working directory of the loader to \a dir. The loader + looks for other resources, such as icons and resource files, + in paths relative to this directory. + + \sa workingDirectory() +*/ + +void QUiLoader::setWorkingDirectory(const QDir &dir) +{ + Q_D(QUiLoader); + d->builder.setWorkingDirectory(dir); +} + +/*! + Returns the working directory of the loader. + + \sa setWorkingDirectory() +*/ + +QDir QUiLoader::workingDirectory() const +{ + Q_D(const QUiLoader); + return d->builder.workingDirectory(); +} + +/*! + Sets whether the execution of scripts is enabled to \a enabled. + \since 4.3 + \internal +*/ + +void QUiLoader::setScriptingEnabled(bool enabled) +{ + Q_D(QUiLoader); + d->builder.setScriptingEnabled(enabled); +} + +/*! + Returns whether the execution of scripts is enabled. + \sa setScriptingEnabled() + \since 4.3 + \internal +*/ + +bool QUiLoader::isScriptingEnabled() const +{ + Q_D(const QUiLoader); + return d->builder.isScriptingEnabled(); +} + +/*! + Sets whether user interfaces loaded by this loader automatically + retranslate themselves upon receiving a language change event or not, + depending on \a enabled. + + \since 4.5 +*/ + +void QUiLoader::setLanguageChangeEnabled(bool enabled) +{ + Q_D(QUiLoader); + d->builder.dynamicTr = enabled; +} + +/*! + Returns whether dynamic retranslation on language change is enabled. + \sa setLanguageChangeEnabled() + \since 4.5 +*/ + +bool QUiLoader::isLanguageChangeEnabled() const +{ + Q_D(const QUiLoader); + return d->builder.dynamicTr; +} + +/*! + \internal + + Sets whether user interfaces loaded by this loader are translated + at all. Note that this is orthogonal to languageChangeEnabled. + + \since 4.5 +*/ + +void QUiLoader::setTranslationEnabled(bool enabled) +{ + Q_D(QUiLoader); + d->builder.trEnabled = enabled; +} + +/*! + \internal + + Returns whether translation is enabled. + \sa setTranslationEnabled() + + \since 4.5 +*/ + +bool QUiLoader::isTranslationEnabled() const +{ + Q_D(const QUiLoader); + return d->builder.trEnabled; +} + +QT_END_NAMESPACE + +#include "quiloader.moc" diff --git a/tools/designer/src/uitools/quiloader.h b/tools/designer/src/uitools/quiloader.h new file mode 100644 index 0000000..6543ba8 --- /dev/null +++ b/tools/designer/src/uitools/quiloader.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUILOADER_H +#define QUILOADER_H + +#include <QtCore/QObject> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QWidget; +class QLayout; +class QAction; +class QActionGroup; +class QString; +class QIODevice; +class QDir; + +class QUiLoaderPrivate; +class QUiLoader : public QObject +{ + Q_OBJECT +public: + QUiLoader(QObject *parent = 0); + virtual ~QUiLoader(); + + QStringList pluginPaths() const; + void clearPluginPaths(); + void addPluginPath(const QString &path); + + QWidget *load(QIODevice *device, QWidget *parentWidget = 0); + QStringList availableWidgets() const; + QStringList availableLayouts() const; + + virtual QWidget *createWidget(const QString &className, QWidget *parent = 0, const QString &name = QString()); + virtual QLayout *createLayout(const QString &className, QObject *parent = 0, const QString &name = QString()); + virtual QActionGroup *createActionGroup(QObject *parent = 0, const QString &name = QString()); + virtual QAction *createAction(QObject *parent = 0, const QString &name = QString()); + + void setWorkingDirectory(const QDir &dir); + QDir workingDirectory() const; + + void setScriptingEnabled(bool enabled); + bool isScriptingEnabled() const; + + void setLanguageChangeEnabled(bool enabled); + bool isLanguageChangeEnabled() const; + + void setTranslationEnabled(bool enabled); + bool isTranslationEnabled() const; + +private: + QUiLoaderPrivate *d_ptr; + Q_DECLARE_PRIVATE(QUiLoader) + Q_DISABLE_COPY(QUiLoader) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QUILOADER_H diff --git a/tools/designer/src/uitools/quiloader_p.h b/tools/designer/src/uitools/quiloader_p.h new file mode 100644 index 0000000..6441106 --- /dev/null +++ b/tools/designer/src/uitools/quiloader_p.h @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the Qt Designer of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUILOADER_P_H +#define QUILOADER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QByteArray> +#include <QtCore/QMetaType> + +// This file is here for use by the form preview in Linguist. If you change anything +// here or in the code which uses it, remember to adapt Linguist accordingly. + +#define PROP_GENERIC_PREFIX "_q_notr_" +#define PROP_TOOLITEMTEXT "_q_toolItemText_notr" +#define PROP_TOOLITEMTOOLTIP "_q_toolItemToolTip_notr" +#define PROP_TABPAGETEXT "_q_tabPageText_notr" +#define PROP_TABPAGETOOLTIP "_q_tabPageToolTip_notr" +#define PROP_TABPAGEWHATSTHIS "_q_tabPageWhatsThis_notr" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QUiTranslatableStringValue +{ +public: + QByteArray value() const { return m_value; } + void setValue(const QByteArray &value) { m_value = value; } + QByteArray comment() const { return m_comment; } + void setComment(const QByteArray &comment) { m_comment = comment; } + +private: + QByteArray m_value; + QByteArray m_comment; +}; + +struct QUiItemRolePair { + int realRole; + int shadowRole; +}; + +#ifdef QFORMINTERNAL_NAMESPACE +namespace QFormInternal +{ +#endif + +extern const QUiItemRolePair qUiItemRoles[]; + +#ifdef QFORMINTERNAL_NAMESPACE +} +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +Q_DECLARE_METATYPE(QUiTranslatableStringValue) + + +#endif // QUILOADER_P_H diff --git a/tools/designer/src/uitools/uitools.pro b/tools/designer/src/uitools/uitools.pro new file mode 100644 index 0000000..a20abf0 --- /dev/null +++ b/tools/designer/src/uitools/uitools.pro @@ -0,0 +1,41 @@ +TEMPLATE = lib +TARGET = $$qtLibraryTarget(QtUiTools) +QT += xml +CONFIG += qt staticlib +DESTDIR = ../../../../lib +DLLDESTDIR = ../../../../bin + +win32|mac:!macx-xcode:CONFIG += debug_and_release build_all + +DEFINES += QFORMINTERNAL_NAMESPACE QT_DESIGNER_STATIC QT_FORMBUILDER_NO_SCRIPT +isEmpty(QT_MAJOR_VERSION) { + VERSION=4.3.0 +} else { + VERSION=$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION} +} +include(../../../../src/qt_targets.pri) +QMAKE_TARGET_PRODUCT = UiLoader +QMAKE_TARGET_DESCRIPTION = QUiLoader + +include(../lib/uilib/uilib.pri) + +HEADERS += quiloader.h +SOURCES += quiloader.cpp + +include($$QT_BUILD_TREE/include/QtUiTools/headers.pri) +quitools_headers.files = $$SYNCQT.HEADER_FILES $$SYNCQT.HEADER_CLASSES +quitools_headers.path = $$[QT_INSTALL_HEADERS]/QtUiTools +INSTALLS += quitools_headers + +target.path=$$[QT_INSTALL_LIBS] +INSTALLS += target + +unix { + CONFIG += create_pc + QMAKE_PKGCONFIG_LIBDIR = $$[QT_INSTALL_LIBS] + QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS]/$$TARGET + QMAKE_PKGCONFIG_CFLAGS = -I$$[QT_INSTALL_HEADERS] + QMAKE_PKGCONFIG_DESTDIR = pkgconfig + QMAKE_PKGCONFIG_REQUIRES += QtXml +} + |