comments and some improvements

This commit is contained in:
jorenchik
2024-11-23 23:06:44 +02:00
parent 8367e17381
commit 7facd5c2a1
5 changed files with 626 additions and 370 deletions

View File

@@ -8,7 +8,7 @@
Result<ParseInfo> transpile(std::string fileContent); Result<ParseInfo> transpile(std::string fileContent);
std::string escapeText(std::string text); std::string escapeText(std::string text);
std::string wrapText(std::string text, size_t width); std::string wrapLine(std::string text, size_t width);
extern std::chrono::high_resolution_clock::time_point start; extern std::chrono::high_resolution_clock::time_point start;

View File

@@ -73,7 +73,7 @@
#include "parser.h" #include "parser.h"
#include "qscilexer.h" #include "qscilexer.h"
// Memorybase. // Atmiņas bāze.
QString currentPath = ""; QString currentPath = "";
std::string currentMdem = ""; std::string currentMdem = "";
QFileSystemModel *model; QFileSystemModel *model;
@@ -81,7 +81,7 @@ QTreeView *mdemList;
std::map<std::string, MdemBuffer*> buffers; std::map<std::string, MdemBuffer*> buffers;
MdemBuffer *currentMdemBuffer; MdemBuffer *currentMdemBuffer;
// Mdem list. // Atmiņas kaartīšu saraksts.
std::vector<Mdem*> mdems = std::vector<Mdem*>(); std::vector<Mdem*> mdems = std::vector<Mdem*>();
QVBoxLayout *hMdemScroll; QVBoxLayout *hMdemScroll;
QSpacerItem *mdemSpacer; QSpacerItem *mdemSpacer;
@@ -89,17 +89,20 @@ ErrorView *errorView;
Pagination *pagination; Pagination *pagination;
int perPage; int perPage;
// Editor // Redaktors.
QsciScintilla *editor; QsciScintilla *editor;
QMainWindow *editorWindow; QMainWindow *editorWindow;
Mdem *editMdem; Mdem *editMdem;
// Top labels. // Augšēja informācija.
QLabel *membaseLabel; QLabel *membaseLabel;
QLabel *mdemLabel; QLabel *mdemLabel;
QLabel *lastPracticeLabel; QLabel *lastPracticeLabel;
QMainWindow *trainWindow; QMainWindow *trainWindow;
/*
* Atmiņas kartītei parāda visus slēptos elementus.
* */
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) {
if (i < mdem->labelCount) { if (i < mdem->labelCount) {
@@ -114,14 +117,19 @@ void showBacklabels(Mdem *mdem) {
} }
} }
/*
* Izveido jautājuma kartīšu pirmkodu ar norādītu trenešanas laiku.
* Papildus konfigurācijai var norādīt platumu pirms jaunas rindas un laika zonu.
*/
std::string outputMdem( std::string outputMdem(
std::vector<Question*> questions, std::vector<Question*> questions,
time_t time = 0, time_t time = 0,
const int wrap_width = 80, const int wrapWidth = 80,
const int timezoneOffset = 0 const int timezoneOffset = 0
) { ) {
std::stringstream ss; std::stringstream ss;
// Ja ir saistīts laiks, ja tāds ir.
if (time > 0) { if (time > 0) {
std::tm* tm = std::localtime(&time); std::tm* tm = std::localtime(&time);
char buffer[100]; char buffer[100];
@@ -130,18 +138,25 @@ std::string outputMdem(
ss << time << std::endl; ss << time << std::endl;
} }
// Detranspilē katru jautājumu.
for (auto question: questions) { for (auto question: questions) {
// Pārtraukums.
ss << std::endl; 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(
// Jautājuma teksts.
ss << wrapLine(
std::format("-{}{} >\n", std::format("-{}{} >\n",
cooldownPart, cooldownPart,
" " + escapeText(question->questionText)), " " + escapeText(question->questionText)),
wrap_width wrapWidth
); );
// Detranspilē atbilstoši veidam.
if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) { if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) {
for (auto choice: mw->choices) { for (auto choice: mw->choices) {
char opener; char opener;
@@ -155,30 +170,32 @@ std::string outputMdem(
orderModifier = "^"; orderModifier = "^";
} }
ss << ss <<
wrapText( wrapLine(
std::format( std::format(
"\t{}{} {}\n", "\t{}{} {}\n",
opener, opener,
orderModifier, orderModifier,
escapeText(choice.answer) escapeText(choice.answer)
) )
, wrap_width); , wrapWidth);
} }
} else if (GroupQuestion* gq = dynamic_cast<GroupQuestion*>(question)) { } else if (GroupQuestion* gq = dynamic_cast<GroupQuestion*>(question)) {
for (auto group: gq->groups) { for (auto group: gq->groups) {
ss << wrapText( ss << wrapLine(
std::format( std::format(
"\t- {}:\n", "\t- {}:\n",
escapeText(group.name) escapeText(group.name)
) )
, wrap_width); , wrapWidth);
for (auto element: group.elements) { for (auto element: group.elements) {
ss << wrapText( ss << wrapLine(
std::format( std::format(
"\t\t- {}\n", "\t\t- {}\n",
escapeText(element) escapeText(element)
) )
, wrap_width); , wrapWidth);
} }
} }
} }
@@ -186,14 +203,21 @@ std::string outputMdem(
return ss.str(); return ss.str();
} }
/*
* Izveido lappušu objektus atbilstoši jautājumu skaitam vienā lapā.
* */
void makePages() { void makePages() {
pagination->pages.clear(); pagination->pages.clear();
auto len = currentMdemBuffer->questions.size(); auto len = currentMdemBuffer->questions.size();
perPage = settings->value(SETTING_PER_PAGE).toInt(); perPage = settings->value(SETTING_PER_PAGE).toInt();
auto pageAmount = len / perPage; auto pageAmount = len / perPage;
// Papildus lapa, ja objektu skaits nedalās tieši un paliek papildus kartītes.
if (len % perPage != 0) { if (len % perPage != 0) {
pageAmount += 1; pageAmount += 1;
} }
// Veido lappuses objektus.
for (size_t i = 0; i < pageAmount; i++) { for (size_t i = 0; i < pageAmount; i++) {
size_t startingIndex = perPage * i ; size_t startingIndex = perPage * i ;
size_t amount = perPage; size_t amount = perPage;
@@ -204,9 +228,20 @@ void makePages() {
Page{startingIndex, startingIndex + amount} Page{startingIndex, startingIndex + amount}
); );
} }
// Ja tiek noņemts pēdējais lappuses elements, pārliek lappusi uz iepriekšējo.
if (pagination->pages.size() > 1 && pagination->currentPage >= pagination->pages.size()) {
--pagination->currentPage;
}
} }
/*
* Uzstāda atmiņas kartīti ar jebkura veida jautājuma.
* Uzstāda jautājuma tekstu un pievieno/uzstāda atbildes elementus.
* */
void setupMdem(Mdem *mdem, Question *question) { void setupMdem(Mdem *mdem, Question *question) {
// Priekšas teksts.
std::stringstream ss; std::stringstream ss;
if (question->cooldown > 0) { if (question->cooldown > 0) {
ss << std::format("[{:.2f}] ", question->cooldown); ss << std::format("[{:.2f}] ", question->cooldown);
@@ -215,10 +250,15 @@ void setupMdem(Mdem *mdem, Question *question) {
mdem->wFrontText.setText( mdem->wFrontText.setText(
QString::fromStdString(ss.str()) QString::fromStdString(ss.str())
); );
if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) { if (MultiElementQuestion* mw = dynamic_cast<MultiElementQuestion*>(question)) {
auto choices = mw->choices; auto choices = mw->choices;
// Pievieno vairākus elementus atbilstoši veidam.
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;
// Sagatavo elementu.
switch (mw->type) { switch (mw->type) {
case MultiElementType::Order: case MultiElementType::Order:
answer = std::format("{}. {}", k + 1, answer); answer = std::format("{}. {}", k + 1, answer);
@@ -234,6 +274,8 @@ void setupMdem(Mdem *mdem, Question *question) {
answer = std::format("- {}", answer); answer = std::format("- {}", answer);
break; break;
} }
// Pievieno elementu.
if (k < mdem->backLabels.size()) { if (k < mdem->backLabels.size()) {
mdem->backLabels[k]->setText(QString::fromStdString(answer)); mdem->backLabels[k]->setText(QString::fromStdString(answer));
} else { } else {
@@ -243,10 +285,13 @@ void setupMdem(Mdem *mdem, Question *question) {
mdem->wBack.layout()->addWidget(label); mdem->wBack.layout()->addWidget(label);
} }
} }
mdem->labelCount = choices.size(); mdem->labelCount = choices.size();
} else if (GroupQuestion* mw = dynamic_cast<GroupQuestion*>(question)) { } else if (GroupQuestion* mw = dynamic_cast<GroupQuestion*>(question)) {
auto groups = mw->groups; auto groups = mw->groups;
std::vector<std::string> elements; std::vector<std::string> elements;
// Sagatovo grupas un elementus.
for (size_t k = 0; k < groups.size(); ++k) { for (size_t k = 0; k < groups.size(); ++k) {
auto answer = groups[k].name; auto answer = groups[k].name;
elements.push_back(std::format("- {}:", answer)); elements.push_back(std::format("- {}:", answer));
@@ -254,6 +299,8 @@ void setupMdem(Mdem *mdem, Question *question) {
elements.push_back(std::format(" - {}", groups[k].elements[l])); elements.push_back(std::format(" - {}", groups[k].elements[l]));
} }
} }
// Pievieno grupas un elementus.
for (size_t k = 0; k < elements.size(); ++k) { for (size_t k = 0; k < elements.size(); ++k) {
if (k < mdem->backLabels.size()) { if (k < mdem->backLabels.size()) {
mdem->backLabels[k]->setText(QString::fromStdString(elements[k])); mdem->backLabels[k]->setText(QString::fromStdString(elements[k]));
@@ -264,12 +311,16 @@ void setupMdem(Mdem *mdem, Question *question) {
mdem->wBack.layout()->addWidget(label); mdem->wBack.layout()->addWidget(label);
} }
} }
mdem->labelCount = elements.size(); mdem->labelCount = elements.size();
} }
} }
void switchPage(int pageIdx); void switchPage(int pageIdx);
/*
* Iegūst faila nosaukumu no faila ceļa.
*/
std::string getFilename(std::string path) { std::string getFilename(std::string path) {
static const std::regex lastPathElementExp = std::regex("(.+\\/)*(.+)"); static const std::regex lastPathElementExp = std::regex("(.+\\/)*(.+)");
std::smatch matches; std::smatch matches;
@@ -277,6 +328,9 @@ std::string getFilename(std::string path) {
return matches[2].str(); return matches[2].str();
} }
/*
* Atjauno atmiņas kartīšu faila augšējo informāciju.
* */
void updateMdemInfo(std::string filename, bool isChanged) { void updateMdemInfo(std::string filename, bool isChanged) {
currentMdemBuffer->isModified = isChanged; currentMdemBuffer->isModified = isChanged;
if (filename.length() > 0) { if (filename.length() > 0) {
@@ -301,14 +355,16 @@ void updateMdemInfo(std::string filename, bool isChanged) {
} }
} }
/*
* Izveido atmiņas kartīti un visus tās elementus.
* */
Mdem* makeMdem() { Mdem* makeMdem() {
auto mdem = new Mdem; auto mdem = new Mdem;
mdem->wMdem.setLayout(&mdem->vMdem); mdem->wMdem.setLayout(&mdem->vMdem);
// Priekša.
QString id = QString("mdem_%1").arg(1); QString id = QString("mdem_%1").arg(1);
mdem->wMdem.setObjectName(id); mdem->wMdem.setObjectName(id);
// Front
mdem->wFront.setMinimumHeight(70); mdem->wFront.setMinimumHeight(70);
mdem->wFront.setLayout(&mdem->hFront); mdem->wFront.setLayout(&mdem->hFront);
mdem->wFront.setProperty("first", "true"); mdem->wFront.setProperty("first", "true");
@@ -324,7 +380,7 @@ Mdem* makeMdem() {
"}" "}"
).arg(id, MDEM_BACKGROUND)); ).arg(id, MDEM_BACKGROUND));
// Add Front Content // Saturs.
mdem->wFrontText.setWordWrap(true); mdem->wFrontText.setWordWrap(true);
mdem->wFrontText.setSizePolicy( mdem->wFrontText.setSizePolicy(
QSizePolicy::Expanding, QSizePolicy::Expanding,
@@ -332,6 +388,7 @@ Mdem* makeMdem() {
); );
mdem->hFront.addWidget(&mdem->wFrontText); mdem->hFront.addWidget(&mdem->wFrontText);
// Rediģēšanas poga.
mdem->editButton.setText("Rediģēt"); mdem->editButton.setText("Rediģēt");
QObject::connect( QObject::connect(
&mdem->editButton, &mdem->editButton,
@@ -355,6 +412,7 @@ Mdem* makeMdem() {
); );
mdem->hFront.addWidget(&mdem->editButton); mdem->hFront.addWidget(&mdem->editButton);
// Dzēšanas poga.
mdem->deleteButton.setText("Dzēst"); mdem->deleteButton.setText("Dzēst");
QObject::connect( QObject::connect(
&mdem->deleteButton, &mdem->deleteButton,
@@ -381,14 +439,11 @@ Mdem* makeMdem() {
); );
mdem->hFront.addWidget(&mdem->deleteButton); mdem->hFront.addWidget(&mdem->deleteButton);
mdem->toggleVisibility.setText("Parādīt"); // Aizmugura.
mdem->hFront.addWidget(&mdem->toggleVisibility);
// Back
mdem->wBack.setLayout(&mdem->hBack); mdem->wBack.setLayout(&mdem->hBack);
mdem->vMdem.addWidget(&mdem->wBack); mdem->vMdem.addWidget(&mdem->wBack);
// Add Back Content // Aizmuguras saturs.
for (size_t i = 0; i < 20; ++i) { for (size_t i = 0; i < 20; ++i) {
// @Improve: back label pooling // @Improve: back label pooling
QLabel *elBackText = new QLabel(); QLabel *elBackText = new QLabel();
@@ -404,7 +459,9 @@ Mdem* makeMdem() {
mdem->wBack.hide(); mdem->wBack.hide();
mdem->wMdem.hide(); mdem->wMdem.hide();
// Connect button to toggle view // Atbildes parādīšanas poga.
mdem->toggleVisibility.setText("Parādīt");
mdem->hFront.addWidget(&mdem->toggleVisibility);
QObject::connect(&mdem->toggleVisibility, &QToolButton::clicked, [mdem]() { QObject::connect(&mdem->toggleVisibility, &QToolButton::clicked, [mdem]() {
if (mdem->wBack.isVisible()) { if (mdem->wBack.isVisible()) {
mdem->wBack.hide(); mdem->wBack.hide();
@@ -418,16 +475,21 @@ Mdem* makeMdem() {
return mdem; return mdem;
} }
/*
* Izveido rādāmās kartītes (argumentam nedrīkst pārniegt maksimāli iespējamo daudzumu lapā).
* */
void createMdems(std::vector<Question*>& questions) {
void CreateMdems(std::vector<Question*>& questions) {
hMdemScroll->removeItem(mdemSpacer); hMdemScroll->removeItem(mdemSpacer);
// Paslēp visas atmiņas kartītes.
for (Mdem *mdem : mdems) { for (Mdem *mdem : mdems) {
if (mdem->wMdem.isVisible()) { if (mdem->wMdem.isVisible()) {
mdem->wMdem.hide(); mdem->wMdem.hide();
} }
} }
// Pievieno atmiņas kartītes, ja nepieciešamais daudzums pārsniedz esošo.
perPage = settings->value(SETTING_PER_PAGE).toInt(); perPage = settings->value(SETTING_PER_PAGE).toInt();
if (perPage > mdems.size()) { if (perPage > mdems.size()) {
for (size_t i = mdems.size(); i < perPage; i++) { for (size_t i = mdems.size(); i < perPage; i++) {
@@ -439,6 +501,7 @@ void CreateMdems(std::vector<Question*>& questions) {
} }
} }
// Parāda nepieciešamās atmiņas kartītes.
for (size_t i = 0; i < questions.size(); ++i) { for (size_t i = 0; i < questions.size(); ++i) {
mdems[i]->question = questions[i]; mdems[i]->question = questions[i];
setupMdem(mdems[i], questions[i]); setupMdem(mdems[i], questions[i]);
@@ -450,6 +513,9 @@ void CreateMdems(std::vector<Question*>& questions) {
hMdemScroll->addItem(mdemSpacer); hMdemScroll->addItem(mdemSpacer);
} }
/*
* Atjauno sarakstu un tā informāciju.
*/
void update(bool isChanged) { void update(bool isChanged) {
if (pagination->currentPage > -1) { if (pagination->currentPage > -1) {
switchPage(pagination->currentPage); switchPage(pagination->currentPage);
@@ -460,9 +526,10 @@ void update(bool isChanged) {
} }
void switchPage(int pageIdx) { void switchPage(int pageIdx) {
pagination->currentPage = pageIdx; pagination->currentPage = pageIdx;
// Hide all pagination buttons // Paslēp visas lappušu pogas.
for (auto& button : pagination->paginationButtons) { for (auto& button : pagination->paginationButtons) {
button->hide(); button->hide();
} }
@@ -472,7 +539,7 @@ void switchPage(int pageIdx) {
snprintf(buffer, sizeof(buffer), "Lappuse: %d", pageIdx + 1); snprintf(buffer, sizeof(buffer), "Lappuse: %d", pageIdx + 1);
pagination->paginationLabel.setText(buffer); pagination->paginationLabel.setText(buffer);
// Adjust mdem amount, hide widgets in mdems // Paslēp atbilžu elementus.
for (auto& mdem : mdems) { for (auto& mdem : mdems) {
if (mdem->wBack.isVisible()) { if (mdem->wBack.isVisible()) {
mdem->wBack.hide(); mdem->wBack.hide();
@@ -480,7 +547,7 @@ void switchPage(int pageIdx) {
} }
} }
// Update pagination buttons // Atjauno lappušu pogas.
for (int k = -DISTANCE; k <= DISTANCE; ++k) { for (int k = -DISTANCE; k <= DISTANCE; ++k) {
if (pageIdx + k >= 0 && pageIdx + k < pagination->pages.size()) { if (pageIdx + k >= 0 && pageIdx + k < pagination->pages.size()) {
auto button = pagination->paginationButtons[l]; auto button = pagination->paginationButtons[l];
@@ -496,50 +563,51 @@ void switchPage(int pageIdx) {
} }
} }
// Handle first and last buttons // Pirmās un pēdējās pogas redzamība.
if (pageIdx > 0 && pagination->pages.size() > 1) { if (pageIdx > 0 && pagination->pages.size() > 1) {
pagination->firstButton.show(); pagination->firstButton.show();
} else { } else {
pagination->firstButton.hide(); pagination->firstButton.hide();
} }
if (pageIdx < pagination->pages.size() - 1 && pagination->pages.size() > 1) { if (pageIdx < pagination->pages.size() - 1 && pagination->pages.size() > 1) {
pagination->lastButton.show(); pagination->lastButton.show();
} else { } else {
pagination->lastButton.hide(); pagination->lastButton.hide();
} }
// Handle next and previous buttons // Iepriekšējās pogas redzamība.
if (!pagination->pages.empty() && pagination->currentPage < pagination->pages.size() - 1) {
pagination->nextButton.show();
} else {
pagination->nextButton.hide();
}
if (!pagination->pages.empty() && pagination->currentPage >= 1) { if (!pagination->pages.empty() && pagination->currentPage >= 1) {
pagination->prevButton.show(); pagination->prevButton.show();
} else { } else {
pagination->prevButton.hide(); pagination->prevButton.hide();
} }
Page page; // Nākamās pogas redzamība.
if (pagination->pages.size() <= 0) { if (!pagination->pages.empty() && pagination->currentPage < pagination->pages.size() - 1) {
page = Page(); pagination->nextButton.show();
} else if (pageIdx < pagination->pages.size()){
page = pagination->pages[pageIdx];
} else { } else {
if (pageIdx - 1 < pagination->pages.size()) { pagination->nextButton.hide();
page = pagination->pages[pageIdx -1];
} else {
page = pagination->pages[0];
}
} }
Page page;
// Samazina lappuses numuru, ja pēdējai lappusei nepietiek atmiņas kartīšu.
if (pagination->pages.size() <= 0) {
// Nav lapu -> veidojam tukšu lapu.
page = Page();
} else if (pageIdx < pagination->pages.size()){
// Pieprasītā lapa eksistē -> atgriežam to.
page = pagination->pages[pageIdx];
} else {
// Pieprasītā lapa eksistē -> atgriežam iepriekšējo.
page = pagination->pages[pageIdx - 1];
}
// Izveido lappusi.
std::vector<Question*> pageSlice( std::vector<Question*> pageSlice(
currentMdemBuffer->questions.begin() + page.start, currentMdemBuffer->questions.begin() + page.start,
currentMdemBuffer->questions.begin() + page.end currentMdemBuffer->questions.begin() + page.end
); );
CreateMdems(pageSlice); createMdems(pageSlice);
} }
void reloadMdem(std::string path) { void reloadMdem(std::string path) {
@@ -586,7 +654,7 @@ void reloadMdem(std::string path) {
auto file = std::ifstream(path); auto file = std::ifstream(path);
std::string content; std::string content;
// Reset the mdem list. // Atiestata atmiņas kartīšu sarakstu.
for (auto mdem: mdems) { for (auto mdem: mdems) {
mdem->wMdem.hide(); mdem->wMdem.hide();
} }
@@ -631,7 +699,7 @@ void reloadMdem(std::string path) {
delete question; delete question;
} }
// Show errors. // Parāda kļūdu.
hMdemScroll->removeItem(mdemSpacer); hMdemScroll->removeItem(mdemSpacer);
errorView->label.setText( errorView->label.setText(
QString::fromStdString( QString::fromStdString(
@@ -680,7 +748,7 @@ void pickDirectory(QString directory) {
currentPath = directory; currentPath = directory;
// Update tree view. // Atjauno failu sarakstu.
if (directory.length() <= 0) { if (directory.length() <= 0) {
membaseLabel->setText(directory); membaseLabel->setText(directory);
return; return;
@@ -688,7 +756,7 @@ void pickDirectory(QString directory) {
mdemList->setRootIndex(model->setRootPath(directory)); mdemList->setRootIndex(model->setRootPath(directory));
std::smatch matches; std::smatch matches;
// Update label. // Atjauno teksta elementu.
membaseLabel->setText(QString::fromStdString( membaseLabel->setText(QString::fromStdString(
std::format( std::format(
"Atmiņas bāze: {}", "Atmiņas bāze: {}",
@@ -794,17 +862,20 @@ void saveMdem() {
} }
} }
/*
* Inicializē visus atmiņas kartīšu saraksta elementus un izvēlni.
*/
QMainWindow *initMdemListWindow() { QMainWindow *initMdemListWindow() {
QMainWindow* window = new QMainWindow; QMainWindow* window = new QMainWindow;
pagination = new Pagination; pagination = new Pagination;
auto *toolbar = new Toolbar(); auto *toolbar = new Toolbar();
// Setup the related windows. // Saistīti logi.
auto *settingsWindow = initSettings(); auto *settingsWindow = initSettings();
trainWindow = initTrainWindow(); trainWindow = initTrainWindow();
QMainWindow *guideWindow = new QMainWindow; QMainWindow *guideWindow = new QMainWindow;
{ // Guide window. { // Apmācības logs.
auto guideWidget = new QWidget; auto guideWidget = new QWidget;
auto *layout = new QVBoxLayout; auto *layout = new QVBoxLayout;
auto *textBrowser = new QTextBrowser; auto *textBrowser = new QTextBrowser;
@@ -818,13 +889,13 @@ QMainWindow *initMdemListWindow() {
QAction *actionOpen; QAction *actionOpen;
QAction *openSettings; QAction *openSettings;
QAction *actionHelp; QAction *actionHelp;
{ // Menu bar. { // Izvēlne.
QMenuBar *menuBar = new QMenuBar; QMenuBar *menuBar = new QMenuBar;
QFileDialog *fileDialog = new QFileDialog; QFileDialog *fileDialog = new QFileDialog;
QMenu *menu = new QMenu("Fails"); QMenu *menu = new QMenu("Fails");
menu->setStyleSheet("font-size: 15px;"); menu->setStyleSheet("font-size: 15px;");
actionOpen = menu->addAction("Atvērt atmņas bāzi (Ctrl+O)"); actionOpen = menu->addAction("Atvērt atmiņas bāzi (Ctrl+O)");
QObject::connect( QObject::connect(
actionOpen, actionOpen,
&QAction::triggered, &QAction::triggered,
@@ -862,7 +933,7 @@ QMainWindow *initMdemListWindow() {
window->setMenuBar(menuBar); window->setMenuBar(menuBar);
} }
{ // Editor. { // Redaktors.
editorWindow = new QMainWindow; editorWindow = new QMainWindow;
editorWindow->setWindowTitle("Jautājumu redaktors"); editorWindow->setWindowTitle("Jautājumu redaktors");
@@ -905,25 +976,25 @@ QMainWindow *initMdemListWindow() {
} }
auto *wTop = new QWidget(); auto *wTop = new QWidget();
{ // Top. { // Augša.
// Main top layout. // Pamata augšējais izklājums.
QHBoxLayout *hlTop = new QHBoxLayout(); QHBoxLayout *hlTop = new QHBoxLayout();
wTop->setLayout(hlTop); wTop->setLayout(hlTop);
// Labels // Teksta elementi.
auto *wLabels = new QWidget(); auto *wLabels = new QWidget();
auto *vlLeftTop = new QVBoxLayout(); auto *vlLeftTop = new QVBoxLayout();
wLabels->setLayout(vlLeftTop); wLabels->setLayout(vlLeftTop);
wLabels->setMinimumSize(0, 40); wLabels->setMinimumSize(0, 40);
// Atmiņas bāzes teksta elements.
QString labelStyle = "font-size: 20px; font-weight: 400;"; QString labelStyle = "font-size: 20px; font-weight: 400;";
// Memorybase label.
membaseLabel = new QLabel(); membaseLabel = new QLabel();
membaseLabel->setStyleSheet(labelStyle); membaseLabel->setStyleSheet(labelStyle);
vlLeftTop->addWidget(membaseLabel); vlLeftTop->addWidget(membaseLabel);
// Memorybase label. // Atmiņas kartīšu faila teksta elements.
mdemLabel = new QLabel(); mdemLabel = new QLabel();
mdemLabel->setStyleSheet(labelStyle); mdemLabel->setStyleSheet(labelStyle);
vlLeftTop->addWidget(mdemLabel); vlLeftTop->addWidget(mdemLabel);
@@ -932,7 +1003,7 @@ QMainWindow *initMdemListWindow() {
lastPracticeLabel->setStyleSheet(labelStyle); lastPracticeLabel->setStyleSheet(labelStyle);
vlLeftTop->addWidget(lastPracticeLabel); vlLeftTop->addWidget(lastPracticeLabel);
// Button layout. // Pogu izklājums.
auto buttons = new QWidget(); auto buttons = new QWidget();
auto vlButtons = new QVBoxLayout(); auto vlButtons = new QVBoxLayout();
buttons->setLayout(vlButtons); buttons->setLayout(vlButtons);
@@ -946,8 +1017,7 @@ QMainWindow *initMdemListWindow() {
auto hlButtonsBottom = new QHBoxLayout(); auto hlButtonsBottom = new QHBoxLayout();
buttonsBottom->setLayout(hlButtonsBottom); buttonsBottom->setLayout(hlButtonsBottom);
// Define buttons. // Pogu definēšana.
QObject::connect(&toolbar->btnAdd, &QToolButton::clicked, []() { QObject::connect(&toolbar->btnAdd, &QToolButton::clicked, []() {
editMdem = nullptr; editMdem = nullptr;
editorWindow->show(); editorWindow->show();
@@ -976,7 +1046,7 @@ QMainWindow *initMdemListWindow() {
} }
); );
// Button content. // Pogu saturs.
toolbar->btnAdd.setText("Pievienot"); toolbar->btnAdd.setText("Pievienot");
toolbar->btnSave.setText("Saglabāt"); toolbar->btnSave.setText("Saglabāt");
toolbar->btnLoad.setText("Ielādēt"); toolbar->btnLoad.setText("Ielādēt");
@@ -987,7 +1057,7 @@ QMainWindow *initMdemListWindow() {
toolbar->cbAlgorithm.addItem("Primārais", PRIMARY); toolbar->cbAlgorithm.addItem("Primārais", PRIMARY);
toolbar->btnPractice.setText("Mācīties"); toolbar->btnPractice.setText("Mācīties");
// Add buttons. // Pievieno pogas.
hlButtonsTop->addWidget(&toolbar->btnAdd); hlButtonsTop->addWidget(&toolbar->btnAdd);
hlButtonsTop->addWidget(&toolbar->btnSave); hlButtonsTop->addWidget(&toolbar->btnSave);
hlButtonsTop->addWidget(&toolbar->btnLoad); hlButtonsTop->addWidget(&toolbar->btnLoad);
@@ -1009,7 +1079,7 @@ QMainWindow *initMdemListWindow() {
} }
QWidget *leftWidget = new QWidget(); QWidget *leftWidget = new QWidget();
{ // Left side. { // Kreisā puse.
QVBoxLayout *leftLayout = new QVBoxLayout(); QVBoxLayout *leftLayout = new QVBoxLayout();
leftWidget->setLayout(leftLayout); leftWidget->setLayout(leftLayout);
@@ -1032,7 +1102,6 @@ QMainWindow *initMdemListWindow() {
if (currentPath.size() > 0) { if (currentPath.size() > 0) {
pickDirectory(currentPath); pickDirectory(currentPath);
} }
/*leftLayout->addWidget(leftTop);*/
QObject::connect( QObject::connect(
mdemList, mdemList,
@@ -1049,14 +1118,13 @@ QMainWindow *initMdemListWindow() {
for (int col = 1; col < model->columnCount(); ++col) { for (int col = 1; col < model->columnCount(); ++col) {
mdemList->hideColumn(col); mdemList->hideColumn(col);
} }
// TODO: name -> nosaukums in HEADER
leftLayout->addWidget(mdemList); leftLayout->addWidget(mdemList);
} }
auto wMain = new QWidget; auto wMain = new QWidget;
auto *rightWidget = new QWidget(); auto *rightWidget = new QWidget();
auto *rightLayout = new QVBoxLayout(); auto *rightLayout = new QVBoxLayout();
{ // Main layout. { // Pamata izklājums.
auto vlMain = new QVBoxLayout; auto vlMain = new QVBoxLayout;
wMain->setLayout(vlMain); wMain->setLayout(vlMain);
@@ -1072,7 +1140,7 @@ QMainWindow *initMdemListWindow() {
vlMain->addWidget(hSplitter); vlMain->addWidget(hSplitter);
} }
{ // Error. { // Kļūda.
errorView = new ErrorView; errorView = new ErrorView;
errorView->box.setObjectName("error-box"); errorView->box.setObjectName("error-box");
errorView->box.setLayout(&errorView->layout); errorView->box.setLayout(&errorView->layout);
@@ -1089,7 +1157,7 @@ QMainWindow *initMdemListWindow() {
errorView->label.setWordWrap(true); errorView->label.setWordWrap(true);
} }
{ // Mdems { // Atmiņas kartītes.
QScrollArea *mdemScroll = new QScrollArea(); QScrollArea *mdemScroll = new QScrollArea();
QWidget *mdemContainer = new QWidget(); QWidget *mdemContainer = new QWidget();
hMdemScroll = new QVBoxLayout(); hMdemScroll = new QVBoxLayout();
@@ -1104,10 +1172,9 @@ QMainWindow *initMdemListWindow() {
QSizePolicy::Minimum, QSizePolicy::Minimum,
QSizePolicy::Expanding QSizePolicy::Expanding
); );
/*hMdemScroll->addItem(mdemSpacer);*/
} }
{ // Pagination { // Lappušu pogas.
auto wPagination = new QWidget(); auto wPagination = new QWidget();
auto hPagination = new QHBoxLayout(); auto hPagination = new QHBoxLayout();
@@ -1171,7 +1238,7 @@ QMainWindow *initMdemListWindow() {
rightLayout->addWidget(wPagination); rightLayout->addWidget(wPagination);
} }
{ // Setup shortcuts. { // Uzstāda īsceļus.
auto addShortcut = [window](QString key, std::function<void()> func) { auto addShortcut = [window](QString key, std::function<void()> func) {
QShortcut* shortcut = new QShortcut(QKeySequence(key), window); QShortcut* shortcut = new QShortcut(QKeySequence(key), window);
QObject::connect(shortcut, &QShortcut::activated, [func]() { QObject::connect(shortcut, &QShortcut::activated, [func]() {

View File

@@ -63,19 +63,25 @@
QSettings *settings; QSettings *settings;
/*
* Inicializē uzstādījumu logu.
* */
QWidget *initSettings () { QWidget *initSettings () {
QString configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
// Uzstādījumu fails - paņem standarta atrašanās vietu operētājsistēmā.
auto configDir = QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation);
QDir().mkpath(configDir); QDir().mkpath(configDir);
QString settingsFile = configDir + "/mdem.ini"; QString settingsFile = configDir + "/mdem.ini";
settings = new QSettings(settingsFile, QSettings::IniFormat); settings = new QSettings(settingsFile, QSettings::IniFormat);
auto* settingsWindow = new QWidget;
// Logs.
auto* settingsWindow = new QWidget;
settingsWindow->setWindowTitle("Iestatījumi"); settingsWindow->setWindowTitle("Iestatījumi");
// Augšējais izklājums.
auto top = new QWidget; auto top = new QWidget;
auto hlTop = new QVBoxLayout; auto hlTop = new QVBoxLayout;
top->setLayout(hlTop); top->setLayout(hlTop);
auto settingsLabel = new QLabel; auto settingsLabel = new QLabel;
settingsLabel->setText("Iestatījumi"); settingsLabel->setText("Iestatījumi");
settingsLabel->setStyleSheet( settingsLabel->setStyleSheet(
@@ -83,17 +89,29 @@ QWidget *initSettings () {
); );
hlTop->addWidget(settingsLabel); hlTop->addWidget(settingsLabel);
// Forma.
auto wForm = new QWidget; auto wForm = new QWidget;
auto formLayout = new QFormLayout; auto formLayout = new QFormLayout;
wForm->setLayout(formLayout);
auto mbaseInput = new QLineEdit; auto mbaseInput = new QLineEdit;
auto browseButton = new QPushButton("Izvēlēties"); auto browseButton = new QPushButton("Izvēlēties");
auto pathLayout = new QHBoxLayout; auto pathLayout = new QHBoxLayout;
wForm->setLayout(formLayout);
pathLayout->addWidget(mbaseInput); pathLayout->addWidget(mbaseInput);
pathLayout->addWidget(browseButton); pathLayout->addWidget(browseButton);
wForm->setStyleSheet("font-size: 15px;"); wForm->setStyleSheet("font-size: 15px;");
formLayout->addRow("Noklusējuma memorybase:", pathLayout); // Lauki.
auto perPage = new QSpinBox;
auto characterWrap = new QSpinBox;
auto* timezone = new QSpinBox;
auto* notRemembered = new QDoubleSpinBox;
auto* hard = new QDoubleSpinBox;
auto* medium = new QDoubleSpinBox;
auto* easy = new QDoubleSpinBox;
auto* debug = new QCheckBox;
auto* showTimes = new QCheckBox;
{ // Uzstāda uzstādījumu laukus.
formLayout->addRow("Noklusējuma atmiņas bāze:", pathLayout);
QObject::connect(browseButton, &QPushButton::clicked, [mbaseInput]() { QObject::connect(browseButton, &QPushButton::clicked, [mbaseInput]() {
QString dir = QFileDialog::getExistingDirectory( QString dir = QFileDialog::getExistingDirectory(
nullptr, nullptr,
@@ -105,40 +123,33 @@ QWidget *initSettings () {
} }
}); });
auto perPage = new QSpinBox;
perPage->setRange(5, 50); perPage->setRange(5, 50);
formLayout->addRow("Mdems per page [5-50]:", perPage); formLayout->addRow("Mdems per page [5-50]:", perPage);
auto characterWrap = new QSpinBox;
characterWrap->setRange(30, 150); characterWrap->setRange(30, 150);
formLayout->addRow("Rindas pārnešanas platums jautājumu teksta ģenerēšanā [30-150]:", characterWrap); formLayout->addRow("Rindas pārnešanas platums jautājumu teksta ģenerēšanā [30-150]:", characterWrap);
auto* timezone = new QSpinBox;
timezone->setRange(-12, 12); timezone->setRange(-12, 12);
formLayout->addRow("Laika zona (e.g. +2 as 2):", timezone); formLayout->addRow("Laika zona (e.g. +2 as 2):", timezone);
auto* notRemembered = new QDoubleSpinBox;
notRemembered->setRange(0, 100); notRemembered->setRange(0, 100);
formLayout->addRow("Neatcerējos:", notRemembered); formLayout->addRow("Neatcerējos:", notRemembered);
auto* hard = new QDoubleSpinBox;
hard->setRange(0, 100); hard->setRange(0, 100);
formLayout->addRow("Grūti:", hard); formLayout->addRow("Grūti:", hard);
auto* medium = new QDoubleSpinBox;
medium->setRange(0, 100); medium->setRange(0, 100);
formLayout->addRow("Vidēji:", medium); formLayout->addRow("Vidēji:", medium);
auto* easy = new QDoubleSpinBox;
easy->setRange(0, 100); easy->setRange(0, 100);
formLayout->addRow("Viegli:", easy); formLayout->addRow("Viegli:", easy);
auto* debug = new QCheckBox;
formLayout->addRow("Atkļūdošana:", debug); formLayout->addRow("Atkļūdošana:", debug);
auto* showTimes = new QCheckBox;
formLayout->addRow("Rādīt laikus komandrindā:", showTimes); formLayout->addRow("Rādīt laikus komandrindā:", showTimes);
}
// Uzstādījumu pogas.
auto wButtons = new QWidget; auto wButtons = new QWidget;
auto btnLayout = new QHBoxLayout; auto btnLayout = new QHBoxLayout;
wButtons->setLayout(btnLayout); wButtons->setLayout(btnLayout);
@@ -149,7 +160,7 @@ QWidget *initSettings () {
btnLayout->addWidget(btnLoad); btnLayout->addWidget(btnLoad);
wButtons->setStyleSheet("font-size: 15px;"); wButtons->setStyleSheet("font-size: 15px;");
// @Improve: validate setting values // Uzstāda lauku vērtības no uzstādījumu vērtībām.
auto setSettingInputs = [ auto setSettingInputs = [
perPage, perPage,
mbaseInput, mbaseInput,
@@ -174,6 +185,7 @@ QWidget *initSettings () {
showTimes->setChecked(settings->value(SETTING_SHOW_TIMES).toBool() == true); showTimes->setChecked(settings->value(SETTING_SHOW_TIMES).toBool() == true);
}; };
// Parāda izmaiņas indikatoru.
auto updateSettingsLabel = [settingsLabel](bool isChanged) { auto updateSettingsLabel = [settingsLabel](bool isChanged) {
if (isChanged) { if (isChanged) {
settingsLabel->setText("Iestatījumi *"); settingsLabel->setText("Iestatījumi *");
@@ -182,6 +194,7 @@ QWidget *initSettings () {
} }
}; };
// Pievieno klausītāju atbilstoši izmantotam lauku tipam.
auto attachChangeListener = [settingsLabel, updateSettingsLabel](QObject *input, QString key) { auto attachChangeListener = [settingsLabel, updateSettingsLabel](QObject *input, QString key) {
if (QLineEdit *lineInput = qobject_cast<QLineEdit*>(input)) { if (QLineEdit *lineInput = qobject_cast<QLineEdit*>(input)) {
QObject::connect( QObject::connect(
@@ -224,6 +237,7 @@ QWidget *initSettings () {
} }
}; };
// Izmaiņas laukos parāda indikatoros.
attachChangeListener(perPage, SETTING_PER_PAGE); attachChangeListener(perPage, SETTING_PER_PAGE);
attachChangeListener(mbaseInput, SETTING_MEMORYBASE); attachChangeListener(mbaseInput, SETTING_MEMORYBASE);
attachChangeListener(characterWrap, SETTING_CHARACTER_WRAP); attachChangeListener(characterWrap, SETTING_CHARACTER_WRAP);
@@ -235,6 +249,7 @@ QWidget *initSettings () {
attachChangeListener(debug, SETTING_DEBUG); attachChangeListener(debug, SETTING_DEBUG);
attachChangeListener(showTimes, SETTING_SHOW_TIMES); attachChangeListener(showTimes, SETTING_SHOW_TIMES);
// Atjauno uzstādījumus no lauku vērtībām.
auto saveSettings = [ auto saveSettings = [
perPage, perPage,
mbaseInput, mbaseInput,
@@ -260,7 +275,6 @@ QWidget *initSettings () {
settings->setValue(SETTING_SHOW_TIMES, showTimes->isChecked()); settings->setValue(SETTING_SHOW_TIMES, showTimes->isChecked());
updateSettingsLabel(false); updateSettingsLabel(false);
}; };
auto loadSettings = [setSettingInputs, updateSettingsLabel]() { auto loadSettings = [setSettingInputs, updateSettingsLabel]() {
settings->sync(); settings->sync();
setSettingInputs(); setSettingInputs();
@@ -274,6 +288,17 @@ QWidget *initSettings () {
saveSettings(); saveSettings();
} }
); );
auto shortcutSave = new QShortcut(
QKeySequence("Ctrl+S"),
settingsWindow
);
QObject::connect(
shortcutSave,
&QShortcut::activated,
[saveSettings]() {
saveSettings();
}
);
QObject::connect( QObject::connect(
btnLoad, btnLoad,
&QPushButton::clicked, &QPushButton::clicked,
@@ -283,11 +308,7 @@ QWidget *initSettings () {
); );
loadSettings(); loadSettings();
QShortcut* shortcutSave = new QShortcut(QKeySequence("Ctrl+S"), settingsWindow); // Lai pogas ir lejā.
QObject::connect(shortcutSave, &QShortcut::activated, [saveSettings]() {
saveSettings();
});
auto spacer = new QSpacerItem( auto spacer = new QSpacerItem(
50, 50,
50, 50,
@@ -295,6 +316,7 @@ QWidget *initSettings () {
QSizePolicy::Expanding QSizePolicy::Expanding
); );
// Pievieno elementus.
mainLayout->addWidget(top); mainLayout->addWidget(top);
mainLayout->addWidget(wForm); mainLayout->addWidget(wForm);
mainLayout->addItem(spacer); mainLayout->addItem(spacer);

View File

@@ -71,12 +71,20 @@ const QString buttonStyle =
"font-size: 15px;" "font-size: 15px;"
"}"; "}";
/*
* Pielāgots sarakta elements, kam var uzstādīt sarkanu, zaļu vai neitrālu (pelēku) krāsu.
* */
class CustomItemDelegate : public QStyledItemDelegate { class CustomItemDelegate : public QStyledItemDelegate {
public:
CustomItemDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
// Override the paint method to apply custom styling public:
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { CustomItemDelegate(QObject *parent = nullptr)
: QStyledItemDelegate(parent) {}
void paint(
QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index
) const override {
painter->save(); painter->save();
Qt::GlobalColor color; Qt::GlobalColor color;
auto colorIdx = index.data(Qt::UserRole + 1).toInt(); auto colorIdx = index.data(Qt::UserRole + 1).toInt();
@@ -100,6 +108,9 @@ public:
} }
}; };
/*
* Saraksta skats, kas tiek izmantots vairāku elementu jautājumā.
*/
class MultiChoiceListView : public QListView class MultiChoiceListView : public QListView
{ {
Q_OBJECT Q_OBJECT
@@ -114,6 +125,9 @@ public:
} }
}; };
/*
* Saraksta skats, kas tiek izmantots secības jautājumā.
*/
class OrderListView : public QListView class OrderListView : public QListView
{ {
Q_OBJECT Q_OBJECT
@@ -133,6 +147,8 @@ protected:
QModelIndex sourceIndex = currentIndex(); QModelIndex sourceIndex = currentIndex();
QModelIndex targetIndex = indexAt(event->pos()); QModelIndex targetIndex = indexAt(event->pos());
// Secības jautājumā, drag & drop var mainīt tikai secību -,
// novedot ar jautājumu uz otru jautājumu, tos pamaina vietām.
if (sourceIndex.isValid() && targetIndex.isValid()) { if (sourceIndex.isValid() && targetIndex.isValid()) {
QStandardItemModel *model = qobject_cast<QStandardItemModel *>(this->model()); QStandardItemModel *model = qobject_cast<QStandardItemModel *>(this->model());
if (model) { if (model) {
@@ -148,6 +164,9 @@ protected:
} }
}; };
/*
* Saraksta skats, kas tiek izmantots grupēšanas jautājumā.
*/
class MoveListView : public QListView class MoveListView : public QListView
{ {
Q_OBJECT Q_OBJECT
@@ -171,6 +190,8 @@ protected:
event->acceptProposedAction(); event->acceptProposedAction();
} }
// Ja elements pārvilkts uz šo sarakstu,
// tas tiks atvienots no sākotnējā skata un pievienots beigām.
void dropEvent(QDropEvent *event) override { void dropEvent(QDropEvent *event) override {
QListView *source = qobject_cast<QListView *>(event->source()); QListView *source = qobject_cast<QListView *>(event->source());
QStandardItemModel *sourceModel = qobject_cast<QStandardItemModel *>(source->model()); QStandardItemModel *sourceModel = qobject_cast<QStandardItemModel *>(source->model());
@@ -185,6 +206,7 @@ protected:
} }
}; };
// Nepieciešams, lai klases strādātu.
#include "trainWindow.moc" #include "trainWindow.moc"
struct GroupView { struct GroupView {
@@ -196,19 +218,17 @@ struct GroupView {
MoveListView itemList; MoveListView itemList;
}; };
#define ITEM_POOL_CHUNK 200 // Pamata komponentes
// Main components
QWidget *trainWidget; QWidget *trainWidget;
QVBoxLayout *vTrainWidget; QVBoxLayout *vTrainWidget;
CustomItemDelegate *itemDelegate; CustomItemDelegate *itemDelegate;
// Question // Jautājums.
QWidget *questionBox; QWidget *questionBox;
QVBoxLayout *vQuestionBox; QVBoxLayout *vQuestionBox;
QLabel *lQuestionText; QLabel *lQuestionText;
// Bottom buttons // Apakšējās pogas.
QVBoxLayout *vButtonBox; QVBoxLayout *vButtonBox;
QWidget *actionButtons; QWidget *actionButtons;
QHBoxLayout *hButtons; QHBoxLayout *hButtons;
@@ -218,18 +238,18 @@ QToolButton *btnShowAnswer;
QSpacerItem *rightSpacer; QSpacerItem *rightSpacer;
QToolButton *btnNext; QToolButton *btnNext;
// Answer question // Atbildes jautājums.
QLabel *answerText; QLabel *answerText;
// Multi-choice question // Izvēles jautājums.
QStandardItemModel *multiChoiceModel; QStandardItemModel *multiChoiceModel;
QListView *multiChoiceList; QListView *multiChoiceList;
// Order question // Secības jautājums.
OrderListView *orderList; OrderListView *orderList;
QStandardItemModel *orderModel; QStandardItemModel *orderModel;
// Group question // Grupas jautājums.
QStandardItemModel *groupItemModel; QStandardItemModel *groupItemModel;
QListView *groupItemList; QListView *groupItemList;
QWidget *wGroupQuestion; QWidget *wGroupQuestion;
@@ -237,22 +257,28 @@ QVBoxLayout *vGroups;
QSpacerItem *groupSpacer; QSpacerItem *groupSpacer;
std::vector<QStandardItemModel*> groupModels; std::vector<QStandardItemModel*> groupModels;
// Questions & State // Jautājumi un stāvokļa dati.
MdemBuffer *practiceBuffer; MdemBuffer *practiceBuffer;
int32_t currentQuestionIndex = -1; int32_t currentQuestionIndex = -1;
std::vector<GroupView*> groupViews; std::vector<GroupView*> groupViews;
PracticeAlgorithm practiceAlgoritm; PracticeAlgorithm practiceAlgoritm;
time_t lastTrainedAt; time_t lastTrainedAt;
std::default_random_engine rng;
std::vector<QStandardItem*> itemPool; std::vector<QStandardItem*> itemPool;
std::default_random_engine rng;
// Intervālu izvēles pogas.
QToolButton *btnNotRemembered; QToolButton *btnNotRemembered;
QToolButton *btnHard; QToolButton *btnHard;
QToolButton *btnMedium; QToolButton *btnMedium;
QToolButton *btnEasy; QToolButton *btnEasy;
#define ITEM_POOL_CHUNK 200
// Elementi no sarakstiem tiek
// pārizmantoti un pievienoti pēc pieprasījuma.
/*
* Aizņemas elementu no pārizmantota saraksta, papildinot sarakstu, ja nepieciešams.
*/
QStandardItem* acquireItem() { QStandardItem* acquireItem() {
if (itemPool.size() <= 0) { if (itemPool.size() <= 0) {
for (size_t i = 0; i < ITEM_POOL_CHUNK; ++i) { for (size_t i = 0; i < ITEM_POOL_CHUNK; ++i) {
@@ -264,11 +290,17 @@ QStandardItem* acquireItem() {
return item; return item;
} }
/*
* Atgriež elementu pārizmantotā sarakstā.
*/
void releaseItem(QStandardItem** item) { void releaseItem(QStandardItem** item) {
itemPool.push_back(*item); itemPool.push_back(*item);
(*item) = nullptr; (*item) = nullptr;
} }
/**
* Atgriež visus pārizmantotos elementus no saraksta modeļa.
*/
auto releaseAllInModel(QStandardItemModel *model) { auto releaseAllInModel(QStandardItemModel *model) {
auto itemCount = model->rowCount(); auto itemCount = model->rowCount();
for (size_t i = 0; i < itemCount; ++i) { for (size_t i = 0; i < itemCount; ++i) {
@@ -278,6 +310,9 @@ auto releaseAllInModel(QStandardItemModel *model) {
} }
}; };
/**
* Atgriež visus pārizmantotos elementus no katra modeļa.
*/
void releaseAllItems() { void releaseAllItems() {
releaseAllInModel(multiChoiceModel); releaseAllInModel(multiChoiceModel);
releaseAllInModel(groupItemModel); releaseAllInModel(groupItemModel);
@@ -287,6 +322,10 @@ void releaseAllItems() {
} }
} }
/**
* Paslēp visus jautājumu specifiskus
* un pogu elementus, izņemot pogu Nākamais.
*/
void hideQuestionElements() { void hideQuestionElements() {
lQuestionText->hide(); lQuestionText->hide();
answerText->hide(); answerText->hide();
@@ -302,6 +341,9 @@ void hideQuestionElements() {
btnShowAnswer->hide(); btnShowAnswer->hide();
} }
/*
* Parāda intervāla atbildes pogas.
*/
void showFeedBackButtons() { void showFeedBackButtons() {
btnNotRemembered->show(); btnNotRemembered->show();
btnHard->show(); btnHard->show();
@@ -309,11 +351,18 @@ void showFeedBackButtons() {
btnEasy->show(); btnEasy->show();
} }
/*
* Uzstāda atbildes jautājumu mācīšanās procesā.
*/
void setupAnswerQuestion(MultiElementQuestion *question) { void setupAnswerQuestion(MultiElementQuestion *question) {
// Jautājuma teksts.
lQuestionText->setText( lQuestionText->setText(
QString::fromStdString(question->questionText) QString::fromStdString(question->questionText)
); );
lQuestionText->show(); lQuestionText->show();
// Formē atbildes elementu.
auto ss = std::stringstream(); auto ss = std::stringstream();
for (auto answerEl: question->choices) { for (auto answerEl: question->choices) {
ss << std::format("- {}", answerEl.answer) << std::endl; ss << std::format("- {}", answerEl.answer) << std::endl;
@@ -325,35 +374,39 @@ void setupAnswerQuestion(MultiElementQuestion *question) {
answerText->hide(); answerText->hide();
} }
auto checkAnswerClicked = []() {
answerText->show();
btnCheck->hide();
if (practiceAlgoritm == SPACED) {
showFeedBackButtons();
}
};
// Rāda tikai atbildes parādīšanas opciju. // Rāda tikai atbildes parādīšanas opciju.
QObject::connect( QObject::connect(
btnShowAnswer, btnShowAnswer,
&QToolButton::clicked, &QToolButton::clicked,
[checkAnswerClicked](bool checked) { [](bool checked) {
checkAnswerClicked(); answerText->show();
// btnCheck->hide();
if (practiceAlgoritm == SPACED) {
showFeedBackButtons();
}
btnShowAnswer->hide(); btnShowAnswer->hide();
} }
); );
btnShowAnswer->show(); btnShowAnswer->show();
} }
/*
* Uzstāda secības jautājumu mācīšanās procesā.
*/
void setupOrderQuestion(MultiElementQuestion *question) { void setupOrderQuestion(MultiElementQuestion *question) {
// Jautājuma teksts.
lQuestionText->setText( lQuestionText->setText(
QString::fromStdString(question->questionText) QString::fromStdString(question->questionText)
); );
lQuestionText->show(); lQuestionText->show();
// Secības jautājumam ir nepieciešami jautājumi nejaušā secībā.
orderModel->clear(); orderModel->clear();
auto shuffledAnswers = question->choices; auto shuffledAnswers = question->choices;
std::shuffle(shuffledAnswers.begin(), shuffledAnswers.end(), rng); std::shuffle(shuffledAnswers.begin(), shuffledAnswers.end(), rng);
// Pievieno secības elementus.
auto addChoice = [](QStandardItem *item, std::string text) { auto addChoice = [](QStandardItem *item, std::string text) {
item->setData(QVariant(), Qt::CheckStateRole); item->setData(QVariant(), Qt::CheckStateRole);
item->setCheckable(false); item->setCheckable(false);
@@ -365,12 +418,15 @@ void setupOrderQuestion(MultiElementQuestion *question) {
addChoice(item, answerEl.answer); addChoice(item, answerEl.answer);
item->setData(NEUTRAL, Qt::UserRole + 1); item->setData(NEUTRAL, Qt::UserRole + 1);
} }
orderList->show(); orderList->show();
// Pārbaudes poga.
QObject::connect( QObject::connect(
btnCheck, btnCheck,
&QToolButton::clicked, &QToolButton::clicked,
[question](bool checked) { [question](bool checked) {
// Salīdzina atbildes pēc atbildes satura.
for (size_t i = 0; i < orderModel->rowCount(); ++i) { for (size_t i = 0; i < orderModel->rowCount(); ++i) {
auto item = orderModel->item(i, 0); auto item = orderModel->item(i, 0);
auto text = item->text(); auto text = item->text();
@@ -390,12 +446,14 @@ void setupOrderQuestion(MultiElementQuestion *question) {
} }
} }
); );
btnCheck->show();
// Pareizās atbildes poga.
btnCheck->show();
QObject::connect( QObject::connect(
btnShowAnswer, btnShowAnswer,
&QToolButton::clicked, &QToolButton::clicked,
[question](bool checked) { [question](bool checked) {
// Salīdzina atbildes pēc atbildes satura.
for (size_t i = 0; i < question->choices.size(); ++i) { for (size_t i = 0; i < question->choices.size(); ++i) {
auto item = orderModel->item(i, 0); auto item = orderModel->item(i, 0);
auto choice = question->choices[i]; auto choice = question->choices[i];
@@ -408,12 +466,18 @@ void setupOrderQuestion(MultiElementQuestion *question) {
); );
} }
/*
* Uzstāda vairāku elementu jautājumu mācīšanās procesā.
*/
void setupMultiChoiceQuestion(MultiElementQuestion *question) { void setupMultiChoiceQuestion(MultiElementQuestion *question) {
// Jautājuma teksts.
lQuestionText->setText( lQuestionText->setText(
QString::fromStdString(question->questionText) QString::fromStdString(question->questionText)
); );
lQuestionText->show(); lQuestionText->show();
// Pievieno izvēles elementus.
multiChoiceModel->clear(); multiChoiceModel->clear();
for (auto answerEl: question->choices) { for (auto answerEl: question->choices) {
auto *item = acquireItem(); auto *item = acquireItem();
@@ -425,11 +489,14 @@ void setupMultiChoiceQuestion(MultiElementQuestion *question) {
} }
multiChoiceList->show(); multiChoiceList->show();
// Rāda tikai pārbaudes opciju, jo izvēles jautājumam
// atbildi var saprast jau pēc pārbaudes.
QObject::connect( QObject::connect(
btnCheck, btnCheck,
&QToolButton::clicked, &QToolButton::clicked,
[question](bool checked) { [question](bool checked) {
for (size_t i = 0; i < multiChoiceModel->rowCount(); ++i) { for (size_t i = 0; i < multiChoiceModel->rowCount(); ++i) {
// Elementu secība nav mainīta -> skatās pareizumu pēc pozīcijas.
auto item = multiChoiceModel->item(i, 0); auto item = multiChoiceModel->item(i, 0);
auto isCorrect = question->choices[i].isCorrect == (item->checkState() == Qt::Checked); auto isCorrect = question->choices[i].isCorrect == (item->checkState() == Qt::Checked);
if (isCorrect) { if (isCorrect) {
@@ -437,6 +504,8 @@ void setupMultiChoiceQuestion(MultiElementQuestion *question) {
} else { } else {
item->setData(INCORRECT, Qt::UserRole + 1); item->setData(INCORRECT, Qt::UserRole + 1);
} }
// Jāatjauno saraksts, lai atjaunotos elementu krāsa.
multiChoiceList->update(); multiChoiceList->update();
} }
btnCheck->hide(); btnCheck->hide();
@@ -448,15 +517,22 @@ void setupMultiChoiceQuestion(MultiElementQuestion *question) {
btnCheck->show(); btnCheck->show();
} }
/*
* Uzstāda grupēšanas jautājumu mācīšanās procesā.
*/
void setupGroupQuestion(GroupQuestion *question) { void setupGroupQuestion(GroupQuestion *question) {
// Noņem tieši sākumā, lai pēc tam to pieliktu.
vGroups->removeItem(groupSpacer); vGroups->removeItem(groupSpacer);
// Jautājuma teksts.
lQuestionText->setText( lQuestionText->setText(
QString::fromStdString(question->questionText) QString::fromStdString(question->questionText)
); );
lQuestionText->show(); lQuestionText->show();
wGroupQuestion->show();
// Ieliek nesagrupētos elementus.
wGroupQuestion->show();
for (auto group: question->groups) { for (auto group: question->groups) {
for (auto itemText: group.elements) { for (auto itemText: group.elements) {
auto *qItem = acquireItem(); auto *qItem = acquireItem();
@@ -469,6 +545,14 @@ void setupGroupQuestion(GroupQuestion *question) {
} }
groupItemList->update(); groupItemList->update();
{ // Uzstāda grupu sarakstus, kur lietotājs pārliek elementus;
// Paslēp visas grupas.
for (int k = 0; k < groupViews.size(); k++) {
groupViews[k]->widget.hide();
}
// Izveido grupas sarakstus, ja nepietiek jau esošo.
auto makeGroup = []() { auto makeGroup = []() {
auto groupView = new GroupView; auto groupView = new GroupView;
vGroups->addWidget(&groupView->label); vGroups->addWidget(&groupView->label);
@@ -481,10 +565,6 @@ void setupGroupQuestion(GroupQuestion *question) {
groupView->widget.layout()->addWidget(&groupView->itemList); groupView->widget.layout()->addWidget(&groupView->itemList);
return groupView; return groupView;
}; };
for (int k = 0; k < groupViews.size(); k++) {
groupViews[k]->widget.hide();
}
for (size_t i = 0; i < question->groups.size(); i++) { for (size_t i = 0; i < question->groups.size(); i++) {
GroupView *groupView; GroupView *groupView;
if (i < groupViews.size()) { if (i < groupViews.size()) {
@@ -502,18 +582,27 @@ void setupGroupQuestion(GroupQuestion *question) {
groupView->widget.show(); groupView->widget.show();
} }
vGroups->addItem(groupSpacer); vGroups->addItem(groupSpacer);
}
// Pārbaudes poga.
QObject::connect( QObject::connect(
btnCheck, btnCheck,
&QToolButton::clicked, &QToolButton::clicked,
[question](bool checked) { [question](bool checked) {
// Katrs nesagrupēts -> nepareizs.
for (size_t i = 0; i < groupItemModel->rowCount(); ++i) { for (size_t i = 0; i < groupItemModel->rowCount(); ++i) {
auto item = groupItemModel->item(i, 0); auto item = groupItemModel->item(i, 0);
item->setData(INCORRECT, Qt::UserRole + 1); item->setData(INCORRECT, Qt::UserRole + 1);
} }
// Pārbauda elementus katrai grupai.
for (size_t i = 0; i < question->groups.size(); i++) { for (size_t i = 0; i < question->groups.size(); i++) {
auto groupView = groupViews[i]; auto groupView = groupViews[i];
auto group = question->groups[i]; auto group = question->groups[i];
// Ja pārnestā saraksta grupā elements ir atrasts atbilstošā grupā,
// tas ir pareizs, citādi - nepareizs.
for (int j = 0; j < groupView->itemModel.rowCount(); ++j) { for (int j = 0; j < groupView->itemModel.rowCount(); ++j) {
auto item = groupView->itemModel.item(j, 0); auto item = groupView->itemModel.item(j, 0);
auto itemText = item->text().toStdString(); auto itemText = item->text().toStdString();
@@ -542,15 +631,20 @@ void setupGroupQuestion(GroupQuestion *question) {
); );
btnCheck->show(); btnCheck->show();
// Atbildes parādīšanas poga.
QObject::connect( QObject::connect(
btnShowAnswer, btnShowAnswer,
&QToolButton::clicked, &QToolButton::clicked,
[question](bool checked) { [question](bool checked) {
// Vienkāršuma pēc atgriežam visus elementus.
releaseAllInModel(groupItemModel); releaseAllInModel(groupItemModel);
for (size_t i = 0; i < question->groups.size(); i++) { for (size_t i = 0; i < question->groups.size(); i++) {
auto groupView = groupViews[i]; auto groupView = groupViews[i];
auto group = question->groups[i]; auto group = question->groups[i];
releaseAllInModel(&groupView->itemModel); releaseAllInModel(&groupView->itemModel);
// Pievienojam elementus atbilstošiem sarakstam.
for (int j = 0; j < group.elements.size(); ++j) { for (int j = 0; j < group.elements.size(); ++j) {
auto *qItem = acquireItem(); auto *qItem = acquireItem();
auto groupElement = group.elements[j]; auto groupElement = group.elements[j];
@@ -561,8 +655,8 @@ void setupGroupQuestion(GroupQuestion *question) {
groupView->itemModel.appendRow(qItem); groupView->itemModel.appendRow(qItem);
} }
} }
btnShowAnswer->hide(); btnShowAnswer->hide();
if (practiceAlgoritm == SPACED) { if (practiceAlgoritm == SPACED) {
showFeedBackButtons(); showFeedBackButtons();
} }
@@ -570,11 +664,18 @@ void setupGroupQuestion(GroupQuestion *question) {
); );
} }
/*
* Uzstāda jebkura veida jautājumu mācīšanās procesā.
*/
void setupQuestion(Question *question) { void setupQuestion(Question *question) {
// Atiestata jautājuma skatu jautājuma uzstādīšanai.
hideQuestionElements(); hideQuestionElements();
releaseAllItems(); releaseAllItems();
QObject::disconnect(btnShowAnswer, 0, 0, 0); QObject::disconnect(btnShowAnswer, 0, 0, 0);
QObject::disconnect(btnCheck, 0, 0, 0); QObject::disconnect(btnCheck, 0, 0, 0);
// Izsauc atbilstošu f-ju jautājuma tipam.
if (auto *q = dynamic_cast<MultiElementQuestion*>(question)) { if (auto *q = dynamic_cast<MultiElementQuestion*>(question)) {
switch (q->type) { switch (q->type) {
case MultiElementType::Order: case MultiElementType::Order:
@@ -587,14 +688,15 @@ void setupQuestion(Question *question) {
setupAnswerQuestion(q); setupAnswerQuestion(q);
break; break;
} }
} else if ( } else if (auto *q = dynamic_cast<GroupQuestion*>(question)) {
auto *q = dynamic_cast<GroupQuestion*>(question)
) {
setupGroupQuestion(q); setupGroupQuestion(q);
} }
} }
void updatePaginationVisibility() { /*
* Parāda/paslēp nākamā jautājuma pogu.
* */
void updateNextButtonPrimary() {
if (currentQuestionIndex == practiceBuffer->questions.size() - 1) { if (currentQuestionIndex == practiceBuffer->questions.size() - 1) {
btnNext->hide(); btnNext->hide();
} else { } else {
@@ -602,12 +704,18 @@ void updatePaginationVisibility() {
} }
} }
/*
* Nejaušs indekss vektorā.
* */
template <typename T> template <typename T>
int randomIndex(std::vector<T> *vec) { int randomIndex(std::vector<T> *vec) {
srand(time(NULL)); srand(time(NULL));
return rand() % vec->size(); return rand() % vec->size();
} }
/*
* Iegūst UNIX epoch laiku.
* */
time_t getTime() { time_t getTime() {
auto now = std::chrono::system_clock::now(); auto now = std::chrono::system_clock::now();
return std::chrono::duration_cast<std::chrono::seconds>( return std::chrono::duration_cast<std::chrono::seconds>(
@@ -615,23 +723,31 @@ time_t getTime() {
).count(); ).count();
} }
/*
* Uzstāda nākamo jautajumu atbilstoši algoritmam.
*/
void setupNextQuestion() { void setupNextQuestion() {
if (practiceBuffer->questions.size() <= 0) { if (practiceBuffer->questions.size() <= 0) {
return; return;
} }
switch (practiceAlgoritm) { switch (practiceAlgoritm) {
case PRIMARY: { case PRIMARY: {
// Uzstāda nākamo pēc indeksa.
currentQuestionIndex++; currentQuestionIndex++;
if (currentQuestionIndex < practiceBuffer->questions.size()) { if (currentQuestionIndex < practiceBuffer->questions.size()) {
setupQuestion(practiceBuffer->questions[currentQuestionIndex]); setupQuestion(practiceBuffer->questions[currentQuestionIndex]);
} }
updatePaginationVisibility(); updateNextButtonPrimary();
} break; } break;
case RANDOM: { case RANDOM: {
// Iegūst kandidātus - visi jautājumi, izņemot tagadējo.
auto questionCandidates = practiceBuffer->questions; auto questionCandidates = practiceBuffer->questions;
if (currentQuestionIndex > -1) { if (currentQuestionIndex > -1) {
questionCandidates.erase(questionCandidates.begin() + currentQuestionIndex); questionCandidates.erase(questionCandidates.begin() + currentQuestionIndex);
} }
// Iegūst nejaušo jautājumu.
if (questionCandidates.size() > 0) { if (questionCandidates.size() > 0) {
auto i = randomIndex(&questionCandidates); auto i = randomIndex(&questionCandidates);
setupQuestion(questionCandidates[i]); setupQuestion(questionCandidates[i]);
@@ -644,6 +760,9 @@ void setupNextQuestion() {
} }
} break; } break;
case SPACED: { case SPACED: {
// Iegūst kandidātus - jautājumi (izņemot tagadējo), kam ir pagājis pārtraukums, vai kam tā nav.
// Noteikšanas laikā atjauno pārtraukuma skaitli, balstoties uz tagadējo laiku.
auto questionCandidates = std::vector<Question*>(); auto questionCandidates = std::vector<Question*>();
time_t time = getTime(); time_t time = getTime();
auto lastTrainedAt = practiceBuffer->trainedAt; auto lastTrainedAt = practiceBuffer->trainedAt;
@@ -660,6 +779,8 @@ void setupNextQuestion() {
} }
practiceBuffer->questions[i]->cooldown = (double)newCooldown / 3600; practiceBuffer->questions[i]->cooldown = (double)newCooldown / 3600;
} }
// Ja kandidāti eksistē, izvēlas nejaušo.
if (questionCandidates.size() > 0) { if (questionCandidates.size() > 0) {
auto i = randomIndex(&questionCandidates); auto i = randomIndex(&questionCandidates);
setupQuestion( setupQuestion(
@@ -672,28 +793,35 @@ void setupNextQuestion() {
} }
} }
} }
// Ir jāatjauno atmiņas kartīšu skats,
// jo ir potenciāli izmainīti pārtraukumi.
update(true); update(true);
} break; } break;
} }
} }
/*
* Iesāk mācīšanos ar padotiem jautājumiem un algoritmu.
* */
void initiatePractice( void initiatePractice(
MdemBuffer *mdemBuffer, MdemBuffer *mdemBuffer,
PracticeAlgorithm algorithm PracticeAlgorithm algorithm
) { ) {
practiceAlgoritm = algorithm; practiceAlgoritm = algorithm;
practiceBuffer = mdemBuffer; practiceBuffer = mdemBuffer;
if (practiceBuffer->questions.size() <= 0) { if (practiceBuffer->questions.size() <= 0) {
return; return;
} }
currentQuestionIndex = -1; currentQuestionIndex = -1;
hideQuestionElements(); hideQuestionElements();
updatePaginationVisibility(); updateNextButtonPrimary();
setupNextQuestion(); setupNextQuestion();
} }
/*
* Uzstāda tagadējā jautājuma pārtraukumu.
*/
void setCooldownHours(double cooldown) { void setCooldownHours(double cooldown) {
time_t time = getTime(); time_t time = getTime();
practiceBuffer->trainedAt = time; practiceBuffer->trainedAt = time;
@@ -702,22 +830,30 @@ void setCooldownHours(double cooldown) {
update(true); update(true);
} }
/*
* Inicializē mācīšanās logu.
* */
QMainWindow *initTrainWindow() { QMainWindow *initTrainWindow() {
// Inicializē RNG nejaušiem jautājumiem.
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);
auto trainWindow = new QMainWindow(); auto trainWindow = new QMainWindow();
{ // Mācīšanās komponente.
trainWidget = new QWidget(); trainWidget = new QWidget();
vTrainWidget = new QVBoxLayout(); vTrainWidget = new QVBoxLayout();
trainWidget->setLayout(vTrainWidget); trainWidget->setLayout(vTrainWidget);
trainWindow->setCentralWidget(trainWidget); trainWindow->setCentralWidget(trainWidget);
trainWidget->setLayout(vTrainWidget); trainWidget->setLayout(vTrainWidget);
vTrainWidget->setAlignment(Qt::AlignCenter); vTrainWidget->setAlignment(Qt::AlignCenter);
trainWidget->setObjectName("answer-question-widget"); trainWidget->setObjectName("answer-question-widget");
}
// Pārizmantots elementu delegāts.
itemDelegate = new CustomItemDelegate(multiChoiceList); itemDelegate = new CustomItemDelegate(multiChoiceList);
// Pievieno īsceļu ar doto f-ju.
auto addShortcut = [trainWindow](QString key, std::function<void()> func) { auto addShortcut = [trainWindow](QString key, std::function<void()> func) {
QShortcut* shortcut = new QShortcut(QKeySequence(key), trainWindow); QShortcut* shortcut = new QShortcut(QKeySequence(key), trainWindow);
QObject::connect(shortcut, &QShortcut::activated, [func]() { QObject::connect(shortcut, &QShortcut::activated, [func]() {
@@ -725,42 +861,55 @@ QMainWindow *initTrainWindow() {
}); });
}; };
{ // Top button menu. { // Augšējā pogu izvēlne.
// Izklājums.
auto hTopButtons = new QHBoxLayout(); auto hTopButtons = new QHBoxLayout();
auto topButtons = new QWidget(); auto topButtons = new QWidget();
topButtons->setStyleSheet(buttonStyle); topButtons->setStyleSheet(buttonStyle);
topButtons->setLayout(hTopButtons); topButtons->setLayout(hTopButtons);
auto topLeftSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum); // Starplika, lai poga parādās labā pusē.
auto topLeftSpacer = new QSpacerItem(
50,
50,
QSizePolicy::Expanding,
QSizePolicy::Minimum
);
hTopButtons->addItem(topLeftSpacer);
// Saglabāšanas poga.
auto btnSaveProgress = new QToolButton(); auto btnSaveProgress = new QToolButton();
btnSaveProgress->setText("Saglabāt progresu"); btnSaveProgress->setText("Saglabāt progresu");
hTopButtons->addItem(topLeftSpacer);
hTopButtons->addWidget(btnSaveProgress);
vTrainWidget->addWidget(topButtons);
QObject::connect(btnSaveProgress, &QToolButton::clicked, []() { QObject::connect(btnSaveProgress, &QToolButton::clicked, []() {
saveMdem(); saveMdem();
}); });
addShortcut(
QShortcut* shortcutSaveProgress = new QShortcut(QKeySequence("Ctrl+S"), trainWindow); "Ctrl+S",
QObject::connect(shortcutSaveProgress, &QShortcut::activated, []() { []() {
saveMdem(); saveMdem();
}); }
);
hTopButtons->addWidget(btnSaveProgress);
vTrainWidget->addWidget(topButtons);
} }
{ // Make the question box. { // Jautājuma box.
questionBox = new QWidget(); questionBox = new QWidget();
questionBox->setStyleSheet( questionBox->setStyleSheet(
"font-size: 15px;" "font-size: 15px;"
); );
vQuestionBox = new QVBoxLayout(); vQuestionBox = new QVBoxLayout();
questionBox->setLayout(vQuestionBox); questionBox->setLayout(vQuestionBox);
questionBox->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); questionBox->setSizePolicy(
QSizePolicy::Minimum,
QSizePolicy::Expanding
);
vQuestionBox->setAlignment(Qt::AlignCenter); vQuestionBox->setAlignment(Qt::AlignCenter);
} }
{ // Make question text. { // Jautājuma teksts.
lQuestionText = new QLabel(); lQuestionText = new QLabel();
lQuestionText->setWordWrap(true); lQuestionText->setWordWrap(true);
lQuestionText->setStyleSheet(QString( lQuestionText->setStyleSheet(QString(
@@ -773,7 +922,7 @@ QMainWindow *initTrainWindow() {
lQuestionText->hide(); lQuestionText->hide();
} }
{ // Make multi-choice list. { // Izvēles saraksts.
multiChoiceModel = new QStandardItemModel(); multiChoiceModel = new QStandardItemModel();
multiChoiceList = new MultiChoiceListView(); multiChoiceList = new MultiChoiceListView();
multiChoiceList->setModel(multiChoiceModel); multiChoiceList->setModel(multiChoiceModel);
@@ -783,7 +932,7 @@ QMainWindow *initTrainWindow() {
multiChoiceList->setItemDelegate(itemDelegate); multiChoiceList->setItemDelegate(itemDelegate);
} }
{ // Make answer text. { // Atbildes teksts.
answerText = new QLabel(); answerText = new QLabel();
answerText->setWordWrap(true); answerText->setWordWrap(true);
answerText->setStyleSheet(QString( answerText->setStyleSheet(QString(
@@ -796,33 +945,63 @@ QMainWindow *initTrainWindow() {
answerText->hide(); answerText->hide();
} }
{ // Make order list. { // Secības jautājums.
orderModel = new QStandardItemModel(); orderModel = new QStandardItemModel();
orderList = new OrderListView(); orderList = new OrderListView();
orderList->setModel(orderModel); orderList->setModel(orderModel);
orderList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); orderList->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
orderList->setItemDelegate(itemDelegate); orderList->setItemDelegate(itemDelegate);
// Connect to handle the drop event properly
QObject::connect(
orderModel,
&QStandardItemModel::rowsMoved,
[](const QModelIndex &, int sourceRow, int, const QModelIndex &, int destinationRow) {
if (sourceRow != destinationRow - 1) {
auto *movedItem = orderModel->takeItem(sourceRow);
orderModel->insertRow(destinationRow > sourceRow ? destinationRow - 1 : destinationRow, movedItem);
}
}
);
questionBox->layout()->addWidget(orderList); questionBox->layout()->addWidget(orderList);
orderList->hide(); orderList->hide();
} }
{ // Make buttons menu. There are left middle and right buttons. { // Grupēšanas jautājums.
// Izklājums.
wGroupQuestion = new QWidget();
wGroupQuestion->setStyleSheet(
"border:none;"
);
auto hGroupQuestion = new QHBoxLayout();
groupSpacer = new QSpacerItem(
50, 50,
QSizePolicy::Minimum,
QSizePolicy::Expanding
);
wGroupQuestion->setLayout(hGroupQuestion);
wGroupQuestion->setStyleSheet("padding: 0; margin: 0;");
wGroupQuestion->hide();
// Kreisais saraksts.
auto itemScroll = new QScrollArea();
auto vItems = new QVBoxLayout();
itemScroll->setLayout(vItems);
groupItemModel = new QStandardItemModel();
groupItemList = new MoveListView();
groupItemList->setItemDelegate(itemDelegate);
groupItemList->setModel(groupItemModel);
vItems->addWidget(groupItemList);
hGroupQuestion->addWidget(itemScroll);
// Labais saraksts.
auto groupScroll = new QScrollArea();
auto wGroupContainer = new QWidget();
vGroups = new QVBoxLayout();
groupScroll->setWidget(wGroupContainer);
groupScroll->setWidgetResizable(true);
wGroupContainer->setLayout(vGroups);
hGroupQuestion->addWidget(groupScroll);
questionBox->layout()->addWidget(wGroupQuestion);
}
{ // Lejas pogu izvēlne - ir centra un labās puses pogas.
// Pamata elementi.
vButtonBox = new QVBoxLayout(); vButtonBox = new QVBoxLayout();
actionButtons = new QWidget(); actionButtons = new QWidget();
hButtons = new QHBoxLayout(); hButtons = new QHBoxLayout();
leftSpacer = new QSpacerItem( leftSpacer = new QSpacerItem(
50, 50,
50, 50,
@@ -830,7 +1009,8 @@ QMainWindow *initTrainWindow() {
QSizePolicy::Minimum QSizePolicy::Minimum
); );
btnCheck = new QToolButton(); // Intervālu pogām uzstāda pārtraukumu no uzstādījumiem vai noklusējuma
// vērtību, ja nav norādīts.
btnNotRemembered = new QToolButton(); btnNotRemembered = new QToolButton();
QObject::connect(btnNotRemembered, &QToolButton::clicked, []() { QObject::connect(btnNotRemembered, &QToolButton::clicked, []() {
QString key = SETTING_NOT_REMEMBERED; QString key = SETTING_NOT_REMEMBERED;
@@ -867,6 +1047,8 @@ QMainWindow *initTrainWindow() {
setCooldownHours(48); setCooldownHours(48);
} }
}); });
// Intervālu pogu teksti un īsceļi.
btnNotRemembered->setText("Neatcerējos (Z)"); btnNotRemembered->setText("Neatcerējos (Z)");
addShortcut("Z", []() { addShortcut("Z", []() {
if (btnNotRemembered->isVisible()) { if (btnNotRemembered->isVisible()) {
@@ -892,21 +1074,44 @@ QMainWindow *initTrainWindow() {
} }
}); });
// Kontroles pogas.
btnCheck = new QToolButton(); btnCheck = new QToolButton();
QShortcut* shortcutCheck = new QShortcut(QKeySequence("Return"), trainWindow);
QObject::connect(shortcutCheck, &QShortcut::activated, []() {
btnCheck->click();
});
btnShowAnswer = new QToolButton(); btnShowAnswer = new QToolButton();
QShortcut* shortcutShowAnswer = new QShortcut(QKeySequence("Return"), trainWindow); btnCheck->setText("Pārbaudīt atbildi");
QObject::connect(shortcutShowAnswer, &QShortcut::activated, []() { btnShowAnswer->setText("Parādīt atbildi");
addShortcut(
"Return",
[]() {
if (btnCheck->isVisible()) {
btnCheck->click();
}
if (btnShowAnswer->isVisible()) {
btnShowAnswer->click(); btnShowAnswer->click();
}
}
);
btnCheck->hide();
btnShowAnswer->hide();
// Nākamāis poga.
rightSpacer = new QSpacerItem(
50,
50,
QSizePolicy::Expanding,
QSizePolicy::Minimum
);
btnNext = new QToolButton();
btnNext->setText("Nākamais");
QObject::connect(btnNext, &QToolButton::clicked, []() {
setupNextQuestion();
});
addShortcut("l", []() {
if (btnNext->isVisible()) {
btnNext->click();
}
}); });
rightSpacer = new QSpacerItem(50, 50, QSizePolicy::Expanding, QSizePolicy::Minimum); // Pievieno pogas.
btnNext = new QToolButton();
hButtons->addItem(leftSpacer); hButtons->addItem(leftSpacer);
hButtons->addWidget(btnCheck); hButtons->addWidget(btnCheck);
hButtons->addWidget(btnShowAnswer); hButtons->addWidget(btnShowAnswer);
@@ -914,71 +1119,16 @@ QMainWindow *initTrainWindow() {
hButtons->addWidget(btnHard); hButtons->addWidget(btnHard);
hButtons->addWidget(btnMedium); hButtons->addWidget(btnMedium);
hButtons->addWidget(btnEasy); hButtons->addWidget(btnEasy);
hButtons->addItem(rightSpacer); hButtons->addItem(rightSpacer);
hButtons->addWidget(btnNext); hButtons->addWidget(btnNext);
vButtonBox->addWidget(actionButtons); vButtonBox->addWidget(actionButtons);
actionButtons->setLayout(hButtons); actionButtons->setLayout(hButtons);
btnCheck->setText("Pārbaudīt atbildi");
btnShowAnswer->setText("Parādīt atbildi");
btnCheck->hide();
btnShowAnswer->hide();
btnNext->setText("Nākamais");
QObject::connect(btnNext, &QToolButton::clicked, []() {
setupNextQuestion();
});
questionBox->setObjectName("question-box"); questionBox->setObjectName("question-box");
actionButtons->setStyleSheet(buttonStyle); actionButtons->setStyleSheet(buttonStyle);
} }
{ // Make group question view. // Pievieno uzstādīto.
wGroupQuestion = new QWidget();
wGroupQuestion->setStyleSheet(
"border:none;"
);
auto hGroupQuestion = new QHBoxLayout();
groupSpacer = new QSpacerItem(
50, 50,
QSizePolicy::Minimum,
QSizePolicy::Expanding
);
wGroupQuestion->setLayout(hGroupQuestion);
// Items on the left.
auto itemScroll = new QScrollArea();
auto vItems = new QVBoxLayout();
itemScroll->setLayout(vItems);
groupItemModel = new QStandardItemModel();
groupItemList = new MoveListView();
groupItemList->setItemDelegate(itemDelegate);
groupItemList->setModel(groupItemModel);
vItems->addWidget(groupItemList);
hGroupQuestion->addWidget(itemScroll);
// Items on the right.
auto groupScroll = new QScrollArea();
auto wGroupContainer = new QWidget();
vGroups = new QVBoxLayout();
groupScroll->setWidget(wGroupContainer);
groupScroll->setWidgetResizable(true);
wGroupContainer->setLayout(vGroups);
hGroupQuestion->addWidget(groupScroll);
wGroupQuestion->setStyleSheet("padding: 0; margin: 0;");
wGroupQuestion->hide();
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; return trainWindow;

View File

@@ -16,11 +16,17 @@ bool showTimes = false;
std::chrono::high_resolution_clock::time_point start; std::chrono::high_resolution_clock::time_point start;
std::chrono::high_resolution_clock::time_point end; std::chrono::high_resolution_clock::time_point end;
std::string wrapText(std::string text, size_t width) { /*
* Pārveido teksta rindu tā, lai teksts nepārsniegtu doto
* platumu. Pievieno nākamās rindās atstarpi ar platumu kurā sākas pirmās rindas
* teksts.
* */
std::string wrapLine(std::string text, size_t width) {
std::string result; std::string result;
size_t currentLineLength = 0; size_t currentLineLength = 0;
size_t wordStart = 0; size_t wordStart = 0;
// Nosaka, cik tālu no rindas sākuma atrodas teksts pirmā rindā.
size_t preservedSpaceCount = 0; size_t preservedSpaceCount = 0;
for (size_t i = 0; i < text.length(); ++i) { for (size_t i = 0; i < text.length(); ++i) {
if (text[i] == '\t') { if (text[i] == '\t') {
@@ -37,7 +43,9 @@ std::string wrapText(std::string text, size_t width) {
for (size_t i = wordStart; i < text.length(); ++i) { for (size_t i = wordStart; i < text.length(); ++i) {
if (text[i] == ' ' || i == text.length() - 1) { if (text[i] == ' ' || i == text.length() - 1) {
size_t wordEnd = (i == text.length() - 1) ? i + 1 : i; // Handle the last word // Ja vārds pārsniedz norādīto platumu, pievieno
// jaunās rindas simbolu un turpina no iepriekš noteiktā attāluma.
size_t wordEnd = (i == text.length() - 1) ? i + 1 : i;
size_t wordLength = wordEnd - wordStart; size_t wordLength = wordEnd - wordStart;
if (currentLineLength + wordLength > width) { if (currentLineLength + wordLength > width) {
result += '\n'; result += '\n';
@@ -53,6 +61,9 @@ std::string wrapText(std::string text, size_t width) {
return result; return result;
} }
/*
* Tekstā katram rezervētam tekstvienību simbolam pievieno '\' pirms simbola.
*/
std::string escapeText(std::string text) { std::string escapeText(std::string text) {
std::stringstream ss; std::stringstream ss;
for (auto c: text) { for (auto c: text) {
@@ -89,6 +100,10 @@ std::string escapeText(std::string text) {
return ss.str(); return ss.str();
} }
/*
* Transpilē tekstu jautājumos un metadatos.
* Veic leksisko analīzi un parsēšanu.
* */
Result<ParseInfo> transpile(std::string fileContent) { Result<ParseInfo> transpile(std::string fileContent) {
start = std::chrono::high_resolution_clock::now(); start = std::chrono::high_resolution_clock::now();
end = std::chrono::high_resolution_clock::now(); end = std::chrono::high_resolution_clock::now();
@@ -125,7 +140,9 @@ Result<ParseInfo> transpile(std::string fileContent) {
return {questions}; return {questions};
} }
/*
* Parāda nomērīta laika sekundes un milisekundes.
*/
std::string showTime(std::string label) { std::string showTime(std::string label) {
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start); auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
double_t seconds = (double_t) duration.count() / 1000000; double_t seconds = (double_t) duration.count() / 1000000;