SettingsDialog: Polish

Use QGridLayout to align header label and QStackedLayout for the pages
(in code, as it is not available in Designer).
Derive new class FilterLineEdit for filter widgets based on a modified
version of FancyLineEdit and use that in settings.
Rubber-stamped-by: con <qtc-committer@nokia.com>
This commit is contained in:
Friedemann Kleint
2009-11-27 13:54:27 +01:00
parent cf975fc308
commit bf73896928
13 changed files with 253 additions and 73 deletions

View File

@@ -33,20 +33,29 @@
#include "icore.h"
#include <utils/qtcassert.h>
#include <utils/filterlineedit.h>
#include <QtCore/QSettings>
#include <QtGui/QHeaderView>
#include <QtGui/QPushButton>
#include <QtGui/QStandardItemModel>
#include <QtGui/QStandardItem>
#include <QtGui/QSortFilterProxyModel>
#include <QtGui/QItemSelectionModel>
#include <QtGui/QHBoxLayout>
#include <QtGui/QIcon>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QToolButton>
#include <QtGui/QToolBar>
#include <QtGui/QSpacerItem>
#include <QtGui/QStyle>
#include <QtGui/QStackedLayout>
#include <QtGui/QGridLayout>
#include <QtGui/QLineEdit>
#include <QtGui/QFrame>
#include <QtGui/QDialogButtonBox>
#include <QtGui/QTreeView>
#include <QtGui/QApplication>
enum ItemType { CategoryItem, PageItem };
@@ -186,9 +195,13 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId,
m_pages(ExtensionSystem::PluginManager::instance()->getObjects<IOptionsPage>()),
m_proxyModel(new PageFilterModel),
m_model(0),
m_applied(false)
m_applied(false),
m_stackedLayout(new QStackedLayout),
m_filterLineEdit(new Utils::FilterLineEdit),
m_pageTree(new QTreeView),
m_headerLabel(new QLabel)
{
setupUi(this);
createGui();
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
#ifdef Q_OS_MAC
setWindowTitle(tr("Preferences"));
@@ -202,73 +215,77 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &categoryId,
initialCategory = settings->value(QLatin1String(categoryKeyC), QVariant(QString())).toString();
initialPage = settings->value(QLatin1String(pageKeyC), QVariant(QString())).toString();
}
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply()));
// Create pages with title labels with a larger, bold font, left-aligned
// with the group boxes of the page.
const int pageCount = m_pages.size();
QFont titleLabelFont;
const int leftMargin = qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) +
qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
for (int i = 0; i < pageCount; i++) {
// Title bar
QHBoxLayout *titleLayout = new QHBoxLayout;
titleLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
QLabel *titleLabel = new QLabel(m_pages.at(i)->trName());
if (i == 0) { // Create a bold header font from the default label font.
titleLabelFont = titleLabel->font();
titleLabelFont.setBold(true);
// Paranoia: Should a font be set in pixels...
const int pointSize = titleLabelFont.pointSize();
if (pointSize > 0)
titleLabelFont.setPointSize(pointSize + 2);
}
titleLabel->setFont(titleLabelFont);
titleLayout->addWidget(titleLabel);
// Page
QWidget *pageContainer =new QWidget;
QVBoxLayout *pageLayout = new QVBoxLayout(pageContainer);
pageLayout->addLayout(titleLayout);
pageLayout->addSpacerItem(new QSpacerItem(0, 6, QSizePolicy::Ignored, QSizePolicy::Fixed));
pageLayout->addWidget(m_pages.at(i)->createPage(0));
stackedPages->addWidget(pageContainer);
}
// foreach(IOptionsPage *page, m_pages)
// stackedPages->addWidget();
splitter->setCollapsible(1, false);
pageTree->header()->setVisible(false);
foreach(IOptionsPage *page, m_pages)
m_stackedLayout->addWidget(page->createPage(0));
QModelIndex initialIndex;
m_model = pageModel(m_pages, 0, initialCategory, initialPage, &initialIndex);
m_proxyModel->setFilterKeyColumn(0);
m_proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
m_proxyModel->setSourceModel(m_model);
pageTree->setModel(m_proxyModel);
pageTree->setSelectionMode(QAbstractItemView::SingleSelection);
connect(pageTree->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
m_pageTree->setModel(m_proxyModel);
m_pageTree->setSelectionMode(QAbstractItemView::SingleSelection);
connect(m_pageTree->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)),
this, SLOT(currentChanged(QModelIndex,QModelIndex)));
if (initialIndex.isValid()) {
const QModelIndex proxyIndex = m_proxyModel->mapFromSource(initialIndex);
pageTree->selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::ClearAndSelect);
m_pageTree->selectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::ClearAndSelect);
}
m_pageTree->resizeColumnToContents(0);
QList<int> sizes;
sizes << 150 << 300;
splitter->setSizes(sizes);
splitter->setStretchFactor(splitter->indexOf(pageTree), 0);
splitter->setStretchFactor(splitter->indexOf(layoutWidget), 1);
filterClearButton->setIcon(QIcon(QLatin1String(":/core/images/reset.png")));
connect(filterClearButton, SIGNAL(clicked()), filterLineEdit, SLOT(clear()));
// The order of the slot connection matters here, the filter slot
// opens the matching page after the model has filtered.
connect(filterLineEdit, SIGNAL(textChanged(QString)),
connect(m_filterLineEdit, SIGNAL(filterChanged(QString)),
m_proxyModel, SLOT(setFilterFixedString(QString)));
connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filter(QString)));
connect(m_filterLineEdit, SIGNAL(filterChanged(QString)), this, SLOT(filter(QString)));
}
void SettingsDialog::createGui()
{
// Header label with large font and a bit of spacing (align with group boxes)
QFont headerLabelFont = m_headerLabel->font();
headerLabelFont.setBold(true);
// Paranoia: Should a font be set in pixels...
const int pointSize = headerLabelFont.pointSize();
if (pointSize > 0)
headerLabelFont.setPointSize(pointSize + 2);
m_headerLabel->setFont(headerLabelFont);
QHBoxLayout *headerHLayout = new QHBoxLayout;
const int leftMargin = qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin) +
qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
headerHLayout->addSpacerItem(new QSpacerItem(leftMargin, 0, QSizePolicy::Fixed, QSizePolicy::Ignored));
headerHLayout->addWidget(m_headerLabel);
// Tree
m_pageTree->header()->setVisible(false);
m_stackedLayout->setMargin(0);
// Separator Line
QFrame *bottomLine = new QFrame;
bottomLine->setFrameShape(QFrame::HLine);
bottomLine->setFrameShadow(QFrame::Sunken);
// Button box
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Apply|QDialogButtonBox::Cancel);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
connect(buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), this, SLOT(apply()));
connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
QGridLayout *mainGridLayout = new QGridLayout;
mainGridLayout->addWidget(m_filterLineEdit, 0, 0, 1, 1);
mainGridLayout->addLayout(headerHLayout, 0, 1, 1, 1);
mainGridLayout->addWidget(m_pageTree, 1, 0, 2, 1);
mainGridLayout->addLayout(m_stackedLayout, 1, 1, 1, 1);
mainGridLayout->addWidget(bottomLine, 2, 1, 1, 1);
mainGridLayout->addWidget(buttonBox, 3, 0, 1, 2);
mainGridLayout->setColumnStretch(0, 1);
mainGridLayout->setColumnStretch(1, 4);
setLayout(mainGridLayout);
}
SettingsDialog::~SettingsDialog()
@@ -284,8 +301,9 @@ void SettingsDialog::showPage(const QStandardItem *item)
IOptionsPage *page = pageOfItem(item);
m_currentCategory = page->category();
m_currentPage = page->id();
stackedPages->setCurrentIndex(indexOfItem(item));
m_stackedLayout->setCurrentIndex(indexOfItem(item));
m_visitedPages.insert(page);
m_headerLabel->setText(page->trName());
}
break;
case CategoryItem:
@@ -337,17 +355,17 @@ void SettingsDialog::filter(const QString &text)
{
// Filter cleared, collapse all.
if (text.isEmpty()) {
pageTree->collapseAll();
m_pageTree->collapseAll();
return;
}
// Expand match and select the first page. Note: This depends
// on the order of slot invocation, needs to be done after filtering
if (!m_proxyModel->rowCount(QModelIndex()))
return;
pageTree->expandAll();
m_pageTree->expandAll();
const QModelIndex firstVisiblePage = findPage(m_proxyModel);
if (firstVisiblePage.isValid())
pageTree->selectionModel()->setCurrentIndex(firstVisiblePage, QItemSelectionModel::ClearAndSelect);
m_pageTree->selectionModel()->setCurrentIndex(firstVisiblePage, QItemSelectionModel::ClearAndSelect);
}
void SettingsDialog::accept()
@@ -376,6 +394,7 @@ void SettingsDialog::apply()
bool SettingsDialog::execDialog()
{
m_pageTree->setFocus();
m_applied = false;
exec();
return m_applied;