Improve game import

This commit is contained in:
Loic Guegan 2022-12-27 15:58:16 +01:00
parent f40fd3e7a4
commit c97e151e1b
14 changed files with 47 additions and 106 deletions

View file

@ -60,11 +60,11 @@ MainWindow::MainWindow()
NewGame(std::shared_ptr<Game>(new Game())); NewGame(std::shared_ptr<Game>(new Game()));
// Temporary TO REMOVE JUST FOR TESTS: // Temporary TO REMOVE JUST FOR TESTS:
/*BaseTab *bt = new BaseTab((wxFrame *)notebook, "/home/loic/jean.pgn"); BaseTab *bt = new BaseTab((wxFrame *)notebook, "/home/loic/pgn/Milov.pgn");
this->AddPage(bt,bt); this->AddPage(bt,bt);
bt = new BaseTab((wxFrame *)notebook, "/home/loic/pgn/Milov.pgn"); bt = new BaseTab((wxFrame *)notebook, "/home/loic/jean.pgn");
this->AddPage(bt,bt);*/ this->AddPage(bt,bt);
} }
void MainWindow::AddPage(wxWindow* window, TabInfos* infos){ void MainWindow::AddPage(wxWindow* window, TabInfos* infos){

View file

@ -1,47 +0,0 @@
#include "AppendGameDialog.hpp"
#include "MainWindow.hpp"
#include "ochess.hpp"
AppendGameDialog::AppendGameDialog(wxWindow *parent, std::shared_ptr<GameBase> base)
: DialogAppendGame(parent), base(base) {
for (TabInfos *i : wxGetApp().ListTabInfos()) {
if (i->type == TabInfos::GAME || i->type == TabInfos::BASE) {
wxWindow *win = dynamic_cast<wxWindow *>(i);
game_list->Append(win->GetLabel());
tinfos.push_back(i);
}
}
Bind(wxEVT_BUTTON, &AppendGameDialog::OnCancel, this,
ID_DIALOG_CANCEL_BUTTON);
Bind(wxEVT_BUTTON, &AppendGameDialog::OnImport, this,
ID_DIALOG_IMPORT_BUTTON);
Bind(wxEVT_CLOSE_WINDOW, &AppendGameDialog::OnClose, this);
}
void AppendGameDialog::OnClose(wxCloseEvent &e) { Destroy(); }
void AppendGameDialog::OnCancel(wxCommandEvent &event) { this->Close(); }
void AppendGameDialog::OnImport(wxCommandEvent &event) {
std::vector<std::uint32_t> to_ignore;
std::vector<std::shared_ptr<GameBase>> new_games_bases;
std::vector<std::shared_ptr<Game>> new_games;
wxArrayInt selections;
game_list->GetSelections(selections);
for (int &i : selections) {
TabInfos *tinfo = tinfos[i];
if (tinfo->type == TabInfos::BASE) {
new_games_bases.push_back(tinfo->GetBase());
} else if (tinfo->type == TabInfos::GAME) {
new_games.push_back(tinfo->GetGame());
}
}
base->Save(to_ignore, new_games_bases, new_games);
this->Close();
}

View file

@ -1,12 +0,0 @@
#include "gamebase/GameBase.hpp"
class AppendGameDialog : public DialogAppendGame {
std::shared_ptr<GameBase> base; // Should not be destroy
std::vector<TabInfos *> tinfos;
public:
AppendGameDialog(wxWindow *parent, std::shared_ptr<GameBase> base);
void OnCancel(wxCommandEvent &event);
void OnImport(wxCommandEvent &event);
void OnClose(wxCloseEvent &e);
};

View file

@ -1,5 +1,4 @@
#include "BaseGameTab.hpp" #include "BaseGameTab.hpp"
#include "AppendGameDialog.hpp"
#include <wx/filename.h> #include <wx/filename.h>
wxDEFINE_EVENT(OPEN_GAME_EVENT, wxCommandEvent); wxDEFINE_EVENT(OPEN_GAME_EVENT, wxCommandEvent);

View file

@ -17,9 +17,9 @@ TabBase_TabImport(parent), main_tab(main_tab), base(db)
} }
void BaseImportTab::OnImportDatabase(wxCommandEvent &event){ void BaseImportTab::OnImportDatabase(wxCommandEvent &event){
if(std::find(databases_to_import.begin(), databases_to_import.end(), selected_base) == databases_to_import.end()){ if(std::find(databases_to_import.begin(), databases_to_import.end(), selected_base->GetFilePath()) == databases_to_import.end()){
databases_to_import.push_back(selected_base); databases_to_import.push_back(selected_base->GetFilePath());
selected_games_to_import.clear(); selected_games_to_import.erase(selected_base->GetFilePath());
glm->Clear(); glm->Clear();
RefreshPendingImports(); RefreshPendingImports();
} }
@ -29,7 +29,10 @@ void BaseImportTab::OnImportDatabase(wxCommandEvent &event){
void BaseImportTab::RefreshPendingImports(){ void BaseImportTab::RefreshPendingImports(){
int ngames=games_to_import.size(); int ngames=games_to_import.size();
int ndb=databases_to_import.size(); int ndb=databases_to_import.size();
int nbselect=selected_games_to_import.size(); int nbselect=0;
for (auto it = selected_games_to_import.begin(); it != selected_games_to_import.end(); it++){
nbselect+=it->second.size();
}
pending_imports->Clear(); pending_imports->Clear();
if(ngames+ndb+nbselect>0){ if(ngames+ndb+nbselect>0){
pending_imports->AppendText(" Pending imports: "+std::to_string(ngames+nbselect)+" games and "+std::to_string(ndb)+" databases"); pending_imports->AppendText(" Pending imports: "+std::to_string(ngames+nbselect)+" games and "+std::to_string(ndb)+" databases");
@ -55,14 +58,15 @@ void BaseImportTab::RefreshImportLists(){
} }
void BaseImportTab::OnImportSelection(wxCommandEvent &event){ void BaseImportTab::OnImportSelection(wxCommandEvent &event){
if(std::find(databases_to_import.begin(), databases_to_import.end(), selected_base) == databases_to_import.end()){ if(std::find(databases_to_import.begin(), databases_to_import.end(), selected_base->GetFilePath()) == databases_to_import.end()){
long selected = -1; long selected = -1;
while ((selected = game_list->GetNextItem(selected, wxLIST_NEXT_ALL, while ((selected = game_list->GetNextItem(selected, wxLIST_NEXT_ALL,
wxLIST_STATE_SELECTED)) != wxLIST_STATE_SELECTED)) !=
wxNOT_FOUND) { wxNOT_FOUND) {
long game_id=glm->GetItemGameId(selected); long game_id=glm->GetItemGameId(selected);
if(selected_games_to_import.find(game_id) == selected_games_to_import.end()){ auto &game_list=selected_games_to_import[selected_base->GetFilePath()];
selected_games_to_import[game_id]=selected_base->GetGame(glm->GetItemGameId(selected)); if(game_list.find(game_id) == game_list.end()){
game_list[game_id]=selected_base->GetGame(glm->GetItemGameId(selected));
glm->MarkItemAsImported(selected); glm->MarkItemAsImported(selected);
} }
} }
@ -85,21 +89,23 @@ void BaseImportTab::OnImportGame(wxCommandEvent &event){
void BaseImportTab::OnLoad(wxCommandEvent &event){ void BaseImportTab::OnLoad(wxCommandEvent &event){
TabInfos *game_tab=(TabInfos*)opened_db_list->GetClientData(opened_db_list->GetSelection()); TabInfos *game_tab=(TabInfos*)opened_db_list->GetClientData(opened_db_list->GetSelection());
selected_base.reset();
selected_base=game_tab->GetBase();
glm->Clear();
// Load all games (for now :) // Load all games (for now :)
selected_base->Reset(); glm->Clear();
selected_base=OpenDatabase(game_tab->GetBase()->GetFilePath());
SHOW_DIALOG_BUSY("Loading database..."); SHOW_DIALOG_BUSY("Loading database...");
auto &game_list=selected_games_to_import[selected_base->GetFilePath()];
while (selected_base->NextGame()) { while (selected_base->NextGame()) {
glm->AddGame( long id=glm->AddGame(
selected_base->GetTag("White"), selected_base->GetTag("White"),
selected_base->GetTag("Black"), selected_base->GetTag("Black"),
selected_base->GetTag("Event"), selected_base->GetTag("Event"),
selected_base->GetTag("Round"), selected_base->GetTag("Round"),
selected_base->GetTag("Result"), selected_base->GetTag("Result"),
selected_base->GetTag("ECO")); selected_base->GetTag("ECO"));
if(game_list.find(id)!=game_list.end()){
glm->MarkItemAsImported(id);
}
} }
} }
@ -109,13 +115,16 @@ void BaseImportTab::Reset(std::shared_ptr<GameBase> base){
this->databases_to_import.clear(); this->databases_to_import.clear();
this->selected_games_to_import.clear(); this->selected_games_to_import.clear();
glm->Clear(); glm->Clear();
RefreshPendingImports();
} }
std::vector<std::shared_ptr<Game>> BaseImportTab::GetGameToImport(){ std::vector<std::shared_ptr<Game>> BaseImportTab::GetGameToImport(){
std::vector<std::shared_ptr<Game>> to_import; std::vector<std::shared_ptr<Game>> to_import;
for(auto g: games_to_import){to_import.push_back(g);} for(auto g: games_to_import){to_import.push_back(g);}
for (auto it = selected_games_to_import.begin(); it != selected_games_to_import.end(); it++){ for (auto it = selected_games_to_import.begin(); it != selected_games_to_import.end(); it++){
to_import.push_back(it->second); for (auto it2 = it->second.begin(); it2 != it->second.end(); it2++){
to_import.push_back(it2->second);
}
} }
return to_import; return to_import;
} }

View file

@ -4,13 +4,15 @@
#include "GameListManager.hpp" #include "GameListManager.hpp"
#include "game_tab/Game.hpp" #include "game_tab/Game.hpp"
#include <vector> #include <vector>
#include <utility>
class BaseImportTab : public TabBase_TabImport { class BaseImportTab : public TabBase_TabImport {
TabInfos *main_tab; TabInfos *main_tab;
std::shared_ptr<GameListManager> glm; std::shared_ptr<GameListManager> glm;
std::vector<std::shared_ptr<Game>> games_to_import; std::vector<std::shared_ptr<Game>> games_to_import;
std::vector<std::shared_ptr<GameBase>> databases_to_import; std::vector<std::string> databases_to_import;
std::unordered_map<long, std::shared_ptr<Game>> selected_games_to_import; /// @brief Old for each pair of DB (file path) and game id, the given game object
std::unordered_map<std::string, std::unordered_map<long,std::shared_ptr<Game>>> selected_games_to_import;
std::shared_ptr<GameBase> base; std::shared_ptr<GameBase> base;
std::shared_ptr<GameBase> selected_base; std::shared_ptr<GameBase> selected_base;
@ -24,5 +26,5 @@ public:
void OnImportDatabase(wxCommandEvent &event); void OnImportDatabase(wxCommandEvent &event);
void Reset(std::shared_ptr<GameBase> base); void Reset(std::shared_ptr<GameBase> base);
std::vector<std::shared_ptr<Game>> GetGameToImport(); std::vector<std::shared_ptr<Game>> GetGameToImport();
std::vector<std::shared_ptr<GameBase>> GetDatabaseToImport() {return databases_to_import;}; std::vector<std::string> GetDatabaseToImport() {return databases_to_import;};
}; };

View file

@ -1,12 +1,11 @@
#include "BaseTab.hpp" #include "BaseTab.hpp"
#include "AppendGameDialog.hpp"
#include <wx/filename.h> #include <wx/filename.h>
BaseTab::BaseTab(wxFrame *parent, std::string base_file) BaseTab::BaseTab(wxFrame *parent, std::string base_file)
: TabBase(parent), TabInfos(TabInfos::BASE), base_file(base_file){ : TabBase(parent), TabInfos(TabInfos::BASE), base_file(base_file){
// First open the database // First open the database
OpenDatabase(base_file); base=OpenDatabase(base_file);
// Games tab // Games tab
games_tab=new BaseGameTab((wxFrame *)notebook,base,this); games_tab=new BaseGameTab((wxFrame *)notebook,base,this);
@ -45,34 +44,23 @@ void BaseTab::Refresh(){
SetLabel(wxFileName(base->GetFilePath()).GetName()+" [DB]"); // Propagated to MainWindow tab title automatically by wxWidget SetLabel(wxFileName(base->GetFilePath()).GetName()+" [DB]"); // Propagated to MainWindow tab title automatically by wxWidget
} }
void BaseTab::OpenDatabase(std::string dbpath) {
wxFileName file(dbpath);
wxString ext = file.GetExt().Lower();
wxLogDebug("Here");
if (ext == "pgn") {
if(!file.Exists())
PGNGameBase::CreateDatabaseFile(dbpath);
base.reset();
base = std::shared_ptr<GameBase>(new PGNGameBase(dbpath));
}
}
void BaseTab::OnSave(wxCommandEvent &event) { void BaseTab::OnSave(wxCommandEvent &event) {
// Build new games SHOW_DIALOG_BUSY("Apply all changes. Take a coffee, this process can takes time...");
// First import games
std::vector<std::shared_ptr<Game>> new_games=games_tab->GetEditedGames(); std::vector<std::shared_ptr<Game>> new_games=games_tab->GetEditedGames();
for(auto g: import_tab->GetGameToImport()){ for(auto g: import_tab->GetGameToImport()){
new_games.push_back(g); new_games.push_back(g);
} }
SHOW_DIALOG_BUSY("Apply all changes. Take a coffee, this process can takes time...");
base->Save(games_tab->GetDeletedGameIds(), import_tab->GetDatabaseToImport(), new_games); base->Save(games_tab->GetDeletedGameIds(), import_tab->GetDatabaseToImport(), new_games);
// Close all opened games in this database // Close all opened games in this database
wxCommandEvent closeLinkedTabEvent(CLOSE_LINKED_TAB, GetId()); wxCommandEvent closeLinkedTabEvent(CLOSE_LINKED_TAB, GetId());
closeLinkedTabEvent.SetClientData((TabInfos*)this); closeLinkedTabEvent.SetClientData((TabInfos*)this);
ProcessEvent(closeLinkedTabEvent); ProcessEvent(closeLinkedTabEvent);
// Reopen the saved database // Reopen the saved database
OpenDatabase(base_file); base.reset();
base=OpenDatabase(base_file);
games_tab->Reset(base); games_tab->Reset(base);
manage_tab->Reset(base); manage_tab->Reset(base);
import_tab->Reset(base); import_tab->Reset(base);

View file

@ -24,7 +24,6 @@ class BaseTab : public TabBase, public TabInfos {
void OnOpenGame(wxCommandEvent &event); void OnOpenGame(wxCommandEvent &event);
void OnSave(wxCommandEvent &event); void OnSave(wxCommandEvent &event);
void OpenDatabase(std::string dbpath);
public: public:
BaseTab(wxFrame *parent, std::string base_file); BaseTab(wxFrame *parent, std::string base_file);

View file

@ -11,12 +11,14 @@ GameListManager::GameListManager(wxListCtrl *game_list): game_list(game_list), g
game_list->InsertColumn(6, L"ECO", wxLIST_FORMAT_LEFT, 200); game_list->InsertColumn(6, L"ECO", wxLIST_FORMAT_LEFT, 200);
} }
void GameListManager::AddGame(CType White,CType Black,CType Event,CType Round, CType Result, CType Eco){ long GameListManager::AddGame(CType White,CType Black,CType Event,CType Round, CType Result, CType Eco){
// Update rows elements // Update rows elements
rows.push_back({game_counter,White,Black,Event,Round,Result,Eco}); rows.push_back({game_counter,White,Black,Event,Round,Result,Eco});
// Display the row // Display the row
DisplayRow(game_counter); DisplayRow(game_counter);
long id=game_counter;
game_counter++; game_counter++;
return id;
} }
void GameListManager::DisplayRow(long id){ void GameListManager::DisplayRow(long id){

View file

@ -33,7 +33,7 @@ public:
std::vector<RType> rows; std::vector<RType> rows;
GameListManager(wxListCtrl *game_list); GameListManager(wxListCtrl *game_list);
void AddGame(CType White,CType Black,CType Event,CType Round, CType Result, CType Eco); long AddGame(CType White,CType Black,CType Event,CType Round, CType Result, CType Eco);
void Clear(); void Clear();
void MarkItemAsOpen(long item); void MarkItemAsOpen(long item);
void MarkItemAsDeleted(long item); void MarkItemAsDeleted(long item);

View file

@ -4,8 +4,9 @@
std::shared_ptr<GameBase> OpenDatabase(const std::string &dbpath, bool createIfNotExist){ std::shared_ptr<GameBase> OpenDatabase(const std::string &dbpath, bool createIfNotExist){
wxFileName file(dbpath); wxFileName file(dbpath);
wxString ext = file.GetExt().Lower(); wxString ext = file.GetExt().Lower();
bool create=createIfNotExist && !file.Exists();
if (ext == "pgn") { if (ext == "pgn") {
if(createIfNotExist && !file.Exists()) if(create)
PGNGameBase::CreateDatabaseFile(dbpath); PGNGameBase::CreateDatabaseFile(dbpath);
return std::shared_ptr<GameBase>(new PGNGameBase(dbpath)); return std::shared_ptr<GameBase>(new PGNGameBase(dbpath));
} }

View file

@ -8,7 +8,7 @@ class GameBase {
public: public:
virtual std::shared_ptr<Game> GetGame(std::uint32_t id) = 0; virtual std::shared_ptr<Game> GetGame(std::uint32_t id) = 0;
virtual void Save(std::vector<std::uint32_t> to_delete, virtual void Save(std::vector<std::uint32_t> to_delete,
std::vector<std::shared_ptr<GameBase>> databases_to_import, std::vector<std::string> databases_to_import,
std::vector<std::shared_ptr<Game>> games_to_import) = 0; std::vector<std::shared_ptr<Game>> games_to_import) = 0;
virtual std::shared_ptr<Game> GetCurrentGame() = 0; virtual std::shared_ptr<Game> GetCurrentGame() = 0;
virtual bool NextGame() = 0; virtual bool NextGame() = 0;

View file

@ -79,7 +79,7 @@ std::shared_ptr<Game> PGNGameBase::GetGame(std::uint32_t id) {
} }
void PGNGameBase::Save(std::vector<std::uint32_t> to_delete, void PGNGameBase::Save(std::vector<std::uint32_t> to_delete,
std::vector<std::shared_ptr<GameBase>> databases_to_import, std::vector<std::string> databases_to_import,
std::vector<std::shared_ptr<Game>> games_to_import) { std::vector<std::shared_ptr<Game>> games_to_import) {
wxStandardPaths stdPaths = wxStandardPaths::Get(); wxStandardPaths stdPaths = wxStandardPaths::Get();
wxString tmp = stdPaths.GetTempDir() + "/save_pgn_tmp.pgn"; wxString tmp = stdPaths.GetTempDir() + "/save_pgn_tmp.pgn";
@ -102,8 +102,8 @@ void PGNGameBase::Save(std::vector<std::uint32_t> to_delete,
} }
// Now add new games // Now add new games
for (std::shared_ptr<GameBase> current : databases_to_import) { for(auto dbpath: databases_to_import){
current->Reset(); std::shared_ptr<GameBase> current=OpenDatabase(dbpath);
while (current->NextGame()) { while (current->NextGame()) {
if (several) { if (several) {
new_pgn.Write("\n\n"); new_pgn.Write("\n\n");

View file

@ -14,7 +14,7 @@ public:
std::shared_ptr<Game> GetCurrentGame(); std::shared_ptr<Game> GetCurrentGame();
std::string GetTag(std::string tag); std::string GetTag(std::string tag);
void Save(std::vector<std::uint32_t> to_delete, void Save(std::vector<std::uint32_t> to_delete,
std::vector<std::shared_ptr<GameBase>> databases_to_import, std::vector<std::string> databases_to_import,
std::vector<std::shared_ptr<Game>> games_to_import); std::vector<std::shared_ptr<Game>> games_to_import);
void Reset(); void Reset();
void Export(std::shared_ptr<GameBase> base); void Export(std::shared_ptr<GameBase> base);