diff -r 6e8b807bda4b -r ba39a1d396c0 QTfrontend/model/ThemeModel.cpp --- a/QTfrontend/model/ThemeModel.cpp Sun Jun 10 18:56:51 2018 +0200 +++ b/QTfrontend/model/ThemeModel.cpp Sun Jun 10 19:12:26 2018 +0200 @@ -33,21 +33,48 @@ m_themesLoaded = false; m_filteredNoDLC = NULL; + m_filteredNoHidden = NULL; + m_filteredNoDLCOrHidden = NULL; } -QSortFilterProxyModel * ThemeModel::withoutDLC() +// Filters out DLC themes, e.g. themes which do not come by default +ThemeFilterProxyModel * ThemeModel::withoutDLC() { if (m_filteredNoDLC == NULL) { - m_filteredNoDLC = new QSortFilterProxyModel(this); + m_filteredNoDLC = new ThemeFilterProxyModel(this); m_filteredNoDLC->setSourceModel(this); - // filtering based on IsDlcRole would be nicer - // but seems this model can only do string-based filtering :| - m_filteredNoDLC->setFilterRegExp(QRegExp("^[^*]")); + m_filteredNoDLC->setFilterDLC(true); } return m_filteredNoDLC; } +// Filters out hidden themes, these are themes which are not supposed to be +// seen by the user. +ThemeFilterProxyModel * ThemeModel::withoutHidden() +{ + if (m_filteredNoHidden == NULL) + { + m_filteredNoHidden = new ThemeFilterProxyModel(this); + m_filteredNoHidden->setSourceModel(this); + m_filteredNoHidden->setFilterHidden(true); + } + return m_filteredNoHidden; +} + +// Combination of the two above for convenience +ThemeFilterProxyModel * ThemeModel::withoutDLCOrHidden() +{ + if (m_filteredNoDLCOrHidden == NULL) + { + m_filteredNoDLCOrHidden = new ThemeFilterProxyModel(this); + m_filteredNoDLCOrHidden->setSourceModel(this); + m_filteredNoDLCOrHidden->setFilterDLC(true); + m_filteredNoDLCOrHidden->setFilterHidden(true); + } + return m_filteredNoDLCOrHidden; +} + int ThemeModel::rowCount(const QModelIndex &parent) const { if(parent.isValid()) @@ -95,16 +122,42 @@ foreach (QString theme, themes) { + QMap dataset; + // themes without icon are supposed to be hidden QString iconpath = QString("physfs://Themes/%1/icon.png").arg(theme); if (!QFile::exists(iconpath)) - continue; - - QMap dataset; + { + dataset.insert(IsHiddenRole, true); + } + else + { + // themes with the key “hidden” in theme.cfg are hidden, too + QFile themeCfgFile(QString("physfs://Themes/%1/theme.cfg").arg(theme)); + if (themeCfgFile.open(QFile::ReadOnly)) + { + QTextStream stream(&themeCfgFile); + QString line = stream.readLine(); + QString key; + while (!line.isNull()) + { + key = QString(line); + int equalsPos = line.indexOf('='); + key.truncate(equalsPos - 1); + key = key.simplified(); + if (!line.startsWith(';') && key == "hidden") + { + dataset.insert(IsHiddenRole, true); + break; + } + line = stream.readLine(); + } + } + } // detect if theme is dlc - QString themeDir = PHYSFS_getRealDir(QString("Themes/%1/icon.png").arg(theme).toLocal8Bit().data()); + QString themeDir = PHYSFS_getRealDir(QString("Themes/%1").arg(theme).toLocal8Bit().data()); bool isDLC = !themeDir.startsWith(datadir->absolutePath()); dataset.insert(IsDlcRole, isDLC); @@ -118,8 +171,12 @@ dataset.insert(Qt::DisplayRole, (isDLC ? "*" : "") + theme); // load and set preview icon - QIcon preview(QString("physfs://Themes/%1/icon@2x.png").arg(theme)); - dataset.insert(Qt::DecorationRole, preview); + iconpath = QString("physfs://Themes/%1/icon@2x.png").arg(theme); + if (QFile::exists(iconpath)) + { + QIcon preview(QString("physfs://Themes/%1/icon@2x.png").arg(theme)); + dataset.insert(Qt::DecorationRole, preview); + } m_data.append(dataset); }