diff --git a/src/plugins/find/searchresulttreeitemdelegate.cpp b/src/plugins/find/searchresulttreeitemdelegate.cpp
index 379db290b1243556b33fab769d9ac494517e25ca..807381f4cfc41ed3783cdca0341eb79e70f081be 100644
--- a/src/plugins/find/searchresulttreeitemdelegate.cpp
+++ b/src/plugins/find/searchresulttreeitemdelegate.cpp
@@ -48,6 +48,8 @@ SearchResultTreeItemDelegate::SearchResultTreeItemDelegate(QObject *parent)
 
 void SearchResultTreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
 {
+    static const int iconSize = 16;
+
     painter->save();
 
     QStyleOptionViewItemV3 opt = setOptions(index, option);
@@ -55,56 +57,63 @@ void SearchResultTreeItemDelegate::paint(QPainter *painter, const QStyleOptionVi
 
     QItemDelegate::drawBackground(painter, opt, index);
 
-    int iconAreaWidth = drawIcon(painter, opt, opt.rect, index);
-    QRect resultRowRect(opt.rect.adjusted(iconAreaWidth, 0, 0, 0));
+    // ---- do the layout
+    QRect checkRect;
+    QRect pixmapRect;
+    QRect textRect;
+
+    // check mark
+    bool checkable = (index.model()->flags(index) & Qt::ItemIsUserCheckable);
+    Qt::CheckState checkState = Qt::Unchecked;
+    if (checkable) {
+        QVariant checkStateData = index.data(Qt::CheckStateRole);
+        checkState = static_cast<Qt::CheckState>(checkStateData.toInt());
+        checkRect = check(opt, opt.rect, checkStateData);
+    }
+
+    // icon
+    QIcon icon = index.model()->data(index, ItemDataRoles::ResultIconRole).value<QIcon>();
+    if (!icon.isNull()) {
+        pixmapRect = QRect(0, 0, iconSize, iconSize);
+    }
 
-    int lineNumberAreaWidth = drawLineNumber(painter, opt, resultRowRect, index);
-    resultRowRect.adjust(lineNumberAreaWidth, 0, 0, 0);
+    // text
+    textRect = opt.rect.adjusted(0, 0, checkRect.width() + pixmapRect.width(), 0);
 
+    // do layout
+    doLayout(opt, &checkRect, &pixmapRect, &textRect, false);
+
+    // ---- draw the items
+    // icon
+    if (!icon.isNull())
+        QItemDelegate::drawDecoration(painter, opt, pixmapRect, icon.pixmap(iconSize));
+
+    // line numbers
+    int lineNumberAreaWidth = drawLineNumber(painter, opt, textRect, index);
+    textRect.adjust(lineNumberAreaWidth, 0, 0, 0);
+
+    // selected text
     QString displayString = index.model()->data(index, Qt::DisplayRole).toString();
-    drawMarker(painter, index, displayString, resultRowRect);
+    drawMarker(painter, index, displayString, textRect);
 
-    // Show number of subresults in displayString
+    // show number of subresults in displayString
     if (index.model()->hasChildren(index)) {
         displayString += QString::fromLatin1(" (")
                          + QString::number(index.model()->rowCount(index))
                          + QLatin1Char(')');
     }
 
-    // Draw the text and focus/selection
-    QItemDelegate::drawDisplay(painter, opt, resultRowRect, displayString);
+    // text and focus/selection
+    QItemDelegate::drawDisplay(painter, opt, textRect, displayString);
     QItemDelegate::drawFocus(painter, opt, opt.rect);
 
-    QVariant value = index.data(Qt::CheckStateRole);
-    if (value.isValid()) {
-        Qt::CheckState checkState = Qt::Unchecked;
-        checkState = static_cast<Qt::CheckState>(value.toInt());
-        QRect checkRect = check(opt, opt.rect, value);
-
-        QRect emptyRect;
-        doLayout(opt, &checkRect, &emptyRect, &emptyRect, false);
-
+    // check mark
+    if (checkable)
         QItemDelegate::drawCheck(painter, opt, checkRect, checkState);
-    }
 
     painter->restore();
 }
 
-int SearchResultTreeItemDelegate::drawIcon(QPainter *painter, const QStyleOptionViewItemV3 &option,
-                                                 const QRect &rect,
-                                                 const QModelIndex &index) const
-{
-    static const int iconWidth = 16;
-    static const int iconPadding = 4;
-    QIcon icon = index.model()->data(index, ItemDataRoles::ResultIconRole).value<QIcon>();
-    if (icon.isNull())
-        return 0;
-    QRect iconRect = rect.adjusted(iconPadding, 0, /*is set below anyhow*/0, 0);
-    iconRect.setWidth(iconWidth);
-    QItemDelegate::drawDecoration(painter, option, iconRect, icon.pixmap(iconWidth));
-    return iconWidth + iconPadding;
-}
-
 int SearchResultTreeItemDelegate::drawLineNumber(QPainter *painter, const QStyleOptionViewItemV3 &option,
                                                  const QRect &rect,
                                                  const QModelIndex &index) const
diff --git a/src/plugins/find/searchresulttreeitemdelegate.h b/src/plugins/find/searchresulttreeitemdelegate.h
index d9fe62cc7f0dac7c4ef9f4bf50080af0e3562ae6..c788a94437b3806eecf629072fd86e9274880e16 100644
--- a/src/plugins/find/searchresulttreeitemdelegate.h
+++ b/src/plugins/find/searchresulttreeitemdelegate.h
@@ -42,7 +42,6 @@ public:
     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
 
 private:
-    int drawIcon(QPainter *painter, const QStyleOptionViewItemV3 &option, const QRect &rect, const QModelIndex &index) const;
     int drawLineNumber(QPainter *painter, const QStyleOptionViewItemV3 &option, const QRect &rect, const QModelIndex &index) const;
     void drawMarker(QPainter *painter, const QModelIndex &index, const QString text, const QRect &rect) const;
 
diff --git a/src/plugins/find/searchresulttreeitems.cpp b/src/plugins/find/searchresulttreeitems.cpp
index 9f240680f37d4fc97ea926af90585e3f21836032..d318b4eae6643cb83b428a80615835d0fdef3e0a 100644
--- a/src/plugins/find/searchresulttreeitems.cpp
+++ b/src/plugins/find/searchresulttreeitems.cpp
@@ -32,7 +32,7 @@
 using namespace Find::Internal;
 
 SearchResultTreeItem::SearchResultTreeItem(const Find::SearchResultItem &item,
-                                           const SearchResultTreeItem *parent)
+                                           SearchResultTreeItem *parent)
   : item(item),
   m_parent(parent),
   m_isUserCheckable(false),
@@ -92,7 +92,7 @@ SearchResultTreeItem* SearchResultTreeItem::childAt(int index) const
     return m_children.at(index);
 }
 
-const SearchResultTreeItem *SearchResultTreeItem::parent() const
+SearchResultTreeItem *SearchResultTreeItem::parent() const
 {
     return m_parent;
 }
diff --git a/src/plugins/find/searchresulttreeitems.h b/src/plugins/find/searchresulttreeitems.h
index ac7fab03d175c335591b1bdda7e512f816964a7a..1c77eb9f6708bf966094f4a4739c9597b81667ca 100644
--- a/src/plugins/find/searchresulttreeitems.h
+++ b/src/plugins/find/searchresulttreeitems.h
@@ -44,11 +44,11 @@ class SearchResultTreeItem
 {
 public:
     SearchResultTreeItem(const SearchResultItem &item = SearchResultItem(),
-                         const SearchResultTreeItem *parent = NULL);
+                         SearchResultTreeItem *parent = NULL);
     virtual ~SearchResultTreeItem();
 
     bool isLeaf() const;
-    const SearchResultTreeItem *parent() const;
+    SearchResultTreeItem *parent() const;
     SearchResultTreeItem *childAt(int index) const;
     int insertionIndex(const QString &text, SearchResultTreeItem **existingItem) const;
     int insertionIndex(const SearchResultItem &item, SearchResultTreeItem **existingItem) const;
@@ -71,7 +71,7 @@ public:
     SearchResultItem item;
 
 private:
-    const SearchResultTreeItem *m_parent;
+    SearchResultTreeItem *m_parent;
     QList<SearchResultTreeItem *> m_children;
     bool m_isUserCheckable;
     Qt::CheckState m_checkState;
diff --git a/src/plugins/find/searchresulttreemodel.cpp b/src/plugins/find/searchresulttreemodel.cpp
index a03922114dc6adb77925f6ca03c3607b1e9d2a84..0c19da073ca0f3b1bb3ef072c85a15f1519ad5ad 100644
--- a/src/plugins/find/searchresulttreemodel.cpp
+++ b/src/plugins/find/searchresulttreemodel.cpp
@@ -76,7 +76,7 @@ Qt::ItemFlags SearchResultTreeModel::flags(const QModelIndex &idx) const
 
     if (idx.isValid()) {
         if (const SearchResultTreeItem *item = treeItemAtIndex(idx)) {
-            if (item->isLeaf() && item->isUserCheckable()) {
+            if (item->isUserCheckable()) {
                 flags |= Qt::ItemIsUserCheckable;
             }
         }
@@ -173,12 +173,62 @@ bool SearchResultTreeModel::setData(const QModelIndex &idx, const QVariant &valu
 {
     if (role == Qt::CheckStateRole) {
         Qt::CheckState checkState = static_cast<Qt::CheckState>(value.toInt());
-        treeItemAtIndex(idx)->setCheckState(checkState);
-        return true;
+        return setCheckState(idx, checkState);
     }
     return QAbstractItemModel::setData(idx, value, role);
 }
 
+bool SearchResultTreeModel::setCheckState(const QModelIndex &idx, Qt::CheckState checkState, bool firstCall)
+{
+    SearchResultTreeItem *item = treeItemAtIndex(idx);
+    if (item->checkState() == checkState)
+        return false;
+    item->setCheckState(checkState);
+    if (firstCall) {
+        emit dataChanged(idx, idx);
+        // check parents
+        SearchResultTreeItem *currentItem = item;
+        QModelIndex currentIndex = idx;
+        while (SearchResultTreeItem *parent = currentItem->parent()) {
+            if (parent->isUserCheckable()) {
+                bool hasChecked = false;
+                bool hasUnchecked = false;
+                for (int i = 0; i < parent->childrenCount(); ++i) {
+                    SearchResultTreeItem *child = parent->childAt(i);
+                    if (!child->isUserCheckable())
+                        continue;
+                    if (child->checkState() == Qt::Checked) {
+                        hasChecked = true;
+                    } else if (child->checkState() == Qt::Unchecked) {
+                        hasUnchecked = true;
+                    } else if (child->checkState() == Qt::PartiallyChecked) {
+                        hasChecked = hasUnchecked = true;
+                    }
+                }
+                if (hasChecked && hasUnchecked)
+                    parent->setCheckState(Qt::PartiallyChecked);
+                else if (hasChecked)
+                    parent->setCheckState(Qt::Checked);
+                else
+                    parent->setCheckState(Qt::Unchecked);
+                emit dataChanged(idx.parent(), idx.parent());
+            }
+            currentItem = parent;
+            currentIndex = idx.parent();
+        }
+    }
+    // check children
+    if (int children = item->childrenCount()) {
+        for (int i = 0; i < children; ++i) {
+            setCheckState(idx.child(i, 0), checkState, false);
+        }
+        emit dataChanged(idx.child(0, 0), idx.child(children-1, 0));
+    }
+    return true;
+}
+
+void setDataInternal(const QModelIndex &index, const QVariant &value, int role);
+
 QVariant SearchResultTreeModel::data(const SearchResultTreeItem *row, int role) const
 {
     QVariant result;
diff --git a/src/plugins/find/searchresulttreemodel.h b/src/plugins/find/searchresulttreemodel.h
index ef0cfefce8e9ef18cfe1cf0acab0924010ef36a3..935eab2f12589387004f1422c90725d302c146d9 100644
--- a/src/plugins/find/searchresulttreemodel.h
+++ b/src/plugins/find/searchresulttreemodel.h
@@ -82,6 +82,7 @@ private:
     void addResultsToCurrentParent(const QList<SearchResultItem> &items, SearchResultWindow::AddMode mode);
     QSet<SearchResultTreeItem *> addPath(const QStringList &path);
     QVariant data(const SearchResultTreeItem *row, int role) const;
+    bool setCheckState(const QModelIndex &idx, Qt::CheckState checkState, bool firstCall = true);
     QModelIndex nextIndex(const QModelIndex &idx) const;
     QModelIndex prevIndex(const QModelIndex &idx) const;
     SearchResultTreeItem *treeItemAtIndex(const QModelIndex &idx) const;