bool ModList::installMod ( const QFileInfo& filename, int index ) { if(!filename.exists() || !filename.isReadable() || index < 0) { return false; } Mod m(filename); if(!m.valid()) return false; // if it's already there, replace the original mod (in place) int idx = mods.indexOf(m); if(idx != -1) { if(mods[idx].replace(m)) { auto left = this->index(index); auto right = this->index(index, columnCount(QModelIndex()) - 1); emit dataChanged(left, right); saveListFile(); emit changed(); return true; } return false; } auto type = m.type(); if(type == Mod::MOD_UNKNOWN) return false; if(type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE) { QString newpath = PathCombine(m_dir.path(), filename.fileName()); if(!QFile::copy(filename.filePath(), newpath)) return false; m.repath(newpath); beginInsertRows(QModelIndex(), index, index); mods.insert(index,m); endInsertRows(); saveListFile(); emit changed(); return true; } else if(type == Mod::MOD_FOLDER) { QString from = filename.filePath(); QString to = PathCombine(m_dir.path(), filename.fileName()); if(!copyPath(from, to)) return false; m.repath(to); beginInsertRows(QModelIndex(), index, index); mods.insert(index,m); endInsertRows(); saveListFile(); emit changed(); return true; } return false; }
bool ModList::update() { if (!isValid()) return false; QList<Mod> newMods; m_dir.refresh(); auto folderContents = m_dir.entryInfoList(); bool orderWasInvalid = false; // first, process the ordered items (if any) int currentOrderIndex = 0; QStringList listOrder = readListFile(); for(auto item: listOrder) { QFileInfo info (m_dir.filePath(item)); int idx = folderContents.indexOf(info); // 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)); } else { orderWasInvalid = true; } } for(auto entry: folderContents) { newMods.append(Mod(entry)); } if(mods.size() != newMods.size()) { orderWasInvalid = true; } else for(int i = 0; i < mods.size(); i++) { if(!mods[i].strongCompare(newMods[i])) { orderWasInvalid = true; break; } } beginResetModel(); mods.swap(newMods); endResetModel(); if(orderWasInvalid) { saveListFile(); emit changed(); } return true; }
bool ModList::moveModsDown(int first, int last) { if (last == mods.size() - 1) return false; beginMoveRows(QModelIndex(), first, last, QModelIndex(), last + 2); mods.move(last + 1, first); endMoveRows(); saveListFile(); emit changed(); return true; }
bool ModList::moveModsUp(int first, int last) { if (first == 0) return false; beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1); mods.move(first - 1, last); endMoveRows(); saveListFile(); emit changed(); return true; }
bool ModList::deleteMods(int first, int last) { for (int i = first; i <= last; i++) { Mod &m = mods[i]; m.destroy(); } beginRemoveRows(QModelIndex(), first, last); mods.erase(mods.begin() + first, mods.begin() + last + 1); endRemoveRows(); saveListFile(); emit changed(); return true; }
bool ModList::deleteMod(int index) { if (index >= mods.size() || index < 0) return false; Mod &m = mods[index]; if (m.destroy()) { beginRemoveRows(QModelIndex(), index, index); mods.removeAt(index); endRemoveRows(); saveListFile(); emit changed(); return true; } return false; }
bool ModList::moveModTo(int from, int to) { if (from < 0 || from >= mods.size()) return false; if (to >= rowCount()) to = rowCount() - 1; if (to == -1) to = rowCount() - 1; if (from == to) return false; int togap = to > from ? to + 1 : to; beginMoveRows(QModelIndex(), from, from, QModelIndex(), togap); mods.move(from, to); endMoveRows(); saveListFile(); emit changed(); return true; }
bool ModList::update() { if (!isValid()) return false; QList<Mod> orderedMods; QList<Mod> newMods; m_dir.refresh(); auto folderContents = m_dir.entryInfoList(); bool orderOrStateChanged = false; // first, process the ordered items (if any) OrderList listOrder = readListFile(); for (auto item : listOrder) { 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); bool isEnabled; // if both enabled and disabled versions are present, it's a special case... if (idxEnabled >= 0 && idxDisabled >= 0) { // we only process the one we actually have in the order file. // and exactly as we have it. // THIS IS A CORNER CASE isEnabled = item.enabled; } else { // only one is present. // we pick the one that we found. // we assume the mod was enabled/disabled by external means 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 orderedMods.append(Mod(info)); if (isEnabled != item.enabled) orderOrStateChanged = true; } else { orderOrStateChanged = true; } } // if there are any untracked files... if (folderContents.size()) { // the order surely changed! for (auto entry : folderContents) { newMods.append(Mod(entry)); } 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(); } return true; }