From 6e5017e48b633e20bbba61ac2e7cd58e693aec4e Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 19 Feb 2013 12:15:22 -0600 Subject: Implemented loadList() stuff. --- data/inst/instance.h | 27 --- data/inst/instancelist.cpp | 59 +++++- data/inst/instancelist.h | 26 ++- data/inst/instanceloader.cpp | 24 +++ data/inst/instanceloader.h | 54 +++-- data/instancemodel.cpp | 457 ------------------------------------------- data/instancemodel.h | 137 ------------- 7 files changed, 138 insertions(+), 646 deletions(-) delete mode 100644 data/instancemodel.cpp delete mode 100644 data/instancemodel.h (limited to 'data') diff --git a/data/inst/instance.h b/data/inst/instance.h index 1b282b03..56e9d0b8 100644 --- a/data/inst/instance.h +++ b/data/inst/instance.h @@ -79,23 +79,6 @@ public: virtual InstanceList *instList(); - /*! - * \brief Gets this instance's group. - * This function is used by the instance grouping system and should - * not be touched by classes deriving from Instance. - * \return The instance's group name. - * \sa setGroup() - */ - QString group() const { return m_group; } - - /*! - * \brief Sets the instance's group. - * \param group The instance's new group name. - * \sa group() - */ - void setGroup(const QString &group) { m_group = group; emit groupChanged(this, group); } - - //////// FIELDS AND SETTINGS //////// // Fields are options stored in the instance's config file that are specific // to instances (not a part of SettingsBase). Settings are things overridden @@ -278,14 +261,6 @@ public: */ virtual void updateCurrentVersion(bool keepCurrent = false) = 0; -signals: - /*! - * \brief Signal emitted when the instance's group changes. - * \param inst Pointer to the instance whose group changed. - * \param newGroup The instance's new group. - */ - void groupChanged(Instance *inst, QString newGroup); - protected: /*! * \brief Gets the value of the given field in the instance's config file. @@ -314,8 +289,6 @@ protected: INIFile config; private: - QString m_group; - QString m_rootDir; }; diff --git a/data/inst/instancelist.cpp b/data/inst/instancelist.cpp index 62367ed6..cbb89f05 100644 --- a/data/inst/instancelist.cpp +++ b/data/inst/instancelist.cpp @@ -17,7 +17,62 @@ #include "data/siglist_impl.h" -InstanceList::InstanceList(QObject *parent) : - QObject(parent) +#include +#include +#include + +#include "instance.h" +#include "instanceloader.h" + +#include "util/pathutils.h" + + +InstanceList::InstanceList(const QString &instDir, QObject *parent) : + QObject(parent), m_instDir(instDir) +{ + +} + +InstanceList::InstListError InstanceList::loadList() { + QDir dir(m_instDir); + QDirIterator iter(dir); + + while (iter.hasNext()) + { + QString subDir = iter.next(); + if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) + { + QSharedPointer inst; + InstanceLoader::InstTypeError error = InstanceLoader::loader. + loadInstance(inst.data(), subDir); + + if (inst.data() && error == InstanceLoader::NoError) + { + qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8()); + inst->setParent(this); + append(QSharedPointer(inst)); + } + else if (error != InstanceLoader::NotAnInstance) + { + QString errorMsg = QString("Failed to load instance %1: "). + arg(QFileInfo(subDir).baseName()).toUtf8(); + + switch (error) + { + case InstanceLoader::TypeNotRegistered: + errorMsg += "Instance type not found."; + break; + } + qDebug(errorMsg.toUtf8()); + } + else if (!inst.data()) + { + qDebug(QString("Error loading instance %1. Instance loader returned null."). + arg(QFileInfo(subDir).baseName()).toUtf8()); + } + } + } + + return NoError; } diff --git a/data/inst/instancelist.h b/data/inst/instancelist.h index 72dec5f0..c43c4cc0 100644 --- a/data/inst/instancelist.h +++ b/data/inst/instancelist.h @@ -24,16 +24,34 @@ class Instance; -class InstanceList : public QObject, SigList> +class InstanceList : public QObject, public SigList> { Q_OBJECT public: - explicit InstanceList(QObject *parent = 0); + explicit InstanceList(const QString &instDir, QObject *parent = 0); -signals: + /*! + * \brief Error codes returned by functions in the InstanceList class. + * NoError Indicates that no error occurred. + * UnknownError indicates that an unspecified error occurred. + */ + enum InstListError + { + NoError = 0, + UnknownError + }; -public slots: + QString instDir() const { return m_instDir; } + /*! + * \brief Loads the instance list. + */ + InstListError loadList(); + + DEFINE_SIGLIST_SIGNALS(QSharedPointer); + SETUP_SIGLIST_SIGNALS(QSharedPointer); +protected: + QString m_instDir; }; #endif // INSTANCELIST_H diff --git a/data/inst/instanceloader.cpp b/data/inst/instanceloader.cpp index 1a53bfa7..e80a0e9e 100644 --- a/data/inst/instanceloader.cpp +++ b/data/inst/instanceloader.cpp @@ -15,8 +15,16 @@ #include "instanceloader.h" +#include + #include "instancetype.h" +#include "data/inifile.h" + +#include "util/pathutils.h" + +InstanceLoader InstanceLoader::loader; + InstanceLoader::InstanceLoader() : QObject(NULL) { @@ -61,6 +69,22 @@ InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, return type->loadInstance(inst, instDir); } +InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, + const QString &instDir) +{ + QFileInfo instConfig(PathCombine(instDir, "instance.cfg")); + + if (!instConfig.exists()) + return NotAnInstance; + + INIFile ini; + ini.loadFile(instConfig.path()); + QString typeName = ini.get("type", "StdInstance").toString(); + const InstanceType *type = findType(typeName); + + return loadInstance(inst, type, instDir); +} + const InstanceType *InstanceLoader::findType(const QString &id) { if (!m_typeMap.contains(id)) diff --git a/data/inst/instanceloader.h b/data/inst/instanceloader.h index b7092edc..60c4e998 100644 --- a/data/inst/instanceloader.h +++ b/data/inst/instanceloader.h @@ -34,18 +34,18 @@ class InstanceLoader : public QObject { Q_OBJECT public: - static InstanceLoader instLoader; + static InstanceLoader loader; /*! * \brief Error codes returned by functions in the InstanceLoader and InstanceType classes. - * NoError indicates that no error occurred. - * OtherError indicates that an unspecified error occurred. - * TypeIDExists is returned by registerInstanceType() if the ID of the type being registered already exists. - * - * TypeNotRegistered is returned by createInstance() and loadInstance() when the given type is not registered. - * InstExists is returned by createInstance() if the given instance directory is already an instance. - * NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. - * WrongInstType is returned by loadInstance() if the given instance directory's type doesn't match the given type. + * + * - NoError indicates that no error occurred. + * - OtherError indicates that an unspecified error occurred. + * - TypeIDExists is returned by registerInstanceType() if the ID of the type being registered already exists. + * - TypeNotRegistered is returned by createInstance() and loadInstance() when the given type is not registered. + * - InstExists is returned by createInstance() if the given instance directory is already an instance. + * - NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance. + * - WrongInstType is returned by loadInstance() if the given instance directory's type doesn't match the given type. */ enum InstTypeError { @@ -62,41 +62,56 @@ public: /*! * \brief Registers the given InstanceType with the instance loader. - * This causes the instance loader to take ownership of the given - * instance type (meaning the instance type's parent will be set to - * the instance loader). + * This causes the instance loader to take ownership of the given + * instance type (meaning the instance type's parent will be set to + * the instance loader). + * * \param type The InstanceType to register. * \return An InstTypeError error code. - * TypeIDExists if the given type's is already registered to another instance type. + * - TypeIDExists if the given type's is already registered to another instance type. */ InstTypeError registerInstanceType(InstanceType *type); /*! * \brief Creates an instance with the given type and stores it in inst. + * * \param inst Pointer to store the created instance in. * \param type The type of instance to create. * \param instDir The instance's directory. * \return An InstTypeError error code. - * TypeNotRegistered if the given type is not registered with the InstanceLoader. - * InstExists if the given instance directory is already an instance. + * - TypeNotRegistered if the given type is not registered with the InstanceLoader. + * - InstExists if the given instance directory is already an instance. */ InstTypeError createInstance(Instance *inst, const InstanceType *type, const QString &instDir); /*! * \brief Loads an instance from the given directory. + * * \param inst Pointer to store the loaded instance in. * \param type The type of instance to load. * \param instDir The instance's directory. * \return An InstTypeError error code. - * TypeNotRegistered if the given type is not registered with the InstanceLoader. - * NotAnInstance if the given instance directory isn't a valid instance. - * WrongInstType if the given instance directory's type isn't the same as the given type. + * - TypeNotRegistered if the given type is not registered with the InstanceLoader. + * - NotAnInstance if the given instance directory isn't a valid instance. + * - WrongInstType if the given instance directory's type isn't the same as the given type. */ InstTypeError loadInstance(Instance *inst, const InstanceType *type, const QString &instDir); + /*! + * \brief Loads an instance from the given directory. + * Checks the instance's INI file to figure out what the instance's type is first. + * \param inst Pointer to store the loaded instance in. + * \param instDir The instance's directory. + * \return An InstTypeError error code. + * - TypeNotRegistered if the instance's type is not registered with the InstanceLoader. + * - NotAnInstance if the given instance directory isn't a valid instance. + */ + InstTypeError loadInstance(Instance *inst, const QString &instDir); + /*! * \brief Finds an instance type with the given ID. - * If one cannot be found, returns NULL. + * If one cannot be found, returns NULL. + * * \param id The ID of the type to find. * \return The type with the given ID. NULL if none were found. */ @@ -104,6 +119,7 @@ public: /*! * \brief Gets a list of the registered instance types. + * * \return A list of instance types. */ InstTypeList typeList(); diff --git a/data/instancemodel.cpp b/data/instancemodel.cpp deleted file mode 100644 index fbdb8212..00000000 --- a/data/instancemodel.cpp +++ /dev/null @@ -1,457 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "instancemodel.h" - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "data/stdinstance.h" -#include "util/pathutils.h" - -#define GROUP_FILE_FORMAT_VERSION 1 - -InstanceModel::InstanceModel( QObject* parent ) : - QAbstractItemModel() -{ -} - -InstanceModel::~InstanceModel() -{ - saveGroupInfo(); - for(int i = 0; i < groups.size(); i++) - { - delete groups[i]; - } -} - -void InstanceModel::addInstance( InstanceBase* inst, const QString& groupName ) -{ - auto group = getGroupByName(groupName); - group->addInstance(inst); -} - -void InstanceGroup::addInstance ( InstanceBase* inst ) -{ - instances.append(inst); - inst->setGroup(this); - // TODO: notify model. -} - - -void InstanceModel::initialLoad(QString dir) -{ - groupFileName = dir + "/instgroups.json"; - implicitGroup = new InstanceGroup("Ungrouped", this); - groups.append(implicitGroup); - - // temporary map from instance ID to group name - QMap groupMap; - - if (QFileInfo(groupFileName).exists()) - { - QFile groupFile(groupFileName); - - if (!groupFile.open(QIODevice::ReadOnly)) - { - // An error occurred. Ignore it. - qDebug("Failed to read instance group file."); - goto groupParseFail; - } - - QTextStream in(&groupFile); - QString jsonStr = in.readAll(); - groupFile.close(); - - QJsonParseError error; - QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error); - - if (error.error != QJsonParseError::NoError) - { - qWarning(QString("Failed to parse instance group file: %1 at offset %2"). - arg(error.errorString(), QString::number(error.offset)).toUtf8()); - goto groupParseFail; - } - - if (!jsonDoc.isObject()) - { - qWarning("Invalid group file. Root entry should be an object."); - goto groupParseFail; - } - - QJsonObject rootObj = jsonDoc.object(); - - // Make sure the format version matches. - if (rootObj.value("formatVersion").toVariant().toInt() == GROUP_FILE_FORMAT_VERSION) - { - // Get the group list. - if (!rootObj.value("groups").isObject()) - { - qWarning("Invalid group list JSON: 'groups' should be an object."); - goto groupParseFail; - } - - // Iterate through the list. - QJsonObject groupList = rootObj.value("groups").toObject(); - - for (QJsonObject::iterator iter = groupList.begin(); - iter != groupList.end(); iter++) - { - QString groupName = iter.key(); - - // If not an object, complain and skip to the next one. - if (!iter.value().isObject()) - { - qWarning(QString("Group '%1' in the group list should " - "be an object.").arg(groupName).toUtf8()); - continue; - } - - QJsonObject groupObj = iter.value().toObject(); - - // Create the group object. - InstanceGroup *group = new InstanceGroup(groupName, this); - groups.push_back(group); - - // If 'hidden' isn't a bool value, just assume it's false. - if (groupObj.value("hidden").isBool() && groupObj.value("hidden").toBool()) - { - group->setHidden(groupObj.value("hidden").toBool()); - } - - if (!groupObj.value("instances").isArray()) - { - qWarning(QString("Group '%1' in the group list is invalid. " - "It should contain an array " - "called 'instances'.").arg(groupName).toUtf8()); - continue; - } - - // Iterate through the list of instances in the group. - QJsonArray instancesArray = groupObj.value("instances").toArray(); - - for (QJsonArray::iterator iter2 = instancesArray.begin(); - iter2 != instancesArray.end(); iter2++) - { - groupMap[(*iter2).toString()] = groupName; - } - } - } - } - -groupParseFail: - - qDebug("Loading instances"); - QDir instDir(dir); - QDirIterator iter(instDir); - - while (iter.hasNext()) - { - QString subDir = iter.next(); - if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) - { - // TODO Differentiate between different instance types. - InstanceBase* inst = new StdInstance(subDir); - QString instID = inst->getInstID(); - auto iter = groupMap.find(instID); - if(iter != groupMap.end()) - { - addInstance(inst,iter.value()); - } - else - { - addInstance(inst); - } - } - } -} - -int InstanceModel::columnCount ( const QModelIndex& parent ) const -{ - // for now... - return 1; -} - -QVariant InstanceModel::data ( const QModelIndex& index, int role ) const -{ - if (!index.isValid()) - return QVariant(); - - if (role != Qt::DisplayRole) - return QVariant(); - - InstanceModelItem *item = static_cast(index.internalPointer()); - - return item->data(index.column()); -} - -QModelIndex InstanceModel::index ( int row, int column, const QModelIndex& parent ) const -{ - if (!hasIndex(row, column, parent)) - return QModelIndex(); - - InstanceModelItem *parentItem; - - if (!parent.isValid()) - parentItem = (InstanceModelItem *) this; - else - parentItem = static_cast(parent.internalPointer()); - - InstanceModelItem *childItem = parentItem->getChild(row); - if (childItem) - return createIndex(row, column, childItem); - else - return QModelIndex(); - -} - -QModelIndex InstanceModel::parent ( const QModelIndex& index ) const -{ - if (!index.isValid()) - return QModelIndex(); - - InstanceModelItem *childItem = static_cast(index.internalPointer()); - InstanceModelItem *parentItem = childItem->getParent(); - - if (parentItem == this) - return QModelIndex(); - - return createIndex(parentItem->getRow(), 0, parentItem); -} - -int InstanceModel::rowCount ( const QModelIndex& parent ) const -{ - InstanceModelItem *parentItem; - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) - parentItem = (InstanceModelItem*) this; - else - parentItem = static_cast(parent.internalPointer()); - - return parentItem->numChildren(); -} - -bool InstanceModel::saveGroupInfo() const -{ - /* - using namespace boost::property_tree; - ptree pt; - - pt.put("formatVersion", GROUP_FILE_FORMAT_VERSION); - - try - { - typedef QMap > GroupListMap; - - GroupListMap groupLists; - for (auto iter = instances.begin(); iter != instances.end(); iter++) - { - InstanceGroup *group = getInstanceGroup(*iter); - - if (group != nullptr) - groupLists[group].push_back(*iter); - } - - ptree groupsPtree; - for (auto iter = groupLists.begin(); iter != groupLists.end(); iter++) - { - auto group = iter.key(); - auto & gList = iter.value(); - - ptree groupTree; - - groupTree.put("hidden", group->isHidden()); - - ptree instList; - for (auto iter2 = gList.begin(); iter2 != gList.end(); iter2++) - { - std::string instID((*iter2)->getInstID().toUtf8()); - instList.push_back(std::make_pair("", ptree(instID))); - } - groupTree.put_child("instances", instList); - - groupsPtree.push_back(std::make_pair(std::string(group->getName().toUtf8()), groupTree)); - } - pt.put_child("groups", groupsPtree); - - write_json(groupFile.toStdString(), pt); - } - catch (json_parser_error e) - { -// wxLogError(_("Failed to read group list.\nJSON parser error at line %i: %s"), -// e.line(), wxStr(e.message()).c_str()); - return false; - } - catch (ptree_error e) - { -// wxLogError(_("Failed to save group list. Unknown ptree error.")); - return false; - } - - return true; - */ - return false; -} - -void InstanceModel::setInstanceGroup ( InstanceBase* inst, const QString& groupName ) -{ - /* - InstanceGroup *prevGroup = getInstanceGroup(inst); - - if (prevGroup != nullptr) - { - groupsMap.remove(inst); - } - - if (!groupName.isEmpty()) - { - InstanceGroup *newGroup = nullptr; - - for (auto iter = root->groups.begin(); iter != root->groups.end(); iter++) - { - if ((*iter)->getName() == groupName) - { - newGroup = *iter; - } - } - - if (newGroup == nullptr) - { - newGroup = new InstanceGroup(groupName, this); - root->groups.push_back(newGroup); - } - - groupsMap[inst] = newGroup; - } - - // TODO: propagate change, reflect in model, etc. - //InstanceGroupChanged(inst); - */ -} - -InstanceGroup* InstanceModel::getGroupByName ( const QString& name ) const -{ - for (auto iter = groups.begin(); iter != groups.end(); iter++) - { - if ((*iter)->getName() == name) - return *iter; - } - return nullptr; -} -/* -void InstanceModel::setGroupFile ( QString filename ) -{ - groupFile = filename; -}*/ - -int InstanceModel::numChildren() const -{ - return groups.count(); -} - -InstanceModelItem* InstanceModel::getChild ( int index ) const -{ - return groups[index]; -} - -QVariant InstanceModel::data ( int role ) const -{ - switch(role) - { - case Qt::DisplayRole: - return "name"; - } - return QVariant(); -} - - -InstanceGroup::InstanceGroup(const QString& name, InstanceModel *parent) -{ - this->name = name; - this->model = parent; - this->hidden = false; -} - -InstanceGroup::~InstanceGroup() -{ - for(int i = 0; i < instances.size(); i++) - { - delete instances[i]; - } -} - - -QString InstanceGroup::getName() const -{ - return name; -} - -void InstanceGroup::setName(const QString& name) -{ - this->name = name; - //TODO: propagate change -} - -InstanceModelItem* InstanceGroup::getParent() const -{ - return model; -} - -bool InstanceGroup::isHidden() const -{ - return hidden; -} - -void InstanceGroup::setHidden(bool hidden) -{ - this->hidden = hidden; - //TODO: propagate change -} - -int InstanceGroup::getRow() const -{ - return model->getIndexOf( this); -} - -InstanceModelItem* InstanceGroup::getChild ( int index ) const -{ - return instances[index]; -} - -int InstanceGroup::numChildren() const -{ - return instances.size(); -} - -QVariant InstanceGroup::data ( int role ) const -{ - switch(role) - { - case Qt::DisplayRole: - return name; - default: - return QVariant(); - } -} diff --git a/data/instancemodel.h b/data/instancemodel.h deleted file mode 100644 index 9678fef0..00000000 --- a/data/instancemodel.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright 2013 MultiMC Contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef INSTANCEMODEL_H -#define INSTANCEMODEL_H - -#include -#include -#include -#include - -enum IMI_type -{ - IMI_Root, - IMI_Group, - IMI_Instance -}; - -class InstanceModel; -class InstanceGroup; -class InstanceBase; - -class InstanceModelItem -{ - public: - virtual IMI_type getModelItemType() const = 0; - virtual InstanceModelItem * getParent() const = 0; - virtual int numChildren() const = 0; - virtual InstanceModelItem * getChild(int index) const = 0; - virtual InstanceModel * getModel() const = 0; - virtual QVariant data(int role) const = 0; - virtual int getRow() const = 0; -}; - -class InstanceGroup : public InstanceModelItem -{ -public: - InstanceGroup(const QString& name, InstanceModel * model); - ~InstanceGroup(); - - QString getName() const; - void setName(const QString& name); - - bool isHidden() const; - void setHidden(bool hidden); - - virtual IMI_type getModelItemType() const - { - return IMI_Group; - } - virtual InstanceModelItem* getParent() const; - virtual InstanceModelItem* getChild ( int index ) const; - virtual int numChildren() const; - virtual InstanceModel * getModel() const - { - return model; - }; - virtual QVariant data ( int column ) const; - int getIndexOf(InstanceBase * inst) - { - return instances.indexOf(inst); - }; - virtual int getRow() const; - void addInstance ( InstanceBase* inst ); -protected: - QString name; - InstanceModel * model; - QVector instances; - bool hidden; - int row; -}; - -class InstanceModel : public QAbstractItemModel, public InstanceModelItem -{ -public: - explicit InstanceModel(QObject *parent = 0); - ~InstanceModel(); - - virtual int columnCount ( const QModelIndex& parent = QModelIndex() ) const; - virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const; - virtual QModelIndex index ( int row, int column, const QModelIndex& parent = QModelIndex() ) const; - virtual QModelIndex parent ( const QModelIndex& child ) const; - virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const; - - void addInstance(InstanceBase *inst, const QString& groupName = "Ungrouped"); - void setInstanceGroup(InstanceBase *inst, const QString & groupName); - InstanceGroup* getGroupByName(const QString & name) const; - - void initialLoad(QString dir); - bool saveGroupInfo() const; - - virtual IMI_type getModelItemType() const - { - return IMI_Root; - } - virtual InstanceModelItem * getParent() const - { - return nullptr; - }; - virtual int numChildren() const; - virtual InstanceModelItem* getChild ( int index ) const; - virtual InstanceModel* getModel() const - { - return nullptr; - }; - virtual QVariant data ( int column ) const; - int getIndexOf(const InstanceGroup * grp) const - { - return groups.indexOf((InstanceGroup *) grp); - }; - virtual int getRow() const - { - return 0; - }; -signals: - -public slots: - -private: - QString groupFileName; - QVector groups; - InstanceGroup * implicitGroup; -}; - -#endif // INSTANCEMODEL_H -- cgit v1.2.3