summaryrefslogtreecommitdiffstats
path: root/src/designer/src/components/formeditor/qdesigner_resource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/designer/src/components/formeditor/qdesigner_resource.cpp')
-rw-r--r--src/designer/src/components/formeditor/qdesigner_resource.cpp2475
1 files changed, 2475 insertions, 0 deletions
diff --git a/src/designer/src/components/formeditor/qdesigner_resource.cpp b/src/designer/src/components/formeditor/qdesigner_resource.cpp
new file mode 100644
index 000000000..409a20e8d
--- /dev/null
+++ b/src/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -0,0 +1,2475 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesigner_resource.h"
+#include "formwindow.h"
+#include "dynamicpropertysheet.h"
+#include "qdesigner_tabwidget_p.h"
+#include "qdesigner_toolbox_p.h"
+#include "qdesigner_stackedbox_p.h"
+#include "qdesigner_toolbar_p.h"
+#include "qdesigner_dockwidget_p.h"
+#include "qdesigner_menu_p.h"
+#include "qdesigner_menubar_p.h"
+#include "qdesigner_membersheet_p.h"
+#include "qtresourcemodel_p.h"
+#include "qmdiarea_container.h"
+#include "qwizard_container.h"
+#include "layout_propertysheet.h"
+
+#include <ui4_p.h>
+#include <formbuilderextra_p.h>
+#include <resourcebuilder_p.h>
+#include <textbuilder_p.h>
+#include <qdesigner_widgetitem_p.h>
+
+// shared
+#include <widgetdatabase_p.h>
+#include <metadatabase_p.h>
+#include <layout_p.h>
+#include <layoutinfo_p.h>
+#include <spacer_widget_p.h>
+#include <pluginmanager_p.h>
+#include <widgetfactory_p.h>
+#include <abstractlanguage.h>
+#include <abstractintrospection_p.h>
+
+#include <qlayout_widget_p.h>
+#include <qdesigner_utils_p.h>
+#include <ui4_p.h>
+
+// sdk
+#include <QtDesigner/QDesignerPropertySheetExtension>
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <QtDesigner/QDesignerExtraInfoExtension>
+#include <QtDesigner/QDesignerFormWindowToolInterface>
+#include <QtDesigner/QExtensionManager>
+#include <QtDesigner/QDesignerContainerExtension>
+#include <abstractdialoggui_p.h>
+
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+#include <QtGui/QLayout>
+#include <QtGui/QFormLayout>
+#include <QtGui/QTabWidget>
+#include <QtGui/QToolBox>
+#include <QtGui/QStackedWidget>
+#include <QtGui/QToolBar>
+#include <QtGui/QTabBar>
+#include <QtGui/QAction>
+#include <QtGui/QActionGroup>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QApplication>
+#include <QtGui/QMainWindow>
+#include <QtGui/QSplitter>
+#include <QtGui/QMdiArea>
+#include <QtGui/QWorkspace>
+#include <QtGui/QMenuBar>
+#include <QtGui/QFileDialog>
+#include <QtGui/QHeaderView>
+#include <QtGui/QWizardPage>
+#include <private/qlayoutengine_p.h>
+
+#include <QtCore/QBuffer>
+#include <QtCore/QDir>
+#include <QtCore/QMetaProperty>
+#include <QtCore/qdebug.h>
+#include <QtCore/QXmlStreamWriter>
+
+Q_DECLARE_METATYPE(QWidgetList)
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ typedef QList<DomProperty*> DomPropertyList;
+}
+
+static const char *currentUiVersion = "4.0";
+static const char *clipboardObjectName = "__qt_fake_top_level";
+
+#define OLD_RESOURCE_FORMAT // Support pre 4.4 format.
+
+namespace qdesigner_internal {
+
+// -------------------- QDesignerResourceBuilder: A resource builder that works on the property sheet icon types.
+class QDesignerResourceBuilder : public QResourceBuilder
+{
+public:
+ QDesignerResourceBuilder(QDesignerFormEditorInterface *core, DesignerPixmapCache *pixmapCache, DesignerIconCache *iconCache);
+
+ void setPixmapCache(DesignerPixmapCache *pixmapCache) { m_pixmapCache = pixmapCache; }
+ void setIconCache(DesignerIconCache *iconCache) { m_iconCache = iconCache; }
+ bool isSaveRelative() const { return m_saveRelative; }
+ void setSaveRelative(bool relative) { m_saveRelative = relative; }
+ QStringList usedQrcFiles() const { return m_usedQrcFiles.keys(); }
+#ifdef OLD_RESOURCE_FORMAT
+ QStringList loadedQrcFiles() const { return m_loadedQrcFiles.keys(); } // needed only for loading old resource attribute of <iconset> tag.
+#endif
+
+ virtual QVariant loadResource(const QDir &workingDirectory, const DomProperty *icon) const;
+
+ virtual QVariant toNativeValue(const QVariant &value) const;
+
+ virtual DomProperty *saveResource(const QDir &workingDirectory, const QVariant &value) const;
+
+ virtual bool isResourceType(const QVariant &value) const;
+private:
+
+ QDesignerFormEditorInterface *m_core;
+ DesignerPixmapCache *m_pixmapCache;
+ DesignerIconCache *m_iconCache;
+ const QDesignerLanguageExtension *m_lang;
+ bool m_saveRelative;
+ mutable QMap<QString, bool> m_usedQrcFiles;
+ mutable QMap<QString, bool> m_loadedQrcFiles;
+};
+
+QDesignerResourceBuilder::QDesignerResourceBuilder(QDesignerFormEditorInterface *core, DesignerPixmapCache *pixmapCache, DesignerIconCache *iconCache) :
+ m_core(core),
+ m_pixmapCache(pixmapCache),
+ m_iconCache(iconCache),
+ m_lang(qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core)),
+ m_saveRelative(true)
+{
+}
+
+static inline void setIconPixmap(QIcon::Mode m, QIcon::State s, const QDir &workingDirectory,
+ QString path, PropertySheetIconValue &icon,
+ const QDesignerLanguageExtension *lang = 0)
+{
+ if (lang == 0 || !lang->isLanguageResource(path))
+ path = QFileInfo(workingDirectory, path).absoluteFilePath();
+ icon.setPixmap(m, s, PropertySheetPixmapValue(path));
+}
+
+QVariant QDesignerResourceBuilder::loadResource(const QDir &workingDirectory, const DomProperty *property) const
+{
+ switch (property->kind()) {
+ case DomProperty::Pixmap: {
+ PropertySheetPixmapValue pixmap;
+ DomResourcePixmap *dp = property->elementPixmap();
+ if (!dp->text().isEmpty()) {
+ if (m_lang != 0 && m_lang->isLanguageResource(dp->text())) {
+ pixmap.setPath(dp->text());
+ } else {
+ pixmap.setPath(QFileInfo(workingDirectory, dp->text()).absoluteFilePath());
+ }
+#ifdef OLD_RESOURCE_FORMAT
+ if (dp->hasAttributeResource())
+ m_loadedQrcFiles.insert(QFileInfo(workingDirectory, dp->attributeResource()).absoluteFilePath(), false);
+#endif
+ }
+ return QVariant::fromValue(pixmap);
+ }
+
+ case DomProperty::IconSet: {
+ PropertySheetIconValue icon;
+ DomResourceIcon *di = property->elementIconSet();
+ icon.setTheme(di->attributeTheme());
+ if (const int flags = iconStateFlags(di)) { // new, post 4.4 format
+ if (flags & NormalOff)
+ setIconPixmap(QIcon::Normal, QIcon::Off, workingDirectory, di->elementNormalOff()->text(), icon, m_lang);
+ if (flags & NormalOn)
+ setIconPixmap(QIcon::Normal, QIcon::On, workingDirectory, di->elementNormalOn()->text(), icon, m_lang);
+ if (flags & DisabledOff)
+ setIconPixmap(QIcon::Disabled, QIcon::Off, workingDirectory, di->elementDisabledOff()->text(), icon, m_lang);
+ if (flags & DisabledOn)
+ setIconPixmap(QIcon::Disabled, QIcon::On, workingDirectory, di->elementDisabledOn()->text(), icon, m_lang);
+ if (flags & ActiveOff)
+ setIconPixmap(QIcon::Active, QIcon::Off, workingDirectory, di->elementActiveOff()->text(), icon, m_lang);
+ if (flags & ActiveOn)
+ setIconPixmap(QIcon::Active, QIcon::On, workingDirectory, di->elementActiveOn()->text(), icon, m_lang);
+ if (flags & SelectedOff)
+ setIconPixmap(QIcon::Selected, QIcon::Off, workingDirectory, di->elementSelectedOff()->text(), icon, m_lang);
+ if (flags & SelectedOn)
+ setIconPixmap(QIcon::Selected, QIcon::On, workingDirectory, di->elementSelectedOn()->text(), icon, m_lang);
+ } else {
+#ifdef OLD_RESOURCE_FORMAT
+ setIconPixmap(QIcon::Normal, QIcon::Off, workingDirectory, di->text(), icon, m_lang);
+ if (di->hasAttributeResource())
+ m_loadedQrcFiles.insert(QFileInfo(workingDirectory, di->attributeResource()).absoluteFilePath(), false);
+#endif
+ }
+ return QVariant::fromValue(icon);
+ }
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QVariant QDesignerResourceBuilder::toNativeValue(const QVariant &value) const
+{
+ if (value.canConvert<PropertySheetPixmapValue>()) {
+ if (m_pixmapCache)
+ return m_pixmapCache->pixmap(qvariant_cast<PropertySheetPixmapValue>(value));
+ } else if (value.canConvert<PropertySheetIconValue>()) {
+ if (m_iconCache)
+ return m_iconCache->icon(qvariant_cast<PropertySheetIconValue>(value));
+ }
+ return value;
+}
+
+DomProperty *QDesignerResourceBuilder::saveResource(const QDir &workingDirectory, const QVariant &value) const
+{
+ DomProperty *p = new DomProperty;
+ if (value.canConvert<PropertySheetPixmapValue>()) {
+ const PropertySheetPixmapValue pix = qvariant_cast<PropertySheetPixmapValue>(value);
+ DomResourcePixmap *rp = new DomResourcePixmap;
+ const QString pixPath = pix.path();
+ switch (pix.pixmapSource(m_core)) {
+ case PropertySheetPixmapValue::LanguageResourcePixmap:
+ rp->setText(pixPath);
+ break;
+ case PropertySheetPixmapValue::ResourcePixmap: {
+ rp->setText(pixPath);
+ const QString qrcFile = m_core->resourceModel()->qrcPath(pixPath);
+ if (!qrcFile.isEmpty()) {
+ m_usedQrcFiles.insert(qrcFile, false);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Add qrc path
+ rp->setAttributeResource(workingDirectory.relativeFilePath(qrcFile));
+#endif
+ }
+ }
+ break;
+ case PropertySheetPixmapValue::FilePixmap:
+ rp->setText(m_saveRelative ? workingDirectory.relativeFilePath(pixPath) : pixPath);
+ break;
+ }
+ p->setElementPixmap(rp);
+ return p;
+ } else if (value.canConvert<PropertySheetIconValue>()) {
+ const PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(value);
+ const QMap<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> pixmaps = icon.paths();
+ const QString theme = icon.theme();
+ if (!pixmaps.isEmpty() || !theme.isEmpty()) {
+ DomResourceIcon *ri = new DomResourceIcon;
+ if (!theme.isEmpty())
+ ri->setAttributeTheme(theme);
+ QMapIterator<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> itPix(pixmaps);
+ while (itPix.hasNext()) {
+ const QIcon::Mode mode = itPix.next().key().first;
+ const QIcon::State state = itPix.key().second;
+ DomResourcePixmap *rp = new DomResourcePixmap;
+ const PropertySheetPixmapValue pix = itPix.value();
+ const PropertySheetPixmapValue::PixmapSource ps = pix.pixmapSource(m_core);
+ const QString pixPath = pix.path();
+ rp->setText(ps == PropertySheetPixmapValue::FilePixmap && m_saveRelative ? workingDirectory.relativeFilePath(pixPath) : pixPath);
+ if (state == QIcon::Off) {
+ switch (mode) {
+ case QIcon::Normal:
+ ri->setElementNormalOff(rp);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Set Normal off as text/path in old format.
+ ri->setText(rp->text());
+#endif
+ if (ps == PropertySheetPixmapValue::ResourcePixmap) {
+ // Be sure that ri->text() file comes from active resourceSet (i.e. make appropriate
+ // resourceSet active before calling this method).
+ const QString qrcFile = m_core->resourceModel()->qrcPath(ri->text());
+ if (!qrcFile.isEmpty()) {
+ m_usedQrcFiles.insert(qrcFile, false);
+#ifdef OLD_RESOURCE_FORMAT // Legacy: Set Normal off as text/path in old format.
+ ri->setAttributeResource(workingDirectory.relativeFilePath(qrcFile));
+#endif
+ }
+ }
+ break;
+ case QIcon::Disabled: ri->setElementDisabledOff(rp); break;
+ case QIcon::Active: ri->setElementActiveOff(rp); break;
+ case QIcon::Selected: ri->setElementSelectedOff(rp); break;
+ }
+ } else {
+ switch (mode) {
+ case QIcon::Normal: ri->setElementNormalOn(rp); break;
+ case QIcon::Disabled: ri->setElementDisabledOn(rp); break;
+ case QIcon::Active: ri->setElementActiveOn(rp); break;
+ case QIcon::Selected: ri->setElementSelectedOn(rp); break;
+ }
+ }
+ }
+ p->setElementIconSet(ri);
+ return p;
+ }
+ }
+ delete p;
+ return 0;
+}
+
+bool QDesignerResourceBuilder::isResourceType(const QVariant &value) const
+{
+ if (value.canConvert<PropertySheetPixmapValue>() || value.canConvert<PropertySheetIconValue>())
+ return true;
+ return false;
+}
+// ------------------------- QDesignerTextBuilder
+class QDesignerTextBuilder : public QTextBuilder
+{
+public:
+ QDesignerTextBuilder() {}
+
+ virtual QVariant loadText(const DomProperty *icon) const;
+
+ virtual QVariant toNativeValue(const QVariant &value) const;
+
+ virtual DomProperty *saveText(const QVariant &value) const;
+};
+
+QVariant QDesignerTextBuilder::loadText(const DomProperty *text) const
+{
+ const DomString *str = text->elementString();
+ PropertySheetStringValue strVal(str->text());
+ if (str->hasAttributeComment()) {
+ strVal.setDisambiguation(str->attributeComment());
+ }
+ if (str->hasAttributeExtraComment()) {
+ strVal.setComment(str->attributeExtraComment());
+ }
+ if (str->hasAttributeNotr()) {
+ const QString notr = str->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ strVal.setTranslatable(translatable);
+ }
+ return QVariant::fromValue(strVal);
+}
+
+QVariant QDesignerTextBuilder::toNativeValue(const QVariant &value) const
+{
+ if (value.canConvert<PropertySheetStringValue>())
+ return QVariant::fromValue(qvariant_cast<PropertySheetStringValue>(value).value());
+ return value;
+}
+
+DomProperty *QDesignerTextBuilder::saveText(const QVariant &value) const
+{
+ if (!value.canConvert<PropertySheetStringValue>() && !value.canConvert<QString>())
+ return 0;
+
+ DomProperty *property = new DomProperty();
+ DomString *domStr = new DomString();
+
+ if (value.canConvert<PropertySheetStringValue>()) {
+ PropertySheetStringValue str = qvariant_cast<PropertySheetStringValue>(value);
+
+ domStr->setText(str.value());
+
+ const QString property_comment = str.disambiguation();
+ if (!property_comment.isEmpty())
+ domStr->setAttributeComment(property_comment);
+ const QString property_extraComment = str.comment();
+ if (!property_extraComment.isEmpty())
+ domStr->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = str.translatable();
+ if (!property_translatable)
+ domStr->setAttributeNotr(QLatin1String("true"));
+ } else {
+ domStr->setText(value.toString());
+ }
+
+ property->setElementString(domStr);
+ return property;
+}
+
+QDesignerResource::QDesignerResource(FormWindow *formWindow) :
+ QEditorFormBuilder(formWindow->core()),
+ m_formWindow(formWindow),
+ m_topLevelSpacerCount(0),
+ m_copyWidget(false),
+ m_selected(0),
+ m_resourceBuilder(new QDesignerResourceBuilder(m_formWindow->core(), m_formWindow->pixmapCache(), m_formWindow->iconCache()))
+{
+ setWorkingDirectory(formWindow->absoluteDir());
+ setResourceBuilder(m_resourceBuilder);
+ setTextBuilder(new QDesignerTextBuilder());
+
+ // ### generalise
+ const QString designerWidget = QLatin1String("QDesignerWidget");
+ const QString layoutWidget = QLatin1String("QLayoutWidget");
+ const QString widget = QLatin1String("QWidget");
+ m_internal_to_qt.insert(layoutWidget, widget);
+ m_internal_to_qt.insert(designerWidget, widget);
+ m_internal_to_qt.insert(QLatin1String("QDesignerDialog"), QLatin1String("QDialog"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerMenuBar"), QLatin1String("QMenuBar"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerMenu"), QLatin1String("QMenu"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerDockWidget"), QLatin1String("QDockWidget"));
+ m_internal_to_qt.insert(QLatin1String("QDesignerQ3WidgetStack"), QLatin1String("Q3WidgetStack"));
+
+ // invert
+ QHash<QString, QString>::const_iterator cend = m_internal_to_qt.constEnd();
+ for (QHash<QString, QString>::const_iterator it = m_internal_to_qt.constBegin();it != cend; ++it ) {
+ if (it.value() != designerWidget && it.value() != layoutWidget)
+ m_qt_to_internal.insert(it.value(), it.key());
+
+ }
+}
+
+QDesignerResource::~QDesignerResource()
+{
+}
+
+static inline QString messageBoxTitle()
+{
+ return QApplication::translate("Designer", "Qt Designer");
+}
+
+void QDesignerResource::save(QIODevice *dev, QWidget *widget)
+{
+ m_topLevelSpacerCount = 0;
+
+ QAbstractFormBuilder::save(dev, widget);
+
+ if (QSimpleResource::warningsEnabled() && m_topLevelSpacerCount != 0) {
+ const QString message = QApplication::translate("Designer", "This file contains top level spacers.<br>"
+ "They have <b>NOT</b> been saved into the form.");
+ const QString infoMessage = QApplication::translate("Designer", "Perhaps you forgot to create a layout?");
+
+ core()->dialogGui()->message(widget->window(), QDesignerDialogGuiInterface::TopLevelSpacerMessage,
+ QMessageBox::Warning, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ }
+}
+
+void QDesignerResource::saveDom(DomUI *ui, QWidget *widget)
+{
+ QAbstractFormBuilder::saveDom(ui, widget);
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ Q_ASSERT(sheet != 0);
+
+ const QVariant classVar = sheet->property(sheet->indexOf(QLatin1String("objectName")));
+ QString classStr;
+ if (classVar.canConvert(QVariant::String))
+ classStr = classVar.toString();
+ else
+ classStr = qvariant_cast<PropertySheetStringValue>(classVar).value();
+ ui->setElementClass(classStr);
+
+ for (int index = 0; index < m_formWindow->toolCount(); ++index) {
+ QDesignerFormWindowToolInterface *tool = m_formWindow->tool(index);
+ Q_ASSERT(tool != 0);
+ tool->saveToDom(ui, widget);
+ }
+
+ const QString author = m_formWindow->author();
+ if (!author.isEmpty()) {
+ ui->setElementAuthor(author);
+ }
+
+ const QString comment = m_formWindow->comment();
+ if (!comment.isEmpty()) {
+ ui->setElementComment(comment);
+ }
+
+ const QString exportMacro = m_formWindow->exportMacro();
+ if (!exportMacro.isEmpty()) {
+ ui->setElementExportMacro(exportMacro);
+ }
+
+ const QVariantMap designerFormData = m_formWindow->formData();
+ if (!designerFormData.empty()) {
+ DomPropertyList domPropertyList;
+ const QVariantMap::const_iterator cend = designerFormData.constEnd();
+ for (QVariantMap::const_iterator it = designerFormData.constBegin(); it != cend; ++it) {
+ if (DomProperty *prop = variantToDomProperty(this, widget->metaObject(), it.key(), it.value()))
+ domPropertyList += prop;
+ }
+ if (!domPropertyList.empty()) {
+ DomDesignerData* domDesignerFormData = new DomDesignerData;
+ domDesignerFormData->setElementProperty(domPropertyList);
+ ui->setElementDesignerdata(domDesignerFormData);
+ }
+ }
+
+ if (!m_formWindow->includeHints().isEmpty()) {
+ const QString local = QLatin1String("local");
+ const QString global = QLatin1String("global");
+ QList<DomInclude*> ui_includes;
+ foreach (QString includeHint, m_formWindow->includeHints()) {
+ if (includeHint.isEmpty())
+ continue;
+ DomInclude *incl = new DomInclude;
+ const QString location = includeHint.at(0) == QLatin1Char('<') ? global : local;
+ includeHint.remove(QLatin1Char('"'));
+ includeHint.remove(QLatin1Char('<'));
+ includeHint.remove(QLatin1Char('>'));
+ incl->setAttributeLocation(location);
+ incl->setText(includeHint);
+ ui_includes.append(incl);
+ }
+
+ DomIncludes *includes = new DomIncludes;
+ includes->setElementInclude(ui_includes);
+ ui->setElementIncludes(includes);
+ }
+
+ int defaultMargin = INT_MIN, defaultSpacing = INT_MIN;
+ m_formWindow->layoutDefault(&defaultMargin, &defaultSpacing);
+
+ if (defaultMargin != INT_MIN || defaultSpacing != INT_MIN) {
+ DomLayoutDefault *def = new DomLayoutDefault;
+ if (defaultMargin != INT_MIN)
+ def->setAttributeMargin(defaultMargin);
+ if (defaultSpacing != INT_MIN)
+ def->setAttributeSpacing(defaultSpacing);
+ ui->setElementLayoutDefault(def);
+ }
+
+ QString marginFunction, spacingFunction;
+ m_formWindow->layoutFunction(&marginFunction, &spacingFunction);
+ if (!marginFunction.isEmpty() || !spacingFunction.isEmpty()) {
+ DomLayoutFunction *def = new DomLayoutFunction;
+
+ if (!marginFunction.isEmpty())
+ def->setAttributeMargin(marginFunction);
+ if (!spacingFunction.isEmpty())
+ def->setAttributeSpacing(spacingFunction);
+ ui->setElementLayoutFunction(def);
+ }
+
+ QString pixFunction = m_formWindow->pixmapFunction();
+ if (!pixFunction.isEmpty()) {
+ ui->setElementPixmapFunction(pixFunction);
+ }
+
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core()))
+ extra->saveUiExtraInfo(ui);
+
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ const MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(m_formWindow->mainContainer());
+ const QStringList fakeSlots = item->fakeSlots();
+ const QStringList fakeSignals =item->fakeSignals();
+ if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ DomSlots *domSlots = new DomSlots();
+ domSlots->setElementSlot(fakeSlots);
+ domSlots->setElementSignal(fakeSignals);
+ ui->setElementSlots(domSlots);
+ }
+ }
+}
+
+namespace {
+ enum LoadPreCheck { LoadPreCheckFailed, LoadPreCheckVersion3, LoadPreCheckVersionMismatch, LoadPreCheckOk };
+ // Pair of major, minor
+ typedef QPair<int, int> UiVersion;
+}
+
+static UiVersion uiVersion(const QString &attr)
+{
+ const QStringList versions = attr.split(QLatin1Char('.'));
+ if (versions.empty())
+ return UiVersion(-1, -1);
+
+ bool ok = false;
+ UiVersion rc(versions.at(0).toInt(&ok), 0);
+
+ if (!ok)
+ return UiVersion(-1, -1);
+
+ if (versions.size() > 1) {
+ const int minorVersion = versions.at(1).toInt(&ok);
+ if (ok)
+ rc.second = minorVersion;
+ }
+ return rc;
+}
+
+// Read version and language attributes of an <UI> element.
+static bool readUiAttributes(QIODevice *dev, QString *errorMessage,
+ QString *version,
+ QString *language)
+{
+ const QString uiElement = QLatin1String("ui");
+ const QString versionAttribute = QLatin1String("version");
+ const QString languageAttribute = QLatin1String("language");
+ QXmlStreamReader reader(dev);
+ // Read up to first element
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ const QStringRef tag = reader.name();
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive) == 0) {
+ const QXmlStreamAttributes attributes = reader.attributes();
+ if (attributes.hasAttribute(versionAttribute))
+ *version = attributes.value(versionAttribute).toString();
+ if (attributes.hasAttribute(languageAttribute))
+ *language = attributes.value(languageAttribute).toString();
+ return true;
+ } else {
+ *errorMessage = QCoreApplication::translate("Designer", "Invalid UI file: The root element <ui> is missing.");
+ return false;
+
+ }
+ }
+ }
+ *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the UI file at line %1, column %2: %3")
+ .arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString());
+ return false;
+}
+
+// While loading a file, check language, version and extra extension
+static LoadPreCheck loadPrecheck(QDesignerFormEditorInterface *core,
+ QIODevice *dev,
+ QString *errorMessage, QString *versionString)
+{
+ QString language;
+ // Read attributes of <ui> and rewind
+ if (!readUiAttributes(dev, errorMessage, versionString, &language)) {
+ // XML error: Mimick the behaviour occurring if an XML error is
+ // detected later on, report to warning log and have embedding
+ // application display a dialog.
+ designerWarning(*errorMessage);
+ errorMessage->clear();
+ return LoadPreCheckFailed;
+ }
+ dev->seek(0);
+
+ // Check language unless extension present (Jambi)
+ if (!language.isEmpty() && !qt_extension<QDesignerLanguageExtension*>(core->extensionManager(), core)) {
+ if (language.toLower() != QLatin1String("c++")) {
+ // Jambi?!
+ *errorMessage = QApplication::translate("Designer", "This file cannot be read because it was created using %1.").arg(language);
+ return LoadPreCheckFailed;
+ }
+ }
+
+ // Version
+ if (!versionString->isEmpty()) {
+ const UiVersion version = uiVersion(*versionString);
+ switch (version.first) {
+ case 3:
+ return LoadPreCheckVersion3;
+ case 4:
+ break;
+ default:
+ *errorMessage = QApplication::translate("Designer", "This file was created using Designer from Qt-%1 and cannot be read.").arg(*versionString);
+ return LoadPreCheckVersionMismatch;
+ }
+ }
+ return LoadPreCheckOk;
+}
+
+QWidget *QDesignerResource::load(QIODevice *dev, QWidget *parentWidget)
+{
+ // Run loadPreCheck for version and language
+ QString errorMessage;
+ QString version;
+ switch (loadPrecheck(core(), dev, &errorMessage, &version)) {
+ case LoadPreCheckFailed:
+ case LoadPreCheckVersionMismatch:
+ if (!errorMessage.isEmpty())
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), errorMessage, QMessageBox::Ok);
+ return 0;
+ case LoadPreCheckVersion3: {
+ QWidget *w = 0;
+ QByteArray ba;
+ if (runUIC( m_formWindow->fileName(), UIC_ConvertV3, ba, errorMessage)) {
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::ReadOnly);
+ w = load(&buffer, parentWidget);
+ if (w) {
+ // Force the form to pop up a save file dialog
+ m_formWindow->setFileName(QString());
+ } else {
+ errorMessage = QApplication::translate("Designer", "The converted file could not be read.");
+ }
+ }
+ if (w) {
+ const QString message = QApplication::translate("Designer",
+ "This file was created using Designer from Qt-%1 and"
+ " will be converted to a new form by Qt Designer.").arg(version);
+ const QString infoMessage = QApplication::translate("Designer",
+ "The old form has not been touched, but you will have to save the form"
+ " under a new name.");
+
+ core()->dialogGui()->message(parentWidget->window(),
+ QDesignerDialogGuiInterface::UiVersionMismatchMessage,
+ QMessageBox::Information, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ return w;
+ }
+
+ const QString message = QApplication::translate("Designer",
+ "This file was created using Designer from Qt-%1 and "
+ "could not be read:\n%2").arg(version).arg(errorMessage);
+ const QString infoMessage = QApplication::translate("Designer",
+ "Please run it through <b>uic3&nbsp;-convert</b> to convert "
+ "it to Qt-4's ui format.");
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), message, infoMessage,
+ QMessageBox::Ok);
+ return 0;
+ }
+
+ case LoadPreCheckOk:
+ break;
+ }
+ QWidget *w = QEditorFormBuilder::load(dev, parentWidget);
+ if (w) // Store the class name as 'reset' value for the main container's object name.
+ w->setProperty("_q_classname", w->objectName());
+ return w;
+}
+
+bool QDesignerResource::saveRelative() const
+{
+ return m_resourceBuilder->isSaveRelative();
+}
+
+void QDesignerResource::setSaveRelative(bool relative)
+{
+ m_resourceBuilder->setSaveRelative(relative);
+}
+
+QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget)
+{
+ // Load extra info extension. This is used by Jambi for preventing
+ // C++ UI files from being loaded
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core())) {
+ if (!extra->loadUiExtraInfo(ui)) {
+ const QString errorMessage = QApplication::translate("Designer", "This file cannot be read because the extra info extension failed to load.");
+ core()->dialogGui()->message(parentWidget->window(), QDesignerDialogGuiInterface::FormLoadFailureMessage,
+ QMessageBox::Warning, messageBoxTitle(), errorMessage, QMessageBox::Ok);
+ return 0;
+ }
+ }
+
+ qdesigner_internal::WidgetFactory *factory = qobject_cast<qdesigner_internal::WidgetFactory*>(core()->widgetFactory());
+ Q_ASSERT(factory != 0);
+
+ QDesignerFormWindowInterface *previousFormWindow = factory->currentFormWindow(m_formWindow);
+
+ m_isMainWidget = true;
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ QWidget *mainWidget = QAbstractFormBuilder::create(ui, parentWidget);
+
+ if (mainWidget && m_formWindow) {
+ m_formWindow->setAuthor(ui->elementAuthor());
+ m_formWindow->setComment(ui->elementComment());
+ m_formWindow->setExportMacro(ui->elementExportMacro());
+
+ // Designer data
+ QVariantMap designerFormData;
+ if (ui->hasElementDesignerdata()) {
+ const DomPropertyList domPropertyList = ui->elementDesignerdata()->elementProperty();
+ const DomPropertyList::const_iterator cend = domPropertyList.constEnd();
+ for (DomPropertyList::const_iterator it = domPropertyList.constBegin(); it != cend; ++it) {
+ const QVariant vprop = domPropertyToVariant(this, mainWidget->metaObject(), *it);
+ if (vprop.type() != QVariant::Invalid)
+ designerFormData.insert((*it)->attributeName(), vprop);
+ }
+ }
+ m_formWindow->setFormData(designerFormData);
+
+ m_formWindow->setPixmapFunction(ui->elementPixmapFunction());
+
+ if (DomLayoutDefault *def = ui->elementLayoutDefault()) {
+ m_formWindow->setLayoutDefault(def->attributeMargin(), def->attributeSpacing());
+ }
+
+ if (DomLayoutFunction *fun = ui->elementLayoutFunction()) {
+ m_formWindow->setLayoutFunction(fun->attributeMargin(), fun->attributeSpacing());
+ }
+
+ if (DomIncludes *includes = ui->elementIncludes()) {
+ const QString global = QLatin1String("global");
+ QStringList includeHints;
+ foreach (DomInclude *incl, includes->elementInclude()) {
+ QString text = incl->text();
+
+ if (text.isEmpty())
+ continue;
+
+ if (incl->hasAttributeLocation() && incl->attributeLocation() == global ) {
+ text = text.prepend(QLatin1Char('<')).append(QLatin1Char('>'));
+ } else {
+ text = text.prepend(QLatin1Char('"')).append(QLatin1Char('"'));
+ }
+
+ includeHints.append(text);
+ }
+
+ m_formWindow->setIncludeHints(includeHints);
+ }
+
+ // Register all button groups the form builder adds as children of the main container for them to be found
+ // in the signal slot editor
+ const QObjectList mchildren = mainWidget->children();
+ if (!mchildren.empty()) {
+ QDesignerMetaDataBaseInterface *mdb = core()->metaDataBase();
+ const QObjectList::const_iterator cend = mchildren.constEnd();
+ for (QObjectList::const_iterator it = mchildren.constBegin(); it != cend; ++it)
+ if (QButtonGroup *bg = qobject_cast<QButtonGroup*>(*it))
+ mdb->add(bg);
+ }
+ // Load tools
+ for (int index = 0; index < m_formWindow->toolCount(); ++index) {
+ QDesignerFormWindowToolInterface *tool = m_formWindow->tool(index);
+ Q_ASSERT(tool != 0);
+ tool->loadFromDom(ui, mainWidget);
+ }
+ }
+
+ factory->currentFormWindow(previousFormWindow);
+
+ if (const DomSlots *domSlots = ui->elementSlots()) {
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ QStringList fakeSlots;
+ QStringList fakeSignals;
+ if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) {
+ MetaDataBaseItem *item = metaDataBase->metaDataBaseItem(mainWidget);
+ item->setFakeSlots(fakeSlots);
+ item->setFakeSignals(fakeSignals);
+ }
+ }
+ }
+ if (mainWidget) {
+ // Initialize the mainwindow geometry. Has it been explicitly specified?
+ bool hasExplicitGeometry = false;
+ const QList<DomProperty *> properties = ui->elementWidget()->elementProperty();
+ if (!properties.empty()) {
+ const QString geometry = QLatin1String("geometry");
+ foreach (const DomProperty *p, properties)
+ if (p->attributeName() == geometry) {
+ hasExplicitGeometry = true;
+ break;
+ }
+ }
+ if (hasExplicitGeometry) {
+ // Geometry was specified explicitly: Verify that smartMinSize is respected
+ // (changed fonts, label wrapping policies, etc). This does not happen automatically in docked mode.
+ const QSize size = mainWidget->size();
+ const QSize minSize = size.expandedTo(qSmartMinSize(mainWidget));
+ if (minSize != size)
+ mainWidget->resize(minSize);
+ } else {
+ // No explicit Geometry: perform an adjustSize() to resize the form correctly before embedding it into a container
+ // (which might otherwise squeeze the form)
+ mainWidget->adjustSize();
+ }
+ // Some integration wizards create forms with main containers
+ // based on derived classes of QWidget and load them into Designer
+ // without the plugin existing. This will trigger the auto-promotion
+ // mechanism of Designer, which will set container=false for
+ // QWidgets. For the main container, force container=true and warn.
+ const QDesignerWidgetDataBaseInterface *wdb = core()->widgetDataBase();
+ const int wdbIndex = wdb->indexOfObject(mainWidget);
+ if (wdbIndex != -1) {
+ QDesignerWidgetDataBaseItemInterface *item = wdb->item(wdbIndex);
+ // Promoted main container that is not of container type
+ if (item->isPromoted() && !item->isContainer()) {
+ item->setContainer(true);
+ qWarning("** WARNING The form's main container is an unknown custom widget '%s'."
+ " Defaulting to a promoted instance of '%s', assuming container.",
+ item->name().toUtf8().constData(), item->extends().toUtf8().constData());
+ }
+ }
+ }
+ return mainWidget;
+}
+
+QWidget *QDesignerResource::create(DomWidget *ui_widget, QWidget *parentWidget)
+{
+ const QString className = ui_widget->attributeClass();
+ if (!m_isMainWidget && className == QLatin1String("QWidget") && ui_widget->elementLayout().size() &&
+ !ui_widget->hasAttributeNative()) {
+ // ### check if elementLayout.size() == 1
+
+ QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget);
+
+ if (container == 0) {
+ // generate a QLayoutWidget iff the parent is not an QDesignerContainerExtension.
+ ui_widget->setAttributeClass(QLatin1String("QLayoutWidget"));
+ }
+ }
+
+ // save the actions
+ const QList<DomActionRef*> actionRefs = ui_widget->elementAddAction();
+ ui_widget->setElementAddAction(QList<DomActionRef*>());
+
+ QWidget *w = QAbstractFormBuilder::create(ui_widget, parentWidget);
+
+ // restore the actions
+ ui_widget->setElementAddAction(actionRefs);
+
+ if (w == 0)
+ return 0;
+
+ // ### generalize using the extension manager
+ QDesignerMenu *menu = qobject_cast<QDesignerMenu*>(w);
+ QDesignerMenuBar *menuBar = qobject_cast<QDesignerMenuBar*>(w);
+
+ if (menu) {
+ menu->interactive(false);
+ menu->hide();
+ } else if (menuBar) {
+ menuBar->interactive(false);
+ }
+
+ foreach (DomActionRef *ui_action_ref, actionRefs) {
+ const QString name = ui_action_ref->attributeName();
+ if (name == QLatin1String("separator")) {
+ QAction *sep = new QAction(w);
+ sep->setSeparator(true);
+ w->addAction(sep);
+ addMenuAction(sep);
+ } else if (QAction *a = m_actions.value(name)) {
+ w->addAction(a);
+ } else if (QActionGroup *g = m_actionGroups.value(name)) {
+ w->addActions(g->actions());
+ } else if (QMenu *menu = w->findChild<QMenu*>(name)) {
+ w->addAction(menu->menuAction());
+ addMenuAction(menu->menuAction());
+ }
+ }
+
+ if (menu) {
+ menu->interactive(true);
+ menu->adjustSpecialActions();
+ } else if (menuBar) {
+ menuBar->interactive(true);
+ menuBar->adjustSpecialActions();
+ }
+
+ ui_widget->setAttributeClass(className); // fix the class name
+ applyExtensionDataFromDOM(this, core(), ui_widget, w, true);
+
+ // store user-defined scripts
+ if (MetaDataBase *metaDataBase = qobject_cast<MetaDataBase *>(core()->metaDataBase())) {
+ const QString designerSource = QLatin1String("designer");
+ const DomScripts domScripts = ui_widget->elementScript();
+ if (!domScripts.empty()) {
+ foreach (const DomScript *script, domScripts) {
+ if (script->hasAttributeSource() && script->attributeSource() == designerSource) {
+ metaDataBase->metaDataBaseItem(w)->setScript(script->text());
+ }
+ }
+ }
+ }
+
+ return w;
+}
+
+QLayout *QDesignerResource::create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget)
+{
+ QLayout *l = QAbstractFormBuilder::create(ui_layout, layout, parentWidget);
+
+ if (QGridLayout *gridLayout = qobject_cast<QGridLayout*>(l)) {
+ QLayoutSupport::createEmptyCells(gridLayout);
+ } else {
+ if (QFormLayout *formLayout = qobject_cast<QFormLayout*>(l))
+ QLayoutSupport::createEmptyCells(formLayout);
+ }
+ // While the actual values are applied by the form builder, we still need
+ // to mark them as 'changed'.
+ LayoutPropertySheet::markChangedStretchProperties(core(), l, ui_layout);
+ return l;
+}
+
+QLayoutItem *QDesignerResource::create(DomLayoutItem *ui_layoutItem, QLayout *layout, QWidget *parentWidget)
+{
+ if (ui_layoutItem->kind() == DomLayoutItem::Spacer) {
+ const DomSpacer *domSpacer = ui_layoutItem->elementSpacer();
+ const QHash<QString, DomProperty*> properties = propertyMap(domSpacer->elementProperty());
+ Spacer *spacer = static_cast<Spacer*>(core()->widgetFactory()->createWidget(QLatin1String("Spacer"), parentWidget));
+ if (domSpacer->hasAttributeName())
+ changeObjectName(spacer, domSpacer->attributeName());
+ core()->metaDataBase()->add(spacer);
+
+ spacer->setInteractiveMode(false);
+ applyProperties(spacer, ui_layoutItem->elementSpacer()->elementProperty());
+ spacer->setInteractiveMode(true);
+
+ if (m_formWindow) {
+ m_formWindow->manageWidget(spacer);
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), spacer))
+ sheet->setChanged(sheet->indexOf(QLatin1String("orientation")), true);
+ }
+
+ return new QWidgetItem(spacer);
+ } else if (ui_layoutItem->kind() == DomLayoutItem::Layout && parentWidget) {
+ DomLayout *ui_layout = ui_layoutItem->elementLayout();
+ QLayoutWidget *layoutWidget = new QLayoutWidget(m_formWindow, parentWidget);
+ core()->metaDataBase()->add(layoutWidget);
+ if (m_formWindow)
+ m_formWindow->manageWidget(layoutWidget);
+ (void) create(ui_layout, 0, layoutWidget);
+ return new QWidgetItem(layoutWidget);
+ }
+ return QAbstractFormBuilder::create(ui_layoutItem, layout, parentWidget);
+}
+
+void QDesignerResource::changeObjectName(QObject *o, QString objName)
+{
+ m_formWindow->unify(o, objName, true);
+ o->setObjectName(objName);
+
+}
+
+/* If the property is a enum or flag value, retrieve
+ * the existing enum/flag via property sheet and use it to convert */
+
+static bool readDomEnumerationValue(const DomProperty *p,
+ const QDesignerPropertySheetExtension* sheet, int index,
+ QVariant &v)
+{
+ switch (p->kind()) {
+ case DomProperty::Set: {
+ const QVariant sheetValue = sheet->property(index);
+ if (sheetValue.canConvert<PropertySheetFlagValue>()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(sheetValue);
+ bool ok = false;
+ v = f.metaFlags.parseFlags(p->elementSet(), &ok);
+ if (!ok)
+ designerWarning(f.metaFlags.messageParseFailed(p->elementSet()));
+ return true;
+ }
+ }
+ break;
+ case DomProperty::Enum: {
+ const QVariant sheetValue = sheet->property(index);
+ if (sheetValue.canConvert<PropertySheetEnumValue>()) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(sheetValue);
+ bool ok = false;
+ v = e.metaEnum.parseEnum(p->elementEnum(), &ok);
+ if (!ok)
+ designerWarning(e.metaEnum.messageParseFailed(p->elementEnum()));
+ return true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return false;
+}
+
+void QDesignerResource::applyProperties(QObject *o, const QList<DomProperty*> &properties)
+{
+ if (properties.empty())
+ return;
+
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), o);
+ if (!sheet)
+ return;
+
+ QFormBuilderExtra *formBuilderExtra = QFormBuilderExtra::instance(this);
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), o);
+ const bool dynamicPropertiesAllowed = dynamicSheet && dynamicSheet->dynamicPropertiesAllowed();
+
+ const QString objectNameProperty = QLatin1String("objectName");
+ const DomPropertyList::const_iterator cend = properties.constEnd();
+ for (DomPropertyList::const_iterator it = properties.constBegin(); it != cend; ++it) {
+ const DomProperty *p = *it;
+ const QString propertyName = p->attributeName();
+ const int index = sheet->indexOf(propertyName);
+ QVariant v;
+ if (!readDomEnumerationValue(p, sheet, index, v))
+ v = toVariant(o->metaObject(), *it);
+
+ if (p->kind() == DomProperty::String) {
+ if (index != -1 && sheet->property(index).userType() == qMetaTypeId<PropertySheetKeySequenceValue>()) {
+ const DomString *key = p->elementString();
+ PropertySheetKeySequenceValue keyVal(QKeySequence(key->text()));
+ if (key->hasAttributeComment())
+ keyVal.setDisambiguation(key->attributeComment());
+ if (key->hasAttributeExtraComment())
+ keyVal.setComment(key->attributeExtraComment());
+ if (key->hasAttributeNotr()) {
+ const QString notr = key->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ keyVal.setTranslatable(translatable);
+ }
+ v = QVariant::fromValue(keyVal);
+ } else {
+ const DomString *str = p->elementString();
+ PropertySheetStringValue strVal(v.toString());
+ if (str->hasAttributeComment())
+ strVal.setDisambiguation(str->attributeComment());
+ if (str->hasAttributeExtraComment())
+ strVal.setComment(str->attributeExtraComment());
+ if (str->hasAttributeNotr()) {
+ const QString notr = str->attributeNotr();
+ const bool translatable = !(notr == QLatin1String("true") || notr == QLatin1String("yes"));
+ if (!translatable)
+ strVal.setTranslatable(translatable);
+ }
+ v = QVariant::fromValue(strVal);
+ }
+ }
+
+ formBuilderExtra->applyPropertyInternally(o, propertyName, v);
+ if (index != -1) {
+ sheet->setProperty(index, v);
+ sheet->setChanged(index, true);
+ } else if (dynamicPropertiesAllowed) {
+ QVariant defaultValue = QVariant(v.type());
+ bool isDefault = (v == defaultValue);
+ if (v.canConvert<PropertySheetIconValue>()) {
+ defaultValue = QVariant(QVariant::Icon);
+ isDefault = (qvariant_cast<PropertySheetIconValue>(v) == PropertySheetIconValue());
+ } else if (v.canConvert<PropertySheetPixmapValue>()) {
+ defaultValue = QVariant(QVariant::Pixmap);
+ isDefault = (qvariant_cast<PropertySheetPixmapValue>(v) == PropertySheetPixmapValue());
+ } else if (v.canConvert<PropertySheetStringValue>()) {
+ defaultValue = QVariant(QVariant::String);
+ isDefault = (qvariant_cast<PropertySheetStringValue>(v) == PropertySheetStringValue());
+ } else if (v.canConvert<PropertySheetKeySequenceValue>()) {
+ defaultValue = QVariant(QVariant::KeySequence);
+ isDefault = (qvariant_cast<PropertySheetKeySequenceValue>(v) == PropertySheetKeySequenceValue());
+ }
+ if (defaultValue.type() != QVariant::UserType) {
+ const int idx = dynamicSheet->addDynamicProperty(p->attributeName(), defaultValue);
+ if (idx != -1) {
+ sheet->setProperty(idx, v);
+ sheet->setChanged(idx, !isDefault);
+ }
+ }
+ }
+
+ if (propertyName == objectNameProperty)
+ changeObjectName(o, o->objectName());
+ }
+}
+
+QWidget *QDesignerResource::createWidget(const QString &widgetName, QWidget *parentWidget, const QString &_name)
+{
+ QString name = _name;
+ QString className = widgetName;
+ if (m_isMainWidget)
+ m_isMainWidget = false;
+
+ QWidget *w = core()->widgetFactory()->createWidget(className, parentWidget);
+ if (!w)
+ return 0;
+
+ if (name.isEmpty()) {
+ QDesignerWidgetDataBaseInterface *db = core()->widgetDataBase();
+ if (QDesignerWidgetDataBaseItemInterface *item = db->item(db->indexOfObject(w)))
+ name = qtify(item->name());
+ }
+
+ changeObjectName(w, name);
+
+ QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget);
+ if (!qobject_cast<QMenu*>(w) && (!parentWidget || !container)) {
+ m_formWindow->manageWidget(w);
+ if (parentWidget) {
+ QList<QWidget *> list = qvariant_cast<QWidgetList>(parentWidget->property("_q_widgetOrder"));
+ list.append(w);
+ parentWidget->setProperty("_q_widgetOrder", QVariant::fromValue(list));
+ QList<QWidget *> zOrder = qvariant_cast<QWidgetList>(parentWidget->property("_q_zOrder"));
+ zOrder.append(w);
+ parentWidget->setProperty("_q_zOrder", QVariant::fromValue(zOrder));
+ }
+ } else {
+ core()->metaDataBase()->add(w);
+ }
+
+ w->setWindowFlags(w->windowFlags() & ~Qt::Window);
+ // Make sure it is non-modal (for example, KDialog calls setModal(true) in the constructor).
+ w->setWindowModality(Qt::NonModal);
+
+ return w;
+}
+
+QLayout *QDesignerResource::createLayout(const QString &layoutName, QObject *parent, const QString &name)
+{
+ QWidget *layoutBase = 0;
+ QLayout *layout = qobject_cast<QLayout*>(parent);
+
+ if (parent->isWidgetType())
+ layoutBase = static_cast<QWidget*>(parent);
+ else {
+ Q_ASSERT( layout != 0 );
+ layoutBase = layout->parentWidget();
+ }
+
+ LayoutInfo::Type layoutType = LayoutInfo::layoutType(layoutName);
+ if (layoutType == LayoutInfo::NoLayout) {
+ designerWarning(QCoreApplication::translate("QDesignerResource", "The layout type '%1' is not supported, defaulting to grid.").arg(layoutName));
+ layoutType = LayoutInfo::Grid;
+ }
+ QLayout *lay = core()->widgetFactory()->createLayout(layoutBase, layout, layoutType);
+ if (lay != 0)
+ changeObjectName(lay, name);
+
+ return lay;
+}
+
+// save
+DomWidget *QDesignerResource::createDom(QWidget *widget, DomWidget *ui_parentWidget, bool recursive)
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(widget);
+ if (!item)
+ return 0;
+
+ if (qobject_cast<Spacer*>(widget) && m_copyWidget == false) {
+ ++m_topLevelSpacerCount;
+ return 0;
+ }
+
+ const QDesignerWidgetDataBaseInterface *wdb = core()->widgetDataBase();
+ QDesignerWidgetDataBaseItemInterface *widgetInfo = 0;
+ const int widgetInfoIndex = wdb->indexOfObject(widget, false);
+ if (widgetInfoIndex != -1) {
+ widgetInfo = wdb->item(widgetInfoIndex);
+ // Recursively add all dependent custom widgets
+ QDesignerWidgetDataBaseItemInterface *customInfo = widgetInfo;
+ while (customInfo && customInfo->isCustom()) {
+ m_usedCustomWidgets.insert(customInfo, true);
+ const QString extends = customInfo->extends();
+ if (extends == customInfo->name()) {
+ break; // There are faulty files around that have name==extends
+ } else {
+ const int extendsIndex = wdb->indexOfClassName(customInfo->extends());
+ customInfo = extendsIndex != -1 ? wdb->item(extendsIndex) : static_cast<QDesignerWidgetDataBaseItemInterface *>(0);
+ }
+ }
+ }
+
+ DomWidget *w = 0;
+
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(widget))
+ w = saveWidget(tabWidget, ui_parentWidget);
+ else if (QStackedWidget *stackedWidget = qobject_cast<QStackedWidget*>(widget))
+ w = saveWidget(stackedWidget, ui_parentWidget);
+ else if (QToolBox *toolBox = qobject_cast<QToolBox*>(widget))
+ w = saveWidget(toolBox, ui_parentWidget);
+ else if (QToolBar *toolBar = qobject_cast<QToolBar*>(widget))
+ w = saveWidget(toolBar, ui_parentWidget);
+ else if (QDesignerDockWidget *dockWidget = qobject_cast<QDesignerDockWidget*>(widget))
+ w = saveWidget(dockWidget, ui_parentWidget);
+ else if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget))
+ w = saveWidget(widget, container, ui_parentWidget);
+ else if (QWizardPage *wizardPage = qobject_cast<QWizardPage*>(widget))
+ w = saveWidget(wizardPage, ui_parentWidget);
+ else
+ w = QAbstractFormBuilder::createDom(widget, ui_parentWidget, recursive);
+
+ Q_ASSERT( w != 0 );
+
+ if (!qobject_cast<QLayoutWidget*>(widget) && w->attributeClass() == QLatin1String("QWidget")) {
+ w->setAttributeNative(true);
+ }
+
+ const QString className = w->attributeClass();
+ if (m_internal_to_qt.contains(className))
+ w->setAttributeClass(m_internal_to_qt.value(className));
+
+ w->setAttributeName(widget->objectName());
+
+ if (isPromoted( core(), widget)) { // is promoted?
+ Q_ASSERT(widgetInfo != 0);
+
+ w->setAttributeName(widget->objectName());
+ w->setAttributeClass(widgetInfo->name());
+
+ QList<DomProperty*> prop_list = w->elementProperty();
+ foreach (DomProperty *prop, prop_list) {
+ if (prop->attributeName() == QLatin1String("geometry")) {
+ if (DomRect *rect = prop->elementRect()) {
+ rect->setElementX(widget->x());
+ rect->setElementY(widget->y());
+ }
+ break;
+ }
+ }
+ } else if (widgetInfo != 0 && m_usedCustomWidgets.contains(widgetInfo)) {
+ if (widgetInfo->name() != w->attributeClass())
+ w->setAttributeClass(widgetInfo->name());
+ }
+ addExtensionDataToDOM(this, core(), w, widget);
+
+ addUserDefinedScripts(widget, w);
+ return w;
+}
+
+DomLayout *QDesignerResource::createDom(QLayout *layout, DomLayout *ui_parentLayout, DomWidget *ui_parentWidget)
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(layout);
+
+ if (item == 0) {
+ layout = layout->findChild<QLayout*>();
+ // refresh the meta database item
+ item = core()->metaDataBase()->item(layout);
+ }
+
+ if (item == 0) {
+ // nothing to do.
+ return 0;
+ }
+
+ if (qobject_cast<QSplitter*>(layout->parentWidget()) != 0) {
+ // nothing to do.
+ return 0;
+ }
+
+ m_chain.push(layout);
+
+ DomLayout *l = QAbstractFormBuilder::createDom(layout, ui_parentLayout, ui_parentWidget);
+ Q_ASSERT(l != 0);
+ LayoutPropertySheet::stretchAttributesToDom(core(), layout, l);
+
+ m_chain.pop();
+
+ return l;
+}
+
+DomLayoutItem *QDesignerResource::createDom(QLayoutItem *item, DomLayout *ui_layout, DomWidget *ui_parentWidget)
+{
+ DomLayoutItem *ui_item = 0;
+
+ if (Spacer *s = qobject_cast<Spacer*>(item->widget())) {
+ if (!core()->metaDataBase()->item(s))
+ return 0;
+
+ DomSpacer *spacer = new DomSpacer();
+ const QString objectName = s->objectName();
+ if (!objectName.isEmpty())
+ spacer->setAttributeName(objectName);
+ const QList<DomProperty*> properties = computeProperties(item->widget());
+ // ### filter the properties
+ spacer->setElementProperty(properties);
+
+ ui_item = new DomLayoutItem();
+ ui_item->setElementSpacer(spacer);
+ m_laidout.insert(item->widget(), true);
+ } else if (QLayoutWidget *layoutWidget = qobject_cast<QLayoutWidget*>(item->widget())) {
+ // Do not save a QLayoutWidget if it is within a layout (else it is saved as "QWidget"
+ Q_ASSERT(layoutWidget->layout());
+ DomLayout *l = createDom(layoutWidget->layout(), ui_layout, ui_parentWidget);
+ ui_item = new DomLayoutItem();
+ ui_item->setElementLayout(l);
+ m_laidout.insert(item->widget(), true);
+ } else if (!item->spacerItem()) { // we use spacer as fake item in the Designer
+ ui_item = QAbstractFormBuilder::createDom(item, ui_layout, ui_parentWidget);
+ } else {
+ return 0;
+ }
+ return ui_item;
+}
+
+void QDesignerResource::createCustomWidgets(DomCustomWidgets *dom_custom_widgets)
+{
+ QSimpleResource::handleDomCustomWidgets(core(), dom_custom_widgets);
+}
+
+DomTabStops *QDesignerResource::saveTabStops()
+{
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(m_formWindow);
+ Q_ASSERT(item);
+
+ QStringList tabStops;
+ foreach (QWidget *widget, item->tabOrder()) {
+ if (m_formWindow->mainContainer()->isAncestorOf(widget))
+ tabStops.append(widget->objectName());
+ }
+
+ if (tabStops.count()) {
+ DomTabStops *dom = new DomTabStops;
+ dom->setElementTabStop(tabStops);
+ return dom;
+ }
+
+ return 0;
+}
+
+void QDesignerResource::applyTabStops(QWidget *widget, DomTabStops *tabStops)
+{
+ if (!tabStops)
+ return;
+
+ QList<QWidget*> tabOrder;
+ foreach (const QString &widgetName, tabStops->elementTabStop()) {
+ if (QWidget *w = widget->findChild<QWidget*>(widgetName)) {
+ tabOrder.append(w);
+ }
+ }
+
+ QDesignerMetaDataBaseItemInterface *item = core()->metaDataBase()->item(m_formWindow);
+ Q_ASSERT(item);
+ item->setTabOrder(tabOrder);
+}
+
+/* Unmanaged container pages occur when someone adds a page in a custom widget
+ * constructor. They don't have a meta DB entry which causes createDom
+ * to return 0. */
+inline QString msgUnmanagedPage(QDesignerFormEditorInterface *core,
+ QWidget *container, int index, QWidget *page)
+{
+ return QCoreApplication::translate("QDesignerResource",
+"The container extension of the widget '%1' (%2) returned a widget not managed by Designer '%3' (%4) when queried for page #%5.\n"
+"Container pages should only be added by specifying them in XML returned by the domXml() method of the custom widget.").
+ arg(container->objectName(), WidgetFactory::classNameOf(core, container),
+ page->objectName(), WidgetFactory::classNameOf(core, page)).
+ arg(index);
+}
+
+DomWidget *QDesignerResource::saveWidget(QWidget *widget, QDesignerContainerExtension *container, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ if (DomWidget *ui_page = createDom(page, ui_widget)) {
+ ui_widget_list.append(ui_page);
+ } else {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ }
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QStackedWidget *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+ if (DomWidget *ui_page = createDom(page, ui_widget)) {
+ ui_widget_list.append(ui_page);
+ } else {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ }
+ }
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QToolBar *toolBar, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(toolBar, ui_parentWidget, false);
+ if (const QMainWindow *mainWindow = qobject_cast<QMainWindow*>(toolBar->parentWidget())) {
+ const bool toolBarBreak = mainWindow->toolBarBreak(toolBar);
+ const Qt::ToolBarArea area = mainWindow->toolBarArea(toolBar);
+
+ QList<DomProperty*> attributes = ui_widget->elementAttribute();
+
+ DomProperty *attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("toolBarArea"));
+ attr->setElementEnum(QLatin1String(toolBarAreaMetaEnum().valueToKey(area)));
+ attributes << attr;
+
+ attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("toolBarBreak"));
+ attr->setElementBool(toolBarBreak ? QLatin1String("true") : QLatin1String("false"));
+ attributes << attr;
+ ui_widget->setElementAttribute(attributes);
+ }
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QDesignerDockWidget *dockWidget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(dockWidget, ui_parentWidget, true);
+ if (QMainWindow *mainWindow = qobject_cast<QMainWindow*>(dockWidget->parentWidget())) {
+ const Qt::DockWidgetArea area = mainWindow->dockWidgetArea(dockWidget);
+ DomProperty *attr = new DomProperty();
+ attr->setAttributeName(QLatin1String("dockWidgetArea"));
+ attr->setElementNumber(int(area));
+ ui_widget->setElementAttribute(ui_widget->elementAttribute() << attr);
+ }
+
+ return ui_widget;
+}
+
+static void saveStringProperty(DomProperty *property, const PropertySheetStringValue &value)
+{
+ DomString *str = new DomString();
+ str->setText(value.value());
+
+ const QString property_comment = value.disambiguation();
+ if (!property_comment.isEmpty())
+ str->setAttributeComment(property_comment);
+ const QString property_extraComment = value.comment();
+ if (!property_extraComment.isEmpty())
+ str->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = value.translatable();
+ if (!property_translatable)
+ str->setAttributeNotr(QLatin1String("true"));
+
+ property->setElementString(str);
+}
+
+static void saveKeySequenceProperty(DomProperty *property, const PropertySheetKeySequenceValue &value)
+{
+ DomString *str = new DomString();
+ str->setText(value.value().toString());
+
+ const QString property_comment = value.disambiguation();
+ if (!property_comment.isEmpty())
+ str->setAttributeComment(property_comment);
+ const QString property_extraComment = value.comment();
+ if (!property_extraComment.isEmpty())
+ str->setAttributeExtraComment(property_extraComment);
+ const bool property_translatable = value.translatable();
+ if (!property_translatable)
+ str->setAttributeNotr(QLatin1String("true"));
+
+ property->setElementString(str);
+}
+
+DomWidget *QDesignerResource::saveWidget(QTabWidget *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ const int current = widget->currentIndex();
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ DomWidget *ui_page = createDom(page, ui_widget);
+ if (!ui_page) {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ continue;
+ }
+ QList<DomProperty*> ui_attribute_list;
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+ // attribute `icon'
+ widget->setCurrentIndex(i);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String("currentTabIcon"))));
+ DomProperty *p = resourceBuilder()->saveResource(workingDirectory(), QVariant::fromValue(icon));
+ if (p) {
+ p->setAttributeName(strings.iconAttribute);
+ ui_attribute_list.append(p);
+ }
+ // attribute `title'
+ p = textBuilder()->saveText(sheet->property(sheet->indexOf(QLatin1String("currentTabText"))));
+ if (p) {
+ p->setAttributeName(strings.titleAttribute);
+ ui_attribute_list.append(p);
+ }
+
+ // attribute `toolTip'
+ QVariant v = sheet->property(sheet->indexOf(QLatin1String("currentTabToolTip")));
+ if (!qvariant_cast<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.toolTipAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ // attribute `whatsThis'
+ v = sheet->property(sheet->indexOf(QLatin1String("currentTabWhatsThis")));
+ if (!qvariant_cast<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.whatsThisAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ ui_page->setElementAttribute(ui_attribute_list);
+
+ ui_widget_list.append(ui_page);
+ }
+ widget->setCurrentIndex(current);
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QToolBox *widget, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(widget, ui_parentWidget, false);
+ QList<DomWidget*> ui_widget_list;
+
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
+ const int current = widget->currentIndex();
+ for (int i=0; i<container->count(); ++i) {
+ QWidget *page = container->widget(i);
+ Q_ASSERT(page);
+
+ DomWidget *ui_page = createDom(page, ui_widget);
+ if (!ui_page) {
+ if (QSimpleResource::warningsEnabled())
+ designerWarning(msgUnmanagedPage(core(), widget, i, page));
+ continue;
+ }
+
+ // attribute `label'
+ QList<DomProperty*> ui_attribute_list;
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ // attribute `icon'
+ widget->setCurrentIndex(i);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), widget);
+ PropertySheetIconValue icon = qvariant_cast<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String("currentItemIcon"))));
+ DomProperty *p = resourceBuilder()->saveResource(workingDirectory(), QVariant::fromValue(icon));
+ if (p) {
+ p->setAttributeName(strings.iconAttribute);
+ ui_attribute_list.append(p);
+ }
+ p = textBuilder()->saveText(sheet->property(sheet->indexOf(QLatin1String("currentItemText"))));
+ if (p) {
+ p->setAttributeName(strings.labelAttribute);
+ ui_attribute_list.append(p);
+ }
+
+ // attribute `toolTip'
+ QVariant v = sheet->property(sheet->indexOf(QLatin1String("currentItemToolTip")));
+ if (!qvariant_cast<PropertySheetStringValue>(v).value().isEmpty()) {
+ p = textBuilder()->saveText(v);
+ if (p) {
+ p->setAttributeName(strings.toolTipAttribute);
+ ui_attribute_list.append(p);
+ }
+ }
+
+ ui_page->setElementAttribute(ui_attribute_list);
+
+ ui_widget_list.append(ui_page);
+ }
+ widget->setCurrentIndex(current);
+ }
+
+ ui_widget->setElementWidget(ui_widget_list);
+
+ return ui_widget;
+}
+
+DomWidget *QDesignerResource::saveWidget(QWizardPage *wizardPage, DomWidget *ui_parentWidget)
+{
+ DomWidget *ui_widget = QAbstractFormBuilder::createDom(wizardPage, ui_parentWidget, true);
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), wizardPage);
+ // Save the page id (string) attribute, append to existing attributes
+ const QString pageIdPropertyName = QLatin1String(QWizardPagePropertySheet::pageIdProperty);
+ const int pageIdIndex = sheet->indexOf(pageIdPropertyName);
+ if (pageIdIndex != -1 && sheet->isChanged(pageIdIndex)) {
+ DomProperty *property = variantToDomProperty(this, wizardPage->metaObject(), pageIdPropertyName, sheet->property(pageIdIndex));
+ Q_ASSERT(property);
+ property->elementString()->setAttributeNotr(QLatin1String("true"));
+ DomPropertyList attributes = ui_widget->elementAttribute();
+ attributes.push_back(property);
+ ui_widget->setElementAttribute(attributes);
+ }
+ return ui_widget;
+}
+
+// Do not save the 'currentTabName' properties of containers
+static inline bool checkContainerProperty(const QWidget *w, const QString &propertyName)
+{
+ if (qobject_cast<const QToolBox *>(w))
+ return QToolBoxWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QTabWidget *>(w))
+ return QTabWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QStackedWidget *>(w))
+ return QStackedWidgetPropertySheet::checkProperty(propertyName);
+ if (qobject_cast<const QMdiArea *>(w) || qobject_cast<const QWorkspace *>(w))
+ return QMdiAreaPropertySheet::checkProperty(propertyName);
+ return true;
+}
+
+bool QDesignerResource::checkProperty(QObject *obj, const QString &prop) const
+{
+ const QDesignerMetaObjectInterface *meta = core()->introspection()->metaObject(obj);
+
+ const int pindex = meta->indexOfProperty(prop);
+ if (pindex != -1 && !(meta->property(pindex)->attributes(obj) & QDesignerMetaPropertyInterface::StoredAttribute))
+ return false;
+
+ if (prop == QLatin1String("objectName") || prop == QLatin1String("spacerName")) // ### don't store the property objectName
+ return false;
+
+ QWidget *check_widget = 0;
+ if (obj->isWidgetType())
+ check_widget = static_cast<QWidget*>(obj);
+
+ if (check_widget && prop == QLatin1String("geometry")) {
+ if (check_widget == m_formWindow->mainContainer())
+ return true; // Save although maincontainer is technically laid-out by embedding container
+ if (m_selected && m_selected == check_widget)
+ return true;
+
+ return !LayoutInfo::isWidgetLaidout(core(), check_widget);
+ }
+
+ if (check_widget && !checkContainerProperty(check_widget, prop))
+ return false;
+
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), obj)) {
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), obj);
+ const int pindex = sheet->indexOf(prop);
+ if (sheet->isAttribute(pindex))
+ return false;
+
+ if (!dynamicSheet || !dynamicSheet->isDynamicProperty(pindex))
+ return sheet->isChanged(pindex);
+ if (!sheet->isVisible(pindex))
+ return false;
+ return true;
+ }
+
+ return false;
+}
+
+bool QDesignerResource::addItem(DomLayoutItem *ui_item, QLayoutItem *item, QLayout *layout)
+{
+ if (item->widget() == 0) {
+ return false;
+ }
+
+ QGridLayout *grid = qobject_cast<QGridLayout*>(layout);
+ QBoxLayout *box = qobject_cast<QBoxLayout*>(layout);
+
+ if (grid != 0) {
+ const int rowSpan = ui_item->hasAttributeRowSpan() ? ui_item->attributeRowSpan() : 1;
+ const int colSpan = ui_item->hasAttributeColSpan() ? ui_item->attributeColSpan() : 1;
+ grid->addWidget(item->widget(), ui_item->attributeRow(), ui_item->attributeColumn(), rowSpan, colSpan, item->alignment());
+ return true;
+ } else if (box != 0) {
+ box->addItem(item);
+ return true;
+ }
+
+ return QAbstractFormBuilder::addItem(ui_item, item, layout);
+}
+
+bool QDesignerResource::addItem(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ core()->metaDataBase()->add(widget); // ensure the widget is in the meta database
+
+ if (! QAbstractFormBuilder::addItem(ui_widget, widget, parentWidget) || qobject_cast<QMainWindow*> (parentWidget)) {
+ if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), parentWidget))
+ container->addWidget(widget);
+ }
+
+ if (QTabWidget *tabWidget = qobject_cast<QTabWidget*>(parentWidget)) {
+ const int tabIndex = tabWidget->count() - 1;
+ const int current = tabWidget->currentIndex();
+
+ tabWidget->setCurrentIndex(tabIndex);
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), parentWidget);
+ if (DomProperty *picon = attributes.value(strings.iconAttribute)) {
+ QVariant v = resourceBuilder()->loadResource(workingDirectory(), picon);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabIcon")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.titleAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabText")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.toolTipAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabToolTip")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.whatsThisAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentTabWhatsThis")), v);
+ }
+ tabWidget->setCurrentIndex(current);
+ } else if (QToolBox *toolBox = qobject_cast<QToolBox*>(parentWidget)) {
+ const int itemIndex = toolBox->count() - 1;
+ const int current = toolBox->currentIndex();
+
+ toolBox->setCurrentIndex(itemIndex);
+
+ const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
+
+ const DomPropertyHash attributes = propertyMap(ui_widget->elementAttribute());
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), parentWidget);
+ if (DomProperty *picon = attributes.value(strings.iconAttribute)) {
+ QVariant v = resourceBuilder()->loadResource(workingDirectory(), picon);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemIcon")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.labelAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemText")), v);
+ }
+ if (DomProperty *ptext = attributes.value(strings.toolTipAttribute)) {
+ QVariant v = textBuilder()->loadText(ptext);
+ sheet->setProperty(sheet->indexOf(QLatin1String("currentItemToolTip")), v);
+ }
+ toolBox->setCurrentIndex(current);
+ }
+
+ return true;
+}
+
+bool QDesignerResource::copy(QIODevice *dev, const FormBuilderClipboard &selection)
+{
+ m_copyWidget = true;
+
+ DomUI *ui = copy(selection);
+
+ m_laidout.clear();
+ m_copyWidget = false;
+
+ if (!ui)
+ return false;
+
+ QXmlStreamWriter writer(dev);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(1);
+ writer.writeStartDocument();
+ ui->write(writer);
+ writer.writeEndDocument();
+ delete ui;
+ return true;
+}
+
+DomUI *QDesignerResource::copy(const FormBuilderClipboard &selection)
+{
+ if (selection.empty())
+ return 0;
+
+ m_copyWidget = true;
+
+ DomWidget *ui_widget = new DomWidget();
+ ui_widget->setAttributeName(QLatin1String(clipboardObjectName));
+ bool hasItems = false;
+ // Widgets
+ if (!selection.m_widgets.empty()) {
+ QList<DomWidget*> ui_widget_list;
+ const int size = selection.m_widgets.size();
+ for (int i=0; i< size; ++i) {
+ QWidget *w = selection.m_widgets.at(i);
+ m_selected = w;
+ DomWidget *ui_child = createDom(w, ui_widget);
+ m_selected = 0;
+ if (ui_child)
+ ui_widget_list.append(ui_child);
+ }
+ if (!ui_widget_list.empty()) {
+ ui_widget->setElementWidget(ui_widget_list);
+ hasItems = true;
+ }
+ }
+ // actions
+ if (!selection.m_actions.empty()) {
+ QList<DomAction*> domActions;
+ foreach(QAction* action, selection.m_actions)
+ if (DomAction *domAction = createDom(action))
+ domActions += domAction;
+ if (!domActions.empty()) {
+ ui_widget-> setElementAction(domActions);
+ hasItems = true;
+ }
+ }
+
+ m_laidout.clear();
+ m_copyWidget = false;
+
+ if (!hasItems) {
+ delete ui_widget;
+ return 0;
+ }
+ // UI
+ DomUI *ui = new DomUI();
+ ui->setAttributeVersion(QLatin1String(currentUiVersion));
+ ui->setElementWidget(ui_widget);
+ ui->setElementResources(saveResources(m_resourceBuilder->usedQrcFiles()));
+ if (DomCustomWidgets *cws = saveCustomWidgets())
+ ui->setElementCustomWidgets(cws);
+ return ui;
+}
+
+FormBuilderClipboard QDesignerResource::paste(DomUI *ui, QWidget *widgetParent, QObject *actionParent)
+{
+ QDesignerWidgetItemInstaller wii; // Make sure we use QDesignerWidgetItem.
+ const int saved = m_isMainWidget;
+ m_isMainWidget = false;
+
+ FormBuilderClipboard rc;
+
+ // Widgets
+ const DomWidget *topLevel = ui->elementWidget();
+ initialize(ui);
+ const QList<DomWidget*> domWidgets = topLevel->elementWidget();
+ if (!domWidgets.empty()) {
+ const QPoint offset = m_formWindow->grid();
+ foreach (DomWidget* domWidget, domWidgets) {
+ if (QWidget *w = create(domWidget, widgetParent)) {
+ w->move(w->pos() + offset);
+ // ### change the init properties of w
+ rc.m_widgets.append(w);
+ }
+ }
+ }
+ const QList<DomAction*> domActions = topLevel->elementAction();
+ if (!domActions.empty())
+ foreach (DomAction *domAction, domActions)
+ if (QAction *a = create(domAction, actionParent))
+ rc.m_actions .append(a);
+
+ m_isMainWidget = saved;
+
+ if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core()))
+ extra->loadUiExtraInfo(ui);
+
+ createResources(ui->elementResources());
+
+ return rc;
+}
+
+FormBuilderClipboard QDesignerResource::paste(QIODevice *dev, QWidget *widgetParent, QObject *actionParent)
+{
+ DomUI ui;
+ QXmlStreamReader reader(dev);
+ bool uiInitialized = false;
+
+ const QString uiElement = QLatin1String("ui");
+ while (!reader.atEnd()) {
+ if (reader.readNext() == QXmlStreamReader::StartElement) {
+ if (reader.name().compare(uiElement, Qt::CaseInsensitive)) {
+ ui.read(reader);
+ uiInitialized = true;
+ } else {
+ //: Parsing clipboard contents
+ reader.raiseError(QCoreApplication::translate("QDesignerResource", "Unexpected element <%1>").arg(reader.name().toString()));
+ }
+ }
+ }
+ if (reader.hasError()) {
+ //: Parsing clipboard contents
+ designerWarning(QCoreApplication::translate("QDesignerResource", "Error while pasting clipboard contents at line %1, column %2: %3")
+ .arg(reader.lineNumber()).arg(reader.columnNumber())
+ .arg(reader.errorString()));
+ uiInitialized = false;
+ } else if (uiInitialized == false) {
+ //: Parsing clipboard contents
+ designerWarning(QCoreApplication::translate("QDesignerResource", "Error while pasting clipboard contents: The root element <ui> is missing."));
+ }
+
+ if (!uiInitialized)
+ return FormBuilderClipboard();
+
+ FormBuilderClipboard clipBoard = paste(&ui, widgetParent, actionParent);
+
+ return clipBoard;
+}
+
+void QDesignerResource::layoutInfo(DomLayout *layout, QObject *parent, int *margin, int *spacing)
+{
+ QAbstractFormBuilder::layoutInfo(layout, parent, margin, spacing);
+}
+
+DomCustomWidgets *QDesignerResource::saveCustomWidgets()
+{
+ if (m_usedCustomWidgets.isEmpty())
+ return 0;
+
+ // We would like the list to be in order of the widget database indexes
+ // to ensure that base classes come first (nice optics)
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ QDesignerWidgetDataBaseInterface *db = core->widgetDataBase();
+ const bool isInternalWidgetDataBase = qobject_cast<const WidgetDataBase *>(db);
+ typedef QMap<int,DomCustomWidget*> OrderedDBIndexDomCustomWidgetMap;
+ OrderedDBIndexDomCustomWidgetMap orderedMap;
+
+ const QString global = QLatin1String("global");
+ foreach (QDesignerWidgetDataBaseItemInterface *item, m_usedCustomWidgets.keys()) {
+ const QString name = item->name();
+ DomCustomWidget *custom_widget = new DomCustomWidget;
+
+ custom_widget->setElementClass(name);
+ if (item->isContainer())
+ custom_widget->setElementContainer(item->isContainer());
+
+ if (!item->includeFile().isEmpty()) {
+ DomHeader *header = new DomHeader;
+ const IncludeSpecification spec = includeSpecification(item->includeFile());
+ header->setText(spec.first);
+ if (spec.second == IncludeGlobal) {
+ header->setAttributeLocation(global);
+ }
+ custom_widget->setElementHeader(header);
+ custom_widget->setElementExtends(item->extends());
+ }
+
+ if (isInternalWidgetDataBase) {
+ WidgetDataBaseItem *internalItem = static_cast<WidgetDataBaseItem *>(item);
+ const QStringList fakeSlots = internalItem->fakeSlots();
+ const QStringList fakeSignals = internalItem->fakeSignals();
+ if (!fakeSlots.empty() || !fakeSignals.empty()) {
+ DomSlots *domSlots = new DomSlots();
+ domSlots->setElementSlot(fakeSlots);
+ domSlots->setElementSignal(fakeSignals);
+ custom_widget->setElementSlots(domSlots);
+ }
+ const QString addPageMethod = internalItem->addPageMethod();
+ if (!addPageMethod.isEmpty())
+ custom_widget->setElementAddPageMethod(addPageMethod);
+ }
+
+ // Look up static per-class scripts of designer
+ if (DomScript *domScript = createScript(customWidgetScript(core, name), ScriptCustomWidgetPlugin))
+ custom_widget->setElementScript(domScript);
+
+ orderedMap.insert(db->indexOfClassName(name), custom_widget);
+ }
+
+ DomCustomWidgets *customWidgets = new DomCustomWidgets;
+ customWidgets->setElementCustomWidget(orderedMap.values());
+ return customWidgets;
+}
+
+bool QDesignerResource::canCompressMargins(QObject *object) const
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ if (qobject_cast<QLayout *>(object)) {
+ const int l = sheet->property(sheet->indexOf(QLatin1String("leftMargin"))).toInt();
+ const int t = sheet->property(sheet->indexOf(QLatin1String("topMargin"))).toInt();
+ const int r = sheet->property(sheet->indexOf(QLatin1String("rightMargin"))).toInt();
+ const int b = sheet->property(sheet->indexOf(QLatin1String("bottomMargin"))).toInt();
+ if (l == t && l == r && l == b)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool QDesignerResource::canCompressSpacings(QObject *object) const
+{
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ if (qobject_cast<QGridLayout *>(object)) {
+ const int h = sheet->property(sheet->indexOf(QLatin1String("horizontalSpacing"))).toInt();
+ const int v = sheet->property(sheet->indexOf(QLatin1String("verticalSpacing"))).toInt();
+ if (h == v)
+ return true;
+ }
+ }
+ return false;
+}
+
+QList<DomProperty*> QDesignerResource::computeProperties(QObject *object)
+{
+ QList<DomProperty*> properties;
+ if (QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), object)) {
+ QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(core()->extensionManager(), object);
+ const int count = sheet->count();
+ QList<DomProperty *> marginProperties;
+ QList<DomProperty *> spacingProperties;
+ const bool compressMargins = canCompressMargins(object);
+ const bool compressSpacings = canCompressSpacings(object);
+ for (int index = 0; index < count; ++index) {
+ if (!sheet->isChanged(index) && (!dynamicSheet || !dynamicSheet->isDynamicProperty(index)))
+ continue;
+
+ const QString propertyName = sheet->propertyName(index);
+ // Suppress windowModality in legacy forms that have it set on child widgets
+ if (propertyName == QLatin1String("windowModality") && !sheet->isVisible(index))
+ continue;
+
+ const QVariant value = sheet->property(index);
+ if (DomProperty *p = createProperty(object, propertyName, value)) {
+ if (compressMargins && (propertyName == QLatin1String("leftMargin")
+ || propertyName == QLatin1String("rightMargin")
+ || propertyName == QLatin1String("topMargin")
+ || propertyName == QLatin1String("bottomMargin"))) {
+ marginProperties.append(p);
+ } else if (compressSpacings && (propertyName == QLatin1String("horizontalSpacing")
+ || propertyName == QLatin1String("verticalSpacing"))) {
+ spacingProperties.append(p);
+ } else {
+ properties.append(p);
+ }
+ }
+ }
+ if (compressMargins) {
+ if (marginProperties.count() == 4) { // if we have 3 it means one is reset so we can't compress
+ DomProperty *marginProperty = marginProperties.at(0);
+ marginProperty->setAttributeName(QLatin1String("margin"));
+ properties.append(marginProperty);
+ delete marginProperties.at(1);
+ delete marginProperties.at(2);
+ delete marginProperties.at(3);
+ } else {
+ properties += marginProperties;
+ }
+ }
+ if (compressSpacings) {
+ if (spacingProperties.count() == 2) {
+ DomProperty *spacingProperty = spacingProperties.at(0);
+ spacingProperty->setAttributeName(QLatin1String("spacing"));
+ properties.append(spacingProperty);
+ delete spacingProperties.at(1);
+ } else {
+ properties += spacingProperties;
+ }
+ }
+ }
+ return properties;
+}
+
+DomProperty *QDesignerResource::applyProperStdSetAttribute(QObject *object, const QString &propertyName, DomProperty *property)
+{
+ if (!property)
+ return 0;
+
+ QExtensionManager *mgr = core()->extensionManager();
+ if (const QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(mgr, object)) {
+ const QDesignerDynamicPropertySheetExtension *dynamicSheet = qt_extension<QDesignerDynamicPropertySheetExtension*>(mgr, object);
+ const QDesignerPropertySheet *designerSheet = qobject_cast<QDesignerPropertySheet*>(core()->extensionManager()->extension(object, Q_TYPEID(QDesignerPropertySheetExtension)));
+ const int index = sheet->indexOf(propertyName);
+ if ((dynamicSheet && dynamicSheet->isDynamicProperty(index)) || (designerSheet && designerSheet->isDefaultDynamicProperty(index)))
+ property->setAttributeStdset(0);
+ }
+ return property;
+}
+
+// Optimistic check for a standard setter function
+static inline bool hasSetter(QDesignerFormEditorInterface *core, QObject *object, const QString &propertyName)
+{
+ const QDesignerMetaObjectInterface *meta = core->introspection()->metaObject(object);
+ const int pindex = meta->indexOfProperty(propertyName);
+ if (pindex == -1)
+ return true;
+ return meta->property(pindex)->hasSetter();
+}
+
+DomProperty *QDesignerResource::createProperty(QObject *object, const QString &propertyName, const QVariant &value)
+{
+ if (!checkProperty(object, propertyName)) {
+ return 0;
+ }
+
+ if (value.canConvert<PropertySheetFlagValue>()) {
+ const PropertySheetFlagValue f = qvariant_cast<PropertySheetFlagValue>(value);
+ const QString flagString = f.metaFlags.toString(f.value, DesignerMetaFlags::FullyQualified);
+ if (flagString.isEmpty())
+ return 0;
+
+ DomProperty *p = new DomProperty;
+ // check if we have a standard cpp set function
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+ p->setAttributeName(propertyName);
+ p->setElementSet(flagString);
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (value.canConvert<PropertySheetEnumValue>()) {
+ const PropertySheetEnumValue e = qvariant_cast<PropertySheetEnumValue>(value);
+ bool ok;
+ const QString id = e.metaEnum.toString(e.value, DesignerMetaEnum::FullyQualified, &ok);
+ if (!ok)
+ designerWarning(e.metaEnum.messageToStringFailed(e.value));
+ if (id.isEmpty())
+ return 0;
+
+ DomProperty *p = new DomProperty;
+ // check if we have a standard cpp set function
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+ p->setAttributeName(propertyName);
+ p->setElementEnum(id);
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (value.canConvert<PropertySheetStringValue>()) {
+ const PropertySheetStringValue strVal = qvariant_cast<PropertySheetStringValue>(value);
+ DomProperty *p = new DomProperty;
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+
+ p->setAttributeName(propertyName);
+
+ saveStringProperty(p, strVal);
+
+ return applyProperStdSetAttribute(object, propertyName, p);
+ } else if (value.canConvert<PropertySheetKeySequenceValue>()) {
+ const PropertySheetKeySequenceValue keyVal = qvariant_cast<PropertySheetKeySequenceValue>(value);
+ DomProperty *p = new DomProperty;
+ if (!hasSetter(core(), object, propertyName))
+ p->setAttributeStdset(0);
+
+ p->setAttributeName(propertyName);
+
+ saveKeySequenceProperty(p, keyVal);
+
+ return applyProperStdSetAttribute(object, propertyName, p);
+ }
+
+ return applyProperStdSetAttribute(object, propertyName, QAbstractFormBuilder::createProperty(object, propertyName, value));
+}
+
+QStringList QDesignerResource::mergeWithLoadedPaths(const QStringList &paths) const
+{
+ QStringList newPaths = paths;
+#ifdef OLD_RESOURCE_FORMAT
+ QStringList loadedPaths = m_resourceBuilder->loadedQrcFiles();
+ QStringListIterator it(loadedPaths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ if (!newPaths.contains(path))
+ newPaths << path;
+ }
+#endif
+ return newPaths;
+}
+
+
+void QDesignerResource::createResources(DomResources *resources)
+{
+ QStringList paths;
+ if (resources != 0) {
+ const QList<DomResource*> dom_include = resources->elementInclude();
+ foreach (DomResource *res, dom_include) {
+ QString path = QDir::cleanPath(m_formWindow->absoluteDir().absoluteFilePath(res->attributeLocation()));
+ while (!QFile::exists(path)) {
+ QWidget *dialogParent = m_formWindow->core()->topLevel();
+ const QString promptTitle = QApplication::translate("qdesigner_internal::QDesignerResource", "Loading qrc file", 0, QApplication::UnicodeUTF8);
+ const QString prompt = QApplication::translate("qdesigner_internal::QDesignerResource", "The specified qrc file <p><b>%1</b></p><p>could not be found. Do you want to update the file location?</p>", 0, QApplication::UnicodeUTF8).arg(path);
+
+ const QMessageBox::StandardButton answer = core()->dialogGui()->message(dialogParent, QDesignerDialogGuiInterface::ResourceLoadFailureMessage,
+ QMessageBox::Warning, promptTitle, prompt, QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
+ if (answer == QMessageBox::Yes) {
+ const QFileInfo fi(path);
+ const QString fileDialogTitle = QApplication::translate("qdesigner_internal::QDesignerResource", "New location for %1", 0, QApplication::UnicodeUTF8).arg(fi.fileName());
+ const QString fileDialogPattern = QApplication::translate("qdesigner_internal::QDesignerResource", "Resource files (*.qrc)", 0, QApplication::UnicodeUTF8);
+ path = core()->dialogGui()->getOpenFileName(dialogParent, fileDialogTitle, fi.absolutePath(), fileDialogPattern);
+ if (path.isEmpty())
+ break;
+ m_formWindow->setProperty("_q_resourcepathchanged", QVariant(true));
+ } else {
+ break;
+ }
+ }
+ if (!path.isEmpty()) {
+ paths << path;
+ m_formWindow->addResourceFile(path);
+ }
+ }
+ }
+
+#ifdef OLD_RESOURCE_FORMAT
+ paths = mergeWithLoadedPaths(paths);
+#endif
+
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ if (resourceSet) {
+ QStringList oldPaths = resourceSet->activeQrcPaths();
+ QStringList newPaths = oldPaths;
+ QStringListIterator it(paths);
+ while (it.hasNext()) {
+ const QString path = it.next();
+ if (!newPaths.contains(path))
+ newPaths << path;
+ }
+ resourceSet->activateQrcPaths(newPaths);
+ } else {
+ resourceSet = m_formWindow->core()->resourceModel()->addResourceSet(paths);
+ m_formWindow->setResourceSet(resourceSet);
+ QObject::connect(m_formWindow->core()->resourceModel(), SIGNAL(resourceSetActivated(QtResourceSet*,bool)),
+ m_formWindow, SLOT(resourceSetActivated(QtResourceSet*,bool)));
+ }
+}
+
+DomResources *QDesignerResource::saveResources()
+{
+ QStringList paths;
+ if (m_formWindow->saveResourcesBehaviour() == FormWindowBase::SaveAll) {
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ QList<DomResource*> dom_include;
+ if (resourceSet)
+ paths = resourceSet->activeQrcPaths();
+ } else if (m_formWindow->saveResourcesBehaviour() == FormWindowBase::SaveOnlyUsedQrcFiles) {
+ paths = m_resourceBuilder->usedQrcFiles();
+ }
+
+ return saveResources(paths);
+}
+
+DomResources *QDesignerResource::saveResources(const QStringList &qrcPaths)
+{
+ QtResourceSet *resourceSet = m_formWindow->resourceSet();
+ QList<DomResource*> dom_include;
+ if (resourceSet) {
+ const QStringList activePaths = resourceSet->activeQrcPaths();
+ foreach (const QString &path, activePaths) {
+ if (qrcPaths.contains(path)) {
+ DomResource *dom_res = new DomResource;
+ QString conv_path = path;
+ if (m_resourceBuilder->isSaveRelative())
+ conv_path = m_formWindow->absoluteDir().relativeFilePath(path);
+ dom_res->setAttributeLocation(conv_path.replace(QDir::separator(), QLatin1Char('/')));
+ dom_include.append(dom_res);
+ }
+ }
+ }
+
+ DomResources *dom_resources = new DomResources;
+ dom_resources->setElementInclude(dom_include);
+
+ return dom_resources;
+}
+
+DomAction *QDesignerResource::createDom(QAction *action)
+{
+ if (!core()->metaDataBase()->item(action) || action->menu())
+ return 0;
+
+ return QAbstractFormBuilder::createDom(action);
+}
+
+DomActionGroup *QDesignerResource::createDom(QActionGroup *actionGroup)
+{
+ if (core()->metaDataBase()->item(actionGroup) != 0) {
+ return QAbstractFormBuilder::createDom(actionGroup);
+ }
+
+ return 0;
+}
+
+QAction *QDesignerResource::create(DomAction *ui_action, QObject *parent)
+{
+ if (QAction *action = QAbstractFormBuilder::create(ui_action, parent)) {
+ core()->metaDataBase()->add(action);
+ return action;
+ }
+
+ return 0;
+}
+
+QActionGroup *QDesignerResource::create(DomActionGroup *ui_action_group, QObject *parent)
+{
+ if (QActionGroup *actionGroup = QAbstractFormBuilder::create(ui_action_group, parent)) {
+ core()->metaDataBase()->add(actionGroup);
+ return actionGroup;
+ }
+
+ return 0;
+}
+
+DomActionRef *QDesignerResource::createActionRefDom(QAction *action)
+{
+ if (!core()->metaDataBase()->item(action)
+ || (!action->isSeparator() && !action->menu() && action->objectName().isEmpty()))
+ return 0;
+
+ return QAbstractFormBuilder::createActionRefDom(action);
+}
+
+void QDesignerResource::addMenuAction(QAction *action)
+{
+ core()->metaDataBase()->add(action);
+}
+
+QAction *QDesignerResource::createAction(QObject *parent, const QString &name)
+{
+ if (QAction *action = QAbstractFormBuilder::createAction(parent, name)) {
+ core()->metaDataBase()->add(action);
+ return action;
+ }
+
+ return 0;
+}
+
+QActionGroup *QDesignerResource::createActionGroup(QObject *parent, const QString &name)
+{
+ if (QActionGroup *actionGroup = QAbstractFormBuilder::createActionGroup(parent, name)) {
+ core()->metaDataBase()->add(actionGroup);
+ return actionGroup;
+ }
+
+ return 0;
+}
+
+/* Apply the attributes to a widget via property sheet where appropriate,
+ * that is, the sheet handles attributive fake properties */
+void QDesignerResource::applyAttributesToPropertySheet(const DomWidget *ui_widget, QWidget *widget)
+{
+ const DomPropertyList attributes = ui_widget->elementAttribute();
+ if (attributes.empty())
+ return;
+ QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(m_formWindow->core()->extensionManager(), widget);
+ const DomPropertyList::const_iterator acend = attributes.constEnd();
+ for (DomPropertyList::const_iterator it = attributes.constBegin(); it != acend; ++it) {
+ const QString name = (*it)->attributeName();
+ const int index = sheet->indexOf(name);
+ if (index == -1) {
+ const QString msg = QString::fromUtf8("Unable to apply attributive property '%1' to '%2'. It does not exist.").arg(name, widget->objectName());
+ designerWarning(msg);
+ } else {
+ sheet->setProperty(index, domPropertyToVariant(this, widget->metaObject(), *it));
+ sheet->setChanged(index, true);
+ }
+ }
+}
+
+void QDesignerResource::loadExtraInfo(DomWidget *ui_widget, QWidget *widget, QWidget *parentWidget)
+{
+ QAbstractFormBuilder::loadExtraInfo(ui_widget, widget, parentWidget);
+ // Apply the page id attribute of a QWizardPage (which is an attributive fake property)
+ if (qobject_cast<const QWizardPage*>(widget))
+ applyAttributesToPropertySheet(ui_widget, widget);
+}
+
+// Add user defined scripts (dialog box) belonging to QWidget to DomWidget.
+void QDesignerResource::addUserDefinedScripts(QWidget *w, DomWidget *ui_widget)
+{
+ QDesignerFormEditorInterface *core = m_formWindow->core();
+ DomScripts domScripts = ui_widget->elementScript();
+ // Look up user-defined scripts of designer
+ if (const qdesigner_internal::MetaDataBase *metaDataBase = qobject_cast<const qdesigner_internal::MetaDataBase *>(core->metaDataBase())) {
+ if (const qdesigner_internal::MetaDataBaseItem *metaItem = metaDataBase->metaDataBaseItem(w)) {
+ addScript(metaItem->script(), ScriptDesigner, domScripts);
+ }
+ }
+ if (!domScripts.empty())
+ ui_widget->setElementScript(domScripts);
+}
+}
+
+QT_END_NAMESPACE