QTfrontend/model/MapModel.cpp
changeset 8377 869f80966a77
parent 8049 133e22b5c410
child 8385 9e8924ff9813
equal deleted inserted replaced
8376:c11cc7246df7 8377:869f80966a77
    20  * @file
    20  * @file
    21  * @brief MapModel class implementation
    21  * @brief MapModel class implementation
    22  */
    22  */
    23 
    23 
    24 #include "MapModel.h"
    24 #include "MapModel.h"
       
    25 #include "hwapplication.h"
    25 
    26 
       
    27 #include <QSettings>
    26 
    28 
    27 void MapModel::loadMaps()
    29 MapModel::MapInfo MapModel::MapInfoRandom = {MapModel::GeneratedMap, "+rnd+", "", 0, "", "", ""};
       
    30 MapModel::MapInfo MapModel::MapInfoMaze = {MapModel::GeneratedMaze, "+maze+", "", 0, "", "", ""};
       
    31 MapModel::MapInfo MapModel::MapInfoDrawn = {MapModel::HandDrawnMap, "+drawn+", "", 0, "", "", ""};
       
    32 
       
    33 void MapModel::loadMaps(MapType maptype)
    28 {
    34 {
    29     // this method resets the contents of this model (important to know for views).
    35     // this method resets the contents of this model (important to know for views).
    30     beginResetModel();
    36     beginResetModel();
    31 
    37 
    32     // we'll need the DataManager a few times, so let's get a reference to it
    38     // we'll need the DataManager a few times, so let's get a reference to it
    37         datamgr.entryList("Maps", QDir::AllDirs | QDir::NoDotAndDotDot);
    43         datamgr.entryList("Maps", QDir::AllDirs | QDir::NoDotAndDotDot);
    38 
    44 
    39     // empty list, so that we can (re)fill it
    45     // empty list, so that we can (re)fill it
    40     QStandardItemModel::clear();
    46     QStandardItemModel::clear();
    41 
    47 
    42     QList<QStandardItem *> genMaps;
    48     //QList<QStandardItem *> staticMaps;
    43     QList<QStandardItem *> missionMaps;
    49     //QList<QStandardItem *> missionMaps;
    44     QList<QStandardItem *> staticMaps;
    50     QList<QStandardItem *> mapList;
    45 
       
    46     // add generated/handdrawn maps to list
       
    47     // TODO: icons for these
       
    48 
       
    49     genMaps.append(
       
    50         infoToItem(QIcon(), QComboBox::tr("generated map..."), GeneratedMap, "+rnd+"));
       
    51     genMaps.append(
       
    52         infoToItem(QIcon(), QComboBox::tr("generated maze..."), GeneratedMaze, "+maze+"));
       
    53     genMaps.append(
       
    54         infoToItem(QIcon(), QComboBox::tr("hand drawn map..."), HandDrawnMap, "+drawn+"));
       
    55 
    51 
    56     // only 2 map relate files are relevant:
    52     // only 2 map relate files are relevant:
    57     // - the cfg file that contains the settings/info of the map
    53     // - the cfg file that contains the settings/info of the map
    58     // - the lua file - if it exists it's a mission, otherwise it isn't
    54     // - the lua file - if it exists it's a mission, otherwise it isn't
    59     QFile mapLuaFile;
    55     QFile mapLuaFile;
    62     // add mission/static maps to lists
    58     // add mission/static maps to lists
    63     foreach (QString map, maps)
    59     foreach (QString map, maps)
    64     {
    60     {
    65         mapCfgFile.setFileName(QString("physfs://Maps/%1/map.cfg").arg(map));
    61         mapCfgFile.setFileName(QString("physfs://Maps/%1/map.cfg").arg(map));
    66         mapLuaFile.setFileName(QString("physfs://Maps/%1/map.lua").arg(map));
    62         mapLuaFile.setFileName(QString("physfs://Maps/%1/map.lua").arg(map));
    67 
    63         QSettings descSettings(QString("physfs://Maps/%1/desc.txt").arg(map), QSettings::IniFormat);
    68 
    64 
    69         if (mapCfgFile.open(QFile::ReadOnly))
    65         if (mapCfgFile.open(QFile::ReadOnly))
    70         {
    66         {
    71             QString caption;
    67             QString caption;
    72             QString theme;
    68             QString theme;
    73             quint32 limit = 0;
    69             quint32 limit = 0;
    74             QString scheme;
    70             QString scheme;
    75             QString weapons;
    71             QString weapons;
       
    72             QString desc;
       
    73 
    76             // if there is a lua file for this map, then it's a mission
    74             // if there is a lua file for this map, then it's a mission
    77             bool isMission = mapLuaFile.exists();
    75             bool isMission = mapLuaFile.exists();
    78             MapType type = isMission?MissionMap:StaticMap;
    76             MapType type = isMission ? MissionMap : StaticMap;
       
    77 
       
    78             // If we're supposed to ignore this type, continue
       
    79             if (type != maptype) continue;
    79 
    80 
    80             // load map info from file
    81             // load map info from file
    81             QTextStream input(&mapCfgFile);
    82             QTextStream input(&mapCfgFile);
    82             input >> theme;
    83             theme = input.readLine();
    83             input >> limit;
    84             limit = input.readLine().toInt();
    84             if (isMission) { // scheme and weapons are only relevant for missions
    85             if (isMission) { // scheme and weapons are only relevant for missions
    85                 input >> scheme;
    86                 scheme = input.readLine();
    86                 input >> weapons;
    87                 weapons = input.readLine();
    87             }
    88             }
    88             mapCfgFile.close();
    89             mapCfgFile.close();
       
    90 
       
    91             // Load description (if applicable)
       
    92             if (isMission)
       
    93             {
       
    94                 QString locale = HWApplication::keyboardInputLocale().name();
       
    95                 desc = descSettings.value(locale, QString()).toString().replace("|", "\n");
       
    96             }
    89 
    97 
    90             // let's use some semi-sane hedgehog limit, rather than none
    98             // let's use some semi-sane hedgehog limit, rather than none
    91             if (limit == 0)
    99             if (limit == 0)
    92                 limit = 18;
   100                 limit = 18;
    93 
       
    94 
   101 
    95             // the default scheme/weaponset for missions.
   102             // the default scheme/weaponset for missions.
    96             // if empty we assume the map sets these internally -> locked
   103             // if empty we assume the map sets these internally -> locked
    97             if (isMission)
   104             if (isMission)
    98             {
   105             {
   105                     weapons = "locked";
   112                     weapons = "locked";
   106                 else
   113                 else
   107                     weapons.replace("_", " ");
   114                     weapons.replace("_", " ");
   108             }
   115             }
   109 
   116 
   110             // add a mission caption prefix to missions
   117             // caption
   111             if (isMission)
   118             caption = map;
   112             {
       
   113                 // TODO: icon
       
   114                 caption = QComboBox::tr("Mission") + ": " + map;
       
   115             }
       
   116             else
       
   117                 caption = map;
       
   118 
   119 
   119             // we know everything there is about the map, let's get am item for it
   120             // we know everything there is about the map, let's get am item for it
   120             QStandardItem * item = infoToItem(
   121             QStandardItem * item = MapModel::infoToItem(
   121                 QIcon(), caption, type, map, theme, limit, scheme, weapons);
   122                 QIcon(), caption, type, map, theme, limit, scheme, weapons, desc);
   122 
   123 
   123             // append item to the list
   124             // append item to the list
   124             if (isMission)
   125             mapList.append(item);
   125                 missionMaps.append(item);
       
   126             else
       
   127                 staticMaps.append(item);
       
   128         
       
   129         }
   126         }
   130 
   127 
   131     }
   128     }
   132 
   129 
   133 
   130     // Create column-index lookup table
   134     // define a separator item
       
   135     QStandardItem separator("---");
       
   136     separator.setData(QLatin1String("separator"), Qt::AccessibleDescriptionRole);
       
   137     separator.setFlags(separator.flags() & ~( Qt::ItemIsEnabled | Qt::ItemIsSelectable ) );
       
   138 
       
   139     // create list:
       
   140     // generated+handdrawn maps, 2 saperators, missions, 1 separator, static maps
       
   141     QList<QStandardItem * > items;
       
   142     items.append(genMaps);
       
   143     items.append(separator.clone());
       
   144     items.append(separator.clone());
       
   145     items.append(missionMaps);
       
   146     items.append(separator.clone());
       
   147     items.append(staticMaps);
       
   148 
       
   149 
       
   150     // create row-index lookup table
       
   151 
   131 
   152     m_mapIndexes.clear();
   132     m_mapIndexes.clear();
   153 
   133 
   154     int count = items.size();
       
   155 
   134 
       
   135     int count = mapList.size();
   156     for (int i = 0; i < count; i++)
   136     for (int i = 0; i < count; i++)
   157     {
   137     {
   158         QStandardItem * si = items.at(i);
   138         QStandardItem * si = mapList.at(i);
   159         QVariant v = si->data(Qt::UserRole + 1);
   139         QVariant v = si->data(Qt::UserRole + 1);
   160         if (v.canConvert<MapInfo>())
   140         if (v.canConvert<MapInfo>())
   161             m_mapIndexes.insert(v.value<MapInfo>().name, i);
   141             m_mapIndexes.insert(v.value<MapInfo>().name, i);
   162     }
   142     }
   163 
   143 
   164 
   144     QStandardItemModel::appendColumn(mapList);
   165     // store start-index and count of relevant types
       
   166 
       
   167     m_typeLoc.insert(GeneratedMap, QPair<int,int>(0, 1));
       
   168     m_typeLoc.insert(GeneratedMaze, QPair<int,int>(1, 1));
       
   169     m_typeLoc.insert(HandDrawnMap, QPair<int,int>(2, 1));
       
   170     // mission maps
       
   171     int startIdx = genMaps.size() + 2; // start after genMaps and 2 separators
       
   172     count = missionMaps.size();
       
   173     m_typeLoc.insert(MissionMap, QPair<int,int>(startIdx, count));
       
   174     // static maps
       
   175     startIdx += count + 1; // start after missions and 2 separators
       
   176     count = staticMaps.size();
       
   177     m_typeLoc.insert(StaticMap, QPair<int,int>(startIdx, count));
       
   178 
       
   179     // store list contents in the item model
       
   180     QStandardItemModel::appendColumn(items);
       
   181 
       
   182 
   145 
   183     endResetModel();
   146     endResetModel();
   184 }
   147 }
   185 
   148 
   186 
   149 bool MapModel::mapExists(const QString & map) const
   187 int MapModel::randomMap(MapType type) const
       
   188 {
   150 {
   189     // return a random index for this type or -1 if none available
   151     return findMap(map) >= 0;
   190     QPair<int,int> loc = m_typeLoc.value(type, QPair<int,int>(-1,0));
       
   191 
       
   192     int startIdx = loc.first;
       
   193     int count = loc.second;
       
   194 
       
   195     if (count < 1)
       
   196         return -1;
       
   197     else
       
   198         return startIdx + (rand() % count);
       
   199 }
   152 }
   200 
   153 
       
   154 int MapModel::findMap(const QString & map) const
       
   155 {
       
   156     return m_mapIndexes.value(map, -1);
       
   157 }
       
   158 
       
   159 QStandardItem * MapModel::getMap(const QString & map)
       
   160 {
       
   161     int loc = findMap(map);
       
   162     if (loc < 0) return NULL;
       
   163     return item(loc);
       
   164 }
   201 
   165 
   202 QStandardItem * MapModel::infoToItem(
   166 QStandardItem * MapModel::infoToItem(
   203     const QIcon & icon,
   167     const QIcon & icon,
   204     const QString caption,
   168     const QString caption,
   205     MapType type,
   169     MapType type,
   206     QString name,
   170     QString name,
   207     QString theme,
   171     QString theme,
   208     quint32 limit,
   172     quint32 limit,
   209     QString scheme,
   173     QString scheme,
   210     QString weapons)
   174     QString weapons,
   211 const
   175     QString desc)
   212 {
   176 {
   213     QStandardItem * item = new QStandardItem(icon, caption);
   177     QStandardItem * item = new QStandardItem(icon, caption);
   214     MapInfo mapInfo;
   178     MapInfo mapInfo;
   215     QVariant qvar(QVariant::UserType);
   179     QVariant qvar(QVariant::UserType);
   216 
   180 
   218     mapInfo.name = name;
   182     mapInfo.name = name;
   219     mapInfo.theme = theme;
   183     mapInfo.theme = theme;
   220     mapInfo.limit = limit;
   184     mapInfo.limit = limit;
   221     mapInfo.scheme = scheme;
   185     mapInfo.scheme = scheme;
   222     mapInfo.weapons = weapons;
   186     mapInfo.weapons = weapons;
   223 
   187     mapInfo.desc = desc.isEmpty() ? tr("No description available.") : desc;
   224 
   188 
   225     qvar.setValue(mapInfo);
   189     qvar.setValue(mapInfo);
   226     item->setData(qvar, Qt::UserRole + 1);
   190     item->setData(qvar, Qt::UserRole + 1);
   227 
   191 
   228     return item;
   192     return item;
   229 }
   193 }
   230 
       
   231 
       
   232 int MapModel::indexOf(const QString & map) const
       
   233 {
       
   234     return m_mapIndexes.value(map, -1);
       
   235 }
       
   236