From 84ffa26a72ca4d3dc6cdfc00a31a06133edb72b0 Mon Sep 17 00:00:00 2001 From: openshwprojects Date: Wed, 30 Nov 2022 17:59:47 +0100 Subject: [PATCH] sim: recent files list (that is stored in json file) --- openBeken_win32_mvsc2017.vcxproj | 2 + openBeken_win32_mvsc2017.vcxproj.filters | 6 +++ src/sim/RecentList.cpp | 51 ++++++++++++++++++++++++ src/sim/RecentList.h | 36 +++++++++++++++++ src/sim/Simulator.cpp | 5 +++ src/sim/Simulator.h | 4 ++ src/sim/WinMenuBar.cpp | 33 ++++++++++++--- src/sim/WinMenuBar.h | 1 + src/sim/sim_local.h | 3 ++ 9 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 src/sim/RecentList.cpp create mode 100644 src/sim/RecentList.h diff --git a/openBeken_win32_mvsc2017.vcxproj b/openBeken_win32_mvsc2017.vcxproj index cec773bd8..9c1d31dde 100644 --- a/openBeken_win32_mvsc2017.vcxproj +++ b/openBeken_win32_mvsc2017.vcxproj @@ -522,6 +522,7 @@ + @@ -566,6 +567,7 @@ + diff --git a/openBeken_win32_mvsc2017.vcxproj.filters b/openBeken_win32_mvsc2017.vcxproj.filters index 5587103ce..6086f6857 100644 --- a/openBeken_win32_mvsc2017.vcxproj.filters +++ b/openBeken_win32_mvsc2017.vcxproj.filters @@ -399,6 +399,9 @@ Simulator + + Simulator + @@ -476,6 +479,9 @@ Simulator + + Simulator + diff --git a/src/sim/RecentList.cpp b/src/sim/RecentList.cpp new file mode 100644 index 000000000..1ce966177 --- /dev/null +++ b/src/sim/RecentList.cpp @@ -0,0 +1,51 @@ +#ifdef WINDOWS +#include "RecentList.h" +#include "../cJSON/cJSON.h" + +void CRecentList::remove(const char *s) { + for (int i = recents.size() - 1; i >= 0; i--) { + if (!stricmp(recents[i].c_str(), s)) { + recents.removeAt(i); + } + } + +} +void CRecentList::registerAndSave(const char *s) { + remove(s); + recents.insert(recents.begin(), s); + save(); +} +bool CRecentList::load(const char *fname) { + char *jsonData; + jsonData = FS_ReadTextFile(fname); + if (jsonData == 0) { + return 0; + } + cJSON *n_jSim = cJSON_Parse(jsonData); + cJSON *n_jObjects = cJSON_GetObjectItemCaseSensitive(n_jSim, "recents"); + cJSON *jObject; + clear(); + cJSON_ArrayForEach(jObject, n_jObjects) + { + cJSON *cPath = cJSON_GetObjectItemCaseSensitive(jObject, "path"); + push_back(cPath->valuestring); + } + return true; +} +void CRecentList::save(const char *fname) { + cJSON *root_sim = cJSON_CreateObject(); + cJSON *main_objects = cJSON_AddObjectToObject(root_sim, "recents"); + for (int i = 0; i < size(); i++) { + const char *path = get(i); + cJSON *j_obj = cJSON_AddObjectToObject(main_objects, "recent"); + cJSON_AddStringToObject(j_obj, "path", path); + } + char *msg = cJSON_Print(root_sim); + + FS_WriteTextFile(msg, fname); + + free(msg); +} + +#endif + diff --git a/src/sim/RecentList.h b/src/sim/RecentList.h new file mode 100644 index 000000000..1c23d923f --- /dev/null +++ b/src/sim/RecentList.h @@ -0,0 +1,36 @@ +#ifndef __RECENTLIST_H__ +#define __RECENTLIST_H__ + +#include "sim_local.h" + +#define RECENTS_FILE_PATH "recents.json" + +class CRecentList { + TArray recents; + + void remove(const char *s); +public: + int size() const { + return recents.size(); + } + const char *get(int i) const { + return recents[i].c_str(); + } + void push_back(const char *s) { + recents.push_back(s); + } + int getSizeCappedAt(int mx) const { + if (mx < recents.size()) + return mx; + return recents.size(); + } + void clear() { + recents.clear(); + } + void registerAndSave(const char *s); + bool load(const char *path = RECENTS_FILE_PATH); + void save(const char *path = RECENTS_FILE_PATH); + +}; + +#endif diff --git a/src/sim/Simulator.cpp b/src/sim/Simulator.cpp index 631608e79..f6fe2373a 100644 --- a/src/sim/Simulator.cpp +++ b/src/sim/Simulator.cpp @@ -20,6 +20,7 @@ #include "WinMenuBar.h" #include "SaveLoad.h" #include "sim_import.h" +#include "RecentList.h" CSimulator::CSimulator() { @@ -37,6 +38,8 @@ CSimulator::CSimulator() { solver = new CSolver(); saveLoad = new CSaveLoad(); saveLoad->setSimulator(this); + recents = new CRecentList(); + recents->load(); } void CSimulator::setTool(Tool_Base *tb) { @@ -261,6 +264,7 @@ bool CSimulator::loadSimulation(const char *s) { projectPath = s; project = saveLoad->loadProjectFile(s); sim = saveLoad->loadSimulationFromFile(simPath.c_str()); + recents->registerAndSave(projectPath.c_str()); SIM_ClearOBK(); SIM_SetupFlashFileReading(memPath.c_str()); SIM_DoFreshOBKBoot(); @@ -292,6 +296,7 @@ bool CSimulator::saveSimulationAs(const char *s) { printf("CSimulator::saveSimulationAs: memPath %s\n", memPath.c_str()); FS_CreateDirectoriesForPath(simPath.c_str()); FS_CreateDirectoriesForPath(memPath.c_str()); + recents->registerAndSave(projectPath.c_str()); saveLoad->saveProjectToFile(project, projectPath.c_str()); saveLoad->saveSimulationToFile(sim, simPath.c_str()); SIM_SaveFlashData(memPath.c_str()); diff --git a/src/sim/Simulator.h b/src/sim/Simulator.h index dd742d348..046d5fec0 100644 --- a/src/sim/Simulator.h +++ b/src/sim/Simulator.h @@ -22,6 +22,7 @@ class CSimulator { class CProject *project; bool bSchematicModified; class CText *currentlyEditingText; + class CRecentList *recents; void onKeyDown(int keyCode); void setTool(class Tool_Base *tb); @@ -37,6 +38,9 @@ public: class CSimulation*getSim() { return sim; } + class CRecentList *getRecents() { + return recents; + } class PrefabManager*getPfbs() { return prefabs; } diff --git a/src/sim/WinMenuBar.cpp b/src/sim/WinMenuBar.cpp index ad269e32a..894b1051d 100644 --- a/src/sim/WinMenuBar.cpp +++ b/src/sim/WinMenuBar.cpp @@ -2,6 +2,7 @@ #include "WinMenuBar.h" #include "Simulator.h" +#include "RecentList.h" #include #pragma comment (lib, "nfd_d.lib") @@ -16,6 +17,8 @@ enum { ID_SAVEAS, ID_SAVE, ID_EXIT, + ID_OPEN_RECENT_FIRST, + ID_OPEN_RECENT_LAST = ID_OPEN_RECENT_FIRST + 100, ID_OPTIONS, ID_ABOUT, }; @@ -25,6 +28,7 @@ void CWinMenuBar::createWindowsMenu(HWND windowRef) { hFile = CreateMenu(); hEdit = CreateMenu(); hHelp = CreateMenu(); + HMENU hRecent = CreateMenu(); AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFile, "File"); AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hEdit, "Edit"); @@ -35,6 +39,16 @@ void CWinMenuBar::createWindowsMenu(HWND windowRef) { AppendMenu(hFile, MF_STRING, ID_LOAD, "Load..."); AppendMenu(hFile, MF_STRING, ID_SAVE, "Save"); AppendMenu(hFile, MF_STRING, ID_SAVEAS, "Save as..."); + AppendMenu(hFile, MF_POPUP, (UINT_PTR)hRecent, "Open recent"); + CRecentList *rList = sim->getRecents(); + recents.clear(); + for (int i = 0; i < rList->getSizeCappedAt(10); i++) { + const char *entr = rList->get(i); + recents.push_back(entr); + CString tmp = "Open "; + tmp.append(entr); + AppendMenu(hRecent, MF_STRING, ID_OPEN_RECENT_FIRST + i, tmp.c_str()); + } AppendMenu(hFile, MF_STRING, ID_EXIT, "Exit"); AppendMenu(hEdit, MF_STRING, ID_OPTIONS, "Options"); @@ -78,33 +92,40 @@ void CWinMenuBar::processEvent(const SDL_Event &Event) { if (Event.type == SDL_SYSWMEVENT) { if (Event.syswm.msg->msg.win.msg == WM_COMMAND) { - if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_EXIT) + int id = LOWORD(Event.syswm.msg->msg.win.wParam); + if (id == ID_EXIT) { sim->onUserClose(); } - else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_NEW) + else if (id == ID_NEW) { sim->createSimulation(false); } - else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_NEW_DEMO) + else if (id == ID_NEW_DEMO) { sim->createSimulation(true); } - else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_LOAD) + else if (id == ID_LOAD) { result = NFD_OpenDialog("obkproj", NULL, &outPath); if (result == NFD_OKAY) { sim->loadSimulation(outPath); } } - else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_SAVEAS) + else if (id == ID_SAVEAS) { showSaveAsDialog(); } - else if (LOWORD(Event.syswm.msg->msg.win.wParam) == ID_SAVE) + else if (id == ID_SAVE) { sim->saveOrShowSaveAsDialogIfNeeded(); } + else if (id >= ID_OPEN_RECENT_FIRST && id <= ID_OPEN_RECENT_LAST) + { + int recentID = id - ID_OPEN_RECENT_FIRST; + const char *recentStr = recents[recentID].c_str(); + sim->loadSimulation(outPath); + } } } } diff --git a/src/sim/WinMenuBar.h b/src/sim/WinMenuBar.h index dd14909f4..1d8aedf6d 100644 --- a/src/sim/WinMenuBar.h +++ b/src/sim/WinMenuBar.h @@ -11,6 +11,7 @@ class CWinMenuBar { HMENU hFile; HMENU hEdit; HMENU hHelp; + TArray recents; void createWindowsMenu(HWND windowRef); HWND getHWNDForSDLWindow(SDL_Window* win); diff --git a/src/sim/sim_local.h b/src/sim/sim_local.h index 84c1634f6..74ffe2764 100644 --- a/src/sim/sim_local.h +++ b/src/sim/sim_local.h @@ -50,6 +50,9 @@ public: void remove(T o) { this->erase(std::remove(this->begin(), this->end(), o), this->end()); } + void removeAt(int i) { + this->erase(this->begin() + i); + } bool contains(const T&o) const { for (unsigned int i = 0; i < size(); i++) { if ((*this)[i] == o)