Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions src/directoryrefresher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,10 +179,13 @@ void DirectoryRefresher::setMods(

m_Mods.clear();
for (auto mod = mods.begin(); mod != mods.end(); ++mod) {
QString name = std::get<0>(*mod);
ModInfo::Ptr info = ModInfo::getByIndex(ModInfo::getIndex(name));
m_Mods.push_back(EntryInfo(name, std::get<1>(*mod), info->stealFiles(),
info->archives(), std::get<2>(*mod)));
QString name = std::get<0>(*mod);
ModInfo::Ptr info = ModInfo::getByIndex(ModInfo::getIndex(name));
QString path = std::get<1>(*mod);
QString modDataDir = m_Core.managedGame()->modDataDirectory();
path = modDataDir.isEmpty() ? path : path + "/" + modDataDir;
m_Mods.push_back(
EntryInfo(name, path, info->stealFiles(), info->archives(), std::get<2>(*mod)));
}

m_EnabledArchives = managedArchives;
Expand Down
5 changes: 4 additions & 1 deletion src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2916,8 +2916,11 @@ void MainWindow::originModified(int originID)
origin.enable(false);

DirectoryStats dummy;
QString path = QString::fromStdWString(origin.getPath());
QString modDataDir = m_OrganizerCore.managedGame()->modDataDirectory();
path = modDataDir.isEmpty() ? path : path + "/" + modDataDir;
m_OrganizerCore.directoryStructure()->addFromOrigin(
origin.getName(), origin.getPath(), origin.getPriority(), dummy);
origin.getName(), path.toStdWString(), origin.getPriority(), dummy);

DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure());
}
Expand Down
1 change: 1 addition & 0 deletions src/moapplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ int MOApplication::setup(MOMultiProcess& multiProcess, bool forceSelect)
// setting up organizer core
m_core->setManagedGame(m_instance->gamePlugin());
m_core->createDefaultProfile();
m_core->createOverwriteDirectories();

log::info("using game plugin '{}' ('{}', variant {}, steam id '{}') at {}",
m_instance->gamePlugin()->gameName(),
Expand Down
29 changes: 17 additions & 12 deletions src/modinfodialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,25 +571,30 @@ void ModInfoDialog::updateTabs(bool becauseOriginChanged)

void ModInfoDialog::feedFiles(std::vector<TabInfo*>& interestedTabs)
{
const auto rootPath = m_mod->absolutePath();
const auto rootPath =
m_mod->absolutePath() + (m_core.managedGame()->modDataDirectory().isEmpty()
? ""
: "/" + m_core.managedGame()->modDataDirectory());
if (rootPath.isEmpty()) {
return;
}

const fs::path fsPath(rootPath.toStdWString());
if (fs::exists(rootPath.toStdWString())) {
const fs::path fsPath(rootPath.toStdWString());

for (const auto& entry : fs::recursive_directory_iterator(fsPath)) {
if (!entry.is_regular_file()) {
// skip directories
continue;
}
for (const auto& entry : fs::recursive_directory_iterator(fsPath)) {
if (!entry.is_regular_file()) {
// skip directories
continue;
}

const auto filePath = QString::fromStdWString(entry.path().native());
const auto filePath = QString::fromStdWString(entry.path().native());

// for each tab
for (auto* tabInfo : interestedTabs) {
if (tabInfo->tab->feedFile(rootPath, filePath)) {
break;
// for each tab
for (auto* tabInfo : interestedTabs) {
if (tabInfo->tab->feedFile(rootPath, filePath)) {
break;
}
}
}
}
Expand Down
23 changes: 19 additions & 4 deletions src/modinfooverwrite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "settings.h"
#include "shared/appconfig.h"

#include "organizercore.h"
#include <QApplication>
#include <QDirIterator>

Expand All @@ -14,10 +15,24 @@ bool ModInfoOverwrite::isEmpty() const
QDirIterator iter(absolutePath(), QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs);
if (!iter.hasNext())
return true;
iter.next();
if ((iter.fileName() == "meta.ini") && !iter.hasNext())
return true;
return false;
while (iter.hasNext()) {
iter.next();
if (iter.fileInfo().isDir() &&
!m_Core.managedGame()->getModMappings().keys().contains(iter.fileName(),
Qt::CaseInsensitive))
return false;
if (iter.fileInfo().isDir() &&
m_Core.managedGame()->getModMappings().keys().contains(iter.fileName(),
Qt::CaseInsensitive)) {
if (QDir(iter.filePath()).count() > 2) {
return false;
}
}
if (iter.fileInfo().isFile() && iter.fileName() != "meta.ini")
return false;
}

return true;
}

QString ModInfoOverwrite::absolutePath() const
Expand Down
49 changes: 42 additions & 7 deletions src/modlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,15 +1028,50 @@ bool ModList::dropLocalFiles(const ModListDropInfo& dropInfo, int row,
QList<QPair<QString, QString>> relativePathList;

for (auto localUrl : dropInfo.localUrls()) {

QFileInfo sourceInfo(localUrl.url.toLocalFile());
QString sourceFile = sourceInfo.canonicalFilePath();
if (localUrl.originName.compare("overwrite", Qt::CaseInsensitive) == 0) {
bool needsMove = true;
if (sourceInfo.isDir()) {
for (auto dir : m_Organizer->managedGame()->getModMappings().keys()) {
QDir overDir(m_Organizer->overwritePath());
if (sourceInfo.canonicalFilePath().compare(overDir.absoluteFilePath(dir),
Qt::CaseInsensitive) == 0) {
needsMove = false;

QDirIterator dirIter(overDir.absoluteFilePath(dir),
QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
while (dirIter.hasNext()) {
auto entry = dirIter.nextFileInfo();
QString sourceFile = entry.canonicalFilePath();

QFileInfo targetInfo(modDir.absoluteFilePath(
overDir.relativeFilePath(entry.absoluteFilePath())));
sourceList << sourceFile;
targetList << targetInfo.absoluteFilePath();
relativePathList << QPair<QString, QString>(localUrl.relativePath,
localUrl.originName);
}
}
}
}
if (needsMove) {
QString sourceFile = sourceInfo.canonicalFilePath();

QFileInfo targetInfo(modDir.absoluteFilePath(localUrl.relativePath));
sourceList << sourceFile;
targetList << targetInfo.absoluteFilePath();
relativePathList << QPair<QString, QString>(localUrl.relativePath,
localUrl.originName);
}
} else {
QString sourceFile = sourceInfo.canonicalFilePath();

QFileInfo targetInfo(modDir.absoluteFilePath(localUrl.relativePath));
sourceList << sourceFile;
targetList << targetInfo.absoluteFilePath();
relativePathList << QPair<QString, QString>(localUrl.relativePath,
localUrl.originName);
QFileInfo targetInfo(modDir.absoluteFilePath(localUrl.relativePath));
sourceList << sourceFile;
targetList << targetInfo.absoluteFilePath();
relativePathList << QPair<QString, QString>(localUrl.relativePath,
localUrl.originName);
}
}

if (sourceList.count()) {
Expand Down
63 changes: 54 additions & 9 deletions src/modlistviewactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ void ModListViewActions::displayModInformation(ModInfo::Ptr modInfo,
QDialog* dialog = m_parent->findChild<QDialog*>("__overwriteDialog");
try {
if (dialog == nullptr) {
dialog = new OverwriteInfoDialog(modInfo, m_parent);
dialog = new OverwriteInfoDialog(modInfo, m_core, m_parent);
dialog->setObjectName("__overwriteDialog");
} else {
qobject_cast<OverwriteInfoDialog*>(dialog)->setModInfo(modInfo);
Expand Down Expand Up @@ -599,10 +599,12 @@ void ModListViewActions::displayModInformation(ModInfo::Ptr modInfo,
FilesOrigin& origin =
m_core.directoryStructure()->getOriginByName(ToWString(modInfo->name()));
origin.enable(false);

QString path = modInfo->absolutePath();
QString modDataDir = m_core.managedGame()->modDataDirectory();
path = modDataDir.isEmpty() ? path : path + "/" + modDataDir;
m_core.directoryRefresher()->addModToStructure(
m_core.directoryStructure(), modInfo->name(),
m_core.currentProfile()->getModPriority(modIndex), modInfo->absolutePath(),
m_core.currentProfile()->getModPriority(modIndex), path,
modInfo->stealFiles(), modInfo->archives());
DirectoryRefresher::cleanStructure(m_core.directoryStructure());
m_core.directoryStructure()->getFileRegister()->sortOrigins();
Expand Down Expand Up @@ -1299,9 +1301,42 @@ void ModListViewActions::restoreBackup(const QModelIndex& index) const
void ModListViewActions::moveOverwriteContentsTo(const QString& absolutePath) const
{
ModInfo::Ptr overwriteInfo = ModInfo::getOverwrite();
bool successful =
shellMove((QDir::toNativeSeparators(overwriteInfo->absolutePath()) + "\\*"),
(QDir::toNativeSeparators(absolutePath)), false, m_parent);
bool successful = false;
if (m_core.managedGame()->getModMappings().count() > 1 ||
m_core.managedGame()->getModMappings().keys().first() != "") {
QDirIterator iter(overwriteInfo->absolutePath(),
QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
while (iter.hasNext()) {
auto entry = iter.nextFileInfo();
if (entry.isDir() && m_core.managedGame()->getModMappings().keys().contains(
entry.fileName(), Qt::CaseInsensitive)) {
successful =
shellCopy((QDir::toNativeSeparators(entry.absolutePath())),
(QDir::toNativeSeparators(absolutePath)), false, m_parent);
QDirIterator subDirIter(entry.absoluteFilePath(),
QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
while (subDirIter.hasNext()) {
auto subDirEntry = subDirIter.nextFileInfo();
if (subDirEntry.isDir()) {
QDir(subDirEntry.absoluteFilePath()).removeRecursively();
} else {
QFile(subDirEntry.absoluteFilePath()).remove();
}
}
} else {
successful =
shellMove((QDir::toNativeSeparators(iter.filePath())),
(QDir::toNativeSeparators(absolutePath)), false, m_parent);
}
if (!successful)
break;
}

} else {
successful =
shellMove((QDir::toNativeSeparators(overwriteInfo->absolutePath()) + "\\*"),
(QDir::toNativeSeparators(absolutePath)), false, m_parent);
}

if (successful) {
MessageDialog::showMessage(tr("Move successful."), m_parent);
Expand Down Expand Up @@ -1396,9 +1431,19 @@ void ModListViewActions::clearOverwrite() const
tr("About to recursively delete:\n") + overwriteDir.absolutePath(),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
QStringList delList;
for (auto f :
overwriteDir.entryList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot))
delList.push_back(overwriteDir.absoluteFilePath(f));
for (auto f : overwriteDir.entryInfoList(QDir::AllDirs | QDir::Files |
QDir::NoDotAndDotDot)) {
if (f.isDir() && m_core.managedGame()->getModMappings().keys().contains(
f.fileName(), Qt::CaseInsensitive)) {
for (auto sf :
QDir(f.absoluteFilePath())
.entryInfoList(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot)) {
delList.push_back(sf.absoluteFilePath());
}
} else {
delList.push_back(f.absoluteFilePath());
}
}
if (shellDelete(delList, true)) {
emit overwriteCleared();
m_core.refresh();
Expand Down
53 changes: 37 additions & 16 deletions src/organizercore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,16 @@ void OrganizerCore::createDefaultProfile()
}
}

void OrganizerCore::createOverwriteDirectories()
{
QString overwritePath = settings().paths().overwrite();
for (auto modDirectory : managedGame()->getModMappings().keys()) {
if (!modDirectory.isEmpty()) {
QDir(overwritePath).mkdir(modDirectory);
}
}
}

void OrganizerCore::prepareVFS()
{
m_USVFS.updateMapping(fileMapping(m_CurrentProfile->name(), QString()));
Expand Down Expand Up @@ -1396,8 +1406,11 @@ void OrganizerCore::updateModsInDirectoryStructure(
std::vector<DirectoryRefresher::EntryInfo> entries;

for (auto idx : modInfo.keys()) {
QString path = modInfo[idx]->absolutePath();
QString modDataDir = managedGame()->modDataDirectory();
path = modDataDir.isEmpty() ? path : path + "/" + modDataDir;
entries.push_back({modInfo[idx]->name(),
modInfo[idx]->absolutePath(),
path,
modInfo[idx]->stealFiles(),
{},
m_CurrentProfile->getModPriority(idx)});
Expand Down Expand Up @@ -1426,10 +1439,12 @@ void OrganizerCore::updateModsInDirectoryStructure(

// finally also add files from bsas to the directory structure
for (auto idx : modInfo.keys()) {
QString path = modInfo[idx]->absolutePath();
QString modDataDir = managedGame()->modDataDirectory();
path = modDataDir.isEmpty() ? path : path + "/" + modDataDir;
m_DirectoryRefresher->addModBSAToStructure(
m_DirectoryStructure, modInfo[idx]->name(),
m_CurrentProfile->getModPriority(idx), modInfo[idx]->absolutePath(),
modInfo[idx]->archives());
m_CurrentProfile->getModPriority(idx), path, modInfo[idx]->archives());
}
}

Expand Down Expand Up @@ -2034,12 +2049,7 @@ std::vector<Mapping> OrganizerCore::fileMapping(const QString& profileName,

MappingType result;

QStringList dataPaths;
dataPaths.append(QDir::toNativeSeparators(game->dataDirectory().absolutePath()));

for (auto directory : game->secondaryDataDirectories()) {
dataPaths.append(directory.absolutePath());
}
auto dataMaps = game->getModMappings();

bool overwriteActive = false;

Expand All @@ -2052,13 +2062,19 @@ std::vector<Mapping> OrganizerCore::fileMapping(const QString& profileName,
ModInfo::Ptr modPtr = ModInfo::getByIndex(modIndex);

bool createTarget = customOverwrite == std::get<0>(mod);
QDir modDir = QDir(std::get<1>(mod));

overwriteActive |= createTarget;

if (modPtr->isRegular()) {
for (auto dataPath : dataPaths) {
result.insert(result.end(), {QDir::toNativeSeparators(std::get<1>(mod)),
dataPath, true, createTarget});
for (auto dataMap : dataMaps.asKeyValueRange()) {
auto mapDir = QDir(modDir.absoluteFilePath(dataMap.first));
if (mapDir.exists()) {
for (auto dir : dataMap.second) {
result.insert(result.end(),
{mapDir.absolutePath(), dir, true, createTarget});
}
}
}
}
}
Expand All @@ -2080,10 +2096,15 @@ std::vector<Mapping> OrganizerCore::fileMapping(const QString& profileName,
}
}

for (auto dataPath : dataPaths) {
result.insert(result.end(),
{QDir::toNativeSeparators(m_Settings.paths().overwrite()), dataPath,
true, customOverwrite.isEmpty()});
QDir overwriteDir(m_Settings.paths().overwrite());
for (auto dataMap : dataMaps.asKeyValueRange()) {
auto overwriteSubpath = overwriteDir.absoluteFilePath(dataMap.first);
if (QDir(overwriteSubpath).exists()) {
for (auto dir : dataMap.second) {
result.insert(result.end(),
{overwriteSubpath, dir, true, customOverwrite.isEmpty()});
}
}
}

for (MOBase::IPluginFileMapper* mapper :
Expand Down
1 change: 1 addition & 0 deletions src/organizercore.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ class OrganizerCore : public QObject, public MOBase::IPluginDiagnose
bool checkPathSymlinks();
bool bootstrap();
void createDefaultProfile();
void createOverwriteDirectories();

MOBase::DelayedFileWriter& pluginsWriter() { return m_PluginListsWriter; }

Expand Down
Loading
Loading