mirror of
https://github.com/jorenchik/mdemory.git
synced 2026-03-22 00:26:21 +00:00
refactoring, shortcuts, layout changes
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <qapplication.h>
|
#include <qapplication.h>
|
||||||
#include <qboxlayout.h>
|
#include <qboxlayout.h>
|
||||||
|
#include <qcombobox.h>
|
||||||
#include <qlabel.h>
|
#include <qlabel.h>
|
||||||
#include <qmainwindow.h>
|
#include <qmainwindow.h>
|
||||||
#include <qtoolbutton.h>
|
#include <qtoolbutton.h>
|
||||||
@@ -45,6 +46,25 @@ struct Page {
|
|||||||
size_t end;
|
size_t end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Pagination {
|
||||||
|
int currentPage = -1;
|
||||||
|
std::vector<Page> pages;
|
||||||
|
QList<QToolButton*> paginationButtons;
|
||||||
|
QToolButton prevButton;
|
||||||
|
QToolButton firstButton;
|
||||||
|
QToolButton lastButton;
|
||||||
|
QToolButton nextButton;
|
||||||
|
QLabel paginationLabel;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Toolbar {
|
||||||
|
QToolButton btnAdd;
|
||||||
|
QToolButton btnSave;
|
||||||
|
QToolButton btnLoad;
|
||||||
|
QComboBox cbAlgorithm;
|
||||||
|
QToolButton btnPractice;
|
||||||
|
};
|
||||||
|
|
||||||
void update(bool isChanged = false);
|
void update(bool isChanged = false);
|
||||||
void saveMdem();
|
void saveMdem();
|
||||||
void updateMdemInfo(std::string filename = "", bool isChanged = true);
|
void updateMdemInfo(std::string filename = "", bool isChanged = true);
|
||||||
@@ -57,3 +77,9 @@ QMainWindow *initMdemListWindow();
|
|||||||
#define SETTING_HARD "hard"
|
#define SETTING_HARD "hard"
|
||||||
#define SETTING_MEDIUM "medium"
|
#define SETTING_MEDIUM "medium"
|
||||||
#define SETTING_EASY "easy"
|
#define SETTING_EASY "easy"
|
||||||
|
|
||||||
|
#define TEXT_LG = 20
|
||||||
|
#define ERROR_POOL_CHUNK 50
|
||||||
|
#define DISTANCE 2
|
||||||
|
#define PER_PAGE 8
|
||||||
|
#define MDEM_BACKGROUND "#F7F7F7"
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <qmainwindow.h>
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "mdemList.h"
|
#include "mdemList.h"
|
||||||
|
|
||||||
extern QMainWindow *trainWindow;
|
|
||||||
|
|
||||||
enum PracticeAlgorithm {
|
enum PracticeAlgorithm {
|
||||||
PRIMARY,
|
PRIMARY,
|
||||||
RANDOM,
|
RANDOM,
|
||||||
SPACED,
|
SPACED,
|
||||||
};
|
};
|
||||||
|
|
||||||
void initTrainWindow();
|
|
||||||
|
|
||||||
void initiatePractice(
|
void initiatePractice(
|
||||||
MdemBuffer *mdemBuffer,
|
MdemBuffer *mdemBuffer,
|
||||||
PracticeAlgorithm algorithm
|
PracticeAlgorithm algorithm
|
||||||
);
|
);
|
||||||
|
|
||||||
void hideQuestionElements();
|
void hideQuestionElements();
|
||||||
|
QMainWindow *initTrainWindow();
|
||||||
|
|||||||
@@ -5,6 +5,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <regex>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <qabstractbutton.h>
|
#include <qabstractbutton.h>
|
||||||
#include <qapplication.h>
|
#include <qapplication.h>
|
||||||
#include <qboxlayout.h>
|
#include <qboxlayout.h>
|
||||||
@@ -22,9 +26,6 @@
|
|||||||
#include <qwidget.h>
|
#include <qwidget.h>
|
||||||
#include <qwindow.h>
|
#include <qwindow.h>
|
||||||
#include <qwindowdefs.h>
|
#include <qwindowdefs.h>
|
||||||
#include <regex>
|
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <Qsci/qsciscintilla.h>
|
#include <Qsci/qsciscintilla.h>
|
||||||
#include <Qsci/qscilexercpp.h>
|
#include <Qsci/qscilexercpp.h>
|
||||||
@@ -70,54 +71,32 @@
|
|||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "qscilexer.h"
|
#include "qscilexer.h"
|
||||||
|
|
||||||
#define TEXT_LG = 20
|
// Memorybase.
|
||||||
#define ERROR_POOL_CHUNK 50
|
|
||||||
#define DISTANCE 2
|
|
||||||
#define PER_PAGE 8
|
|
||||||
#define MDEM_BACKGROUND "#F7F7F7"
|
|
||||||
|
|
||||||
// Memorybase info.
|
|
||||||
// @Improve: set the default directory for convenience. It should be configured by user
|
|
||||||
// or set to "".
|
|
||||||
QString currentPath = "";
|
QString currentPath = "";
|
||||||
std::string currentMdem = "";
|
std::string currentMdem = "";
|
||||||
QFileSystemModel *model;
|
QFileSystemModel *model;
|
||||||
QTreeView *mdemList;
|
QTreeView *mdemList;
|
||||||
QLabel *membaseLabel;
|
|
||||||
|
|
||||||
std::map<std::string, MdemBuffer*> buffers;
|
std::map<std::string, MdemBuffer*> buffers;
|
||||||
MdemBuffer *currentMdemBuffer = nullptr;
|
MdemBuffer *currentMdemBuffer;
|
||||||
|
|
||||||
// Mdem scroll list.
|
// Mdem list.
|
||||||
std::vector<Mdem*> mdems = std::vector<Mdem*>();
|
std::vector<Mdem*> mdems = std::vector<Mdem*>();
|
||||||
QVBoxLayout *hMdemScroll;
|
QVBoxLayout *hMdemScroll;
|
||||||
QSpacerItem *mdemSpacer;
|
QSpacerItem *mdemSpacer;
|
||||||
ErrorView* errorView;
|
ErrorView *errorView;
|
||||||
|
Pagination *pagination;
|
||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
Mdem* editMdem;
|
|
||||||
|
|
||||||
// Pagination
|
|
||||||
int currentPage = -1;
|
|
||||||
std::vector<Page> pages;
|
|
||||||
QList<QToolButton*> paginationButtons;
|
|
||||||
QToolButton* prevButton;
|
|
||||||
QToolButton* firstButton;
|
|
||||||
QToolButton* lastButton;
|
|
||||||
QToolButton* nextButton;
|
|
||||||
QLabel* paginationLabel;
|
|
||||||
|
|
||||||
// Top layout.
|
|
||||||
QLabel *deckListLabel;
|
|
||||||
QToolButton *add;
|
|
||||||
QToolButton *btnSaveFile;
|
|
||||||
QToolButton *load;
|
|
||||||
QToolButton *practice;
|
|
||||||
|
|
||||||
QsciScintilla *editor;
|
QsciScintilla *editor;
|
||||||
QMainWindow* editorWindow;
|
QMainWindow *editorWindow;
|
||||||
|
Mdem *editMdem;
|
||||||
|
|
||||||
const std::regex lastPathElementExp = std::regex("(.+\\/)*(.+)");
|
// Top labels.
|
||||||
|
QLabel *membaseLabel;
|
||||||
|
QLabel *mdemLabel;
|
||||||
|
QLabel *lastPracticeLabel;
|
||||||
|
|
||||||
|
QMainWindow *trainWindow;
|
||||||
|
|
||||||
void showBacklabels(Mdem *mdem) {
|
void showBacklabels(Mdem *mdem) {
|
||||||
for (size_t i = 0; i < mdem->backLabels.size(); ++i) {
|
for (size_t i = 0; i < mdem->backLabels.size(); ++i) {
|
||||||
@@ -208,7 +187,7 @@ std::string outputMdem(std::vector<Question*> questions, time_t time = 0) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void makePages() {
|
void makePages() {
|
||||||
pages.clear();
|
pagination->pages.clear();
|
||||||
auto len = currentMdemBuffer->questions.size();
|
auto len = currentMdemBuffer->questions.size();
|
||||||
auto pageAmount = len / PER_PAGE;
|
auto pageAmount = len / PER_PAGE;
|
||||||
if (len % PER_PAGE != 0) {
|
if (len % PER_PAGE != 0) {
|
||||||
@@ -220,7 +199,9 @@ void makePages() {
|
|||||||
if (i == currentMdemBuffer->questions.size() / PER_PAGE) {
|
if (i == currentMdemBuffer->questions.size() / PER_PAGE) {
|
||||||
amount = currentMdemBuffer->questions.size() % PER_PAGE;
|
amount = currentMdemBuffer->questions.size() % PER_PAGE;
|
||||||
}
|
}
|
||||||
pages.push_back(Page{startingIndex, startingIndex + amount});
|
pagination->pages.push_back(
|
||||||
|
Page{startingIndex, startingIndex + amount}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,6 +270,7 @@ void setupMdem(Mdem *mdem, Question *question) {
|
|||||||
void SwitchPage(int pageIdx);
|
void SwitchPage(int pageIdx);
|
||||||
|
|
||||||
std::string getFilename(std::string path) {
|
std::string getFilename(std::string path) {
|
||||||
|
static const std::regex lastPathElementExp = std::regex("(.+\\/)*(.+)");
|
||||||
std::smatch matches;
|
std::smatch matches;
|
||||||
auto filenameMatched = std::regex_search(path, matches, lastPathElementExp);
|
auto filenameMatched = std::regex_search(path, matches, lastPathElementExp);
|
||||||
return matches[2].str();
|
return matches[2].str();
|
||||||
@@ -302,15 +284,19 @@ void updateMdemInfo(std::string filename, bool isChanged) {
|
|||||||
if (isChanged) {
|
if (isChanged) {
|
||||||
ss << "*";
|
ss << "*";
|
||||||
}
|
}
|
||||||
|
mdemLabel->setText(QString::fromStdString(ss.str()));
|
||||||
|
ss.str("");
|
||||||
|
|
||||||
if (currentMdemBuffer->trainedAt > 0) {
|
if (currentMdemBuffer->trainedAt > 0) {
|
||||||
std::tm* tm = std::localtime(¤tMdemBuffer->trainedAt);
|
std::tm* tm = std::localtime(¤tMdemBuffer->trainedAt);
|
||||||
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);
|
||||||
ss << std::endl << "Last practiced: " << std::string(buffer);
|
ss << "Last practiced: " << std::string(buffer);
|
||||||
}
|
}
|
||||||
deckListLabel->setText(QString::fromStdString(ss.str()));
|
lastPracticeLabel->setText(QString::fromStdString(ss.str()));
|
||||||
} else {
|
} else {
|
||||||
deckListLabel->setText("");
|
mdemLabel->setText("");
|
||||||
|
lastPracticeLabel->setText("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -377,7 +363,7 @@ Mdem* makeMdem() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
makePages();
|
makePages();
|
||||||
SwitchPage(currentPage);
|
SwitchPage(pagination->currentPage);
|
||||||
}
|
}
|
||||||
if (editMdem == mdem) {
|
if (editMdem == mdem) {
|
||||||
editorWindow->hide();
|
editorWindow->hide();
|
||||||
@@ -455,8 +441,8 @@ void CreateMdems(std::vector<Question*>& questions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void update(bool isChanged) {
|
void update(bool isChanged) {
|
||||||
if (currentPage > -1) {
|
if (pagination->currentPage > -1) {
|
||||||
SwitchPage(currentPage);
|
SwitchPage(pagination->currentPage);
|
||||||
}
|
}
|
||||||
if (currentMdem.length() > 0) {
|
if (currentMdem.length() > 0) {
|
||||||
updateMdemInfo(getFilename(currentMdem), isChanged);
|
updateMdemInfo(getFilename(currentMdem), isChanged);
|
||||||
@@ -464,17 +450,17 @@ void update(bool isChanged) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SwitchPage(int pageIdx) {
|
void SwitchPage(int pageIdx) {
|
||||||
currentPage = pageIdx;
|
pagination->currentPage = pageIdx;
|
||||||
|
|
||||||
// Hide all pagination buttons
|
// Hide all pagination buttons
|
||||||
for (auto& button : paginationButtons) {
|
for (auto& button : pagination->paginationButtons) {
|
||||||
button->hide();
|
button->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
int l = 0;
|
int l = 0;
|
||||||
char buffer[50];
|
char buffer[50];
|
||||||
snprintf(buffer, sizeof(buffer), "Page: %d", pageIdx + 1);
|
snprintf(buffer, sizeof(buffer), "Page: %d", pageIdx + 1);
|
||||||
paginationLabel->setText(buffer);
|
pagination->paginationLabel.setText(buffer);
|
||||||
|
|
||||||
// Hide widgets in mdems
|
// Hide widgets in mdems
|
||||||
for (auto& mdem : mdems) {
|
for (auto& mdem : mdems) {
|
||||||
@@ -486,8 +472,8 @@ void SwitchPage(int pageIdx) {
|
|||||||
|
|
||||||
// Update pagination buttons
|
// Update pagination buttons
|
||||||
for (int k = -DISTANCE; k <= DISTANCE; ++k) {
|
for (int k = -DISTANCE; k <= DISTANCE; ++k) {
|
||||||
if (pageIdx + k >= 0 && pageIdx + k < pages.size()) {
|
if (pageIdx + k >= 0 && pageIdx + k < pagination->pages.size()) {
|
||||||
auto button = paginationButtons[l];
|
auto button = pagination->paginationButtons[l];
|
||||||
snprintf(buffer, sizeof(buffer), "%d", pageIdx + k + 1);
|
snprintf(buffer, sizeof(buffer), "%d", pageIdx + k + 1);
|
||||||
button->setText(buffer);
|
button->setText(buffer);
|
||||||
|
|
||||||
@@ -501,41 +487,41 @@ void SwitchPage(int pageIdx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle first and last buttons
|
// Handle first and last buttons
|
||||||
if (pageIdx > 0 && pages.size() > 1) {
|
if (pageIdx > 0 && pagination->pages.size() > 1) {
|
||||||
firstButton->show();
|
pagination->firstButton.show();
|
||||||
} else {
|
} else {
|
||||||
firstButton->hide();
|
pagination->firstButton.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pageIdx < pages.size() - 1 && pages.size() > 1) {
|
if (pageIdx < pagination->pages.size() - 1 && pagination->pages.size() > 1) {
|
||||||
lastButton->show();
|
pagination->lastButton.show();
|
||||||
} else {
|
} else {
|
||||||
lastButton->hide();
|
pagination->lastButton.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle next and previous buttons
|
// Handle next and previous buttons
|
||||||
if (!pages.empty() && currentPage < pages.size() - 1) {
|
if (!pagination->pages.empty() && pagination->currentPage < pagination->pages.size() - 1) {
|
||||||
nextButton->show();
|
pagination->nextButton.show();
|
||||||
} else {
|
} else {
|
||||||
nextButton->hide();
|
pagination->nextButton.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pages.empty() && currentPage >= 1) {
|
if (!pagination->pages.empty() && pagination->currentPage >= 1) {
|
||||||
prevButton->show();
|
pagination->prevButton.show();
|
||||||
} else {
|
} else {
|
||||||
prevButton->hide();
|
pagination->prevButton.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
Page page;
|
Page page;
|
||||||
if (pages.size() <= 0) {
|
if (pagination->pages.size() <= 0) {
|
||||||
page = Page();
|
page = Page();
|
||||||
} else if (pageIdx < pages.size()){
|
} else if (pageIdx < pagination->pages.size()){
|
||||||
page = pages[pageIdx];
|
page = pagination->pages[pageIdx];
|
||||||
} else {
|
} else {
|
||||||
if (pageIdx - 1 < pages.size()) {
|
if (pageIdx - 1 < pagination->pages.size()) {
|
||||||
page = pages[pageIdx -1];
|
page = pagination->pages[pageIdx -1];
|
||||||
} else {
|
} else {
|
||||||
page = pages[0];
|
page = pagination->pages[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,7 +637,6 @@ void reloadMdem(std::string path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hideQuestionElements();
|
hideQuestionElements();
|
||||||
trainWindow->close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void pickDirectory(QString directory) {
|
void pickDirectory(QString directory) {
|
||||||
@@ -764,7 +749,12 @@ void saveMdem() {
|
|||||||
|
|
||||||
QMainWindow *initMdemListWindow() {
|
QMainWindow *initMdemListWindow() {
|
||||||
QMainWindow* window = new QMainWindow;
|
QMainWindow* window = new QMainWindow;
|
||||||
|
pagination = new Pagination;
|
||||||
|
auto *toolbar = new Toolbar();
|
||||||
|
|
||||||
|
// Setup related windows
|
||||||
auto *settingsWindow = initSettings();
|
auto *settingsWindow = initSettings();
|
||||||
|
trainWindow = initTrainWindow();
|
||||||
|
|
||||||
{ // Menu bar.
|
{ // Menu bar.
|
||||||
QMenuBar *menuBar = new QMenuBar;
|
QMenuBar *menuBar = new QMenuBar;
|
||||||
@@ -796,7 +786,7 @@ QMainWindow *initMdemListWindow() {
|
|||||||
window->setMenuBar(menuBar);
|
window->setMenuBar(menuBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Setup editor.
|
{ // Editor.
|
||||||
editorWindow = new QMainWindow;
|
editorWindow = new QMainWindow;
|
||||||
|
|
||||||
editorWindow->setWindowTitle("QScintilla Simple Editor");
|
editorWindow->setWindowTitle("QScintilla Simple Editor");
|
||||||
@@ -838,33 +828,127 @@ QMainWindow *initMdemListWindow() {
|
|||||||
editorWindow->setCentralWidget(wEditor);
|
editorWindow->setCentralWidget(wEditor);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSplitter *hSplitter = new QSplitter();
|
auto *wTop = new QWidget();
|
||||||
|
{ // Top.
|
||||||
|
|
||||||
|
// Main top layout.
|
||||||
|
QHBoxLayout *hlTop = new QHBoxLayout();
|
||||||
|
wTop->setLayout(hlTop);
|
||||||
|
|
||||||
|
// Labels
|
||||||
|
auto *wLabels = new QWidget();
|
||||||
|
auto *vlLeftTop = new QVBoxLayout();
|
||||||
|
wLabels->setLayout(vlLeftTop);
|
||||||
|
wLabels->setMinimumSize(0, 40);
|
||||||
|
|
||||||
|
QString labelStyle = "font-size: 17px; font-weight: 400;";
|
||||||
|
// Memorybase label.
|
||||||
|
membaseLabel = new QLabel();
|
||||||
|
membaseLabel->setStyleSheet(labelStyle);
|
||||||
|
vlLeftTop->addWidget(membaseLabel);
|
||||||
|
|
||||||
|
// Memorybase label.
|
||||||
|
mdemLabel = new QLabel();
|
||||||
|
mdemLabel->setStyleSheet(labelStyle);
|
||||||
|
vlLeftTop->addWidget(mdemLabel);
|
||||||
|
|
||||||
|
lastPracticeLabel = new QLabel();
|
||||||
|
lastPracticeLabel->setStyleSheet(labelStyle);
|
||||||
|
vlLeftTop->addWidget(lastPracticeLabel);
|
||||||
|
|
||||||
|
// Button layout.
|
||||||
|
auto buttons = new QWidget();
|
||||||
|
auto vlButtons = new QVBoxLayout();
|
||||||
|
buttons->setLayout(vlButtons);
|
||||||
|
|
||||||
|
auto buttonsTop = new QWidget();
|
||||||
|
auto hlButtonsTop = new QHBoxLayout();
|
||||||
|
buttonsTop->setLayout(hlButtonsTop);
|
||||||
|
|
||||||
|
auto buttonsBottom = new QWidget();
|
||||||
|
auto hlButtonsBottom = new QHBoxLayout();
|
||||||
|
buttonsBottom->setLayout(hlButtonsBottom);
|
||||||
|
|
||||||
|
// Define buttons.
|
||||||
|
|
||||||
|
QObject::connect(&toolbar->btnAdd, &QToolButton::clicked, []() {
|
||||||
|
editMdem = nullptr;
|
||||||
|
editorWindow->show();
|
||||||
|
editor->setText("");
|
||||||
|
});
|
||||||
|
QObject::connect(&toolbar->btnLoad, &QToolButton::clicked, []() {
|
||||||
|
reloadMdem(currentMdem);
|
||||||
|
});
|
||||||
|
QObject::connect(&toolbar->btnSave, &QToolButton::clicked, []() {
|
||||||
|
saveMdem();
|
||||||
|
});
|
||||||
|
QObject::connect(
|
||||||
|
&toolbar->btnPractice,
|
||||||
|
&QToolButton::clicked,
|
||||||
|
[toolbar]() {
|
||||||
|
if (currentMdemBuffer) {
|
||||||
|
trainWindow->show();
|
||||||
|
trainWindow->resize(600, 300);
|
||||||
|
initiatePractice(
|
||||||
|
currentMdemBuffer,
|
||||||
|
static_cast<PracticeAlgorithm>(
|
||||||
|
toolbar->cbAlgorithm.currentData().toInt()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Button content.
|
||||||
|
toolbar->btnAdd.setText("Add");
|
||||||
|
toolbar->btnSave.setText("Save");
|
||||||
|
toolbar->btnLoad.setText("Load");
|
||||||
|
toolbar->btnPractice.setText("Practice");
|
||||||
|
|
||||||
|
toolbar->cbAlgorithm.addItem("Spaced", SPACED);
|
||||||
|
toolbar->cbAlgorithm.addItem("Random", RANDOM);
|
||||||
|
toolbar->cbAlgorithm.addItem("Primary", PRIMARY);
|
||||||
|
|
||||||
|
// Add buttons.
|
||||||
|
hlButtonsTop->addWidget(&toolbar->btnAdd);
|
||||||
|
hlButtonsTop->addWidget(&toolbar->btnSave);
|
||||||
|
hlButtonsTop->addWidget(&toolbar->btnLoad);
|
||||||
|
hlButtonsBottom->addWidget(&toolbar->cbAlgorithm);
|
||||||
|
hlButtonsBottom->addWidget(&toolbar->btnPractice);
|
||||||
|
vlButtons->addWidget(buttonsTop);
|
||||||
|
vlButtons->addWidget(buttonsBottom);
|
||||||
|
|
||||||
|
// Style buttons
|
||||||
|
hlButtonsTop->setContentsMargins(0, 0, 0, 0);
|
||||||
|
hlButtonsBottom->setContentsMargins(0, 5, 0, 0);
|
||||||
|
|
||||||
|
// Add top components.
|
||||||
|
hlTop->addWidget(wLabels);
|
||||||
|
hlTop->addStretch(1);
|
||||||
|
hlTop->addWidget(buttons);
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *leftWidget = new QWidget();
|
QWidget *leftWidget = new QWidget();
|
||||||
{ // Left side.
|
{ // 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);
|
|
||||||
|
|
||||||
|
QVBoxLayout *leftLayout = new QVBoxLayout();
|
||||||
leftWidget->setLayout(leftLayout);
|
leftWidget->setLayout(leftLayout);
|
||||||
leftLayout->addWidget(leftTop);
|
|
||||||
leftTop->setLayout(vLeftTop);
|
model = new QFileSystemModel();
|
||||||
leftTop->setMinimumSize(0, 40);
|
mdemList = new QTreeView();
|
||||||
vLeftTop->addWidget(membaseLabel);
|
|
||||||
// Hide all columns except the first one
|
|
||||||
mdemList->setModel(model);
|
mdemList->setModel(model);
|
||||||
|
currentPath = settings->value(SETTING_MEMORYBASE).toString();
|
||||||
|
if (currentPath.size() > 0) {
|
||||||
|
pickDirectory(currentPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*leftLayout->addWidget(leftTop);*/
|
||||||
|
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
mdemList,
|
mdemList,
|
||||||
&QTreeView::doubleClicked,
|
&QTreeView::doubleClicked,
|
||||||
[](const QModelIndex &index) {
|
[](const QModelIndex &index) {
|
||||||
|
trainWindow->close();
|
||||||
auto fileInfo = model->fileInfo(index);
|
auto fileInfo = model->fileInfo(index);
|
||||||
reloadMdem(fileInfo.filePath().toStdString());
|
reloadMdem(fileInfo.filePath().toStdString());
|
||||||
}
|
}
|
||||||
@@ -877,89 +961,23 @@ QMainWindow *initMdemListWindow() {
|
|||||||
leftLayout->addWidget(mdemList);
|
leftLayout->addWidget(mdemList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto wMain = new QWidget;
|
||||||
|
auto *rightWidget = new QWidget();
|
||||||
|
auto *rightLayout = new QVBoxLayout();
|
||||||
|
{ // Main layout.
|
||||||
|
auto vlMain = new QVBoxLayout;
|
||||||
|
wMain->setLayout(vlMain);
|
||||||
|
|
||||||
// RightSide
|
|
||||||
QWidget *rightWidget = new QWidget();
|
|
||||||
QVBoxLayout *rightLayout = new QVBoxLayout();
|
|
||||||
rightWidget->setLayout(rightLayout);
|
rightWidget->setLayout(rightLayout);
|
||||||
|
|
||||||
{ // Mdem list top.
|
auto *hSplitter = new QSplitter();
|
||||||
QWidget *top = new QWidget();
|
hSplitter->addWidget(leftWidget);
|
||||||
QHBoxLayout *hTop = new QHBoxLayout();
|
hSplitter->addWidget(rightWidget);
|
||||||
deckListLabel = new QLabel();
|
hSplitter->setStretchFactor(1, 3);
|
||||||
deckListLabel->setStyleSheet(
|
hSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
"font-size: 17px;"
|
|
||||||
"font-weight: 400;"
|
|
||||||
);
|
|
||||||
top->setMinimumSize(0, 40);
|
|
||||||
top->setLayout(hTop);
|
|
||||||
rightLayout->addWidget(top);
|
|
||||||
|
|
||||||
hTop->addWidget(deckListLabel);
|
vlMain->addWidget(wTop);
|
||||||
hTop->addStretch(1);
|
vlMain->addWidget(hSplitter);
|
||||||
|
|
||||||
add = new QToolButton;
|
|
||||||
btnSaveFile = new QToolButton;
|
|
||||||
load = new QToolButton;
|
|
||||||
auto cbAlgorithm = new QComboBox;
|
|
||||||
practice = new QToolButton;
|
|
||||||
|
|
||||||
// Buttons
|
|
||||||
auto buttons = new QWidget();
|
|
||||||
auto vlButtons = new QVBoxLayout();
|
|
||||||
buttons->setLayout(vlButtons);
|
|
||||||
auto buttonsTop = new QWidget();
|
|
||||||
auto hlButtonsTop = new QHBoxLayout();
|
|
||||||
buttonsTop->setLayout(hlButtonsTop);
|
|
||||||
auto buttonsBottom = new QWidget();
|
|
||||||
auto hlButtonsBottom = new QHBoxLayout();
|
|
||||||
buttonsBottom->setLayout(hlButtonsBottom);
|
|
||||||
add->setText("Add");
|
|
||||||
btnSaveFile->setText("Save");
|
|
||||||
load->setText("Load");
|
|
||||||
hlButtonsTop->addWidget(add);
|
|
||||||
hlButtonsTop->addWidget(btnSaveFile);
|
|
||||||
hlButtonsTop->addWidget(load);
|
|
||||||
cbAlgorithm->addItem("Spaced", SPACED);
|
|
||||||
cbAlgorithm->addItem("Random", RANDOM);
|
|
||||||
cbAlgorithm->addItem("Primary", PRIMARY);
|
|
||||||
practice->setText("Practice");
|
|
||||||
hlButtonsBottom->addWidget(cbAlgorithm);
|
|
||||||
hlButtonsBottom->addWidget(practice);
|
|
||||||
vlButtons->addWidget(buttonsTop);
|
|
||||||
vlButtons->addWidget(buttonsBottom);
|
|
||||||
hlButtonsTop->setContentsMargins(0, 0, 0, 0);
|
|
||||||
hlButtonsBottom->setContentsMargins(0, 5, 0, 0);
|
|
||||||
|
|
||||||
hTop->addWidget(buttons);
|
|
||||||
|
|
||||||
QObject::connect(add, &QToolButton::clicked, []() {
|
|
||||||
editMdem = nullptr;
|
|
||||||
editorWindow->show();
|
|
||||||
editor->setText("");
|
|
||||||
});
|
|
||||||
QObject::connect(load, &QToolButton::clicked, []() {
|
|
||||||
reloadMdem(currentMdem);
|
|
||||||
});
|
|
||||||
QObject::connect(btnSaveFile, &QToolButton::clicked, []() {
|
|
||||||
saveMdem();
|
|
||||||
});
|
|
||||||
QObject::connect(
|
|
||||||
practice,
|
|
||||||
&QToolButton::clicked,
|
|
||||||
[cbAlgorithm]() {
|
|
||||||
if (currentMdemBuffer) {
|
|
||||||
trainWindow->show();
|
|
||||||
trainWindow->resize(600, 300);
|
|
||||||
initiatePractice(
|
|
||||||
currentMdemBuffer,
|
|
||||||
static_cast<PracticeAlgorithm>(
|
|
||||||
cbAlgorithm->currentData().toInt()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Error.
|
{ // Error.
|
||||||
@@ -987,36 +1005,36 @@ QMainWindow *initMdemListWindow() {
|
|||||||
mdemScroll->setWidgetResizable(true);
|
mdemScroll->setWidgetResizable(true);
|
||||||
mdemContainer->setLayout(hMdemScroll);
|
mdemContainer->setLayout(hMdemScroll);
|
||||||
rightLayout->addWidget(mdemScroll);
|
rightLayout->addWidget(mdemScroll);
|
||||||
hMdemScroll->addItem(mdemSpacer);
|
mdemSpacer = new QSpacerItem(
|
||||||
|
50,
|
||||||
|
50,
|
||||||
|
QSizePolicy::Minimum,
|
||||||
|
QSizePolicy::Expanding
|
||||||
|
);
|
||||||
|
/*hMdemScroll->addItem(mdemSpacer);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Pagination
|
{ // Pagination
|
||||||
hSplitter->addWidget(leftWidget);
|
|
||||||
hSplitter->addWidget(rightWidget);
|
|
||||||
hSplitter->setStretchFactor(0, 1);
|
|
||||||
hSplitter->setStretchFactor(1, 3);
|
|
||||||
|
|
||||||
auto pagination = new QWidget();
|
auto wPagination = new QWidget();
|
||||||
auto hPagination = new QHBoxLayout();
|
auto hPagination = new QHBoxLayout();
|
||||||
pagination->setLayout(hPagination);
|
wPagination->setLayout(hPagination);
|
||||||
|
|
||||||
firstButton = new QToolButton();
|
pagination->firstButton.setText(QString::fromStdString("<<"));
|
||||||
firstButton->setText(QString::fromStdString("<<"));
|
hPagination->addWidget(&pagination->firstButton);
|
||||||
hPagination->addWidget(firstButton);
|
pagination->firstButton.hide();
|
||||||
firstButton->hide();
|
QObject::connect(&pagination->firstButton, &QToolButton::clicked, []() {
|
||||||
QObject::connect(firstButton, &QToolButton::clicked, []() {
|
if (pagination->pages.size() > 0) {
|
||||||
if (pages.size() > 0) {
|
|
||||||
SwitchPage(0);
|
SwitchPage(0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
prevButton = new QToolButton();
|
pagination->prevButton.setText(QString::fromStdString("<"));
|
||||||
prevButton->setText(QString::fromStdString("<"));
|
hPagination->addWidget(&pagination->prevButton);
|
||||||
hPagination->addWidget(prevButton);
|
pagination->prevButton.hide();
|
||||||
prevButton->hide();
|
QObject::connect(&pagination->prevButton, &QToolButton::clicked, []() {
|
||||||
QObject::connect(prevButton, &QToolButton::clicked, []() {
|
if (pagination->pages.size() > 0) {
|
||||||
if (pages.size() > 0) {
|
SwitchPage(pagination->currentPage - 1);
|
||||||
SwitchPage(currentPage - 1);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1028,57 +1046,61 @@ QMainWindow *initMdemListWindow() {
|
|||||||
QObject::connect(elButton, &QToolButton::clicked, [elButton]() {
|
QObject::connect(elButton, &QToolButton::clicked, [elButton]() {
|
||||||
auto pageNum = std::stoi(elButton->text().toStdString().c_str());
|
auto pageNum = std::stoi(elButton->text().toStdString().c_str());
|
||||||
auto pageIdx = pageNum - 1;
|
auto pageIdx = pageNum - 1;
|
||||||
if (pageIdx < pages.size()) {
|
if (pageIdx < pagination->pages.size()) {
|
||||||
SwitchPage(pageIdx);
|
SwitchPage(pageIdx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
paginationButtons.push_back(elButton);
|
pagination->paginationButtons.push_back(elButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
nextButton = new QToolButton();
|
pagination->nextButton.setText(QString::fromStdString(">"));
|
||||||
nextButton->setText(QString::fromStdString(">"));
|
hPagination->addWidget(&pagination->nextButton);
|
||||||
hPagination->addWidget(nextButton);
|
pagination->nextButton.hide();
|
||||||
nextButton->hide();
|
QObject::connect(&pagination->nextButton, &QToolButton::clicked, []() {
|
||||||
QObject::connect(nextButton, &QToolButton::clicked, []() {
|
if (pagination->pages.size() > 0) {
|
||||||
if (pages.size() > 0) {
|
SwitchPage(pagination->currentPage + 1);
|
||||||
SwitchPage(currentPage + 1);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
lastButton = new QToolButton();
|
pagination->lastButton.setText(QString::fromStdString(">>"));
|
||||||
lastButton->setText(QString::fromStdString(">>"));
|
hPagination->addWidget(&pagination->lastButton);
|
||||||
hPagination->addWidget(lastButton);
|
pagination->lastButton.hide();
|
||||||
lastButton->hide();
|
QObject::connect(&pagination->lastButton, &QToolButton::clicked, []() {
|
||||||
QObject::connect(lastButton, &QToolButton::clicked, []() {
|
if (pagination->pages.size() > 0) {
|
||||||
if (pages.size() > 0) {
|
SwitchPage(pagination->pages.size() - 1);
|
||||||
SwitchPage(pages.size() - 1);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
hPagination->addStretch(1);
|
hPagination->addStretch(1);
|
||||||
paginationLabel = new QLabel();
|
hPagination->addWidget(&pagination->paginationLabel);
|
||||||
hPagination->addWidget(paginationLabel);
|
rightLayout->addWidget(wPagination);
|
||||||
rightLayout->addWidget(pagination);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initTrainWindow();
|
{ // Setup shortcuts.
|
||||||
|
auto addShortcut = [window](QString key, std::function<void()> func) {
|
||||||
|
QShortcut* shortcut = new QShortcut(QKeySequence(key), window);
|
||||||
|
QObject::connect(shortcut, &QShortcut::activated, [func]() {
|
||||||
|
func();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
window->setCentralWidget(hSplitter);
|
addShortcut("Ctrl+S", []() {
|
||||||
window->show();
|
|
||||||
|
|
||||||
currentPath = settings->value(SETTING_MEMORYBASE).toString();
|
|
||||||
if (currentPath.size() > 0) {
|
|
||||||
pickDirectory(currentPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
QShortcut* shortcutSaveFile = new QShortcut(QKeySequence("Ctrl+S"), window);
|
|
||||||
QObject::connect(shortcutSaveFile, &QShortcut::activated, []() {
|
|
||||||
saveMdem();
|
saveMdem();
|
||||||
});
|
});
|
||||||
|
addShortcut("Ctrl+,", [settingsWindow]() {
|
||||||
QShortcut* shortcutSettings = new QShortcut(QKeySequence("Ctrl+C"), window);
|
|
||||||
QObject::connect(shortcutSettings, &QShortcut::activated, [settingsWindow]() {
|
|
||||||
settingsWindow->show();
|
settingsWindow->show();
|
||||||
});
|
});
|
||||||
|
addShortcut("Ctrl+P", [toolbar]() {
|
||||||
|
toolbar->btnPractice.click();
|
||||||
|
});
|
||||||
|
addShortcut("Ctrl+A", [toolbar]() {
|
||||||
|
toolbar->btnAdd.click();
|
||||||
|
});
|
||||||
|
addShortcut("Ctrl+L", [toolbar]() {
|
||||||
|
toolbar->btnLoad.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window->setCentralWidget(wMain);
|
||||||
|
window->show();
|
||||||
return window;
|
return window;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <format>
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <format>
|
|
||||||
#include <qabstractitemview.h>
|
#include <qabstractitemview.h>
|
||||||
#include <qboxlayout.h>
|
#include <qboxlayout.h>
|
||||||
#include <qchar.h>
|
#include <qchar.h>
|
||||||
@@ -14,6 +12,7 @@
|
|||||||
#include <qlabel.h>
|
#include <qlabel.h>
|
||||||
#include <qlayoutitem.h>
|
#include <qlayoutitem.h>
|
||||||
#include <qlistview.h>
|
#include <qlistview.h>
|
||||||
|
#include <qmainwindow.h>
|
||||||
#include <qnamespace.h>
|
#include <qnamespace.h>
|
||||||
#include <qscrollarea.h>
|
#include <qscrollarea.h>
|
||||||
#include <qstandarditemmodel.h>
|
#include <qstandarditemmodel.h>
|
||||||
@@ -26,7 +25,6 @@
|
|||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
#include <QDropEvent>
|
#include <QDropEvent>
|
||||||
#include <QDrag>
|
#include <QDrag>
|
||||||
#include <iostream>
|
|
||||||
#include <QStyledItemDelegate>
|
#include <QStyledItemDelegate>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
@@ -194,7 +192,6 @@ struct GroupView {
|
|||||||
#define ITEM_POOL_CHUNK 200
|
#define ITEM_POOL_CHUNK 200
|
||||||
|
|
||||||
// Main components
|
// Main components
|
||||||
QMainWindow *trainWindow;
|
|
||||||
QWidget *trainWidget;
|
QWidget *trainWidget;
|
||||||
QVBoxLayout *vTrainWidget;
|
QVBoxLayout *vTrainWidget;
|
||||||
CustomItemDelegate *itemDelegate;
|
CustomItemDelegate *itemDelegate;
|
||||||
@@ -286,6 +283,7 @@ void hideQuestionElements() {
|
|||||||
orderList->hide();
|
orderList->hide();
|
||||||
multiChoiceList->hide();
|
multiChoiceList->hide();
|
||||||
wGroupQuestion->hide();
|
wGroupQuestion->hide();
|
||||||
|
|
||||||
btnNotRemembered->hide();
|
btnNotRemembered->hide();
|
||||||
btnHard->hide();
|
btnHard->hide();
|
||||||
btnMedium->hide();
|
btnMedium->hide();
|
||||||
@@ -641,11 +639,11 @@ void setCooldownHours(double cooldown) {
|
|||||||
update(true);
|
update(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initTrainWindow() {
|
QMainWindow *initTrainWindow() {
|
||||||
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
|
||||||
rng = std::default_random_engine(seed);
|
rng = std::default_random_engine(seed);
|
||||||
|
|
||||||
trainWindow = new QMainWindow();
|
auto trainWindow = new QMainWindow();
|
||||||
trainWidget = new QWidget();
|
trainWidget = new QWidget();
|
||||||
vTrainWidget = new QVBoxLayout();
|
vTrainWidget = new QVBoxLayout();
|
||||||
|
|
||||||
@@ -657,6 +655,13 @@ void initTrainWindow() {
|
|||||||
|
|
||||||
itemDelegate = new CustomItemDelegate(multiChoiceList);
|
itemDelegate = new CustomItemDelegate(multiChoiceList);
|
||||||
|
|
||||||
|
auto addShortcut = [trainWindow](QString key, std::function<void()> func) {
|
||||||
|
QShortcut* shortcut = new QShortcut(QKeySequence(key), trainWindow);
|
||||||
|
QObject::connect(shortcut, &QShortcut::activated, [func]() {
|
||||||
|
func();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
{ // Top button menu.
|
{ // Top button menu.
|
||||||
auto hTopButtons = new QHBoxLayout();
|
auto hTopButtons = new QHBoxLayout();
|
||||||
auto topButtons = new QWidget();
|
auto topButtons = new QWidget();
|
||||||
@@ -794,10 +799,30 @@ void initTrainWindow() {
|
|||||||
setCooldownHours(48);
|
setCooldownHours(48);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
btnNotRemembered->setText("Not remembered");
|
btnNotRemembered->setText("Not remembered (Z)");
|
||||||
btnHard->setText("Hard");
|
addShortcut("Z", []() {
|
||||||
btnMedium->setText("Medium");
|
if (btnNotRemembered->isVisible()) {
|
||||||
btnEasy->setText("Easy");
|
btnNotRemembered->click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnHard->setText("Hard (X)");
|
||||||
|
addShortcut("X", []() {
|
||||||
|
if (btnHard->isVisible()) {
|
||||||
|
btnHard->click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnMedium->setText("Medium (C)");
|
||||||
|
addShortcut("C", []() {
|
||||||
|
if (btnMedium->isVisible()) {
|
||||||
|
btnMedium->click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnEasy->setText("Easy (V)");
|
||||||
|
addShortcut("V", []() {
|
||||||
|
if (btnEasy->isVisible()) {
|
||||||
|
btnEasy->click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
btnTriggerAnswer = new QToolButton();
|
btnTriggerAnswer = new QToolButton();
|
||||||
|
|
||||||
@@ -872,7 +897,14 @@ void initTrainWindow() {
|
|||||||
questionBox->layout()->addWidget(wGroupQuestion);
|
questionBox->layout()->addWidget(wGroupQuestion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addShortcut("l", []() {
|
||||||
|
if (btnNext->isVisible()) {
|
||||||
|
btnNext->click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
vTrainWidget->addWidget(questionBox);
|
vTrainWidget->addWidget(questionBox);
|
||||||
vTrainWidget->addWidget(actionButtons);
|
vTrainWidget->addWidget(actionButtons);
|
||||||
|
return trainWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user