Merge from Qt Creator. Adds geometry awareness.
authorkh1 <karsten.heimrich@digia.com>
Wed, 19 Dec 2012 13:08:35 +0000 (14:08 +0100)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Wed, 9 Jan 2013 11:40:05 +0000 (12:40 +0100)
Task-number: QTBUG-22619

Change-Id: I34cd11c1021592560776e78452072c335b1ead21
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
src/assistant/assistant/helpenginewrapper.cpp
src/assistant/assistant/helpenginewrapper.h
src/assistant/assistant/topicchooser.cpp
src/assistant/assistant/topicchooser.h
src/assistant/assistant/topicchooser.ui

index 0a9d423..e5e8441 100644 (file)
@@ -74,6 +74,7 @@ namespace {
     const QString VersionKey(QString(QLatin1String("qtVersion%1$$$%2")).
                              arg(QLatin1String(QT_VERSION_STR)));
     const QString ShowTabsKey(QLatin1String("showTabs"));
+    const QString TopicChooserGeometryKey(QLatin1String("TopicChooserGeometry"));
 } // anonymous namespace
 
 class TimeoutForwarder : public QObject
@@ -730,6 +731,18 @@ bool HelpEngineWrapper::fullTextSearchFallbackEnabled() const
     return CollectionConfiguration::fullTextSearchFallbackEnabled(*d->m_helpEngine);
 }
 
+const QByteArray HelpEngineWrapper::topicChooserGeometry() const
+{
+    TRACE_OBJ
+    return d->m_helpEngine->customValue(TopicChooserGeometryKey).toByteArray();
+}
+
+void HelpEngineWrapper::setTopicChooserGeometry(const QByteArray &geometry)
+{
+    TRACE_OBJ
+    d->m_helpEngine->setCustomValue(TopicChooserGeometryKey, geometry);
+}
+
 // -- TimeoutForwarder
 
 TimeoutForwarder::TimeoutForwarder(const QString &fileName)
index 8b86946..d352bd6 100644 (file)
@@ -192,6 +192,9 @@ public:
 
     bool fullTextSearchFallbackEnabled() const;
 
+    const QByteArray topicChooserGeometry() const;
+    void setTopicChooserGeometry(const QByteArray &geometry);
+
 signals:
 
     // For asynchronous doc updates triggered by external actions.
index 7ff8303..b5c502e 100644 (file)
 #include "tracer.h"
 
 #include "topicchooser.h"
+#include "helpenginewrapper.h"
+
+#include <QKeyEvent>
+#include <QStandardItemModel>
+#include <QSortFilterProxyModel>
+#include <QUrl>
 
 QT_BEGIN_NAMESPACE
 
-TopicChooser::TopicChooser(QWidget *parent, const QString &keyword,
-                         const QMap<QString, QUrl> &links)
+TopicChooser::TopicChooser(QWidget *parent, const QString &keyword, const QMap<QString, QUrl> &links)
     : QDialog(parent)
+    , m_filterModel(new QSortFilterProxyModel(this))
 {
     TRACE_OBJ
     ui.setupUi(this);
+
+    setFocusProxy(ui.lineEdit);
+    ui.lineEdit->installEventFilter(this);
+    ui.lineEdit->setPlaceholderText(tr("Filter"));
     ui.label->setText(tr("Choose a topic for <b>%1</b>:").arg(keyword));
 
+    QStandardItemModel *model = new QStandardItemModel(this);
+    m_filterModel->setSourceModel(model);
+    m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+
     QMap<QString, QUrl>::const_iterator it = links.constBegin();
     for (; it != links.constEnd(); ++it) {
-        ui.listWidget->addItem(it.key());
         m_links.append(it.value());
+        QStandardItem *item = new QStandardItem(it.key());
+        item->setToolTip(it.value().toString());
+        model->appendRow(item);
     }
-    
-    if (ui.listWidget->count() != 0)
-        ui.listWidget->setCurrentRow(0);
-    ui.listWidget->setFocus();
 
-    connect(ui.buttonDisplay, SIGNAL(clicked()), this, SLOT(accept()));
+    ui.listWidget->setModel(m_filterModel);
+    ui.listWidget->setUniformItemSizes(true);
+    ui.listWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
+
+    if (m_filterModel->rowCount() != 0)
+        ui.listWidget->setCurrentIndex(m_filterModel->index(0, 0));
+
     connect(ui.buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
-    connect(ui.listWidget, SIGNAL(itemActivated(QListWidgetItem*)), this,
-        SLOT(accept()));
+    connect(ui.buttonDisplay, SIGNAL(clicked()), this, SLOT(acceptDialog()));
+    connect(ui.lineEdit, SIGNAL(textChanged(QString)), this, SLOT(setFilter(QString)));
+    connect(ui.listWidget, SIGNAL(activated(QModelIndex)), this, SLOT(activated(QModelIndex)));
+
+    const QByteArray ba = HelpEngineWrapper::instance().topicChooserGeometry();
+    if (!ba.isEmpty())
+        restoreGeometry(ba);
+}
+
+TopicChooser::~TopicChooser()
+{
+    HelpEngineWrapper::instance().setTopicChooserGeometry(saveGeometry());
 }
 
 QUrl TopicChooser::link() const
 {
     TRACE_OBJ
-    QListWidgetItem *item = ui.listWidget->currentItem();
-    if (!item)
-        return QUrl();
+    if (m_activedIndex.isValid())
+        return m_links.at(m_filterModel->mapToSource(m_activedIndex).row());
+    return QUrl();
+}
+
+void TopicChooser::acceptDialog()
+{
+    TRACE_OBJ
+    m_activedIndex = ui.listWidget->currentIndex();
+    accept();
+}
 
-    QString title = item->text();
-    if (title.isEmpty())
-        return QUrl();
+void TopicChooser::setFilter(const QString &pattern)
+{
+    TRACE_OBJ
+    m_filterModel->setFilterFixedString(pattern);
+    if (m_filterModel->rowCount() != 0 && !ui.listWidget->currentIndex().isValid())
+        ui.listWidget->setCurrentIndex(m_filterModel->index(0, 0));
+}
 
-    const int row = ui.listWidget->row(item);
-    Q_ASSERT(row < m_links.count());
-    return m_links.at(row);
+void TopicChooser::activated(const QModelIndex &index)
+{
+    TRACE_OBJ
+    m_activedIndex = index;
+    accept();
+}
+
+bool TopicChooser::eventFilter(QObject *object, QEvent *event)
+{
+    TRACE_OBJ
+    if (object == ui.lineEdit && event->type() == QEvent::KeyPress) {
+        QModelIndex idx = ui.listWidget->currentIndex();
+        switch ((static_cast<QKeyEvent*>(event)->key())) {
+            case Qt::Key_Up:
+                idx = m_filterModel->index(idx.row() - 1, idx.column(),
+                    idx.parent());
+                if (idx.isValid())
+                    ui.listWidget->setCurrentIndex(idx);
+                break;
+
+            case Qt::Key_Down:
+                idx = m_filterModel->index(idx.row() + 1, idx.column(),
+                    idx.parent());
+                if (idx.isValid())
+                    ui.listWidget->setCurrentIndex(idx);
+                break;
+
+            default: ;
+        }
+    } else if (ui.lineEdit && event->type() == QEvent::FocusIn
+        && static_cast<QFocusEvent *>(event)->reason() != Qt::MouseFocusReason) {
+            ui.lineEdit->selectAll();
+            ui.lineEdit->setFocus();
+    }
+    return QDialog::eventFilter(object, event);
 }
 
 QT_END_NAMESPACE
index e66a337..6d77005 100644 (file)
 
 #include "ui_topicchooser.h"
 
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QUrl>
-
 #include <QtWidgets/QDialog>
 
 QT_BEGIN_NAMESPACE
 
+class QSortFilterProxyModel;
+
 class TopicChooser : public QDialog
 {
     Q_OBJECT
 
 public:
-    TopicChooser(QWidget *parent, const QString &keyword,
-        const QMap<QString, QUrl> &links);
+    TopicChooser(QWidget *parent, const QString &keyword, const QMap<QString, QUrl> &links);
+    ~TopicChooser();
+
+    QUrl link() const;
+
+private slots:
+    void acceptDialog();
+    void setFilter(const QString &pattern);
+    void activated(const QModelIndex &index);
+
+private:
+    bool eventFilter(QObject *object, QEvent *event);
 
-    QUrl link() const;    
-    
 private:
     Ui::TopicChooser ui;
     QList<QUrl> m_links;
+
+    QModelIndex m_activedIndex;
+    QSortFilterProxyModel *m_filterModel;
 };
 
 QT_END_NAMESPACE
index d4c90bb..b28a5e7 100644 (file)
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <UI version="4.0" stdsetdef="1" >
  <class>TopicChooser</class> 
  <widget class="QDialog" name="TopicChooser" >
     </widget>
    </item>
    <item>
-    <widget class="QListWidget" name="listWidget" >
-     <property name="objectName" >
-      <string notr="true">listWidget</string>
-     </property>     
-    </widget>
+    <widget class="QLineEdit" name="lineEdit" />
+   </item>
+   <item>
+    <widget class="QListView" name="listWidget" />
    </item>
    <item>
-    <widget class="QWidget" name="Layout16" >
-     <property name="objectName" >
-      <string notr="true">Layout16</string>
-     </property>
      <layout class="QHBoxLayout" >
       <property name="objectName" >
        <string notr="true">unnamed</string>
          <bool>true</bool>
         </property>        
        </widget>
-      </item>
-     </layout>
-    </widget>
+     </item>
+    </layout>
    </item>
   </layout>
  </widget>