mirror of
https://github.com/jorenchik/mdemory.git
synced 2026-03-22 00:26:21 +00:00
refactoring the source files
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
58
src/include/mdemList.h
Normal 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
7
src/include/settings.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <qsettings.h>
|
||||
#include <qwidget.h>
|
||||
|
||||
extern QSettings *settings;
|
||||
QWidget *initSettings();
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <QMainWindow>
|
||||
|
||||
#include "main.h"
|
||||
#include "parser.h"
|
||||
#include "mdemList.h"
|
||||
|
||||
extern QMainWindow *trainWindow;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
1157
src/qtapp/main.cpp
1157
src/qtapp/main.cpp
File diff suppressed because it is too large
Load Diff
1059
src/qtapp/mdemList.cpp
Normal file
1059
src/qtapp/mdemList.cpp
Normal file
File diff suppressed because it is too large
Load Diff
136
src/qtapp/settings.cpp
Normal file
136
src/qtapp/settings.cpp
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user