Fix broken keyboard navigation in the new file/project dialog

* Enabled proper keyboard navigation
* Skip header items when using arrow keys
* Fixed a static pixmap warning

Task-number: QTCREATORBUG-1237

Reviewed-by: Daniel Molkentin
This commit is contained in:
Jens Bache-Wiig
2010-04-20 19:07:36 +02:00
parent e00464d2b4
commit fa2d2717a9
4 changed files with 71 additions and 46 deletions

View File

@@ -34,6 +34,7 @@
#include <QMap> #include <QMap>
#include <QHash> #include <QHash>
#include <QVariant> #include <QVariant>
#include <QStyle>
namespace Utils { namespace Utils {

View File

@@ -37,6 +37,7 @@
#include <coreplugin/dialogs/iwizard.h> #include <coreplugin/dialogs/iwizard.h>
#include <QtGui/QAbstractProxyModel> #include <QtGui/QAbstractProxyModel>
#include <QtGui/QItemSelectionModel>
#include <QtGui/QHeaderView> #include <QtGui/QHeaderView>
#include <QtGui/QPushButton> #include <QtGui/QPushButton>
#include <QtGui/QStandardItem> #include <QtGui/QStandardItem>
@@ -92,15 +93,6 @@ public:
return QModelIndex(); return QModelIndex();
return static_cast<TwoLevelProxyModel*>(sourceModel())->createIndex(index.row(), index.column(), index.internalPointer()); return static_cast<TwoLevelProxyModel*>(sourceModel())->createIndex(index.row(), index.column(), index.internalPointer());
} }
Qt::ItemFlags flags(const QModelIndex &index) const
{
Qt::ItemFlags f = sourceModel()->flags(index);
if (!index.parent().isValid())
return f ^ Qt::ItemIsSelectable;
else
return f;
}
}; };
#define CATEGORY_ROW_HEIGHT 18 #define CATEGORY_ROW_HEIGHT 18
@@ -111,10 +103,10 @@ public:
FancyTopLevelDelegate(QObject *parent = 0) FancyTopLevelDelegate(QObject *parent = 0)
: QItemDelegate(parent) {} : QItemDelegate(parent) {}
void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const
{ {
if (rect.height() == CATEGORY_ROW_HEIGHT) { QStyleOptionViewItem newoption = option;
if (!(option.state & QStyle::State_Enabled)) {
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft()); QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
gradient.setColorAt(0, option.palette.window().color().lighter(106)); gradient.setColorAt(0, option.palette.window().color().lighter(106));
gradient.setColorAt(1, option.palette.window().color().darker(106)); gradient.setColorAt(1, option.palette.window().color().darker(106));
@@ -123,15 +115,12 @@ public:
if (rect.top()) if (rect.top())
painter->drawLine(rect.topRight(), rect.topLeft()); painter->drawLine(rect.topRight(), rect.topLeft());
painter->drawLine(rect.bottomRight(), rect.bottomLeft()); painter->drawLine(rect.bottomRight(), rect.bottomLeft());
// Fake enabled state
newoption.state |= newoption.state | QStyle::State_Enabled;
} }
QItemDelegate::drawDisplay(painter, option, rect, text); QItemDelegate::drawDisplay(painter, newoption, rect, text);
}
void drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const
{
if (rect.height() != CATEGORY_ROW_HEIGHT)
QItemDelegate::drawFocus(painter, option, rect);
} }
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
@@ -183,8 +172,13 @@ NewDialog::NewDialog(QWidget *parent) :
this, SLOT(currentCategoryChanged(const QModelIndex&))); this, SLOT(currentCategoryChanged(const QModelIndex&)));
connect(m_ui->templatesView, SIGNAL(clicked(const QModelIndex&)), connect(m_ui->templatesView, SIGNAL(clicked(const QModelIndex&)),
this, SLOT(currentItemChanged(const QModelIndex&))); this, SLOT(currentItemChanged(const QModelIndex&)));
// connect(m_ui->templatesView, SIGNAL(activated(const QModelIndex&)),
// m_okButton, SLOT(animateClick())); connect(m_ui->templateCategoryView->selectionModel(),
SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)),
this, SLOT(currentCategoryChanged(const QModelIndex&)));
connect(m_ui->templatesView,
SIGNAL(doubleClicked(const QModelIndex&)),
this, SLOT(okButtonClicked()));
connect(m_okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked())); connect(m_okButton, SIGNAL(clicked()), this, SLOT(okButtonClicked()));
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject())); connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
@@ -215,15 +209,18 @@ void NewDialog::setWizards(QList<IWizard*> wizards)
m_model->clear(); m_model->clear();
QStandardItem *projectKindItem = new QStandardItem(tr("Projects")); QStandardItem *projectKindItem = new QStandardItem(tr("Projects"));
projectKindItem->setData(IWizard::ProjectWizard, Qt::UserRole); projectKindItem->setData(IWizard::ProjectWizard, Qt::UserRole);
projectKindItem->setFlags(0); // disable item to prevent focus
QStandardItem *filesClassesKindItem = new QStandardItem(tr("Files and Classes")); QStandardItem *filesClassesKindItem = new QStandardItem(tr("Files and Classes"));
filesClassesKindItem->setData(IWizard::FileWizard, Qt::UserRole); filesClassesKindItem->setData(IWizard::FileWizard, Qt::UserRole);
filesClassesKindItem->setFlags(0); // disable item to prevent focus
QStandardItem *parentItem = m_model->invisibleRootItem(); QStandardItem *parentItem = m_model->invisibleRootItem();
parentItem->appendRow(projectKindItem); parentItem->appendRow(projectKindItem);
parentItem->appendRow(filesClassesKindItem); parentItem->appendRow(filesClassesKindItem);
static QPixmap dummyIcon(22, 22); if (m_dummyIcon.isNull()) {
dummyIcon.fill(Qt::transparent); m_dummyIcon = QPixmap(22, 22);
m_dummyIcon.fill(Qt::transparent);
}
foreach (IWizard *wizard, wizards) { foreach (IWizard *wizard, wizards) {
// ensure category root // ensure category root
@@ -255,7 +252,7 @@ void NewDialog::setWizards(QList<IWizard*> wizards)
// spacing hack. Add proper icons instead // spacing hack. Add proper icons instead
if (wizard->icon().isNull()) if (wizard->icon().isNull())
wizardIcon = dummyIcon; wizardIcon = m_dummyIcon;
else else
wizardIcon = wizard->icon(); wizardIcon = wizard->icon();
wizardItem->setIcon(wizardIcon); wizardItem->setIcon(wizardIcon);
@@ -273,11 +270,15 @@ void NewDialog::setWizards(QList<IWizard*> wizards)
QModelIndex idx = filesClassesKindItem->index(); QModelIndex idx = filesClassesKindItem->index();
m_model->removeRow(idx.row()); m_model->removeRow(idx.row());
} }
} }
Core::IWizard *NewDialog::showDialog() Core::IWizard *NewDialog::showDialog()
{ {
// Select first category, first item by default
m_ui->templateCategoryView->setCurrentIndex(m_proxyModel->index(0,0, m_proxyModel->index(0,0)));
// We need to set ensure that the category has default focus
m_ui->templateCategoryView->setFocus(Qt::NoFocusReason);
for (int row = 0; row < m_proxyModel->rowCount(); ++row) for (int row = 0; row < m_proxyModel->rowCount(); ++row)
m_ui->templateCategoryView->setExpanded(m_proxyModel->index(row, 0), true); m_ui->templateCategoryView->setExpanded(m_proxyModel->index(row, 0), true);
@@ -299,12 +300,16 @@ IWizard *NewDialog::currentWizard() const
void NewDialog::currentCategoryChanged(const QModelIndex &index) void NewDialog::currentCategoryChanged(const QModelIndex &index)
{ {
if (index.parent() != m_model->invisibleRootItem()->index()) { if (index.parent() != m_model->invisibleRootItem()->index()) {
m_ui->templatesView->setModel(m_model); m_ui->templatesView->setModel(m_model);
m_ui->templatesView->setRootIndex(m_proxyModel->mapToSource(index)); m_ui->templatesView->setRootIndex(m_proxyModel->mapToSource(index));
} else {
m_ui->templatesView->setModel(0); // Focus the first item by default
m_ui->templatesView->setCurrentIndex(m_ui->templatesView->rootIndex().child(0,0));
connect(m_ui->templatesView->selectionModel(),
SIGNAL(currentChanged(const QModelIndex&,const QModelIndex&)),
this, SLOT(currentItemChanged(const QModelIndex&)));
} }
} }

View File

@@ -70,7 +70,6 @@ private slots:
void currentItemChanged(const QModelIndex &); void currentItemChanged(const QModelIndex &);
void okButtonClicked(); void okButtonClicked();
void updateOkButton(); void updateOkButton();
private: private:
Core::IWizard *currentWizard() const; Core::IWizard *currentWizard() const;

View File

@@ -14,20 +14,7 @@
<string>New Project</string> <string>New Project</string>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="1" column="1"> <item row="3" column="1">
<widget class="QListView" name="templatesView">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="uniformItemSizes">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QTextBrowser" name="templateDescription"> <widget class="QTextBrowser" name="templateDescription">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding"> <sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
@@ -41,16 +28,19 @@
<height>100</height> <height>100</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
</widget> </widget>
</item> </item>
<item row="3" column="0" colspan="2"> <item row="4" column="0" colspan="2">
<widget class="Line" name="line"> <widget class="Line" name="line">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0" colspan="2"> <item row="5" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox"> <widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation"> <property name="orientation">
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
@@ -67,7 +57,26 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0" rowspan="2"> <item row="1" column="1" rowspan="2">
<widget class="QListView" name="templatesView">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="uniformItemSizes">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="0" rowspan="3">
<widget class="QTreeView" name="templateCategoryView"> <widget class="QTreeView" name="templateCategoryView">
<property name="maximumSize"> <property name="maximumSize">
<size> <size>
@@ -75,6 +84,9 @@
<height>16777215</height> <height>16777215</height>
</size> </size>
</property> </property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="indentation"> <property name="indentation">
<number>0</number> <number>0</number>
</property> </property>
@@ -90,10 +102,18 @@
<attribute name="headerVisible"> <attribute name="headerVisible">
<bool>false</bool> <bool>false</bool>
</attribute> </attribute>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<tabstops>
<tabstop>templateCategoryView</tabstop>
<tabstop>templatesView</tabstop>
<tabstop>buttonBox</tabstop>
</tabstops>
<resources/> <resources/>
<connections/> <connections/>
</ui> </ui>