From 0f4d82ebbe7c60f864ae6a18b44292de6797834d Mon Sep 17 00:00:00 2001 From: Awth Wathje Date: Sun, 16 Oct 2016 16:27:57 +0300 Subject: [PATCH] Fixed a bug when screenshots weren't added to the VDF-file if latest copied screenshot was a dupe. Major refactoring (partially conforms to the MVC pattern). Minor UI improvement. --- README.md | 4 +- SteaScree.pro | 25 +- main.cpp | 105 +++++++ mainwindow.cpp | 810 ++++++++++++------------------------------------- mainwindow.h | 103 +++---- mainwindow.ui | 667 ++++++++++++++++++++-------------------- model.cpp | 627 ++++++++++++++++++++++++++++++++++++++ model.h | 105 +++++++ 8 files changed, 1423 insertions(+), 1023 deletions(-) create mode 100644 model.cpp create mode 100644 model.h diff --git a/README.md b/README.md index 827d289..1df9cfd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,6 @@ SteaScree: Steam Cloud Screenshot Uploader -SteaScree is a simple cross-platform open-source utility which allows an uploading of screenshots to the Steam Cloud taken without a use of Steam in-game overlay. You just pick screenshots and game and SteaScree will do the rest. +SteaScree is a simple cross-platform open-source utility which makes screenshots taken without the use of Steam's in-game overlay uploadable to the Steam Cloud. You just pick pics and a game and SteaScree will do the rest. -Latest installers for all platforms are always available at https://steascree.download. +Latest installers for all platforms are always available at https://steascree.download. \ No newline at end of file diff --git a/SteaScree.pro b/SteaScree.pro index 6bcc03b..051c5cc 100644 --- a/SteaScree.pro +++ b/SteaScree.pro @@ -1,26 +1,23 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-08-20T12:24:15 -# -#------------------------------------------------- +QT += core gui network -QT += core gui network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -TARGET = SteaScree +TARGET = SteaScree -TEMPLATE = app +TEMPLATE = app -SOURCES += main.cpp\ - mainwindow.cpp +SOURCES += main.cpp\ + mainwindow.cpp \ + model.cpp -HEADERS += mainwindow.h +HEADERS += mainwindow.h \ + model.h -FORMS += mainwindow.ui +FORMS += mainwindow.ui -VERSION = 1.0.3.0 +VERSION = 1.0.4.0 -macx:ICON = res/icons/SteaScree.icns +macx:ICON = res/icons/SteaScree.icns win32:RC_ICONS = res/icons/SteaScree.ico win32:QMAKE_TARGET_COMPANY = Foyl diff --git a/main.cpp b/main.cpp index d9a129b..1978364 100644 --- a/main.cpp +++ b/main.cpp @@ -1,4 +1,5 @@ #include "mainwindow.h" +#include "model.h" #include @@ -11,7 +12,111 @@ int main(int argc, char *argv[]) QCoreApplication::setApplicationName("SteaScree"); MainWindow w; + Model m; + + QObject::connect(&w, &MainWindow::getOS, + &m, &Model::returnOS); + + QObject::connect(&m, &Model::sendOS, + &w, &MainWindow::setButtonPadding); + + QObject::connect(&m, &Model::addWidgetItemToScreenshotList, + &w, &MainWindow::addWidgetItemToScreenshotList); + + QObject::connect(&m, &Model::resizeScreenshotListColumns, + &w, &MainWindow::resizeScreenshotListColumns); + + QObject::connect(&w, &MainWindow::getSteamDir, + &m, &Model::returnSteamDir); + + QObject::connect(&m, &Model::sendSteamDir, + &w, &MainWindow::locateSteamDir); + + QObject::connect(&w, &MainWindow::setUserDataPaths, + &m, &Model::setUserDataPaths); + + QObject::connect(&w, &MainWindow::pushButtonAddScreenshots_clicked, + &m, &Model::returnLastSelectedScreenshotDir); + + QObject::connect(&m, &Model::sendLastSelectedScreenshotDir, + &w, &MainWindow::returnScreenshotsSelected); + + QObject::connect(&w, &MainWindow::sendScreenshotsSelected, + &m, &Model::addScreenshotsToPool); + + QObject::connect(&w, &MainWindow::pushButtonPrepare_clicked, + &m, &Model::returnLinesState); + + QObject::connect(&m, &Model::sendLinesState, + &w, &MainWindow::prepareScreenshots); + + QObject::connect(&m, &Model::disableWidgets, + &w, &MainWindow::setWidgetsDisabled); + + QObject::connect(&w, &MainWindow::clearScreenshotPathsPool, + &m, &Model::clearScreenshotPathsPool); + + QObject::connect(&w, &MainWindow::clearCopyingStatusLabels, + &m, &Model::clearCopyingStatusLabels); + + QObject::connect(&w, &MainWindow::getScreenshotPathsPoolLength, + &m, &Model::returnScreenshotPathPoolLength); + + QObject::connect(&m, &Model::sendScreenshotPathPoolLength, + &w, &MainWindow::setVisibleProgressBar); + + QObject::connect(&w, &MainWindow::writeVDF, + &m, &Model::writeVDF); + + QObject::connect(&w, &MainWindow::pushScreenshots, + &m, &Model::pushScreenshots); + + QObject::connect(&w, &MainWindow::getVDFStatus, + &m, &Model::returnVDFStatus); + + QObject::connect(&m, &Model::sendVDFStatus, + &w, &MainWindow::warnOnMissingVDF); + + QObject::connect(&m, &Model::moveWindow, + &w, &MainWindow::moveWindow); + + QObject::connect(&m, &Model::setLabelStatusErrorVisible, + &w, &MainWindow::setLabelStatusErrorVisible); + + QObject::connect(&w, &MainWindow::sendSettings, + &m, &Model::writeSettings); + + QObject::connect(&m, &Model::clearWidgets, + &w, &MainWindow::setComboBoxesCleared); + + QObject::connect(&m, &Model::sendToComboBox, + &w, &MainWindow::insertIntoComboBox); + + QObject::connect(&m, &Model::setIndexOfComboBoxGameID, + &w, &MainWindow::setIndexOfComboBoxGameID); + + QObject::connect(&m, &Model::setLabelsOnMissingStuff, + &w, &MainWindow::setLabelsOnMissingStuff); + + QObject::connect(&m, &Model::getComboBoxUserIDCurrentText, + &w, &MainWindow::returnComboBoxUserIDCurrentText, + Qt::DirectConnection); + + QObject::connect(&w, &MainWindow::sendComboBoxUserIDCurrentText, + &m, &Model::setSelectedUserID); + + QObject::connect(&m, &Model::sendLabelsText, + &w, &MainWindow::setLabelsText); + + QObject::connect(&m, &Model::setProgressBarValue, + &w, &MainWindow::setProgressBarValue); + + QObject::connect(&m, &Model::deleteCopiedWidgetItem, + &w, &MainWindow::deleteCopiedWidgetItem); + w.show(); + w.bootStrap(); + m.bootStrap(); return a.exec(); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 5e55a9e..d40f246 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -4,33 +4,16 @@ #include #include #include -#include -#include -#include +#include #include #include #include #include -#include #include -#include -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include #include -#include -#include MainWindow::MainWindow(QWidget *parent) : @@ -40,36 +23,20 @@ MainWindow::MainWindow(QWidget *parent) : { ui->setupUi(this); +} - QList buttonList; // list of buttons for setting a different padding for each OS - buttonList << ui->pushButtonClearQueue << ui->pushButtonCopyScreenshots << ui->pushButtonAddScreenshots << ui->pushButtonPrepare; - if ( (os == "Linux") | (os == "macOS") ) { - isUnixLikeOS = true; - if ( os == "Linux" ) { - settings = new QSettings(QSettings::NativeFormat, QSettings::UserScope, "Foyl", "SteaScree"); - defaultSteamDir = QDir::homePath() + "/.steam/steam"; - foreach (QPushButton *button, buttonList) - button->setStyleSheet("padding: 3px 13px"); - } else { - settings = new QSettings(QSettings::NativeFormat, QSettings::UserScope, "foyl.io", "SteaScree"); - defaultSteamDir = QDir::homePath() + "/Library/Application Support/Steam"; - }; - } else { - isUnixLikeOS = false; - settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "Foyl", "SteaScree"); - if ( QSysInfo::currentCpuArchitecture() == "x86_64" ) - defaultSteamDir = "C:/Program Files (x86)/Steam"; - else - defaultSteamDir = "C:/Program Files/Steam"; - foreach (QPushButton *button, buttonList) - button->setStyleSheet("padding: 4px 14px"); - }; +MainWindow::~MainWindow() +{ + delete ui; +} + +void MainWindow::bootStrap() +{ ui->progressBarScreenshotsUploading->setVisible(false); // initial widget states setting - ui->pushButtonClearQueue->setDisabled(true); - ui->pushButtonCopyScreenshots->setDisabled(true); - ui->pushButtonPrepare->setDisabled(true); + ui->labelStatusError->setVisible(false); + setWidgetsDisabled(QStringList() << "pushButtonClearQueue" << "pushButtonCopyScreenshots" << "pushButtonPrepare", true); QSizePolicy sp_retain = ui->labelInfoScreenshots->sizePolicy(); // hack to prevent layout size change on a widget visibility changing events sp_retain.setRetainSizeWhenHidden(true); @@ -78,618 +45,281 @@ MainWindow::MainWindow(QWidget *parent) : toggleLabelInfo(false); // information labels are hidden at start - readSettings(); // read settings from the file, if any + emit getOS(); +} - if ( !screenshotPathsPool.isEmpty() ) { - populateScreenshotQueue(screenshotPathsPool); - ui->pushButtonClearQueue->setDisabled(false); - ui->pushButtonCopyScreenshots->setDisabled(false); - }; - if ( !steamDir.isNull() ) { - userDataDir = steamDir + "/userdata"; - setUserDataPaths(steamDir); - }; +void MainWindow::setButtonPadding(QString os) +{ + QList buttonList; // list of buttons for setting a different padding for each OS + buttonList << ui->pushButtonClearQueue << ui->pushButtonCopyScreenshots << ui->pushButtonAddScreenshots << ui->pushButtonPrepare; - QObject::connect(this, &MainWindow::vdfIsMissing, // if vdf file isn't found in last/default location, warning message box appears - this, &MainWindow::warnOnMissingVDF); + if (os == "Linux") + foreach (QPushButton *button, buttonList) + button->setStyleSheet("padding: 3px 13px"); + else if (os == "Windows") + foreach (QPushButton *button, buttonList) + button->setStyleSheet("padding: 4px 14px"); } -MainWindow::~MainWindow() +void MainWindow::checkVDF() { - delete ui; + emit getVDFStatus(); } -void MainWindow::showEvent(QShowEvent *event) // hack to show message boxes only after the main window is shown +void MainWindow::toggleLabelInfo(bool isVisible) // info labels show/hide toggle { - QMainWindow::showEvent(event); - QTimer::singleShot(50, this, SLOT(warnOnMissingVDF())); + QList labelInfoList; + labelInfoList << ui->labelInfoScreenshots << ui->labelInfo1 << ui->labelInfo2 << ui->labelInfoDirectories; + foreach (QLabel *label, labelInfoList) + label->setVisible(isVisible); } -void MainWindow::closeEvent(QCloseEvent *event) +void MainWindow::addWidgetItemToScreenshotList(QTreeWidgetItem *item) { - writeSettings(); - event->accept(); + ui->treeWidgetScreenshotList->addTopLevelItem(item); } -void MainWindow::readSettings() +void MainWindow::resizeScreenshotListColumns() { - settings->beginGroup("Main"); - isFirstStart = settings->value("FirstStart", true).toBool(); - settings->endGroup(); - - settings->beginGroup("WindowGeometry"); - QRect rec = QApplication::desktop()->availableGeometry(); - resize(settings->value("Size", QSize(800, 800)).toSize()); - move(settings->value("Position", QPoint((rec.width()-800)/2, (rec.height()-800)/2)).toPoint()); - settings->endGroup(); - - settings->beginGroup("LastSelection"); - steamDir = settings->value("SteamDir", defaultSteamDir).toString(); - - if ( QDir(steamDir).exists() ) - ui->labelSteamDirValue->setText(convertSlashes(steamDir)); - else - ui->labelSteamDirValue->setText("Not found, please locate manually"); - - lastSelectedScreenshotDir = settings->value("Screenshots", QDir::currentPath()).toString(); - lastSelectedUserID = settings->value("UserID").toString(); - lastSelectedGameID = settings->value("GameID").toString(); - - settings->endGroup(); - - settings->beginGroup("Screenshots"); - screenshotPathsPool = settings->value("Queue").toStringList(); - settings->endGroup(); + ui->treeWidgetScreenshotList->resizeColumnToContents(0); // after all has been added, resize columns for a better appearance + ui->treeWidgetScreenshotList->resizeColumnToContents(1); } -void MainWindow::writeSettings() +void MainWindow::warnOnMissingVDF(bool userDataExists, QString vdfFilename) { - settings->beginGroup("Main"); - settings->setValue("FirstStart", isFirstStart); - settings->endGroup(); + QMessageBox msgBox(this); + msgBox.setIcon(QMessageBox::Warning); - settings->beginGroup("WindowGeometry"); - settings->setValue("Size", size()); - settings->setValue("Position", pos()); - settings->endGroup(); - - settings->beginGroup("LastSelection"); - settings->setValue("SteamDir", steamDir.replace("\\", "/")); - settings->setValue("Screenshots", lastSelectedScreenshotDir.replace("\\", "/")); - if ( !ui->comboBoxUserID->currentText().isEmpty() ) - settings->setValue("UserID", ui->comboBoxUserID->currentText()); - if ( !ui->comboBoxGameID->currentText().isEmpty() ) - settings->setValue("GameID", ui->comboBoxGameID->currentText().remove(QRegularExpression(" <.+>$"))); // sanitize game ID before saving to settings file - settings->endGroup(); + if ( !userDataExists ) { + msgBox.setText("SteaScree has been unable to find a Steam userdata directory in the current location."); + msgBox.setInformativeText("Please choose an existing Steam directory."); + } else { + msgBox.setText("Steam userdata directory is found, but there is no " + vdfFilename); + msgBox.setInformativeText("Please start Steam, make some screenshots with it and try again."); + }; - settings->beginGroup("Screenshots"); - settings->setValue("Queue", screenshotPathsPool); - settings->endGroup(); + msgBox.exec(); } -void MainWindow::toggleLabelInfo(bool isVisible) // info lables show/hide toggle +void MainWindow::locateSteamDir(QString steamDir) { - QList labelInfoList; - labelInfoList << ui->labelInfoScreenshots << ui->labelInfo1 << ui->labelInfo2 << ui->labelInfoDirectories; - foreach (QLabel *label, labelInfoList) - label->setVisible(isVisible); + QString steamDirLocated = QFileDialog::getExistingDirectory(this, + "Locate Steam directory", + steamDir, + QFileDialog::ShowDirsOnly | QFileDialog::ReadOnly); + if ( !steamDirLocated.isEmpty() ) { + + steamDirLocated.remove(QRegularExpression("/userdata$")); + emit setUserDataPaths(steamDirLocated); + }; } -void MainWindow::populateScreenshotQueue(QStringList screenshotPathsList) // function to populate screenshot list with visible entries +void MainWindow::setLabelsText(QStringList list, QString text) { - if ( !screenshotPathsList.isEmpty() ) { - - QTreeWidgetItem *item = NULL; - QListIterator i(screenshotPathsList); - while ( i.hasNext() ) { - QString current = i.next(); - if ( QFile(current).exists() ) { - item = new QTreeWidgetItem; - item->setText(0, current.section('/', -1)); - item->setText(1, QFileInfo(QFile(current)).lastModified().toString("yyyy/MM/dd hh:mm:ss")); - QString path; - path = convertSlashes(current.section('/', 0, -2)); - item->setText(2, path); - ui->treeWidgetScreenshotList->addTopLevelItem(item); - } else - screenshotPathsPool.removeOne(current); - }; - - ui->treeWidgetScreenshotList->resizeColumnToContents(0); // after all has been added, resize columns for a better appearance - ui->treeWidgetScreenshotList->resizeColumnToContents(1); - + QStringListIterator i(list); + while ( i.hasNext() ) { + QString current = i.next(); + QLabel *label = this->findChild(current); + label->setText(text); }; } - -void MainWindow::setUserDataPaths(QString dir) // function to validate and set data paths and IDs +void MainWindow::setWidgetsDisabled(QStringList list, bool disable) { - QStringList userIDsCombined; - - vdfPaths.clear(); // there may be multiple Steam installations in the system and thus multiple VDFs - userID.clear(); - someID.clear(); - gameIDs.clear(); - - ui->comboBoxUserID->clear(); - ui->comboBoxGameID->clear(); - ui->labelStatusError->clear(); - - QList widgetList; // list of widgets for easier disabling/enabling - widgetList << ui->labelUserID << ui->comboBoxUserID << ui->labelGameID << ui->comboBoxGameID - << ui->groupBoxScreenshotQueue; - - foreach (QWidget *widget, widgetList) - widget->setDisabled(true); - - if ( QDir(dir + "/userdata").exists() ) { - - QDirIterator i(userDataDir, QStringList() << vdfFilename, QDir::Files, QDirIterator::Subdirectories); - while ( i.hasNext() ) { - vdfPaths << i.next(); - }; - - if ( !vdfPaths.isEmpty() ) { - - foreach (QWidget *widget, widgetList) - widget->setDisabled(false); - - ui->groupBoxScreenshotQueue->setDisabled(false); - ui->treeWidgetScreenshotList->setDisabled(false); - ui->labelSteamDirValue->setText(convertSlashes(dir)); - steamDir = dir; - - QListIterator i(vdfPaths); - while ( i.hasNext() ) { - QString current = i.next(); - QStringList splitted = current.split('/'); - userID = splitted.takeAt(splitted.length() - 3); - someID = splitted.takeAt(splitted.length() - 2); - userIDsCombined << userID + "/" + someID; - }; - - QStringList items; - if ( isUnixLikeOS ) - items = userIDsCombined; - else - items = userIDsCombined.replaceInStrings("/", "\\"); - ui->comboBoxUserID->insertItems(0, items); - - if ( !isFirstStart ) - ui->comboBoxUserID->setCurrentIndex(ui->comboBoxUserID->findText(lastSelectedUserID)); - - isFirstStart = false; - - ui->comboBoxGameID->insertItem(0, "loading..."); - - QNetworkAccessManager *nam = new QNetworkAccessManager(this); - - QObject::connect(nam, &QNetworkAccessManager::finished, - this, &MainWindow::getGameNames); - - nam->get(QNetworkRequest(QUrl("http://api.steampowered.com/ISteamApps/GetAppList/v2"))); - - } else { - ui->labelStatusError->setText("Steam userdata directory is found, but " + vdfFilename + " is missing."); - ui->labelSteamDirValue->setText("not found"); - ui->labelSteamDirValue->setStyleSheet("color: gray;"); - }; - - } else { - ui->labelStatusError->setText("Steam userdata directory is missing. Please locate correct Steam directory."); - ui->labelSteamDirValue->setText("not found"); - ui->labelSteamDirValue->setStyleSheet("color: gray;"); + QStringListIterator i(list); + while ( i.hasNext() ) { + QString current = i.next(); + QWidget *widget = this->findChild(current); + widget->setDisabled(disable); }; } -void MainWindow::warnOnMissingVDF() +void MainWindow::setComboBoxesCleared(QStringList list) { - if ( vdfPaths.isEmpty() ) { - - QMessageBox msgBox(this); - msgBox.setIcon(QMessageBox::Warning); - - if ( !QDir(steamDir + "/userdata").exists() ) { - msgBox.setText("SteaScree has been unable to find a Steam userdata directory in the current location."); - msgBox.setInformativeText("Please choose an existing Steam directory."); - } else { - msgBox.setText("Steam userdata directory is found, but there is no " + vdfFilename); - msgBox.setInformativeText("Please start Steam, make some screenshots with it and try again."); - }; - - msgBox.exec(); - + QStringListIterator i(list); + while ( i.hasNext() ) { + QString current = i.next(); + QComboBox *widget = this->findChild(current); + widget->clear(); }; } -void MainWindow::getGameNames(QNetworkReply *reply) +void MainWindow::setVisibleProgressBar(int length) { - if ( games.isEmpty() ) { - - if ( reply->error() == QNetworkReply::NoError ) { - - QByteArray raw = reply->readAll(); - QJsonDocument doc(QJsonDocument::fromJson(raw)); - QJsonArray apps = doc.object().value("applist").toObject().value("apps").toArray(); - - foreach (QJsonValue app, apps) { - QJsonObject obj = app.toObject(); - QString appID = QString::number(static_cast(obj.value("appid").toDouble())); - QString name = obj.value("name").toString(); - games[appID] = name; - }; - }; - - selectedUserID = ui->comboBoxUserID->currentText(); - QStringList lines = readVDF(); - int shortcutNamesHeaderPos = lines.indexOf("\t\"shortcutnames\""); // if there are any non-Steam games, get names for them too, from the VDF - int shortcutNamesEndPos = lines.indexOf("\t}", shortcutNamesHeaderPos); - QStringList shortcutNamesSection = lines.mid(shortcutNamesHeaderPos, shortcutNamesEndPos - shortcutNamesHeaderPos); - QRegularExpression re("^\t\t\"[0-9]+\"\t\t\".+\"$"); - - if ( shortcutNamesSection.indexOf(re) != -1 ) { - - int entryPos = 0; - - while ( (entryPos <= shortcutNamesSection.length() - 1) && (entryPos != -1) ) { + ui->progressBarScreenshotsUploading->setVisible(true); + ui->progressBarScreenshotsUploading->setMinimum(0); + ui->progressBarScreenshotsUploading->setMaximum(length); +} - entryPos = shortcutNamesSection.indexOf(re, entryPos + 1); - if ( entryPos != -1 ) { - QString gameID = shortcutNamesSection[entryPos].section("\t\t", 1, 1).remove(QRegularExpression("(^\")|(\"$)")); - QString gameName = shortcutNamesSection[entryPos].section("\t\t", 2, 2).remove(QRegularExpression("(^\")|(\"$)")); - games[gameID] = gameName; - }; - }; - }; - }; +void MainWindow::setLabelStatusErrorVisible(bool visible) +{ + ui->labelStatusError->setVisible(visible); +} - QDirIterator i(userDataDir + "/" + userID + "/" + someID + "/remote", QDir::Dirs | QDir::NoDotAndDotDot); - while ( i.hasNext() ) { - QString gameID = i.next().section('/', -1); +void MainWindow::moveWindow(QSize geometry, QPoint moveToPoint) +{ + resize(geometry); + move(moveToPoint); +} - if ( !games[gameID].isEmpty() ) - gameIDs << gameID + " <" + games[gameID] + ">"; - else - gameIDs << gameID; - }; +void MainWindow::insertIntoComboBox(QString name, QStringList items) +{ + QComboBox *comboBox = this->findChild(name); + comboBox->insertItems(0, items); +} - ui->comboBoxGameID->clear(); - if ( !gameIDs.isEmpty() ) - ui->comboBoxGameID->insertItems(0, gameIDs); +void MainWindow::setIndexOfComboBoxUserID(QString item) +{ + ui->comboBoxUserID->setCurrentIndex(ui->comboBoxUserID->findText(item)); +} - if ( !lastSelectedGameID.isEmpty() ) - ui->comboBoxGameID->setCurrentIndex(ui->comboBoxGameID->findText(lastSelectedGameID, Qt::MatchStartsWith)); - ui->pushButtonAddScreenshots->setDisabled(false); +void MainWindow::setIndexOfComboBoxGameID(QString lastSelectedGameID) +{ + ui->comboBoxGameID->setCurrentIndex(ui->comboBoxGameID->findText(lastSelectedGameID, Qt::MatchStartsWith)); } -QString MainWindow::convertSlashes(QString str) // +void MainWindow::setLabelsOnMissingStuff(bool userDataMissing, QString vdfFilename) { - QString converted; - - if ( isUnixLikeOS ) - converted = str; + ui->labelStatusError->setVisible(true); + if ( userDataMissing ) + ui->labelStatusError->setText("Steam userdata directory is missing. Please locate correct Steam directory."); else - converted = str.replace("/", "\\"); + ui->labelStatusError->setText("Steam userdata directory is found, but " + vdfFilename + " is missing."); - return converted; + ui->labelSteamDirValue->setText("not found"); + ui->labelSteamDirValue->setStyleSheet("color: gray;"); } -QStringList MainWindow::readVDF() // read text from the VDF and return it in the form of list of strings for easy manipulating +void MainWindow::returnComboBoxUserIDCurrentText() { - QFile vdf(userDataDir + "/" + selectedUserID + "/" + vdfFilename); - vdf.open(QIODevice::ReadOnly | QIODevice::Text); - QTextStream text(&vdf); - QStringList lines; + emit sendComboBoxUserIDCurrentText(ui->comboBoxUserID->currentText()); +} - while ( !text.atEnd() ) { - QString line = text.readLine(); - lines << line; - }; - vdf.close(); - return lines; +void MainWindow::returnScreenshotsSelected(QString lastSelectedScreenshotDir) +{ + QStringList screenshotsSelected = QFileDialog::getOpenFileNames(this, + "Select one or more screenshots", + lastSelectedScreenshotDir, + "Images (*.jpg *.jpeg *.png *.bmp *.tif *.tiff)"); + emit sendScreenshotsSelected(screenshotsSelected); } -void MainWindow::writeVDF(QStringList lines) // write to VDF from list of strings. previous contents are discarded +void MainWindow::setProgressBarValue(int value) { - QFile vdf(userDataDir + "/" + selectedUserID + "/" + vdfFilename); - vdf.open(QIODevice::WriteOnly | QIODevice::Truncate); - QTextStream text(&vdf); + ui->progressBarScreenshotsUploading->setValue(value); +} - QListIterator i(lines); - while ( i.hasNext() ) { - QString current = i.next(); - text << current + "\n"; - }; - vdf.close(); +void MainWindow::deleteCopiedWidgetItem(QString path) +{ + QFile file(path); + QTreeWidgetItem *item = ui->treeWidgetScreenshotList->findItems(QFileInfo(file).lastModified() + .toString("yyyy/MM/dd hh:mm:ss"), Qt::MatchExactly, 1)[0]; + delete item; } -void MainWindow::pushScreenshots() // this routine copies screenshots to the respective folders and manipulates a string list copy of the VDF. VDF is not written +void MainWindow::prepareScreenshots(int addedLines) { - QString path = userDataDir + "/" + selectedUserID + "/remote/" + selectedGameID + "/screenshots/thumbnails"; - if ( !QDir().exists(path) ) - QDir().mkpath(path); - - QRegularExpression re("^\t\"" + selectedGameID + "\"$"); // calculate a location for inserting new screenshot metadata - int header = lines.indexOf(re, 0); + if ( addedLines > 0 ) { - int opening, closing; + QMessageBox msgBox(this); + msgBox.setIcon(QMessageBox::Warning); - if ( header == -1 ) { + QString text = "Steam has to be quitted."; + QString info = "This program only works when Steam exited. It will not try to determine if Steam is running or not, so you should be sure it is quitted. " + + QString("If it is not, it is safe to exit Steam now.

Is Steam exited now?"); + msgBox.setText(text); + msgBox.setInformativeText(info); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); - QList headers; + QGridLayout* layout = (QGridLayout*)msgBox.layout(); // hack to make wide message boxes + layout->addItem(new QSpacerItem(500, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), layout->rowCount(), 0, 1, layout->columnCount()); - int pos = 0; - re.setPattern("^\t\"[0-9]+\"$"); - while ( lines.indexOf(re, pos) != -1 ) { - pos = lines.indexOf(re, pos + 1); - if ( pos == -1 ) - break; - QString h = lines[pos].section('"', 1, -2); - headers.append(h.toInt()); - }; + int ret = msgBox.exec(); - int before = -1; + if ( ret == QMessageBox::Yes ) { - if ( !headers.isEmpty() ) { + toggleLabelInfo(false); + setLabelsText(QStringList() << "labelInfoScreenshots" << "labelInfoDirectories", "0"); + emit clearScreenshotPathsPool(); - bool unorderedHeaders = false; + ui->pushButtonPrepare->setDisabled(true); - for ( int i = 0; i < headers.length() - 1; i++ ) { - if (headers[i] > headers[i + 1]) - unorderedHeaders = true; - }; + emit writeVDF(); - if ( !unorderedHeaders ) { // proceed only if all headers in the VDF are ordered, e.g. game ID 1000 is before 2000 - QListIterator i(headers); - while ( i.hasNext() ) { - int current = i.next(); - if ( selectedGameID.toInt() < current) { - before = current; - break; - }; - }; - }; + QMessageBox msgBox(this); + msgBox.setIcon(QMessageBox::Information); + msgBox.setText("SteaScree has updated the VDF-file."); + msgBox.setInformativeText("Now you can start Steam as usual and upload screenshots to the Steam Cloud."); + msgBox.exec(); }; - int insertPos; - if ( before != -1 ) { - QRegularExpression re("^\t\"" + QString::number(before) + "\"$"); - insertPos = lines.indexOf(re, 0); - } else - insertPos = lines.indexOf("\t\"shortcutnames\""); + } else { - lines.insert(insertPos, "\t}"); - lines.insert(insertPos, "\t{"); - lines.insert(insertPos, "\t\"" + selectedGameID +"\""); - header = insertPos; - opening = insertPos + 1; - closing = insertPos + 2; + QMessageBox msgBox(this); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setText("All screenshots from the upload queue are already in the screenshots.vdf file."); + msgBox.setInformativeText("Nothing has been added. Please add new screenshots and try again."); + msgBox.exec(); + toggleLabelInfo(false); + ui->pushButtonPrepare->setDisabled(true); }; - if ( lines[header + 1] == "\t{" ) { - - opening = header + 1; - closing = lines.indexOf("\t}", opening); - - if ( (header != -1) & (opening != -1) & (closing != -1) ) { - - int lastEntryPos = -1; - int lastEntryValue; - - if ( closing - opening != 1 ) { - QRegularExpression re("^\t\t\"[0-9]+\"$"); - lastEntryPos = lines.lastIndexOf(re, closing); - } else - lastEntryValue = -1; - - if ( lastEntryPos == -1 ) - lastEntryValue = -1; - - if ( lastEntryValue != -1 ) - lastEntryValue = lines[lastEntryPos].section('"', 1, -2).toInt(); - - QString copyDest = userDataDir + "/" + selectedUserID + "/remote/" + selectedGameID + "/screenshots/"; - - if ( !copiedGames.contains(selectedGameID) ) - ui->labelInfoDirectories->setText(QString::number(++copiedDirsToNum)); - - nothingAddedToVDF = true; - - // routine to detect timestamp overlapping - QMap repeatingTimestamps; - QList screenshotPool; - { - QListIterator i(screenshotPathsPool); - while ( i.hasNext() ) { - - QString path = i.next(); - QString timestamp = QFileInfo(QFile(path)).lastModified().toString("yyyyMMddhhmmss"); - QString filename; - int inc = 1; - - for ( int j = screenshotPathsPool.indexOf(path); j < screenshotPathsPool.length(); ++j ) { - - QString comparedTimestamp = QFileInfo(QFile(screenshotPathsPool[j])).lastModified().toString("yyyyMMddhhmmss"); - - if ( timestamp == comparedTimestamp ) { - - - if ( !repeatingTimestamps.contains(timestamp) ) - repeatingTimestamps[timestamp] = 0; - else - ++repeatingTimestamps[timestamp]; // if timestamp is non-unique for this set, increment the int in the end of a filename - - inc = repeatingTimestamps[timestamp] + 1; - - break; - }; - }; - - filename = timestamp + "_" + QString::number(inc) + ".jpg"; - screenshotPool << ( QStringList() << path << filename ); - }; - } - - QListIterator i(screenshotPool); // when insertion location is determined, proceed to the insertion and file conversion/copying - while ( i.hasNext() ) { - - QStringList current = i.next(); - QString path = current[0]; - QString filename = current[1]; - - // files - QImage screenshot(path); - QFile file(path); - QString extension = path.section('.', -1).toLower(); - - if ( !(QFile(copyDest + filename + "_1.jpg").exists()) ) { - - if ( (extension == "jpg") | (extension == "jpeg") ) - file.copy(copyDest + filename); - else - screenshot.save(copyDest + filename, "jpg", 95); - - ui->labelInfoScreenshots->setText(QString::number(++copiedScreenshotsNum)); - - }; - - - int width = QImage(screenshot).size().width(); - int heigth = QImage(screenshot).size().height(); - - int tnWidth = 200; - int tnHeigth = (tnWidth * heigth) / width; - - screenshot.scaled(QSize(tnWidth, tnHeigth), Qt::IgnoreAspectRatio).save(copyDest + "/thumbnails/" + - filename, "jpg", 95); - QDateTime lm = QFileInfo(file).lastModified(); - qint64 epoch = lm.toMSecsSinceEpoch(); - QString creation = QString::number(epoch/1000); - - - // vdf - if ( lines.mid(opening, closing - opening ) - .contains("\t\t\t\"filename\"\t\t\"" + selectedGameID + "/screenshots/" + filename + "\"") ) - continue; - - lines.insert(closing++, "\t\t\"" + QString::number(++lastEntryValue) + "\""); - lines.insert(closing++, "\t\t{"); - lines.insert(closing++, "\t\t\t\"type\"\t\t\"1\""); - lines.insert(closing++, "\t\t\t\"filename\"\t\t\"" + selectedGameID + "/screenshots/" + filename + "\""); - lines.insert(closing++, "\t\t\t\"thumbnail\"\t\t\"" + selectedGameID + "/screenshots/thumbnails/" + filename + "\""); - lines.insert(closing++, "\t\t\t\"vrfilename\"\t\t\"\""); - lines.insert(closing++, "\t\t\t\"imported\"\t\t\"0\""); - lines.insert(closing++, "\t\t\t\"width\"\t\t\"" + QString::number(width) + "\""); - lines.insert(closing++, "\t\t\t\"heigth\"\t\t\"" + QString::number(heigth) + "\""); - lines.insert(closing++, "\t\t\t\"gameid\"\t\t\"" + selectedGameID + "\""); - lines.insert(closing++, "\t\t\t\"creation\"\t\t\"" + creation + "\""); - lines.insert(closing++, "\t\t\t\"caption\"\t\t\"\""); - lines.insert(closing++, "\t\t\t\"Permissions\"\t\t\"\""); - lines.insert(closing++, "\t\t\t\"hscreenshot\"\t\t\"\""); - lines.insert(closing++, "\t\t}"); - - ui->progressBarScreenshotsUploading->setValue(screenshotPathsPool.indexOf(path)); - - QTreeWidgetItem *item = ui->treeWidgetScreenshotList->findItems(QFileInfo(file).lastModified() - .toString("yyyy/MM/dd hh:mm:ss"), Qt::MatchExactly, 1)[0]; - delete item; - - if ( !copiedGames.contains(selectedGameID) ) - copiedGames << selectedGameID; - - nothingAddedToVDF = false; - - QCoreApplication::processEvents(); - - }; - }; - }; + emit clearCopyingStatusLabels(); } void MainWindow::on_pushButtonLocateSteamDir_clicked() { - QString steamDirLocated = QFileDialog::getExistingDirectory(this, - "Locate Steam directory", - steamDir, - QFileDialog::ShowDirsOnly | QFileDialog::ReadOnly); - if ( !steamDirLocated.isEmpty() ) { - - steamDirLocated.remove(QRegularExpression("/userdata$")); - userDataDir = steamDirLocated + "/userdata"; - setUserDataPaths(steamDirLocated); - - }; + emit getSteamDir(); } void MainWindow::on_pushButtonAddScreenshots_clicked() { - QStringList screenshotsSelected = QFileDialog::getOpenFileNames(this, - "Select one or more screenshots", - lastSelectedScreenshotDir, - "Images (*.jpg *.jpeg *.png *.bmp *.tif *.tiff)"); - QListIterator i(screenshotsSelected); - while ( i.hasNext() ) { - QString current = i.next(); - if ( screenshotPathsPool.contains(current) ) - screenshotsSelected.removeOne(current); // copies are removed from the list - }; - - if ( !screenshotsSelected.isEmpty() ) { - - lastSelectedScreenshotDir = screenshotsSelected.last().section('/', 0, -2); - - populateScreenshotQueue(screenshotsSelected); - - screenshotPathsPool << screenshotsSelected; - ui->pushButtonClearQueue->setDisabled(false); - ui->pushButtonCopyScreenshots->setDisabled(false); - - }; + emit pushButtonAddScreenshots_clicked(); } void MainWindow::on_pushButtonClearQueue_clicked() { ui->treeWidgetScreenshotList->clear(); - screenshotPathsPool.clear(); - ui->pushButtonClearQueue->setDisabled(true); - ui->pushButtonCopyScreenshots->setDisabled(true); - ui->labelUserID->setDisabled(false); - ui->comboBoxGameID->setDisabled(false); - ui->labelGameID->setDisabled(false); - ui->comboBoxUserID->setDisabled(false); - ui->pushButtonLocateSteamDir->setDisabled(false); + + setWidgetsDisabled(QStringList() << "pushButtonClearQueue" << "pushButtonCopyScreenshots", true); + + setWidgetsDisabled(QStringList() << "labelUserID" << "comboBoxGameID" << "labelGameID" + << "comboBoxUserID" << "pushButtonLocateSteamDir", false); + + emit clearScreenshotPathsPool(); } void MainWindow::on_pushButtonCopyScreenshots_clicked() { - selectedUserID = ui->comboBoxUserID->currentText(); - selectedGameID = ui->comboBoxGameID->currentText(); + QString selectedUserID = ui->comboBoxUserID->currentText(); + QString selectedGameID = ui->comboBoxGameID->currentText(); QRegularExpression re("^[0-9]+( <.+>)?$"); @@ -701,95 +331,37 @@ void MainWindow::on_pushButtonCopyScreenshots_clicked() ui->labelStatusError->clear(); - selectedGameID = selectedGameID.remove(QRegularExpression(" <.+>$")); // it's possible to enter game ID by hand or left what was auto-generated (with <...>) - - if ( screenshotPathsPool.length() >= 10 ) { - - ui->progressBarScreenshotsUploading->setVisible(true); - ui->progressBarScreenshotsUploading->setMinimum(0); - ui->progressBarScreenshotsUploading->setMaximum(screenshotPathsPool.length()); - - }; - - ui->pushButtonClearQueue->setDisabled(true); - ui->pushButtonAddScreenshots->setDisabled(true); - ui->pushButtonCopyScreenshots->setDisabled(true); - + emit getScreenshotPathsPoolLength(); + setWidgetsDisabled( QStringList() << "pushButtonClearQueue" << "pushButtonAddScreenshots" << "pushButtonCopyScreenshots", true ); toggleLabelInfo(true); - - if ( lines.isEmpty() ) - lines = readVDF(); - - pushScreenshots(); - - ui->progressBarScreenshotsUploading->setVisible(false); - ui->pushButtonAddScreenshots->setDisabled(false); + emit pushScreenshots(selectedUserID, selectedGameID); + setWidgetsDisabled( QStringList() << "pushButtonAddScreenshots" << "pushButtonPrepare", false); ui->pushButtonLocateSteamDir->setDisabled(true); + ui->progressBarScreenshotsUploading->setVisible(false); ui->progressBarScreenshotsUploading->reset(); ui->treeWidgetScreenshotList->clear(); - screenshotPathsPool.clear(); - - ui->pushButtonPrepare->setDisabled(false); - + emit clearScreenshotPathsPool(); }; } void MainWindow::on_pushButtonPrepare_clicked() -{ - if ( !nothingAddedToVDF ) { - - QMessageBox msgBox(this); - msgBox.setIcon(QMessageBox::Warning); - - QString text = "Steam has to be quitted."; - QString info = "This program only works when Steam exited. It will not try to determine if Steam is running or not, so you should be sure it is quitted. " + - QString("If it is not, it is safe to exit Steam now.

Is Steam exited now?"); - msgBox.setText(text); - msgBox.setInformativeText(info); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - - QGridLayout* layout = (QGridLayout*)msgBox.layout(); // hack to make wide message boxes - layout->addItem(new QSpacerItem(500, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), layout->rowCount(), 0, 1, layout->columnCount()); - - int ret = msgBox.exec(); - - if ( ret == QMessageBox::Yes ) { - - toggleLabelInfo(false); - ui->labelInfoScreenshots->setText("0"); - ui->labelInfoDirectories->setText("0"); - copiedScreenshotsNum = 0; - copiedDirsToNum = 0; - screenshotPathsPool.clear(); - ui->pushButtonPrepare->setDisabled(true); - - QString vdfPath = userDataDir + "/" + selectedUserID + "/" + vdfFilename; - QFile(vdfPath).copy(vdfPath + ".bak"); // backup VDF just in case - - writeVDF(lines); - - QMessageBox msgBox(this); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("SteaScree has updated the VDF-file."); - msgBox.setInformativeText("Now you can start Steam as usual and upload screenshots to the Steam Cloud."); - msgBox.exec(); - - }; +{ + emit pushButtonPrepare_clicked(); +} - } else { - QMessageBox msgBox(this); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setText("All screenshots from the upload queue are already in the screenshots.vdf file."); - msgBox.setInformativeText("Nothing has been added. Please add new screenshots and try again."); - msgBox.exec(); +void MainWindow::showEvent(QShowEvent *event) // hack to show message boxes only after the main window is shown +{ + QMainWindow::showEvent(event); + QTimer::singleShot(50, this, SLOT(checkVDF())); +} - toggleLabelInfo(false); - copiedScreenshotsNum = 0; - copiedDirsToNum = 0; - ui->pushButtonPrepare->setDisabled(true); - }; +void MainWindow::closeEvent(QCloseEvent *event) +{ + emit sendSettings(size(), pos(), + ui->comboBoxUserID->currentText(), + ui->comboBoxGameID->currentText().remove(QRegularExpression(" <.+>$"))); + event->accept(); } diff --git a/mainwindow.h b/mainwindow.h index d244103..f9e478d 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -2,8 +2,7 @@ #define MAINWINDOW_H #include -#include -#include +#include namespace Ui { @@ -15,10 +14,10 @@ class MainWindow : public QMainWindow { Q_OBJECT - public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); + void bootStrap(); protected: @@ -26,64 +25,60 @@ class MainWindow : public QMainWindow void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; +private: + Ui::MainWindow *ui; + void toggleLabelInfo(bool isVisible); + + +signals: + void getOS(); + void pushButtonAddScreenshots_clicked(); + void pushButtonPrepare_clicked(); + void clearScreenshotPathsPool(); + void getScreenshotPathsPoolLength(); + void pushScreenshots(QString selectedUserID, QString selectedGameID); + void getSteamDir(); + void setUserDataPaths(QString steamDir); + void clearCopyingStatusLabels(); + void writeVDF(); + void getVDFStatus(); + void sendSettings(QSize size, QPoint pos, QString userID, QString gameID); + void sendComboBoxUserIDCurrentText(QString text); + void sendScreenshotsSelected(QStringList screenshotsSelected); + + +public slots: + void setButtonPadding(QString os); + void addWidgetItemToScreenshotList(QTreeWidgetItem *item); + void resizeScreenshotListColumns(); + void setWidgetsDisabled(QStringList list, bool disable); + void setVisibleProgressBar(int length); + void locateSteamDir(QString steamDir); + void prepareScreenshots(int addedLines); + void warnOnMissingVDF(bool userDataExists, QString vdfFilename); + void moveWindow(QSize geometry, QPoint moveToPoint); + void setLabelStatusErrorVisible(bool visible); + void setComboBoxesCleared(QStringList list); + void insertIntoComboBox(QString name, QStringList items); + void setIndexOfComboBoxUserID(QString item); + void setLabelsOnMissingStuff(bool userDataMissing, QString vdfFilename); + void returnComboBoxUserIDCurrentText(); + void returnScreenshotsSelected(QString lastSelectedScreenshotDir); + void setProgressBarValue(int value); + void deleteCopiedWidgetItem(QString path); + void setIndexOfComboBoxGameID(QString lastSelectedGameID); + void setLabelsText(QStringList list, QString text); + + private slots: - void warnOnMissingVDF(); - void getGameNames(QNetworkReply *reply); - void on_pushButtonLocateSteamDir_clicked(); void on_pushButtonAddScreenshots_clicked(); void on_pushButtonClearQueue_clicked(); void on_pushButtonCopyScreenshots_clicked(); void on_pushButtonPrepare_clicked(); + void on_pushButtonLocateSteamDir_clicked(); + void checkVDF(); -signals: - void vdfIsMissing(); - - -private: - Ui::MainWindow *ui; - void setUserDataPaths(QString dir); - void writeSettings(); - void readSettings(); - void populateScreenshotQueue(QStringList screenshotPathsList); - void disableAllOnMissingSteamDir(); - void pushScreenshots(); - void toggleLabelInfo(bool isVisible); - QString convertSlashes(QString str); - QStringList readVDF(); - void writeVDF(QStringList lines); - - #if defined(Q_OS_WIN32) - const QString os = "Windows"; - #elif defined(Q_OS_LINUX) - const QString os = "Linux"; - #elif defined(Q_OS_OSX) - const QString os = "macOS"; - #endif - - bool isUnixLikeOS; - bool isFirstStart; - const QString vdfFilename = "screenshots.vdf"; - QString selectedUserID; - QString userDataDir; - QString defaultSteamDir; - QSettings *settings; - QString steamDir; - QStringList vdfPaths; - QString userID; - QString someID; - QStringList gameIDs; - QHash games; - QStringList screenshotPathsPool; - QStringList lines; - QString selectedGameID; - QString lastSelectedScreenshotDir; - QString lastSelectedUserID; - QString lastSelectedGameID; - QStringList copiedGames; - bool nothingAddedToVDF = true; - int copiedScreenshotsNum = 0; - int copiedDirsToNum = 0; }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 4bf73a4..2724610 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -12,7 +12,7 @@ - 720 + 685 450 @@ -29,11 +29,8 @@ - - - - true - + + 0 @@ -41,138 +38,247 @@ - Screenshot queue + IDs - - - - - - - + + + + + + + 0 0 + + + 0 + 0 + + + + + + + QFrame::StyledPanel + + + QFrame::Sunken + + + not found + + + Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft + + + + + + + + 0 + 0 + + - Clear queue + Locate... - + Qt::Horizontal - QSizePolicy::Minimum + QSizePolicy::MinimumExpanding - 40 + 0 20 + + + + - + + + false + 0 0 - - Copy screenshots to game directory + + + 100 + 0 + + + + true + + + QComboBox::AdjustToContents - + Qt::Horizontal - QSizePolicy::Minimum + QSizePolicy::MinimumExpanding - 40 + 0 20 - - + + + + + + + + false + 0 0 - - Add screenshots to queue... + + + 100 + 0 + + + + Qt::LeftToRight + + + false + + + QComboBox::AdjustToContents + + + + Qt::Horizontal + + + QSizePolicy::MinimumExpanding + + + + 0 + 20 + + + + - + + + + 0 + 0 + + + + Steam userdata directory: + + + + + - true + false - + 0 0 - - - PreferDefault - + + + 96 + 0 + + + + + 96 + 16777215 + Qt::LeftToRight - + + Game ID: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + false - - QAbstractScrollArea::AdjustIgnored + + + 0 + 0 + - - QAbstractItemView::DropOnly + + + 96 + 0 + - - false + + + 96 + 16777215 + - - true + + Qt::LeftToRight + + + User ID: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - true - - - - Filename - - - - - Taken at - - - - - Directory - - @@ -180,106 +286,41 @@ - - + + - + Qt::Horizontal - - QSizePolicy::Minimum - - 40 - 20 + 0 + 0 - + - + 0 0 + + color: #bb3c2f; + - Prepare screenshots for uploading... + Error text. - - - Qt::Horizontal - - - QSizePolicy::Minimum - - - - 40 - 20 - - - - - - - - - - Qt::Horizontal - - - QSizePolicy::MinimumExpanding - - - - 0 - 0 - - - - - - - - - - Qt::Horizontal - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - color: #bb3c2f; - - - Error text. - - - - - - - true + + + true @@ -445,24 +486,11 @@ - - - - Qt::Vertical - - - QSizePolicy::Preferred - - - - 20 - 20 - + + + + true - - - - 0 @@ -470,127 +498,15 @@ - IDs + Screenshot queue - - - - - - - - 0 - 0 - - - - Steam userdata directory: - - - - - - - false - - - - 0 - 0 - - - - - 96 - 0 - - - - - 96 - 16777215 - - - - Qt::LeftToRight - - - Game ID: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - + + + - - - false - - - - 0 - 0 - - - - - 96 - 0 - - - - - 96 - 16777215 - - - - Qt::LeftToRight - - - User ID: - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - - - QFrame::StyledPanel - - - QFrame::Sunken - - - not found - - - Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft - - - - - + + + 0 @@ -598,15 +514,18 @@ - Locate... + Clear queue - + Qt::Horizontal + + QSizePolicy::Minimum + 1 @@ -615,43 +534,30 @@ - - - - - - - false - + 0 0 - - - 100 - 0 - + + - - Qt::LeftToRight - - - false - - - QComboBox::AdjustToContents + + Copy screenshots to game directory - + Qt::Horizontal + + QSizePolicy::Minimum + 1 @@ -660,55 +566,148 @@ - - - - - - - - false - + + 0 0 - - - 100 - 0 - - - - true - - - QComboBox::AdjustToContents + + Add screenshots to queue... - - - - Qt::Horizontal - - - - 1 - 20 - - - - + + + + true + + + + 0 + 0 + + + + + PreferDefault + + + + Qt::LeftToRight + + + false + + + QAbstractScrollArea::AdjustIgnored + + + QAbstractItemView::DropOnly + + + false + + + true + + + true + + + + Filename + + + + + Taken at + + + + + Directory + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + + + Prepare screenshots for uploading... + + + + + + + Qt::Horizontal + + + QSizePolicy::Minimum + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 16777215 + 0 + + + + diff --git a/model.cpp b/model.cpp new file mode 100644 index 0000000..15c0f3a --- /dev/null +++ b/model.cpp @@ -0,0 +1,627 @@ +#include "model.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +Model::Model(QObject *parent) : QObject(parent) +{ +} + + +void Model::bootStrap() +{ + if ( (os == "Linux") | (os == "macOS") ) { + isUnixLikeOS = true; + if ( os == "Linux" ) { + settings = new QSettings(QSettings::NativeFormat, QSettings::UserScope, "Foyl", "SteaScree"); + defaultSteamDir = QDir::homePath() + "/.steam/steam"; + } else { + settings = new QSettings(QSettings::NativeFormat, QSettings::UserScope, "foyl.io", "SteaScree"); + defaultSteamDir = QDir::homePath() + "/Library/Application Support/Steam"; + }; + } else { + isUnixLikeOS = false; + settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "Foyl", "SteaScree"); + if ( QSysInfo::currentCpuArchitecture() == "x86_64" ) + defaultSteamDir = "C:/Program Files (x86)/Steam"; + else + defaultSteamDir = "C:/Program Files/Steam"; + }; + + readSettings(); // read settings from the file, if any + + if ( !screenshotPathsPool.isEmpty() ) { + populateScreenshotQueue(screenshotPathsPool); + emit disableWidgets(QStringList() << "pushButtonClearQueue" << "pushButtonCopyScreenshots", false); + }; + + if ( !steamDir.isNull() ) { + userDataDir = steamDir + "/userdata"; + setUserDataPaths(steamDir); + }; +} + + +void Model::readSettings() +{ + settings->beginGroup("Main"); + isFirstStart = settings->value("FirstStart", true).toBool(); + settings->endGroup(); + + settings->beginGroup("WindowGeometry"); + QRect rec = QApplication::desktop()->availableGeometry(); + QSize geometry = settings->value("Size", QSize(685, 450)).toSize(); + QPoint moveToPoint = settings->value("Position", QPoint((rec.width()-800)/2, (rec.height()-800)/2)).toPoint(); + emit moveWindow(geometry, moveToPoint); + settings->endGroup(); + + settings->beginGroup("LastSelection"); + steamDir = settings->value("SteamDir", defaultSteamDir).toString(); + if ( QDir(steamDir).exists() ) + emit sendLabelsText(QStringList() << "labelSteamDirValue", convertSlashes(steamDir)); + else + emit sendLabelsText(QStringList() << "labelSteamDirValue", "Not found, please locate manually"); + lastSelectedScreenshotDir = settings->value("Screenshots", QDir::currentPath()).toString(); + lastSelectedUserID = settings->value("UserID").toString(); + lastSelectedGameID = settings->value("GameID").toString(); + settings->endGroup(); + + settings->beginGroup("Screenshots"); + screenshotPathsPool = settings->value("Queue").toStringList(); + settings->endGroup(); +} + + +void Model::writeSettings(QSize size, QPoint pos, QString userID, QString gameID) +{ + settings->beginGroup("Main"); + settings->setValue("FirstStart", isFirstStart); + settings->endGroup(); + + settings->beginGroup("WindowGeometry"); + settings->setValue("Size", size); + settings->setValue("Position", pos); + settings->endGroup(); + + settings->beginGroup("LastSelection"); + settings->setValue("SteamDir", steamDir.replace("\\", "/")); + settings->setValue("Screenshots", lastSelectedScreenshotDir.replace("\\", "/")); + if ( !userID.isEmpty() ) + settings->setValue("UserID", userID); + if ( !gameID.isEmpty() ) + settings->setValue("GameID", gameID); + settings->endGroup(); + + settings->beginGroup("Screenshots"); + settings->setValue("Queue", screenshotPathsPool); + settings->endGroup(); +} + + +void Model::setUserDataPaths(QString dir) // function to validate and set data paths and IDs +{ + userDataDir = dir + "/userdata"; + QStringList userIDsCombined; + + vdfPaths.clear(); // there may be multiple Steam installations in the system and thus multiple VDFs + userID.clear(); + someID.clear(); + gameIDs.clear(); + + emit clearWidgets( QStringList() << "comboBoxUserID" << "comboBoxGameID"); + + QStringList widgetList; + widgetList << "labelUserID" << "comboBoxUserID" << "labelGameID" << "comboBoxGameID" << "groupBoxScreenshotQueue"; + + emit disableWidgets(widgetList, true); + + if ( QDir(dir + "/userdata").exists() ) { + + QDirIterator i(userDataDir, QStringList() << vdfFilename, QDir::Files, QDirIterator::Subdirectories); + while ( i.hasNext() ) { + vdfPaths << i.next(); + }; + + if ( !vdfPaths.isEmpty() ) { + + emit disableWidgets(widgetList << "groupBoxScreenshotQueue" << "treeWidgetScreenshotList", false); + emit sendLabelsText(QStringList() << "labelSteamDirValue", convertSlashes(dir)); + emit setLabelStatusErrorVisible(false); + + steamDir = dir; + + QListIterator i(vdfPaths); + while ( i.hasNext() ) { + QString current = i.next(); + QStringList splitted = current.split('/'); + userID = splitted.takeAt(splitted.length() - 3); + someID = splitted.takeAt(splitted.length() - 2); + userIDsCombined << userID + "/" + someID; + }; + + QStringList items; + if ( isUnixLikeOS ) + items = userIDsCombined; + else + items = userIDsCombined.replaceInStrings("/", "\\"); + emit sendToComboBox("comboBoxUserID", items); + + if ( !isFirstStart ) + emit setIndexOfComboBoxUserID(lastSelectedUserID); + + isFirstStart = false; + + emit sendToComboBox("comboBoxGameID", QStringList() << "loading..."); + + QNetworkAccessManager *nam = new QNetworkAccessManager(this); + + QObject::connect(nam, &QNetworkAccessManager::finished, + this, &Model::getGameNames); + + nam->get(QNetworkRequest(QUrl("http://api.steampowered.com/ISteamApps/GetAppList/v2"))); + + } else + emit setLabelsOnMissingStuff(false, vdfFilename); + + } else + emit setLabelsOnMissingStuff(true, vdfFilename); +} + + +void Model::getGameNames(QNetworkReply *reply) +{ + if ( games.isEmpty() ) { + + if ( reply->error() == QNetworkReply::NoError ) { + + QByteArray raw = reply->readAll(); + QJsonDocument doc(QJsonDocument::fromJson(raw)); + QJsonArray apps = doc.object().value("applist").toObject().value("apps").toArray(); + + foreach (QJsonValue app, apps) { + QJsonObject obj = app.toObject(); + QString appID = QString::number(static_cast(obj.value("appid").toDouble())); + QString name = obj.value("name").toString(); + games[appID] = name; + }; + }; + + emit getComboBoxUserIDCurrentText(); + + QStringList lines = readVDF(); + int shortcutNamesHeaderPos = lines.indexOf("\t\"shortcutnames\""); // if there are any non-Steam games, get names for them too, from the VDF + int shortcutNamesEndPos = lines.indexOf("\t}", shortcutNamesHeaderPos); + QStringList shortcutNamesSection = lines.mid(shortcutNamesHeaderPos, shortcutNamesEndPos - shortcutNamesHeaderPos); + QRegularExpression re("^\t\t\"[0-9]+\"\t\t\".+\"$"); + + if ( shortcutNamesSection.indexOf(re) != -1 ) { + + int entryPos = 0; + + while ( (entryPos <= shortcutNamesSection.length() - 1) && (entryPos != -1) ) { + + entryPos = shortcutNamesSection.indexOf(re, entryPos + 1); + + if ( entryPos != -1 ) { + QString gameID = shortcutNamesSection[entryPos].section("\t\t", 1, 1).remove(QRegularExpression("(^\")|(\"$)")); + QString gameName = shortcutNamesSection[entryPos].section("\t\t", 2, 2).remove(QRegularExpression("(^\")|(\"$)")); + games[gameID] = gameName; + }; + }; + }; + }; + + QDirIterator i(userDataDir + "/" + userID + "/" + someID + "/remote", QDir::Dirs | QDir::NoDotAndDotDot); + while ( i.hasNext() ) { + + QString gameID = i.next().section('/', -1); + + if ( !games[gameID].isEmpty() ) + gameIDs << gameID + " <" + games[gameID] + ">"; + else + gameIDs << gameID; + + }; + + emit clearWidgets( QStringList() << "comboBoxGameID" ); + + if ( !gameIDs.isEmpty() ) + emit sendToComboBox("comboBoxGameID", gameIDs); + + if ( !lastSelectedGameID.isEmpty() ) + emit setIndexOfComboBoxGameID(lastSelectedGameID); + + emit disableWidgets( QStringList() << "pushButtonAddScreenshots", false); +} + + +void Model::populateScreenshotQueue(QStringList screenshotPathsList) // function to populate screenshot queue with entries +{ + if ( !screenshotPathsList.isEmpty() ) { + + QTreeWidgetItem *item = NULL; + QListIterator i(screenshotPathsList); + while ( i.hasNext() ) { + QString current = i.next(); + if ( QFile(current).exists() ) { + item = new QTreeWidgetItem; + item->setText(0, current.section('/', -1)); + item->setText(1, QFileInfo(QFile(current)).lastModified().toString("yyyy/MM/dd hh:mm:ss")); + QString path; + path = convertSlashes(current.section('/', 0, -2)); + item->setText(2, path); + emit addWidgetItemToScreenshotList(item); + } else + screenshotPathsPool.removeOne(current); + }; + + emit resizeScreenshotListColumns(); + }; +} + + +void Model::addScreenshotsToPool(QStringList screenshotsSelected) +{ + QListIterator i(screenshotsSelected); + while ( i.hasNext() ) { + + QString current = i.next(); + + if ( screenshotPathsPool.contains(current) ) + screenshotsSelected.removeOne(current); // copies are removed from the list + + }; + + if ( !screenshotsSelected.isEmpty() ) { + + lastSelectedScreenshotDir = screenshotsSelected.last().section('/', 0, -2); + populateScreenshotQueue(screenshotsSelected); + screenshotPathsPool << screenshotsSelected; + emit disableWidgets( QStringList() << "pushButtonClearQueue" << "pushButtonCopyScreenshots", false ); + }; +} + + +QStringList Model::readVDF() // read text from the VDF and return it in the form of list of strings for easy manipulating +{ + QFile vdf(userDataDir + "/" + selectedUserID + "/" + vdfFilename); + vdf.open(QIODevice::ReadOnly | QIODevice::Text); + QTextStream text(&vdf); + QStringList lines; + + while ( !text.atEnd() ) { + QString line = text.readLine(); + lines << line; + }; + + vdf.close(); + return lines; +} + + +void Model::writeVDF() // write to VDF from list of strings. previous contents are discarded +{ + QString vdfPath = userDataDir + "/" + selectedUserID + "/" + vdfFilename; + QFile(vdfPath).copy(vdfPath + ".bak"); // backup VDF just in case + + QFile vdf(vdfPath); + vdf.open(QIODevice::WriteOnly | QIODevice::Truncate); + QTextStream text(&vdf); + + QListIterator i(lines); + while ( i.hasNext() ) { + QString current = i.next(); + text << current + "\n"; + }; + + vdf.close(); +} + + +void Model::pushScreenshots(QString userID, QString gameID) // this routine copies screenshots to the respective folders and manipulates a string list copy of the VDF. VDF is not written +{ + selectedUserID = userID.replace("\\", "/"); + selectedGameID = gameID.remove(QRegularExpression(" <.+>$")); // it's possible to enter game ID by hand or left what was auto-generated (with <...>) + + if ( lines.isEmpty() ) + lines = readVDF(); + + QString path = userDataDir + "/" + selectedUserID + "/remote/" + selectedGameID + "/screenshots/thumbnails"; + if ( !QDir().exists(path) ) + QDir().mkpath(path); + + QRegularExpression re("^\t\"" + selectedGameID + "\"$"); // calculate a location for inserting new screenshot metadata + int header = lines.indexOf(re, 0); + + int opening, closing; + + if ( header == -1 ) { + + QList headers; + + int pos = 0; + re.setPattern("^\t\"[0-9]+\"$"); + while ( lines.indexOf(re, pos) != -1 ) { + pos = lines.indexOf(re, pos + 1); + if ( pos == -1 ) + break; + QString h = lines[pos].section('"', 1, -2); + headers.append(h.toInt()); + }; + + int before = -1; + + if ( !headers.isEmpty() ) { + + bool unorderedHeaders = false; + + for ( int i = 0; i < headers.length() - 1; i++ ) { + if (headers[i] > headers[i + 1]) + unorderedHeaders = true; + }; + + if ( !unorderedHeaders ) { // proceed only if all headers in the VDF are ordered, e.g. game ID 1000 is before 2000 + QListIterator i(headers); + while ( i.hasNext() ) { + int current = i.next(); + if ( selectedGameID.toInt() < current) { + before = current; + break; + }; + }; + }; + }; + + int insertPos; + if ( before != -1 ) { + QRegularExpression re("^\t\"" + QString::number(before) + "\"$"); + insertPos = lines.indexOf(re, 0); + } else + insertPos = lines.indexOf("\t\"shortcutnames\""); + + lines.insert(insertPos, "\t}"); + lines.insert(insertPos, "\t{"); + lines.insert(insertPos, "\t\"" + selectedGameID +"\""); + header = insertPos; + opening = insertPos + 1; + closing = insertPos + 2; + }; + + if ( lines[header + 1] == "\t{" ) { + + opening = header + 1; + closing = lines.indexOf("\t}", opening); + + if ( (header != -1) & (opening != -1) & (closing != -1) ) { + + int lastEntryPos = -1; + + if ( closing - opening != 1 ) { + QRegularExpression re("^\t\t\"[0-9]+\"$"); + lastEntryPos = lines.lastIndexOf(re, closing); + } else + lastEntryValue = -1; + + if ( lastEntryPos == -1 ) + lastEntryValue = -1; + + if ( lastEntryValue != -1 ) + lastEntryValue = lines[lastEntryPos].section('"', 1, -2).toInt(); + + QString copyDest = userDataDir + "/" + selectedUserID + "/remote/" + selectedGameID + "/screenshots/"; + + if ( !copiedGames.contains(selectedGameID) ) + emit sendLabelsText(QStringList() << "labelInfoDirectories", QString::number(++copiedDirsToNum)); + + // routine to detect timestamp overlapping + QMap repeatingTimestamps; + QList screenshotPool; + { + QListIterator i(screenshotPathsPool); + while ( i.hasNext() ) { + + QString path = i.next(); + QString timestamp = QFileInfo(QFile(path)).lastModified().toString("yyyyMMddhhmmss"); + QString filename; + int inc = 1; + + for ( int j = screenshotPathsPool.indexOf(path); j < screenshotPathsPool.length(); ++j ) { + + QString comparedTimestamp = QFileInfo(QFile(screenshotPathsPool[j])).lastModified().toString("yyyyMMddhhmmss"); + + if ( timestamp == comparedTimestamp ) { + + if ( !repeatingTimestamps.contains(timestamp) ) + repeatingTimestamps[timestamp] = 0; + else + ++repeatingTimestamps[timestamp]; // if timestamp is non-unique for this set, increment the int in the end of a filename + + inc = repeatingTimestamps[timestamp] + 1; + + break; + }; + }; + + filename = timestamp + "_" + QString::number(inc) + ".jpg"; + screenshotPool << ( QStringList() << path << filename ); + }; + } + + QListIterator i(screenshotPool); // when insertion location is determined, proceed to the insertion and file conversion/copying + while ( i.hasNext() ) { + + QStringList current = i.next(); + QString path = current[0]; + QString filename = current[1]; + + // files + QImage screenshot(path); + QFile file(path); + QString extension = path.section('.', -1).toLower(); + + if ( !(QFile(copyDest + filename).exists()) ) { + + if ( (extension == "jpg") | (extension == "jpeg") ) + file.copy(copyDest + filename); + else + screenshot.save(copyDest + filename, "jpg", 95); + + emit sendLabelsText(QStringList() << "labelInfoScreenshots", QString::number(++copiedScreenshotsNum)); + + }; + + int width = QImage(screenshot).size().width(); + int heigth = QImage(screenshot).size().height(); + + int tnWidth = 200; + int tnHeigth = (tnWidth * heigth) / width; + + screenshot.scaled(QSize(tnWidth, tnHeigth), Qt::IgnoreAspectRatio).save(copyDest + "/thumbnails/" + + filename, "jpg", 95); + QDateTime lm = QFileInfo(file).lastModified(); + qint64 epoch = lm.toMSecsSinceEpoch(); + QString creation = QString::number(epoch/1000); + + // vdf + if ( lines.mid(opening, closing - opening ) + .contains("\t\t\t\"filename\"\t\t\"" + selectedGameID + "/screenshots/" + filename + "\"") ) + continue; + + lines.insert(closing++, "\t\t\"" + QString::number(++lastEntryValue) + "\""); + lines.insert(closing++, "\t\t{"); + lines.insert(closing++, "\t\t\t\"type\"\t\t\"1\""); + lines.insert(closing++, "\t\t\t\"filename\"\t\t\"" + selectedGameID + "/screenshots/" + filename + "\""); + lines.insert(closing++, "\t\t\t\"thumbnail\"\t\t\"" + selectedGameID + "/screenshots/thumbnails/" + filename + "\""); + lines.insert(closing++, "\t\t\t\"vrfilename\"\t\t\"\""); + lines.insert(closing++, "\t\t\t\"imported\"\t\t\"0\""); + lines.insert(closing++, "\t\t\t\"width\"\t\t\"" + QString::number(width) + "\""); + lines.insert(closing++, "\t\t\t\"heigth\"\t\t\"" + QString::number(heigth) + "\""); + lines.insert(closing++, "\t\t\t\"gameid\"\t\t\"" + selectedGameID + "\""); + lines.insert(closing++, "\t\t\t\"creation\"\t\t\"" + creation + "\""); + lines.insert(closing++, "\t\t\t\"caption\"\t\t\"\""); + lines.insert(closing++, "\t\t\t\"Permissions\"\t\t\"\""); + lines.insert(closing++, "\t\t\t\"hscreenshot\"\t\t\"\""); + lines.insert(closing++, "\t\t}"); + + addedLines++; + + emit setProgressBarValue(screenshotPathsPool.indexOf(path)); + emit deleteCopiedWidgetItem(path); + + if ( !copiedGames.contains(selectedGameID) ) + copiedGames << selectedGameID; + + QCoreApplication::processEvents(); + }; + }; + }; +} + + +void Model::returnOS() +{ + emit sendOS(os); +} + + +void Model::removeEntryFromScreenshotPathsPool(QString entry) +{ + screenshotPathsPool.removeOne(entry); +} + + +void Model::setSelectedUserID(QString text) +{ + selectedUserID = text; +} + + +QString Model::convertSlashes(QString str) +{ + QString converted; + + if ( isUnixLikeOS ) + converted = str; + else + converted = str.replace("/", "\\"); + + return converted; +} + + +void Model::returnVDFStatus() +{ + if ( vdfPaths.isEmpty() ) + emit sendVDFStatus(QDir(steamDir + "/userdata").exists(), vdfFilename); +} + + +void Model::returnLinesState() +{ + emit sendLinesState(addedLines); +} + + +void Model::clearScreenshotPathsPool() +{ + screenshotPathsPool.clear(); +} + + +void Model::clearCopyingStatusLabels() +{ + copiedScreenshotsNum = 0; + copiedDirsToNum = 0; +} + + +void Model::returnLastSelectedScreenshotDir() +{ + emit sendLastSelectedScreenshotDir(lastSelectedScreenshotDir); +} + + +void Model::returnScreenshotPathPoolLength() +{ + if ( screenshotPathsPool.length() >= 10 ) + emit sendScreenshotPathPoolLength(screenshotPathsPool.length()); +} + + +void Model::returnSteamDir() +{ + emit sendSteamDir(steamDir); +} + + +void Model::setSelectedIDs(QString userID, QString gameID) +{ + selectedUserID = userID; + selectedGameID = gameID; +} + diff --git a/model.h b/model.h new file mode 100644 index 0000000..3c53135 --- /dev/null +++ b/model.h @@ -0,0 +1,105 @@ +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include +#include + +class Model : public QObject +{ + Q_OBJECT + +public: + explicit Model(QObject *parent = 0); + void bootStrap(); + + +private: + void readSettings(); + QString convertSlashes(QString str); + QStringList readVDF(); + void populateScreenshotQueue(QStringList screenshotPathsList); + + bool isUnixLikeOS; + bool isFirstStart; + const QString vdfFilename = "screenshots.vdf"; + QString selectedUserID; + QString selectedGameID; + QString userDataDir; + QString defaultSteamDir; + QSettings *settings; + QString steamDir; + QStringList vdfPaths; + QString userID; + QString someID; + QStringList gameIDs; + QHash games; + QStringList screenshotPathsPool; + QStringList lines; + QString lastSelectedScreenshotDir; + QString lastSelectedUserID; + QString lastSelectedGameID; + QStringList copiedGames; + int lastEntryValue; + int copiedScreenshotsNum = 0; + int copiedDirsToNum = 0; + int addedLines = 0; + + #if defined(Q_OS_WIN32) + const QString os = "Windows"; + #elif defined(Q_OS_LINUX) + const QString os = "Linux"; + #elif defined(Q_OS_OSX) + const QString os = "macOS"; + #endif + + +signals: + void sendOS(QString); + void addWidgetItemToScreenshotList(QTreeWidgetItem *item); + void resizeScreenshotListColumns(); + void sendScreenshotPathPoolLength(int length); + void sendSteamDir(QString steamDir); + void sendLinesState(bool isVDFEmpty); + void sendVDFStatus(bool userDataExists, QString vdfFilename); + void moveWindow(QSize geometry, QPoint moveToPoint); + void setLabelStatusErrorVisible(bool visible); + void disableWidgets(QStringList list, bool disable); + void clearWidgets(QStringList list); + void setLabelsOnMissingStuff(bool userDataMissing, QString vdfFilename); + void setIndexOfComboBoxUserID(QString item); + void getComboBoxUserIDCurrentText(); + void sendLastSelectedScreenshotDir(QString lastSelectedScreenshotDir); + void setProgressBarValue(int value); + void deleteCopiedWidgetItem(QString path); + void sendToComboBox(QString name, QStringList items); + void setIndexOfComboBoxGameID(QString lastSelectedGameID); + void sendLabelsText(QStringList list, QString text); + + +public slots: + void returnOS(); + void writeSettings(QSize size, QPoint pos, QString userID, QString gameID); + void removeEntryFromScreenshotPathsPool(QString entry); + void returnLastSelectedScreenshotDir(); + void clearScreenshotPathsPool(); + void returnScreenshotPathPoolLength(); + void pushScreenshots(QString userID, QString gameID); + void setUserDataPaths(QString dir); + void returnSteamDir(); + void writeVDF(); + void returnLinesState(); + void clearCopyingStatusLabels(); + void returnVDFStatus(); + void setSelectedUserID(QString text); + void addScreenshotsToPool(QStringList screenshotsSelected); + void setSelectedIDs(QString userID, QString gameID); + + +private slots: + void getGameNames(QNetworkReply *reply); + +}; + +#endif // MODEL_H