Skip to content

Commit 2423fcd

Browse files
authored
Merge pull request #3 from WrenSwift/Dev
The Cloud has entered the chat
2 parents 8b4073d + 028434f commit 2423fcd

4 files changed

Lines changed: 123 additions & 8 deletions

File tree

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"files.associations": {
3-
"qmainwindow": "cpp"
3+
"qmainwindow": "cpp",
4+
"qstandarditemmodel": "cpp"
45
}
56
}

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,4 @@ add_custom_command(
4040
"${CMAKE_CURRENT_SOURCE_DIR}/inc"
4141
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/inc"
4242
COMMENT "Copying inclusions folder to the build directory..."
43-
)
43+
)

mainwindow.cpp

Lines changed: 118 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@
2323
#include <QJsonObject>
2424
#include <QByteArray>
2525
#include <QJsonArray>
26+
#include <QEventLoop>
2627

27-
QString activeSubDirName = "Mods"; // Change this to your desired subdirectory
28+
QString activeSubDirName = "Mods"; // This is where the active mods are stored
2829
QString disabledSubDirName = "(d)Mods"; // Change this to your desired subdirectory
2930
QString csvFilePath = "inc/packsDil.csv";
30-
QString version = "1.0.0"; // Version of the application
31+
QString csvCloudPath = "https://wrenswift.com/packsDil.csv";
32+
QString version = "1.1.0"; // Version of the application
3133

3234
MainWindow::MainWindow(QWidget *parent)
3335
: QMainWindow(parent)
@@ -72,7 +74,7 @@ MainWindow::MainWindow(QWidget *parent)
7274
}
7375
if (!cachedGameSource.isEmpty()) {
7476
ui->gameLineEdit->setText(cachedGameSource);
75-
populatePacksListWidget(cachedGameSource,csvFilePath);
77+
loadPacksCsv(csvCloudPath, csvFilePath);
7678
}
7779

7880
qDebug() << "Resource exists:" << QFile::exists(":/inc/packsDil.csv");
@@ -156,6 +158,65 @@ void MainWindow::doVersionCheck() {
156158
reply->deleteLater();
157159
}
158160

161+
void MainWindow::loadPacksCsv(const QString &url, const QString &localPath)
162+
{
163+
QNetworkAccessManager manager;
164+
QEventLoop loop;
165+
QNetworkReply *reply = manager.get(QNetworkRequest(QUrl(url)));
166+
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
167+
loop.exec();
168+
169+
QByteArray csvData;
170+
bool usedNetwork = false;
171+
172+
if (reply->error() == QNetworkReply::NoError) {
173+
csvData = reply->readAll();
174+
usedNetwork = true;
175+
// Save the latest network version locally for future offline use
176+
QFile localFile(localPath);
177+
if (localFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
178+
localFile.write(csvData);
179+
localFile.close();
180+
}
181+
} else {
182+
// Network failed, try to load from local file
183+
QFile localFile(localPath);
184+
if (localFile.open(QIODevice::ReadOnly)) {
185+
csvData = localFile.readAll();
186+
localFile.close();
187+
QMessageBox::warning(this, tr("Network Error"),
188+
tr("Failed to download packs CSV from the cloud. Using local backup copy instead."));
189+
} else {
190+
QMessageBox::warning(this, tr("Network Error"),
191+
tr("Failed to download packs CSV from the cloud and no local backup is available: %1").arg(reply->errorString()));
192+
reply->deleteLater();
193+
return;
194+
}
195+
}
196+
reply->deleteLater();
197+
198+
// Parse CSV data (same as before)
199+
QHash<QString, QString> folderMapping;
200+
QTextStream in(csvData);
201+
bool firstLine = true;
202+
while (!in.atEnd()) {
203+
QString line = in.readLine().trimmed();
204+
if (line.isEmpty())
205+
continue;
206+
if (firstLine) {
207+
firstLine = false;
208+
// continue; // Uncomment if your CSV has a header
209+
}
210+
QStringList parts = line.split(',');
211+
if (parts.size() >= 2) {
212+
QString originalName = parts.at(0).trimmed();
213+
QString friendlyName = parts.at(1).trimmed();
214+
folderMapping.insert(originalName, friendlyName);
215+
}
216+
}
217+
populatePacksListWidgetWithMapping(ui->gameLineEdit->text(), folderMapping);
218+
}
219+
159220
void MainWindow::on_menuMods_clicked(){
160221
ui->mainStackedWidget->setCurrentIndex(0);
161222
}
@@ -614,8 +675,8 @@ void MainWindow::do_S4MPCheck() {
614675

615676
if (foundS4MP) {
616677
QMessageBox::warning(this, tr("S4MP Detected"),
617-
tr("\"S4MP Launcher Windows.exe\" is present in your active mods. "
618-
"If you plan to use S4MP please use their launcher for pack selection after desired mods are selected."));
678+
tr("'%1' is present in your active mods. "
679+
"If you plan to use S4MP please use their launcher for pack selection after desired mods are selected.").arg(s4mpExeName));
619680
}
620681
}
621682

@@ -742,6 +803,57 @@ void MainWindow::populatePacksListWidget(const QString &folderPath, const QStrin
742803
sortPacksListByCategory();
743804
}
744805

806+
void MainWindow::populatePacksListWidgetWithMapping(const QString &folderPath, const QHash<QString, QString> &folderMapping)
807+
{
808+
ui->packsListWidget->clear();
809+
810+
QSettings settings("Falcon", "SimsSwitcher");
811+
QStringList checkedPacks = settings.value("packsSelection").toStringList();
812+
813+
QDir dir(folderPath);
814+
QFileInfoList folderList = dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
815+
816+
for (const QFileInfo &info : folderList) {
817+
QString originalName = info.fileName();
818+
if (!folderMapping.contains(originalName))
819+
continue;
820+
QString displayName = folderMapping.value(originalName);
821+
QListWidgetItem *item = new QListWidgetItem(displayName);
822+
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
823+
if (checkedPacks.contains(originalName))
824+
item->setCheckState(Qt::Checked);
825+
else
826+
item->setCheckState(Qt::Unchecked);
827+
item->setData(Qt::UserRole, info.absoluteFilePath());
828+
item->setData(Qt::UserRole + 1, originalName);
829+
ui->packsListWidget->addItem(item);
830+
qDebug() << "Added folder:" << originalName << "as" << displayName
831+
<< "Full path:" << info.absoluteFilePath();
832+
}
833+
// If any packs are present in the source directory that are not in the mapping, display a warning.
834+
QStringList mappedNames = folderMapping.keys();
835+
// Check for unmapped packs in the directory.
836+
for (const QFileInfo &info : folderList) {
837+
// Get the original name from the QFileInfo.
838+
QString originalName = info.fileName();
839+
// Sort out original names that are not in the format of "EP01", "GP02", etc.
840+
if (originalName.length() < 4 || !originalName.startsWith("EP") && !originalName.startsWith("GP") &&
841+
!originalName.startsWith("SP") && !originalName.startsWith("FP")) {
842+
continue; // Skip names that do not match the expected format.
843+
}
844+
if (!mappedNames.contains(originalName)) {
845+
// If the original name is not in the mapping, it means it's an unmapped pack.
846+
qDebug() << "Unmapped pack found:" << originalName;
847+
QMessageBox::warning(this, tr("Unmapped Pack Warning"),
848+
tr("The pack '%1' is not mapped in the CSV file. "
849+
"This could mean the packs data is out of date or another error is occuring. "
850+
"If you have not recieved a Network Error please report the issue.").arg(originalName));
851+
}
852+
}
853+
// Automatically call the sorting function to group items into categories.
854+
sortPacksListByCategory();
855+
}
856+
745857
void MainWindow::sortPacksListByCategory()
746858
{
747859
// Define alias-to-description mappings
@@ -825,7 +937,7 @@ void MainWindow::on_browseGameButton_clicked() {
825937
ui->gameLineEdit->setText(gameDir);
826938

827939
// Populate the file list using the full path (Sims 4 Root + Subdirectory).
828-
populatePacksListWidget(gameDir,csvFilePath);
940+
loadPacksCsv(csvCloudPath, csvFilePath);
829941

830942
// Use QSettings to store the full path including the subdirectory.
831943
QSettings settings("Falcon", "SimsSwitcher");

mainwindow.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,7 @@ private slots:
6363
void doVersionCheck();
6464
void do_patreonLink();
6565
void do_S4MPCheck();
66+
void loadPacksCsv(const QString &url, const QString &localPath);
67+
void populatePacksListWidgetWithMapping(const QString &folderPath, const QHash<QString, QString> &folderMapping);
6668
};
6769
#endif // MAINWINDOW_H

0 commit comments

Comments
 (0)