Group pages in the settings dialog into categories

This commit is contained in:
David Sansome 2011-10-30 16:51:43 +00:00
parent d3abed6044
commit a2b95b7f54
6 changed files with 176 additions and 81 deletions

View File

@ -1315,6 +1315,9 @@ msgstr ""
msgid "GStreamer audio engine"
msgstr ""
msgid "General"
msgstr ""
msgid "General settings"
msgstr ""
@ -1473,6 +1476,9 @@ msgstr ""
msgid "Internet"
msgstr ""
msgid "Internet providers"
msgstr ""
msgid "Invalid API key"
msgstr ""
@ -3003,6 +3009,9 @@ msgstr ""
msgid "User %1 doesn't have a Grooveshark Anywhere account"
msgstr ""
msgid "User interface"
msgstr ""
msgid "Username"
msgstr ""

View File

@ -37,7 +37,7 @@
#include "playlist/playlistview.h"
#include "songinfo/songinfosettingspage.h"
#include "transcoder/transcodersettingspage.h"
#include "widgets/groupediconview.h"
#include "widgets/osdpretty.h"
#include "ui_settingsdialog.h"
@ -59,10 +59,41 @@
#endif
#include <QDesktopWidget>
#include <QPainter>
#include <QPushButton>
#include <QScrollArea>
SettingsItemDelegate::SettingsItemDelegate(QObject* parent)
: QStyledItemDelegate(parent)
{
}
QSize SettingsItemDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const {
const bool is_separator = index.data(SettingsDialog::Role_IsSeparator).toBool();
QSize ret = QStyledItemDelegate::sizeHint(option, index);
if (is_separator) {
ret.setHeight(ret.height() * 2);
}
return ret;
}
void SettingsItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const {
const bool is_separator = index.data(SettingsDialog::Role_IsSeparator).toBool();
if (is_separator) {
GroupedIconView::DrawHeader(painter, option.rect, option.font,
option.palette, index.data().toString());
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
SettingsDialog::SettingsDialog(BackgroundStreams* streams, QWidget* parent)
: QDialog(parent),
model_(NULL),
@ -73,44 +104,54 @@ SettingsDialog::SettingsDialog(BackgroundStreams* streams, QWidget* parent)
loading_settings_(false)
{
ui_->setupUi(this);
ui_->list->setItemDelegate(new SettingsItemDelegate(this));
AddPage(Page_Playback, new PlaybackSettingsPage(this));
AddPage(Page_Behaviour, new BehaviourSettingsPage(this));
AddPage(Page_SongInformation, new SongInfoSettingsPage(this));
AddPage(Page_GlobalShortcuts, new GlobalShortcutsSettingsPage(this));
AddPage(Page_Notifications, new NotificationsSettingsPage(this));
AddPage(Page_Library, new LibrarySettingsPage(this));
QTreeWidgetItem* general = AddCategory(tr("General"));
#ifdef HAVE_LIBLASTFM
AddPage(Page_Lastfm, new LastFMSettingsPage(this));
#endif
AddPage(Page_Grooveshark, new GroovesharkSettingsPage(this));
#ifdef HAVE_SPOTIFY
AddPage(Page_Spotify, new SpotifySettingsPage(this));
#endif
AddPage(Page_Magnatune, new MagnatuneSettingsPage(this));
AddPage(Page_DigitallyImported, new DigitallyImportedSettingsPage(this));
AddPage(Page_BackgroundStreams, new BackgroundStreamsSettingsPage(this));
AddPage(Page_Proxy, new NetworkProxySettingsPage(this));
AddPage(Page_Transcoding, new TranscoderSettingsPage(this));
AddPage(Page_Playback, new PlaybackSettingsPage(this), general);
AddPage(Page_Behaviour, new BehaviourSettingsPage(this), general);
AddPage(Page_Library, new LibrarySettingsPage(this), general);
AddPage(Page_Proxy, new NetworkProxySettingsPage(this), general);
AddPage(Page_Transcoding, new TranscoderSettingsPage(this), general);
#ifdef HAVE_REMOTE
AddPage(Page_Remote, new RemoteSettingsPage(this));
AddPage(Page_Remote, new RemoteSettingsPage(this), general);
#endif
#ifdef HAVE_WIIMOTEDEV
AddPage(Page_Wiimotedev, new WiimoteSettingsPage(this));
AddPage(Page_Wiimotedev, new WiimoteSettingsPage(this), general);
#endif
// User interface
QTreeWidgetItem* interface = AddCategory(tr("User interface"));
AddPage(Page_GlobalShortcuts, new GlobalShortcutsSettingsPage(this), interface);
AddPage(Page_SongInformation, new SongInfoSettingsPage(this), interface);
AddPage(Page_Notifications, new NotificationsSettingsPage(this), interface);
// Internet providers
QTreeWidgetItem* providers = AddCategory(tr("Internet providers"));
#ifdef HAVE_LIBLASTFM
AddPage(Page_Lastfm, new LastFMSettingsPage(this), providers);
#endif
AddPage(Page_Grooveshark, new GroovesharkSettingsPage(this), providers);
#ifdef HAVE_SPOTIFY
AddPage(Page_Spotify, new SpotifySettingsPage(this), providers);
#endif
AddPage(Page_Magnatune, new MagnatuneSettingsPage(this), providers);
AddPage(Page_DigitallyImported, new DigitallyImportedSettingsPage(this), providers);
AddPage(Page_BackgroundStreams, new BackgroundStreamsSettingsPage(this), providers);
// List box
connect(ui_->list, SIGNAL(currentTextChanged(QString)), SLOT(CurrentTextChanged(QString)));
ui_->list->setCurrentRow(Page_Playback);
connect(ui_->list, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
SLOT(CurrentItemChanged(QTreeWidgetItem*)));
ui_->list->setCurrentItem(pages_[Page_Playback].item_);
// Make sure the list is big enough to show all the items
ui_->list->setMinimumWidth(ui_->list->sizeHintForColumn(0));
ui_->list->setMinimumWidth(static_cast<QAbstractItemView*>(ui_->list)->sizeHintForColumn(0));
ui_->buttonBox->button(QDialogButtonBox::Cancel)->setShortcut(QKeySequence::Close);
}
@ -119,7 +160,22 @@ SettingsDialog::~SettingsDialog() {
delete ui_;
}
void SettingsDialog::AddPage(Page id, SettingsPage* page) {
QTreeWidgetItem* SettingsDialog::AddCategory(const QString& name) {
QTreeWidgetItem* item = new QTreeWidgetItem;
item->setText(0, name);
item->setData(0, Role_IsSeparator, true);
item->setFlags(Qt::ItemIsEnabled);
ui_->list->invisibleRootItem()->addChild(item);
item->setExpanded(true);
return item;
}
void SettingsDialog::AddPage(Page id, SettingsPage* page, QTreeWidgetItem* parent) {
if (!parent)
parent = ui_->list->invisibleRootItem();
// Connect page's signals to the settings dialog's signals
connect(page, SIGNAL(NotificationPreview(OSD::Behaviour,QString,QString)),
SIGNAL(NotificationPreview(OSD::Behaviour,QString,QString)));
@ -127,14 +183,17 @@ void SettingsDialog::AddPage(Page id, SettingsPage* page) {
SIGNAL(SetWiimotedevInterfaceActived(bool)));
// Create the list item
QListWidgetItem* item = new QListWidgetItem(page->windowIcon(),
page->windowTitle());
ui_->list->addItem(item);
QTreeWidgetItem* item = new QTreeWidgetItem;
item->setText(0, page->windowTitle());
item->setIcon(0, page->windowIcon());
item->setData(0, Role_IsSeparator, false);
if (!page->IsEnabled()) {
item->setFlags(Qt::NoItemFlags);
}
parent->addChild(item);
// Create a scroll area containing the page
QScrollArea* area = new QScrollArea;
area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@ -148,7 +207,7 @@ void SettingsDialog::AddPage(Page id, SettingsPage* page) {
// Remember where the page is
PageData data;
data.index_ = ui_->list->row(item);
data.item_ = item;
data.scroll_area_ = area;
data.page_ = page;
pages_[id] = data;
@ -185,10 +244,23 @@ void SettingsDialog::OpenAtPage(Page page) {
return;
}
ui_->list->setCurrentRow(pages_[page].index_);
ui_->list->setCurrentItem(pages_[page].item_);
show();
}
void SettingsDialog::CurrentTextChanged(const QString& text) {
ui_->title->setText("<b>" + text + "</b>");
void SettingsDialog::CurrentItemChanged(QTreeWidgetItem* item) {
if (! (item->flags() & Qt::ItemIsSelectable)) {
return;
}
// Set the title
ui_->title->setText("<b>" + item->text(0) + "</b>");
// Display the right page
foreach (const PageData& data, pages_.values()) {
if (data.item_ == item) {
ui_->stacked_widget->setCurrentWidget(data.scroll_area_);
break;
}
}
}

View File

@ -19,11 +19,13 @@
#define SETTINGSDIALOG_H
#include <QDialog>
#include <QStyledItemDelegate>
#include "config.h"
#include "widgets/osd.h"
class QScrollArea;
class QTreeWidgetItem;
class BackgroundStreams;
class GlobalShortcuts;
@ -34,6 +36,17 @@ class Ui_SettingsDialog;
class GstEngine;
class SettingsItemDelegate : public QStyledItemDelegate {
public:
SettingsItemDelegate(QObject* parent);
QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
void paint(QPainter* painter, const QStyleOptionViewItem& option,
const QModelIndex& index) const;
};
class SettingsDialog : public QDialog {
Q_OBJECT
@ -60,6 +73,10 @@ public:
Page_Wiimotedev,
};
enum Role {
Role_IsSeparator = Qt::UserRole
};
void SetLibraryDirectoryModel(LibraryDirectoryModel* model) { model_ = model; }
void SetGlobalShortcutManager(GlobalShortcuts* manager) { manager_ = manager; }
void SetGstEngine(const GstEngine* engine) { gst_engine_ = engine; }
@ -86,16 +103,17 @@ signals:
void SetWiimotedevInterfaceActived(bool);
private slots:
void CurrentTextChanged(const QString& text);
void CurrentItemChanged(QTreeWidgetItem* item);
private:
struct PageData {
int index_;
QTreeWidgetItem* item_;
QScrollArea* scroll_area_;
SettingsPage* page_;
};
void AddPage(Page id, SettingsPage* page);
QTreeWidgetItem* AddCategory(const QString& name);
void AddPage(Page id, SettingsPage* page, QTreeWidgetItem* parent = NULL);
private:
LibraryDirectoryModel* model_;

View File

@ -19,37 +19,39 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QListWidget" name="list">
<widget class="QTreeWidget" name="list">
<property name="maximumSize">
<size>
<width>220</width>
<height>16777215</height>
</size>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="iconSize">
<size>
<width>32</width>
<height>32</height>
</size>
</property>
<property name="movement">
<enum>QListView::Static</enum>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="spacing">
<number>2</number>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="viewMode">
<enum>QListView::ListMode</enum>
</property>
<property name="uniformItemSizes">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="selectionRectVisible">
<bool>true</bool>
<property name="expandsOnDoubleClick">
<bool>false</bool>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</item>
<item>
@ -97,22 +99,6 @@
<include location="../../data/data.qrc"/>
</resources>
<connections>
<connection>
<sender>list</sender>
<signal>currentRowChanged(int)</signal>
<receiver>stacked_widget</receiver>
<slot>setCurrentIndex(int)</slot>
<hints>
<hint type="sourcelabel">
<x>82</x>
<y>72</y>
</hint>
<hint type="destinationlabel">
<x>307</x>
<y>96</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>

View File

@ -66,26 +66,32 @@ int GroupedIconView::header_height() const {
return default_header_height_;
}
void GroupedIconView::DrawHeader(const QModelIndex& index,
const QRect& rect, QPainter* painter) {
void GroupedIconView::DrawHeader(QPainter* painter, const QRect& rect,
const QFont& font, const QPalette& palette,
const QString& text) {
painter->save();
// Bold font
QFont bold_font(font());
QFont bold_font(font);
bold_font.setBold(true);
QFontMetrics metrics(bold_font);
QRect text_rect(rect);
text_rect.setHeight(metrics.height());
text_rect.moveTop(rect.top() + (rect.height() - text_rect.height() -
kBarThickness - kBarMarginTop) / 2);
text_rect.setLeft(text_rect.left() + 3);
// Draw text
const QString category = header_text_.arg(index.data(Role_Group).toString());
painter->setFont(bold_font);
painter->drawText(rect, category);
painter->drawText(text_rect, text);
// Draw a line underneath
const QPoint start(rect.left(), rect.top() + metrics.height());
const QPoint start(rect.left(), text_rect.bottom() + kBarMarginTop);
const QPoint end(rect.right(), start.y());
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setPen(QPen(palette().color(QPalette::Disabled, QPalette::Text),
painter->setPen(QPen(palette.color(QPalette::Disabled, QPalette::Text),
kBarThickness, Qt::SolidLine, Qt::RoundCap));
painter->setOpacity(0.5);
painter->drawLine(start, end);
@ -273,9 +279,11 @@ void GroupedIconView::paintEvent(QPaintEvent* e) {
}
// Draw the header
DrawHeader(model()->index(header.first_row, 0),
DrawHeader(&painter,
header_rect.translated(-horizontalOffset(), -verticalOffset()),
&painter);
font(),
palette(),
model()->index(header.first_row, 0).data(Role_Group).toString());
}
}

View File

@ -61,10 +61,12 @@ public:
QModelIndex moveCursor(CursorAction action, Qt::KeyboardModifiers modifiers);
void setModel(QAbstractItemModel* model);
static void DrawHeader(QPainter* painter, const QRect& rect,
const QFont& font, const QPalette& palette,
const QString& text);
protected:
virtual int header_height() const;
virtual void DrawHeader(const QModelIndex& first_child, const QRect& rect,
QPainter* painter);
// QWidget
void paintEvent(QPaintEvent* e);