|
|
@@ -904,9 +904,10 @@ void CModListView::installFiles(QStringList files)
|
|
|
|
|
|
if (hasModJson)
|
|
|
mods.push_back(filename);
|
|
|
-
|
|
|
- if (hasMaps)
|
|
|
+ else if (hasMaps)
|
|
|
maps.push_back(filename);
|
|
|
+ else
|
|
|
+ mods.push_back(filename);
|
|
|
}
|
|
|
else if(realFilename.endsWith(".h3m", Qt::CaseInsensitive) || realFilename.endsWith(".h3c", Qt::CaseInsensitive) || realFilename.endsWith(".vmap", Qt::CaseInsensitive) || realFilename.endsWith(".vcmp", Qt::CaseInsensitive))
|
|
|
maps.push_back(filename);
|
|
|
@@ -1082,17 +1083,47 @@ void CModListView::installMods(QStringList archives)
|
|
|
|
|
|
void CModListView::installMaps(QStringList maps)
|
|
|
{
|
|
|
- const auto destDir = CLauncherDirs::mapsPath() + QChar{'/'};
|
|
|
+ const auto destDir = CLauncherDirs::mapsPath() + QChar{ '/' };
|
|
|
int successCount = 0;
|
|
|
QStringList failedMaps;
|
|
|
|
|
|
- for(QString map : maps)
|
|
|
+ // Pre-scan all maps and ZIPs to detect total number of conflicts
|
|
|
+ int conflictCount = 0;
|
|
|
+ for (const QString& map : maps)
|
|
|
{
|
|
|
- // ZIP archive handling
|
|
|
if (map.endsWith(".zip", Qt::CaseInsensitive))
|
|
|
{
|
|
|
- logGlobal->info("Importing map archive '%s'", map.toStdString());
|
|
|
+ ZipArchive archive(qstringToPath(map));
|
|
|
+ for (const auto& file : archive.listFiles())
|
|
|
+ {
|
|
|
+ QString name = QString::fromStdString(file);
|
|
|
+ if (name.endsWith(".h3m", Qt::CaseInsensitive) || name.endsWith(".h3c", Qt::CaseInsensitive) ||
|
|
|
+ name.endsWith(".vmap", Qt::CaseInsensitive) || name.endsWith(".vcmp", Qt::CaseInsensitive))
|
|
|
+ {
|
|
|
+ QString destFile = destDir + name;
|
|
|
+ if (QFile::exists(destFile))
|
|
|
+ conflictCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ QString fileName = map.section('/', -1, -1);
|
|
|
+ QString destFile = destDir + fileName;
|
|
|
+ if (QFile::exists(destFile))
|
|
|
+ conflictCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ bool applyToAll = false;
|
|
|
+ bool overwriteAll = false;
|
|
|
+
|
|
|
+ for (QString map : maps)
|
|
|
+ {
|
|
|
+ // Handle ZIP archive
|
|
|
+ if (map.endsWith(".zip", Qt::CaseInsensitive))
|
|
|
+ {
|
|
|
+ logGlobal->info("Importing map archive '%s'", map.toStdString());
|
|
|
ZipArchive archive(qstringToPath(map));
|
|
|
auto fileList = archive.listFiles();
|
|
|
|
|
|
@@ -1100,17 +1131,62 @@ void CModListView::installMaps(QStringList maps)
|
|
|
{
|
|
|
QString name = QString::fromStdString(file);
|
|
|
|
|
|
- if (!(name.endsWith(".h3m", Qt::CaseInsensitive) || name.endsWith(".h3c", Qt::CaseInsensitive) || name.endsWith(".vmap", Qt::CaseInsensitive) || name.endsWith(".vcmp", Qt::CaseInsensitive)))
|
|
|
+ if (!(name.endsWith(".h3m", Qt::CaseInsensitive) || name.endsWith(".h3c", Qt::CaseInsensitive) ||
|
|
|
+ name.endsWith(".vmap", Qt::CaseInsensitive) || name.endsWith(".vcmp", Qt::CaseInsensitive)))
|
|
|
continue;
|
|
|
|
|
|
QString destFile = destDir + name;
|
|
|
|
|
|
- // prompt if exists
|
|
|
+ // Ask user if file exists
|
|
|
if (QFile::exists(destFile))
|
|
|
{
|
|
|
- int ret = QMessageBox::question(this, tr("Map exists"), tr("Map '%1' already exists. Do you want to overwrite it?").arg(name), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
|
|
+ bool overwrite = false;
|
|
|
|
|
|
- if (ret != QMessageBox::Yes)
|
|
|
+ if (!applyToAll)
|
|
|
+ {
|
|
|
+ QMessageBox msgBox(this);
|
|
|
+ msgBox.setIcon(QMessageBox::Question);
|
|
|
+ msgBox.setWindowTitle(tr("Map exists"));
|
|
|
+ msgBox.setText(tr("Map '%1' already exists. Do you want to overwrite it?").arg(name));
|
|
|
+
|
|
|
+ QPushButton* yes = msgBox.addButton(QMessageBox::Yes);
|
|
|
+ QPushButton* no = msgBox.addButton(QMessageBox::No);
|
|
|
+ QPushButton* yesAll = nullptr;
|
|
|
+ QPushButton* noAll = nullptr;
|
|
|
+
|
|
|
+ // Only show Yes to All / No to All if we have more than one conflict in total
|
|
|
+ if (conflictCount > 1)
|
|
|
+ {
|
|
|
+ yesAll = msgBox.addButton(tr("Yes to All"), QMessageBox::YesRole);
|
|
|
+ noAll = msgBox.addButton(tr("No to All"), QMessageBox::NoRole);
|
|
|
+ }
|
|
|
+
|
|
|
+ msgBox.exec();
|
|
|
+ QAbstractButton* clicked = msgBox.clickedButton();
|
|
|
+
|
|
|
+ if (clicked == yes)
|
|
|
+ overwrite = true;
|
|
|
+ else if (clicked == yesAll)
|
|
|
+ {
|
|
|
+ applyToAll = true;
|
|
|
+ overwriteAll = true;
|
|
|
+ overwrite = true;
|
|
|
+ }
|
|
|
+ else if (clicked == noAll)
|
|
|
+ {
|
|
|
+ applyToAll = true;
|
|
|
+ overwriteAll = false;
|
|
|
+ overwrite = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ overwrite = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ overwrite = overwriteAll;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!overwrite)
|
|
|
{
|
|
|
logGlobal->info("Skipped map '%s'", name.toStdString());
|
|
|
continue;
|
|
|
@@ -1129,19 +1205,63 @@ void CModListView::installMaps(QStringList maps)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- continue; // skip to next map entry
|
|
|
+ continue; // next map in list
|
|
|
}
|
|
|
|
|
|
- // Single map file handling
|
|
|
+ // Handle single map file
|
|
|
QString fileName = map.section('/', -1, -1);
|
|
|
QString destFile = destDir + fileName;
|
|
|
logGlobal->info("Importing map '%s'", map.toStdString());
|
|
|
|
|
|
if (QFile::exists(destFile))
|
|
|
{
|
|
|
- int ret = QMessageBox::question(this, tr("Map exists"), tr("Map '%1' already exists. Do you want to overwrite it?").arg(fileName), QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
|
|
|
+ bool overwrite = false;
|
|
|
+
|
|
|
+ if (!applyToAll)
|
|
|
+ {
|
|
|
+ QMessageBox msgBox(this);
|
|
|
+ msgBox.setIcon(QMessageBox::Question);
|
|
|
+ msgBox.setWindowTitle(tr("Map exists"));
|
|
|
+ msgBox.setText(tr("Map '%1' already exists. Do you want to overwrite it?").arg(fileName));
|
|
|
+
|
|
|
+ QPushButton* yes = msgBox.addButton(QMessageBox::Yes);
|
|
|
+ QPushButton* no = msgBox.addButton(QMessageBox::No);
|
|
|
+ QPushButton* yesAll = nullptr;
|
|
|
+ QPushButton* noAll = nullptr;
|
|
|
+
|
|
|
+ // Only show Yes to All / No to All if we have more than one conflict in total
|
|
|
+ if (conflictCount > 1)
|
|
|
+ {
|
|
|
+ yesAll = msgBox.addButton(tr("Yes to All"), QMessageBox::YesRole);
|
|
|
+ noAll = msgBox.addButton(tr("No to All"), QMessageBox::NoRole);
|
|
|
+ }
|
|
|
+
|
|
|
+ msgBox.exec();
|
|
|
+ QAbstractButton* clicked = msgBox.clickedButton();
|
|
|
+
|
|
|
+ if (clicked == yes)
|
|
|
+ overwrite = true;
|
|
|
+ else if (clicked == yesAll)
|
|
|
+ {
|
|
|
+ applyToAll = true;
|
|
|
+ overwriteAll = true;
|
|
|
+ overwrite = true;
|
|
|
+ }
|
|
|
+ else if (clicked == noAll)
|
|
|
+ {
|
|
|
+ applyToAll = true;
|
|
|
+ overwriteAll = false;
|
|
|
+ overwrite = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ overwrite = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ overwrite = overwriteAll;
|
|
|
+ }
|
|
|
|
|
|
- if (ret != QMessageBox::Yes)
|
|
|
+ if (!overwrite)
|
|
|
{
|
|
|
logGlobal->info("Skipped map '%s'", fileName.toStdString());
|
|
|
continue;
|
|
|
@@ -1161,11 +1281,11 @@ void CModListView::installMaps(QStringList maps)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // success message
|
|
|
+ // Show success message
|
|
|
if (successCount > 0)
|
|
|
QMessageBox::information(this, tr("Import complete"), tr("%1 map(s) successfully imported.").arg(successCount), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
|
|
|
- // error message
|
|
|
+ // Show error message
|
|
|
if (!failedMaps.isEmpty())
|
|
|
QMessageBox::warning(this, tr("Import failed"), tr("Failed to import the following maps:\n%1").arg(failedMaps.join("\n")), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
}
|