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

View File

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

View File

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

View File

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