mdem showing fixes && buffer indicator

This commit is contained in:
jorenchik
2024-10-20 11:20:37 +03:00
parent 2d1589c94d
commit 83e731e3de
4 changed files with 380 additions and 320 deletions

View File

@@ -4,7 +4,7 @@
#include "parser.h"
void update();
void update(bool isChanged = false);
void saveMdem();
struct MdemBuffer {
@@ -12,3 +12,5 @@ struct MdemBuffer {
time_t trainedAt = 0;
};
void updateMdemInfo(std::string filename = "", bool isChanged = true);

View File

@@ -19,3 +19,5 @@ void initiatePractice(
MdemBuffer *mdemBuffer,
PracticeAlgorithm algorithm
);
void hideQuestionElements();

View File

@@ -1,4 +1,3 @@
#include <cmath>
#include <cstdio>
#include <ctime>
#include <format>
@@ -57,6 +56,7 @@
#include <QCheckBox>
#include <QPushButton>
#include <QStandardPaths>
#include <QShortcut>
#include "main.h"
#include "api.h"
@@ -98,23 +98,25 @@ struct Page {
int end;
};
// @Debug: set the default directory for convenience. It should be configured by user
// Memorybase info.
// @Improve: set the default directory for convenience. It should be configured by user
// or set to "".
std::string currentPath = "/home/jorenchik/Code/mdemory/memorybase/";
std::string currentMdem = "";
/*std::string currentPath = "";*/
QFileSystemModel *model;
QLabel *mdemLabel;
QTreeView *mdemList;
QLabel *membaseLabel;
// Mdem list
QLabel *deckListLabel;
QVBoxLayout *hMdemScroll;
// @Improvement: make it into a hashmap with different buffers;
MdemBuffer *mdemBuffer;
bool isBufferModified = false;
// Mdem scroll list.
QList<Mdem*> mdems = QList<Mdem*>();
QVBoxLayout *hMdemScroll;
QSpacerItem *mdemSpacer;
std::vector<ErrorView*> errorPool;
std::vector<ErrorView*> errorViews;
MdemBuffer *mdemBuffer;
// Editor
Mdem* editMdem;
@@ -129,9 +131,10 @@ QToolButton* lastButton;
QToolButton* nextButton;
QLabel* paginationLabel;
// Mdem actions
// Top layout.
QLabel *deckListLabel;
QToolButton *add;
QToolButton *save;
QToolButton *btnSaveFile;
QToolButton *load;
QToolButton *practice;
@@ -166,18 +169,19 @@ std::string outputMdem(std::vector<Question*> questions, time_t time = 0) {
char buffer[100];
std::strftime(buffer, sizeof(buffer), "%d.%m.%Y %H\\:%M", tm);
auto time = std::string(buffer);
ss << time << std::endl << std::endl;
ss << time << std::endl;
}
for (auto question: questions) {
ss << std::endl;
std::string cooldownPart;
if (question->Cooldown != 0) {
cooldownPart = std::format("[{:.2f}]", question->Cooldown);
cooldownPart = std::format(" [{:.2f}]", question->Cooldown);
}
ss << wrapText(
std::format("- {} {} >\n",
std::format("-{}{} >\n",
cooldownPart,
escapeText(question->QuestionText)),
" " + escapeText(question->QuestionText)),
WRAP_WIDTH
);
if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) {
@@ -220,7 +224,6 @@ std::string outputMdem(std::vector<Question*> questions, time_t time = 0) {
}
}
}
ss << std::endl;
}
return ss.str();
}
@@ -228,7 +231,11 @@ std::string outputMdem(std::vector<Question*> questions, time_t time = 0) {
void makePages() {
pages.clear();
auto len = mdemBuffer->questions.size();
for (int i = 0; i < (len / PER_PAGE) + 1; i++) {
auto pageAmount = len / PER_PAGE;
if (len % PER_PAGE != 0) {
pageAmount += 1;
}
for (int i = 0; i < pageAmount; i++) {
auto startingIndex = PER_PAGE * i ;
auto amount = PER_PAGE;
if (i == mdemBuffer->questions.size() / PER_PAGE) {
@@ -239,15 +246,15 @@ void makePages() {
}
void setupMdem(Mdem *mdem, Question *question) {
if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) {
std::stringstream ss;
if (mw->Cooldown > 0) {
if (question->Cooldown > 0) {
ss << std::format("[{:.2f}] ", question->Cooldown);
}
ss << mw->QuestionText;
ss << question->QuestionText;
mdem->wFrontText.setText(
QString::fromStdString(ss.str())
);
if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) {
auto choices = mw->Choices;
for (size_t k = 0; k < choices.size(); ++k) {
auto answer = choices[k].Answer;
@@ -277,9 +284,6 @@ void setupMdem(Mdem *mdem, Question *question) {
}
mdem->labelCount = choices.size();
} else if (GroupQuestion* mw = dynamic_cast<GroupQuestion*>(question)) {
mdem->wFrontText.setText(
QString::fromStdString(mw->QuestionText)
);
auto groups = mw->Groups;
std::vector<std::string> elements;
for (size_t k = 0; k < groups.size(); ++k) {
@@ -305,22 +309,29 @@ void setupMdem(Mdem *mdem, Question *question) {
void SwitchPage(int pageIdx);
void deleteMdem(Mdem* mdem) {
if (mdem->question) {
Question* deleted = nullptr;
for (int i = 0; i < mdemBuffer->questions.size(); ++i) {
if (mdemBuffer->questions[i] == mdem->question) {
mdemBuffer->questions.erase(mdemBuffer->questions.begin() + i);
delete mdem->question;
mdem->question = nullptr;
break;
std::string getFilename(std::string path) {
std::smatch matches;
auto filenameMatched = std::regex_search(path, matches, lastPathElementExp);
return matches[2].str();
}
void updateMdemInfo(std::string filename, bool isChanged) {
isBufferModified = isBufferModified;
if (filename.length() > 0) {
std::stringstream ss;
ss << std::format("mdem: {}", filename);
if (isChanged) {
ss << "*";
}
if (mdemBuffer->trainedAt > 0) {
std::tm* tm = std::localtime(&mdemBuffer->trainedAt);
char buffer[100];
std::strftime(buffer, sizeof(buffer), "%d.%m.%Y %H:%M", tm);
ss << std::endl << "Last practiced: " << std::string(buffer);
}
makePages();
SwitchPage(0);
}
if (editMdem == mdem) {
editorWindow->hide();
deckListLabel->setText(QString::fromStdString(ss.str()));
} else {
deckListLabel->setText("");
}
}
@@ -364,6 +375,7 @@ Mdem* makeMdem() {
)
);
editorWindow->show();
editor->setCursorPosition(1, 2);
}
}
);
@@ -374,7 +386,23 @@ Mdem* makeMdem() {
&mdem->deleteButton,
&QToolButton::clicked,
[mdem](bool checked) {
deleteMdem(mdem);
if (mdem->question) {
Question* deleted = nullptr;
for (int i = 0; i < mdemBuffer->questions.size(); ++i) {
if (mdemBuffer->questions[i] == mdem->question) {
mdemBuffer->questions.erase(mdemBuffer->questions.begin() + i);
delete mdem->question;
mdem->question = nullptr;
updateMdemInfo(getFilename(currentMdem), true);
break;
}
}
makePages();
SwitchPage(currentPage);
}
if (editMdem == mdem) {
editorWindow->hide();
}
}
);
mdem->hFront.addWidget(&mdem->deleteButton);
@@ -447,34 +475,13 @@ void CreateMdems(std::vector<Question*>& questions) {
hMdemScroll->addItem(mdemSpacer);
}
void updateMdemInfo(std::string filename, bool isChanged = false) {
if (filename.length() > 0) {
std::stringstream ss;
ss << std::format("mdem: {}", filename);
if (isChanged) {
ss << "*";
}
if (mdemBuffer->trainedAt > 0) {
std::tm* tm = std::localtime(&mdemBuffer->trainedAt);
char buffer[100];
std::strftime(buffer, sizeof(buffer), "%d.%m.%Y %H:%M", tm);
ss << std::endl << "Last practiced: " << std::string(buffer);
}
deckListLabel->setText(QString::fromStdString(ss.str()));
} else {
deckListLabel->setText("");
}
}
std::string getFilename(std::string path) {
std::smatch matches;
auto filenameMatched = std::regex_search(path, matches, lastPathElementExp);
return matches[2].str();
}
void update() {
void update(bool isChanged) {
if (currentPage > -1) {
SwitchPage(currentPage);
updateMdemInfo(getFilename(currentMdem));
}
if (currentMdem.length() > 0) {
updateMdemInfo(getFilename(currentMdem), isChanged);
}
}
void SwitchPage(int pageIdx) {
@@ -541,7 +548,18 @@ void SwitchPage(int pageIdx) {
}
// Handle page slice
const Page& page = pages[pageIdx];
Page page;
if (pages.size() <= 0) {
page = Page();
} else if (pageIdx < pages.size()){
page = pages[pageIdx];
} else {
if (pageIdx - 1 < pages.size()) {
page = pages[pageIdx -1];
} else {
page = pages[0];
}
}
std::vector<Question*> pageSlice(
mdemBuffer->questions.begin() + page.start,
@@ -631,6 +649,7 @@ void reloadMdem() {
mdemBuffer->questions = res.value.questions;
makePages();
SwitchPage(0);
updateMdemInfo(filename, false);
} else {
mdemBuffer->trainedAt = 0;
std::cout << std::format("Compilation error: {}", res.error) << std::endl;
@@ -661,7 +680,8 @@ void reloadMdem() {
std::cout << std::format("Could not open the file: {}", currentPath) << std::endl;
}
updateMdemInfo(filename);
hideQuestionElements();
trainWindow->close();
}
void pickDirectory(QString directory) {
@@ -669,14 +689,14 @@ void pickDirectory(QString directory) {
// Update tree view.
if (directory.length() <= 0) {
mdemLabel->setText(directory);
membaseLabel->setText(directory);
return;
}
mdemList->setRootIndex(model->setRootPath(directory));
std::smatch matches;
// Update label.
mdemLabel->setText(QString::fromStdString(
membaseLabel->setText(QString::fromStdString(
std::format(
"memorybase: {}",
getFilename(currentPath)
@@ -687,7 +707,7 @@ void pickDirectory(QString directory) {
reloadMdem();
}
void setupEditorSave(bool checked) {
void setupEditorSave() {
auto res = transpile(editor->text().toStdString(), true);
if (res.error.length() > 0) {
mdemBuffer->trainedAt = 0;
@@ -721,6 +741,7 @@ void setupEditorSave(bool checked) {
setupMdem(editMdem, res.value.questions[0]);
showBacklabels(editMdem);
editorWindow->hide();
updateMdemInfo(getFilename(currentMdem), true);
} else {
QMessageBox::information(
nullptr,
@@ -744,6 +765,7 @@ void setupEditorSave(bool checked) {
makePages();
SwitchPage(0);
editorWindow->hide();
updateMdemInfo(getFilename(currentMdem), true);
}
}
}
@@ -753,6 +775,7 @@ void saveMdem() {
auto filename = getFilename(currentMdem);
std::ofstream out(currentMdem);
out << outputMdem(mdemBuffer->questions, mdemBuffer->trainedAt);
updateMdemInfo(getFilename(currentMdem), false);
}
int main(int argc, char *argv[]) {
@@ -760,6 +783,9 @@ int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QMainWindow window;
auto* settingsWindow = new QWidget;
{ // Menu bar.
QMenuBar *menuBar = new QMenuBar;
QFileDialog *fileDialog = new QFileDialog;
@@ -777,12 +803,23 @@ int main(int argc, char *argv[]) {
);
});
auto* settingsWindow = new QWidget;
QAction *openSettings = menu->addAction("Settings");
QObject::connect(
openSettings,
&QAction::triggered,
[settingsWindow]() {
settingsWindow->show();
});
menuBar->addMenu(menu);
window.setMenuBar(menuBar);
}
{ // Settings window.
QString configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
QDir().mkpath(configDir); // Ensure the directory exists
QDir().mkpath(configDir);
QString settingsFile = configDir + "/mdem.ini";
settings = new QSettings(settingsFile, QSettings::IniFormat);
{ // Settings window.
settingsWindow->setWindowTitle("Settings");
auto formLayout = new QFormLayout;
@@ -811,7 +848,7 @@ int main(int argc, char *argv[]) {
easy->setRange(0, 100);
formLayout->addRow("Easy:", easy);
auto* saveButton = new QPushButton("Save");
auto* btnSaveSettings = new QPushButton("Save");
auto* mainLayout = new QVBoxLayout;
// TODO: make defaults and validate settings values
@@ -823,7 +860,7 @@ int main(int argc, char *argv[]) {
easy->setValue(settings->value("easy").toInt());
QObject::connect(
saveButton,
btnSaveSettings,
&QPushButton::clicked,
[characterWrap, timezone, notRemembered, hard, medium, easy]() {
settings->setValue("characterWrap", characterWrap->value());
@@ -835,23 +872,11 @@ int main(int argc, char *argv[]) {
});
mainLayout->addLayout(formLayout);
mainLayout->addWidget(saveButton);
mainLayout->addWidget(btnSaveSettings);
settingsWindow->setLayout(mainLayout);
}
QAction *openSettings = menu->addAction("Settings");
QObject::connect(
openSettings,
&QAction::triggered,
[settingsWindow]() {
settingsWindow->show();
});
menuBar->addMenu(menu);
window.setMenuBar(menuBar);
{ // Setup editor.
editorWindow = new QMainWindow;
@@ -861,40 +886,49 @@ int main(int argc, char *argv[]) {
QVBoxLayout *vlEditor = new QVBoxLayout;
wEditor->setLayout(vlEditor);
editor = new QsciScintilla;
QsciLexerCPP *lexer = new QsciLexerCPP;
editor = new QsciScintilla;
editor->setLexer(lexer);
editor->setUtf8(true);
editor->setMarginWidth(0, 15);
editor->zoomIn(2);
QHBoxLayout *buttonLayout = new QHBoxLayout;
QWidget *editorButtons = new QWidget;
auto save = new QToolButton;
auto btnSaveEditor = new QPushButton;
editorButtons->setLayout(buttonLayout);
save->setText(QString::fromStdString("Save"));
btnSaveEditor->setText(QString::fromStdString("Save"));
QObject::connect(
save,
btnSaveEditor,
&QToolButton::clicked,
setupEditorSave
);
buttonLayout->addWidget(save);
buttonLayout->addWidget(btnSaveEditor);
vlEditor->addWidget(editor);
vlEditor->addWidget(editorButtons);
QShortcut* shortcutSave = new QShortcut(QKeySequence("Ctrl+S"), editorWindow);
QObject::connect(shortcutSave, &QShortcut::activated, []() {
if (editor->isVisible()) {
setupEditorSave();
}
});
editorWindow->setCentralWidget(wEditor);
}
QSplitter *hSplitter = new QSplitter();
// LeftSide
QWidget *leftWidget = new QWidget();
{ // Left side.
QVBoxLayout *leftLayout = new QVBoxLayout();
QWidget *leftTop = new QWidget();
QVBoxLayout *vLeftTop = new QVBoxLayout();
mdemList = new QTreeView();
mdemLabel = new QLabel();
membaseLabel = new QLabel();
model = new QFileSystemModel();
mdemLabel->setStyleSheet(
membaseLabel->setStyleSheet(
"font-size: 17px;"
"font-weight: 400;"
);
@@ -904,7 +938,7 @@ int main(int argc, char *argv[]) {
leftLayout->addWidget(leftTop);
leftTop->setLayout(vLeftTop);
leftTop->setMinimumSize(0, 40);
vLeftTop->addWidget(mdemLabel);
vLeftTop->addWidget(membaseLabel);
// Hide all columns except the first one
mdemList->setModel(model);
@@ -923,6 +957,7 @@ int main(int argc, char *argv[]) {
}
model->setHeaderData(0, Qt::Horizontal, QObject::tr("Custom Name"));
leftLayout->addWidget(mdemList);
}
// RightSide
@@ -930,6 +965,7 @@ int main(int argc, char *argv[]) {
QVBoxLayout *rightLayout = new QVBoxLayout();
rightWidget->setLayout(rightLayout);
{ // Mdem list top.
QWidget *top = new QWidget();
QHBoxLayout *hTop = new QHBoxLayout();
deckListLabel = new QLabel();
@@ -945,7 +981,7 @@ int main(int argc, char *argv[]) {
hTop->addStretch(1);
add = new QToolButton;
save = new QToolButton;
btnSaveFile = new QToolButton;
load = new QToolButton;
auto cbAlgorithm = new QComboBox;
practice = new QToolButton;
@@ -961,10 +997,10 @@ int main(int argc, char *argv[]) {
auto hlButtonsBottom = new QHBoxLayout();
buttonsBottom->setLayout(hlButtonsBottom);
add->setText("Add");
save->setText("Save");
btnSaveFile->setText("Save");
load->setText("Load");
hlButtonsTop->addWidget(add);
hlButtonsTop->addWidget(save);
hlButtonsTop->addWidget(btnSaveFile);
hlButtonsTop->addWidget(load);
cbAlgorithm->addItem("Spaced", SPACED);
cbAlgorithm->addItem("Random", RANDOM);
@@ -985,7 +1021,7 @@ int main(int argc, char *argv[]) {
editor->setText("");
});
QObject::connect(load, &QToolButton::clicked, &reloadMdem);
QObject::connect(save, &QToolButton::clicked, []() {
QObject::connect(btnSaveFile, &QToolButton::clicked, []() {
saveMdem();
});
QObject::connect(
@@ -1000,8 +1036,9 @@ int main(int argc, char *argv[]) {
);
}
);
}
// Mdems
{ // Mdems
QScrollArea *mdemScroll = new QScrollArea();
QWidget *mdemContainer = new QWidget();
hMdemScroll = new QVBoxLayout();
@@ -1010,14 +1047,14 @@ int main(int argc, char *argv[]) {
mdemContainer->setLayout(hMdemScroll);
rightLayout->addWidget(mdemScroll);
hMdemScroll->addItem(mdemSpacer);
}
// Pagination
{ // Pagination
hSplitter->addWidget(leftWidget);
hSplitter->addWidget(rightWidget);
hSplitter->setStretchFactor(0, 1);
hSplitter->setStretchFactor(1, 3);
auto pagination = new QWidget();
auto hPagination = new QHBoxLayout();
pagination->setLayout(hPagination);
@@ -1080,6 +1117,7 @@ int main(int argc, char *argv[]) {
paginationLabel = new QLabel();
hPagination->addWidget(paginationLabel);
rightLayout->addWidget(pagination);
}
initTrainWindow();
@@ -1090,5 +1128,9 @@ int main(int argc, char *argv[]) {
pickDirectory(QString::fromStdString(currentPath));
}
QShortcut* shortcutSaveFile = new QShortcut(QKeySequence("Ctrl+S"), &window);
QObject::connect(shortcutSaveFile, &QShortcut::activated, []() {
saveMdem();
});
return app.exec();
}

View File

@@ -29,6 +29,7 @@
#include <iostream>
#include <QStyledItemDelegate>
#include <QPainter>
#include <QShortcut>
#include "main.h"
#include "trainWindow.h"
@@ -295,6 +296,13 @@ void hideQuestionElements() {
btnTriggerAnswer->hide();
}
void showFeedBackButtons() {
btnNotRemembered->show();
btnHard->show();
btnMedium->show();
btnEasy->show();
}
void setupAnswerQuestion(MultiElementQuestion *question) {
lQuestionText->setText(
QString::fromStdString(question->QuestionText)
@@ -316,10 +324,9 @@ void setupAnswerQuestion(MultiElementQuestion *question) {
[](bool checked) {
answerText->show();
btnTriggerAnswer->hide();
btnNotRemembered->show();
btnHard->show();
btnMedium->show();
btnEasy->show();
if (practiceAlgoritm == SPACED) {
showFeedBackButtons();
}
}
);
btnTriggerAnswer->show();
@@ -360,10 +367,7 @@ void setupOrderQuestion(MultiElementQuestion *question) {
btnTriggerAnswer->hide();
if (practiceAlgoritm == SPACED) {
btnNotRemembered->show();
btnHard->show();
btnMedium->show();
btnEasy->show();
showFeedBackButtons();
}
}
);
@@ -402,6 +406,9 @@ void setupMultiChoiceQuestion(MultiElementQuestion *question) {
multiChoiceList->update();
}
btnTriggerAnswer->hide();
if (practiceAlgoritm == SPACED) {
showFeedBackButtons();
}
}
);
btnTriggerAnswer->show();
@@ -494,6 +501,9 @@ void setupGroupQuestion(GroupQuestion *question) {
groupView->itemList.update();
}
btnTriggerAnswer->hide();
if (practiceAlgoritm == SPACED) {
showFeedBackButtons();
}
}
);
btnTriggerAnswer->show();
@@ -515,10 +525,10 @@ void setupQuestion(Question *question) {
setupAnswerQuestion(q);
break;
}
} else if (auto *question = dynamic_cast<GroupQuestion*>(
currentBuffer->questions[currentQuestionIndex])
} else if (
auto *q = dynamic_cast<GroupQuestion*>(question)
) {
setupGroupQuestion(question);
setupGroupQuestion(q);
}
}
@@ -590,7 +600,6 @@ void setupNextQuestion() {
}
if (questionCandidates.size() > 0) {
auto i = randomIndex(&questionCandidates);
setupQuestion(questionCandidates[i]);
setupQuestion(
questionCandidates[randomIndex(&questionCandidates)]
);
@@ -601,7 +610,7 @@ void setupNextQuestion() {
}
}
}
update();
update(true);
} break;
}
}
@@ -628,7 +637,7 @@ void setCooldownHours(int cooldown) {
currentBuffer->trainedAt = time;
auto question = currentBuffer->questions[currentQuestionIndex];
question->Cooldown = cooldown;
update();
update(true);
}
void initTrainWindow() {
@@ -663,6 +672,11 @@ void initTrainWindow() {
QObject::connect(btnSaveProgress, &QToolButton::clicked, []() {
saveMdem();
});
QShortcut* shortcutSaveProgress = new QShortcut(QKeySequence("Ctrl+S"), trainWindow);
QObject::connect(shortcutSaveProgress, &QShortcut::activated, []() {
saveMdem();
});
}