diff --git a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
index e200d8427ea0d5b9460841e2a49aea2b981d767e..0daca6b5c7f4a931e5ceedeaa7ad444ccf80b318 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
@@ -121,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 28295292e743359577319800c3d82168a2820b06..6adf53504dc4b3af6c5efd017bece852c11d7251 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h
@@ -48,6 +48,7 @@ class ItemLibrary : public QFrame
 {
     Q_OBJECT
     Q_DISABLE_COPY(ItemLibrary)
+
 public:
     ItemLibrary(QWidget *parent = 0);
     virtual ~ItemLibrary();
@@ -55,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 &sectionName, 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 4c4e00d13681606636db46a6fa1cda496f91a478..22a1beef7aab00b6eccdf75c007d6fa23eaaffec 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
@@ -1,91 +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>
 
-QT_BEGIN_NAMESPACE
-class QLabel;
-QT_END_NAMESPACE
+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 &sectionName, 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"
+    }
+}
+