// MassBuilderSaveTool // Copyright (C) 2021-2024 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 . #include #include #include "../FontAwesome/IconsFontAwesome5.h" #include "Application.h" extern const ImVec2 center_pivot; namespace mbst { void Application::drawProfileManager() { static std::size_t profile_index = 0; ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot); if(ImGui::Begin("Profile management##ProfileManager", nullptr, ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoBringToFrontOnFocus| ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_MenuBar)) { if(ImGui::BeginMenuBar()) { ImGui::TextUnformatted("Profile manager"); ImGui::EndMenuBar(); } static ImGuiID backup_list_popup_id = drawBackupListPopup(); static ImGuiID backup_popup_id = drawBackupProfilePopup(profile_index); static ImGuiID delete_popup_id = drawDeleteProfilePopup(profile_index); if(ImGui::BeginTable("##ManagerLayout", 2)) { ImGui::TableSetupColumn("##Label", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Refresh", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted("Here are the detected profiles:"); ImGui::TableSetColumnIndex(1); if(ImGui::SmallButton("Refresh")) { if(!_profileManager->refreshProfiles()) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _profileManager->lastError().data(), window()); exit(EXIT_FAILURE); } } ImGui::SameLine(); if(ImGui::SmallButton("Backups")) { _profileManager->refreshBackups(); ImGui::OpenPopup(backup_list_popup_id); } ImGui::EndTable(); } if(ImGui::BeginTable("##Profiles", 3, ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg)) { ImGui::TableSetupColumn("Company name", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##Buttons", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted("Company name"); ImGui::TableSetColumnIndex(1); ImGui::TextUnformatted("Type"); ImGui::TableSetColumnIndex(2); ImGui::TextUnformatted("Actions"); for(std::size_t i = 0; i < _profileManager->profiles().size(); ++i) { GameObjects::Profile& profile = _profileManager->profiles()[i]; ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::PushID(int(i)); if(ImGui::Selectable(profile.companyName().data(), false, ImGuiSelectableFlags_SpanAllColumns|ImGuiSelectableFlags_AllowItemOverlap)) { _currentProfile = _profileManager->getProfile(i); initialiseMassManager(); initialiseFileWatcher(); _uiState = UiState::MainManager; } ImGui::TableSetColumnIndex(1); ImGui::TextUnformatted(profile.isDemo() ? "Demo" : "Full"); ImGui::TableSetColumnIndex(2); if(ImGui::SmallButton(ICON_FA_FILE_ARCHIVE)) { profile_index = i; ImGui::OpenPopup(backup_popup_id); } drawTooltip("Backup"); ImGui::SameLine(0.0f, 2.0f); if(drawUnsafeWidget(ImGui::SmallButton, ICON_FA_TRASH_ALT)) { profile_index = i; ImGui::OpenPopup(delete_popup_id); } drawTooltip("Delete"); ImGui::PopID(); } ImGui::EndTable(); } ImGui::TextUnformatted("Click a profile to manage it."); } drawBackupListPopup(); drawBackupProfilePopup(profile_index); drawDeleteProfilePopup(profile_index); ImGui::End(); } ImGuiID Application::drawBackupListPopup() { ImGui::SetNextWindowPos(ImVec2{Vector2{windowSize() / 2.0f} / dpiScaling()}, ImGuiCond_Always, center_pivot); if(!ImGui::BeginPopupModal("Backups##BackupsModal", nullptr, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) { return ImGui::GetID("Backups##BackupsModal"); } static std::size_t backup_index; if(ImGui::BeginPopupModal("Restore backup", nullptr, ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::PushTextWrapPos(float(windowSize().x()) * 0.40f); ImGui::Text("Are you sure you want to restore the %s backup from %.4i-%.2i-%.2i %.2i:%.2i:%.2i ? Any existing data will be overwritten.", _profileManager->backups()[backup_index].company.data(), _profileManager->backups()[backup_index].timestamp.year, _profileManager->backups()[backup_index].timestamp.month, _profileManager->backups()[backup_index].timestamp.day, _profileManager->backups()[backup_index].timestamp.hour, _profileManager->backups()[backup_index].timestamp.minute, _profileManager->backups()[backup_index].timestamp.second); ImGui::PopTextWrapPos(); if(ImGui::BeginTable("##RestoreBackupLayout", 2)) { ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(1); if(ImGui::Button("Yes")) { if(!_profileManager->restoreBackup(backup_index)) { _queue.addToast(Toast::Type::Error, _profileManager->lastError()); } if(!_profileManager->refreshProfiles()) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _profileManager->lastError().data(), window()); exit(EXIT_FAILURE); } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if(ImGui::Button("No", ImGui::GetItemRectSize())) { ImGui::CloseCurrentPopup(); } ImGui::EndTable(); } ImGui::EndPopup(); } if(ImGui::BeginPopupModal("Delete backup", nullptr, ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_AlwaysAutoResize)) { ImGui::PushTextWrapPos(float(windowSize().x()) * 0.40f); ImGui::Text("Are you sure you want to delete the %s backup from %.4i-%.2i-%.2i %.2i:%.2i:%.2i ? This operation is irreversible.", _profileManager->backups()[backup_index].company.data(), _profileManager->backups()[backup_index].timestamp.year, _profileManager->backups()[backup_index].timestamp.month, _profileManager->backups()[backup_index].timestamp.day, _profileManager->backups()[backup_index].timestamp.hour, _profileManager->backups()[backup_index].timestamp.minute, _profileManager->backups()[backup_index].timestamp.second); ImGui::PopTextWrapPos(); if(ImGui::BeginTable("##DeleteBackupLayout", 2)) { ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(1); if(ImGui::Button("Yes")) { if(!_profileManager->deleteBackup(backup_index)) { _queue.addToast(Toast::Type::Error, _profileManager->lastError()); } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if(ImGui::Button("No", ImGui::GetItemRectSize())) { ImGui::CloseCurrentPopup(); } ImGui::EndTable(); } ImGui::EndPopup(); } static ImGuiID restore_backup_popup_id = ImGui::GetID("Restore backup"); static ImGuiID delete_backup_popup_id = ImGui::GetID("Delete backup"); if(ImGui::BeginTable("##BackupsLabelLayout", 2)) { ImGui::TableSetupColumn("##Label", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Refresh", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted("Here's a list of detected backups:"); ImGui::TableSetColumnIndex(1); if(ImGui::SmallButton("Refresh")) { _profileManager->refreshBackups(); } ImGui::EndTable(); } if(_profileManager->backups().isEmpty()) { ImGui::TextDisabled("No backups were found."); } else if(ImGui::BeginTable("##Backups", 4, ImGuiTableFlags_BordersOuter|ImGuiTableFlags_RowBg)) { ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableSetupColumn("##CompanyName", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##BackupDate", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##Type", ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##Actions", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(ImGuiTableRowFlags_Headers); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted("Company name"); ImGui::TableSetColumnIndex(1); ImGui::TextUnformatted("Backup date"); ImGui::TableSetColumnIndex(2); ImGui::TextUnformatted("Type"); ImGui::TableSetColumnIndex(3); ImGui::TextUnformatted("Actions"); for(std::size_t i = 0; i < _profileManager->backups().size(); ++i) { auto& backup = _profileManager->backups()[i]; ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::TextUnformatted(backup.company.cbegin(), backup.company.cend()); if(ImGui::IsItemHovered() && ImGui::BeginTooltip()) { for(const auto& file : backup.includedFiles) { ImGui::TextUnformatted(file.cbegin()); } ImGui::EndTooltip(); } ImGui::TableSetColumnIndex(1); ImGui::Text("%.4i-%.2i-%.2i %.2i:%.2i:%.2i", backup.timestamp.year, backup.timestamp.month, backup.timestamp.day, backup.timestamp.hour, backup.timestamp.minute, backup.timestamp.second); ImGui::TableSetColumnIndex(2); ImGui::TextUnformatted(backup.demo ? "Demo" : "Full"); ImGui::TableSetColumnIndex(3); ImGui::PushID(int(i)); if(ImGui::SmallButton(ICON_FA_UNDO)) { backup_index = i; ImGui::OpenPopup(restore_backup_popup_id); } drawTooltip("Restore"); ImGui::SameLine(0.0f, 2.0f); if(ImGui::SmallButton(ICON_FA_TRASH_ALT)) { backup_index = i; ImGui::OpenPopup(delete_backup_popup_id); } drawTooltip("Delete"); ImGui::PopID(); } ImGui::EndTable(); } ImGui::PushTextWrapPos(ImGui::GetContentRegionAvail().x); ImGui::TextUnformatted("Hover over a company name to see which files are included in the backup."); ImGui::PopTextWrapPos(); if(ImGui::BeginTable("##BackupListCloseLayout", 2)) { ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##Close", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(1); if(ImGui::Button("Close")) { ImGui::CloseCurrentPopup(); } ImGui::EndTable(); } ImGui::EndPopup(); return 0; } ImGuiID Application::drawBackupProfilePopup(std::size_t profile_index) { if(!ImGui::BeginPopupModal("Include builds ?##IncludeBuildsDialog", nullptr, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) { return ImGui::GetID("Include builds ?##IncludeBuildsDialog"); } ImGui::TextUnformatted("Should builds be added to the backup ?"); if(ImGui::BeginTable("##NameBackupLayout", 2)) { ImGui::TableSetupColumn("##Dummy", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(1); if(ImGui::Button("Yes")) { if(!_profileManager->backupProfile(profile_index, true)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _profileManager->lastError().data(), window()); } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if(ImGui::Button("No", ImGui::GetItemRectSize())) { if(!_profileManager->backupProfile(profile_index, false)) { SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error", _profileManager->lastError().data(), window()); } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if(ImGui::Button("Cancel")) { ImGui::CloseCurrentPopup(); } ImGui::EndTable(); } ImGui::EndPopup(); return 0; } ImGuiID Application::drawDeleteProfilePopup(std::size_t profile_index) { if(!ImGui::BeginPopupModal("Confirmation##DeleteProfileConfirmation", nullptr, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoMove)) { return ImGui::GetID("Confirmation##DeleteProfileConfirmation"); } static bool delete_builds = false; if(ImGui::IsWindowAppearing()) { delete_builds = false; } ImGui::PushTextWrapPos(float(windowSize().x()) * 0.40f); ImGui::Text("Are you sure you want to delete the %s profile named %s ? This operation is irreversible.", _profileManager->profiles()[profile_index].isDemo() ? "demo" : "full game", _profileManager->profiles()[profile_index].companyName().data()); ImGui::PopTextWrapPos(); if(ImGui::BeginTable("##DeleteProfileLayout", 2)) { ImGui::TableSetupColumn("##Checkbox", ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("##YesNo", ImGuiTableColumnFlags_WidthFixed); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Checkbox("Delete builds", &delete_builds); ImGui::TableSetColumnIndex(1); if(ImGui::Button("Yes")) { if(!_profileManager->deleteProfile(profile_index, delete_builds)) { _queue.addToast(Toast::Type::Error, _profileManager->lastError()); } ImGui::CloseCurrentPopup(); } ImGui::SameLine(); if(ImGui::Button("No", ImGui::GetItemRectSize())) { ImGui::CloseCurrentPopup(); } ImGui::EndTable(); } ImGui::EndPopup(); return 0; } }