Disable/enable mods with checkboxes. Needs testing.
A lot of testing!
This commit is contained in:
		| @@ -30,7 +30,7 @@ void MCModInfoFrame::updateWithMod(Mod &m) | ||||
|  | ||||
| 	QString text = ""; | ||||
| 	QString name = ""; | ||||
| 	if(m.name().isEmpty()) name = m.id(); | ||||
| 	if(m.name().isEmpty()) name = m.mmc_id(); | ||||
| 	else name = m.name(); | ||||
|  | ||||
| 	if(m.homeurl().isEmpty()) text = name; | ||||
|   | ||||
| @@ -44,8 +44,9 @@ void ModListView::setModel ( QAbstractItemModel* model ) | ||||
| 	QTreeView::setModel ( model ); | ||||
| 	auto head = header(); | ||||
| 	head->setStretchLastSection(false); | ||||
| 	head->setSectionResizeMode(0, QHeaderView::Stretch); | ||||
| 	for(int i = 1; i < head->count(); i++) | ||||
| 	head->setSectionResizeMode(0, QHeaderView::ResizeToContents); | ||||
| 	head->setSectionResizeMode(1, QHeaderView::Stretch); | ||||
| 	for(int i = 2; i < head->count(); i++) | ||||
| 		head->setSectionResizeMode(i, QHeaderView::ResizeToContents); | ||||
| 	dropIndicatorPosition(); | ||||
| } | ||||
|   | ||||
| @@ -150,6 +150,7 @@ std::shared_ptr<ModList> LegacyInstance::jarModList() | ||||
|  | ||||
| void LegacyInstance::jarModsChanged() | ||||
| { | ||||
| 	QLOG_INFO() << "Jar mods of instance " << name() << " have changed. Jar will be rebuilt."; | ||||
| 	setShouldRebuild(true); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -35,20 +35,40 @@ Mod::Mod(const QFileInfo &file) | ||||
| void Mod::repath(const QFileInfo &file) | ||||
| { | ||||
| 	m_file = file; | ||||
| 	m_name = file.completeBaseName(); | ||||
| 	m_id = file.fileName(); | ||||
| 	QString name_base = file.fileName(); | ||||
|  | ||||
| 	m_type = Mod::MOD_UNKNOWN; | ||||
|  | ||||
| 	if (m_file.isDir()) | ||||
| 	{ | ||||
| 		m_type = MOD_FOLDER; | ||||
| 		m_name = name_base; | ||||
| 		m_mmc_id = name_base; | ||||
| 	} | ||||
| 	else if (m_file.isFile()) | ||||
| 	{ | ||||
| 		QString ext = m_file.suffix().toLower(); | ||||
| 		if (ext == "zip" || ext == "jar") | ||||
| 			m_type = MOD_ZIPFILE; | ||||
| 		if(name_base.endsWith(".disabled")) | ||||
| 		{ | ||||
| 			m_enabled = false; | ||||
| 			name_base.chop(9); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			m_enabled = true; | ||||
| 		} | ||||
| 		m_mmc_id = name_base; | ||||
| 		if (name_base.endsWith(".zip") || name_base.endsWith(".jar")) | ||||
| 		{ | ||||
| 			m_type = MOD_ZIPFILE; | ||||
| 			name_base.chop(4); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			m_type = MOD_SINGLEFILE; | ||||
| 		} | ||||
| 		m_name = name_base; | ||||
| 	} | ||||
|  | ||||
| 	if (m_type == MOD_ZIPFILE) | ||||
| 	{ | ||||
| 		QuaZip zip(m_file.filePath()); | ||||
| @@ -114,7 +134,7 @@ void Mod::ReadMCModInfo(QByteArray contents) | ||||
| 		if (!arr.at(0).isObject()) | ||||
| 			return; | ||||
| 		auto firstObj = arr.at(0).toObject(); | ||||
| 		m_id = firstObj.value("modid").toString(); | ||||
| 		m_mod_id = firstObj.value("modid").toString(); | ||||
| 		m_name = firstObj.value("name").toString(); | ||||
| 		m_version = firstObj.value("version").toString(); | ||||
| 		m_homeurl = firstObj.value("url").toString(); | ||||
| @@ -163,7 +183,7 @@ void Mod::ReadForgeInfo(QByteArray contents) | ||||
| { | ||||
| 	// Read the data | ||||
| 	m_name = "Minecraft Forge"; | ||||
| 	m_id = "Forge"; | ||||
| 	m_mod_id = "Forge"; | ||||
| 	m_homeurl = "http://www.minecraftforge.net/forum/"; | ||||
| 	INIFile ini; | ||||
| 	if (!ini.loadFile(contents)) | ||||
| @@ -183,9 +203,11 @@ bool Mod::replace(Mod &with) | ||||
| 		return false; | ||||
| 	bool success = false; | ||||
| 	auto t = with.type(); | ||||
| 	 | ||||
| 	if (t == MOD_ZIPFILE || t == MOD_SINGLEFILE) | ||||
| 	{ | ||||
| 		success = QFile::copy(with.m_file.filePath(), m_file.path()); | ||||
| 		QLOG_DEBUG() << "Copy: " << with.m_file.filePath() << " to " << m_file.filePath(); | ||||
| 		success = QFile::copy(with.m_file.filePath(), m_file.filePath()); | ||||
| 	} | ||||
| 	if (t == MOD_FOLDER) | ||||
| 	{ | ||||
| @@ -193,11 +215,17 @@ bool Mod::replace(Mod &with) | ||||
| 	} | ||||
| 	if (success) | ||||
| 	{ | ||||
| 		m_id = with.m_id; | ||||
| 		m_mcversion = with.m_mcversion; | ||||
| 		m_type = with.m_type; | ||||
| 		m_name = with.m_name; | ||||
| 		m_mmc_id = with.m_mmc_id; | ||||
| 		m_mod_id = with.m_mod_id; | ||||
| 		m_version = with.m_version; | ||||
| 		m_mcversion = with.m_mcversion; | ||||
| 		m_description = with.m_description; | ||||
| 		m_authors = with.m_authors; | ||||
| 		m_credits = with.m_credits; | ||||
| 		m_homeurl = with.m_homeurl; | ||||
| 		m_type = with.m_type; | ||||
| 		m_file.refresh(); | ||||
| 	} | ||||
| 	return success; | ||||
| } | ||||
| @@ -241,3 +269,42 @@ QString Mod::version() const | ||||
| 		return "VOID"; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool Mod::enable(bool value) | ||||
| { | ||||
| 	if(m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER) | ||||
| 		return false; | ||||
|  | ||||
| 	if(m_enabled == value) | ||||
| 		return false; | ||||
|  | ||||
| 	QString path = m_file.absoluteFilePath(); | ||||
| 	if(value) | ||||
| 	{ | ||||
| 		QFile foo(path); | ||||
| 		if(!path.endsWith(".disabled")) | ||||
| 			return false; | ||||
| 		path.chop(9); | ||||
| 		if(!foo.rename(path)) | ||||
| 			return false; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		QFile foo(path); | ||||
| 		path += ".disabled"; | ||||
| 		if(!foo.rename(path)) | ||||
| 			return false; | ||||
| 	} | ||||
| 	m_file = QFileInfo(path); | ||||
| 	m_enabled = value; | ||||
| 	return true; | ||||
| } | ||||
| bool Mod::operator==(const Mod &other) const | ||||
| { | ||||
| 	return mmc_id() == other.mmc_id(); | ||||
| } | ||||
| bool Mod::strongCompare(const Mod &other) const | ||||
| { | ||||
| 	return mmc_id() == other.mmc_id() && | ||||
| 		   version() == other.version() && type() == other.type(); | ||||
| } | ||||
|   | ||||
							
								
								
									
										30
									
								
								logic/Mod.h
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								logic/Mod.h
									
									
									
									
									
								
							| @@ -33,9 +33,13 @@ public: | ||||
| 	{ | ||||
| 		return m_file; | ||||
| 	} | ||||
| 	QString id() const | ||||
| 	QString mmc_id() const | ||||
| 	{ | ||||
| 		return m_id; | ||||
| 		return m_mmc_id; | ||||
| 	} | ||||
| 	QString mod_id() const | ||||
| 	{ | ||||
| 		return m_mod_id; | ||||
| 	} | ||||
| 	ModType type() const | ||||
| 	{ | ||||
| @@ -77,6 +81,13 @@ public: | ||||
| 		return m_credits; | ||||
| 	} | ||||
|  | ||||
| 	bool enabled() const | ||||
| 	{ | ||||
| 		return m_enabled; | ||||
| 	} | ||||
|  | ||||
| 	bool enable(bool value); | ||||
|  | ||||
| 	// delete all the files of this mod | ||||
| 	bool destroy(); | ||||
| 	// replace this mod with a copy of the other | ||||
| @@ -85,15 +96,8 @@ public: | ||||
| 	void repath(const QFileInfo &file); | ||||
|  | ||||
| 	// WEAK compare operator - used for replacing mods | ||||
| 	bool operator==(const Mod &other) const | ||||
| 	{ | ||||
| 		return filename() == other.filename(); | ||||
| 	} | ||||
| 	bool strongCompare(const Mod &other) const | ||||
| 	{ | ||||
| 		return filename() == other.filename() && id() == other.id() && | ||||
| 			   version() == other.version() && type() == other.type(); | ||||
| 	} | ||||
| 	bool operator==(const Mod &other) const; | ||||
| 	bool strongCompare(const Mod &other) const; | ||||
|  | ||||
| private: | ||||
| 	void ReadMCModInfo(QByteArray contents); | ||||
| @@ -108,7 +112,9 @@ protected: | ||||
| 	*/ | ||||
|  | ||||
| 	QFileInfo m_file; | ||||
| 	QString m_id; | ||||
| 	QString m_mmc_id; | ||||
| 	QString m_mod_id; | ||||
| 	bool m_enabled = true; | ||||
| 	QString m_name; | ||||
| 	QString m_version; | ||||
| 	QString m_mcversion; | ||||
|   | ||||
| @@ -19,6 +19,7 @@ | ||||
| #include <QMimeData> | ||||
| #include <QUrl> | ||||
| #include <QUuid> | ||||
| #include <QString> | ||||
| #include <QFileSystemWatcher> | ||||
| #include "logger/QsLog.h" | ||||
|  | ||||
| @@ -27,7 +28,7 @@ ModList::ModList(const QString &dir, const QString &list_file) | ||||
| { | ||||
| 	m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs | | ||||
| 					QDir::NoSymLinks); | ||||
| 	m_dir.setSorting(QDir::Name); | ||||
| 	m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); | ||||
| 	m_list_id = QUuid::createUuid().toString(); | ||||
| 	m_watcher = new QFileSystemWatcher(this); | ||||
| 	is_watching = false; | ||||
| @@ -66,52 +67,79 @@ bool ModList::update() | ||||
| 	if (!isValid()) | ||||
| 		return false; | ||||
|  | ||||
| 	QList<Mod> orderedMods; | ||||
| 	QList<Mod> newMods; | ||||
| 	m_dir.refresh(); | ||||
| 	auto folderContents = m_dir.entryInfoList(); | ||||
| 	bool orderWasInvalid = false; | ||||
| 	bool orderOrStateChanged = false; | ||||
|  | ||||
| 	// first, process the ordered items (if any) | ||||
| 	QStringList listOrder = readListFile(); | ||||
| 	OrderList listOrder = readListFile(); | ||||
| 	for (auto item : listOrder) | ||||
| 	{ | ||||
| 		QFileInfo info(m_dir.filePath(item)); | ||||
| 		int idx = folderContents.indexOf(info); | ||||
| 		QFileInfo infoEnabled(m_dir.filePath(item.id)); | ||||
| 		QFileInfo infoDisabled(m_dir.filePath(item.id + ".disabled")); | ||||
| 		int idxEnabled = folderContents.indexOf(infoEnabled); | ||||
| 		int idxDisabled = folderContents.indexOf(infoDisabled); | ||||
| 		// if both enabled and disabled versions are present, PANIC! | ||||
| 		if (idxEnabled >= 0 && idxDisabled >= 0) | ||||
| 		{ | ||||
| 			return false; | ||||
| 		} | ||||
| 		bool isEnabled = idxEnabled >= 0; | ||||
| 		int idx = isEnabled ? idxEnabled : idxDisabled; | ||||
| 		QFileInfo info = isEnabled ? infoEnabled : infoDisabled; | ||||
| 		// if the file from the index file exists | ||||
| 		if (idx != -1) | ||||
| 		{ | ||||
| 			// remove from the actual folder contents list | ||||
| 			folderContents.takeAt(idx); | ||||
| 			// append the new mod | ||||
| 			newMods.append(Mod(info)); | ||||
| 			orderedMods.append(Mod(info)); | ||||
| 			if (isEnabled != item.enabled) | ||||
| 				orderOrStateChanged = true; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			orderWasInvalid = true; | ||||
| 			orderOrStateChanged = true; | ||||
| 		} | ||||
| 	} | ||||
| 	for (auto entry : folderContents) | ||||
| 	// if there are any untracked files... | ||||
| 	if (folderContents.size()) | ||||
| 	{ | ||||
| 		newMods.append(Mod(entry)); | ||||
| 	} | ||||
| 	if (mods.size() != newMods.size()) | ||||
| 	{ | ||||
| 		orderWasInvalid = true; | ||||
| 	} | ||||
| 	else | ||||
| 		for (int i = 0; i < mods.size(); i++) | ||||
| 		// the order surely changed! | ||||
| 		for (auto entry : folderContents) | ||||
| 		{ | ||||
| 			if (!mods[i].strongCompare(newMods[i])) | ||||
| 			{ | ||||
| 				orderWasInvalid = true; | ||||
| 				break; | ||||
| 			} | ||||
| 			newMods.append(Mod(entry)); | ||||
| 		} | ||||
| 	beginResetModel(); | ||||
| 	mods.swap(newMods); | ||||
| 	endResetModel(); | ||||
| 	if (orderWasInvalid) | ||||
| 		std::sort(newMods.begin(), newMods.end(), [](const Mod & left, const Mod & right) | ||||
| 		{ return left.name().localeAwareCompare(right.name()) <= 0; }); | ||||
| 		orderedMods.append(newMods); | ||||
| 		orderOrStateChanged = true; | ||||
| 	} | ||||
| 	// otherwise, if we were already tracking some mods | ||||
| 	else if (mods.size()) | ||||
| 	{ | ||||
| 		// if the number doesn't match, order changed. | ||||
| 		if (mods.size() != orderedMods.size()) | ||||
| 			orderOrStateChanged = true; | ||||
| 		// if it does match, compare the mods themselves | ||||
| 		else | ||||
| 			for (int i = 0; i < mods.size(); i++) | ||||
| 			{ | ||||
| 				if (!mods[i].strongCompare(orderedMods[i])) | ||||
| 				{ | ||||
| 					orderOrStateChanged = true; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 	} | ||||
| 	beginResetModel(); | ||||
| 	mods.swap(orderedMods); | ||||
| 	endResetModel(); | ||||
| 	if (orderOrStateChanged && !m_list_file.isEmpty()) | ||||
| 	{ | ||||
| 		QLOG_INFO() << "Mod list " << m_list_file << " changed!"; | ||||
| 		saveListFile(); | ||||
| 		emit changed(); | ||||
| 	} | ||||
| @@ -123,17 +151,19 @@ void ModList::directoryChanged(QString path) | ||||
| 	update(); | ||||
| } | ||||
|  | ||||
| QStringList ModList::readListFile() | ||||
| ModList::OrderList ModList::readListFile() | ||||
| { | ||||
| 	QStringList stringList; | ||||
| 	OrderList itemList; | ||||
| 	if (m_list_file.isNull() || m_list_file.isEmpty()) | ||||
| 		return stringList; | ||||
| 		return itemList; | ||||
|  | ||||
| 	QFile textFile(m_list_file); | ||||
| 	if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text)) | ||||
| 		return QStringList(); | ||||
| 		return OrderList(); | ||||
|  | ||||
| 	QTextStream textStream(&textFile); | ||||
| 	QTextStream textStream; | ||||
| 	textStream.setAutoDetectUnicode(true); | ||||
| 	textStream.setDevice(&textFile); | ||||
| 	while (true) | ||||
| 	{ | ||||
| 		QString line = textStream.readLine(); | ||||
| @@ -141,11 +171,18 @@ QStringList ModList::readListFile() | ||||
| 			break; | ||||
| 		else | ||||
| 		{ | ||||
| 			stringList.append(line); | ||||
| 			OrderItem it; | ||||
| 			it.enabled = !line.endsWith(".disabled"); | ||||
| 			if (!it.enabled) | ||||
| 			{ | ||||
| 				line.chop(9); | ||||
| 			} | ||||
| 			it.id = line; | ||||
| 			itemList.append(it); | ||||
| 		} | ||||
| 	} | ||||
| 	textFile.close(); | ||||
| 	return stringList; | ||||
| 	return itemList; | ||||
| } | ||||
|  | ||||
| bool ModList::saveListFile() | ||||
| @@ -155,12 +192,16 @@ bool ModList::saveListFile() | ||||
| 	QFile textFile(m_list_file); | ||||
| 	if (!textFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) | ||||
| 		return false; | ||||
| 	QTextStream textStream(&textFile); | ||||
| 	QTextStream textStream; | ||||
| 	textStream.setGenerateByteOrderMark(true); | ||||
| 	textStream.setCodec("UTF-8"); | ||||
| 	textStream.setDevice(&textFile); | ||||
| 	for (auto mod : mods) | ||||
| 	{ | ||||
| 		auto pathname = mod.filename(); | ||||
| 		QString filename = pathname.fileName(); | ||||
| 		textStream << filename << endl; | ||||
| 		textStream << mod.mmc_id(); | ||||
| 		if (!mod.enabled()) | ||||
| 			textStream << ".disabled"; | ||||
| 		textStream << endl; | ||||
| 	} | ||||
| 	textFile.close(); | ||||
| 	return false; | ||||
| @@ -327,7 +368,7 @@ bool ModList::moveModsDown(int first, int last) | ||||
|  | ||||
| int ModList::columnCount(const QModelIndex &parent) const | ||||
| { | ||||
| 	return 2; | ||||
| 	return 3; | ||||
| } | ||||
|  | ||||
| QVariant ModList::data(const QModelIndex &index, int role) const | ||||
| @@ -341,43 +382,96 @@ QVariant ModList::data(const QModelIndex &index, int role) const | ||||
| 	if (row < 0 || row >= mods.size()) | ||||
| 		return QVariant(); | ||||
|  | ||||
| 	if (role != Qt::DisplayRole) | ||||
| 		return QVariant(); | ||||
|  | ||||
| 	switch (column) | ||||
| 	switch (role) | ||||
| 	{ | ||||
| 	case 0: | ||||
| 		return mods[row].name(); | ||||
| 	case 1: | ||||
| 		return mods[row].version(); | ||||
| 	case 2: | ||||
| 		return mods[row].mcversion(); | ||||
| 	case Qt::DisplayRole: | ||||
| 		switch (index.column()) | ||||
| 		{ | ||||
| 		case NameColumn: | ||||
| 			return mods[row].name(); | ||||
| 		case VersionColumn: | ||||
| 			return mods[row].version(); | ||||
|  | ||||
| 		default: | ||||
| 			return QVariant(); | ||||
| 		} | ||||
|  | ||||
| 	case Qt::ToolTipRole: | ||||
| 		return mods[row].mmc_id(); | ||||
|  | ||||
| 	case Qt::CheckStateRole: | ||||
| 		switch (index.column()) | ||||
| 		{ | ||||
| 		case ActiveColumn: | ||||
| 			return mods[row].enabled(); | ||||
| 		default: | ||||
| 			return QVariant(); | ||||
| 		} | ||||
| 	default: | ||||
| 		return QVariant(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| bool ModList::setData(const QModelIndex &index, const QVariant &value, int role) | ||||
| { | ||||
| 	if (index.row() < 0 || index.row() >= rowCount(index) || !index.isValid()) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	if (role == Qt::CheckStateRole) | ||||
| 	{ | ||||
| 		auto &mod = mods[index.row()]; | ||||
| 		if (mod.enable(!mod.enabled())) | ||||
| 		{ | ||||
| 			emit dataChanged(index, index); | ||||
| 			return true; | ||||
| 		} | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| QVariant ModList::headerData(int section, Qt::Orientation orientation, int role) const | ||||
| { | ||||
| 	if (role != Qt::DisplayRole || orientation != Qt::Horizontal) | ||||
| 		return QVariant(); | ||||
| 	switch (section) | ||||
| 	switch (role) | ||||
| 	{ | ||||
| 	case 0: | ||||
| 		return QString("Name"); | ||||
| 	case 1: | ||||
| 		return QString("Version"); | ||||
| 	case 2: | ||||
| 		return QString("Minecraft"); | ||||
| 	case Qt::DisplayRole: | ||||
| 		switch (section) | ||||
| 		{ | ||||
| 		case ActiveColumn: | ||||
| 			return QString(); | ||||
| 		case NameColumn: | ||||
| 			return QString("Name"); | ||||
| 		case VersionColumn: | ||||
| 			return QString("Version"); | ||||
| 		default: | ||||
| 			return QVariant(); | ||||
| 		} | ||||
|  | ||||
| 	case Qt::ToolTipRole: | ||||
| 		switch (section) | ||||
| 		{ | ||||
| 		case ActiveColumn: | ||||
| 			return "Is the mod enabled?"; | ||||
| 		case NameColumn: | ||||
| 			return "The name of the mod."; | ||||
| 		case VersionColumn: | ||||
| 			return "The version of the mod."; | ||||
| 		default: | ||||
| 			return QVariant(); | ||||
| 		} | ||||
| 	default: | ||||
| 		return QVariant(); | ||||
| 	} | ||||
| 	return QString(); | ||||
| 	return QVariant(); | ||||
| } | ||||
|  | ||||
| Qt::ItemFlags ModList::flags(const QModelIndex &index) const | ||||
| { | ||||
| 	Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index); | ||||
| 	if (index.isValid()) | ||||
| 		return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags; | ||||
| 		return Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | | ||||
| 			   defaultFlags; | ||||
| 	else | ||||
| 		return Qt::ItemIsDropEnabled | defaultFlags; | ||||
| } | ||||
| @@ -456,6 +550,14 @@ bool ModList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row | ||||
| 			QString filename = url.toLocalFile(); | ||||
| 			installMod(filename, row); | ||||
| 			QLOG_INFO() << "installing: " << filename; | ||||
| 			// if there is no ordering, re-sort the list | ||||
| 			if (m_list_file.isEmpty()) | ||||
| 			{ | ||||
| 				beginResetModel(); | ||||
| 				std::sort(mods.begin(), mods.end(), [](const Mod & left, const Mod & right) | ||||
| 				{ return left.name().localeAwareCompare(right.name()) <= 0; }); | ||||
| 				endResetModel(); | ||||
| 			} | ||||
| 		} | ||||
| 		if (was_watching) | ||||
| 			startWatching(); | ||||
|   | ||||
| @@ -34,9 +34,18 @@ class ModList : public QAbstractListModel | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	enum Columns | ||||
| 	{ | ||||
| 		ActiveColumn = 0, | ||||
| 		NameColumn, | ||||
| 		VersionColumn | ||||
| 	}; | ||||
| 	ModList(const QString &dir, const QString &list_file = QString()); | ||||
|  | ||||
| 	virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; | ||||
| 	virtual bool setData(const QModelIndex &index, const QVariant &value, | ||||
| 						 int role = Qt::EditRole); | ||||
|  | ||||
| 	virtual int rowCount(const QModelIndex &parent = QModelIndex()) const | ||||
| 	{ | ||||
| 		return size(); | ||||
| @@ -59,7 +68,6 @@ public: | ||||
| 	{ | ||||
| 		return mods[index]; | ||||
| 	} | ||||
| 	; | ||||
|  | ||||
| 	/// Reloads the mod list and returns true if the list changed. | ||||
| 	virtual bool update(); | ||||
| @@ -119,7 +127,13 @@ public: | ||||
| 	} | ||||
|  | ||||
| private: | ||||
| 	QStringList readListFile(); | ||||
| 	struct OrderItem | ||||
| 	{ | ||||
| 		QString id; | ||||
| 		bool enabled = false; | ||||
| 	}; | ||||
| 	typedef QList<OrderItem> OrderList; | ||||
| 	OrderList readListFile(); | ||||
| 	bool saveListFile(); | ||||
| private | ||||
| slots: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user