From 46df765740679d94af70beec6d2a69eb2ffc88a0 Mon Sep 17 00:00:00 2001
From: Alessandro Portale <alessandro.portale@digia.com>
Date: Tue, 3 Jun 2014 13:10:31 +0200
Subject: [PATCH] MimeTypeSettings: Use QTreeView instead of QTableView

QTreeView is a better list view with columns than QTableView.
One special reason for this change is that QTreeView
finds a proper default row height regardless of the system
DPI.

Change-Id: I0a4091585d4745fd91179c82a55682f88f8d2549
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
---
 .../coreplugin/mimetypemagicdialog.cpp        |   2 +
 src/plugins/coreplugin/mimetypesettings.cpp   |  92 ++----
 .../coreplugin/mimetypesettingspage.ui        | 292 +++++++++---------
 3 files changed, 172 insertions(+), 214 deletions(-)

diff --git a/src/plugins/coreplugin/mimetypemagicdialog.cpp b/src/plugins/coreplugin/mimetypemagicdialog.cpp
index f089231a4a..e24fd78811 100644
--- a/src/plugins/coreplugin/mimetypemagicdialog.cpp
+++ b/src/plugins/coreplugin/mimetypemagicdialog.cpp
@@ -30,6 +30,8 @@
 #include "mimetypemagicdialog.h"
 #include "mimedatabase.h"
 
+#include <utils/headerviewstretcher.h>
+
 #include <QMessageBox>
 
 using namespace Core;
diff --git a/src/plugins/coreplugin/mimetypesettings.cpp b/src/plugins/coreplugin/mimetypesettings.cpp
index 22824414ee..f2a589168a 100644
--- a/src/plugins/coreplugin/mimetypesettings.cpp
+++ b/src/plugins/coreplugin/mimetypesettings.cpp
@@ -36,6 +36,7 @@
 #include <coreplugin/editormanager/editormanager.h>
 #include <coreplugin/editormanager/ieditorfactory.h>
 #include <coreplugin/editormanager/iexternaleditor.h>
+#include <utils/headerviewstretcher.h>
 
 #include <QAbstractTableModel>
 #include <QCoreApplication>
@@ -45,7 +46,6 @@
 #include <QScopedPointer>
 #include <QSet>
 #include <QStringList>
-#include <QTableWidgetItem>
 #include <QSortFilterProxyModel>
 #include <QtAlgorithms>
 
@@ -118,9 +118,6 @@ QVariant MimeTypeSettingsModel::data(const QModelIndex &modelIndex, int role) co
             return type;
         else
             return m_handlersByMimeType.value(type);
-    } else if (role == Qt::TextAlignmentRole) {
-        if (column == 1)
-            return Qt::AlignCenter;
     }
     return QVariant();
 }
@@ -206,7 +203,6 @@ public:
     virtual ~MimeTypeSettingsPrivate();
 
     void configureUi(QWidget *w);
-    static void configureTable(QTableView *tableView);
 
     bool checkSelectedMimeType() const;
     bool checkSelectedMagicHeader() const;
@@ -277,12 +273,11 @@ void MimeTypeSettingsPrivate::configureUi(QWidget *w)
     m_model->load();
     connect(m_ui.filterLineEdit, SIGNAL(textChanged(QString)),
             this, SLOT(setFilterPattern(QString)));
-    m_ui.mimeTypesTableView->setModel(m_filterModel);
+    m_ui.mimeTypesTreeView->setModel(m_filterModel);
 
-    configureTable(m_ui.mimeTypesTableView);
-    configureTable(m_ui.magicHeadersTableWidget);
+    new Utils::HeaderViewStretcher(m_ui.mimeTypesTreeView->header(), 1);
 
-    connect(m_ui.mimeTypesTableView->selectionModel(),
+    connect(m_ui.mimeTypesTreeView->selectionModel(),
             SIGNAL(currentChanged(QModelIndex,QModelIndex)),
             this,
             SLOT(syncData(QModelIndex,QModelIndex)));
@@ -292,29 +287,15 @@ void MimeTypeSettingsPrivate::configureUi(QWidget *w)
     connect(m_ui.removeMagicButton, SIGNAL(clicked()), this, SLOT(removeMagicHeader()));
     connect(m_ui.editMagicButton, SIGNAL(clicked()), this, SLOT(editMagicHeader()));
     connect(m_ui.resetButton, SIGNAL(clicked()), this, SLOT(resetMimeTypes()));
-    connect(m_ui.magicHeadersTableWidget->selectionModel(),
-            SIGNAL(currentChanged(QModelIndex,QModelIndex)),
-            this,
+    connect(m_ui.magicHeadersTreeWidget,
+            SIGNAL(itemSelectionChanged()),
             SLOT(updateMagicHeaderButtons()));
     updateMagicHeaderButtons();
 }
 
-void MimeTypeSettingsPrivate::configureTable(QTableView *tableView)
-{
-    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
-    tableView->setSelectionMode(QAbstractItemView::SingleSelection);
-    tableView->verticalHeader()->setVisible(false);
-    tableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
-    tableView->horizontalHeader()->setResizeMode(0, QHeaderView::Interactive);
-    tableView->horizontalHeader()->resizeSection(
-        0, 4 * tableView->horizontalHeader()->defaultSectionSize());
-    tableView->horizontalHeader()->setHighlightSections(false);
-    tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
-}
-
 bool MimeTypeSettingsPrivate::checkSelectedMimeType() const
 {
-    const QModelIndex &modelIndex = m_ui.mimeTypesTableView->selectionModel()->currentIndex();
+    const QModelIndex &modelIndex = m_ui.mimeTypesTreeView->currentIndex();
     if (!modelIndex.isValid()) {
         QMessageBox::critical(0, tr("Error"), tr("No MIME type selected."));
         return false;
@@ -324,7 +305,7 @@ bool MimeTypeSettingsPrivate::checkSelectedMimeType() const
 
 bool MimeTypeSettingsPrivate::checkSelectedMagicHeader() const
 {
-    const QModelIndex &modelIndex = m_ui.magicHeadersTableWidget->selectionModel()->currentIndex();
+    const QModelIndex &modelIndex = m_ui.magicHeadersTreeWidget->selectionModel()->currentIndex();
     if (!modelIndex.isValid()) {
         QMessageBox::critical(0, tr("Error"), tr("No magic header selected."));
         return false;
@@ -371,7 +352,7 @@ void MimeTypeSettingsPrivate::syncMimeMagic()
 
     // Gather the magic rules.
     QHash<int, MagicRuleList> rulesByPriority;
-    for (int row = 0; row < m_ui.magicHeadersTableWidget->rowCount(); ++row) {
+    for (int row = 0; row < m_ui.magicHeadersTreeWidget->topLevelItemCount(); ++row) {
         const MagicData &data = getMagicHeaderRowData(row);
         // @TODO: Validate magic rule?
         MagicRule *magicRule;
@@ -404,8 +385,7 @@ void MimeTypeSettingsPrivate::syncData(const QModelIndex &current,
         clearSyncData();
 
         m_ui.patternsLineEdit->clear();
-        m_ui.magicHeadersTableWidget->clearContents();
-        m_ui.magicHeadersTableWidget->setRowCount(0);
+        m_ui.magicHeadersTreeWidget->clear();
     }
 
     if (current.isValid()) {
@@ -436,7 +416,7 @@ void MimeTypeSettingsPrivate::syncData(const QModelIndex &current,
 void MimeTypeSettingsPrivate::handlePatternEdited()
 {
     if (m_mimeForPatternSync == -1) {
-        const QModelIndex &modelIndex = m_ui.mimeTypesTableView->selectionModel()->currentIndex();
+        const QModelIndex &modelIndex = m_ui.mimeTypesTreeView->currentIndex();
         if (modelIndex.isValid())
             markMimeForPatternSync(m_filterModel->mapToSource(modelIndex).row());
     }
@@ -444,42 +424,34 @@ void MimeTypeSettingsPrivate::handlePatternEdited()
 
 void MimeTypeSettingsPrivate::addMagicHeaderRow(const MagicData &data)
 {
-    const int row = m_ui.magicHeadersTableWidget->rowCount();
-    m_ui.magicHeadersTableWidget->insertRow(row);
+    const int row = m_ui.magicHeadersTreeWidget->topLevelItemCount();
     editMagicHeaderRowData(row, data);
 }
 
 MagicData MimeTypeSettingsPrivate::getMagicHeaderRowData(const int row) const
 {
     MagicData data;
-    data.m_value = m_ui.magicHeadersTableWidget->item(row, 0)->text();
-    data.m_type = m_ui.magicHeadersTableWidget->item(row, 1)->text();
+    data.m_value = m_ui.magicHeadersTreeWidget->topLevelItem(row)->text(0);
+    data.m_type = m_ui.magicHeadersTreeWidget->topLevelItem(row)->text(1);
     QPair<int, int> startEnd =
-        MagicRule::fromOffset(m_ui.magicHeadersTableWidget->item(row, 2)->text());
+        MagicRule::fromOffset(m_ui.magicHeadersTreeWidget->topLevelItem(row)->text(2));
     data.m_start = startEnd.first;
     data.m_end = startEnd.second;
-    data.m_priority = m_ui.magicHeadersTableWidget->item(row, 3)->text().toInt();
+    data.m_priority = m_ui.magicHeadersTreeWidget->topLevelItem(row)->text(3).toInt();
 
     return data;
 }
 
 void MimeTypeSettingsPrivate::editMagicHeaderRowData(const int row, const MagicData &data)
 {
-    for (int col = 0; col < m_ui.magicHeadersTableWidget->columnCount(); ++col) {
-        QTableWidgetItem *item = new QTableWidgetItem;
-        if (col == 0) {
-            item->setText(data.m_value);
-        } else {
-            item->setTextAlignment(Qt::AlignCenter);
-            if (col == 1)
-                item->setText(data.m_type);
-            else if (col == 2)
-                item->setText(MagicRule::toOffset(qMakePair(data.m_start, data.m_end)));
-            else
-                item->setText(QString::number(data.m_priority));
-        }
-        m_ui.magicHeadersTableWidget->setItem(row, col, item);
-    }
+    QTreeWidgetItem *item = new QTreeWidgetItem;
+    item->setText(0, data.m_value);
+    item->setText(1, data.m_type);
+    item->setText(2, MagicRule::toOffset(qMakePair(data.m_start, data.m_end)));
+    item->setText(3, QString::number(data.m_priority));
+    m_ui.magicHeadersTreeWidget->takeTopLevelItem(row);
+    m_ui.magicHeadersTreeWidget->insertTopLevelItem(row, item);
+    m_ui.magicHeadersTreeWidget->setCurrentItem(item);
 }
 
 void MimeTypeSettingsPrivate::addMagicHeader()
@@ -491,7 +463,7 @@ void MimeTypeSettingsPrivate::addMagicHeader()
     if (dlg.exec()) {
         addMagicHeaderRow(dlg.magicData());
         markMimeForMagicSync(m_filterModel->mapToSource(
-            m_ui.mimeTypesTableView->selectionModel()->currentIndex()).row());
+            m_ui.mimeTypesTreeView->currentIndex()).row());
     }
 }
 
@@ -500,9 +472,9 @@ void MimeTypeSettingsPrivate::removeMagicHeader()
     if (!checkSelectedMagicHeader())
         return;
 
-    m_ui.magicHeadersTableWidget->removeRow(m_ui.magicHeadersTableWidget->currentRow());
+    m_ui.magicHeadersTreeWidget->takeTopLevelItem(m_ui.magicHeadersTreeWidget->indexOfTopLevelItem(m_ui.magicHeadersTreeWidget->currentItem()));
     markMimeForMagicSync(m_filterModel->mapToSource(
-        m_ui.mimeTypesTableView->selectionModel()->currentIndex()).row());
+        m_ui.mimeTypesTreeView->currentIndex()).row());
 }
 
 void MimeTypeSettingsPrivate::editMagicHeader()
@@ -511,11 +483,11 @@ void MimeTypeSettingsPrivate::editMagicHeader()
         return;
 
     MimeTypeMagicDialog dlg;
-    dlg.setMagicData(getMagicHeaderRowData(m_ui.magicHeadersTableWidget->currentRow()));
+    dlg.setMagicData(getMagicHeaderRowData(m_ui.magicHeadersTreeWidget->indexOfTopLevelItem(m_ui.magicHeadersTreeWidget->currentItem())));
     if (dlg.exec()) {
-        editMagicHeaderRowData(m_ui.magicHeadersTableWidget->currentRow(), dlg.magicData());
+        editMagicHeaderRowData(m_ui.magicHeadersTreeWidget->indexOfTopLevelItem(m_ui.magicHeadersTreeWidget->currentItem()), dlg.magicData());
         markMimeForMagicSync(m_filterModel->mapToSource(
-            m_ui.mimeTypesTableView->selectionModel()->currentIndex()).row());
+            m_ui.mimeTypesTreeView->currentIndex()).row());
     }
 }
 
@@ -558,7 +530,7 @@ void MimeTypeSettingsPrivate::resetMimeTypes()
 
 void MimeTypeSettingsPrivate::updateMagicHeaderButtons()
 {
-    const QModelIndex &modelIndex = m_ui.magicHeadersTableWidget->selectionModel()->currentIndex();
+    const QModelIndex &modelIndex = m_ui.magicHeadersTreeWidget->currentIndex();
     const bool enabled = modelIndex.isValid();
 
     m_ui.removeMagicButton->setEnabled(enabled);
@@ -602,7 +574,7 @@ void MimeTypeSettings::apply()
 {
     if (!d->m_modifiedMimeTypes.isEmpty()) {
         const QModelIndex &modelIndex =
-            d->m_ui.mimeTypesTableView->selectionModel()->currentIndex();
+            d->m_ui.mimeTypesTreeView->currentIndex();
         if (modelIndex.isValid()) {
             if (d->m_mimeForPatternSync == d->m_filterModel->mapToSource(modelIndex).row())
                 d->syncMimePattern();
diff --git a/src/plugins/coreplugin/mimetypesettingspage.ui b/src/plugins/coreplugin/mimetypesettingspage.ui
index 095494b528..2b4e6fbadc 100644
--- a/src/plugins/coreplugin/mimetypesettingspage.ui
+++ b/src/plugins/coreplugin/mimetypesettingspage.ui
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>593</width>
-    <height>403</height>
+    <width>712</width>
+    <height>696</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -15,174 +15,158 @@
   </property>
   <layout class="QVBoxLayout" name="verticalLayout_2">
    <item>
-    <widget class="QGroupBox" name="mimeTypesGroupBox">
-     <property name="title">
-      <string>Registered MIME Types</string>
+    <widget class="QSplitter" name="splitter">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
      </property>
-     <layout class="QGridLayout" name="gridLayout">
-      <item row="0" column="0" colspan="2">
-       <widget class="QLineEdit" name="filterLineEdit">
-        <property name="placeholderText">
-         <string>Filter</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0" colspan="2">
-       <widget class="QTableView" name="mimeTypesTableView">
-        <property name="showGrid">
-         <bool>false</bool>
-        </property>
-        <property name="gridStyle">
-         <enum>Qt::NoPen</enum>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="0">
-       <widget class="QPushButton" name="resetButton">
-        <property name="toolTip">
-         <string>Reset all to default.</string>
-        </property>
-        <property name="text">
-         <string>Reset All</string>
-        </property>
-       </widget>
-      </item>
-      <item row="2" column="1">
-       <spacer name="horizontalSpacer">
-        <property name="orientation">
-         <enum>Qt::Horizontal</enum>
-        </property>
-        <property name="sizeHint" stdset="0">
-         <size>
-          <width>476</width>
-          <height>20</height>
-         </size>
-        </property>
-       </spacer>
-      </item>
-     </layout>
-    </widget>
-   </item>
-   <item>
-    <widget class="QGroupBox" name="detailsGroupBox">
-     <property name="title">
-      <string>Details</string>
+     <property name="childrenCollapsible">
+      <bool>false</bool>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout_4">
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout">
-        <item>
-         <widget class="QLabel" name="patternsLabel">
-          <property name="text">
-           <string>Patterns:</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QLineEdit" name="patternsLineEdit"/>
-        </item>
-       </layout>
-      </item>
-      <item>
-       <layout class="QHBoxLayout" name="horizontalLayout_2">
-        <item>
-         <widget class="QTableWidget" name="magicHeadersTableWidget">
-          <property name="sizePolicy">
-           <sizepolicy hsizetype="Expanding" vsizetype="Maximum">
-            <horstretch>0</horstretch>
-            <verstretch>0</verstretch>
-           </sizepolicy>
-          </property>
-          <property name="maximumSize">
-           <size>
-            <width>16777215</width>
-            <height>100</height>
-           </size>
-          </property>
-          <property name="showGrid">
-           <bool>false</bool>
-          </property>
-          <property name="gridStyle">
-           <enum>Qt::NoPen</enum>
-          </property>
-          <column>
+     <widget class="QGroupBox" name="mimeTypesGroupBox">
+      <property name="title">
+       <string>Registered MIME Types</string>
+      </property>
+      <layout class="QGridLayout" name="gridLayout">
+       <item row="0" column="0" colspan="2">
+        <widget class="QLineEdit" name="filterLineEdit">
+         <property name="placeholderText">
+          <string>Filter</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0">
+        <widget class="QPushButton" name="resetButton">
+         <property name="toolTip">
+          <string>Reset all to default.</string>
+         </property>
+         <property name="text">
+          <string>Reset All</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1">
+        <spacer name="horizontalSpacer">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>476</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="1" column="0" colspan="2">
+        <widget class="QTreeView" name="mimeTypesTreeView">
+         <property name="rootIsDecorated">
+          <bool>false</bool>
+         </property>
+         <property name="uniformRowHeights">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QGroupBox" name="detailsGroupBox">
+      <property name="title">
+       <string>Details</string>
+      </property>
+      <layout class="QVBoxLayout" name="verticalLayout_4">
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout">
+         <item>
+          <widget class="QLabel" name="patternsLabel">
            <property name="text">
-            <string>Magic Header</string>
+            <string>Patterns:</string>
            </property>
-          </column>
-          <column>
-           <property name="text">
-            <string>Type</string>
+          </widget>
+         </item>
+         <item>
+          <widget class="QLineEdit" name="patternsLineEdit"/>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QHBoxLayout" name="horizontalLayout_2">
+         <item>
+          <widget class="QTreeWidget" name="magicHeadersTreeWidget">
+           <property name="rootIsDecorated">
+            <bool>false</bool>
            </property>
-          </column>
-          <column>
-           <property name="text">
-            <string>Range</string>
+           <property name="uniformRowHeights">
+            <bool>true</bool>
            </property>
-          </column>
-          <column>
-           <property name="text">
-            <string>Priority</string>
+           <property name="columnCount">
+            <number>4</number>
            </property>
-          </column>
-         </widget>
-        </item>
-        <item>
-         <layout class="QVBoxLayout" name="verticalLayout">
-          <item>
-           <widget class="QPushButton" name="addMagicButton">
+           <column>
             <property name="text">
-             <string>Add...</string>
+             <string notr="true">Magic Header</string>
             </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QPushButton" name="editMagicButton">
+           </column>
+           <column>
             <property name="text">
-             <string>Edit...</string>
+             <string>Type</string>
             </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QPushButton" name="removeMagicButton">
+           </column>
+           <column>
             <property name="text">
-             <string>Remove</string>
+             <string>Range</string>
             </property>
-           </widget>
-          </item>
-          <item>
-           <spacer name="verticalSpacer_2">
-            <property name="orientation">
-             <enum>Qt::Vertical</enum>
-            </property>
-            <property name="sizeHint" stdset="0">
-             <size>
-              <width>72</width>
-              <height>18</height>
-             </size>
+           </column>
+           <column>
+            <property name="text">
+             <string>Priority</string>
             </property>
-           </spacer>
-          </item>
-         </layout>
-        </item>
-       </layout>
-      </item>
-     </layout>
+           </column>
+          </widget>
+         </item>
+         <item>
+          <layout class="QVBoxLayout" name="verticalLayout">
+           <item>
+            <widget class="QPushButton" name="addMagicButton">
+             <property name="text">
+              <string>Add...</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QPushButton" name="editMagicButton">
+             <property name="text">
+              <string>Edit...</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <widget class="QPushButton" name="removeMagicButton">
+             <property name="text">
+              <string>Remove</string>
+             </property>
+            </widget>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_2">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>72</width>
+               <height>18</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </item>
+        </layout>
+       </item>
+      </layout>
+     </widget>
     </widget>
    </item>
-   <item>
-    <spacer name="verticalSpacer_3">
-     <property name="orientation">
-      <enum>Qt::Vertical</enum>
-     </property>
-     <property name="sizeHint" stdset="0">
-      <size>
-       <width>504</width>
-       <height>16</height>
-      </size>
-     </property>
-    </spacer>
-   </item>
   </layout>
  </widget>
  <resources/>
-- 
GitLab