Browse Source

Yes to All / No to All overwrite support

George King 4 months ago
parent
commit
f0bd50828f
1 changed files with 136 additions and 16 deletions
  1. 136 16
      launcher/modManager/cmodlistview_moc.cpp

+ 136 - 16
launcher/modManager/cmodlistview_moc.cpp

@@ -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);
 }