Fix QSettings problems:
- Reopen file in ReadOnly mode if it was open in ReadWrite mode
and is being read. This is needed for stupid QSettings which
opens file in ReadWrite mode just to call readAll() on it.
- Implement setSize(0)
/*
* Hedgewars, a free turn based strategy game
* Copyright (c) 2004-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"
void MapModel::loadMaps()
{
// this method resets the contents of this model (important to know for views).
beginResetModel();
// we'll need the DataManager a few times, so let's get a reference to it
DataManager & datamgr = DataManager::instance();
// fetch list of available maps
QStringList maps =
datamgr.entryList("Maps", QDir::AllDirs | QDir::NoDotAndDotDot);
// empty list, so that we can (re)fill it
QStandardItemModel::clear();
QList<QStandardItem *> genMaps;
QList<QStandardItem *> missionMaps;
QList<QStandardItem *> staticMaps;
// add generated/handdrawn maps to list
// TODO: icons for these
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+"));
// only 2 map relate files are relevant:
// - the cfg file that contains the settings/info of the map
// - the lua file - if it exists it's a mission, otherwise it isn't
QFile mapLuaFile;
QFile mapCfgFile;
// add mission/static maps to lists
foreach (QString map, maps)
{
mapCfgFile.setFileName(QString("physfs://Maps/%1/map.cfg").arg(map));
mapLuaFile.setFileName(QString("physfs://Maps/%1/map.lua").arg(map));
if (mapCfgFile.open(QFile::ReadOnly))
{
QString caption;
QString theme;
quint32 limit = 0;
QString scheme;
QString weapons;
// if there is a lua file for this map, then it's a mission
bool isMission = mapLuaFile.exists();
MapType type = isMission?MissionMap:StaticMap;
// load map info from file
QTextStream input(&mapCfgFile);
input >> theme;
input >> limit;
if (isMission) { // scheme and weapons are only relevant for missions
input >> scheme;
input >> weapons;
}
mapCfgFile.close();
// let's use some semi-sane hedgehog limit, rather than none
if (limit == 0)
limit = 18;
// the default scheme/weaponset for missions.
// if empty we assume the map sets these internally -> locked
if (isMission)
{
if (scheme.isEmpty())
scheme = "locked";
else
scheme.replace("_", " ");
if (weapons.isEmpty())
weapons = "locked";
else
weapons.replace("_", " ");
}
// add a mission caption prefix to missions
if (isMission)
{
// TODO: icon
caption = QComboBox::tr("Mission") + ": " + map;
}
else
caption = map;
// we know everything there is about the map, let's get am item for it
QStandardItem * item = infoToItem(
QIcon(), caption, type, map, theme, limit, scheme, weapons);
// append item to the list
if (isMission)
missionMaps.append(item);
else
staticMaps.append(item);
}
}
// define a separator item
QStandardItem separator("---");
separator.setData(QLatin1String("separator"), Qt::AccessibleDescriptionRole);
separator.setFlags(separator.flags() & ~( Qt::ItemIsEnabled | Qt::ItemIsSelectable ) );
// create list:
// generated+handdrawn maps, 2 saperators, missions, 1 separator, static maps
QList<QStandardItem * > items;
items.append(genMaps);
items.append(separator.clone());
items.append(separator.clone());
items.append(missionMaps);
items.append(separator.clone());
items.append(staticMaps);
// create row-index lookup table
m_mapIndexes.clear();
int count = items.size();
for (int i = 0; i < count; i++)
{
QStandardItem * si = items.at(i);
QVariant v = si->data(Qt::UserRole + 1);
if (v.canConvert<MapInfo>())
m_mapIndexes.insert(v.value<MapInfo>().name, i);
}
// store start-index and count of relevant types
m_typeLoc.insert(GeneratedMap, QPair<int,int>(0, 1));
m_typeLoc.insert(GeneratedMaze, QPair<int,int>(1, 1));
m_typeLoc.insert(HandDrawnMap, QPair<int,int>(2, 1));
// mission maps
int startIdx = genMaps.size() + 2; // start after genMaps and 2 separators
count = missionMaps.size();
m_typeLoc.insert(MissionMap, QPair<int,int>(startIdx, count));
// static maps
startIdx += count + 1; // start after missions and 2 separators
count = staticMaps.size();
m_typeLoc.insert(StaticMap, QPair<int,int>(startIdx, count));
// store list contents in the item model
QStandardItemModel::appendColumn(items);
endResetModel();
}
int MapModel::randomMap(MapType type) const
{
// return a random index for this type or -1 if none available
QPair<int,int> loc = m_typeLoc.value(type, QPair<int,int>(-1,0));
int startIdx = loc.first;
int count = loc.second;
if (count < 1)
return -1;
else
return startIdx + (rand() % count);
}
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);
return item;
}
int MapModel::indexOf(const QString & map) const
{
return m_mapIndexes.value(map, -1);
}