Add genre filtering to streams pages.
This commit is contained in:
@@ -25,8 +25,8 @@
|
||||
18. Disable playback buttons depending upon size of play queue.
|
||||
19. When sending track change notification, also include cover (if we have one)
|
||||
20. Optionally fade-out track when stopping.
|
||||
21. Add genre filtering to playlists page.
|
||||
22. When pressing play after pressing stop, start playnig at current song -
|
||||
21. Add genre filtering to playlists and streams pages.
|
||||
22. When pressing play after pressing stop, start playing at current song -
|
||||
don't start at begining of play queue.
|
||||
23. Better repeat and consume icons.
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <QtGui/QPushButton>
|
||||
#endif
|
||||
|
||||
StreamDialog::StreamDialog(const QStringList &categories, QWidget *parent)
|
||||
StreamDialog::StreamDialog(const QStringList &categories, const QStringList &genres, QWidget *parent)
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
: KDialog(parent)
|
||||
#else
|
||||
@@ -50,11 +50,14 @@ StreamDialog::StreamDialog(const QStringList &categories, QWidget *parent)
|
||||
urlEntry = new LineEdit(wid);
|
||||
catCombo = new CompletionCombo(wid);
|
||||
catCombo->setEditable(true);
|
||||
genreCombo = new CompletionCombo(wid);
|
||||
|
||||
QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
|
||||
sizePolicy.setHorizontalStretch(0);
|
||||
sizePolicy.setVerticalStretch(0);
|
||||
sizePolicy.setHeightForWidth(catCombo->sizePolicy().hasHeightForWidth());
|
||||
catCombo->setSizePolicy(sizePolicy);
|
||||
genreCombo->setSizePolicy(sizePolicy);
|
||||
int row=0;
|
||||
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
@@ -83,6 +86,12 @@ StreamDialog::StreamDialog(const QStringList &categories, QWidget *parent)
|
||||
#endif
|
||||
layout->setWidget(row++, QFormLayout::FieldRole, catCombo);
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
layout->setWidget(row, QFormLayout::LabelRole, new QLabel(i18n("Genre:"), wid));
|
||||
#else
|
||||
layout->setWidget(row, QFormLayout::LabelRole, new QLabel(tr("Genre:"), wid));
|
||||
#endif
|
||||
layout->setWidget(row++, QFormLayout::FieldRole, genreCombo);
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
setMainWidget(wid);
|
||||
setButtons(KDialog::Ok|KDialog::Cancel);
|
||||
setCaption(i18n("Add Stream"));
|
||||
@@ -99,17 +108,19 @@ StreamDialog::StreamDialog(const QStringList &categories, QWidget *parent)
|
||||
#endif
|
||||
catCombo->clear();
|
||||
catCombo->insertItems(0, categories);
|
||||
|
||||
genreCombo->clear();
|
||||
genreCombo->insertItems(0, genres);
|
||||
connect(nameEntry, SIGNAL(textChanged(const QString &)), SLOT(changed()));
|
||||
connect(urlEntry, SIGNAL(textChanged(const QString &)), SLOT(changed()));
|
||||
connect(catCombo, SIGNAL(editTextChanged(const QString &)), SLOT(changed()));
|
||||
connect(genreCombo, SIGNAL(editTextChanged(const QString &)), SLOT(changed()));
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
connect(iconButton, SIGNAL(clicked()), SLOT(setIcon()));
|
||||
#endif
|
||||
nameEntry->setFocus();
|
||||
}
|
||||
|
||||
void StreamDialog::setEdit(const QString &cat, const QString &editName, const QString &editIconName, const QString &editUrl)
|
||||
void StreamDialog::setEdit(const QString &cat, const QString &editName, const QString &editGenre, const QString &editIconName, const QString &editUrl)
|
||||
{
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
setCaption(i18n("Edit Stream"));
|
||||
@@ -124,9 +135,11 @@ void StreamDialog::setEdit(const QString &cat, const QString &editName, const QS
|
||||
prevName=editName;
|
||||
prevUrl=editUrl;
|
||||
prevCat=cat;
|
||||
prevGenre=editGenre;
|
||||
nameEntry->setText(editName);
|
||||
urlEntry->setText(editUrl);
|
||||
catCombo->setEditText(cat);
|
||||
genreCombo->setEditText(editGenre);
|
||||
}
|
||||
|
||||
void StreamDialog::changed()
|
||||
@@ -134,7 +147,8 @@ void StreamDialog::changed()
|
||||
QString n=name();
|
||||
QString u=url();
|
||||
QString c=category();
|
||||
bool enableOk=!n.isEmpty() && !u.isEmpty() && !c.isEmpty() && (n!=prevName || u!=prevUrl || c!=prevCat);
|
||||
QString g=genre();
|
||||
bool enableOk=!n.isEmpty() && !u.isEmpty() && !c.isEmpty() && (n!=prevName || u!=prevUrl || c!=prevCat || g!=prevGenre);
|
||||
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
enableOk=enableOk || icon()!=prevIconName;
|
||||
|
||||
@@ -44,13 +44,14 @@ class StreamDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
StreamDialog(const QStringList &categories, QWidget *parent);
|
||||
StreamDialog(const QStringList &categories, const QStringList &genres, QWidget *parent);
|
||||
|
||||
void setEdit(const QString &cat, const QString &editName, const QString &editIconName, const QString &editUrl);
|
||||
void setEdit(const QString &cat, const QString &editName, const QString &editGenre, const QString &editIconName, const QString &editUrl);
|
||||
|
||||
QString name() const { return nameEntry->text().trimmed(); }
|
||||
QString url() const { return urlEntry->text().trimmed(); }
|
||||
QString category() const { return catCombo->currentText().trimmed(); }
|
||||
QString genre() const { return genreCombo->currentText().trimmed(); }
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
QString icon() const { return iconName; }
|
||||
#endif
|
||||
@@ -70,6 +71,7 @@ private:
|
||||
QString prevName;
|
||||
QString prevUrl;
|
||||
QString prevCat;
|
||||
QString prevGenre;
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
QString prevIconName;
|
||||
QString iconName;
|
||||
@@ -80,6 +82,7 @@ private:
|
||||
LineEdit *nameEntry;
|
||||
LineEdit *urlEntry;
|
||||
CompletionCombo *catCombo;
|
||||
CompletionCombo *genreCombo;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -81,6 +81,8 @@ StreamsPage::StreamsPage(MainWindow *p)
|
||||
connect(editAction, SIGNAL(triggered(bool)), this, SLOT(edit()));
|
||||
connect(importAction, SIGNAL(triggered(bool)), this, SLOT(importXml()));
|
||||
connect(exportAction, SIGNAL(triggered(bool)), this, SLOT(exportXml()));
|
||||
connect(genreCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(searchItems()));
|
||||
connect(&model, SIGNAL(genresUpdated(const QSet<QString> &)), SLOT(genresUpdated(const QSet<QString> &)));
|
||||
importStreams->setAutoRaise(true);
|
||||
exportStreams->setAutoRaise(true);
|
||||
addStream->setAutoRaise(true);
|
||||
@@ -169,6 +171,43 @@ void StreamsPage::itemDoubleClicked(const QModelIndex &index)
|
||||
addItemsToPlayQueue(indexes);
|
||||
}
|
||||
|
||||
void StreamsPage::genresUpdated(const QSet<QString> &g)
|
||||
{
|
||||
if (genreCombo->count() && g==genres) {
|
||||
return;
|
||||
}
|
||||
|
||||
genres=g;
|
||||
QStringList entries=g.toList();
|
||||
qSort(entries);
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
entries.prepend(i18n("All Genres"));
|
||||
#else
|
||||
entries.prepend(tr("All Genres"));
|
||||
#endif
|
||||
|
||||
QString currentFilter = genreCombo->currentIndex() ? genreCombo->currentText() : QString();
|
||||
|
||||
genreCombo->clear();
|
||||
genreCombo->addItems(entries);
|
||||
if (0==genres.count()) {
|
||||
genreCombo->setCurrentIndex(0);
|
||||
} else {
|
||||
if (!currentFilter.isEmpty()) {
|
||||
bool found=false;
|
||||
for (int i=1; i<genreCombo->count() && !found; ++i) {
|
||||
if (genreCombo->itemText(i) == currentFilter) {
|
||||
genreCombo->setCurrentIndex(i);
|
||||
found=true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
genreCombo->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StreamsPage::importXml()
|
||||
{
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
@@ -229,12 +268,13 @@ void StreamsPage::exportXml()
|
||||
|
||||
void StreamsPage::add()
|
||||
{
|
||||
StreamDialog dlg(getCategories(), this);
|
||||
StreamDialog dlg(getCategories(), getGenres(), this);
|
||||
|
||||
if (QDialog::Accepted==dlg.exec()) {
|
||||
QString name=dlg.name();
|
||||
QString url=dlg.url();
|
||||
QString cat=dlg.category();
|
||||
QString genre=dlg.genre();
|
||||
|
||||
QString existing=model.name(cat, url);
|
||||
if (!existing.isEmpty()) {
|
||||
@@ -246,7 +286,7 @@ void StreamsPage::add()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!model.add(cat, name, QString(), url)) {
|
||||
if (!model.add(cat, name, genre, QString(), url)) {
|
||||
#ifdef ENABLE_KDE_SUPPORT
|
||||
KMessageBox::error(this, i18n("A stream named <b>%1</b> already exists!", name));
|
||||
#else
|
||||
@@ -327,12 +367,13 @@ void StreamsPage::edit()
|
||||
return;
|
||||
}
|
||||
|
||||
StreamDialog dlg(getCategories(), this);
|
||||
StreamDialog dlg(getCategories(), getGenres(), this);
|
||||
StreamsModel::StreamItem *stream=static_cast<StreamsModel::StreamItem *>(item);
|
||||
QString url=stream->url.toString();
|
||||
QString cat=stream->parent->name;
|
||||
QString genre=stream->genre;
|
||||
|
||||
dlg.setEdit(cat, name, icon, url);
|
||||
dlg.setEdit(cat, name, genre, icon, url);
|
||||
|
||||
if (QDialog::Accepted==dlg.exec()) {
|
||||
QString newName=dlg.name();
|
||||
@@ -343,6 +384,7 @@ void StreamsPage::edit()
|
||||
#endif
|
||||
QString newUrl=dlg.url();
|
||||
QString newCat=dlg.category();
|
||||
QString newGenre=dlg.genre();
|
||||
QString existingNameForUrl=newUrl!=url ? model.name(newCat, newUrl) : QString();
|
||||
//
|
||||
if (!existingNameForUrl.isEmpty()) {
|
||||
@@ -358,7 +400,7 @@ void StreamsPage::edit()
|
||||
QMessageBox::critical(this, tr("Error"), tr("A stream named <b>%1 (%2)</b> already exists!").arg(newName).arg(newCat));
|
||||
#endif
|
||||
} else {
|
||||
model.editStream(index, cat, newCat, newName, newIcon, newUrl);
|
||||
model.editStream(index, cat, newCat, newName, newGenre, newIcon, newUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -386,16 +428,25 @@ void StreamsPage::controlActions()
|
||||
|
||||
void StreamsPage::searchItems()
|
||||
{
|
||||
QString genre=0==genreCombo->currentIndex() ? QString() : genreCombo->currentText();
|
||||
QString filter=view->searchText().trimmed();
|
||||
|
||||
if (filter.isEmpty() ) {
|
||||
if (filter.isEmpty() && genre.isEmpty()) {
|
||||
proxy.setFilterEnabled(false);
|
||||
proxy.setFilterGenre(genre);
|
||||
if (!proxy.filterRegExp().isEmpty()) {
|
||||
proxy.setFilterRegExp(QString());
|
||||
} else {
|
||||
proxy.invalidate();
|
||||
}
|
||||
} else if (filter!=proxy.filterRegExp().pattern()) {
|
||||
} else {
|
||||
proxy.setFilterEnabled(true);
|
||||
proxy.setFilterRegExp(filter);
|
||||
proxy.setFilterGenre(genre);
|
||||
if (filter!=proxy.filterRegExp().pattern()) {
|
||||
proxy.setFilterRegExp(filter);
|
||||
} else {
|
||||
proxy.invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,3 +471,10 @@ QStringList StreamsPage::getCategories()
|
||||
qSort(categories);
|
||||
return categories;
|
||||
}
|
||||
|
||||
QStringList StreamsPage::getGenres()
|
||||
{
|
||||
QStringList g=genres.toList();
|
||||
qSort(g);
|
||||
return g;
|
||||
}
|
||||
@@ -58,10 +58,12 @@ private Q_SLOTS:
|
||||
void controlActions();
|
||||
void searchItems();
|
||||
void itemDoubleClicked(const QModelIndex &index);
|
||||
void genresUpdated(const QSet<QString> &g);
|
||||
|
||||
private:
|
||||
void addItemsToPlayQueue(const QModelIndexList &indexes);
|
||||
QStringList getCategories();
|
||||
QStringList getGenres();
|
||||
|
||||
private:
|
||||
bool enabled;
|
||||
@@ -71,6 +73,7 @@ private:
|
||||
Action *editAction;
|
||||
StreamsModel model;
|
||||
StreamsProxyModel proxy;
|
||||
QSet<QString> genres;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,17 +21,7 @@
|
||||
<widget class="ItemView" name="view"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>130</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
<widget class="QComboBox" name="genreCombo"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QToolButton" name="importStreams"/>
|
||||
|
||||
@@ -666,7 +666,9 @@ void PlaylistsModel::PlaylistItem::updateGenres()
|
||||
{
|
||||
genres.clear();
|
||||
foreach (const SongItem *s, songs) {
|
||||
genres.insert(s->genre);
|
||||
if (!s->genre.isEmpty()) {
|
||||
genres.insert(s->genre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,6 +238,7 @@ bool StreamsModel::load(const QString &filename, bool isInternal)
|
||||
if (stream.hasAttribute("name") && stream.hasAttribute("url")) {
|
||||
QString name=stream.attribute("name");
|
||||
QString icon=stream.attribute("icon");
|
||||
QString genre=stream.attribute("genre");
|
||||
QString origName=name;
|
||||
QUrl url=QUrl(stream.attribute("url"));
|
||||
|
||||
@@ -254,7 +255,7 @@ bool StreamsModel::load(const QString &filename, bool isInternal)
|
||||
if (!isInternal) {
|
||||
beginInsertRows(createIndex(items.indexOf(cat), 0, cat), cat->streams.count(), cat->streams.count());
|
||||
}
|
||||
StreamItem *stream=new StreamItem(name, iconIsValid(icon) ? icon : QString(), url, cat);
|
||||
StreamItem *stream=new StreamItem(name, genre, iconIsValid(icon) ? icon : QString(), url, cat);
|
||||
cat->itemMap.insert(url.toString(), stream);
|
||||
cat->streams.append(stream);
|
||||
if (!isInternal) {
|
||||
@@ -270,6 +271,9 @@ bool StreamsModel::load(const QString &filename, bool isInternal)
|
||||
}
|
||||
}
|
||||
|
||||
if (haveInserted) {
|
||||
updateGenres();
|
||||
}
|
||||
if (haveInserted && !isInternal) {
|
||||
modified=true;
|
||||
save();
|
||||
@@ -306,7 +310,10 @@ bool StreamsModel::save(const QString &filename, const QModelIndexList &selectio
|
||||
stream.setAttribute("name", s->name);
|
||||
stream.setAttribute("url", s->url.toString());
|
||||
if (!s->icon.isEmpty() && s->icon!=constDefaultStreamIcon) {
|
||||
stream.setAttribute("icon", c->icon);
|
||||
stream.setAttribute("icon", s->icon);
|
||||
}
|
||||
if (!s->genre.isEmpty()) {
|
||||
stream.setAttribute("genre", s->genre);
|
||||
}
|
||||
cat.appendChild(stream);
|
||||
}
|
||||
@@ -317,7 +324,7 @@ bool StreamsModel::save(const QString &filename, const QModelIndexList &selectio
|
||||
return true;
|
||||
}
|
||||
|
||||
bool StreamsModel::add(const QString &cat, const QString &name, const QString &icon, const QString &url)
|
||||
bool StreamsModel::add(const QString &cat, const QString &name, const QString &genre, const QString &icon, const QString &url)
|
||||
{
|
||||
QUrl u(url);
|
||||
CategoryItem *c=getCategory(cat, true, true);
|
||||
@@ -327,7 +334,7 @@ bool StreamsModel::add(const QString &cat, const QString &name, const QString &i
|
||||
}
|
||||
|
||||
beginInsertRows(createIndex(items.indexOf(c), 0, c), c->streams.count(), c->streams.count());
|
||||
StreamItem *stream=new StreamItem(name, icon.isEmpty() || icon==constDefaultStreamIcon ? QString() : icon, QUrl(url), c);
|
||||
StreamItem *stream=new StreamItem(name, genre, icon.isEmpty() || icon==constDefaultStreamIcon ? QString() : icon, QUrl(url), c);
|
||||
c->itemMap.insert(url, stream);
|
||||
c->streams.append(stream);
|
||||
endInsertRows();
|
||||
@@ -353,7 +360,7 @@ void StreamsModel::editCategory(const QModelIndex &index, const QString &name, c
|
||||
}
|
||||
}
|
||||
|
||||
void StreamsModel::editStream(const QModelIndex &index, const QString &oldCat, const QString &newCat, const QString &name, const QString &icon, const QString &url)
|
||||
void StreamsModel::editStream(const QModelIndex &index, const QString &oldCat, const QString &newCat, const QString &name, const QString &genre, const QString &icon, const QString &url)
|
||||
{
|
||||
if (!index.isValid()) {
|
||||
return;
|
||||
@@ -366,7 +373,8 @@ void StreamsModel::editStream(const QModelIndex &index, const QString &oldCat, c
|
||||
}
|
||||
|
||||
if (!newCat.isEmpty() && oldCat!=newCat) {
|
||||
if(add(newCat, name, icon.isEmpty() || icon==constDefaultStreamIcon ? QString() : icon, url)) {
|
||||
if(add(newCat, name, genre, icon.isEmpty() || icon==constDefaultStreamIcon ? QString() : icon, url)) {
|
||||
updateGenres();
|
||||
remove(index);
|
||||
}
|
||||
return;
|
||||
@@ -384,6 +392,10 @@ void StreamsModel::editStream(const QModelIndex &index, const QString &oldCat, c
|
||||
cat->itemMap.remove(oldUrl);
|
||||
cat->itemMap.insert(url, stream);
|
||||
}
|
||||
if (stream->genre!=genre) {
|
||||
stream->genre=genre;
|
||||
updateGenres();
|
||||
}
|
||||
emit dataChanged(index, index);
|
||||
modified=true;
|
||||
save();
|
||||
@@ -406,6 +418,7 @@ void StreamsModel::remove(const QModelIndex &index)
|
||||
delete old;
|
||||
endRemoveRows();
|
||||
modified=true;
|
||||
updateGenres();
|
||||
}
|
||||
} else {
|
||||
StreamItem *stream=static_cast<StreamItem *>(item);
|
||||
@@ -425,6 +438,7 @@ void StreamsModel::remove(const QModelIndex &index)
|
||||
cat->itemMap.remove(old->url.toString());
|
||||
endRemoveRows();
|
||||
delete old;
|
||||
updateGenres();
|
||||
}
|
||||
modified=true;
|
||||
}
|
||||
@@ -528,6 +542,22 @@ void StreamsModel::persist()
|
||||
}
|
||||
}
|
||||
|
||||
void StreamsModel::updateGenres()
|
||||
{
|
||||
QSet<QString> genres;
|
||||
foreach (CategoryItem *c, items) {
|
||||
c->genres.clear();
|
||||
foreach (const StreamItem *s, c->streams) {
|
||||
if (!s->genre.isEmpty()) {
|
||||
c->genres.insert(s->genre);
|
||||
genres.insert(s->genre);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit genresUpdated(genres);
|
||||
}
|
||||
|
||||
void StreamsModel::clearCategories()
|
||||
{
|
||||
qDeleteAll(items);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QSet>
|
||||
|
||||
class QTimer;
|
||||
|
||||
@@ -51,8 +52,9 @@ public:
|
||||
struct CategoryItem;
|
||||
struct StreamItem : public Item
|
||||
{
|
||||
StreamItem(const QString &n, const QString &i, const QUrl &u, CategoryItem *p=0) : Item(n, i), url(u), parent(p) { }
|
||||
StreamItem(const QString &n, const QString &g, const QString &i, const QUrl &u, CategoryItem *p=0) : Item(n, i), genre(g), url(u), parent(p) { }
|
||||
bool isCategory() { return false; }
|
||||
QString genre;
|
||||
QUrl url;
|
||||
CategoryItem *parent;
|
||||
};
|
||||
@@ -65,6 +67,7 @@ public:
|
||||
void clearStreams();
|
||||
QHash<QString, StreamItem *> itemMap;
|
||||
QList<StreamItem *> streams;
|
||||
QSet<QString> genres;
|
||||
};
|
||||
|
||||
StreamsModel();
|
||||
@@ -80,9 +83,9 @@ public:
|
||||
void save(bool force=false);
|
||||
bool save(const QString &filename, const QModelIndexList &selection=QModelIndexList());
|
||||
bool import(const QString &filename) { return load(filename, false); }
|
||||
bool add(const QString &cat, const QString &name, const QString &icon, const QString &url);
|
||||
bool add(const QString &cat, const QString &name, const QString &genre, const QString &icon, const QString &url);
|
||||
void editCategory(const QModelIndex &index, const QString &name, const QString &icon);
|
||||
void editStream(const QModelIndex &index, const QString &oldCat, const QString &newCat, const QString &name, const QString &icon, const QString &url);
|
||||
void editStream(const QModelIndex &index, const QString &oldCat, const QString &newCat, const QString &name, const QString &genre, const QString &icon, const QString &url);
|
||||
void remove(const QModelIndex &index);
|
||||
QString name(const QString &cat, const QString &url) { return name(getCategory(cat), url); }
|
||||
bool entryExists(const QString &cat, const QString &name, const QUrl &url=QUrl()) { return entryExists(getCategory(cat), name, url); }
|
||||
@@ -91,7 +94,11 @@ public:
|
||||
QMimeData * mimeData(const QModelIndexList &indexes) const;
|
||||
void mark(const QList<int> &rows, bool f);
|
||||
|
||||
Q_SIGNALS:
|
||||
void genresUpdated(const QSet<QString> &genres);
|
||||
|
||||
private:
|
||||
void updateGenres();
|
||||
void clearCategories();
|
||||
bool load(const QString &filename, bool isInternal);
|
||||
CategoryItem * getCategory(const QString &name, bool create=false, bool signal=false);
|
||||
|
||||
@@ -33,13 +33,49 @@ StreamsProxyModel::StreamsProxyModel(QObject *parent)
|
||||
sort(0);
|
||||
}
|
||||
|
||||
void StreamsProxyModel::setFilterGenre(const QString &genre)
|
||||
{
|
||||
if (filterGenre!=genre) {
|
||||
invalidate();
|
||||
}
|
||||
filterGenre=genre;
|
||||
}
|
||||
|
||||
bool StreamsProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
if (filterRegExp().isEmpty()) {
|
||||
if (filterGenre.isEmpty() && filterRegExp().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (!isChildOfRoot(sourceParent)) {
|
||||
return true;
|
||||
}
|
||||
return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
|
||||
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
StreamsModel::Item *item = static_cast<StreamsModel::Item *>(index.internalPointer());
|
||||
|
||||
if (item->isCategory()) {
|
||||
StreamsModel::CategoryItem *cat = static_cast<StreamsModel::CategoryItem *>(item);
|
||||
|
||||
if (!filterGenre.isEmpty() && !cat->genres.contains(filterGenre)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (cat->name.contains(filterRegExp())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (StreamsModel::StreamItem *s, cat->streams) {
|
||||
if (s->name.contains(filterRegExp())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StreamsModel::StreamItem *s = static_cast<StreamsModel::StreamItem *>(item);
|
||||
|
||||
if (!filterGenre.isEmpty() && s->genre!=filterGenre) {
|
||||
return false;
|
||||
}
|
||||
return s->name.contains(filterRegExp());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,11 @@ class StreamsProxyModel : public ProxyModel
|
||||
{
|
||||
public:
|
||||
StreamsProxyModel(QObject *parent = 0);
|
||||
void setFilterGenre(const QString &genre);
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||
|
||||
private:
|
||||
QString filterGenre;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user