- Implement ThemesModel (load theme icons once, store in memory, don't reload from disk every time selection changes)
- .pro file is usable again
--- a/QTfrontend/CMakeLists.txt Wed Jun 22 01:04:38 2011 +0200
+++ b/QTfrontend/CMakeLists.txt Thu Jun 23 21:12:27 2011 +0400
@@ -114,6 +114,7 @@
qaspectratiolayout.cpp
drawmapwidget.cpp
drawmapscene.cpp
+ themesmodel.cpp
)
#xfire integration
@@ -195,6 +196,7 @@
qaspectratiolayout.h
drawmapwidget.h
drawmapscene.h
+ themesmodel.h
)
set(hwfr_hdrs
--- a/QTfrontend/game.cpp Wed Jun 22 01:04:38 2011 +0200
+++ b/QTfrontend/game.cpp Thu Jun 23 21:12:27 2011 +0400
@@ -20,6 +20,7 @@
#include <QByteArray>
#include <QUuid>
#include <QColor>
+#include <QStringListModel>
#include "game.h"
#include "hwconsts.h"
@@ -110,7 +111,7 @@
HWProto::addStringToBuffer(teamscfg, "TL");
HWProto::addStringToBuffer(teamscfg, QString("etheme %1")
- .arg((Themes->size() > 0) ? Themes->at(rand() % Themes->size()) : "steel"));
+ .arg((themesModel->rowCount() > 0) ? themesModel->index(rand() % themesModel->rowCount()).data().toString() : "steel"));
HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString());
HWNamegen namegen;
--- a/QTfrontend/hwconsts.cpp.in Wed Jun 22 01:04:38 2011 +0200
+++ b/QTfrontend/hwconsts.cpp.in Thu Jun 23 21:12:27 2011 +0400
@@ -27,7 +27,7 @@
QDir * cfgdir = new QDir();
QDir * datadir = new QDir();
-QStringList * Themes;
+ThemesModel * themesModel;
QStringList * mapList;
QStringList * scriptList;
--- a/QTfrontend/hwconsts.h Wed Jun 22 01:04:38 2011 +0200
+++ b/QTfrontend/hwconsts.h Thu Jun 23 21:12:27 2011 +0400
@@ -22,6 +22,8 @@
#include <QStringList>
#include <QPair>
+#include "themesmodel.h"
+
extern QString * cProtoVer;
extern QString * cVersionString;
extern QString * cDataDir;
@@ -37,7 +39,9 @@
extern int cMaxTeams;
extern int cMinServerVersion;
-extern QStringList * Themes;
+class QStringListModel;
+
+extern ThemesModel * themesModel;
extern QStringList * mapList;
extern QStringList * scriptList;
--- a/QTfrontend/main.cpp Wed Jun 22 01:04:38 2011 +0200
+++ b/QTfrontend/main.cpp Thu Jun 23 21:12:27 2011 +0400
@@ -25,6 +25,7 @@
#include <QRegExp>
#include <QMap>
#include <QSettings>
+#include <QStringListModel>
#include "hwform.h"
#include "hwconsts.h"
@@ -387,23 +388,49 @@
{
QDir dir;
dir.setPath(cfgdir->absolutePath() + "/Data/Themes");
- Themes = new QStringList();
- Themes->append(dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot));
+
+ QStringList themes;
+ themes.append(dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot));
dir.setPath(datadir->absolutePath() + "/Themes");
- Themes->append(dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot));
-qDebug() << *Themes;
- for(int i = Themes->size() - 1; i >= 0; --i)
+ themes.append(dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot));
+
+ QList<QPair<QIcon, QIcon> > icons;
+
+ for(int i = themes.size() - 1; i >= 0; --i)
{
QFile tmpfile;
- tmpfile.setFileName(QString("%1/Data/Themes/%2/icon.png").arg(cfgdir->absolutePath()).arg(Themes->at(i)));
+ tmpfile.setFileName(QString("%1/Data/Themes/%2/icon.png").arg(cfgdir->absolutePath()).arg(themes.at(i)));
if (!tmpfile.exists())
{
- tmpfile.setFileName(QString("%1/Themes/%2/icon.png").arg(datadir->absolutePath()).arg(Themes->at(i)));
- if(!tmpfile.exists())
- Themes->removeAt(i);
+ tmpfile.setFileName(QString("%1/Themes/%2/icon.png").arg(datadir->absolutePath()).arg(themes.at(i)));
+ if(tmpfile.exists())
+ { // load icon
+ QPair<QIcon, QIcon> ic;
+ ic.first = QIcon(QFileInfo(tmpfile).absoluteFilePath());
+
+ QFile previewIconFile;
+ previewIconFile.setFileName(QString("%1/Data/Themes/%2/icon@2x.png").arg(cfgdir->absolutePath()).arg(themes.at(i)));
+ if (previewIconFile.exists()) ic.second = QIcon(QFileInfo(previewIconFile).absoluteFilePath());
+ else ic.second = QIcon(QString("%1/Themes/%2/icon@2x.png").arg(datadir->absolutePath()).arg(themes.at(i)));
+
+ icons.prepend(ic);
+ }
+ else
+ {
+ themes.removeAt(i);
+ }
}
}
+
+ themesModel = new ThemesModel(themes);
+ for(int i = 0; i < icons.size(); ++i)
+ {
+ themesModel->setData(themesModel->index(i), icons[i].first, Qt::DecorationRole);
+ themesModel->setData(themesModel->index(i), icons[i].second, Qt::UserRole);
+
+ qDebug() << "icon test" << themesModel->index(i).data(Qt::UserRole).toString();
+ }
}
QDir tmpdir;
@@ -434,8 +461,8 @@
QTranslator Translator;
{
QSettings settings(cfgdir->absolutePath() + "/hedgewars.ini", QSettings::IniFormat);
- QString cc = settings.value("misc/locale", "").toString();
- if(!cc.compare(""))
+ QString cc = settings.value("misc/locale", QString()).toString();
+ if(cc.isEmpty())
cc = QLocale::system().name();
QFile tmpfile;
tmpfile.setFileName(cfgdir->absolutePath() + "Data/Locale/hedgewars_" + cc);
--- a/QTfrontend/mapContainer.cpp Wed Jun 22 01:04:38 2011 +0200
+++ b/QTfrontend/mapContainer.cpp Thu Jun 23 21:12:27 2011 +0400
@@ -25,11 +25,12 @@
#include <QColor>
#include <QTextStream>
#include <QLabel>
-#include <QListWidget>
+#include <QListView>
#include <QVBoxLayout>
#include <QIcon>
#include <QLineEdit>
#include <QMessageBox>
+#include <QStringListModel>
#include "hwconsts.h"
#include "mapContainer.h"
@@ -200,24 +201,18 @@
QVBoxLayout * gbTLayout = new QVBoxLayout(gbThemes);
gbTLayout->setContentsMargins(0, 0, 0 ,0);
gbTLayout->setSpacing(0);
- lwThemes = new QListWidget(mapWidget);
- lwThemes->setMinimumHeight(30);
- lwThemes->setFixedWidth(140);
- QFile tmpfile;
- for (int i = 0; i < Themes->size(); ++i) {
- QListWidgetItem * lwi = new QListWidgetItem();
- lwi->setText(Themes->at(i));
- tmpfile.setFileName(QString("%1/Data/Themes/%2/icon.png").arg(cfgdir->absolutePath()).arg(Themes->at(i)));
- if (tmpfile.exists()) lwi->setIcon(QIcon(QFileInfo(tmpfile).absoluteFilePath()));
- else lwi->setIcon(QIcon(QString("%1/Themes/%2/icon.png").arg(datadir->absolutePath()).arg(Themes->at(i))));
- //lwi->setTextAlignment(Qt::AlignHCenter);
- lwThemes->addItem(lwi);
- }
- connect(lwThemes, SIGNAL(currentRowChanged(int)), this, SLOT(themeSelected(int)));
+ lvThemes = new QListView(mapWidget);
+ lvThemes->setMinimumHeight(30);
+ lvThemes->setFixedWidth(140);
+ lvThemes->setModel(themesModel);
+ lvThemes->setIconSize(QSize(16, 16));
+ lvThemes->setEditTriggers(QListView::NoEditTriggers);
+
+ connect(lvThemes->selectionModel(), SIGNAL(currentRowChanged( const QModelIndex &, const QModelIndex &)), this, SLOT(themeSelected( const QModelIndex &, const QModelIndex &)));
// override default style to tighten up theme scroller
- lwThemes->setStyleSheet(QString(
- "QListWidget{"
+ lvThemes->setStyleSheet(QString(
+ "QListView{"
"border: solid;"
"border-width: 0px;"
"border-radius: 0px;"
@@ -229,8 +224,8 @@
)
);
- gbTLayout->addWidget(lwThemes);
- lwThemes->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
+ gbTLayout->addWidget(lvThemes);
+ lvThemes->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum);
mapLayout->setSizeConstraint(QLayout::SetFixedSize);
@@ -376,9 +371,9 @@
);
}
-void HWMapContainer::themeSelected(int currentRow)
+void HWMapContainer::themeSelected(const QModelIndex & current, const QModelIndex &)
{
- QString theme = Themes->at(currentRow);
+ QString theme = current.data().toString();
QList<QVariant> mapInfo;
mapInfo.push_back(QString("+rnd+"));
mapInfo.push_back(theme);
@@ -389,10 +384,8 @@
chooseMap->setItemData(1, mapInfo);
mapInfo[0] = QString("+drawn+");
chooseMap->setItemData(2, mapInfo);
- QFile tmpfile;
- tmpfile.setFileName(QString("%1/Data/Themes/%2/icon@2x.png").arg(cfgdir->absolutePath()).arg(theme));
- if (tmpfile.exists()) gbThemes->setIcon(QIcon(QFileInfo(tmpfile).absoluteFilePath()));
- else gbThemes->setIcon(QIcon(QString("%1/Themes/%2/icon@2x.png").arg(datadir->absolutePath()).arg(theme)));
+
+ gbThemes->setIcon(qVariantValue<QIcon>(current.data(Qt::UserRole)));
emit themeChanged(theme);
}
@@ -487,9 +480,10 @@
void HWMapContainer::setTheme(const QString & theme)
{
- QList<QListWidgetItem *> items = lwThemes->findItems(theme, Qt::MatchExactly);
- if(items.size())
- lwThemes->setCurrentItem(items.at(0));
+ QModelIndexList mdl = themesModel->match(themesModel->index(0), Qt::DisplayRole, theme);
+
+ if(mdl.size())
+ lvThemes->setCurrentIndex(mdl.at(0));
}
void HWMapContainer::setRandomMap()
@@ -539,9 +533,9 @@
void HWMapContainer::setRandomTheme()
{
- if(!Themes->size()) return;
- quint32 themeNum = rand() % Themes->size();
- lwThemes->setCurrentRow(themeNum);
+ if(!themesModel->rowCount()) return;
+ quint32 themeNum = rand() % themesModel->rowCount();
+ lvThemes->setCurrentIndex(themesModel->index(themeNum));
}
void HWMapContainer::intSetTemplateFilter(int filter)
--- a/QTfrontend/mapContainer.h Wed Jun 22 01:04:38 2011 +0200
+++ b/QTfrontend/mapContainer.h Thu Jun 23 21:12:27 2011 +0400
@@ -32,7 +32,7 @@
class QPushButton;
class IconedGroupBox;
-class QListWidget;
+class QListView;
class MapFileErrorException
{
@@ -89,7 +89,7 @@
void setRandomMap();
void setRandomStatic();
void setRandomMission();
- void themeSelected(int currentRow);
+ void themeSelected(const QModelIndex & current, const QModelIndex &);
void addInfoToPreview(QPixmap image);
void seedEdited();
@@ -101,7 +101,7 @@
QPushButton* imageButt;
QComboBox* chooseMap;
IconedGroupBox* gbThemes;
- QListWidget* lwThemes;
+ QListView* lvThemes;
HWMap* pMap;
QString m_seed;
QPushButton* seedSet;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/themesmodel.cpp Thu Jun 23 21:12:27 2011 +0400
@@ -0,0 +1,47 @@
+
+#include "themesmodel.h"
+
+ThemesModel::ThemesModel(QStringList themes, QObject *parent) :
+ QAbstractListModel(parent)
+{
+ m_data.reserve(themes.size());
+
+ foreach(QString theme, themes)
+ {
+ m_data.append(QHash<int, QVariant>());
+ m_data.last().insert(Qt::DisplayRole, theme);
+ }
+}
+
+int ThemesModel::rowCount(const QModelIndex &parent) const
+{
+ if(parent.isValid())
+ return 0;
+ else
+ return m_data.size();
+}
+
+QVariant ThemesModel::data(const QModelIndex &index, int role) const
+{
+ if(index.column() > 0 || index.row() >= m_data.size())
+ return QVariant();
+ else
+ return m_data.at(index.row()).value(role);
+}
+
+bool ThemesModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ if(index.column() > 0 || index.row() >= m_data.size())
+ return false;
+ else
+ {
+ m_data[index.row()].insert(role, value);
+
+ return true;
+ }
+
+}
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/QTfrontend/themesmodel.h Thu Jun 23 21:12:27 2011 +0400
@@ -0,0 +1,28 @@
+#ifndef THEMESMODEL_H
+#define THEMESMODEL_H
+
+#include <QAbstractListModel>
+#include <QStringList>
+#include <QHash>
+
+class ThemesModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ explicit ThemesModel(QStringList themes, QObject *parent = 0);
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value,
+ int role = Qt::EditRole);
+
+signals:
+
+public slots:
+
+private:
+
+ QList<QHash<int, QVariant> > m_data;
+};
+
+#endif // THEMESMODEL_H
--- a/project_files/hedgewars.pro Wed Jun 22 01:04:38 2011 +0200
+++ b/project_files/hedgewars.pro Thu Jun 23 21:12:27 2011 +0400
@@ -59,7 +59,12 @@
../QTfrontend/pagedrawmap.h \
../QTfrontend/pageconnecting.h \
../QTfrontend/pagecampaign.h \
- ../QTfrontend/pageadmin.h
+ ../QTfrontend/pageadmin.h \
+ ../QTfrontend/pageplayrecord.h \
+ ../QTfrontend/pagegamestats.h \
+ ../QTfrontend/HWApplication.h \
+ ../QTfrontend/AbstractPage.h \
+ ../QTfrontend/themesmodel.h
SOURCES += ../QTfrontend/SDLs.cpp ../QTfrontend/SquareLabel.cpp \
../QTfrontend/about.cpp ../QTfrontend/ammoSchemeModel.cpp \
@@ -106,7 +111,11 @@
../QTfrontend/pagedrawmap.cpp \
../QTfrontend/pageconnecting.cpp \
../QTfrontend/pagecampaign.cpp \
- ../QTfrontend/pageadmin.cpp
+ ../QTfrontend/pageadmin.cpp \
+ ../QTfrontend/pagegamestats.cpp \
+ ../QTfrontend/pageplayrecord.cpp \
+ ../QTfrontend/HWApplication.cpp \
+ ../QTfrontend/themesmodel.cpp
win32 {
SOURCES += ../QTfrontend/xfire.cpp