Some early work on classes.
This commit is contained in:
parent
401d7d747e
commit
9ddea11b6e
9 changed files with 698 additions and 0 deletions
|
@ -47,8 +47,16 @@ add_executable(wxMASSManager WIN32
|
|||
GUI/NameChangeDialog.cpp
|
||||
GUI/EvtNameChangeDialog.h
|
||||
GUI/EvtNameChangeDialog.cpp
|
||||
MassBuilderManager/MassBuilderManager.h
|
||||
MassBuilderManager/MassBuilderManager.cpp
|
||||
MassManager/MassManager.h
|
||||
MassManager/MassManager.cpp
|
||||
Profile/Profile.h
|
||||
Profile/Profile.cpp
|
||||
ProfileManager/ProfileManager.h
|
||||
ProfileManager/ProfileManager.cpp
|
||||
ScreenshotManager/ScreenshotManager.h
|
||||
ScreenshotManager/ScreenshotManager.cpp
|
||||
resource.rc)
|
||||
|
||||
target_compile_options(wxMASSManager PRIVATE -D_FILE_OFFSET_BITS=64 -D__WXMSW__ -fpermissive)
|
||||
|
|
87
MassBuilderManager/MassBuilderManager.cpp
Normal file
87
MassBuilderManager/MassBuilderManager.cpp
Normal file
|
@ -0,0 +1,87 @@
|
|||
// wxMASSManager
|
||||
// Copyright (C) 2020 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <shlobj.h>
|
||||
#include <wtsapi32.h>
|
||||
|
||||
#include <Corrade/Utility/Directory.h>
|
||||
#include <Corrade/Utility/Unicode.h>
|
||||
|
||||
#include "MassBuilderManager.h"
|
||||
|
||||
using namespace Corrade;
|
||||
|
||||
MassBuilderManager::MassBuilderManager() {
|
||||
_ready = findSaveDirectory();
|
||||
}
|
||||
|
||||
auto MassBuilderManager::ready() -> bool {
|
||||
return _ready;
|
||||
}
|
||||
|
||||
auto MassBuilderManager::lastError() -> std::string const& {
|
||||
return _lastError;
|
||||
}
|
||||
|
||||
auto MassBuilderManager::saveDirectory() -> std::string const& {
|
||||
return _saveDirectory;
|
||||
}
|
||||
|
||||
auto MassBuilderManager::checkGameState() -> GameState {
|
||||
WTS_PROCESS_INFOW* process_infos = nullptr;
|
||||
unsigned long process_count = 0;
|
||||
_gameState = GameState::Unknown;
|
||||
|
||||
if(WTSEnumerateProcessesW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &process_infos, &process_count)) {
|
||||
for(unsigned long i = 0; i < process_count; ++i) {
|
||||
if(std::wcscmp(process_infos[i].pProcessName, L"MASS_Builder-Win64-Shipping.exe") == 0) {
|
||||
_gameState = GameState::Running;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
_gameState = GameState::NotRunning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(process_infos != nullptr) {
|
||||
WTSFreeMemory(process_infos);
|
||||
process_infos = nullptr;
|
||||
}
|
||||
|
||||
return _gameState;
|
||||
}
|
||||
|
||||
auto MassBuilderManager::gameState() -> GameState {
|
||||
return _gameState;
|
||||
}
|
||||
|
||||
auto MassBuilderManager::findSaveDirectory() -> bool {
|
||||
wchar_t h[MAX_PATH];
|
||||
if(!SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, 0, h))) {
|
||||
_lastError = "SHGetFolderPathW() failed in MassBuilderManager::findSaveDirectory()";
|
||||
return false;
|
||||
}
|
||||
|
||||
_saveDirectory = Utility::Directory::join(Utility::Directory::fromNativeSeparators(Utility::Unicode::narrow(h)), "MASS_Builder");
|
||||
|
||||
if(!Utility::Directory::exists(_saveDirectory)) {
|
||||
_lastError = _saveDirectory + " wasn't found.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
52
MassBuilderManager/MassBuilderManager.h
Normal file
52
MassBuilderManager/MassBuilderManager.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef MASSBUILDERMANAGER_H
|
||||
#define MASSBUILDERMANAGER_H
|
||||
|
||||
// wxMASSManager
|
||||
// Copyright (C) 2020 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <string>
|
||||
|
||||
enum class GameState : std::uint8_t {
|
||||
Unknown, NotRunning, Running
|
||||
};
|
||||
|
||||
class MassBuilderManager {
|
||||
public:
|
||||
MassBuilderManager();
|
||||
|
||||
auto ready() -> bool;
|
||||
auto lastError() -> std::string const&;
|
||||
|
||||
auto saveDirectory() -> std::string const&;
|
||||
|
||||
auto checkGameState() -> GameState;
|
||||
auto gameState() -> GameState;
|
||||
|
||||
private:
|
||||
auto findSaveDirectory() -> bool;
|
||||
|
||||
bool _ready = false;
|
||||
|
||||
std::string _lastError = "";
|
||||
|
||||
std::string _saveDirectory = "";
|
||||
|
||||
GameState _gameState = GameState::Unknown;
|
||||
};
|
||||
|
||||
#endif //MASSBUILDERMANAGER_H
|
134
Profile/Profile.cpp
Normal file
134
Profile/Profile.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
// wxMASSManager
|
||||
// Copyright (C) 2020 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <Corrade/Containers/Array.h>
|
||||
#include <Corrade/Utility/Directory.h>
|
||||
#include <Corrade/Utility/String.h>
|
||||
|
||||
#include "Profile.h"
|
||||
|
||||
constexpr char company_name_locator[] = { 'C', 'o', 'm', 'p', 'a', 'n', 'y', 'N', 'a', 'm', 'e', '\0', 0x0C, '\0', '\0', '\0', 'S', 't', 'r', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', '\0' };
|
||||
|
||||
constexpr char active_slot_locator[] = { 'A', 'c', 't', 'i', 'v', 'e', 'F', 'r', 'a', 'm', 'e', 'S', 'l', 'o', 't', '\0', 0x0C, '\0', '\0', '\0', 'I', 'n', 't', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', '\0' };
|
||||
|
||||
constexpr char credits_locator[] = { 'C', 'r', 'e', 'd', 'i', 't', '\0', 0x0C, '\0', '\0', '\0', 'I', 'n', 't', 'P', 'r', 'o', 'p', 'e', 'r', 't', 'y', '\0' };
|
||||
|
||||
using namespace Corrade;
|
||||
|
||||
Profile::Profile(const std::string& path) {
|
||||
auto map = Utility::Directory::mapRead(path);
|
||||
|
||||
if(!map) {
|
||||
_lastError = "Couldn't memory-map " + Utility::Directory::filename(path);
|
||||
return;
|
||||
}
|
||||
|
||||
_profileDirectory = Utility::Directory::path(path);
|
||||
_filename = Utility::Directory::filename(path);
|
||||
|
||||
if(Utility::String::beginsWith(_filename, "Demo")) {
|
||||
_type = ProfileType::Demo;
|
||||
}
|
||||
else {
|
||||
_type = ProfileType::FullGame;
|
||||
}
|
||||
|
||||
_steamId = Utility::String::ltrim(Utility::String::rtrim(_filename, ".sav"), (_type == ProfileType::Demo ? "Demo" : "") + std::string{"Profile"});
|
||||
|
||||
auto it = std::search(map.begin(), map.end(), &company_name_locator[0], &company_name_locator[27]);
|
||||
|
||||
if(it == map.end()) {
|
||||
_lastError = "Couldn't find a company name in " + _filename;
|
||||
return;
|
||||
}
|
||||
|
||||
_companyName = std::string{it + 41};
|
||||
|
||||
_valid = true;
|
||||
}
|
||||
|
||||
auto Profile::valid() const -> bool {
|
||||
return _valid;
|
||||
}
|
||||
|
||||
auto Profile::lastError() const -> std::string const& {
|
||||
return _lastError;
|
||||
}
|
||||
|
||||
auto Profile::filename() const -> std::string const& {
|
||||
return _filename;
|
||||
}
|
||||
|
||||
auto Profile::type() const -> ProfileType {
|
||||
return _type;
|
||||
}
|
||||
|
||||
auto Profile::steamId() const -> std::string const& {
|
||||
return _steamId;
|
||||
}
|
||||
|
||||
auto Profile::companyName() const -> std::string const& {
|
||||
return _companyName;
|
||||
}
|
||||
|
||||
auto Profile::activeFrameSlot() const -> std::int8_t {
|
||||
return _activeFrameSlot;
|
||||
}
|
||||
|
||||
auto Profile::getActiveFrameSlot() -> std::int8_t {
|
||||
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
||||
|
||||
auto iter = std::search(mmap.begin(), mmap.end(), &active_slot_locator[0], &active_slot_locator[31]);
|
||||
|
||||
if(iter == mmap.end()) {
|
||||
if(std::search(mmap.begin(), mmap.end(), &credits_locator[0], &credits_locator[22]) != mmap.end()) {
|
||||
_activeFrameSlot = 0;
|
||||
}
|
||||
else {
|
||||
_lastError = "The profile save seems to be corrupted or the game didn't release the handle on the file.";
|
||||
_activeFrameSlot = -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_activeFrameSlot = *(iter + 41);
|
||||
}
|
||||
|
||||
return _activeFrameSlot;
|
||||
}
|
||||
|
||||
auto Profile::credits() const -> std::int32_t {
|
||||
return _credits;
|
||||
}
|
||||
|
||||
auto Profile::getCredits() -> std::int32_t {
|
||||
auto mmap = Utility::Directory::mapRead(Utility::Directory::join(_profileDirectory, _filename));
|
||||
|
||||
auto iter = std::search(mmap.begin(), mmap.end(), &credits_locator[0], &credits_locator[22]);
|
||||
|
||||
if(iter != mmap.end()) {
|
||||
_credits = ((*(iter + 0x20)) << 0) +
|
||||
((*(iter + 0x21)) << 8) +
|
||||
((*(iter + 0x22)) << 16) +
|
||||
((*(iter + 0x23)) << 24);
|
||||
}
|
||||
else{
|
||||
_credits = -1;
|
||||
}
|
||||
|
||||
return _credits;
|
||||
}
|
53
Profile/Profile.h
Normal file
53
Profile/Profile.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef PROFILE_H
|
||||
#define PROFILE_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include <string>
|
||||
|
||||
enum class ProfileType : std::uint8_t {
|
||||
Demo,
|
||||
FullGame
|
||||
};
|
||||
|
||||
class Profile {
|
||||
public:
|
||||
explicit Profile(const std::string& path);
|
||||
|
||||
auto valid() const -> bool;
|
||||
|
||||
auto lastError() const -> std::string const&;
|
||||
|
||||
auto filename() const -> std::string const&;
|
||||
|
||||
auto type() const -> ProfileType;
|
||||
|
||||
auto steamId() const -> std::string const&;
|
||||
|
||||
auto companyName() const -> std::string const&;
|
||||
|
||||
auto activeFrameSlot() const -> std::int8_t;
|
||||
auto getActiveFrameSlot() -> std::int8_t;
|
||||
|
||||
auto credits() const -> std::int32_t;
|
||||
auto getCredits() -> std::int32_t;
|
||||
|
||||
private:
|
||||
std::string _profileDirectory;
|
||||
std::string _filename;
|
||||
|
||||
ProfileType _type;
|
||||
|
||||
std::string _steamId;
|
||||
|
||||
bool _valid = false;
|
||||
std::string _lastError = "";
|
||||
|
||||
std::string _companyName;
|
||||
|
||||
std::int8_t _activeFrameSlot = 0;
|
||||
|
||||
std::int32_t _credits;
|
||||
};
|
||||
|
||||
#endif //PROFILE_H
|
100
ProfileManager/ProfileManager.cpp
Normal file
100
ProfileManager/ProfileManager.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
// wxMASSManager
|
||||
// Copyright (C) 2020 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <algorithm>
|
||||
#include <regex>
|
||||
|
||||
#include <Corrade/Utility/Directory.h>
|
||||
#include <Corrade/Utility/String.h>
|
||||
|
||||
#include "ProfileManager.h"
|
||||
|
||||
using namespace Corrade;
|
||||
|
||||
ProfileManager::ProfileManager(const std::string& base_path) {
|
||||
_profileDirectory = Utility::Directory::join(base_path, "Saved/SaveGames");
|
||||
|
||||
if(Utility::Directory::exists(_profileDirectory) == false) {
|
||||
_lastError = "Couldn't find the profile directory. Make sure you played enough of the game.";
|
||||
return;
|
||||
}
|
||||
|
||||
using Utility::Directory::Flag;
|
||||
std::vector<std::string> files = Utility::Directory::list(_profileDirectory, Flag::SkipSpecial|Flag::SkipDirectories|Flag::SkipDotAndDotDot);
|
||||
|
||||
auto predicate = [](const std::string& file)->bool{
|
||||
std::regex regex("(Demo)?Profile[0-9]{17}\\.sav", std::regex::nosubs);
|
||||
std::cmatch m;
|
||||
return !std::regex_match(file.c_str(), m, regex);
|
||||
};
|
||||
|
||||
files.erase(std::remove_if(files.begin(), files.end(), predicate), files.end());
|
||||
|
||||
for(const std::string& file : files) {
|
||||
Profile profile{Utility::Directory::join(_profileDirectory, file)};
|
||||
|
||||
if(profile.valid() == false) {
|
||||
Utility::Warning{} << "Profile" << file.c_str() << "is invalid:" << profile.lastError().c_str();
|
||||
continue;
|
||||
}
|
||||
|
||||
_profiles.push_back(std::move(profile));
|
||||
}
|
||||
|
||||
if(_profiles.size() == 0) {
|
||||
_lastError = "No profiles were found.";
|
||||
return;
|
||||
}
|
||||
|
||||
_ready = true;
|
||||
}
|
||||
|
||||
auto ProfileManager::ready() -> bool {
|
||||
return _ready;
|
||||
}
|
||||
|
||||
auto ProfileManager::lastError() -> std::string const& {
|
||||
return _lastError;
|
||||
}
|
||||
|
||||
auto ProfileManager::profileDirectory() -> std::string const& {
|
||||
return _profileDirectory;
|
||||
}
|
||||
|
||||
auto ProfileManager::profiles() -> std::vector<Profile> const& {
|
||||
return _profiles;
|
||||
}
|
||||
|
||||
auto ProfileManager::currentProfile() -> Profile* {
|
||||
return _currentProfile;
|
||||
}
|
||||
|
||||
auto ProfileManager::setProfile(std::size_t index) -> bool {
|
||||
bool result = false;
|
||||
|
||||
try {
|
||||
_currentProfile = &(_profiles.at(index));
|
||||
result = true;
|
||||
}
|
||||
catch(const std::out_of_range&) {
|
||||
_lastError = "Invalid profile index";
|
||||
_currentProfile = nullptr;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
52
ProfileManager/ProfileManager.h
Normal file
52
ProfileManager/ProfileManager.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef PROFILEMANAGER_H
|
||||
#define PROFILEMANAGER_H
|
||||
|
||||
// wxMASSManager
|
||||
// Copyright (C) 2020 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "../Profile/Profile.h"
|
||||
|
||||
using namespace Corrade;
|
||||
|
||||
class ProfileManager {
|
||||
public:
|
||||
ProfileManager(const std::string& base_path);
|
||||
|
||||
auto ready() -> bool;
|
||||
auto lastError() -> std::string const&;
|
||||
|
||||
auto profileDirectory() -> std::string const&;
|
||||
|
||||
auto profiles() -> std::vector<Profile> const&;
|
||||
|
||||
auto currentProfile() -> Profile*;
|
||||
auto setProfile(std::size_t index) -> bool;
|
||||
|
||||
private:
|
||||
bool _ready = false;
|
||||
std::string _lastError = "";
|
||||
|
||||
std::string _profileDirectory;
|
||||
|
||||
std::vector<Profile> _profiles;
|
||||
|
||||
Profile* _currentProfile = nullptr;
|
||||
};
|
||||
|
||||
#endif //PROFILEMANAGER_H
|
145
ScreenshotManager/ScreenshotManager.cpp
Normal file
145
ScreenshotManager/ScreenshotManager.cpp
Normal file
|
@ -0,0 +1,145 @@
|
|||
// wxMASSManager
|
||||
// Copyright (C) 2020 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <Corrade/Utility/Directory.h>
|
||||
#include <Corrade/Utility/String.h>
|
||||
|
||||
#include <wx/filename.h>
|
||||
|
||||
#include "ScreenshotManager.h"
|
||||
|
||||
using namespace Corrade;
|
||||
|
||||
ScreenshotManager::ScreenshotManager(const std::string& base_path) {
|
||||
_screenshotDirectory = Utility::Directory::join(base_path, "Saved/Screenshots/WindowsNoEditor");
|
||||
|
||||
if(!Utility::Directory::exists(_screenshotDirectory)) {
|
||||
Utility::Directory::mkpath(_screenshotDirectory);
|
||||
}
|
||||
|
||||
using Utility::Directory::Flag;
|
||||
std::vector<std::string> file_list = Utility::Directory::list(_screenshotDirectory, Flag::SkipSpecial|Flag::SkipDirectories|Flag::SkipDotAndDotDot);
|
||||
|
||||
auto iter = std::remove_if(file_list.begin(), file_list.end(), [](std::string& file){
|
||||
return !Utility::String::endsWith(file, ".png");
|
||||
});
|
||||
|
||||
file_list.erase(iter, file_list.end());
|
||||
|
||||
_screenshots.reserve(file_list.size());
|
||||
|
||||
for(const std::string& file : file_list) {
|
||||
addScreenshot(file);
|
||||
}
|
||||
}
|
||||
|
||||
auto ScreenshotManager::screenshotDirectory() -> std::string const& {
|
||||
return _screenshotDirectory;
|
||||
}
|
||||
|
||||
auto ScreenshotManager::screenshots() -> std::vector<Screenshot> const& {
|
||||
return _screenshots;
|
||||
}
|
||||
|
||||
void ScreenshotManager::sortScreenshots(SortType type) {
|
||||
_sortType = type;
|
||||
sortScreenshots();
|
||||
}
|
||||
|
||||
void ScreenshotManager::sortScreenshots(SortOrder order) {
|
||||
_sortOrder = order;
|
||||
sortScreenshots();
|
||||
}
|
||||
|
||||
void ScreenshotManager::sortScreenshots() {
|
||||
auto predicate = [this](const Screenshot& item_1, const Screenshot& item_2)->bool{
|
||||
switch(_sortType) {
|
||||
case SortType::Filename:
|
||||
return wxString::FromUTF8(item_1._filename.c_str()).CmpNoCase(wxString::FromUTF8(item_2._filename.c_str())) < 0;
|
||||
case SortType::CreationDate:
|
||||
return item_1._creationDate.IsEarlierThan(item_2._creationDate);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
switch(_sortOrder) {
|
||||
case SortOrder::Ascending:
|
||||
std::stable_sort(_screenshots.begin(), _screenshots.end(), predicate);
|
||||
break;
|
||||
case SortOrder::Descending:
|
||||
std::stable_sort(_screenshots.rbegin(), _screenshots.rend(), predicate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto ScreenshotManager::updateScreenshot(const std::string& filename) -> int {
|
||||
addScreenshot(filename);
|
||||
sortScreenshots();
|
||||
int index = 0;
|
||||
for(const Screenshot& s : _screenshots) {
|
||||
if(s._filename == filename) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void ScreenshotManager::removeScreenshot(int index) {
|
||||
if(static_cast<size_t>(index + 1) > _screenshots.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = _screenshots.begin() + index;
|
||||
_screenshots.erase(it);
|
||||
}
|
||||
|
||||
void ScreenshotManager::deleteScreenshot(int index) {
|
||||
if(static_cast<size_t>(index + 1) > _screenshots.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Utility::Directory::rm(Utility::Directory::join(_screenshotDirectory, _screenshots[index]._filename));
|
||||
}
|
||||
|
||||
void ScreenshotManager::addScreenshot(const std::string& filename) {
|
||||
std::string screenshot_path = Utility::Directory::toNativeSeparators(Utility::Directory::join(_screenshotDirectory, filename));
|
||||
|
||||
wxFileName screenshot_meta(screenshot_path);
|
||||
wxDateTime creation_date;
|
||||
screenshot_meta.GetTimes(nullptr, nullptr, &creation_date);
|
||||
|
||||
wxImage thumb{screenshot_path, wxBITMAP_TYPE_PNG};
|
||||
|
||||
wxSize size = thumb.GetSize();
|
||||
if(size.GetWidth() > size.GetHeight()) {
|
||||
size.Set(160, (size.GetHeight() * 160) / size.GetWidth());
|
||||
}
|
||||
else if(size.GetHeight() > size.GetWidth()) {
|
||||
size.Set((size.GetWidth() * 160) / size.GetHeight(), 160);
|
||||
}
|
||||
else {
|
||||
size.Set(160, 160);
|
||||
}
|
||||
|
||||
thumb.Rescale(size.GetWidth(), size.GetHeight(), wxIMAGE_QUALITY_HIGH)
|
||||
.Resize(wxSize{160, 160}, wxPoint{(160 - size.GetWidth()) / 2, (160 - size.GetHeight()) / 2});
|
||||
|
||||
_screenshots.push_back(Screenshot{filename, creation_date, thumb});
|
||||
}
|
67
ScreenshotManager/ScreenshotManager.h
Normal file
67
ScreenshotManager/ScreenshotManager.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#ifndef SCREENSHOTMANAGER_H
|
||||
#define SCREENSHOTMANAGER_H
|
||||
|
||||
// wxMASSManager
|
||||
// Copyright (C) 2020 Guillaume Jacquemin
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <wx/datetime.h>
|
||||
#include <wx/image.h>
|
||||
|
||||
enum class SortType : uint8_t {
|
||||
Filename, CreationDate
|
||||
};
|
||||
|
||||
enum class SortOrder: uint8_t {
|
||||
Ascending, Descending
|
||||
};
|
||||
|
||||
struct Screenshot {
|
||||
std::string _filename;
|
||||
wxDateTime _creationDate;
|
||||
wxImage _thumbnail;
|
||||
};
|
||||
|
||||
class ScreenshotManager {
|
||||
public:
|
||||
ScreenshotManager(const std::string& base_path);
|
||||
|
||||
auto screenshotDirectory() -> std::string const&;
|
||||
|
||||
auto screenshots() -> std::vector<Screenshot> const&;
|
||||
|
||||
void sortScreenshots(SortType type);
|
||||
void sortScreenshots(SortOrder order);
|
||||
void sortScreenshots();
|
||||
|
||||
auto updateScreenshot(const std::string& filename) -> int;
|
||||
void removeScreenshot(int index);
|
||||
void deleteScreenshot(int index);
|
||||
|
||||
private:
|
||||
void addScreenshot(const std::string& filename);
|
||||
|
||||
std::string _screenshotDirectory = "";
|
||||
|
||||
std::vector<Screenshot> _screenshots;
|
||||
|
||||
SortType _sortType = SortType::Filename;
|
||||
SortOrder _sortOrder = SortOrder::Ascending;
|
||||
};
|
||||
|
||||
#endif //SCREENSHOTMANAGER_H
|
Loading…
Reference in a new issue