From f7e0366d65f5f96788b80b9e1255debcd904d601 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Schummer?= <ext-jorg.2.schummer@nokia.com>
Date: Wed, 10 Mar 2010 12:45:49 +0200
Subject: [PATCH] QmlDesigner.ItemLibrary: various updates

- clearing search input focus when clicking clear icon
- re-set updated sections' models
- using GridView-based item selection
- C++ code cleanup
- Manhattan-length used for drag & drop initiation
- integrated QtCreator's filter text input
- replaced QToolButtons with a QTabBar
- fix: eliding text & corrected selector offset
- styled resources view
- updated Qml syntax
---
 .../components/itemlibrary/itemlibrary.cpp    | 178 ++++++-------
 .../components/itemlibrary/itemlibrary.h      |  14 +-
 .../components/itemlibrary/itemlibrary.pri    |   2 -
 .../components/itemlibrary/itemlibrary.ui     | 243 ------------------
 .../itemlibrary/itemlibrarymodel.cpp          | 108 ++++++--
 .../components/itemlibrary/itemlibrarymodel.h |  16 +-
 .../itemlibrary/itemlibrarywidgets.cpp        | 106 +++++++-
 .../itemlibrary/itemlibrarywidgets.h          |  27 +-
 .../components/itemlibrary/qml/ItemView.qml   |  30 ++-
 .../components/itemlibrary/qml/ItemsView.qml  | 146 ++++++++---
 .../itemlibrary/qml/ItemsViewStyle.qml        |  10 +-
 .../components/itemlibrary/qml/Scrollbar.qml  |  38 +--
 .../itemlibrary/qml/SectionView.qml           |  81 ++++--
 .../components/itemlibrary/qml/Selector.qml   |  58 +----
 14 files changed, 533 insertions(+), 524 deletions(-)
 delete mode 100644 src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui

diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp
index fd8ee938280..e62a4962804 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp
@@ -29,30 +29,19 @@
 
 #include "itemlibrary.h"
 
+#include <utils/filterlineedit.h>
+#include "itemlibrarywidgets.h"
 #include "itemlibrarymodel.h"
 #include "customdraganddrop.h"
 
-#include "ui_itemlibrary.h"
-#include <metainfo.h>
-#include <itemlibraryinfo.h>
-#include <formeditorscene.h>
-
-#include <QtCore/QDebug>
-#include <QtGui/QContextMenuEvent>
-#include <QtGui/QMenu>
-#include <QtGui/QAction>
-#include <QtGui/QGraphicsView>
-#include <QtGui/QGraphicsScene>
-#include <QtGui/QGraphicsItem>
-#include <QtGui/QPixmap>
-#include <QSortFilterProxyModel>
-#include <QLabel>
-#include <QMainWindow>
-#include <QMenuBar>
-#include <QFile>
-#include <QDirModel>
+#include <QFileInfo>
 #include <QFileIconProvider>
+#include <QDirModel>
+#include <QStackedWidget>
+#include <QGridLayout>
+#include <QTabBar>
 #include <QImageReader>
+#include <QMimeData>
 
 #include <QDeclarativeView>
 #include <QDeclarativeItem>
@@ -104,23 +93,29 @@ class ItemLibraryPrivate {
 public:
     ItemLibraryPrivate(QObject *object);
 
-    Ui::ItemLibrary m_ui;
     Internal::ItemLibraryModel *m_itemLibraryModel;
-    QDeclarativeView *m_itemsView;
     QDirModel *m_resourcesDirModel;
-    QString m_resourcePath;
+
+    QStackedWidget *m_stackedWidget;
+    Utils::FilterLineEdit *m_lineEdit;
+    QDeclarativeView *m_itemsView;
+    Internal::ItemLibraryTreeView *m_resourcesView;
+
     QSize m_itemIconSize, m_resIconSize;
     MyFileIconProvider m_iconProvider;
 };
 
 ItemLibraryPrivate::ItemLibraryPrivate(QObject *object) :
     m_itemLibraryModel(0),
+    m_resourcesDirModel(0),
+    m_stackedWidget(0),
+    m_lineEdit(0),
     m_itemsView(0),
+    m_resourcesView(0),
     m_itemIconSize(22, 22),
     m_resIconSize(22, 22),
     m_iconProvider(m_resIconSize)
 {
-    m_resourcePath = QDir::currentPath();
     Q_UNUSED(object);
 }
 
@@ -128,78 +123,90 @@ ItemLibrary::ItemLibrary(QWidget *parent) :
     QFrame(parent),
     m_d(new ItemLibraryPrivate(this))
 {
-    m_d->m_ui.setupUi(this);
-    layout()->setContentsMargins(2, 2, 2, 0);
-    layout()->setSpacing(2);
-
-    m_d->m_resourcesDirModel = new QDirModel(this);
-
-    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->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-    m_d->m_ui.ItemLibraryTreeView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-    m_d->m_ui.ItemLibraryTreeView->setAttribute(Qt::WA_MacShowFocusRect, false);
-    m_d->m_ui.ItemLibraryTreeView->setRootIndex(m_d->m_resourcesDirModel->index(m_d->m_resourcePath));
+    setWindowTitle(tr("Library", "Title of library view"));
 
+    /* create Items view and its model */
     m_d->m_itemsView = new QDeclarativeView(this);
+    m_d->m_itemsView->setSource(QUrl("qrc:/ItemLibrary/qml/ItemsView.qml"));
     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->setResizeMode(QDeclarativeView::SizeRootObjectToView);
-    m_d->m_ui.ItemLibraryGridLayout->addWidget(m_d->m_itemsView, 0, 0);
-
     m_d->m_itemLibraryModel = new Internal::ItemLibraryModel(QDeclarativeEnginePrivate::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->setSource(QUrl("qrc:/ItemLibrary/qml/ItemsView.qml"));
+    QDeclarativeContext *rootContext = m_d->m_itemsView->rootContext();
+    rootContext->setContextProperty(QLatin1String("itemLibraryModel"), m_d->m_itemLibraryModel);
+    rootContext->setContextProperty(QLatin1String("itemLibraryIconWidth"), m_d->m_itemIconSize.width());
+    rootContext->setContextProperty(QLatin1String("itemLibraryIconHeight"), m_d->m_itemIconSize.height());
 
     QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_d->m_itemsView->rootObject());
     connect(rootItem, SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int)));
     connect(rootItem, SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int)));
-    connect(this, SIGNAL(expandAllItems()), rootItem, SLOT(expandAll()));
-
-    connect(m_d->m_ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(setSearchFilter(QString)));
-    m_d->m_ui.lineEdit->setDragEnabled(false);
-
-    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("");
+    connect(this, SIGNAL(resetItemsView()), rootItem, SLOT(resetView()));
 
+    /* create Resources view and its model */
+    m_d->m_resourcesDirModel = new QDirModel(this);
     m_d->m_resourcesDirModel->setIconProvider(&m_d->m_iconProvider);
-
-    setWindowTitle(tr("Library", "Title of library view"));
-
+    m_d->m_resourcesView = new Internal::ItemLibraryTreeView(this);
+    m_d->m_resourcesView->setModel(m_d->m_resourcesDirModel);
+    m_d->m_resourcesView->setIconSize(m_d->m_resIconSize);
+
+    /* other widgets */
+    QTabBar *tabBar = new QTabBar(this);
+    tabBar->addTab(tr("Items", "Title of library items view"));
+    tabBar->addTab(tr("Resources", "Title of library resources view"));
+    tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+
+    m_d->m_lineEdit = new Utils::FilterLineEdit(this);
+    m_d->m_lineEdit->setObjectName(QLatin1String("itemLibrarySearchInput"));
+    m_d->m_lineEdit->setHintText(tr("<Filter>", "Library search input hint text"));
+    m_d->m_lineEdit->setDragEnabled(false);
+    m_d->m_lineEdit->setMinimumWidth(75);
+    m_d->m_lineEdit->setTextMargins(0, 0, 0, 0);
+    QWidget *lineEditFrame = new QWidget(this);
+    lineEditFrame->setObjectName(QLatin1String("itemLibrarySearchInputFrame"));
+    QGridLayout *lineEditLayout = new QGridLayout(lineEditFrame);
+    lineEditLayout->setMargin(2);
+    lineEditLayout->setSpacing(0);
+    lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 0);
+    lineEditLayout->addWidget(m_d->m_lineEdit, 0, 1, 1, 1);
+    lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 2);
+    connect(m_d->m_lineEdit, SIGNAL(filterChanged(QString)), this, SLOT(setSearchFilter(QString)));
+    connect(m_d->m_lineEdit, SIGNAL(buttonClicked()), this, SLOT(clearLineEditFocus()));
+
+    m_d->m_stackedWidget = new QStackedWidget(this);
+    m_d->m_stackedWidget->addWidget(m_d->m_itemsView);
+    m_d->m_stackedWidget->addWidget(m_d->m_resourcesView);
+    connect(tabBar, SIGNAL(currentChanged(int)),
+            m_d->m_stackedWidget, SLOT(setCurrentIndex(int)));
+    connect(tabBar, SIGNAL(currentChanged(int)),
+            this, SLOT(updateSearch()));
+
+    QGridLayout *layout = new QGridLayout(this);
+    layout->setContentsMargins(0, 0, 0, 0);
+    layout->setSpacing(0);
+    layout->addWidget(tabBar, 0, 0, 1, 1);
+    layout->addWidget(lineEditFrame, 1, 0, 1, 1);
+    layout->addWidget(m_d->m_stackedWidget, 2, 0, 1, 1);
+
+    setResourcePath(QDir::currentPath());
+    setSearchFilter(QString());
+
+    /* style sheets */
     {
         QFile file(":/qmldesigner/stylesheet.css");
         file.open(QFile::ReadOnly);
         QString styleSheet = QLatin1String(file.readAll());
         setStyleSheet(styleSheet);
-
-        QFile fileTool(":/qmldesigner/toolbutton.css");
-        fileTool.open(QFile::ReadOnly);
-        styleSheet = QLatin1String(fileTool.readAll());
-        m_d->m_ui.buttonItems->setStyleSheet(styleSheet);
-        m_d->m_ui.buttonResources->setStyleSheet(styleSheet);
     }
 
     {
         QFile file(":/qmldesigner/scrollbar.css");
         file.open(QFile::ReadOnly);
         QString styleSheet = QLatin1String(file.readAll());
-        m_d->m_ui.ItemLibraryTreeView->setStyleSheet(styleSheet);
+        m_d->m_resourcesView->setStyleSheet(styleSheet);
     }
 }
 
@@ -208,12 +215,17 @@ ItemLibrary::~ItemLibrary()
     delete m_d;
 }
 
+void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo)
+{
+    m_d->m_itemLibraryModel->update(metaInfo);
+}
+
 void ItemLibrary::setSearchFilter(const QString &searchFilter)
 {
-    if (m_d->m_ui.buttonItems->isChecked()) {
+    if (m_d->m_stackedWidget->currentIndex() == 0) {
         m_d->m_itemLibraryModel->setSearchText(searchFilter);
+        emit resetItemsView();
         m_d->m_itemsView->update();
-        emit expandAllItems();
     } else {
         QStringList nameFilterList;
         if (searchFilter.contains('.')) {
@@ -226,29 +238,25 @@ void ItemLibrary::setSearchFilter(const QString &searchFilter)
 
         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);
+       m_d->m_resourcesView->expandToDepth(1);
+        m_d->m_resourcesView->scrollToTop();
     }
 }
 
-void ItemLibrary::itemLibraryButtonToggled()
+void ItemLibrary::updateSearch()
 {
-    m_d->m_ui.LibraryStackedWidget->setCurrentIndex(0);
-    m_d->m_ui.buttonResources->setChecked(false);
-    setSearchFilter(m_d->m_ui.lineEdit->text());
+    setSearchFilter(m_d->m_lineEdit->typedText());
 }
 
-void ItemLibrary::resourcesButtonToggled()
+void ItemLibrary::clearLineEditFocus()
 {
-    m_d->m_ui.LibraryStackedWidget->setCurrentIndex(1);
-    m_d->m_ui.buttonItems->setChecked(false);
-    setSearchFilter(m_d->m_ui.lineEdit->text());
+    m_d->m_lineEdit->clearFocus();
 }
 
 void ItemLibrary::setResourcePath(const QString &resourcePath)
 {
-    m_d->m_resourcePath = resourcePath;
+    if (m_d->m_resourcesView->model() == m_d->m_resourcesDirModel)
+        m_d->m_resourcesView->setRootIndex(m_d->m_resourcesDirModel->index(resourcePath));
 }
 
 void ItemLibrary::startDragAndDrop(int itemLibId)
@@ -272,10 +280,4 @@ void ItemLibrary::showItemInfo(int /*itemLibId*/)
 //    qDebug() << "showing item info about id" << itemLibId;
 }
 
-void ItemLibrary::setMetaInfo(const MetaInfo &metaInfo)
-{
-    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 adb19233742..e5803f01148 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h
@@ -32,12 +32,6 @@
 
 #include <QtGui/QFrame>
 
-QT_BEGIN_NAMESPACE
-class QGraphicsItem;
-class QPixmap;
-class QMimeData;
-QT_END_NAMESPACE
-
 namespace QmlDesigner {
 
 class ItemLibraryPrivate;
@@ -57,10 +51,10 @@ public:
     void setMetaInfo(const MetaInfo &metaInfo);
 
 public Q_SLOTS:
-    void itemLibraryButtonToggled();
-    void resourcesButtonToggled();
+    void setSearchFilter(const QString &searchFilter);
+    void updateSearch();
+    void clearLineEditFocus();
 
-    void setSearchFilter(const QString &nameFilter);
     void setResourcePath(const QString &resourcePath);
 
     void startDragAndDrop(int itemLibId);
@@ -68,7 +62,7 @@ public Q_SLOTS:
 
 signals:
     void itemActivated(const QString& itemName);
-    void expandAllItems();
+    void resetItemsView();
 
 private:
     ItemLibraryPrivate *m_d;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri
index 2cd17cb5c55..f15e463c666 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.pri
@@ -7,7 +7,5 @@ INCLUDEPATH += $$PWD
 
 # Input
 HEADERS += itemlibrary.h customdraganddrop.h itemlibrarymodel.h itemlibrarywidgets.h
-FORMS += itemlibrary.ui
 SOURCES += itemlibrary.cpp customdraganddrop.cpp itemlibrarymodel.cpp itemlibrarywidgets.cpp
 RESOURCES += itemlibrary.qrc
-
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui
deleted file mode 100644
index fdea444759a..00000000000
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.ui
+++ /dev/null
@@ -1,243 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QmlDesigner::ItemLibrary</class>
- <widget class="QFrame" name="QmlDesigner::ItemLibrary">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>497</width>
-    <height>635</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>ItemLibrary</string>
-  </property>
-  <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="QmlDesigner::Internal::ItemLibraryButton" 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="QmlDesigner::Internal::ItemLibraryButton" 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>
-    </widget>
-   </item>
-   <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>
-    <widget class="Line" name="line">
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
-     </property>
-    </widget>
-   </item>
-   <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>
- </widget>
- <layoutdefault spacing="0" margin="0"/>
- <customwidgets>
-  <customwidget>
-   <class>QmlDesigner::Internal::ItemLibraryTreeView</class>
-   <extends>QTreeView</extends>
-   <header>itemlibrarywidgets.h</header>
-  </customwidget>
-  <customwidget>
-   <class>QmlDesigner::Internal::ItemLibraryButton</class>
-   <extends>QToolButton</extends>
-   <header>itemlibrarywidgets.h</header>
-  </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
index c35564e1dc9..76ad7efaa1a 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp
@@ -107,27 +107,20 @@ bool ItemLibrarySortedModel<T>::elementVisible(int libId) const
 
 
 template <class T>
-void ItemLibrarySortedModel<T>::setElementVisible(int libId, bool visible)
+bool ItemLibrarySortedModel<T>::setElementVisible(int libId, bool visible)
 {
-    int pos = findElement(libId),
-          offset = 0;
-
+    int pos = findElement(libId);
     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;
-    }
+        return false;
 
+    int visiblePos = visibleElementPosition(libId);
     if (visible)
-        insert(pos - offset, *(m_elementModels.value(libId)));
+        insert(visiblePos, *(m_elementModels.value(libId)));
     else
-        remove(pos - offset);
+        remove(visiblePos);
 
     m_elementOrder[pos].visible = visible;
+    return true;
 }
 
 
@@ -160,6 +153,22 @@ int ItemLibrarySortedModel<T>::findElement(int libId) const
     return -1;
 }
 
+template <class T>
+int ItemLibrarySortedModel<T>::visibleElementPosition(int libId) const
+{
+    int i = 0;
+    QListIterator<struct order_struct> it(m_elementOrder);
+
+    while (it.hasNext()) {
+        struct order_struct order = it.next();
+        if (order.libId == libId)
+            return i;
+        if (order.visible)
+            ++i;
+    }
+
+    return -1;
+}
 
 
 
@@ -252,14 +261,32 @@ void ItemLibrarySectionModel::removeSectionEntry(int itemLibId)
 }
 
 
-bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText)
+int ItemLibrarySectionModel::visibleItemIndex(int itemLibId)
+{
+    return m_sectionEntries.visibleElementPosition(itemLibId);
+}
+
+
+bool ItemLibrarySectionModel::isItemVisible(int itemLibId)
+{
+    return m_sectionEntries.elementVisible(itemLibId);
+}
+
+
+bool ItemLibrarySectionModel::updateSectionVisibility(const QString &searchText, bool *changed)
 {
     bool haveVisibleItems = false;
+
+    *changed = false;
+
     QMap<int, ItemLibraryItemModel *>::const_iterator itemIt = m_sectionEntries.elements().constBegin();
     while (itemIt != m_sectionEntries.elements().constEnd()) {
 
-        bool itemVisible = itemIt.value()->itemName().toLower().contains(searchText);
-        m_sectionEntries.setElementVisible(itemIt.key(), itemVisible);
+        bool itemVisible = itemIt.value()->itemName().toLower().contains(searchText),
+            itemChanged = false;
+        itemChanged = m_sectionEntries.setElementVisible(itemIt.key(), itemVisible);
+
+        *changed |= itemChanged;
 
         if (itemVisible)
             haveVisibleItems = true;
@@ -334,12 +361,42 @@ void ItemLibraryModel::setItemIconSize(const QSize &itemIconSize)
 }
 
 
+int ItemLibraryModel::getItemSectionIndex(int itemLibId)
+{
+    if (m_sections.contains(itemLibId))
+        return elementModel(m_sections.value(itemLibId))->visibleItemIndex(itemLibId);
+    else
+        return -1;
+}
+
+
+int ItemLibraryModel::getSectionLibId(int itemLibId)
+{
+    return m_sections.value(itemLibId);
+}
+
+
+bool ItemLibraryModel::isItemVisible(int itemLibId)
+{
+    if (!m_sections.contains(itemLibId))
+        return false;
+
+    int sectionLibId = m_sections.value(itemLibId);
+    if (!elementVisible(sectionLibId))
+        return false;
+
+    return elementModel(sectionLibId)->isItemVisible(itemLibId);
+}
+
+
 void ItemLibraryModel::update(const MetaInfo &metaInfo)
 {
     QMap<QString, int> sections;
 
     clearElements();
     m_itemInfos.clear();
+    m_sections.clear();
+    m_nextLibId = 0;
 
     if (!m_metaInfo) {
         m_metaInfo = new MetaInfo(metaInfo);
@@ -371,6 +428,7 @@ void ItemLibraryModel::update(const MetaInfo &metaInfo)
             itemModel->setItemIcon(itemLibraryRepresentation.icon());
             itemModel->setItemIconSize(m_itemIconSize);
             sectionModel->addSectionEntry(itemModel);
+            m_sections.insert(itemId, sectionId);
         }
     }
 
@@ -414,6 +472,8 @@ QIcon ItemLibraryModel::getIcon(int libId)
 
 void ItemLibraryModel::updateVisibility()
 {
+    bool changed = false;
+
     QMap<int, ItemLibrarySectionModel *>::const_iterator sectionIt = elements().constBegin();
     while (sectionIt != elements().constEnd()) {
 
@@ -423,13 +483,21 @@ void ItemLibraryModel::updateVisibility()
         if (sectionModel->sectionName().toLower().contains(m_searchText))
             sectionSearchText = "";
 
-        bool sectionVisibility = sectionModel->updateSectionVisibility(sectionSearchText);
-        setElementVisible(sectionIt.key(), sectionVisibility);
+        bool sectionChanged = false,
+            sectionVisibility = sectionModel->updateSectionVisibility(sectionSearchText,
+                                                                      &sectionChanged);
+        if (sectionChanged) {
+            changed = true;
+            if (sectionVisibility)
+                emit sectionVisibilityChanged(sectionIt.key());
+        }
 
+        changed |= setElementVisible(sectionIt.key(), sectionVisibility);
         ++sectionIt;
     }
 
-    emit visibilityUpdated();
+    if (changed)
+        emit visibilityChanged();
 }
 
 
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
index e819f6b7899..5391d0d83a6 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h
@@ -57,12 +57,13 @@ public:
     void removeElement(int libId);
 
     bool elementVisible(int libId) const;
-    void setElementVisible(int libId, bool visible);
+    bool setElementVisible(int libId, bool visible);
 
     const QMap<int, T *> &elements() const;
 
     T *elementModel(int libId);
     int findElement(int libId) const;
+    int visibleElementPosition(int libId) const;
 
 private:
     struct order_struct {
@@ -106,7 +107,10 @@ public:
     void addSectionEntry(ItemLibraryItemModel *sectionEntry);
     void removeSectionEntry(int itemLibId);
 
-    bool updateSectionVisibility(const QString &searchText);
+    int visibleItemIndex(int itemLibId);
+    bool isItemVisible(int itemLibId);
+
+    bool updateSectionVisibility(const QString &searchText, bool *changed);
     void updateItemIconSize(const QSize &itemIconSize);
 
     bool operator<(const ItemLibrarySectionModel &other) const;
@@ -137,10 +141,15 @@ public slots:
     void setSearchText(const QString &searchText);
     void setItemIconSize(const QSize &itemIconSize);
 
+    int getItemSectionIndex(int itemLibId);
+    int getSectionLibId(int itemLibId);
+    bool isItemVisible(int itemLibId);
+
 signals:
     void qmlModelChanged();
     void searchTextChanged();
-    void visibilityUpdated();
+    void visibilityChanged();
+    void sectionVisibilityChanged(int changedSectionLibId);
 
 private:
     void updateVisibility();
@@ -149,6 +158,7 @@ private:
     QWeakPointer<QScriptEngine> m_scriptEngine;
     MetaInfo *m_metaInfo;
     QMap<int, ItemLibraryInfo> m_itemInfos;
+    QMap<int, int> m_sections;
 
     QString m_searchText;
     QSize m_itemIconSize;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp
index 390961156cc..8d2ba7df2bb 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.cpp
@@ -41,15 +41,59 @@
 #include <QLabel>
 #include <itemlibraryinfo.h>
 #include <QDirModel>
-
+#include <QProxyStyle>
 
 enum { debug = 0 };
 
-
 namespace QmlDesigner {
 
 namespace Internal {
 
+static void drawSelectionBackground(QPainter *painter, const QStyleOption &option)
+{
+    painter->save();
+    QLinearGradient gradient;
+    QColor highlight = option.palette.highlight().color();
+    gradient.setColorAt(0, highlight.lighter(130));
+    gradient.setColorAt(1, highlight.darker(130));
+    gradient.setStart(option.rect.topLeft());
+    gradient.setFinalStop(option.rect.bottomLeft());
+    painter->fillRect(option.rect, gradient);
+    painter->setPen(highlight.lighter());
+    painter->drawLine(option.rect.topLeft(),option.rect.topRight());
+    painter->setPen(highlight.darker());
+    painter->drawLine(option.rect.bottomLeft(),option.rect.bottomRight());
+    painter->restore();
+}
+
+// This style basically allows us to span the entire row
+// including the arrow indicators which would otherwise not be
+// drawn by the delegate
+class TreeViewStyle : public QProxyStyle
+{
+public:
+    void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget * = 0) const
+    {
+        if (element == QStyle::PE_PanelItemViewRow) {
+            if (option->state & QStyle::State_Selected) {
+                drawSelectionBackground(painter, *option);
+            } else {
+                painter->save();
+                painter->setPen(QColor(255, 255, 255, 15));
+                painter->drawLine(option->rect.topLeft(), option->rect.topRight());
+                painter->setPen(QColor(0, 0, 0, 25));
+                painter->drawLine(option->rect.bottomLeft(),option->rect.bottomRight());
+                painter->restore();
+            }
+        }
+    }
+    int styleHint(StyleHint hint, const QStyleOption *option = 0, const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const {
+        if (hint == SH_ItemView_ShowDecorationSelected)
+            return 0;
+        else
+            return QProxyStyle::styleHint(hint, option, widget, returnData);
+    }
+};
 
 ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) :
         QTreeView(parent)
@@ -58,6 +102,17 @@ ItemLibraryTreeView::ItemLibraryTreeView(QWidget *parent) :
     setDragDropMode(QAbstractItemView::DragOnly);
     setUniformRowHeights(true);
     connect(this, SIGNAL(clicked(const QModelIndex &)), this, SLOT(activateItem(const QModelIndex &)));
+    setHeaderHidden(true);
+    setIndentation(20);
+    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    setAttribute(Qt::WA_MacShowFocusRect, false);
+
+    TreeViewStyle *style = new TreeViewStyle;
+    setStyle(style);
+    style->setParent(this);
+    m_delegate = new ResourceItemDelegate(this);
+    setItemDelegateForColumn(0, m_delegate);
 }
 
 // We need to implement startDrag ourselves since we cannot
@@ -86,6 +141,19 @@ void ItemLibraryTreeView::startDrag(Qt::DropActions /* supportedActions */)
     }
 }
 
+void ItemLibraryTreeView::setModel(QAbstractItemModel *model)
+{
+    QDirModel *dirModel = dynamic_cast<QDirModel *>(model);
+    if (dirModel) {
+        QTreeView::setModel(model);
+        m_delegate->setModel(dirModel);
+        setColumnHidden(1, true);
+        setColumnHidden(2, true);
+        setColumnHidden(3, true);
+        setSortingEnabled(true);
+    }
+}
+
 void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/)
 {
     QMimeData *mimeData = model()->mimeData(selectedIndexes());
@@ -103,15 +171,39 @@ void ItemLibraryTreeView::activateItem( const QModelIndex & /*index*/)
     }
 }
 
-ItemLibraryButton::ItemLibraryButton(QWidget *parent)
-: QToolButton(parent)
+void ResourceItemDelegate::paint(QPainter *painter,
+               const QStyleOptionViewItem &option, const QModelIndex &index) const
+{
+    if (option.state & QStyle::State_Selected)
+        drawSelectionBackground(painter, option);
+
+    painter->save();
+
+    QIcon icon(m_model->fileIcon(index));
+    QPixmap pixmap(icon.pixmap(icon.availableSizes().front()));
+    painter->drawPixmap(option.rect.x(),option.rect.y()+2,pixmap);
+    QString myString(m_model->fileName(index));
+
+    // Check text length does not exceed available space
+    int extraSpace=12+pixmap.width();
+    QFontMetrics fm(option.font);
+    myString = fm.elidedText(myString,Qt::ElideMiddle,option.rect.width()-extraSpace);
+
+    painter->drawText(option.rect.bottomLeft()+QPoint(3+pixmap.width(),-8),myString);
+
+    painter->restore();
+}
+
+QSize ResourceItemDelegate::sizeHint(const QStyleOptionViewItem &/*option*/,
+                                     const QModelIndex &index) const
 {
+    QIcon icon(m_model->fileIcon(index));
+    return icon.availableSizes().front() + QSize(25, 4);
 }
 
-void ItemLibraryButton::mousePressEvent(QMouseEvent *event)
+void ResourceItemDelegate::setModel(QDirModel *model)
 {
-    if (!isChecked())
-        QToolButton::mousePressEvent(event);
+    m_model = model;
 }
 
 } // namespace Internal
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h
index 88f987c1123..c5aa644a7bd 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidgets.h
@@ -36,6 +36,9 @@
 #include <QDebug>
 #include <QTimeLine>
 #include <QToolButton>
+#include <QStyledItemDelegate>
+
+class QDirModel;
 
 QT_FORWARD_DECLARE_CLASS(QLabel);
 
@@ -43,6 +46,8 @@ namespace QmlDesigner {
 
 namespace Internal {
 
+class ResourceItemDelegate;
+
 // ItemLibraryTreeView with Drag implementation
 class ItemLibraryTreeView : public QTreeView {
     Q_OBJECT
@@ -50,20 +55,34 @@ public:
     explicit ItemLibraryTreeView(QWidget *parent = 0);
 
     virtual void startDrag(Qt::DropActions supportedActions);
+    virtual void setModel(QAbstractItemModel *model);
 
 signals:
     void itemActivated(const QString &itemName);
 
 private slots:
     void activateItem( const QModelIndex &index);
+
+private:
+    ResourceItemDelegate *m_delegate;
 };
 
-class ItemLibraryButton : public QToolButton {
+class ResourceItemDelegate : public QStyledItemDelegate
+{
 public:
-    ItemLibraryButton(QWidget *parent = 0);
+    explicit ResourceItemDelegate(QObject *parent=0) :
+        QStyledItemDelegate(parent),m_model(0) {}
+
+    void paint(QPainter *painter,
+               const QStyleOptionViewItem &option, const QModelIndex &index) const;
+
+    QSize sizeHint(const QStyleOptionViewItem &option,
+                   const QModelIndex &index) const;
+
+    void setModel(QDirModel *model);
 
-protected:
-    void mousePressEvent(QMouseEvent *event);
+private:
+    QDirModel *m_model;
 };
 
 } // namespace Internal
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml
index 939b4cc9c84..2be2d56c640 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemView.qml
@@ -29,18 +29,21 @@
 
 import Qt 4.6
 
+// view displaying an item library grid item
+
 Item {
     id: itemView
 
     // public
-    
+
     signal itemPressed()
     signal itemDragged()
 
     // internal
 
     ItemsViewStyle { id: style }
-    
+
+    // frame
     Rectangle {
         anchors.top: parent.top
         anchors.left: parent.left
@@ -91,28 +94,31 @@ Item {
         anchors.topMargin: style.cellVerticalMargin
         anchors.horizontalCenter: parent.horizontalCenter
 
-        width: itemLibraryIconWidth
-        height: itemLibraryIconHeight
-        pixmap: itemPixmap
+        width: itemLibraryIconWidth  // to be set in Qml context
+        height: itemLibraryIconHeight   // to be set in Qml context
+        pixmap: itemPixmap  // to be set by model
     }
 
     Text {
         id: text
-        elide: Qt.ElideMiddle
+        elide: ElideMiddle
         anchors.top: itemIcon.bottom
         anchors.topMargin: style.cellVerticalSpacing
-        anchors.horizontalCenter: parent.horizontalCenter
+        anchors.left: parent.left
+	anchors.leftMargin: style.cellHorizontalMargin
+	anchors.right: parent.right
+	anchors.rightMargin: style.cellHorizontalMargin
         width: style.textWidth
         height: style.textHeight
 
         verticalAlignment: "AlignVCenter"
         horizontalAlignment: "AlignHCenter"
-        text: itemName
+        text: itemName  // to be set by model
         color: style.itemNameTextColor
     }
 
     MouseArea {
-        id: mouseArea
+        id: mouseRegion
         anchors.fill: parent
 
         property bool reallyPressed: false
@@ -127,10 +133,10 @@ Item {
         }
         onPositionChanged: {
             if (reallyPressed &&
-                (Math.abs(mouse.x - pressedX) > 2 ||
-                 Math.abs(mouse.y - pressedY) > 2)) {
+                (Math.abs(mouse.x - pressedX) +
+                 Math.abs(mouse.y - pressedY)) > 3) {
                 itemDragged()
-                reallyPressed = false;
+                reallyPressed = false
             }
         }
         onReleased: reallyPressed = false
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml
index ce54230d247..f78a3028d52 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml
@@ -29,14 +29,40 @@
 
 import Qt 4.6
 
+/* The view displaying the item grid.
+
+   The following Qml context properties have to be set:
+     - listmodel itemLibraryModel
+     - int itemLibraryIconWidth
+     - int itemLibraryIconHeight
+
+   itemLibraryModel has to have the following structure:
+
+   ListModel {
+       ListElement {
+           int sectionLibId
+           string sectionName
+           list sectionEntries: [
+               ListElement {
+                   int itemLibId
+                   string itemName
+                   pixmap itemPixmap
+               },
+               ...
+           ]
+       }
+       ...
+   }
+*/
+
 Rectangle {
     id: itemsView
 
     // public
-    
-    function expandAll() {
-        expandAllEntries();
-        scrollbar.moveHandle(0, true)
+
+    function resetView() {
+        expandAllEntries()
+        scrollbar.reset()
     }
 
     signal itemSelected(int itemLibId)
@@ -45,15 +71,11 @@ Rectangle {
     signal stopDragAndDrop
 
     // internal
-    
+
     signal expandAllEntries
 
     ItemsViewStyle { id: style }
 
-    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
-
     color: style.backgroundColor
 
     /* workaround: without this, a completed drag and drop operation would
@@ -62,9 +84,45 @@ Rectangle {
     MouseArea {
         anchors.fill: parent
         hoverEnabled: true
-        onEntered: if (!pressed) itemsView.stopDragAndDrop
+        onEntered: {
+	    if (!pressed)
+		stopDragAndDrop()
+	}
     }
 
+    signal selectionUpdated(int itemSectionIndex)
+
+    property int selectedItemLibId: -1
+    property int selectionSectionLibId: -1
+
+    function setSelection(itemLibId) {
+	selectedItemLibId = itemLibId
+	selectionSectionLibId = itemLibraryModel.getSectionLibId(itemLibId)
+	selectionUpdated(itemLibraryModel.getItemSectionIndex(itemLibId))
+    }
+
+    function unsetSelection() {
+	selectedItemLibId = -1
+	selectionSectionLibId = -1
+	selectionUpdated(-1)
+    }
+
+    Connections {
+	target: itemLibraryModel
+        onVisibilityChanged: {
+	    if (itemLibraryModel.isItemVisible(selectedItemLibId))
+		setSelection(selectedItemLibId)
+	    else
+		unsetSelection()
+	}
+    }
+
+    /* the following 3 properties are calculated here for performance
+       reasons and then passed to the section views */
+    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
+
     Component {
         id: sectionDelegate
 
@@ -78,13 +136,41 @@ Rectangle {
             width: itemsFlickable.width
             itemHighlight: selector
 
-            onItemSelected: itemsView.itemSelected(itemLibId)
-            onItemDragged: itemsView.itemDragged(itemLibId)
+	    property bool containsSelection: (selectionSectionLibId == sectionLibId)
+
+            onItemSelected: {
+		itemsView.setSelection(itemLibId)
+		itemsView.itemSelected(itemLibId)
+	    }
+            onItemDragged: {
+		section.itemSelected(itemLibId)
+		itemsView.itemDragged(itemLibId)
+	    }
 
             Connections {
                 target: itemsView
-                onExpandAllEntries: section.expand();
-            }
+                onExpandAllEntries: section.expand()
+		onSelectionUpdated: {
+		    if (containsSelection) {
+			section.setSelection(itemSectionIndex)
+			section.focusSelection(itemsFlickable)
+		    } else
+			section.unsetSelection()
+		}
+	    }
+
+	    Component {
+		id: selector
+
+		Selector {
+		    x: containsSelection? section.currentItem.x:0
+		    y: containsSelection? section.currentItem.y:0
+		    width: itemsView.cellWidth
+		    height: itemsView.cellHeight
+
+		    visible: containsSelection
+		}
+	    }
         }
     }
 
@@ -92,34 +178,37 @@ Rectangle {
         id: itemsFlickable
 
         anchors.top: parent.top
-        anchors.topMargin: 2
+	anchors.topMargin: 3
         anchors.bottom: parent.bottom
         anchors.left: parent.left
         anchors.right: scrollbar.left
-        anchors.rightMargin: 2
-        clip: true
+	overShoot: false
 
         interactive: false
         contentHeight: col.height
 
+	/* Limit the content position. Without this, resizing would get the
+           content position out of scope regarding the scrollbar. */
+	function limitContentPos() {
+	    if (contentY < 0)
+		contentY = 0;
+	    else {
+		var maxContentY = Math.max(0, contentHeight - height)
+		if (contentY > maxContentY)
+		    contentY = maxContentY;
+	    }
+	}
+	onHeightChanged: limitContentPos()
+	onContentHeightChanged: limitContentPos()
+
         Column {
             id: col
 
             Repeater {
-                model: itemLibraryModel
+                model: itemLibraryModel  // to be set in Qml context
                 delegate: sectionDelegate
             }
         }
-
-        Selector {
-            id: selector
-	    
-            z: -1
-            flickable: itemsFlickable
-
-            width: itemsView.cellWidth
-            height: itemsView.cellHeight
-        }
     }
 
     Scrollbar {
@@ -136,4 +225,3 @@ Rectangle {
         flickable: itemsFlickable
     }
 }
-
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml
index 6516c663465..a2ba71393a2 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml
@@ -29,6 +29,8 @@
 
 import Qt 4.6
 
+// the style used the items view
+
 Item {
     property string backgroundColor: "#707070"
     property string raisedBackgroundColor: "#e0e0e0"
@@ -50,20 +52,18 @@ Item {
     property int sectionTitleHeight: 20
     property int sectionTitleSpacing: 2
 
-    // the selector's offset from the start of the section
-    property int selectionSectionOffset: sectionTitleHeight + sectionTitleSpacing
-
     property int iconWidth: 32
     property int iconHeight: 32
 
-    property int textWidth: 90
+    property int textWidth: 95
     property int textHeight: 15
 
+    property int cellHorizontalMargin: 5
     property int cellVerticalSpacing: 7
     property int cellVerticalMargin: 10
 
     // the following depend on the actual shape of the item delegate
-    property int cellWidth: textWidth
+    property int cellWidth: textWidth + 2 * cellHorizontalMargin
     property int cellHeight: itemLibraryIconHeight + textHeight +
 	                     2 * cellVerticalMargin + cellVerticalSpacing
 }
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml
index 99784a7da37..ec8705c3237 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml
@@ -29,17 +29,25 @@
 
 import Qt 4.6
 
+// scrollbar for the items view
+
 Item {
     id: bar
 
     // public
-    
+
     property var flickable
 
+    function reset() {
+	handle.y = 0
+    }
+
     // internal
 
     ItemsViewStyle { id: style }
-    
+
+    onFlickableChanged: reset()
+
     property int scrollHeight: height - handle.height
 
     Rectangle {
@@ -47,32 +55,28 @@ Item {
         anchors.rightMargin: 1
         anchors.bottomMargin: 1
         color: "transparent"
-        border.width: 1;
-        border.color: style.scrollbarBorderColor;
+        border.width: 1
+        border.color: style.scrollbarBorderColor
     }
 
-    function moveHandle(contentPos, updateFlickable) {
-	handle.updateFlickable = updateFlickable
+    function updateHandle() {
+	handle.updateFlickable = false
 
 	if (flickable)
 	    handle.y = scrollHeight * Math.min(
-		contentPos / (flickable.contentHeight - flickable.height),
-                1);
+		flickable.contentY / (flickable.contentHeight - flickable.height),
+                1)
 	else
-	    handle.y = 0;
+	    handle.y = 0
 
 	handle.updateFlickable = true
     }
 
-    function updateHandle() {
-	moveHandle(flickable.contentY, false);
-    }
-
-    onFlickableChanged: moveHandle(0, true)
+    onHeightChanged: updateHandle()
 
     Connections {
         target: flickable
-        onHeightChanged: moveHandle(0, true)
+        onHeightChanged: updateHandle()
     }
 
     Connections {
@@ -85,8 +89,6 @@ Item {
         onContentYChanged: updateHandle()
     }
 
-    onHeightChanged: updateHandle()
-    
     MouseArea {
         anchors.left: parent.left
         anchors.right: parent.right
@@ -105,7 +107,7 @@ Item {
 	height: Math.max(width, bar.height * Math.min(1, flickable.height / flickable.contentHeight))
 
 	property bool updateFlickable: true
-	
+
 	onYChanged: {
 	    if (updateFlickable)
 		flickable.contentY = Math.max(0, flickable.contentHeight * y / bar.height)
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml
index 3f15e559eba..7edfd62c6db 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/SectionView.qml
@@ -29,28 +29,64 @@
 
 import Qt 4.6
 
+// view displaying one item library section including its grid
+
 Column {
     id: sectionView
 
     // public
-    
+
     property var itemHighlight
 
     property int entriesPerRow
     property int cellWidth
     property int cellHeight
 
+    property var currentItem: gridView.currentItem
+
     function expand() {
-        gridFrame.state = "";
+        gridFrame.state = ""
     }
 
     signal itemSelected(int itemLibId)
     signal itemDragged(int itemLibId)
 
+    function setSelection(itemSectionIndex)
+    {
+	gridView.currentIndex = itemSectionIndex
+    }
+
+    function unsetSelection()
+    {
+	gridView.currentIndex = -1
+    }
+
+    function focusSelection(flickable) {
+	var pos = -1;
+
+	if (!gridView.currentItem)
+	    return;
+
+	var currentItemX = sectionView.x + gridFrame.x + gridView.x + gridView.currentItem.x;
+	var currentItemY = sectionView.y + gridFrame.y + gridView.y + gridView.currentItem.y
+	    - gridView.contentY;  // workaround: GridView reports wrong contentY
+
+	if (currentItemY < flickable.contentY)
+	    pos = Math.max(0, currentItemY)
+
+	else if ((currentItemY + gridView.currentItem.height) >
+		 (flickable.contentY + flickable.height - 1))
+	    pos = Math.min(Math.max(0, flickable.contentHeight - flickable.height),
+			   currentItemY + gridView.currentItem.height - flickable.height + 1)
+
+	if (pos >= 0)
+	    flickable.contentY = pos
+    }
+
     // internal
 
     ItemsViewStyle { id: style }
-    
+
     Component {
         id: itemDelegate
 
@@ -60,25 +96,17 @@ Column {
 	    width: cellWidth
 	    height: cellHeight
 
-            function selectItem() {
-                itemHighlight.select(sectionView, item, gridFrame.x, -gridView.viewportY);
-                sectionView.itemSelected(itemLibId);
-            }
-
-            onItemPressed: selectItem()
-            onItemDragged: {
-                selectItem();
-                sectionView.itemDragged(itemLibId);
-            }
+            onItemPressed: sectionView.itemSelected(itemLibId)
+            onItemDragged: sectionView.itemDragged(itemLibId)
         }
     }
 
+    // clickable header bar
     Rectangle {
         width: parent.width
         height: style.sectionTitleHeight
 
         color: style.sectionTitleBackgroundColor
-        radius: 2
 
         Item {
             id: arrow
@@ -104,19 +132,13 @@ Column {
             anchors.left: arrow.right
             anchors.leftMargin: 5
 
-            text: sectionName
+            text: sectionName  // to be set by model
             color: style.sectionTitleTextColor
+	    elide: Text.ElideMiddle
         }
         MouseArea {
             anchors.fill: parent
-            onClicked: {
-                if (itemHighlight.visible &&
-                    (itemHighlight.section == sectionView)) {
-                    itemHighlight.unselect();
-                    sectionView.itemSelected(-1);
-                }
-                gridFrame.toggleExpanded()
-            }
+            onClicked: gridFrame.toggleExpanded()
         }
     }
 
@@ -137,10 +159,14 @@ Column {
         GridView {
             id: gridView
 
-	    // workaround
             Connections {
-                target: itemLibraryModel
-                onVisibilityUpdated: gridView.positionViewAtIndex(0);
+                target: itemLibraryModel  // to be set in Qml context
+                onSectionVisibilityChanged: {
+		    /* workaround: reset model in order to get the grid view
+                       updated properly under all conditions */
+		    if (changedSectionLibId == sectionLibId)
+			gridView.model = sectionEntries
+		}
             }
 
             anchors.fill: parent
@@ -149,8 +175,9 @@ Column {
 
             cellWidth: sectionView.cellWidth
             cellHeight: sectionView.cellHeight
-            model: sectionEntries
+            model: sectionEntries  // to be set by model
             delegate: itemDelegate
+	    highlight: itemHighlight
             interactive: false
             highlightFollowsCurrentItem: false
         }
diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml
index 8581fbb08ca..badb21fa31a 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml
+++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Selector.qml
@@ -29,66 +29,12 @@
 
 import Qt 4.6
 
+// the coloured selector of the items view
+
 Item {
     id: selector
 
-    // public
-    
-    property var flickable
-
-    // internal
-
     ItemsViewStyle { id: style }
-    
-    visible: false
-
-    property var section: null
-    property var item: null
-    property int sectionXOffset: 0
-    property int sectionYOffset: 0
-
-    x: (section && item)? (section.x + item.x + sectionXOffset):0;
-    y: (section && item)? (section.y + style.selectionSectionOffset + item.y + sectionYOffset):0;
-
-    Connections {
-        target: itemLibraryModel
-        onVisibilityUpdated: unselect()
-    }
-
-    function select(section, item, sectionXOffset, sectionYOffset) {
-
-        selector.item = item
-        selector.section = section
-        selector.sectionXOffset = sectionXOffset
-        selector.sectionYOffset = sectionYOffset
-
-        visible = true
-        focusSelection();
-    }
-
-    function unselect() {
-        section = null
-        item = null
-        sectionXOffset = 0
-        sectionYOffset = 0
-        visible = false
-    }
-
-    function focusSelection() {
-        var pos = -1;
-
-        if (y < flickable.viewportY)
-            pos = Math.max(0, y)
-
-        else if ((y + height) >
-                 (flickable.viewportY + flickable.height - 1))
-            pos = Math.min(Math.max(0, flickable.viewportHeight - flickable.height),
-		y + height - flickable.height + 1)
-
-        if (pos >= 0)
-            flickable.viewportY = pos;
-    }
-    
     SystemPalette { id:systemPalette }
 
     Rectangle {
-- 
GitLab