MapModel converted to QStandardItemList; separators fixed; changed used data format (human-readable struct instead of magic list) for map info in HwMapContainer (+ various small cleanups in that class)
--- a/QTfrontend/model/MapModel.cpp Fri Apr 27 11:47:37 2012 +0200
+++ b/QTfrontend/model/MapModel.cpp Fri Apr 27 22:22:04 2012 +0200
@@ -1,67 +1,29 @@
+/*
+ * Hedgewars, a free turn based strategy game
+ * Copyright (c) 2006-2007 Igor Ulyanov <iulyanov@gmail.com>
+ * Copyright (c) 2007-2012 Andrey Korotaev <unC0Rr@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/**
+ * @file
+ * @brief MapModel class implementation
+ */
#include "MapModel.h"
-MapModel::MapInfo MapModel::mapInfoFromData(const QVariant data)
-{
- MapInfo mapInfo;
-
- mapInfo.type = Invalid;
- mapInfo.name = "";
- mapInfo.theme = "";
- mapInfo.limit = 0;
- mapInfo.scheme = "";
- mapInfo.weapons = "";
-
- if (data.isValid())
- {
- QList<QVariant> list = data.toList();
- if (list.size() < 1) {
- mapInfo.type = Invalid;
- return mapInfo;
- }
- mapInfo.type = (MapType)list[0].toInt();
- switch (mapInfo.type)
- {
- case GeneratedMap:
- case GeneratedMaze:
- case HandDrawnMap:
- return mapInfo;
-
- default:
- mapInfo.name = list[1].toString();
- mapInfo.theme = list[2].toString();
- mapInfo.limit = list[3].toInt();
- mapInfo.scheme = list[4].toString();
- mapInfo.weapons = list[5].toString();
- }
- }
-
- return mapInfo;
-}
-
-MapModel::MapModel(QObject *parent) :
- QAbstractListModel(parent)
-{
- m_data = QList<QMap<int, QVariant> >();
-}
-
-int MapModel::rowCount(const QModelIndex &parent) const
-{
- if(parent.isValid())
- return 0;
- else
- return m_data.size();
-}
-
-
-QVariant MapModel::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, QVariant());
-}
-
void MapModel::loadMaps()
{
@@ -73,34 +35,22 @@
QStringList maps =
datamgr.entryList("Maps", QDir::AllDirs | QDir::NoDotAndDotDot);
- m_data.clear();
+ QStandardItemModel::clear();
-#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
- m_data.reserve(maps.size());
-#endif
-
- QMap<int, QVariant> tmp;
- QList<QVariant> mapInfo;
+ QList<QStandardItem *> genMaps;
+ QList<QStandardItem *> missionMaps;
+ QList<QStandardItem *> staticMaps;
// TODO: icons for these
- tmp.insert(Qt::DisplayRole, QComboBox::tr("generated map..."));
- mapInfo.append(GeneratedMap);
- tmp.insert(Qt::UserRole, mapInfo);
- m_data.append(tmp);
- tmp.insert(Qt::DisplayRole, QComboBox::tr("generated maze..."));
- mapInfo.replace(0, GeneratedMaze);
- tmp.insert(Qt::UserRole, mapInfo);
- m_data.append(tmp);
- tmp.insert(Qt::DisplayRole, QComboBox::tr("hand drawn map..."));
- mapInfo.replace(0, HandDrawnMap);
- tmp.insert(Qt::UserRole, mapInfo);
- m_data.append(tmp);
- m_nGenerators = 3;
+ genMaps.append(
+ infoToItem(QIcon(), QComboBox::tr("generated map..."), GeneratedMap, "+rnd+"));
+ genMaps.append(
+ infoToItem(QIcon(), QComboBox::tr("generated maze..."), GeneratedMaze, "+maze+"));
+ genMaps.append(
+ infoToItem(QIcon(), QComboBox::tr("hand drawn map..."), HandDrawnMap, "+drawn+"));
- m_nMissions = 0;
-
QFile mapLuaFile;
QFile mapCfgFile;
@@ -111,80 +61,113 @@
mapLuaFile.setFileName(
datamgr.findFileForRead(QString("Maps/%1/map.lua").arg(map)));
- QMap<int, QVariant> dataset;
-
if (mapCfgFile.open(QFile::ReadOnly))
{
+ QString caption;
QString theme;
quint32 limit = 0;
QString scheme;
QString weapons;
- QList<QVariant> mapInfo;
bool isMission = mapLuaFile.exists();
- int type = isMission?MissionMap:StaticMap;
+ MapType type = isMission?MissionMap:StaticMap;
QTextStream input(&mapCfgFile);
input >> theme;
input >> limit;
input >> scheme;
input >> weapons;
- mapInfo.push_back(type);
- mapInfo.push_back(map);
- mapInfo.push_back(theme);
- if (limit)
- mapInfo.push_back(limit);
- else
- mapInfo.push_back(18);
+ mapCfgFile.close();
+
+ if (limit == 0)
+ limit = 18;
if (scheme.isEmpty())
scheme = "locked";
- scheme.replace("_", " ");
+ else
+ scheme.replace("_", " ");
if (weapons.isEmpty())
weapons = "locked";
- weapons.replace("_", " ");
+ else
+ weapons.replace("_", " ");
- mapInfo.push_back(scheme);
- mapInfo.push_back(weapons);
-
- if(isMission)
+ if (isMission)
{
// TODO: icon
- map = QComboBox::tr("Mission") + ": " + map;
+ caption = QComboBox::tr("Mission") + ": " + map;
m_nMissions++;
}
-
- mapCfgFile.close();
-
- // set name
- dataset.insert(Qt::DisplayRole, map);
+ else
+ caption = map;
- // TODO
- // dataset.insert(Qt::DecorationRole, icon);
+ QStandardItem * item = infoToItem(
+ QIcon(), caption, type, map, theme, limit, scheme, weapons);
- // set mapinfo
- dataset.insert(Qt::UserRole, mapInfo);
-
- if (isMission) // insert missions before regular maps
- m_data.insert(m_nGenerators + m_nMissions, dataset);
+ if (isMission)
+ missionMaps.append(item);
else
- m_data.append(dataset);
+ staticMaps.append(item);
}
}
+ m_nMissions = missionMaps.size();
+
+ QStandardItem separator("---");
+ separator.setData(QLatin1String("separator"), Qt::AccessibleDescriptionRole);
+ separator.setFlags(separator.flags() & ~( Qt::ItemIsEnabled | Qt::ItemIsSelectable ) );
+
+ QList<QStandardItem * > items;
+ items.append(genMaps);
+ items.append(separator.clone());
+ items.append(separator.clone());
+ items.append(missionMaps);
+ items.append(separator.clone());
+ items.append(staticMaps);
+
+ QStandardItemModel::appendColumn(items);
+
endResetModel();
}
-int MapModel::generatorCount() const
-{
- return m_nGenerators;
-}
int MapModel::missionCount() const
{
return m_nMissions;
}
+
+
+QStandardItem * MapModel::infoToItem(
+ const QIcon & icon,
+ const QString caption,
+ MapType type,
+ QString name,
+ QString theme,
+ quint32 limit,
+ QString scheme,
+ QString weapons)
+const
+{
+ QStandardItem * item = new QStandardItem(icon, caption);
+ MapInfo mapInfo;
+ QVariant qvar(QVariant::UserType);
+
+ mapInfo.type = type;
+ mapInfo.name = name;
+ mapInfo.theme = theme;
+ mapInfo.limit = limit;
+ mapInfo.scheme = scheme;
+ mapInfo.weapons = weapons;
+
+
+ qvar.setValue(mapInfo);
+ item->setData(qvar, Qt::UserRole + 1);
+
+ if (mapInfo.type == Invalid)
+ Q_ASSERT(false);
+
+ return item;
+}
--- a/QTfrontend/model/MapModel.h Fri Apr 27 11:47:37 2012 +0200
+++ b/QTfrontend/model/MapModel.h Fri Apr 27 22:22:04 2012 +0200
@@ -25,7 +25,7 @@
#ifndef HEDGEWARS_MAPMODEL_H
#define HEDGEWARS_MAPMODEL_H
-#include <QAbstractListModel>
+#include <QStandardItemModel>
#include <QStringList>
#include <QTextStream>
#include <QMap>
@@ -40,7 +40,7 @@
* @author sheepluva
* @since 0.9.18
*/
-class MapModel : public QAbstractListModel
+class MapModel : public QStandardItemModel
{
Q_OBJECT
@@ -64,13 +64,6 @@
QString weapons;
};
- static MapInfo mapInfoFromData(const QVariant data);
-
- explicit MapModel(QObject *parent = 0);
-
- int rowCount(const QModelIndex &parent = QModelIndex()) const;
- QVariant data(const QModelIndex &index, int role) const;
- int generatorCount() const;
int missionCount() const;
@@ -80,9 +73,19 @@
private:
- QList<QMap<int, QVariant> > m_data;
- int m_nGenerators;
int m_nMissions;
+
+ QStandardItem * infoToItem(
+ const QIcon & icon,
+ const QString caption,
+ MapType type = Invalid,
+ QString name = "",
+ QString theme = "",
+ quint32 limit = 0,
+ QString scheme = "",
+ QString weapons = "") const;
};
+Q_DECLARE_METATYPE(MapModel::MapInfo)
+
#endif // HEDGEWARS_MAPMODEL_H
--- a/QTfrontend/ui/widget/mapContainer.cpp Fri Apr 27 11:47:37 2012 +0200
+++ b/QTfrontend/ui/widget/mapContainer.cpp Fri Apr 27 22:22:04 2012 +0200
@@ -69,6 +69,7 @@
chooseMap = new QComboBox(mapWidget);
chooseMap->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_mapModel = DataManager::instance().mapModel();
+ chooseMap->setEditable(false);
chooseMap->setModel(m_mapModel);
// update model views after model changes (to e.g. re-adjust separators)
@@ -175,7 +176,6 @@
setRandomTheme();
chooseMap->setCurrentIndex(0);
- m_mapInfo = MapModel::mapInfoFromData(chooseMap->itemData(0));
mapChanged(0);
connect(chooseMap, SIGNAL(activated(int)), this, SLOT(mapChanged(int)));
@@ -210,7 +210,8 @@
void HWMapContainer::mapChanged(int index)
{
- m_mapInfo = MapModel::mapInfoFromData(chooseMap->itemData(chooseMap->currentIndex()));
+ Q_ASSERT(chooseMap->itemData(index, Qt::UserRole + 1).canConvert<MapModel::MapInfo>());
+ m_mapInfo = chooseMap->itemData(chooseMap->currentIndex(), Qt::UserRole + 1).value<MapModel::MapInfo>();
switch(m_mapInfo.type)
{
@@ -222,8 +223,6 @@
cbTemplateFilter->show();
maze_size_label->hide();
cbMazeSize->hide();
- emit mapChanged("+rnd+");
- emit themeChanged(m_mapInfo.theme);
break;
case MapModel::GeneratedMaze:
mapgen = MAPGEN_MAZE;
@@ -233,8 +232,6 @@
cbTemplateFilter->hide();
maze_size_label->show();
cbMazeSize->show();
- emit mapChanged("+maze+");
- emit themeChanged(m_mapInfo.theme);
break;
case MapModel::HandDrawnMap:
mapgen = MAPGEN_DRAWN;
@@ -244,8 +241,6 @@
cbTemplateFilter->hide();
maze_size_label->hide();
cbMazeSize->hide();
- emit mapChanged("+drawn+");
- emit themeChanged(m_mapInfo.theme);
break;
default:
mapgen = MAPGEN_MAP;
@@ -255,9 +250,11 @@
cbTemplateFilter->hide();
maze_size_label->hide();
cbMazeSize->hide();
- emit mapChanged(m_mapInfo.name);
}
+ if (m_mapInfo.theme.isEmpty())
+ emit themeChanged(lvThemes->currentIndex().data().toString());
+ emit mapChanged(m_mapInfo.name);
emit mapgenChanged(mapgen);
}
@@ -303,20 +300,10 @@
void HWMapContainer::themeSelected(const QModelIndex & current, const QModelIndex &)
{
- QString theme = current.data().toString();
- QList<QVariant> mapInfo;
- mapInfo.push_back(QString("+rnd+"));
- mapInfo.push_back(theme);
- mapInfo.push_back(18);
- mapInfo.push_back(false);
- chooseMap->setItemData(0, mapInfo);
- mapInfo[0] = QString("+maze+");
- chooseMap->setItemData(1, mapInfo);
- mapInfo[0] = QString("+drawn+");
- chooseMap->setItemData(2, mapInfo);
+ m_mapInfo.theme = current.data().toString();
gbThemes->setIcon(qVariantValue<QIcon>(current.data(Qt::UserRole)));
- emit themeChanged(theme);
+ emit themeChanged(m_mapInfo.theme);
}
QString HWMapContainer::getCurrentSeed() const
@@ -326,6 +313,7 @@
QString HWMapContainer::getCurrentMap() const
{
+ if(chooseMap->currentIndex() < MAPGEN_MAP) return QString();
return(m_mapInfo.name);
}
@@ -384,9 +372,13 @@
int id = 0;
for(int i = 0; i < chooseMap->count(); i++)
{
- MapModel::MapInfo mapInfo = MapModel::mapInfoFromData(chooseMap->itemData(i));
+ // skip separators
+ if (chooseMap->itemData(i, Qt::AccessibleDescriptionRole) == QLatin1String("separator"))
+ continue;
+ Q_ASSERT(chooseMap->itemData(i, Qt::UserRole + 1).canConvert<MapModel::MapInfo>());
+ MapModel::MapInfo mapInfo = chooseMap->itemData(i, Qt::UserRole + 1).value<MapModel::MapInfo>();
- if (mapInfo.name == map)
+ if (mapInfo.name == map)
{
id = i;
break;
@@ -576,10 +568,12 @@
break;
default:
QPixmap mapImage;
- QFile tmpfile;
- tmpfile.setFileName(cfgdir->absolutePath() + "/Data/Maps/" + m_mapInfo.name + "/preview.png");
- if (!tmpfile.exists()) tmpfile.setFileName(datadir->absolutePath() + "/Maps/" + m_mapInfo.name + "/preview.png");
- if(!mapImage.load(QFileInfo(tmpfile).absoluteFilePath()))
+ bool success = mapImage.load(
+ DataManager::instance().findFileForRead(
+ "Maps/" + m_mapInfo.name + "/preview.png")
+ );
+
+ if(!success)
{
imageButt->setIcon(QIcon());
return;
@@ -606,16 +600,6 @@
{
numMissions = m_mapModel->missionCount();
- intSetMap(m_mapInfo.name);
-
-/*
- int nGenMaps = m_mapModel->generatorCount();
-
- // insert double separator after random maps/mazes/etc
- chooseMap->insertSeparator(nGenMaps);
- chooseMap->insertSeparator(nGenMaps);
-
- // separator between missions and regular maps
- chooseMap->insertSeparator(nGenMaps + m_mapModel->missionCount());
-*/
+ if (!m_mapInfo.name.isEmpty())
+ intSetMap(m_mapInfo.name);
}