diff --git a/src/libs/qmljs/parser/qmljslexer.cpp b/src/libs/qmljs/parser/qmljslexer.cpp index cf3ed34c1e06a9b13c6f2c4c91c4fc8a5f260362..efb4133a56cd5bbb740a35c8eff469b72efe1e47 100644 --- a/src/libs/qmljs/parser/qmljslexer.cpp +++ b/src/libs/qmljs/parser/qmljslexer.cpp @@ -56,9 +56,11 @@ #include <stdio.h> #include <string.h> -QT_QML_BEGIN_NAMESPACE - +QT_BEGIN_NAMESPACE extern double qstrtod(const char *s00, char const **se, bool *ok); +QT_END_NAMESPACE + +QT_QML_BEGIN_NAMESPACE #define shiftWindowsLineBreak() \ do { \ diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp index 647def0006b2317ae47b3af5b65c6a8c8175ce8f..2618e153cce2d821504c08aea1c542ec85509186 100644 --- a/src/plugins/coreplugin/fancytabwidget.cpp +++ b/src/plugins/coreplugin/fancytabwidget.cpp @@ -96,7 +96,8 @@ void FancyTabBar::paintEvent(QPaintEvent *event) paintTab(&p, i); // paint active tab last, since it overlaps the neighbors - paintTab(&p, currentIndex()); + if (currentIndex() != -1) + paintTab(&p, currentIndex()); } // Handle hover events for mouse fade ins @@ -205,6 +206,7 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const bool selected = (tabIndex == m_currentIndex); bool hover = (tabIndex == m_hoverIndex); + bool enabled = isTabEnabled(tabIndex); #ifdef Q_WS_MAC hover = false; // Do not hover on Mac @@ -233,7 +235,7 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const painter->drawLine(rect.bottomLeft(), rect.bottomRight()); } else { painter->fillRect(rect, background); - if (hover) + if (hover && enabled) painter->fillRect(rect, hoverColor); painter->setPen(QPen(light, 0)); painter->drawLine(rect.topLeft(), rect.topRight()); @@ -250,25 +252,55 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const painter->setFont(boldFont); painter->setPen(selected ? Utils::StyleHelper::panelTextColor() : QColor(30, 30, 30, 80)); int textFlags = Qt::AlignCenter | Qt::AlignBottom | Qt::ElideRight | Qt::TextWordWrap; - painter->drawText(tabTextRect, textFlags, tabText); - painter->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor()); + if (enabled) { + painter->drawText(tabTextRect, textFlags, tabText); + painter->setPen(selected ? QColor(60, 60, 60) : Utils::StyleHelper::panelTextColor()); + } else { + painter->setPen(selected ? Utils::StyleHelper::panelTextColor() : QColor(255, 255, 255, 120)); + } + int textHeight = painter->fontMetrics().boundingRect(QRect(0, 0, width(), height()), Qt::TextWordWrap, tabText).height(); tabIconRect.adjust(0, 4, 0, -textHeight); int iconSize = qMin(tabIconRect.width(), tabIconRect.height()); if (iconSize > 4) style()->drawItemPixmap(painter, tabIconRect, Qt::AlignCenter | Qt::AlignVCenter, - tabIcon(tabIndex).pixmap(tabIconRect.size())); + tabIcon(tabIndex).pixmap(tabIconRect.size(), enabled ? QIcon::Normal : QIcon::Disabled)); painter->translate(0, -1); painter->drawText(tabTextRect, textFlags, tabText); painter->restore(); } void FancyTabBar::setCurrentIndex(int index) { - m_currentIndex = index; - update(); - emit currentChanged(index); + if (isTabEnabled(index)) { + m_currentIndex = index; + update(); + emit currentChanged(index); + } } +void FancyTabBar::setTabEnabled(int index, bool enable) +{ + Q_ASSERT(index < m_tabs.size()); + Q_ASSERT(index >= 0); + + if (index < m_tabs.size() && index >= 0) { + m_tabs[index].enabled = enable; + update(tabRect(index)); + } +} + +bool FancyTabBar::isTabEnabled(int index) const +{ + Q_ASSERT(index < m_tabs.size()); + Q_ASSERT(index >= 0); + + if (index < m_tabs.size() && index >= 0) + return m_tabs[index].enabled; + + return false; +} + + ////// // FancyColorButton ////// @@ -410,7 +442,8 @@ QStatusBar *FancyTabWidget::statusBar() const void FancyTabWidget::setCurrentIndex(int index) { - m_tabBar->setCurrentIndex(index); + if (m_tabBar->isTabEnabled(index)) + m_tabBar->setCurrentIndex(index); } void FancyTabWidget::showWidget(int index) @@ -424,3 +457,13 @@ void FancyTabWidget::setTabToolTip(int index, const QString &toolTip) { m_tabBar->setTabToolTip(index, toolTip); } + +void FancyTabWidget::setTabEnabled(int index, bool enable) +{ + m_tabBar->setTabEnabled(index, enable); +} + +bool FancyTabWidget::isTabEnabled(int index) const +{ + return m_tabBar->isTabEnabled(index); +} diff --git a/src/plugins/coreplugin/fancytabwidget.h b/src/plugins/coreplugin/fancytabwidget.h index a9f8485d63f427842d4213bf7a5eaea8f8360e65..22163ce3a58be4d437b759ed08e787a2d1c207d8 100644 --- a/src/plugins/coreplugin/fancytabwidget.h +++ b/src/plugins/coreplugin/fancytabwidget.h @@ -48,6 +48,7 @@ namespace Internal { QIcon icon; QString text; QString toolTip; + bool enabled; }; class FancyTabBar : public QWidget @@ -70,8 +71,12 @@ public: QSize sizeHint() const; QSize minimumSizeHint() const; + void setTabEnabled(int index, bool enable); + bool isTabEnabled(int index) const; + void insertTab(int index, const QIcon &icon, const QString &label) { FancyTab tab; + tab.enabled = true; tab.icon = icon; tab.text = label; m_tabs.insert(index, tab); @@ -130,6 +135,9 @@ public: int currentIndex() const; QStatusBar *statusBar() const; + void setTabEnabled(int index, bool enable); + bool isTabEnabled(int index) const; + signals: void currentAboutToShow(int index); void currentChanged(int index); diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index f3d9e7e462fd59f8c63dd29068788042d177fd7e..5a576f4b56e314964a06e08fadd0521b2960cc0a 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -610,7 +610,7 @@ CPPEditor::CPPEditor(QWidget *parent) , m_firstRenameChange(false) { m_initialized = false; - qRegisterMetaType<SemanticInfo>("SemanticInfo"); + qRegisterMetaType<CppEditor::Internal::SemanticInfo>("CppEditor::Internal::SemanticInfo"); m_semanticHighlighter = new SemanticHighlighter(this); m_semanticHighlighter->start(); @@ -700,8 +700,8 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable) connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateUses())); connect(this, SIGNAL(textChanged()), this, SLOT(updateUses())); - connect(m_semanticHighlighter, SIGNAL(changed(SemanticInfo)), - this, SLOT(updateSemanticInfo(SemanticInfo))); + connect(m_semanticHighlighter, SIGNAL(changed(CppEditor::Internal::SemanticInfo)), + this, SLOT(updateSemanticInfo(CppEditor::Internal::SemanticInfo))); QToolBar *toolBar = static_cast<QToolBar*>(editable->toolBar()); QList<QAction*> actions = toolBar->actions(); diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 243c4843d41eaab86d14a4272739e7981c459a87..6c70e1da62c5fca56439e7a3a151a171a5817877 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -141,7 +141,7 @@ public: void rehighlight(const Source &source); Q_SIGNALS: - void changed(const SemanticInfo &semanticInfo); + void changed(const CppEditor::Internal::SemanticInfo &semanticInfo); protected: virtual void run(); @@ -242,7 +242,7 @@ private Q_SLOTS: void onContentsChanged(int position, int charsRemoved, int charsAdded); void semanticRehighlight(); - void updateSemanticInfo(const SemanticInfo &semanticInfo); + void updateSemanticInfo(const CppEditor::Internal::SemanticInfo &semanticInfo); void performQuickFix(int index); diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h index c2e387c696f5877fe80d7365196f695e31d2875a..c240363569be48770c7f9702a398fdd4a057c4b8 100644 --- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h +++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.h @@ -32,7 +32,9 @@ #include "formeditoritem.h" +QT_BEGIN_NAMESPACE class QGraphicsItem; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h index 9594f4a17a5b3811058a555b40a8fb7fa6ce32e3..959be9e31578f071c464dcc82c50ee62d8108830 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.h @@ -35,7 +35,9 @@ #include <qmlitemnode.h> #include "snappinglinecreator.h" +QT_BEGIN_NAMESPACE class QTimeLine; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.h b/src/plugins/qmldesigner/components/formeditor/formeditorscene.h index ec1eebd22ec790d06e49ab5545416504fffe2ffb..1b01fb5bf76718193b1e8b92596aff2e1b3631a8 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.h @@ -37,8 +37,9 @@ #include <qmlitemnode.h> #include "abstractformeditortool.h" - +QT_BEGIN_NAMESPACE class QGraphicsSceneMouseEvent; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index 7c85013b2ce7035f0fd224bbe9ae43ceb3a15a37..02762efb8f9e97b5ac32583ed801e730f8a86f8e 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -498,7 +498,7 @@ QmlItemNode findRecursiveQmlItemNode(const QmlObjectNode &firstQmlObjectNode) return QmlItemNode(); } -void FormEditorView::transformChanged(const QmlObjectNode &qmlObjectNode) +void FormEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &/*propertyName*/) { QmlItemNode itemNode = qmlObjectNode.toQmlItemNode(); if (itemNode.isValid() && scene()->hasItemForQmlItemNode(itemNode)) { @@ -523,7 +523,7 @@ void FormEditorView::parentChanged(const QmlObjectNode &qmlObjectNode) } } -void FormEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode) +void FormEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &/*propertyName*/) { Q_ASSERT(qmlObjectNode.isValid()); @@ -546,19 +546,6 @@ void FormEditorView::setSelectOnlyContentItemsAction(bool selectOnlyContentItems m_selectionTool->setSelectOnlyContentItems(selectOnlyContentItems); } -void FormEditorView::updateItem(const QmlObjectNode &qmlObjectNode) -{ - - Q_ASSERT(qmlObjectNode.isValid()); - - QmlItemNode itemNode = findRecursiveQmlItemNode(qmlObjectNode); - - if (itemNode.isValid() && scene()->hasItemForQmlItemNode(itemNode)) { - m_scene->synchronizeOtherProperty(itemNode); - m_currentTool->formEditorItemsChanged(QList<FormEditorItem*>() << m_scene->itemForQmlItemNode(itemNode)); - } -} - void FormEditorView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState) { QmlModelView::stateChanged(newQmlModelState, oldQmlModelState); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h index 974a3c29afa731f0b9e0e85861a9d8c2b418a5a6..7afea46e7cd54263e11f3af897469a468433903d 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h @@ -32,8 +32,10 @@ #include <qmlmodelview.h> +QT_BEGIN_NAMESPACE class QGraphicsScene; class QGraphicsSceneMouseEvent; +QT_END_NAMESPACE namespace QmlDesigner { @@ -108,10 +110,9 @@ signals: void ItemCreatorDeActivated(); protected: - void transformChanged(const QmlObjectNode &qmlObjectNode); + void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName); void parentChanged(const QmlObjectNode &qmlObjectNode); - void otherPropertyChanged(const QmlObjectNode &qmlObjectNode); - void updateItem(const QmlObjectNode &qmlObjectNode); + void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName); void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState); protected slots: diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h index 688ef5839385b9b12a790b37d5e3af6d2be3b8aa..56812034094f1813f25c933138b5bd1533a9cbcb 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h @@ -32,7 +32,9 @@ #include <QWidget> +QT_BEGIN_NAMESPACE class QActionGroup; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/numberseriesaction.h b/src/plugins/qmldesigner/components/formeditor/numberseriesaction.h index e6a8c82f160551a8f54193cb58c87ca7c6881556..bc5ec13d6db042af72076d107a157f56482c0424 100644 --- a/src/plugins/qmldesigner/components/formeditor/numberseriesaction.h +++ b/src/plugins/qmldesigner/components/formeditor/numberseriesaction.h @@ -32,7 +32,9 @@ #include <QWidgetAction> +QT_BEGIN_NAMESPACE class QStandardItemModel; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/snapper.h b/src/plugins/qmldesigner/components/formeditor/snapper.h index a176b4e6e1296f1bbd116e593e6df598435d1604..6f9e0f744b77d74a89a5b1e3b658c8f581b1fa06 100644 --- a/src/plugins/qmldesigner/components/formeditor/snapper.h +++ b/src/plugins/qmldesigner/components/formeditor/snapper.h @@ -32,7 +32,9 @@ #include "formeditoritem.h" +QT_BEGIN_NAMESPACE class QLineF; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/toolbox.h b/src/plugins/qmldesigner/components/formeditor/toolbox.h index 98fed3a271949f345730b6c3fdd06849d2f23106..8406e57111f4839d459f00e4d80947caf96e9348 100644 --- a/src/plugins/qmldesigner/components/formeditor/toolbox.h +++ b/src/plugins/qmldesigner/components/formeditor/toolbox.h @@ -32,7 +32,9 @@ #include <QWidget> +QT_BEGIN_NAMESPACE class QToolBar; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/zoomaction.h b/src/plugins/qmldesigner/components/formeditor/zoomaction.h index 02ceb9acc0ea5c66af7669eceb4006841833c0af..9494ee031edc0aba3dd8a3121d59426d72781ae2 100644 --- a/src/plugins/qmldesigner/components/formeditor/zoomaction.h +++ b/src/plugins/qmldesigner/components/formeditor/zoomaction.h @@ -32,7 +32,9 @@ #include <QWidgetAction> +QT_BEGIN_NAMESPACE class QAbstractItemModel; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/integration/componentaction.h b/src/plugins/qmldesigner/components/integration/componentaction.h index e4ee74645fc16437800499904ebe23cbc854f1fa..ce4f6e5cde69631e5ce6d64f77bcc060e271c9c3 100644 --- a/src/plugins/qmldesigner/components/integration/componentaction.h +++ b/src/plugins/qmldesigner/components/integration/componentaction.h @@ -33,7 +33,9 @@ #include <QWidgetAction> #include <QWeakPointer> +QT_BEGIN_NAMESPACE class QComboBox; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/integration/componentview.h b/src/plugins/qmldesigner/components/integration/componentview.h index 47c74ff239d5bc144a2bb9359bc6caa70e4cf368..d40e037df17f36f0ee3f85529b331104df0c58ba 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.h +++ b/src/plugins/qmldesigner/components/integration/componentview.h @@ -35,7 +35,9 @@ #include <QStringList> +QT_BEGIN_NAMESPACE class QStandardItemModel; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h index c4488ec884fb35de024872570c753c62dee5c0f0..1d4384fa2dfa508b4ccbe6d5278f16eac57702de 100644 --- a/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h +++ b/src/plugins/qmldesigner/components/integration/designdocumentcontroller.h @@ -35,12 +35,14 @@ #include <QtCore/QObject> #include <QtCore/QString> +QT_BEGIN_NAMESPACE class QUndoStack; class QWidget; class QIODevice; class QProcess; class QPlainTextEdit; class QmlError; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/integration/integrationcore.h b/src/plugins/qmldesigner/components/integration/integrationcore.h index 170eb6ac48daf70fef41bd0d9e001d12783a5cac..a92905266adae5a732772cf0ad8c68a616e9f02e 100644 --- a/src/plugins/qmldesigner/components/integration/integrationcore.h +++ b/src/plugins/qmldesigner/components/integration/integrationcore.h @@ -32,8 +32,10 @@ #include <QtCore/QObject> +QT_BEGIN_NAMESPACE class QWidget; class QDialog; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h index df50fe6c32fedc7dcdc258d47ddcb406da27dd02..0daca6b5c7f4a931e5ceedeaa7ad444ccf80b318 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h +++ b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h @@ -32,7 +32,9 @@ #include <QTimeLine> #include <QDrag> +QT_BEGIN_NAMESPACE class QMimeData; +QT_END_NAMESPACE namespace QmlDesigner { @@ -119,6 +121,11 @@ class CustomItemLibraryDrag : public QDrag { void exec() { QmlDesignerItemLibraryDragAndDrop::CustomDragAndDrop::startCustomDrag(m_pixmap, m_preview, m_mimeData); } + public slots: + void stopDrag() { + QmlDesignerItemLibraryDragAndDrop::CustomDragAndDrop::endCustomDrag(); + } + private: QPixmap m_pixmap, m_preview; QMimeData *m_mimeData; diff --git a/src/plugins/qmldesigner/components/itemlibrary/default-icon.png b/src/plugins/qmldesigner/components/itemlibrary/images/item-default-icon.png similarity index 100% rename from src/plugins/qmldesigner/components/itemlibrary/default-icon.png rename to src/plugins/qmldesigner/components/itemlibrary/images/item-default-icon.png diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp index d778c56f8effebe4cc4086f5c72d07f8f098a4ad..da5f34c4e018af00ad54a4f6fe74978bde0b9c54 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp @@ -52,6 +52,11 @@ #include <QFile> #include <QDirModel> #include <QFileIconProvider> +#include <QImageReader> + +#include <QmlView> +#include <QmlGraphicsItem> +#include <private/qmlengine_p.h> namespace QmlDesigner { @@ -59,119 +64,127 @@ namespace QmlDesigner { class MyFileIconProvider : public QFileIconProvider { public: - MyFileIconProvider() : QFileIconProvider() + MyFileIconProvider(const QSize &iconSize) + : QFileIconProvider(), + m_iconSize(iconSize) {} + virtual QIcon icon ( const QFileInfo & info ) const { QPixmap pixmap(info.absoluteFilePath()); - if (pixmap.isNull()) - return QFileIconProvider::icon(info); - else return pixmap; //pixmap.scaled(128, 128, Qt::KeepAspectRatio); - } -}; - - + if (pixmap.isNull()) { + QIcon defaultIcon(QFileIconProvider::icon(info)); + pixmap = defaultIcon.pixmap(defaultIcon.actualSize(m_iconSize)); + } -class GrabHelper { - Q_DISABLE_COPY(GrabHelper) -public: - GrabHelper(); - QPixmap grabItem(QGraphicsItem *item); + if (pixmap.width() == m_iconSize.width() + && pixmap.height() == m_iconSize.height()) + return pixmap; + + if ((pixmap.width() > m_iconSize.width()) + || (pixmap.height() > m_iconSize.height())) + return pixmap.scaled(m_iconSize, Qt::KeepAspectRatio); + + QPoint offset((m_iconSize.width() - pixmap.width()) / 2, + (m_iconSize.height() - pixmap.height()) / 2); + QImage newIcon(m_iconSize, QImage::Format_ARGB32_Premultiplied); + newIcon.fill(Qt::transparent); + QPainter painter(&newIcon); + painter.drawPixmap(offset, pixmap); + return QPixmap::fromImage(newIcon); + } private: - QGraphicsScene m_scene; - QGraphicsView m_view; + QSize m_iconSize; }; -GrabHelper::GrabHelper() -{ - m_view.setScene(&m_scene); - m_view.setFrameShape(QFrame::NoFrame); - m_view.setAlignment(Qt::AlignLeft|Qt::AlignTop); - m_view.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - m_view.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); -} - -QPixmap GrabHelper::grabItem(QGraphicsItem *item) -{ - if (item->scene()) { - qWarning("%s: WARNING: Attempt to grab item that is part of another scene!", Q_FUNC_INFO); - return QPixmap(); - } - // Temporarily add the item, resize the view widget and grab it. - m_scene.addItem(item); - item->setPos(0.0, 0.0); - const QSize size = item->boundingRect().size().toSize(); - QPixmap rc; - if (!size.isEmpty()) { // We have seen horses barf... - m_view.resize(size); - rc = QPixmap::grabWidget(&m_view); - } - m_scene.removeItem(item); - return rc; -} // ---------- ItemLibraryPrivate class ItemLibraryPrivate { public: ItemLibraryPrivate(QObject *object); - ~ItemLibraryPrivate(); Ui::ItemLibrary m_ui; Internal::ItemLibraryModel *m_itemLibraryModel; + QmlView *m_itemsView; QDirModel *m_resourcesDirModel; - QSortFilterProxyModel *m_filterProxy; - GrabHelper *m_grabHelper; QString m_resourcePath; + QSize m_itemIconSize, m_resIconSize; + MyFileIconProvider m_iconProvider; }; ItemLibraryPrivate::ItemLibraryPrivate(QObject *object) : m_itemLibraryModel(0), - m_grabHelper(0) + m_itemsView(0), + m_itemIconSize(32, 32), + m_resIconSize(32, 32), + m_iconProvider(m_resIconSize) { m_resourcePath = QDir::currentPath(); Q_UNUSED(object); } -ItemLibraryPrivate::~ItemLibraryPrivate() -{ - delete m_grabHelper; -} - ItemLibrary::ItemLibrary(QWidget *parent) : QFrame(parent), m_d(new ItemLibraryPrivate(this)) { m_d->m_ui.setupUi(this); - m_d->m_itemLibraryModel = new Internal::ItemLibraryModel(this); + layout()->setContentsMargins(3, 3, 3, 3); + layout()->setSpacing(3); + m_d->m_resourcesDirModel = new QDirModel(this); - m_d->m_filterProxy = new QSortFilterProxyModel(this); - m_d->m_filterProxy->setSourceModel(m_d->m_itemLibraryModel); - m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_filterProxy); - m_d->m_filterProxy->setDynamicSortFilter(true); - m_d->m_ui.ItemLibraryTreeView->setRealModel(m_d->m_itemLibraryModel); - m_d->m_ui.ItemLibraryTreeView->setIconSize(QSize(64, 64)); + + m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_resourcesDirModel); + m_d->m_ui.ItemLibraryTreeView->setIconSize(m_d->m_resIconSize); + m_d->m_ui.ItemLibraryTreeView->setColumnHidden(1, true); + m_d->m_ui.ItemLibraryTreeView->setColumnHidden(2, true); + m_d->m_ui.ItemLibraryTreeView->setColumnHidden(3, true); m_d->m_ui.ItemLibraryTreeView->setSortingEnabled(true); m_d->m_ui.ItemLibraryTreeView->setHeaderHidden(true); m_d->m_ui.ItemLibraryTreeView->setIndentation(10); - m_d->m_ui.ItemLibraryTreeView->setAnimated(true); m_d->m_ui.ItemLibraryTreeView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); m_d->m_ui.ItemLibraryTreeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_d->m_ui.ItemLibraryTreeView->setAttribute(Qt::WA_MacShowFocusRect, false); - m_d->m_filterProxy->setFilterCaseSensitivity(Qt::CaseInsensitive); - m_d->m_filterProxy->setFilterRole(Qt::UserRole); - m_d->m_filterProxy->setSortRole(Qt::DisplayRole); - connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), m_d->m_filterProxy, SLOT(setFilterRegExp(QString))); - connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(setNameFilter(QString))); - connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(expandAll())); - connect(m_d->m_ui.buttonItems, SIGNAL(toggled (bool)), this, SLOT(itemLibraryButton())); - connect(m_d->m_ui.buttonResources, SIGNAL(toggled (bool)), this, SLOT(resourcesButton())); - connect(m_d->m_ui.ItemLibraryTreeView, SIGNAL(itemActivated(const QString&)), this, SIGNAL(itemActivated(const QString&))); + m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath)); + + const QString qmlSourcePath(":/ItemLibrary/qml/ItemsView.qml"); + QFile qmlSourceFile(qmlSourcePath); + qmlSourceFile.open(QFile::ReadOnly); + Q_ASSERT(qmlSourceFile.isOpen()); + QString qmlSource(qmlSourceFile.readAll()); + + m_d->m_itemsView = new QmlView(this); + m_d->m_itemsView->setQml(qmlSource, qmlSourcePath); + m_d->m_itemsView->setAttribute(Qt::WA_OpaquePaintEvent); + m_d->m_itemsView->setAttribute(Qt::WA_NoSystemBackground); + m_d->m_itemsView->setAcceptDrops(false); + m_d->m_itemsView->setFocusPolicy(Qt::ClickFocus); + m_d->m_itemsView->setContentResizable(true); + m_d->m_ui.ItemLibraryGridLayout->addWidget(m_d->m_itemsView, 0, 0); + + m_d->m_itemLibraryModel = new Internal::ItemLibraryModel(QmlEnginePrivate::getScriptEngine(m_d->m_itemsView->engine()), this); + m_d->m_itemLibraryModel->setItemIconSize(m_d->m_itemIconSize); + m_d->m_itemsView->rootContext()->setContextProperty(QLatin1String("itemLibraryModel"), m_d->m_itemLibraryModel); + m_d->m_itemsView->rootContext()->setContextProperty(QLatin1String("itemLibraryIconWidth"), m_d->m_itemIconSize.width()); + m_d->m_itemsView->rootContext()->setContextProperty(QLatin1String("itemLibraryIconHeight"), m_d->m_itemIconSize.height()); + + m_d->m_itemsView->execute(); + + connect(m_d->m_itemsView->root(), SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int))); + connect(m_d->m_itemsView->root(), SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int))); + connect(this, SIGNAL(expandAllItems()), m_d->m_itemsView->root(), SLOT(expandAll())); + + connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(setSearchFilter(QString))); m_d->m_ui.lineEdit->setDragEnabled(false); - setNameFilter(""); - MyFileIconProvider *fileIconProvider = new MyFileIconProvider(); - m_d->m_resourcesDirModel->setIconProvider(fileIconProvider); + connect(m_d->m_ui.buttonItems, SIGNAL(clicked()), this, SLOT(itemLibraryButtonToggled())); + connect(m_d->m_ui.buttonResources, SIGNAL(clicked()), this, SLOT(resourcesButtonToggled())); + + m_d->m_ui.buttonItems->setChecked(true); + itemLibraryButtonToggled(); + setSearchFilter(""); + + m_d->m_resourcesDirModel->setIconProvider(&m_d->m_iconProvider); setWindowTitle(tr("Library", "Title of library view")); @@ -194,8 +207,6 @@ ItemLibrary::ItemLibrary(QWidget *parent) : QString styleSheet = QLatin1String(file.readAll()); m_d->m_ui.ItemLibraryTreeView->setStyleSheet(styleSheet); } - - m_d->m_ui.buttonItems->setChecked(true); } ItemLibrary::~ItemLibrary() @@ -203,48 +214,44 @@ ItemLibrary::~ItemLibrary() delete m_d; } -void ItemLibrary::setNameFilter(const QString &nameFilter) -{ - QStringList nameFilterList; - nameFilterList.append(nameFilter + "*.gif"); - nameFilterList.append(nameFilter + "*.png"); - nameFilterList.append(nameFilter + "*.jpg"); - nameFilterList.append(nameFilter + "*."); - m_d->m_resourcesDirModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); - m_d->m_resourcesDirModel->setNameFilters(nameFilterList); - if (m_d->m_ui.ItemLibraryTreeView->model() == m_d->m_resourcesDirModel) - m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath)); -} - -void ItemLibrary::itemLibraryButton() +void ItemLibrary::setSearchFilter(const QString &searchFilter) { if (m_d->m_ui.buttonItems->isChecked()) { - m_d->m_filterProxy->setSourceModel(m_d->m_itemLibraryModel); - m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_filterProxy); - m_d->m_ui.ItemLibraryTreeView->setIconSize(QSize(64, 64)); - m_d->m_ui.buttonResources->setChecked(false); - m_d->m_ui.ItemLibraryTreeView->setRealModel(m_d->m_itemLibraryModel); - expandAll(); + m_d->m_itemLibraryModel->setSearchText(searchFilter); + m_d->m_itemsView->update(); + emit expandAllItems(); + } else { + QStringList nameFilterList; + if (searchFilter.contains('.')) { + nameFilterList.append(QString("*%1*").arg(searchFilter)); + } else { + foreach (const QByteArray &extension, QImageReader::supportedImageFormats()) { + nameFilterList.append(QString("*%1*.%2").arg(searchFilter, QString::fromAscii(extension))); + } + } + + m_d->m_resourcesDirModel->setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot); + m_d->m_resourcesDirModel->setNameFilters(nameFilterList); + if (m_d->m_ui.ItemLibraryTreeView->model() == m_d->m_resourcesDirModel) + m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath)); + m_d->m_ui.ItemLibraryTreeView->expandToDepth(1); } } -void ItemLibrary::resourcesButton() +void ItemLibrary::itemLibraryButtonToggled() { - if (m_d->m_ui.buttonResources->isChecked()) { - m_d->m_ui.ItemLibraryTreeView->setModel(m_d->m_resourcesDirModel); - m_d->m_ui.ItemLibraryTreeView->setIconSize(QSize(32, 32)); - m_d->m_ui.buttonItems->setChecked(false); - m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath)); - m_d->m_ui.ItemLibraryTreeView->setColumnHidden(1, true); - m_d->m_ui.ItemLibraryTreeView->setColumnHidden(2, true); - m_d->m_ui.ItemLibraryTreeView->setColumnHidden(3, true); - expandAll(); - } + m_d->m_ui.LibraryStackedWidget->setCurrentIndex(0); + m_d->m_ui.buttonItems->setChecked(true); + m_d->m_ui.buttonResources->setChecked(false); + setSearchFilter(m_d->m_ui.lineEdit->text()); } -void ItemLibrary::addItemLibraryInfo(const ItemLibraryInfo &itemLibraryInfo) +void ItemLibrary::resourcesButtonToggled() { - m_d->m_itemLibraryModel->addItemLibraryInfo(itemLibraryInfo); + m_d->m_ui.LibraryStackedWidget->setCurrentIndex(1); + m_d->m_ui.buttonResources->setChecked(true); + m_d->m_ui.buttonItems->setChecked(false); + setSearchFilter(m_d->m_ui.lineEdit->text()); } void ItemLibrary::setResourcePath(const QString &resourcePath) @@ -252,70 +259,30 @@ void ItemLibrary::setResourcePath(const QString &resourcePath) m_d->m_resourcePath = resourcePath; } -void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo) +void ItemLibrary::startDragAndDrop(int itemLibId) { - m_d->m_itemLibraryModel->clear(); - - foreach (const QString &type, metaInfo.itemLibraryItems()) { - NodeMetaInfo nodeInfo = metaInfo.nodeMetaInfo(type); - - QList<ItemLibraryInfo> itemLibraryRepresentationList = metaInfo.itemLibraryRepresentations(nodeInfo); - - if (!metaInfo.hasNodeMetaInfo(type)) - qWarning() << "ItemLibrary: type not declared: " << type; - if (!itemLibraryRepresentationList.isEmpty() && metaInfo.hasNodeMetaInfo(type)) { - foreach (ItemLibraryInfo itemLibraryRepresentation, itemLibraryRepresentationList) { - QImage image(64, 64, QImage::Format_RGB32); // = m_d->m_queryView->paintObject(nodeInfo, itemLibraryRepresentation.properties()); TODO - image.fill(0xffffffff); - if (!image.isNull()) { - QPainter p(&image); - QPen pen(Qt::gray); - pen.setWidth(2); - p.setPen(pen); - p.drawRect(1, 1, image.width() - 2, image.height() - 2); - } - QIcon icon = itemLibraryRepresentation.icon(); - if (itemLibraryRepresentation.icon().isNull()) - itemLibraryRepresentation.setIcon(QIcon(":/ItemLibrary/images/default-icon.png")); - - if (itemLibraryRepresentation.category().isEmpty()) - itemLibraryRepresentation.setCategory(nodeInfo.category()); - if (!image.isNull()) { - itemLibraryRepresentation.setDragIcon(QPixmap::fromImage(image)); - addItemLibraryInfo(itemLibraryRepresentation); - } - } - } else { - QImage image; // = m_d->m_queryView->paintObject(nodeInfo); TODO we have to render image - QIcon icon = nodeInfo.icon(); - if (icon.isNull()) - icon = QIcon(":/ItemLibrary/images/default-icon.png"); - - ItemLibraryInfo itemLibraryInfo; - itemLibraryInfo.setName(type); - itemLibraryInfo.setTypeName(nodeInfo.typeName()); - itemLibraryInfo.setCategory(nodeInfo.category()); - itemLibraryInfo.setIcon(icon); - itemLibraryInfo.setMajorVersion(nodeInfo.majorVersion()); - itemLibraryInfo.setMinorVersion(nodeInfo.minorVersion()); - itemLibraryInfo.setDragIcon(QPixmap::fromImage(image)); - addItemLibraryInfo(itemLibraryInfo); - } - } - expandAll(); + QMimeData *mimeData = m_d->m_itemLibraryModel->getMimeData(itemLibId); + CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this); + const QImage image = qvariant_cast<QImage>(mimeData->imageData()); + + drag->setPixmap(m_d->m_itemLibraryModel->getIcon(itemLibId).pixmap(32, 32)); + drag->setPreview(QPixmap::fromImage(image)); + drag->setMimeData(mimeData); + + connect(m_d->m_itemsView->root(), SIGNAL(stopDragAndDrop()), drag, SLOT(stopDrag())); + + drag->exec(); } -void ItemLibrary::expandAll() +void ItemLibrary::showItemInfo(int /*itemLibId*/) { - m_d->m_ui.ItemLibraryTreeView->expandToDepth(1); +// qDebug() << "showing item info about id" << itemLibId; } -void ItemLibrary::contextMenuEvent (QContextMenuEvent *event) +void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo) { - event->accept(); - QMenu menu; - menu.addAction(tr("About plugins...")); - menu.exec(event->globalPos()); + m_d->m_itemLibraryModel->update(metaInfo); } } + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h index 309e120490bf081c8794619403c508369a67263e..6adf53504dc4b3af6c5efd017bece852c11d7251 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h @@ -32,9 +32,11 @@ #include <QtGui/QFrame> +QT_BEGIN_NAMESPACE class QGraphicsItem; class QPixmap; class QMimeData; +QT_END_NAMESPACE namespace QmlDesigner { @@ -46,6 +48,7 @@ class ItemLibrary : public QFrame { Q_OBJECT Q_DISABLE_COPY(ItemLibrary) + public: ItemLibrary(QWidget *parent = 0); virtual ~ItemLibrary(); @@ -53,28 +56,25 @@ public: void addItemLibraryInfo(const ItemLibraryInfo &ItemLibraryInfo); void setMetaInfo(const MetaInfo &metaInfo); - // Helper for creating widget box items. Note that this temporarily - // adds the item to a scene, so, the item must not be associated - // with a scene. - public Q_SLOTS: - void expandAll(); - void itemLibraryButton(); - void resourcesButton(); - void setNameFilter(const QString &nameFilter); + void itemLibraryButtonToggled(); + void resourcesButtonToggled(); + + void setSearchFilter(const QString &nameFilter); void setResourcePath(const QString &resourcePath); + + void startDragAndDrop(int itemLibId); + void showItemInfo(int itemLibId); + signals: void itemActivated(const QString& itemName); - -protected: - virtual void contextMenuEvent (QContextMenuEvent * event); + void expandAllItems(); private: ItemLibraryPrivate *m_d; }; -//class ItemLibraryFilter : public QObject - } #endif // ITEMLIBRARY_H + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri index b8212323f1109dca3c7651f11035a5c280f4d735..470a6295d7bd3973f7ef7e55c33cf5f1e971a02b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri @@ -6,7 +6,8 @@ VPATH += $$PWD INCLUDEPATH += $$PWD # Input -HEADERS += itemlibrary.h itemlibrarymodel.h customdraganddrop.h +HEADERS += itemlibrary.h customdraganddrop.h itemlibrarymodel.h itemlibrarytreeview.h FORMS += itemlibrary.ui -SOURCES += itemlibrary.cpp itemlibrarymodel.cpp customdraganddrop.cpp +SOURCES += itemlibrary.cpp customdraganddrop.cpp itemlibrarymodel.cpp itemlibrarytreeview.cpp RESOURCES += itemlibrary.qrc + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc index c1d136b81d404c61779512e32a7cae55a3b7a865..e4d27b04769854804c139603cbd73d3ef2e3b79d 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.qrc @@ -1,5 +1,13 @@ <RCC> - <qresource prefix="/ItemLibrary/images" > - <file>default-icon.png</file> + <qresource prefix="/ItemLibrary" > + <file>qml/ItemsView.qml</file> + <file>qml/ItemsViewStyle.qml</file> + <file>qml/SectionView.qml</file> + <file>qml/ItemView.qml</file> + <file>qml/Scrollbar.qml</file> + <file>qml/Selector.qml</file> + + <file>images/item-default-icon.png</file> </qresource> </RCC> + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui index 029896d37b0db7d5f9fec7525832e3aeda48f637..0321e5323570c3ab7b40affda3c79167e7bd0b12 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui @@ -7,104 +7,220 @@ <x>0</x> <y>0</y> <width>497</width> - <height>792</height> + <height>635</height> </rect> </property> <property name="windowTitle"> <string>ItemLibrary</string> </property> - <layout class="QGridLayout" name="gridLayout"> - <property name="leftMargin"> - <number>2</number> - </property> - <property name="topMargin"> - <number>6</number> - </property> - <property name="rightMargin"> - <number>2</number> - </property> - <property name="bottomMargin"> - <number>2</number> - </property> - <property name="horizontalSpacing"> - <number>4</number> - </property> - <item row="0" column="0"> - <spacer name="horizontalSpacer_2"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>6</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QToolButton" name="buttonItems"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string>Items</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_4"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>6</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QToolButton" name="buttonResources"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>80</width> + <height>30</height> + </size> + </property> + <property name="text"> + <string>Resources</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <property name="autoExclusive"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_5"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Preferred</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>6</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line_2"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeType"> - <enum>QSizePolicy::Fixed</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>6</width> - <height>27</height> - </size> - </property> - </spacer> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Filter: </string> - </property> - </widget> - </item> - <item row="0" column="2"> - <widget class="QLineEdit" name="lineEdit"/> - </item> - <item row="0" column="3"> - <widget class="QToolButton" name="buttonItems"> - <property name="minimumSize"> - <size> - <width>80</width> - <height>30</height> - </size> - </property> - <property name="text"> - <string>Items</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> </widget> </item> - <item row="0" column="4"> - <widget class="QToolButton" name="buttonResources"> - <property name="minimumSize"> - <size> - <width>80</width> - <height>30</height> - </size> - </property> - <property name="text"> - <string>Resources</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - <property name="checked"> - <bool>false</bool> - </property> - <property name="autoExclusive"> - <bool>false</bool> - </property> - </widget> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>6</width> + <height>6</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Filter: </string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="lineEdit"/> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>6</width> + <height>6</height> + </size> + </property> + </spacer> + </item> + </layout> </item> - <item row="1" column="0" colspan="5"> + <item> <widget class="Line" name="line"> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> </widget> </item> - <item row="2" column="0" colspan="5"> - <widget class="QmlDesigner::Internal::ItemLibraryTreeView" name="ItemLibraryTreeView"> - <property name="enabled"> - <bool>true</bool> + <item> + <widget class="QStackedWidget" name="LibraryStackedWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="currentIndex"> + <number>1</number> </property> + <widget class="QWidget" name="page_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="0" column="0"> + <layout class="QGridLayout" name="ItemLibraryGridLayout"/> + </item> + </layout> + </widget> + <widget class="QWidget" name="page_4"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0"> + <widget class="QmlDesigner::Internal::ItemLibraryTreeView" name="ItemLibraryTreeView"> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> </widget> </item> </layout> @@ -114,7 +230,7 @@ <customwidget> <class>QmlDesigner::Internal::ItemLibraryTreeView</class> <extends>QTreeView</extends> - <header>itemlibrarymodel.h</header> + <header>itemlibrarytreeview.h</header> </customwidget> </customwidgets> <resources/> diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 89e81f8313e5a948db1629626ba701b87cd29d1a..b21a3830c36445108ff574f9fc16f9aac5bfa9f8 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -1,297 +1,460 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - #include "itemlibrarymodel.h" -#include "itemlibrary.h" -#include "customdraganddrop.h" - -#include <QtCore/QMimeData> -#include <QtCore/QDebug> +#include "metainfo.h" -#include <QtGui/QImage> -#include <QtGui/QPixmap> -#include <QtGui/QDrag> -#include <QSortFilterProxyModel> +#include <QVariant> +#include <QMimeData> #include <QPainter> -#include <QLabel> -#include <itemlibraryinfo.h> -#include <QDirModel> +#include <QPen> +#include <qdebug.h> -enum { debug = 0 }; -// Store data and a type enumeration along with the QStandardItem -enum ItemType { CategoryItem, WidgetItem }; -enum Roles { TypeRole = Qt::UserRole + 1, - DataRole = Qt::UserRole + 2, - DragPixmapRole = Qt::UserRole + 3}; +namespace QmlDesigner { + +namespace Internal { -static inline ItemType itemType(const QStandardItem *item) +template <class T> +ItemLibrarySortedModel<T>::ItemLibrarySortedModel(QObject *parent) : + QmlListModel(parent) { - return static_cast<ItemType>(item->data(TypeRole).toInt()); } -static inline QmlDesigner::ItemLibraryInfo widgetItemData(const QStandardItem *item) + +template <class T> +ItemLibrarySortedModel<T>::~ItemLibrarySortedModel() { - const QVariant data = item->data(DataRole); - if (!data.isValid()) - return QmlDesigner::ItemLibraryInfo(); - return qvariant_cast<QmlDesigner::ItemLibraryInfo>(data); + clearElements(); } +template <class T> +void ItemLibrarySortedModel<T>::clearElements() +{ + while (m_elementOrder.count() > 0) + removeElement(m_elementOrder.at(0).libId); +} -namespace QmlDesigner { -namespace Internal { -// Cache a drag pixmap on the icon using the DragPixmapRole data field. -static QImage cachedDragImage(const ItemLibraryInfo &ItemLibraryInfo, - QStandardItem *item) +template <class T> +void ItemLibrarySortedModel<T>::addElement(T *element, int libId) { - const QVariant cached = item->data(DragPixmapRole); - if (cached.type() != QVariant::Invalid) - return qvariant_cast<QImage>(cached); - // TODO: Grab using factory - const QIcon icon = ItemLibraryInfo.dragIcon(); - if (icon.isNull()) - return QImage(); - const QList<QSize> sizes = icon.availableSizes(); - if (sizes.isEmpty()) - return QImage(); - const QImage image = icon.pixmap(sizes.front()).toImage(); - item->setData(image, DragPixmapRole); - return image; + struct order_struct orderEntry; + orderEntry.libId = libId; + orderEntry.visible = false; + + int pos = 0; + while ((pos < m_elementOrder.count()) && + (*(m_elementModels.value(m_elementOrder.at(pos).libId)) < *element)) + ++pos; + + m_elementModels.insert(libId, element); + m_elementOrder.insert(pos, orderEntry); + + setElementVisible(libId, true); } -ItemLibraryModel::ItemLibraryModel(QObject *parent) : - QStandardItemModel(parent) +template <class T> +void ItemLibrarySortedModel<T>::removeElement(int libId) { - setSupportedDragActions(Qt::CopyAction); + T *element = m_elementModels.value(libId); + int pos = findElement(libId); + struct order_struct orderEntry = m_elementOrder.at(pos); + + setElementVisible(libId, false); + + m_elementModels.remove(libId); + m_elementOrder.removeAt(pos); + + delete element; } -static inline QStandardItem *categoryToItem(const QString &g) + +template <class T> +bool ItemLibrarySortedModel<T>::elementVisible(int libId) const { - QStandardItem *rc = new QStandardItem(g); - rc->setFlags(Qt::ItemIsEnabled); - rc->setData(QVariant(CategoryItem), TypeRole); - rc->setData(g, Qt::UserRole); - return rc; + int pos = findElement(libId); + return m_elementOrder.at(pos).visible; } -static QStandardItem *customWidgetDataToItem(const ItemLibraryInfo &ItemLibraryInfo) +template <class T> +void ItemLibrarySortedModel<T>::setElementVisible(int libId, bool visible) { - QStandardItem *item = new QStandardItem(ItemLibraryInfo.name()); - const QIcon icon = ItemLibraryInfo.icon(); - if (!icon.isNull() && !icon.availableSizes().empty()) { - item->setIcon(icon); - if (icon.availableSizes().count() == 1) { - item->setSizeHint(icon.availableSizes().first() + QSize(1, 1)); - } + int pos = findElement(libId), + offset = 0; + + if (m_elementOrder.at(pos).visible == visible) + return; + + for (int i = 0; (i + offset) < pos;) { + if (m_elementOrder.at(i + offset).visible) + ++i; + else + ++offset; } - item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsDragEnabled|Qt::ItemIsSelectable); - item->setData(qVariantFromValue(ItemLibraryInfo), DataRole); - item->setData(QVariant(WidgetItem), TypeRole); - item->setData(ItemLibraryInfo.name(), Qt::UserRole); - return item; + if (visible) + insert(pos - offset, *(m_elementModels.value(libId))); + else + remove(pos - offset); + + m_elementOrder[pos].visible = visible; } -void ItemLibraryModel::addItemLibraryInfo(const ItemLibraryInfo &itemLibraryInfo) +template <class T> +const QMap<int, T *> &ItemLibrarySortedModel<T>::elements() const { - QStandardItem *categoryItem = findCategoryItem(itemLibraryInfo.category()); - if (!categoryItem) { - categoryItem = categoryToItem(itemLibraryInfo.category()); - appendRow(categoryItem); - } - categoryItem->appendRow(customWidgetDataToItem(itemLibraryInfo)); - QString filterList = categoryItem->data(Qt::UserRole).toString(); - filterList += itemLibraryInfo.name(); - categoryItem->setData(filterList, Qt::UserRole); + return m_elementModels; +} + + +template <class T> +T *ItemLibrarySortedModel<T>::elementModel(int libId) +{ + return m_elementModels.value(libId); } -QStandardItem *ItemLibraryModel::findCategoryItem(const QString &category) + +template <class T> +int ItemLibrarySortedModel<T>::findElement(int libId) const { - const QStandardItem *root = invisibleRootItem(); - const int rowCount = root->rowCount(); - for (int i = 0 ; i < rowCount; i++) { - QStandardItem *categoryItem = root->child(i, 0); - if (categoryItem->text() == category) - return categoryItem; + int i = 0; + QListIterator<struct order_struct> it(m_elementOrder); + + while (it.hasNext()) { + if (it.next().libId == libId) + return i; + ++i; } - return 0; + + return -1; +} + + + + +ItemLibraryItemModel::ItemLibraryItemModel(QScriptEngine *scriptEngine, int itemLibId, const QString &itemName) + : QScriptValue(scriptEngine->newObject()), + m_scriptEngine(scriptEngine), + m_libId(itemLibId), + m_name(itemName), + m_icon(), + m_iconSize(64, 64) +{ + QScriptValue pixmapScriptValue(m_scriptEngine->newVariant(QPixmap())); + + setProperty(QLatin1String("itemLibId"), itemLibId); + setProperty(QLatin1String("itemName"), itemName); + setProperty(QLatin1String("itemPixmap"), pixmapScriptValue); } -Qt::DropActions ItemLibraryModel::supportedDragActions() const + +ItemLibraryItemModel::~ItemLibraryItemModel() { - return Qt::CopyAction; + setProperty(QLatin1String("itemPixmap"), QVariant::Invalid); } -Qt::DropActions ItemLibraryModel::supportedDropActions() const + +int ItemLibraryItemModel::itemLibId() const { - return Qt::IgnoreAction; + return m_libId; } -QStringList ItemLibraryModel::mimeTypes () const + +QString ItemLibraryItemModel::itemName() const { - if (debug) - qDebug() << Q_FUNC_INFO; - return QStringList(QLatin1String("text/xml")); + return m_name; } -QByteArray ItemLibraryInfoToByteArray(const ItemLibraryInfo &ItemLibraryInfo) + +void ItemLibraryItemModel::setItemIcon(const QIcon &itemIcon) { - QByteArray byteArray; - QDataStream stream(&byteArray, QIODevice::WriteOnly); + m_icon = itemIcon; + + QScriptValue pixmapScriptValue(m_scriptEngine->newVariant(m_icon.pixmap(m_iconSize))); + setProperty(QLatin1String("itemPixmap"), pixmapScriptValue); +} - stream << ItemLibraryInfo; - return byteArray; +void ItemLibraryItemModel::setItemIconSize(const QSize &itemIconSize) +{ + m_iconSize = itemIconSize; +// qDebug() << "set icon size" << itemIconSize; + setItemIcon(m_icon); } -QMimeData *ItemLibraryModel::mimeData(const QModelIndexList &indexes) const + +bool ItemLibraryItemModel::operator<(const ItemLibraryItemModel &other) const { - if (debug) - qDebug() << Q_FUNC_INFO << indexes.size(); - if (indexes.size() != 1) - return 0; - QStandardItem *item = itemFromIndex (indexes.front()); - if (!item || itemType(item) != WidgetItem) - return 0; - QMimeData *mimeData = new QMimeData; + return itemName() < other.itemName(); +} + + - ItemLibraryInfo ItemLibraryInfo(widgetItemData(item)); - const QImage image = cachedDragImage(ItemLibraryInfo, item); - if (!image.isNull()) - mimeData->setImageData(image); +ItemLibrarySectionModel::ItemLibrarySectionModel(QScriptEngine *scriptEngine, int sectionLibId, const QString §ionName, QObject *parent) + : QScriptValue(scriptEngine->newObject()), + m_name(sectionName), + m_sectionEntries(parent) +{ + QScriptValue::setProperty(QLatin1String("sectionLibId"), sectionLibId); + QScriptValue::setProperty(QLatin1String("sectionName"), sectionName); + QScriptValue::setProperty(QLatin1String("sectionEntries"), + scriptEngine->newVariant(QVariant::fromValue(static_cast<QmlListModel *>(&m_sectionEntries)))); +} - mimeData->setData("application/vnd.bauhaus.itemlibraryinfo", ItemLibraryInfoToByteArray(ItemLibraryInfo)); - mimeData->removeFormat("text/plain"); +QString ItemLibrarySectionModel::sectionName() const +{ + return m_name; +} + - return mimeData; +void ItemLibrarySectionModel::addSectionEntry(ItemLibraryItemModel *sectionEntry) +{ + m_sectionEntries.addElement(sectionEntry, sectionEntry->itemLibId()); } -ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) : - QTreeView(parent) + +void ItemLibrarySectionModel::removeSectionEntry(int itemLibId) { - setDragEnabled(true); - setDragDropMode(QAbstractItemView::DragOnly); - connect(this, SIGNAL(clicked(const QModelIndex &)), this, SLOT(activateItem(const QModelIndex &))); + m_sectionEntries.removeElement(itemLibId); } -// We need to implement startDrag ourselves since we cannot -// otherwise influence drag pixmap and hotspot in the standard -// implementation. -void ItemLibraryTreeView::startDrag(Qt::DropActions /* supportedActions */) + +bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText) { - if (debug) - qDebug() << Q_FUNC_INFO; - QMimeData *mimeData = model()->mimeData(selectedIndexes()); - if (!mimeData) - return; + bool haveVisibleItems = false; + QMap<int, ItemLibraryItemModel *>::const_iterator itemIt = m_sectionEntries.elements().constBegin(); + while (itemIt != m_sectionEntries.elements().constEnd()) { - if (qobject_cast<QSortFilterProxyModel*>(model())) { - QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(selectedIndexes().front()); + bool itemVisible = itemIt.value()->itemName().toLower().contains(searchText); + m_sectionEntries.setElementVisible(itemIt.key(), itemVisible); - QStandardItem *item = m_model->itemFromIndex(index); + if (itemVisible) + haveVisibleItems = true; + + ++itemIt; + } - if (!item) - return; + return haveVisibleItems; +} - CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this); - const QImage image = qvariant_cast<QImage>(mimeData->imageData()); - drag->setPixmap(item->icon().pixmap(32, 32)); - drag->setPreview(QPixmap::fromImage(image)); - drag->setMimeData(mimeData); - drag->exec(); +void ItemLibrarySectionModel::updateItemIconSize(const QSize &itemIconSize) +{ + foreach (ItemLibraryItemModel *item, m_sectionEntries.elements().values()) { + item->setItemIconSize(itemIconSize); + } +} + + +bool ItemLibrarySectionModel::operator<(const ItemLibrarySectionModel &other) const +{ + return sectionName() < other.sectionName(); +} + + + + + +ItemLibraryModel::ItemLibraryModel(QScriptEngine *scriptEngine, QObject *parent) + : ItemLibrarySortedModel<ItemLibrarySectionModel>(parent), + m_scriptEngine(scriptEngine), + m_metaInfo(0), + m_searchText(""), + m_itemIconSize(64, 64), + m_nextLibId(0) +{ +} + + +ItemLibraryModel::~ItemLibraryModel() +{ + if (m_metaInfo) + delete m_metaInfo; +} + + +QString ItemLibraryModel::searchText() const +{ + return m_searchText; +} + + +void ItemLibraryModel::setSearchText(const QString &searchText) +{ + QString lowerSearchText = searchText.toLower(); + + if (m_searchText != lowerSearchText) { + m_searchText = lowerSearchText; + emit searchTextChanged(); + + updateVisibility(); + } +} + + +void ItemLibraryModel::setItemIconSize(const QSize &itemIconSize) +{ + m_itemIconSize = itemIconSize; + + foreach (ItemLibrarySectionModel *section, elements().values()) + section->updateItemIconSize(itemIconSize); +} + + +void ItemLibraryModel::update(const MetaInfo &metaInfo) +{ + QMap<QString, int> sections; + + clearElements(); + m_itemInfos.clear(); + + if (!m_metaInfo) { + m_metaInfo = new MetaInfo(metaInfo); } else { - QDirModel *dirModel = qobject_cast<QDirModel*>(model()); - Q_ASSERT(dirModel); - QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front()); - QPixmap pixmap(fileInfo.absoluteFilePath()); - if (!pixmap.isNull()) { - CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this); - drag->setPreview(pixmap); - drag->setPixmap(QIcon(pixmap).pixmap(128, 128)); - QMimeData *mimeData = new QMimeData; - mimeData->setData("application/vnd.bauhaus.libraryresource", fileInfo.absoluteFilePath().toLatin1()); - drag->setMimeData(mimeData); - drag->exec(); + *m_metaInfo = metaInfo; + } + + foreach (const QString &type, metaInfo.itemLibraryItems()) { + foreach (const ItemLibraryInfo &itemLibraryRepresentation, itemLibraryRepresentations(type)) { + + QString itemSectionName = itemLibraryRepresentation.category(); + ItemLibrarySectionModel *sectionModel; + ItemLibraryItemModel *itemModel; + int itemId = m_nextLibId++, sectionId; + + if (sections.contains(itemSectionName)) { + sectionId = sections.value(itemSectionName); + sectionModel = elementModel(sectionId); + } else { + sectionId = m_nextLibId++; + sectionModel = new ItemLibrarySectionModel(m_scriptEngine.data(), sectionId, itemSectionName, this); + addElement(sectionModel, sectionId); + sections.insert(itemSectionName, sectionId); + } + + m_itemInfos.insert(itemId, itemLibraryRepresentation); + + itemModel = new ItemLibraryItemModel(m_scriptEngine.data(), itemId, itemLibraryRepresentation.name()); + itemModel->setItemIcon(itemLibraryRepresentation.icon()); + itemModel->setItemIconSize(m_itemIconSize); + sectionModel->addSectionEntry(itemModel); } } + + updateVisibility(); +} + + +QString ItemLibraryModel::getTypeName(int libId) +{ + return m_itemInfos.value(libId).typeName(); } -static ItemLibraryInfo ItemLibraryInfoFromData(const QByteArray &data) + +QMimeData *ItemLibraryModel::getMimeData(int libId) { - QDataStream stream(data); + QMimeData *mimeData = new QMimeData(); + + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + stream << m_itemInfos.value(libId); + mimeData->setData(QLatin1String("application/vnd.bauhaus.itemlibraryinfo"), data); + + const QIcon icon = m_itemInfos.value(libId).dragIcon(); + if (!icon.isNull()) { + const QList<QSize> sizes = icon.availableSizes(); + if (!sizes.isEmpty()) + mimeData->setImageData(icon.pixmap(sizes.front()).toImage()); + } - ItemLibraryInfo itemLibraryInfo; - stream >> itemLibraryInfo; + mimeData->removeFormat(QLatin1String("text/plain")); - return itemLibraryInfo; + return mimeData; } -void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/) + +QIcon ItemLibraryModel::getIcon(int libId) { - QMimeData *mimeData = model()->mimeData(selectedIndexes()); - if (!mimeData) - return; + return m_itemInfos.value(libId).icon(); +} + - QString name; - if (qobject_cast<QSortFilterProxyModel*>(model())) { - QModelIndex index = qobject_cast<QSortFilterProxyModel*>(model())->mapToSource(selectedIndexes().front()); +void ItemLibraryModel::updateVisibility() +{ + QMap<int, ItemLibrarySectionModel *>::const_iterator sectionIt = elements().constBegin(); + while (sectionIt != elements().constEnd()) { - QStandardItem *item = m_model->itemFromIndex(index); + ItemLibrarySectionModel *sectionModel = sectionIt.value(); + QString sectionSearchText = m_searchText; - if (!item) - return; + if (sectionModel->sectionName().toLower().contains(m_searchText)) + sectionSearchText = ""; - ItemLibraryInfo itemLibraryInfo = ItemLibraryInfoFromData(mimeData->data("application/vnd.bauhaus.itemlibraryinfo")); - QString type = itemLibraryInfo.name(); + bool sectionVisibility = sectionModel->updateSectionVisibility(sectionSearchText); + setElementVisible(sectionIt.key(), sectionVisibility); - name = "item^" + type; - emit itemActivated(name); - } else { - QDirModel *dirModel = qobject_cast<QDirModel*>(model()); - Q_ASSERT(dirModel); - QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front()); - QPixmap pixmap(fileInfo.absoluteFilePath()); - if (!pixmap.isNull()) { - name = "image^" + fileInfo.absoluteFilePath(); - emit itemActivated(name); + ++sectionIt; + } + + emit visibilityUpdated(); +} + + +QList<ItemLibraryInfo> ItemLibraryModel::itemLibraryRepresentations(const QString &type) +{ + NodeMetaInfo nodeInfo = m_metaInfo->nodeMetaInfo(type); + QList<ItemLibraryInfo> itemLibraryRepresentationList = m_metaInfo->itemLibraryRepresentations(nodeInfo); + + QImage dragImage(64, 64, QImage::Format_RGB32); // TODO: draw item drag icon + dragImage.fill(0xffffffff); + QPainter p(&dragImage); + QPen pen(Qt::gray); + pen.setWidth(2); + p.setPen(pen); + p.drawRect(1, 1, dragImage.width() - 2, dragImage.height() - 2); + QPixmap dragPixmap(QPixmap::fromImage(dragImage)); + + if (!m_metaInfo->hasNodeMetaInfo(type)) + qWarning() << "ItemLibrary: type not declared: " << type; + + static QIcon defaultIcon(QLatin1String(":/ItemLibrary/images/item-default-icon.png")); + + if (itemLibraryRepresentationList.isEmpty() || !m_metaInfo->hasNodeMetaInfo(type)) { + QIcon icon = nodeInfo.icon(); + if (icon.isNull()) + icon = defaultIcon; + + ItemLibraryInfo itemLibraryInfo; + itemLibraryInfo.setName(type); + itemLibraryInfo.setTypeName(nodeInfo.typeName()); + itemLibraryInfo.setCategory(nodeInfo.category()); + itemLibraryInfo.setIcon(icon); + itemLibraryInfo.setDragIcon(dragPixmap); + itemLibraryInfo.setMajorVersion(nodeInfo.majorVersion()); + itemLibraryInfo.setMinorVersion(nodeInfo.minorVersion()); + itemLibraryRepresentationList.append(itemLibraryInfo); + } + else { + foreach (ItemLibraryInfo itemLibraryRepresentation, itemLibraryRepresentationList) { + QIcon icon = itemLibraryRepresentation.icon(); + if (itemLibraryRepresentation.icon().isNull()) + itemLibraryRepresentation.setIcon(defaultIcon); + + if (itemLibraryRepresentation.dragIcon().isNull()) + itemLibraryRepresentation.setDragIcon(dragPixmap); + + if (itemLibraryRepresentation.category().isEmpty()) + itemLibraryRepresentation.setCategory(nodeInfo.category()); } } + + return itemLibraryRepresentationList; } } // namespace Internal } // namespace QmlDesigner + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index f969fdf8859b781d5af38a6647a8a976c9b01cff..22a1beef7aab00b6eccdf75c007d6fa23eaaffec 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -1,89 +1,133 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ - #ifndef ITEMLIBRARYMODEL_H #define ITEMLIBRARYMODEL_H -#include <QtGui/QStandardItemModel> -#include <QtGui/QTreeView> -#include <QDrag> -#include <QDebug> -#include <QTimeLine> +#include <QMap> +#include <QIcon> +#include <QVariant> +#include <QScriptEngine> +#include <private/qmllistmodel_p.h> -class QLabel; +class QMimeData; namespace QmlDesigner { +class MetaInfo; class ItemLibraryInfo; namespace Internal { -// QStandardItemModel-based model for the widget box. -class ItemLibraryModel : public QStandardItemModel -{ - Q_OBJECT +template <class T> +class ItemLibrarySortedModel: public QmlListModel { +public: + ItemLibrarySortedModel(QObject *parent = 0); + ~ItemLibrarySortedModel(); + + void clearElements(); + + void addElement(T *element, int libId); + void removeElement(int libId); + + bool elementVisible(int libId) const; + void setElementVisible(int libId, bool visible); + + const QMap<int, T *> &elements() const; + + T *elementModel(int libId); + int findElement(int libId) const; + +private: + struct order_struct { + int libId; + bool visible; + }; + + QMap<int, T *> m_elementModels; + QList<struct order_struct> m_elementOrder; +}; + + +class ItemLibraryItemModel: public QScriptValue { +public: + ItemLibraryItemModel(QScriptEngine *scriptEngine, int itemLibId, const QString &itemName); + ~ItemLibraryItemModel(); + + int itemLibId() const; + QString itemName() const; + + void setItemIcon(const QIcon &itemIcon); + void setItemIconSize(const QSize &itemIconSize); + + bool operator<(const ItemLibraryItemModel &other) const; + +private: + QWeakPointer<QScriptEngine> m_scriptEngine; + int m_libId; + QString m_name; + QIcon m_icon; + QSize m_iconSize; +}; + + +class ItemLibrarySectionModel: public QScriptValue { public: - explicit ItemLibraryModel(QObject *parent = 0); - void addItemLibraryInfo(const ItemLibraryInfo &ItemLibraryInfo); + ItemLibrarySectionModel(QScriptEngine *scriptEngine, int sectionLibId, const QString §ionName, QObject *parent = 0); + + QString sectionName() const; + void addSectionEntry(ItemLibraryItemModel *sectionEntry); + void removeSectionEntry(int itemLibId); - QStandardItem *findCategoryItem(const QString &category); + bool updateSectionVisibility(const QString &searchText); + void updateItemIconSize(const QSize &itemIconSize); - virtual Qt::DropActions supportedDragActions() const; - virtual Qt::DropActions supportedDropActions() const; + bool operator<(const ItemLibrarySectionModel &other) const; - virtual QStringList mimeTypes() const; - virtual QMimeData *mimeData(const QModelIndexList &indexes) const; +private: + QString m_name; + ItemLibrarySortedModel<ItemLibraryItemModel> m_sectionEntries; }; -// ItemLibraryTreeView with Drag implementation -class ItemLibraryTreeView : public QTreeView { + +class ItemLibraryModel: public ItemLibrarySortedModel<ItemLibrarySectionModel> { Q_OBJECT - public: - explicit ItemLibraryTreeView(QWidget *parent = 0); + Q_PROPERTY(QString searchText READ searchText WRITE setSearchText NOTIFY searchTextChanged) - virtual void startDrag(Qt::DropActions supportedActions); +public: + ItemLibraryModel(QScriptEngine *scriptEngine, QObject *parent = 0); + ~ItemLibraryModel(); + + QString searchText() const; + + void update(const MetaInfo &metaInfo); + + QString getTypeName(int libId); + QMimeData *getMimeData(int libId); + QIcon getIcon(int libId); - void setRealModel(QStandardItemModel *model) { m_model = model; } +public slots: + void setSearchText(const QString &searchText); + void setItemIconSize(const QSize &itemIconSize); signals: - void itemActivated(const QString &itemName); -private slots: - void activateItem( const QModelIndex & index); + void qmlModelChanged(); + void searchTextChanged(); + void visibilityUpdated(); private: - QPixmap m_smallImage, m_bigImage; - QStandardItemModel *m_model; -}; + void updateVisibility(); + QList<ItemLibraryInfo> itemLibraryRepresentations(const QString &type); + QWeakPointer<QScriptEngine> m_scriptEngine; + MetaInfo *m_metaInfo; + QMap<int, ItemLibraryInfo> m_itemInfos; + QString m_searchText; + QSize m_itemIconSize; + int m_nextLibId; +}; } // namespace Internal } // namespace QmlDesigner + #endif // ITEMLIBRARYMODEL_H + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp new file mode 100644 index 0000000000000000000000000000000000000000..141c27f2b467e64236ad761d9c7aec80328c8a50 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.cpp @@ -0,0 +1,109 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "itemlibrarytreeview.h" +#include "itemlibrary.h" +#include "customdraganddrop.h" + +#include <QtCore/QMimeData> +#include <QtCore/QDebug> + +#include <QtGui/QImage> +#include <QtGui/QPixmap> +#include <QtGui/QDrag> +#include <QPainter> +#include <QLabel> +#include <itemlibraryinfo.h> +#include <QDirModel> + + +enum { debug = 0 }; + + +namespace QmlDesigner { + +namespace Internal { + + +ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) : + QTreeView(parent) +{ + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragOnly); + setUniformRowHeights(true); + connect(this, SIGNAL(clicked(const QModelIndex &)), this, SLOT(activateItem(const QModelIndex &))); +} + +// We need to implement startDrag ourselves since we cannot +// otherwise influence drag pixmap and hotspot in the standard +// implementation. +void ItemLibraryTreeView::startDrag(Qt::DropActions /* supportedActions */) +{ + if (debug) + qDebug() << Q_FUNC_INFO; + QMimeData *mimeData = model()->mimeData(selectedIndexes()); + if (!mimeData) + return; + + QDirModel *dirModel = qobject_cast<QDirModel*>(model()); + Q_ASSERT(dirModel); + QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front()); + QPixmap pixmap(fileInfo.absoluteFilePath()); + if (!pixmap.isNull()) { + CustomItemLibraryDrag *drag = new CustomItemLibraryDrag(this); + drag->setPreview(pixmap); + drag->setPixmap(QIcon(pixmap).pixmap(128, 128)); + QMimeData *mimeData = new QMimeData; + mimeData->setData("application/vnd.bauhaus.libraryresource", fileInfo.absoluteFilePath().toLatin1()); + drag->setMimeData(mimeData); + drag->exec(); + } +} + +void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/) +{ + QMimeData *mimeData = model()->mimeData(selectedIndexes()); + if (!mimeData) + return; + + QString name; + QDirModel *dirModel = qobject_cast<QDirModel*>(model()); + Q_ASSERT(dirModel); + QFileInfo fileInfo = dirModel->fileInfo(selectedIndexes().front()); + QPixmap pixmap(fileInfo.absoluteFilePath()); + if (!pixmap.isNull()) { + name = "image^" + fileInfo.absoluteFilePath(); + emit itemActivated(name); + } +} + +} // namespace Internal + +} // namespace QmlDesigner + diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.h new file mode 100644 index 0000000000000000000000000000000000000000..61edc0367ce2e5127931e51a7b874ce737ea36a6 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarytreeview.h @@ -0,0 +1,66 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef ITEMLIBRARYTREEVIEW_H +#define ITEMLIBRARYTREEVIEW_H + +#include <QtGui/QTreeView> +#include <QtGui/QStandardItemModel> +#include <QDrag> +#include <QDebug> +#include <QTimeLine> + +class QLabel; + +namespace QmlDesigner { + +namespace Internal { + +// ItemLibraryTreeView with Drag implementation +class ItemLibraryTreeView : public QTreeView { + Q_OBJECT +public: + explicit ItemLibraryTreeView(QWidget *parent = 0); + + virtual void startDrag(Qt::DropActions supportedActions); + +signals: + void itemActivated(const QString &itemName); + +private slots: + void activateItem( const QModelIndex &index); +}; + + +} // namespace Internal + +} // namespace QmlDesigner + +#endif // ITEMLIBRARYTREEVIEW_H + diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml new file mode 100644 index 0000000000000000000000000000000000000000..2b507cd97f193e126d0e920ccc856b56229f55b3 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml @@ -0,0 +1,87 @@ +import Qt 4.6 + +Item { + id: itemView + + property var style + + width: GridView.view.cellWidth + height: style.cellHeight + + signal itemClicked() + signal itemDragged() + + Rectangle { + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: style.gridLineColor + } + Rectangle { + anchors.bottom: parent.bottom + anchors.bottomMargin: -1 + anchors.left: parent.left + anchors.right: parent.right + height: 1 + color: style.gridLineColor + } + Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + width: 1 + color: style.gridLineColor + } + Rectangle { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.bottomMargin: -1 + anchors.right: parent.right + anchors.rightMargin: -1 + width: 1 + color: style.gridLineColor + } + + Image { + id: itemIcon + + anchors.top: parent.top + anchors.topMargin: style.cellMargin + anchors.horizontalCenter: parent.horizontalCenter + + width: itemLibraryIconWidth + height: itemLibraryIconHeight + pixmap: itemPixmap + } + + Text { + id: text + + anchors.top: itemIcon.bottom + anchors.topMargin: itemView.style.cellSpacing + anchors.horizontalCenter: parent.horizontalCenter + width: style.textWidth + height: style.textHeight + + verticalAlignment: "AlignVCenter" + horizontalAlignment: "AlignHCenter" + text: itemName + // workaround: text color not updated when 'style' var finally assigned + color: style.itemNameTextColor + Component.onCompleted: text.color = style.itemNameTextColor + } + + MouseRegion { + id: mouseRegion + anchors.fill: parent + + onPositionChanged: { + itemDragged(); + } + onClicked: { + itemClicked(); + } + } +} + diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml new file mode 100644 index 0000000000000000000000000000000000000000..6b38d94d78f2beece2a8497d318adbbe263a064a --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml @@ -0,0 +1,144 @@ +import Qt 4.6 + +/* + ListModel { + id: libraryModel + ListElement { + sectionTitle: "Section 1" + sectionEntries: [ + ListElement { itemLibId: 0; itemName: "Comp"; itemIconPath: "../images/default-icon.png" }, + ... + ] + } + ... + } +*/ + +/* workaround: ListView reports bogus viewportHeight + +ListView { + id: itemsView + + property string name: "itemsFlickable" + anchors.fill: parent + + interactive: false + + model: itemsView.model + delegate: sectionDelegate +} +*/ + + +Rectangle { + id: itemsView + + signal itemSelected(int itemLibId) + signal itemDragged(int itemLibId) + + function expandAll() { + expandAllEntries(); + scrollbar.handleBar.y = 0; + } + + signal expandAllEntries() + + property int entriesPerRow: Math.max(1, Math.floor((itemsFlickable.width - 2) / style.cellWidth)) + property int cellWidth: Math.floor((itemsFlickable.width - 2) / entriesPerRow) + property int cellHeight: style.cellHeight + + property var style + style: ItemsViewStyle {} + + color: style.backgroundColor + + /* workaround: without this, a completed drag and drop operation would + result in the drag being continued when QmlView re-gains + focus */ + signal stopDragAndDrop + MouseRegion { + anchors.fill: parent + hoverEnabled: true + onEntered: if (!pressed) itemsView.stopDragAndDrop + } + + Component { + id: sectionDelegate + + SectionView { + id: section + style: itemsView.style + + entriesPerRow: itemsView.entriesPerRow + cellWidth: itemsView.cellWidth + cellHeight: itemsView.cellHeight + + width: itemsFlickable.width + itemHighlight: selector + + onItemSelected: itemsView.itemSelected(itemLibId) + onItemDragged: itemsView.itemDragged(itemLibId) + + function focusSelection() { + itemSelection.focusSelection() + } + + Connection { + sender: itemsView + signal: "expandAllEntries()" + script: section.expand() + } + } + } + + Flickable { + id: itemsFlickable + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: scrollbar.left + anchors.rightMargin: 6 + clip: true + + interactive: false + viewportHeight: col.height + + onViewportHeightChanged: scrollbar.limitHandle() + + Column { + id: col + + Repeater { + model: itemLibraryModel + delegate: sectionDelegate + } + } + + Selector { + id: selector + z: -1 + style: itemsView.style + scrollFlickable: itemsFlickable + + onMoveScrollbarHandle: scrollbar.moveHandle(viewportPos) + + width: itemsView.cellWidth + height: itemsView.cellHeight + } + } + + Scrollbar { + id: scrollbar + + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.right + anchors.leftMargin: -10 + anchors.right: parent.right + + scrollFlickable: itemsFlickable + style: itemsView.style + } +} + diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml new file mode 100644 index 0000000000000000000000000000000000000000..b31e8c58033a9ddce2700b865677862b3b51ccb7 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml @@ -0,0 +1,34 @@ +import Qt 4.6 + +Item { + property string backgroundColor: "#707070" + property string raisedBackgroundColor: "#e0e0e0" + + property string scrollbarBackgroundColor: "#505050" + property string scrollbarHandleColor: "#303030" + + property string itemNameTextColor: "#c0c0c0" + + property string sectionTitleTextColor: "#f0f0f0" + property string sectionTitleBackgroundColor: "#909090" + + property string gridLineColor: "#a0a0a0" + + property int sectionTitleHeight: 20 + property int sectionTitleSpacing: 2 + + property int selectionSectionOffset: sectionTitleHeight + sectionTitleSpacing + + property int iconWidth: 32 + property int iconHeight: 32 + + property int textWidth: 80 + property int textHeight: 15 + + property int cellSpacing: 7 + property int cellMargin: 10 + + property int cellWidth: textWidth + 2*cellMargin + property int cellHeight: itemLibraryIconHeight + textHeight + 2*cellMargin + cellSpacing +} + diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml new file mode 100644 index 0000000000000000000000000000000000000000..cff81189a156a39c562c5481effe6b5e221ea32d --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml @@ -0,0 +1,151 @@ +import Qt 4.6 + +Item { + id: bar + + property var handleBar: handle + + property var scrollFlickable + property var style + + property bool scrolling: (scrollFlickable.viewportHeight > scrollFlickable.height) + property int scrollHeight: height - handle.height + + Binding { + target: scrollFlickable + property: "viewportY" + value: Math.max(0, scrollFlickable.viewportHeight - scrollFlickable.height) * + handle.y / scrollHeight + } + + Rectangle { + anchors.fill: parent; + anchors.rightMargin: 1 + anchors.bottomMargin: 1 + color: "transparent" + border.width: 1; + border.color: "#8F8F8F"; + } + + function moveHandle(viewportPos) { + var pos; + + if (bar.scrollFlickable) {//.visibleArea.yPosition) { + pos = bar.scrollHeight * viewportPos / (bar.scrollFlickable.viewportHeight - bar.scrollFlickable.height); + } else + pos = 0; + +// handleMoveAnimation.to = Math.min(bar.scrollHeight, pos) +// handleMoveAnimation.start(); + handle.y = Math.min(bar.scrollHeight, pos) + } + + function limitHandle() { + // the following "if" is needed to get around NaN when starting up + if (scrollFlickable) + handle.y = Math.min(handle.height * scrollFlickable.visibleArea.yPosition, + scrollHeight); + else + handle.y = 0; + } +/* + NumberAnimation { + id: handleResetAnimation + target: handle + property: "y" + from: handle.y + to: 0 + duration: 500 + } +*/ + Connection { + sender: scrollFlickable + signal: "heightChanged" + script: { + /* since binding loops prevent setting the handle properly, + let's animate it to 0 */ + if (scrollFlickable.viewportY > (scrollFlickable.viewportHeight - scrollFlickable.height)) +// handleResetAnimation.start() + handle.y = 0 + } + } + + onScrollFlickableChanged: handle.y = 0 + +/* + Rectangle { + anchors.fill: parent + anchors.leftMargin: 3 + anchors.rightMargin: 3 + anchors.topMargin: 2 + anchors.bottomMargin: 2 + radius: width / 2 + color: style.scrollbarBackgroundColor + } +*/ + MouseRegion { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: parent.top + anchors.bottom: handle.top + onClicked: { +// handleMoveAnimation.to = Math.max(0, handle.y - 40) +// handleMoveAnimation.start(); + handle.y = Math.max(0, handle.y - 40) + } + } + + Item { + id: handle + + anchors.left: parent.left + anchors.right: parent.right + height: Math.max(width, bar.height * Math.min(1, scrollFlickable.visibleArea.heightRatio)) + +// radius: width / 2 +// color: style.scrollbarHandleColor + + Rectangle { + width: parent.height + height: parent.width + y: parent.height + + rotation: -90 + transformOrigin: Item.TopLeft + + gradient: Gradient { + GradientStop { position: 0.0; color: "#C6C6C6" } + GradientStop { position: 1.0; color: "#7E7E7E" } + } + } + + MouseRegion { + anchors.fill: parent + drag.target: parent + drag.axis: "YAxis" + drag.minimumY: 0 + drag.maximumY: scrollHeight + } + } + + MouseRegion { + anchors.left: parent.left + anchors.right: parent.right + anchors.top: handle.bottom + anchors.bottom: parent.bottom + onClicked: { +// handleMoveAnimation.to = Math.min(scrollHeight, handle.y + 40) +// handleMoveAnimation.start(); + handle.y = Math.min(scrollHeight, handle.y + 40) + } + } +/* + NumberAnimation { + id: handleMoveAnimation + target: handle + property: "y" + duration: 200 + } +*/ +} + diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml new file mode 100644 index 0000000000000000000000000000000000000000..792ee332977d54eaa52eccda2fa8e5c1c9fc3bf9 --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml @@ -0,0 +1,151 @@ +import Qt 4.6 + +Column { + id: sectionView + + property var style + property var itemHighlight + + property int entriesPerRow + property int cellWidth + property int cellHeight + + signal itemSelected(int itemLibId) + signal itemDragged(int itemLibId) + + function expand() { + gridFrame.state = ""; + } + + Component { + id: itemDelegate + + ItemView { + id: item + style: sectionView.style + + function selectItem() { + itemHighlight.select(sectionView, item, gridFrame.x, -gridView.viewportY); + sectionView.itemSelected(itemLibId); + } + + onItemClicked: selectItem() + onItemDragged: { + selectItem(); + sectionView.itemDragged(itemLibId); + } + } + } + + Rectangle { + width: parent.width + height: style.sectionTitleHeight + + color: style.sectionTitleBackgroundColor + radius: 2 + + Item { + id: arrow + + Rectangle { y: 0; x: 0; height: 1; width: 9; color: "#aeaeae" } + Rectangle { y: 1; x: 1; height: 1; width: 7; color: "#aeaeae" } + Rectangle { y: 2; x: 2; height: 1; width: 5; color: "#aeaeae" } + Rectangle { y: 3; x: 3; height: 1; width: 3; color: "#aeaeae" } + Rectangle { y: 4; x: 4; height: 1; width: 1; color: "#aeaeae" } + + anchors.left: parent.left + anchors.leftMargin: 5 + anchors.verticalCenter: parent.verticalCenter + width: 9 + height: 5 + + transformOrigin: Item.Center + } + Text { + id: text + + anchors.verticalCenter: parent.verticalCenter + anchors.left: arrow.right + anchors.leftMargin: 5 + + text: sectionName + color: style.sectionTitleTextColor + Component.onCompleted: text.color = style.sectionTitleTextColor + } + MouseRegion { + anchors.fill: parent + onClicked: { + if (itemHighlight.visible && + (itemHighlight.section == sectionView)) { + itemHighlight.unselect(); + sectionView.itemSelected(-1); + } + gridFrame.toggleVisibility() + } + } + } + + Item { height: 2; width: 1 } + + Item { + id: gridFrame + + function toggleVisibility() { + state = ((state == "hidden")? "":"hidden") + } + + clip: true + width: sectionView.entriesPerRow * sectionView.cellWidth + 1 + height: Math.ceil(sectionEntries.count / sectionView.entriesPerRow) * sectionView.cellHeight + 1 + anchors.horizontalCenter: parent.horizontalCenter + + GridView { + id: gridView + + Connection { + sender: itemLibraryModel + signal: "visibilityUpdated()" + script: gridView.positionViewAtIndex(0) + } + + anchors.fill: parent + anchors.rightMargin: 1 + anchors.bottomMargin: 1 + + cellWidth: sectionView.cellWidth + cellHeight: sectionView.cellHeight + model: sectionEntries + delegate: itemDelegate + interactive: false + highlightFollowsCurrentItem: false + } + + states: [ + State { + name: "hidden" + PropertyChanges { + target: gridFrame + height: 0 + opacity: 0 + } + PropertyChanges { + target: arrow + rotation: -90 + } + } + ] +/* + transitions: [ + Transition { + NumberAnimation { + matchProperties: "x,y,width,height,opacity,rotation" + duration: 200 + } + } + ] +*/ + } + + Item { height: 4; width: 1 } +} + diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml new file mode 100644 index 0000000000000000000000000000000000000000..3de5a29a523ef8d96fac9bb941284bd0c9afda5d --- /dev/null +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml @@ -0,0 +1,140 @@ +import Qt 4.6 + +Item { + id: selector + + property var style + property var scrollFlickable + + signal moveScrollbarHandle(int viewportPos) + + visible: false + + property var section: null + property var item: null + property int sectionXOffset: 0 + property int sectionYOffset: 0 + + property real staticX: (section && item)? (section.x + item.x + sectionXOffset):0; + property real staticY: (section && item)? (section.y + style.selectionSectionOffset + item.y + sectionYOffset):0; + + property bool animateMove: true + + Connection { + sender: itemLibraryModel + signal: "visibilityUpdated()" + script: selector.unselectNow() + } + + function select(section, item, sectionXOffset, sectionYOffset) { + + if (!selector.visible) { + selector.animateMove = false + } + + selector.item = item + selector.section = section + selector.sectionXOffset = sectionXOffset + selector.sectionYOffset = sectionYOffset + + if (!selector.visible) { +// print("no prev selection"); + +// selector.opacity = 0 + selector.visible = true +// selectAnimation.start(); + } + + focusSelection(); + } + + function focusSelection() { + var pos = -1; + + if (selector.staticY < scrollFlickable.viewportY) + pos = selector.staticY + else if ((selector.staticY + selector.height) > + (scrollFlickable.viewportY + scrollFlickable.height - 1)) + pos = selector.staticY + selector.height - scrollFlickable.height + 1 + + if (pos >= 0) { +/* + followSelectionAnimation.to = pos + followSelectionAnimation.start() +*/ + scrollFlickable.viewportY = pos; + selector.moveScrollbarHandle(pos) + } + } + + function unselect() { +// unselectAnimation.start(); + unselectNow(); + } + + function unselectNow() { + selector.section = null + selector.item = null + selector.sectionXOffset = 0 + selector.sectionYOffset = 0 + selector.visible = false + selector.opacity = 1 + } +/* + NumberAnimation { + id: selectAnimation + target: selector + property: "opacity" + from: 0 + to: 1 + duration: 200 + onRunningChanged: { + if (!running) + selector.animateMove = true + } + } + + NumberAnimation { + id: unselectAnimation + target: selector + property: "opacity" + from: 1 + to: 0 + duration: 150 + onRunningChanged: { + if (!running) + selector.unselectNow(); + } + } + + NumberAnimation { + id: followSelectionAnimation + target: scrollFlickable + property: "viewportY" + duration: 200 + } + + x: SpringFollow { + source: selector.staticX; + spring: selector.animateMove? 3.0:0.0; + damping: 0.35 + epsilon: 0.25 + } + + y: SpringFollow { + source: selector.staticY; + spring: selector.animateMove? 3.0:0.0; + damping: 0.35 + epsilon: 0.25 + } +*/ + + x: selector.staticX + y: selector.staticY + + Rectangle { + anchors.fill: parent + color: "steelblue" + } +} + diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreeview.h b/src/plugins/qmldesigner/components/navigator/navigatortreeview.h index 495f00f00ad9661927b85685da87b40edb0e07fd..1d640a1f42dac24877733ca4f44f57d9c1601dce 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreeview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatortreeview.h @@ -37,10 +37,12 @@ #include <QPainter> +QT_BEGIN_NAMESPACE class QTreeView; class QStandardItem; class QItemSelection; class QModelIndex; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index fa8b3b8530ad4f022b9405d6886472f061e21e1e..7a2315dc5263028a4de80c3d3455d470aaa38efe 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -34,10 +34,12 @@ #include <QWeakPointer> +QT_BEGIN_NAMESPACE class QTreeView; class QStandardItem; class QItemSelection; class QModelIndex; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/pluginmanager/iplugin.h b/src/plugins/qmldesigner/components/pluginmanager/iplugin.h index 4c2dd453150f755b3fa7d9b301c4e7f5b58a978c..7f81eb405fd2859af578eee80dc36ad00813961f 100644 --- a/src/plugins/qmldesigner/components/pluginmanager/iplugin.h +++ b/src/plugins/qmldesigner/components/pluginmanager/iplugin.h @@ -51,6 +51,8 @@ public: } // namespace QmlDesigner +QT_BEGIN_NAMESPACE Q_DECLARE_INTERFACE(QmlDesigner::IPlugin, QMLDESIGNER_PLUGIN_INTERFACE) +QT_END_NAMESPACE #endif // IPLUGIN_H diff --git a/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h b/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h index 62afc2c5a58d79aa448dab39e62edcab38055005..dae4e9264fa964f100473f25ef39f3453a812523 100644 --- a/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h +++ b/src/plugins/qmldesigner/components/pluginmanager/pluginmanager.h @@ -34,9 +34,11 @@ #include <QtCore/QObject> #include <QtCore/QList> +QT_BEGIN_NAMESPACE class QString; class QAbstractItemModel; class QDialog; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/propertyeditor/basiclayouts.h b/src/plugins/qmldesigner/components/propertyeditor/basiclayouts.h index 9fe36c2d8f138f8a8aca38daf90aa1fb446e2376..527059dd3a63441acc0fc7e7c95c9d173c250822 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/basiclayouts.h +++ b/src/plugins/qmldesigner/components/propertyeditor/basiclayouts.h @@ -160,7 +160,6 @@ private: int mTop, mLeft, mBottom, mRight; }; -QML_DECLARE_TYPE(QBoxLayoutObject); class QHBoxLayoutObject : public QBoxLayoutObject { @@ -168,7 +167,6 @@ Q_OBJECT public: QHBoxLayoutObject(QObject *parent=0); }; -QML_DECLARE_TYPE(QHBoxLayoutObject); class QVBoxLayoutObject : public QBoxLayoutObject { @@ -176,11 +174,14 @@ Q_OBJECT public: QVBoxLayoutObject(QObject *parent=0); }; -QML_DECLARE_TYPE(QVBoxLayoutObject); #endif // BASICLAYOUTS_H QT_END_NAMESPACE +QML_DECLARE_TYPE(QBoxLayoutObject); +QML_DECLARE_TYPE(QHBoxLayoutObject); +QML_DECLARE_TYPE(QVBoxLayoutObject); + QT_END_HEADER diff --git a/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.cpp b/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.cpp index acf77eda89b45a568de346655c07aa900fd7f87f..3ffdc18a9558a2146467f5f2650572ad0ff3f9ad 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.cpp @@ -1109,9 +1109,6 @@ void QGroupBoxDeclarativeUI::animate(int frame) gb->update(); } -QML_DECLARE_TYPE(QTabObject); -QML_DEFINE_TYPE(Qt,4,6,QTabObject,QTabObject); //### with namespacing, this should just be 'Tab' - class QTabWidgetDeclarativeUI : public QObject { Q_OBJECT @@ -1171,6 +1168,8 @@ public: {} }; +QT_END_NAMESPACE + QML_DEFINE_EXTENDED_TYPE(Bauhaus,1,0,QWidget,QWidget,QWidgetDeclarativeUI); //display @@ -1230,7 +1229,7 @@ QML_DEFINE_EXTENDED_TYPE(Bauhaus,1,0,QMenu,QMenu, QMenuDeclarativeUI) //QML_DEFINE_TYPE(Bauhaus,1,0,BauhausreeView,BauhausreeView); //QML_DEFINE_TYPE(Bauhaus,1,0,BauhausableView,BauhausableView); +QML_DECLARE_TYPE(QTabObject); +QML_DEFINE_TYPE(Qt,4,6,QTabObject,QTabObject); //### with namespacing, this should just be 'Tab' #include "basicwidgets.moc" - -QT_END_NAMESPACE diff --git a/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.h b/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.h index 46dccf1c2c75cc668296554363734f5aa9e16a46..b44eac30f586a8483e08d4847d5855ff75ca3687 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.h +++ b/src/plugins/qmldesigner/components/propertyeditor/basicwidgets.h @@ -57,9 +57,6 @@ #include "filewidget.h" #include "layoutwidget.h" - -QT_BEGIN_NAMESPACE - QML_DECLARE_TYPE(QWidget); //display @@ -97,12 +94,16 @@ QML_DECLARE_TYPE(QTabWidget); QML_DECLARE_TYPE(FileWidget); QML_DECLARE_TYPE(LayoutWidget); +QT_BEGIN_NAMESPACE + class Action : public QAction { Q_OBJECT public: Action(QObject *parent = 0) : QAction(parent) {} }; +QT_END_NAMESPACE + QML_DECLARE_TYPE(QMenu); QML_DECLARE_TYPE(Action); @@ -115,6 +116,4 @@ QML_DECLARE_TYPE(Action); //top-level windows? - -QT_END_NAMESPACE #endif // BASICWIDGETS_H diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h index ad316b8b1d9eef50c69d11be6d48452a0ee9da3c..51e317981fa18e57c9b9b82e0bb6f3e2349d22be 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h +++ b/src/plugins/qmldesigner/components/propertyeditor/colorwidget.h @@ -39,9 +39,10 @@ #include <qml.h> #include <propertyeditorvalue.h> - +QT_BEGIN_NAMESPACE class QtColorButton; class QToolButton; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/propertyeditor/fontwidget.h b/src/plugins/qmldesigner/components/propertyeditor/fontwidget.h index 5bc8afbf82130c04c520dc4e5816416ece0c75be..d04e5e4e332dd7c40d28d7afbfcd65c8105d2209 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/fontwidget.h +++ b/src/plugins/qmldesigner/components/propertyeditor/fontwidget.h @@ -35,10 +35,11 @@ #include <qml.h> - +QT_BEGIN_NAMESPACE class QLabel; class QPushButton; class QFontDialog; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp index cdb4b6708582dc6da47b3ff69eeb72b2e2a42af3..67937e7a1edcdd5b6de774859f99766ad49e217c 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.cpp @@ -351,54 +351,36 @@ void PropertyEditor::changeExpression(const QString &name) } } -void PropertyEditor::anyPropertyChanged(const QmlObjectNode &fxObjectNode) +void PropertyEditor::otherPropertyChanged(const QmlObjectNode &fxObjectNode, const QString &propertyName) { + QmlModelView::otherPropertyChanged(fxObjectNode, propertyName); + if (fxObjectNode.isValid() && m_currentType && fxObjectNode == m_selectedNode && fxObjectNode.currentState().isValid()) { - foreach (const QString &propertyName, fxObjectNode.modelNode().metaInfo().properties(true).keys()) { - if ( propertyName != "id" && propertyName != "objectName") { - AbstractProperty property = fxObjectNode.modelNode().property(propertyName); - if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) { - if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName)) - m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name())); - else - m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name())); - } - } + AbstractProperty property = fxObjectNode.modelNode().property(propertyName); + if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) { + if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName)) + m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name())); + else + m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name())); } } } -void PropertyEditor::geometryPropertyChanged(const QmlObjectNode &fxObjectNode) +void PropertyEditor::transformChanged(const QmlObjectNode &fxObjectNode, const QString &propertyName) { + QmlModelView::transformChanged(fxObjectNode, propertyName); + if (fxObjectNode.isValid() && m_currentType && fxObjectNode == m_selectedNode && fxObjectNode.currentState().isValid()) { - QStringList geometryProperties; - geometryProperties << "x" << "y" << "width" << "height" << "rotation" << "scale"; - foreach (const QString &propertyName, geometryProperties) { - if ( propertyName != "id" && propertyName != "objectName") { - AbstractProperty property = fxObjectNode.modelNode().property(propertyName); - if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) { - if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName)) - m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name())); - else - m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name())); - } - } + AbstractProperty property = fxObjectNode.modelNode().property(propertyName); + if (fxObjectNode == m_selectedNode || QmlObjectNode(m_selectedNode).propertyChangeForCurrentState() == fxObjectNode) { + if ( m_selectedNode.property(property.name()).isBindingProperty() || !m_selectedNode.hasProperty(propertyName)) + m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).instanceValue(property.name())); + else + m_currentType->setValue(m_selectedNode, property.name(), QmlObjectNode(m_selectedNode).modelValue(property.name())); } } } -void PropertyEditor::otherPropertyChanged(const QmlObjectNode &fxObjectNode) -{ - QmlModelView::otherPropertyChanged(fxObjectNode); - anyPropertyChanged(fxObjectNode); -} - -void PropertyEditor::transformChanged(const QmlObjectNode &fxObjectNode) -{ - QmlModelView::transformChanged(fxObjectNode); - geometryPropertyChanged(fxObjectNode); -} - void PropertyEditor::setQmlDir(const QString &qmlDir) { m_qmlDir = qmlDir; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h index 5e6f4851437cd73cb2f758991b85767f948e8d38..1a8ab492e0128f27e32b5c37cc28e7a13b36fa43 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditor.h @@ -37,8 +37,10 @@ #include "qmlanchorbindingproxy.h" +QT_BEGIN_NAMESPACE class QShortcut; class QStackedWidget; +QT_END_NAMESPACE namespace QmlDesigner { @@ -84,10 +86,6 @@ public: - void anyPropertyChanged(const QmlObjectNode &qmlObjectNode); - void geometryPropertyChanged(const QmlObjectNode &fxObjectNode); - - void propertiesAboutToBeRemoved(const QList<AbstractProperty>& propertyList); void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange); @@ -97,8 +95,8 @@ public: protected: void timerEvent(QTimerEvent *event); - void otherPropertyChanged(const QmlObjectNode &); - void transformChanged(const QmlObjectNode &qmlObjectNode); + void otherPropertyChanged(const QmlObjectNode &, const QString &propertyName); + void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName); void setupPane(const QString &typeName); void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState); diff --git a/src/plugins/qmldesigner/components/propertyeditor/qlayoutobject.h b/src/plugins/qmldesigner/components/propertyeditor/qlayoutobject.h index edb3257147d7b4b4c8cfda93e423794a98aeb01d..13b79862b468e4b61577714ce9d18f16617d8734 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qlayoutobject.h +++ b/src/plugins/qmldesigner/components/propertyeditor/qlayoutobject.h @@ -48,11 +48,11 @@ public: virtual QLayout *layout() const; }; -QML_DECLARE_TYPE(QLayoutObject); - -#endif // QLAYOUTOBJECT_H - QT_END_NAMESPACE +QML_DECLARE_TYPE(QLayoutObject); + QT_END_HEADER + +#endif // QLAYOUTOBJECT_H diff --git a/src/plugins/qmldesigner/components/propertyeditor/qproxylayoutitem.h b/src/plugins/qmldesigner/components/propertyeditor/qproxylayoutitem.h index d4c57de32b3c55349bdd1b5754c613b6ee8de605..f511489e8048affe7426e86ee48274abbaa26949 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qproxylayoutitem.h +++ b/src/plugins/qmldesigner/components/propertyeditor/qproxylayoutitem.h @@ -63,7 +63,6 @@ private: QRectF geometry; QGraphicsLayout *proxy; }; -QML_DECLARE_TYPE(QProxyLayout); class QProxyLayoutItem : public QObject, public QGraphicsLayoutItem { @@ -87,10 +86,12 @@ private: QRectF geometry; QGraphicsLayoutItem *other; }; -QML_DECLARE_TYPE(QProxyLayoutItem); #endif // QPROXYLAYOUTITEM_H QT_END_NAMESPACE +QML_DECLARE_TYPE(QProxyLayout); +QML_DECLARE_TYPE(QProxyLayoutItem); + QT_END_HEADER diff --git a/src/plugins/qmldesigner/components/propertyeditor/resetwidget.h b/src/plugins/qmldesigner/components/propertyeditor/resetwidget.h index ddc4c5c1de934c2a90682cf900f4c823b5dbd979..4956c9599857924358325d8d0eafe73dc4747e79 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/resetwidget.h +++ b/src/plugins/qmldesigner/components/propertyeditor/resetwidget.h @@ -33,9 +33,11 @@ #include <QtGui/QGroupBox> #include <QtGui/QPushButton> +QT_BEGIN_NAMESPACE class QListWidget; class QVBoxLayout; class QTableWidget; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index e84a37ad142cdd068bc699f7cf49db8c955bfbe1..0477e9b374b278f0a1b6dcfb6ca491fbcdd6bac7 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -52,13 +52,6 @@ StatesEditorView::StatesEditorView(StatesEditorModel *editorModel, QObject *pare m_editorModel(editorModel) { Q_ASSERT(m_editorModel); - - - connect(nodeInstanceView(), SIGNAL(instanceRemoved(NodeInstance)), this, SLOT(sceneChanged())); - connect(nodeInstanceView(), SIGNAL(transformPropertyChanged(NodeInstance)), this, SLOT(sceneChanged())); - connect(nodeInstanceView(), SIGNAL(parentPropertyChanged(NodeInstance)), this, SLOT(sceneChanged())); - connect(nodeInstanceView(), SIGNAL(otherPropertyChanged(NodeInstance)), this, SLOT(sceneChanged())); - connect(nodeInstanceView(), SIGNAL(updateItem(NodeInstance)), this, SLOT(sceneChanged())); } void StatesEditorView::setCurrentStateSilent(int index) @@ -304,9 +297,9 @@ void StatesEditorView::stateChanged(const QmlModelState &newQmlModelState, const m_editorModel->emitChangedToState(m_modelStates.indexOf(newQmlModelState)); } -void StatesEditorView::transformChanged(const QmlObjectNode &qmlObjectNode) +void StatesEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName) { - QmlModelView::transformChanged(qmlObjectNode); + QmlModelView::transformChanged(qmlObjectNode, propertyName); } void StatesEditorView::parentChanged(const QmlObjectNode &qmlObjectNode) @@ -314,15 +307,11 @@ void StatesEditorView::parentChanged(const QmlObjectNode &qmlObjectNode) QmlModelView::parentChanged(qmlObjectNode); } -void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode) +void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName) { - QmlModelView::otherPropertyChanged(qmlObjectNode); + QmlModelView::otherPropertyChanged(qmlObjectNode, propertyName); } -void StatesEditorView::updateItem(const QmlObjectNode &qmlObjectNode) -{ - QmlModelView::updateItem(qmlObjectNode); -} void StatesEditorView::customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data) { diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index e24599e7aaddb75d2aa40087ef2a2159020647af..ad0ef56d7d28c5bab1976843ffa8bf1c14137f1f 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -69,10 +69,9 @@ protected: // QmlModelView void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState); - void transformChanged(const QmlObjectNode &qmlObjectNode) ; + void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName); void parentChanged(const QmlObjectNode &qmlObjectNode); - void otherPropertyChanged(const QmlObjectNode &qmlObjectNode); - void updateItem(const QmlObjectNode &qmlObjectNode); + void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName); void customNotification(const AbstractView *view, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> &data); diff --git a/src/plugins/qmldesigner/core/core.pri b/src/plugins/qmldesigner/core/core.pri index 948cf2e70e85fdece2650b255315fa0916659c94..9ee99b3470da12c30f82efbb32a8816d7b71a7b9 100644 --- a/src/plugins/qmldesigner/core/core.pri +++ b/src/plugins/qmldesigner/core/core.pri @@ -94,7 +94,8 @@ SOURCES += $$PWD/model/abstractview.cpp \ $$PWD/instances/qmltransitionnodeinstance.cpp \ $$PWD/exceptions/rewritingexception.cpp \ $$PWD/instances/nodeinstancemetaobject.cpp \ - $$PWD/instances/behaviornodeinstance.cpp + $$PWD/instances/behaviornodeinstance.cpp \ + $$PWD/instances/nodeinstancesignalspy.cpp HEADERS += $$PWD/include/corelib_global.h \ $$PWD/include/abstractview.h \ $$PWD/include/nodeinstanceview.h \ @@ -185,7 +186,8 @@ HEADERS += $$PWD/include/corelib_global.h \ $$PWD/include/customnotifications.h \ $$PWD/include/rewritingexception.h \ $$PWD/instances/nodeinstancemetaobject.h \ - $$PWD/instances/behaviornodeinstance.h + $$PWD/instances/behaviornodeinstance.h \ + $$PWD/instances/nodeinstancesignalspy.h DISTFILES += $$PWD/metafile/widget.metafile RESOURCES += $$PWD/core.qrc OTHER_FILES += $$PWD/metainfo/gui.metainfo diff --git a/src/plugins/qmldesigner/core/include/abstractproperty.h b/src/plugins/qmldesigner/core/include/abstractproperty.h index 3cd457bd683fbdda4b10a6c101e916305b737ed0..6ed24496dc7085aa02fc3895507f93c7b798d317 100644 --- a/src/plugins/qmldesigner/core/include/abstractproperty.h +++ b/src/plugins/qmldesigner/core/include/abstractproperty.h @@ -35,7 +35,9 @@ #include <QSharedPointer> #include "corelib_global.h" +QT_BEGIN_NAMESPACE class QTextStream; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/core/include/abstractview.h b/src/plugins/qmldesigner/core/include/abstractview.h index 45c813b181817fd78760ef3d899457c95d02bd8c..6a17fddfe9487ac798e2a88b06d7fe6b822263f5 100644 --- a/src/plugins/qmldesigner/core/include/abstractview.h +++ b/src/plugins/qmldesigner/core/include/abstractview.h @@ -39,7 +39,9 @@ #include <QObject> +QT_BEGIN_NAMESPACE class QStyle; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/core/include/iwidgetplugin.h b/src/plugins/qmldesigner/core/include/iwidgetplugin.h index c151aaa948c74576ccf2a6e1152b64db9b1b830d..3a0166bba63e2a4749dbbccfdc932675af5ca065 100644 --- a/src/plugins/qmldesigner/core/include/iwidgetplugin.h +++ b/src/plugins/qmldesigner/core/include/iwidgetplugin.h @@ -47,6 +47,8 @@ public: } // namespace QmlDesigner +QT_BEGIN_NAMESPACE Q_DECLARE_INTERFACE(QmlDesigner::IWidgetPlugin, QMLDESIGNER_WIDGETPLUGIN_INTERFACE) +QT_END_NAMESPACE #endif // IWIDGETPLUGIN_H diff --git a/src/plugins/qmldesigner/core/include/model.h b/src/plugins/qmldesigner/core/include/model.h index e4ebc81954f8772275e6facbfaf23173bf31b91f..42dd7cc7b550da075761f425f792eb6d3d637d7a 100644 --- a/src/plugins/qmldesigner/core/include/model.h +++ b/src/plugins/qmldesigner/core/include/model.h @@ -38,7 +38,9 @@ #include <import.h> +QT_BEGIN_NAMESPACE class QUrl; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/core/include/modelnode.h b/src/plugins/qmldesigner/core/include/modelnode.h index 64164a7e20343c75e034978f235cfb3dc7841a2c..b62ab780c9e00e2f9d60e7f8565e5f62ff462799 100644 --- a/src/plugins/qmldesigner/core/include/modelnode.h +++ b/src/plugins/qmldesigner/core/include/modelnode.h @@ -36,7 +36,9 @@ #include <QtCore/QMetaType> #include <QVariant> +QT_BEGIN_NAMESPACE class QTextStream; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/core/include/nodeinstance.h b/src/plugins/qmldesigner/core/include/nodeinstance.h index 496007c3bd8eaef2792385084d081a4ddc006fcd..45734ab6ccb3ee1415851a1f388624233cfe45e5 100644 --- a/src/plugins/qmldesigner/core/include/nodeinstance.h +++ b/src/plugins/qmldesigner/core/include/nodeinstance.h @@ -37,11 +37,13 @@ #include <propertymetainfo.h> #include <qmlanchors.h> +QT_BEGIN_NAMESPACE class QPainter; class QStyleOptionGraphicsItem; class QmlContext; class QGraphicsItem; class QGraphicsTransform; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/core/include/nodeinstanceview.h b/src/plugins/qmldesigner/core/include/nodeinstanceview.h index a97d7bf364e304ed1eaab59a64a3f0432c5acfa8..c68c11b8c782c10f17c8ce6847e35dce364e9f20 100644 --- a/src/plugins/qmldesigner/core/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/core/include/nodeinstanceview.h @@ -41,9 +41,11 @@ #include <modelnode.h> #include <nodeinstance.h> +QT_BEGIN_NAMESPACE class QmlEngine; class QGraphicsScene; class QGraphicsView; +QT_END_NAMESPACE namespace QmlDesigner { @@ -107,18 +109,16 @@ public: QRectF sceneRect() const; void setBlockChangeSignal(bool block); + void notifyPropertyChange(const ModelNode &modelNode, const QString &propertyName); + + void setQmlModelView(QmlModelView *qmlModelView); + QmlModelView *qmlModelView() const ; + signals: void instanceRemoved(const NodeInstance &nodeInstance); - void transformPropertyChanged(const NodeInstance &nodeInstance); - void parentPropertyChanged(const NodeInstance &nodeInstance); - void otherPropertyChanged(const NodeInstance &nodeInstance); - void updateItem(const NodeInstance &nodeInstance); private slots: - void emitOtherPropertyChanged(); - void emitParentPropertyChanged(); - void emitTransformPropertyChanged(); - void emitUpdateItem(QObject *object); + void emitParentChanged(QObject *child); private: // functions NodeInstance loadNode(const ModelNode &rootNode, QObject *objectToBeWrapped = 0); @@ -145,6 +145,8 @@ private: //variables QWeakPointer<QmlEngine> m_engine; QWeakPointer<Internal::ChildrenChangeEventFilter> m_childrenChangeEventFilter; + QWeakPointer<QmlModelView> m_qmlModelView; + bool m_blockChangeSignal; }; diff --git a/src/plugins/qmldesigner/core/include/nodemetainfo.h b/src/plugins/qmldesigner/core/include/nodemetainfo.h index 7b80ef07072b67469d7cfa09e8bba68c8045358c..bf1a9313245ec213b2343bc5c58bccc8fca42000 100644 --- a/src/plugins/qmldesigner/core/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/core/include/nodemetainfo.h @@ -38,7 +38,9 @@ #include "corelib_global.h" #include "invalidmetainfoexception.h" +QT_BEGIN_NAMESPACE class QmlContext; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/core/include/qmlmodelview.h b/src/plugins/qmldesigner/core/include/qmlmodelview.h index 4aacd47eefa97978cee4cc994112446d3d0ed485..ff236d9aa5cd6f20419856b0b3e434a2d707ec1a 100644 --- a/src/plugins/qmldesigner/core/include/qmlmodelview.h +++ b/src/plugins/qmldesigner/core/include/qmlmodelview.h @@ -88,22 +88,17 @@ public: void modelAttached(Model *model); void modelAboutToBeDetached(Model *model); + virtual void nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName); + protected: NodeInstance instanceForModelNode(const ModelNode &modelNode); bool hasInstanceForModelNode(const ModelNode &modelNode); NodeInstanceView *nodeInstanceView() const; - virtual void transformChanged(const QmlObjectNode &qmlObjectNode) ; + virtual void transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName) ; virtual void parentChanged(const QmlObjectNode &qmlObjectNode); - virtual void otherPropertyChanged(const QmlObjectNode &qmlObjectNode); + virtual void otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName); virtual void stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState); - virtual void updateItem(const QmlObjectNode &qmlObjectNode); - -private slots: - void notifyTransformChanged(const NodeInstance &nodeInstance); - void notifyParentChanged(const NodeInstance &nodeInstance); - void notifyOtherPropertyChanged(const NodeInstance &nodeInstance); - void notifyUpdateItem(const NodeInstance &nodeInstance); private: QmlModelState m_state; diff --git a/src/plugins/qmldesigner/core/include/variantproperty.h b/src/plugins/qmldesigner/core/include/variantproperty.h index 76a93c5662ca4f301431bd21569a83427acef49d..58c55de5e47c997cbf9d7bd377e517f72f34a990 100644 --- a/src/plugins/qmldesigner/core/include/variantproperty.h +++ b/src/plugins/qmldesigner/core/include/variantproperty.h @@ -33,6 +33,9 @@ #include "corelib_global.h" #include "abstractproperty.h" +QT_BEGIN_NAMESPACE +class QTextStream; +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/core/instances/componentnodeinstance.h b/src/plugins/qmldesigner/core/instances/componentnodeinstance.h index 4554e57ad51d8f1a396c49ab90b21927aa3ccf34..d5b751c18152c6f3763ccbca87e05054ff38aac4 100644 --- a/src/plugins/qmldesigner/core/instances/componentnodeinstance.h +++ b/src/plugins/qmldesigner/core/instances/componentnodeinstance.h @@ -32,7 +32,9 @@ #include "objectnodeinstance.h" +QT_BEGIN_NAMESPACE class QmlComponent; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/core/instances/graphicsobjectnodeinstance.h b/src/plugins/qmldesigner/core/instances/graphicsobjectnodeinstance.h index 797b064f674d655bc3ccb2d007913cd50ff7e729..24e2755d1819bf2352bde9dfd27c0a7570dfae24 100644 --- a/src/plugins/qmldesigner/core/instances/graphicsobjectnodeinstance.h +++ b/src/plugins/qmldesigner/core/instances/graphicsobjectnodeinstance.h @@ -32,7 +32,9 @@ #include "objectnodeinstance.h" +QT_BEGIN_NAMESPACE class QGraphicsObject; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/core/instances/nodeinstance.cpp b/src/plugins/qmldesigner/core/instances/nodeinstance.cpp index ffaa6a6cef38ed7b16922d23495020835ce4547e..ee3e7cfc6d5757ba7a0e40819a19472fdd2d5b0d 100644 --- a/src/plugins/qmldesigner/core/instances/nodeinstance.cpp +++ b/src/plugins/qmldesigner/core/instances/nodeinstance.cpp @@ -181,7 +181,9 @@ NodeInstance NodeInstance::create(NodeInstanceView *nodeInstanceView, const Mode instance.m_nodeInstance->setModelNode(node); - instance.m_nodeInstance->setNodeInstance(nodeInstanceView); + instance.m_nodeInstance->setNodeInstanceView(nodeInstanceView); + + instance.m_nodeInstance->initializePropertyWatcher(instance.m_nodeInstance); instance.setId(node.id()); @@ -198,7 +200,7 @@ NodeInstance NodeInstance::create(NodeInstanceView *nodeInstanceView, const Mode NodeInstance NodeInstance::create(NodeInstanceView *nodeInstanceView, const NodeMetaInfo &metaInfo, QmlContext *context) { NodeInstance instance(createInstance(metaInfo, context, 0)); - instance.m_nodeInstance->setNodeInstance(nodeInstanceView); + instance.m_nodeInstance->setNodeInstanceView(nodeInstanceView); return instance; } diff --git a/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.cpp b/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.cpp index 3bc073a9a6826f5303f9a7f70f11a607adc70e01..e8af9d71f62c95151c5f4b6dc1e1a0cf064c9c66 100644 --- a/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.cpp +++ b/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.cpp @@ -1,11 +1,23 @@ #include "nodeinstancemetaobject.h" +#include "objectnodeinstance.h" +#include <QSharedPointer> +#include <qnumeric.h> + namespace QmlDesigner { namespace Internal { -NodeInstanceMetaObject::NodeInstanceMetaObject(QObject *object, QmlContext *context) +NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstance::Pointer &nodeInstance) + : QmlOpenMetaObject(nodeInstance->object()), + m_nodeInstance(nodeInstance), + m_context(nodeInstance->modelNode().isRootNode() ? nodeInstance->context() : 0) +{ +} + +NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix) : QmlOpenMetaObject(object), - m_context(context) + m_nodeInstance(nodeInstance), + m_prefix(prefix) { } @@ -14,37 +26,73 @@ void NodeInstanceMetaObject::createNewProperty(const QString &name) createProperty(name.toLatin1(), 0); } -int NodeInstanceMetaObject::metaCall(QMetaObject::Call c, int id, void **a) +int NodeInstanceMetaObject::metaCall(QMetaObject::Call call, int id, void **a) { - if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty) + int metaCallReturnValue = -1; + + if (call == QMetaObject::WriteProperty + && reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double + && qIsNaN(reinterpret_cast<QVariant *>(a[0])->toDouble())) { + return -1; + } + + QVariant oldValue; + + if (call == QMetaObject::WriteProperty && !property(id).hasNotifySignal()) + { + oldValue = property(id).read(m_nodeInstance->object()); + } + + if (( call == QMetaObject::ReadProperty || call == QMetaObject::WriteProperty) && id >= type()->propertyOffset()) { int propId = id - type()->propertyOffset(); - if (c == QMetaObject::ReadProperty) { + if (call == QMetaObject::ReadProperty) { propertyRead(propId); *reinterpret_cast<QVariant *>(a[0]) = value(propId); - } else if (c == QMetaObject::WriteProperty) { + } else if (call == QMetaObject::WriteProperty) { if (value(propId) != *reinterpret_cast<QVariant *>(a[0])) { propertyWrite(propId); setValue(propId, *reinterpret_cast<QVariant *>(a[0])); - propertyWritten(propId); + dynamicPropertyWritten(propId); + notifyPropertyChange(id); activate(object(), type()->signalOffset() + propId, 0); } } - return -1; } else { if (parent()) - return parent()->metaCall(c, id, a); + metaCallReturnValue = parent()->metaCall(call, id, a); else - return object()->qt_metacall(c, id, a); + metaCallReturnValue = object()->qt_metacall(call, id, a); + + if (call == QMetaObject::WriteProperty + && !property(id).hasNotifySignal() + && oldValue != property(id).read(m_nodeInstance->object())) + notifyPropertyChange(id); } + return metaCallReturnValue; + } -void NodeInstanceMetaObject::propertyWritten(int propertyId) +void NodeInstanceMetaObject::dynamicPropertyWritten(int propertyId) { + if (m_context) m_context->setContextProperty(name(propertyId), value(propertyId)); } +void NodeInstanceMetaObject::notifyPropertyChange(int id) +{ + ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef(); + + if (objectNodeInstance && objectNodeInstance->nodeInstanceView()) { + if (id < type()->propertyOffset()) { + objectNodeInstance->nodeInstanceView()->notifyPropertyChange(objectNodeInstance->modelNode(), m_prefix + property(id).name()); + } else { + objectNodeInstance->nodeInstanceView()->notifyPropertyChange(objectNodeInstance->modelNode(), m_prefix + name(id - type()->propertyOffset())); + } + } +} + } // namespace Internal } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.h b/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.h index 0a32d579bb8390c0d887cb3baf46260f9a287d40..32d04a88219adc79ebe93b05fefad58242764f48 100644 --- a/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.h +++ b/src/plugins/qmldesigner/core/instances/nodeinstancemetaobject.h @@ -7,17 +7,25 @@ namespace QmlDesigner { namespace Internal { +class ObjectNodeInstance; +typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer; +typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer; + class NodeInstanceMetaObject : public QmlOpenMetaObject { public: - NodeInstanceMetaObject(QObject *object, QmlContext *context); + NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance); + NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix); void createNewProperty(const QString &name); protected: int metaCall(QMetaObject::Call _c, int _id, void **_a); - void propertyWritten(int); + void dynamicPropertyWritten(int); + void notifyPropertyChange(int id); private: + ObjectNodeInstanceWeakPointer m_nodeInstance; + QString m_prefix; QWeakPointer<QmlContext> m_context; }; diff --git a/src/plugins/qmldesigner/core/instances/nodeinstancesignalspy.cpp b/src/plugins/qmldesigner/core/instances/nodeinstancesignalspy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c4a3ccfc08d7ac26431718c7231f333300b8389c --- /dev/null +++ b/src/plugins/qmldesigner/core/instances/nodeinstancesignalspy.cpp @@ -0,0 +1,64 @@ +#include "nodeinstancesignalspy.h" + + +#include <QMetaProperty> +#include <QMetaObject> +#include <QtDebug> +#include <private/qmlmetaproperty_p.h> + +#include "objectnodeinstance.h" +#include <QSharedPointer> + +namespace QmlDesigner { +namespace Internal { + +NodeInstanceSignalSpy::NodeInstanceSignalSpy() : + QObject() +{ +} + +void NodeInstanceSignalSpy::setObjectNodeInstance(const ObjectNodeInstance::Pointer &nodeInstance) +{ + methodeOffset = QObject::staticMetaObject.methodCount() + 1; + registerObject(nodeInstance->object()); + m_objectNodeInstance = nodeInstance; + +} + +void NodeInstanceSignalSpy::registerObject(QObject *spiedObject, const QString &prefix) +{ + for (int index = QObject::staticMetaObject.propertyOffset(); + index < spiedObject->metaObject()->propertyCount(); + index++) { + QMetaProperty metaProperty = spiedObject->metaObject()->property(index); + if (metaProperty.isReadable() + && !metaProperty.isWritable() + && QmlMetaType::isQObject(metaProperty.userType())) { + QObject *propertyObject = QmlMetaType::toQObject(metaProperty.read(spiedObject)); + registerObject(propertyObject, prefix + metaProperty.name() + "."); + } else if (metaProperty.hasNotifySignal()) { + QMetaMethod metaMethod = metaProperty.notifySignal(); + bool isConnecting = QMetaObject::connect(spiedObject, metaMethod.methodIndex(), this, methodeOffset, Qt::DirectConnection); + Q_ASSERT(isConnecting); + m_indexPropertyHash.insert(methodeOffset, prefix + metaProperty.name()); + methodeOffset++; + } + } +} + +int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, void **a) +{ + if (call == QMetaObject::InvokeMetaMethod && methodId > QObject::staticMetaObject.methodCount()) { + ObjectNodeInstance::Pointer nodeInstance = m_objectNodeInstance.toStrongRef(); + + if (nodeInstance && nodeInstance->nodeInstanceView()) { + nodeInstance->nodeInstanceView()->notifyPropertyChange(nodeInstance->modelNode(), m_indexPropertyHash.value(methodId)); + } + + } + + return QObject::qt_metacall(call, methodId, a); +} + +} // namespace Internal +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/core/instances/nodeinstancesignalspy.h b/src/plugins/qmldesigner/core/instances/nodeinstancesignalspy.h new file mode 100644 index 0000000000000000000000000000000000000000..ff33b8cdbef6a038ec211d419612aa5ef17c7e32 --- /dev/null +++ b/src/plugins/qmldesigner/core/instances/nodeinstancesignalspy.h @@ -0,0 +1,36 @@ +#ifndef NODEINSTANCESIGNALSPY_H +#define NODEINSTANCESIGNALSPY_H + +#include <QObject> +#include <QHash> +#include <QSharedPointer> + +namespace QmlDesigner { +namespace Internal { + +class ObjectNodeInstance; +typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer; +typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer; + +class NodeInstanceSignalSpy : public QObject +{ +public: + explicit NodeInstanceSignalSpy(); + + void setObjectNodeInstance(const ObjectNodeInstancePointer &nodeInstance); + + virtual int qt_metacall(QMetaObject::Call, int, void **); + +protected: + void registerObject(QObject *spiedObject, const QString &prefix = QString()); + +private: + int methodeOffset; + QHash<int, QString> m_indexPropertyHash; + ObjectNodeInstanceWeakPointer m_objectNodeInstance; +}; + +} // namespace Internal +} // namespace QmlDesigner + +#endif // NODEINSTANCESIGNALSPY_H diff --git a/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp index c0b36cbce7630db669d93543a375320cf713de91..3e5c09cb2ab30646d4456441250d7c9242519f78 100644 --- a/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/core/instances/nodeinstanceview.cpp @@ -56,6 +56,8 @@ #include "objectnodeinstance.h" +#include "qmlmodelview.h" + enum { debug = false }; @@ -459,43 +461,13 @@ NodeInstance NodeInstanceView::rootNodeInstance() const \see NodeInstance */ -static bool isTransformProperty(const QString &name) -{ - static QStringList transformProperties(QStringList() << "xChanged()" - << "yChanged()" - << "zChanged()" - << "rotationChanged()" - << "scaleChanged()" - << "widthChanged()" - << "heightChanged()" - << "transformOriginChanged(TransformOrigin)"); - return transformProperties.contains(name); -} void NodeInstanceView::insertInstanceNodeRelationship(const ModelNode &node, const NodeInstance &instance) { - // connect with every signal of the object to get the formeditor updated - int otherPropertuChangedSlotIndex = staticMetaObject.indexOfSlot("emitOtherPropertyChanged()"); - int transformPropertuChangedSlotIndex = staticMetaObject.indexOfSlot("emitTransformPropertyChanged()"); - int parentPropertuChangedSlotIndex = staticMetaObject.indexOfSlot("emitParentPropertyChanged()"); - for (int index = QObject::staticMetaObject.methodCount(); - index < instance.internalObject()->metaObject()->methodCount(); - index++) { - QMetaMethod metaMethod = instance.internalObject()->metaObject()->method(index); - if (metaMethod.methodType() == QMetaMethod::Signal) { - if (isTransformProperty(metaMethod.signature())) { - staticMetaObject.connect(instance.internalObject(),index, this, transformPropertuChangedSlotIndex); - } else if (QByteArray(metaMethod.signature()) == QByteArray("parentChanged()")) { - staticMetaObject.connect(instance.internalObject(),index, this, parentPropertuChangedSlotIndex); - } else { - staticMetaObject.connect(instance.internalObject(),index, this, otherPropertuChangedSlotIndex); - } - } - } - instance.internalObject()->installEventFilter(childrenChangeEventFilter()); + Q_ASSERT(!m_nodeInstanceHash.contains(node)); m_nodeInstanceHash.insert(node, instance); m_objectInstanceHash.insert(instance.internalObject(), instance); @@ -510,7 +482,7 @@ Internal::ChildrenChangeEventFilter *NodeInstanceView::childrenChangeEventFilter { if (m_childrenChangeEventFilter.isNull()) { m_childrenChangeEventFilter = new Internal::ChildrenChangeEventFilter(this); - connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitUpdateItem(QObject*))); + connect(m_childrenChangeEventFilter.data(), SIGNAL(childrenChanged(QObject*)), this, SLOT(emitParentChanged(QObject*))); } return m_childrenChangeEventFilter.data(); @@ -526,39 +498,31 @@ void NodeInstanceView::removeInstanceNodeRelationship(const ModelNode &node) instance.makeInvalid(); } -void NodeInstanceView::emitOtherPropertyChanged() +void NodeInstanceView::notifyPropertyChange(const ModelNode &node, const QString &propertyName) { - if (m_blockChangeSignal) - return; - if (hasInstanceForObject(sender())) - emit otherPropertyChanged(instanceForObject(sender())); + if (qmlModelView()) { + qmlModelView()->nodeInstancePropertyChanged(ModelNode(node,qmlModelView()), propertyName); + } } -void NodeInstanceView::emitParentPropertyChanged() + +void NodeInstanceView::setQmlModelView(QmlModelView *qmlModelView) { - if (m_blockChangeSignal) - return; - if (hasInstanceForObject(sender())) - emit parentPropertyChanged(instanceForObject(sender())); + m_qmlModelView = qmlModelView; } -void NodeInstanceView::emitTransformPropertyChanged() +QmlModelView *NodeInstanceView::qmlModelView() const { - if (m_blockChangeSignal) - return; - if (hasInstanceForObject(sender())) - emit transformPropertyChanged(instanceForObject(sender())); + return m_qmlModelView.data(); } -void NodeInstanceView::emitUpdateItem(QObject *object) +void NodeInstanceView::emitParentChanged(QObject *child) { - if (m_blockChangeSignal) - return; - if (hasInstanceForObject(object)) - emit updateItem(instanceForObject(object)); + if (hasInstanceForObject(child)) { + notifyPropertyChange(instanceForObject(child).modelNode(), "parent"); + } } - NodeInstance NodeInstanceView::loadNode(const ModelNode &node, QObject *objectToBeWrapped) { Q_ASSERT(node.isValid()); diff --git a/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp b/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp index 34192e677825b6feca43c2099022de77e7fd0042..eebeccbc81ebc7d52b18a12035dcbe918307d8e8 100644 --- a/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp +++ b/src/plugins/qmldesigner/core/instances/objectnodeinstance.cpp @@ -57,6 +57,7 @@ #include <QmlBinding> #include <QmlMetaType> #include <QmlEngine> +#include <QSharedPointer> #include <private/qmlcontext_p.h> #include <private/qmllistaccessor_p.h> @@ -65,12 +66,14 @@ #include <private/qmlgraphicsrectangle_p.h> // to get QmlGraphicsPen #include <private/qmetaobjectbuilder_p.h> #include <private/qmlvmemetaobject_p.h> +#include <private/qobject_p.h> namespace QmlDesigner { namespace Internal { + ChildrenChangeEventFilter::ChildrenChangeEventFilter(QObject *parent) : QObject(parent) { @@ -81,7 +84,11 @@ bool ChildrenChangeEventFilter::eventFilter(QObject *object, QEvent *event) { switch (event->type()) { case QEvent::ChildAdded: - case QEvent::ChildRemoved: emit childrenChanged(object); break; + case QEvent::ChildRemoved: + { + QChildEvent *childEvent = static_cast<QChildEvent*>(event); + emit childrenChanged(childEvent->child()); break; + } default: break; } @@ -93,6 +100,7 @@ ObjectNodeInstance::ObjectNodeInstance(QObject *object) m_object(object), m_metaObject(0) { + } ObjectNodeInstance::~ObjectNodeInstance() @@ -158,11 +166,39 @@ NodeInstanceView *ObjectNodeInstance::nodeInstanceView() const return m_nodeInstanceView.data(); } -void ObjectNodeInstance::setNodeInstance(NodeInstanceView *view) +void ObjectNodeInstance::setNodeInstanceView(NodeInstanceView *view) { + Q_ASSERT(!m_nodeInstanceView.data()); + m_nodeInstanceView = view; } +static bool hasPropertiesWitoutNotifications(const QMetaObject *metaObject) +{ + for(int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) { + if (!metaObject->property(propertyIndex).hasNotifySignal()) + return true; + } + + return false; +} + +void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance) +{ + m_metaObject = new NodeInstanceMetaObject(objectNodeInstance); + const QMetaObject *metaObject = objectNodeInstance->object()->metaObject(); + for(int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) { + if (QmlMetaType::isQObject(metaObject->property(propertyIndex).userType())) { + QObject *propertyObject = QmlMetaType::toQObject(metaObject->property(propertyIndex).read(objectNodeInstance->object())); + if (propertyObject && hasPropertiesWitoutNotifications(propertyObject->metaObject())) { + new NodeInstanceMetaObject(objectNodeInstance, propertyObject, metaObject->property(propertyIndex).name()); + } + } + } + + m_signalSpy.setObjectNodeInstance(objectNodeInstance); +} + void ObjectNodeInstance::setId(const QString &id) { if (!m_id.isEmpty()) { @@ -701,13 +737,6 @@ static bool metaObjectHasNotPropertyName(NodeInstanceMetaObject *metaObject, con void ObjectNodeInstance::createDynamicProperty(const QString &name, const QString &/*typeName*/) { - if (m_metaObject == 0) { - if (modelNode().isRootNode()) - m_metaObject = new NodeInstanceMetaObject(object(), context()); - else - m_metaObject = new NodeInstanceMetaObject(object(), 0); - } - if (metaObjectHasNotPropertyName(m_metaObject, name)) m_metaObject->createNewProperty(name); } diff --git a/src/plugins/qmldesigner/core/instances/objectnodeinstance.h b/src/plugins/qmldesigner/core/instances/objectnodeinstance.h index 49f5d789e8c6950a56d6692890764e1b0bddaa5c..44f02ac27cbabb1b070cc02ee01856ff6d9130a9 100644 --- a/src/plugins/qmldesigner/core/instances/objectnodeinstance.h +++ b/src/plugins/qmldesigner/core/instances/objectnodeinstance.h @@ -39,12 +39,15 @@ #include <propertymetainfo.h> #include <nodeinstanceview.h> #include "nodeinstancemetaobject.h" +#include "nodeinstancesignalspy.h" +QT_BEGIN_NAMESPACE class QGraphicsItem; class QmlContext; class QmlMetaProperty; class QmlContext; class QmlBinding; +QT_END_NAMESPACE namespace QmlDesigner { @@ -91,8 +94,8 @@ public: void setModelNode(const ModelNode &node); NodeInstanceView *nodeInstanceView() const; - void setNodeInstance(NodeInstanceView *view); - + void setNodeInstanceView(NodeInstanceView *view); + void initializePropertyWatcher(const Pointer &objectNodeInstance); virtual void paint(QPainter *painter) const; virtual bool isTopLevel() const; @@ -186,6 +189,8 @@ private: bool m_deleteHeldInstance; QWeakPointer<QObject> m_object; NodeInstanceMetaObject *m_metaObject; + NodeInstanceSignalSpy m_signalSpy; + }; diff --git a/src/plugins/qmldesigner/core/instances/qmltransitionnodeinstance.h b/src/plugins/qmldesigner/core/instances/qmltransitionnodeinstance.h index 4202549efa30ffd1069d64bfaa27c136a4d7da71..64922c6ae495bec587ebc73196de7773233d47e2 100644 --- a/src/plugins/qmldesigner/core/instances/qmltransitionnodeinstance.h +++ b/src/plugins/qmldesigner/core/instances/qmltransitionnodeinstance.h @@ -32,7 +32,9 @@ #include "objectnodeinstance.h" +QT_BEGIN_NAMESPACE class QmlTransition; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/core/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/core/metainfo/subcomponentmanager.cpp index daa243d909857b512c3ad21b666aafdf7826d6c6..3d1f5acf1032e29bce1f2de622a85f1c7de773b5 100644 --- a/src/plugins/qmldesigner/core/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/core/metainfo/subcomponentmanager.cpp @@ -40,6 +40,7 @@ enum { debug = false }; +QT_BEGIN_NAMESPACE // Allow usage of QFileInfo in hash / qSort @@ -53,6 +54,7 @@ static uint qHash(const QFileInfo &fileInfo) return qHash(fileInfo.filePath()); } +QT_END_NAMESPACE namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/core/model/painteventfilter_p.h b/src/plugins/qmldesigner/core/model/painteventfilter_p.h index 183ade321b4858d80427214ec6f0bb60419275db..a91ac1cc3815e512450f42185fe9811fdc68cbac 100644 --- a/src/plugins/qmldesigner/core/model/painteventfilter_p.h +++ b/src/plugins/qmldesigner/core/model/painteventfilter_p.h @@ -33,7 +33,9 @@ #include <QObject> #include <QList> +QT_BEGIN_NAMESPACE class QTimer; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/core/model/qmlmodelview.cpp b/src/plugins/qmldesigner/core/model/qmlmodelview.cpp index 9e1a10211ddb726e1fbd3eb2d5073d4db540400c..58fa14c13da283d3989ec383a3ddea501c726a7c 100644 --- a/src/plugins/qmldesigner/core/model/qmlmodelview.cpp +++ b/src/plugins/qmldesigner/core/model/qmlmodelview.cpp @@ -42,11 +42,9 @@ namespace QmlDesigner { QmlModelView::QmlModelView(QObject *parent) : ForwardView<NodeInstanceView>(parent) { - appendView(new NodeInstanceView(this)); - connect(nodeInstanceView(), SIGNAL(transformPropertyChanged(NodeInstance)), SLOT(notifyTransformChanged(NodeInstance))); - connect(nodeInstanceView(), SIGNAL(parentPropertyChanged(NodeInstance)), SLOT(notifyParentChanged(NodeInstance))); - connect(nodeInstanceView(), SIGNAL(otherPropertyChanged(NodeInstance)), SLOT(notifyOtherPropertyChanged(NodeInstance))); - connect(nodeInstanceView(), SIGNAL(updateItem(NodeInstance)), SLOT(notifyUpdateItem(NodeInstance))); + NodeInstanceView *nodeInstanceView = new NodeInstanceView(this); + nodeInstanceView->setQmlModelView(this); + appendView(nodeInstanceView); } void QmlModelView::setCurrentState(const QmlModelState &state) @@ -220,27 +218,6 @@ QmlObjectNode QmlModelView::fxObjectNodeForId(const QString &id) return QmlObjectNode(modelNodeForId(id)); } - -void QmlModelView::notifyTransformChanged(const NodeInstance &nodeInstance) -{ - transformChanged(QmlObjectNode(ModelNode(nodeInstance.modelNode(), this))); -} - -void QmlModelView::notifyParentChanged(const NodeInstance &nodeInstance) -{ - parentChanged(QmlObjectNode(ModelNode(nodeInstance.modelNode(), this))); -} - -void QmlModelView::notifyOtherPropertyChanged(const NodeInstance &nodeInstance) -{ - otherPropertyChanged(QmlObjectNode(ModelNode(nodeInstance.modelNode(), this))); -} - -void QmlModelView::notifyUpdateItem(const NodeInstance &nodeInstance) -{ - updateItem(QmlObjectNode(ModelNode(nodeInstance.modelNode(), this))); -} - void QmlModelView::customNotification(const AbstractView * /* view */, const QString &identifier, const QList<ModelNode> &nodeList, const QList<QVariant> & /* data */) { if (identifier == "__state changed__") { @@ -281,25 +258,50 @@ void QmlModelView::modelAboutToBeDetached(Model *model) m_state = QmlModelState(); } -void QmlModelView::transformChanged(const QmlObjectNode &/*qmlObjectNode*/) +static bool isTransformProperty(const QString &name) { + static QStringList transformProperties(QStringList() << "x" + << "y" + << "width" + << "height" + << "z" + << "rotation" + << "scale" + << "transformOrigin"); + + return transformProperties.contains(name); } -void QmlModelView::parentChanged(const QmlObjectNode &/*qmlObjectNode*/) +void QmlModelView::nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName) { + QmlObjectNode qmlObjectNode(node); + + if (!qmlObjectNode.isValid()) + return; + if (isTransformProperty(propertyName)) + transformChanged(qmlObjectNode, propertyName); + else if (propertyName == "parent") + parentChanged(qmlObjectNode); + else + otherPropertyChanged(qmlObjectNode, propertyName); } -void QmlModelView::otherPropertyChanged(const QmlObjectNode &/*qmlObjectNode*/) +void QmlModelView::transformChanged(const QmlObjectNode &/*qmlObjectNode*/, const QString &/*propertyName*/) +{ +} + +void QmlModelView::parentChanged(const QmlObjectNode &/*qmlObjectNode*/) { } -void QmlModelView::updateItem(const QmlObjectNode &/*qmlObjectNode*/) +void QmlModelView::otherPropertyChanged(const QmlObjectNode &/*qmlObjectNode*/, const QString &/*propertyName*/) { } + void QmlModelView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState) { m_state = newQmlModelState; diff --git a/src/plugins/qmldesigner/core/model/variantparser.h b/src/plugins/qmldesigner/core/model/variantparser.h index 711e3b8f4ba613e30d22a2cf3c0c98c3b86b2cb0..5990f47f78b2fe50c50d833e848b62838d9842fd 100644 --- a/src/plugins/qmldesigner/core/model/variantparser.h +++ b/src/plugins/qmldesigner/core/model/variantparser.h @@ -34,7 +34,9 @@ #include <QString> #include <QStringList> +QT_BEGIN_NAMESPACE class QmlValueType; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/designmode.h b/src/plugins/qmldesigner/designmode.h index 4f53b96e853e8b2bf23e20844d6af52f4a9da9d0..89e407b77a890a4141ae33e0a95c8fb37dc64b88 100644 --- a/src/plugins/qmldesigner/designmode.h +++ b/src/plugins/qmldesigner/designmode.h @@ -36,7 +36,9 @@ #include <QWeakPointer> +QT_BEGIN_NAMESPACE class QAction; +QT_END_NAMESPACE namespace QmlDesigner { namespace Internal { diff --git a/src/plugins/qmldesigner/designmodewidget.h b/src/plugins/qmldesigner/designmodewidget.h index 8519716caf4c79b54e5860dd84a97598b04a2a4a..68ce3af9a62166fe56a03fed4d1ab74e9915939f 100644 --- a/src/plugins/qmldesigner/designmodewidget.h +++ b/src/plugins/qmldesigner/designmodewidget.h @@ -52,10 +52,12 @@ #include <QtGui/QComboBox> #include <QtGui/QLabel> +QT_BEGIN_NAMESPACE class QStackedWidget; class QTabWidget; class QVBoxLayout; class QToolButton; +QT_END_NAMESPACE namespace Core { class SideBar; diff --git a/src/plugins/qmlinspector/qmlinspectorplugin.h b/src/plugins/qmlinspector/qmlinspectorplugin.h index 240092e2b2a5b440c983001ebf6a78624211bbea..77f17d05ab86c9fcb6a7488c75385786c004c5bf 100644 --- a/src/plugins/qmlinspector/qmlinspectorplugin.h +++ b/src/plugins/qmlinspector/qmlinspectorplugin.h @@ -35,6 +35,8 @@ #include <QtCore/QPointer> #include <QtCore/QTimer> +QT_BEGIN_NAMESPACE + class QStringList; namespace ProjectExplorer { diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index 319dc0095514d3e8329a8b00980d749e6b8df8b1..924c45d3513f129d9ba4fdf9011b433b69c9ad91 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -564,7 +564,7 @@ QmlJSTextEditor::QmlJSTextEditor(QWidget *parent) : m_methodCombo(0), m_modelManager(0) { - qRegisterMetaType<SemanticInfo>("SemanticInfo"); + qRegisterMetaType<QmlJSEditor::Internal::SemanticInfo>("QmlJSEditor::Internal::SemanticInfo"); m_semanticHighlighter = new SemanticHighlighter(this); m_semanticHighlighter->start(); @@ -596,8 +596,8 @@ QmlJSTextEditor::QmlJSTextEditor(QWidget *parent) : this, SLOT(onDocumentUpdated(QmlJS::Document::Ptr))); } - connect(m_semanticHighlighter, SIGNAL(changed(SemanticInfo)), - this, SLOT(updateSemanticInfo(SemanticInfo))); + connect(m_semanticHighlighter, SIGNAL(changed(QmlJSEditor::Internal::SemanticInfo)), + this, SLOT(updateSemanticInfo(QmlJSEditor::Internal::SemanticInfo))); } QmlJSTextEditor::~QmlJSTextEditor() diff --git a/src/plugins/qmljseditor/qmljseditor.h b/src/plugins/qmljseditor/qmljseditor.h index 956684e1d2a9015ef72fbd2a8fc68f25594b2518..dc8d93a3006fbf4fac15f0bb313a3ca0b8b7f104 100644 --- a/src/plugins/qmljseditor/qmljseditor.h +++ b/src/plugins/qmljseditor/qmljseditor.h @@ -175,7 +175,7 @@ public: void rehighlight(const Source &source); Q_SIGNALS: - void changed(const SemanticInfo &semanticInfo); + void changed(const QmlJSEditor::Internal::SemanticInfo &semanticInfo); protected: virtual void run(); @@ -228,7 +228,7 @@ private slots: void renameIdUnderCursor(); void semanticRehighlight(); - void updateSemanticInfo(const SemanticInfo &semanticInfo); + void updateSemanticInfo(const QmlJSEditor::Internal::SemanticInfo &semanticInfo); protected: void contextMenuEvent(QContextMenuEvent *e); diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp index 28bf0b65d1328c7ef12b378b7b66ab6449eaf547..e12afdc700cc1b788c0d202bdb2438baf8c4445f 100644 --- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp +++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp @@ -194,8 +194,15 @@ ImageFileFilterItem::ImageFileFilterItem(QObject *parent) setFilter(filter); } +CssFileFilterItem::CssFileFilterItem(QObject *parent) + : FileFilterBaseItem(parent) +{ + setFilter(QLatin1String("*.css")); +} + } // namespace QmlProjectManager QML_DEFINE_TYPE(QmlProject,1,0,QmlFiles,QmlProjectManager::QmlFileFilterItem) QML_DEFINE_TYPE(QmlProject,1,0,JavaScriptFiles,QmlProjectManager::JsFileFilterItem) QML_DEFINE_TYPE(QmlProject,1,0,ImageFiles,QmlProjectManager::ImageFileFilterItem) +QML_DEFINE_TYPE(QmlProject,1,0,CssFiles,QmlProjectManager::CssFileFilterItem) diff --git a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h index 18c53149a9d8ac660fd102115e8cd2b01a984ac2..8c302408929a81f54616f6773cd6b55c78a2058b 100644 --- a/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h +++ b/src/plugins/qmlprojectmanager/fileformat/filefilteritems.h @@ -92,10 +92,19 @@ public: ImageFileFilterItem(QObject *parent = 0); }; +class CssFileFilterItem : public FileFilterBaseItem { + Q_OBJECT + Q_PROPERTY(QString filter READ filter WRITE setFilter NOTIFY filterChanged()) + +public: + CssFileFilterItem(QObject *parent = 0); +}; + } // namespace QmlProjectManager QML_DECLARE_TYPE(QmlProjectManager::QmlFileFilterItem) QML_DECLARE_TYPE(QmlProjectManager::JsFileFilterItem) QML_DECLARE_TYPE(QmlProjectManager::ImageFileFilterItem) +QML_DECLARE_TYPE(QmlProjectManager::CssFileFilterItem) #endif // FILEFILTERITEMS_HPROJECTITEM_H