refactoring the source files

This commit is contained in:
jorenchik
2024-10-26 21:44:42 +03:00
parent 9367f9a6e4
commit cf50188f66
11 changed files with 1309 additions and 1214 deletions

View File

@@ -4,5 +4,10 @@ project(Mdemory LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(
CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} -g3 -O0 -ggdb -fvar-tracking-assignments -fno-inline"
)
add_subdirectory(transpiler)
add_subdirectory(qtapp)

View File

@@ -1,28 +0,0 @@
#pragma once
#include <vector>
#include <QSettings>
#include "parser.h"
void update(bool isChanged = false);
void saveMdem();
struct MdemBuffer {
std::vector<Question*> questions = std::vector<Question*>();
time_t trainedAt = 0;
bool error = false;
bool isModified = false;
};
void updateMdemInfo(std::string filename = "", bool isChanged = true);
extern QSettings *settings;
#define SETTING_TIMEZONE "timezone"
#define SETTING_CHARACTER_WRAP "characterWrap"
#define SETTING_NOT_REMEMBERED "notRemembered"
#define SETTING_HARD "hard"
#define SETTING_MEDIUM "medium"
#define SETTING_EASY "easy"

58
src/include/mdemList.h Normal file
View File

@@ -0,0 +1,58 @@
#pragma once
#include <qapplication.h>
#include <qboxlayout.h>
#include <qlabel.h>
#include <qmainwindow.h>
#include <qtoolbutton.h>
#include <qwidget.h>
#include <vector>
#include <QSettings>
#include "parser.h"
struct MdemBuffer {
std::vector<Question*> questions = std::vector<Question*>();
time_t trainedAt = 0;
bool error = false;
bool isModified = false;
};
struct Mdem {
QWidget wMdem;
QVBoxLayout vMdem;
QLabel wFrontText;
QWidget wFront;
QHBoxLayout hFront;
QWidget wBack;
QVBoxLayout hBack;
QToolButton editButton;
QToolButton deleteButton;
QToolButton showButton;
int labelCount;
QVector<QLabel*> backLabels;
Question *question;
};
struct ErrorView {
QWidget box;
QVBoxLayout layout;
QLabel label;
};
struct Page {
size_t start;
size_t end;
};
void update(bool isChanged = false);
void saveMdem();
void updateMdemInfo(std::string filename = "", bool isChanged = true);
QMainWindow *initMdemListWindow();
#define SETTING_TIMEZONE "timezone"
#define SETTING_CHARACTER_WRAP "characterWrap"
#define SETTING_NOT_REMEMBERED "notRemembered"
#define SETTING_HARD "hard"
#define SETTING_MEDIUM "medium"
#define SETTING_EASY "easy"

7
src/include/settings.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <qsettings.h>
#include <qwidget.h>
extern QSettings *settings;
QWidget *initSettings();

View File

@@ -3,7 +3,7 @@
#include <QMainWindow>
#include "main.h"
#include "parser.h"
#include "mdemList.h"
extern QMainWindow *trainWindow;

View File

@@ -19,7 +19,9 @@ include_directories(/usr/include/qt/Qsci)
add_executable(
MdemoryApp
main.cpp
mdemList.cpp
trainWindow.cpp
settings.cpp
)
target_link_libraries(MdemoryApp Qt5::Widgets /usr/lib/libqscintilla2_qt5.so api)

File diff suppressed because it is too large Load Diff

1059
src/qtapp/mdemList.cpp Normal file

File diff suppressed because it is too large Load Diff

136
src/qtapp/settings.cpp Normal file
View File

@@ -0,0 +1,136 @@
#include <qabstractbutton.h>
#include <qapplication.h>
#include <qboxlayout.h>
#include <qcombobox.h>
#include <qdialog.h>
#include <qlabel.h>
#include <qlayoutitem.h>
#include <qmainwindow.h>
#include <qnamespace.h>
#include <qobjectdefs.h>
#include <qsettings.h>
#include <qsizepolicy.h>
#include <qt/QtWidgets/qwidget.h>
#include <qtoolbutton.h>
#include <qwidget.h>
#include <qwindow.h>
#include <qwindowdefs.h>
#include <Qsci/qsciscintilla.h>
#include <Qsci/qscilexercpp.h>
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QToolButton>
#include <QFileSystemModel>
#include <QTreeView>
#include <QSplitter>
#include <QVariant>
#include <QMessageBox>
#include <QScrollArea>
#include <QSpacerItem>
#include <QFile>
#include <QTime>
#include <QRegularExpression>
#include <QStringList>
#include <QListView>
#include <QWindow>
#include <QMenuBar>
#include <QMenu>
#include <QFileDialog>
#include <qabstractitemmodel.h>
#include <QFormLayout>
#include <QSettings>
#include <QLineEdit>
#include <QComboBox>
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QCheckBox>
#include <QPushButton>
#include <QStandardPaths>
#include <QShortcut>
#include <QWidget>
#include "mdemList.h"
#include "api.h"
#include "qscilexer.h"
QSettings *settings;
QWidget *initSettings () {
QString configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
QDir().mkpath(configDir);
QString settingsFile = configDir + "/mdem.ini";
settings = new QSettings(settingsFile, QSettings::IniFormat);
auto* settingsWindow = new QWidget;
settingsWindow->setWindowTitle("Settings");
auto formLayout = new QFormLayout;
auto characterWrap = new QSpinBox;
characterWrap->setRange(30, 150);
formLayout->addRow("Character wrap in code gen [30-150]:", characterWrap);
auto* timezone = new QSpinBox;
timezone->setRange(-12, 12);
formLayout->addRow("Timezone as number (e.g. +2 as 2):", timezone);
auto* notRemembered = new QDoubleSpinBox;
notRemembered->setRange(0, 100);
formLayout->addRow("Not remembered:", notRemembered);
auto* hard = new QDoubleSpinBox;
hard->setRange(0, 100);
formLayout->addRow("Hard:", hard);
auto* medium = new QDoubleSpinBox;
medium->setRange(0, 100);
formLayout->addRow("Medium:", medium);
auto* easy = new QDoubleSpinBox;
easy->setRange(0, 100);
formLayout->addRow("Easy:", easy);
auto* btnSaveSettings = new QPushButton("Save");
auto* mainLayout = new QVBoxLayout;
// @Improve: validate setting values
characterWrap->setValue(settings->value(SETTING_CHARACTER_WRAP).toInt());
timezone->setValue(settings->value(SETTING_TIMEZONE).toInt());
notRemembered->setValue(settings->value(SETTING_NOT_REMEMBERED).toDouble());
hard->setValue(settings->value(SETTING_HARD).toDouble());
medium->setValue(settings->value(SETTING_MEDIUM).toDouble());
easy->setValue(settings->value(SETTING_EASY).toDouble());
auto saveSettings = [characterWrap, timezone, notRemembered, hard, medium, easy]() {
settings->setValue(SETTING_CHARACTER_WRAP, characterWrap->value());
settings->setValue(SETTING_TIMEZONE, timezone->value());
settings->setValue(SETTING_NOT_REMEMBERED, notRemembered->value());
settings->setValue(SETTING_HARD, hard->value());
settings->setValue(SETTING_MEDIUM, medium->value());
settings->setValue(SETTING_EASY, easy->value());
};
QObject::connect(
btnSaveSettings,
&QPushButton::clicked,
[saveSettings]() {
saveSettings();
}
);
QShortcut* shortcutSave = new QShortcut(QKeySequence("Ctrl+S"), settingsWindow);
QObject::connect(shortcutSave, &QShortcut::activated, [saveSettings]() {
saveSettings();
});
mainLayout->addLayout(formLayout);
mainLayout->addWidget(btnSaveSettings);
settingsWindow->setLayout(mainLayout);
return settingsWindow;
}

View File

@@ -31,7 +31,8 @@
#include <QPainter>
#include <QShortcut>
#include "main.h"
#include "settings.h"
#include "mdemList.h"
#include "trainWindow.h"
#include "parser.h"
@@ -75,15 +76,15 @@ public:
Qt::GlobalColor color;
auto colorIdx = index.data(Qt::UserRole + 1).toInt() ;
switch (colorIdx) {
case NEUTRAL:
case NEUTRAL: {
color = Qt::lightGray;
break;
case INCORRECT:
} break;
case INCORRECT: {
color = Qt::red;
break;
case CORRECT:
} break;
case CORRECT: {
color = Qt::green;
break;
} break;
}
painter->setOpacity(0.5);
if (color) {
@@ -248,7 +249,7 @@ QToolButton *btnEasy;
QStandardItem* acquireItem() {
if (itemPool.size() <= 0) {
for (int i = 0; i < ITEM_POOL_CHUNK; ++i) {
for (size_t i = 0; i < ITEM_POOL_CHUNK; ++i) {
itemPool.push_back(new QStandardItem);
}
}
@@ -268,7 +269,7 @@ void releaseAllItems() {
std::endl;
auto releaseAllInModel = [](QStandardItemModel *model) {
auto itemCount = model->rowCount();
for (int i = 0; i < itemCount; ++i) {
for (size_t i = 0; i < itemCount; ++i) {
auto item = model->item(0);
model->takeRow(item->row());
releaseItem(&item);
@@ -357,7 +358,7 @@ void setupOrderQuestion(MultiElementQuestion *question) {
btnTriggerAnswer,
&QToolButton::clicked,
[question](bool checked) {
for (int i = 0; i < orderModel->rowCount(); ++i) {
for (size_t i = 0; i < orderModel->rowCount(); ++i) {
auto item = orderModel->item(i, 0);
auto text = item->text();
auto isCorrect = question->Choices[i].Answer.compare(text.toStdString()) == 0;
@@ -399,7 +400,7 @@ void setupMultiChoiceQuestion(MultiElementQuestion *question) {
btnTriggerAnswer,
&QToolButton::clicked,
[question](bool checked) {
for (int i = 0; i < multiChoiceModel->rowCount(); ++i) {
for (size_t i = 0; i < multiChoiceModel->rowCount(); ++i) {
auto item = multiChoiceModel->item(i, 0);
auto isCorrect = question->Choices[i].IsCorrect == (item->checkState() == Qt::Checked);
if (isCorrect) {
@@ -459,7 +460,7 @@ void setupGroupQuestion(GroupQuestion *question) {
for (int k = 0; k < groupViews.size(); k++) {
groupViews[k]->widget.hide();
}
for (int i = 0; i < question->Groups.size(); i++) {
for (size_t i = 0; i < question->Groups.size(); i++) {
GroupView *groupView;
if (i < groupViews.size()) {
groupView = groupViews[i];
@@ -479,11 +480,11 @@ void setupGroupQuestion(GroupQuestion *question) {
btnTriggerAnswer,
&QToolButton::clicked,
[question](bool checked) {
for (int i = 0; i < groupItemModel->rowCount(); ++i) {
for (size_t i = 0; i < groupItemModel->rowCount(); ++i) {
auto item = groupItemModel->item(i, 0);
item->setData(INCORRECT, Qt::UserRole + 1);
}
for (int i = 0; i < groupViews.size(); i++) {
for (size_t i = 0; i < groupViews.size(); i++) {
auto groupView = groupViews[i];
auto group = question->Groups[i];
for (int j = 0; j < groupView->itemModel.rowCount(); ++j) {
@@ -568,7 +569,7 @@ void setupNextQuestion() {
setupQuestion(practiceBuffer->questions[currentQuestionIndex]);
}
updatePaginationVisibility();
} break;
} break;
case RANDOM: {
auto questionCandidates = practiceBuffer->questions;
if (currentQuestionIndex > -1) {
@@ -584,13 +585,13 @@ void setupNextQuestion() {
}
}
}
} break;
} break;
case SPACED: {
auto questionCandidates = std::vector<Question*>();
time_t time = getTime();
auto lastTrainedAt = practiceBuffer->trainedAt;
practiceBuffer->trainedAt = time;
for (int i = 0; i < practiceBuffer->questions.size(); ++i) {
for (size_t i = 0; i < practiceBuffer->questions.size(); ++i) {
auto cooldownSeconds = practiceBuffer->questions[i]->Cooldown * 3600;
auto cooldownEndsAt = lastTrainedAt + cooldownSeconds;
if (i != currentQuestionIndex && cooldownEndsAt <= time) {
@@ -615,7 +616,7 @@ void setupNextQuestion() {
}
}
update(true);
} break;
} break;
}
}

View File

@@ -113,6 +113,7 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
column = 0;
}
// Add escape char
if (c == '\\') {
i += 1;
if (i < fileRunes.size()) {
@@ -139,7 +140,7 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
// EmitTokens
switch (c) {
case '[':
case '[': {
makeTokenWithTokenBuffer(
TokenType::CooldownStart,
1,
@@ -149,8 +150,8 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
previousColumn = column;
textStarted = false;
identifierStarted = true;
break;
case ']':
} break;
case ']': {
if (!identifierStarted) {
return {
tokens,
@@ -168,8 +169,8 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
previousColumn = column;
textStarted = false;
identifierStarted = false;
break;
case '-':
} break;
case '-': {
makeTokenWithTokenBuffer(
TokenType::ElementDashStart,
1,
@@ -178,8 +179,8 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
previousRow = row;
previousColumn = column;
textStarted = false;
break;
case '^':
} break;
case '^': {
makeTokenWithTokenBuffer(
TokenType::ElementOrderModifier,
1,
@@ -188,8 +189,8 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
previousRow = row;
previousColumn = column;
textStarted = false;
break;
case ':':
} break;
case ':': {
makeTokenWithTokenBuffer(
TokenType::MatchGroupEnd,
1,
@@ -198,8 +199,8 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
previousRow = row;
previousColumn = column;
textStarted = false;
break;
case '>':
} break;
case '>': {
makeTokenWithTokenBuffer(
TokenType::QuestionEnd,
1,
@@ -207,8 +208,9 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
);
previousRow = row;
previousColumn = column;
break;
case '+':
textStarted = false;
} break;
case '+': {
makeTokenWithTokenBuffer(
TokenType::ElementPlusStart,
1,
@@ -217,7 +219,7 @@ Result<std::vector<Token>> tokenizeMdem(const std::string& fileRunes) {
previousRow = row;
previousColumn = column;
textStarted = false;
break;
} break;
}
column += 1;
@@ -262,7 +264,7 @@ std::string Token::ToString(const TokenType* ttype) {
case TokenType::Cooldown: return "cooldown";
case TokenType::CooldownStart: return "start of cooldown";
case TokenType::CooldownEnd: return "end of cooldown";
case TokenType::StartOfFile: return "start of the file";
case TokenType::StartOfFile: return "start of the file";
case TokenType::EndOfFile: return "end of file";
default: return "unrecognized token";
}