mirror of
https://gitlab.cvh-server.de/skrause/flashcards.git
synced 2025-12-12 07:51:38 +01:00
more stuff!
This commit is contained in:
@@ -4,6 +4,7 @@ resources/ui/create-card.blp
|
|||||||
src/flashcardsapp.c
|
src/flashcardsapp.c
|
||||||
src/flashcardsappwin.c
|
src/flashcardsappwin.c
|
||||||
src/create-category.c
|
src/create-category.c
|
||||||
|
src/create-card.c
|
||||||
src/database.c
|
src/database.c
|
||||||
resources/li.sopht.Flashcards.desktop.in
|
resources/li.sopht.Flashcards.desktop.in
|
||||||
resources/li.sopht.Flashcards.metainfo.xml.in
|
resources/li.sopht.Flashcards.metainfo.xml.in
|
||||||
|
|||||||
@@ -10,17 +10,22 @@ template $FlashcardsCreateCardDialog : Adw.AlertDialog {
|
|||||||
]
|
]
|
||||||
response => $on_response();
|
response => $on_response();
|
||||||
|
|
||||||
Adw.EntryRow titleEntry {
|
Box {
|
||||||
title: _("Title");
|
orientation: vertical;
|
||||||
styles [
|
spacing: 12;
|
||||||
"card",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
Adw.EntryRow answerEntry {
|
Adw.EntryRow titleEntry {
|
||||||
title: _("Answer");
|
title: _("Title");
|
||||||
styles [
|
styles [
|
||||||
"card",
|
"card",
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
Adw.EntryRow answerEntry {
|
||||||
|
title: _("Answer");
|
||||||
|
styles [
|
||||||
|
"card",
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,10 +29,11 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
|
|||||||
tooltip-text: _("Create category");
|
tooltip-text: _("Create category");
|
||||||
}
|
}
|
||||||
[start]
|
[start]
|
||||||
Gtk.Button {
|
Gtk.Button delete_category_button {
|
||||||
icon-name: "user-trash-symbolic";
|
icon-name: "user-trash-symbolic";
|
||||||
clicked => $on_delete_category();
|
clicked => $on_delete_category();
|
||||||
tooltip-text: _("Delete category");
|
tooltip-text: _("Delete category");
|
||||||
|
visible: false;
|
||||||
}
|
}
|
||||||
[end]
|
[end]
|
||||||
Gtk.MenuButton {
|
Gtk.MenuButton {
|
||||||
@@ -62,16 +63,18 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
|
|||||||
[top]
|
[top]
|
||||||
Adw.HeaderBar {
|
Adw.HeaderBar {
|
||||||
[start]
|
[start]
|
||||||
Gtk.Button {
|
Gtk.Button add_card_button {
|
||||||
icon-name: "list-add-symbolic";
|
icon-name: "list-add-symbolic";
|
||||||
clicked => $on_add_card();
|
clicked => $on_add_card();
|
||||||
tooltip-text: _("Add flashcard");
|
tooltip-text: _("Add flashcard");
|
||||||
|
visible: false;
|
||||||
}
|
}
|
||||||
[start]
|
[start]
|
||||||
Gtk.Button {
|
Gtk.Button delete_card_button {
|
||||||
icon-name: "user-trash-symbolic";
|
icon-name: "user-trash-symbolic";
|
||||||
clicked => $on_delete_card();
|
clicked => $on_delete_card();
|
||||||
tooltip-text: _("Delete flashcard");
|
tooltip-text: _("Delete flashcard");
|
||||||
|
visible: false;
|
||||||
}
|
}
|
||||||
[title]
|
[title]
|
||||||
Adw.WindowTitle title {
|
Adw.WindowTitle title {
|
||||||
@@ -107,10 +110,11 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
|
|||||||
margin-start: 12;
|
margin-start: 12;
|
||||||
margin-end: 12;
|
margin-end: 12;
|
||||||
|
|
||||||
Box {
|
Button {
|
||||||
styles ["card", "activatable"]
|
styles ["card", "activatable"]
|
||||||
halign: center;
|
halign: center;
|
||||||
Label {
|
clicked => $on_flip_card();
|
||||||
|
Label card_title {
|
||||||
styles ["title-4"]
|
styles ["title-4"]
|
||||||
margin-top: 24;
|
margin-top: 24;
|
||||||
margin-bottom: 24;
|
margin-bottom: 24;
|
||||||
@@ -130,9 +134,9 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
|
|||||||
styles ["linked"]
|
styles ["linked"]
|
||||||
Button {
|
Button {
|
||||||
styles ["pill"]
|
styles ["pill"]
|
||||||
label: _("Easy");
|
label: _("Hard");
|
||||||
hexpand: true;
|
hexpand: true;
|
||||||
clicked => $on_answer_easy();
|
clicked => $on_answer_hard();
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
styles ["pill"]
|
styles ["pill"]
|
||||||
@@ -142,9 +146,9 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
|
|||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
styles ["pill"]
|
styles ["pill"]
|
||||||
label: _("Hard");
|
label: _("Easy");
|
||||||
hexpand: true;
|
hexpand: true;
|
||||||
clicked => $on_answer_hard();
|
clicked => $on_answer_easy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
59
src/create-card.c
Normal file
59
src/create-card.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "create-card.h"
|
||||||
|
|
||||||
|
struct _FlashcardsCreateCardDialog
|
||||||
|
{
|
||||||
|
AdwAlertDialog parent;
|
||||||
|
|
||||||
|
GtkEditable *titleEntry;
|
||||||
|
GtkEditable *answerEntry;
|
||||||
|
|
||||||
|
FlashcardsAppWindow *win;
|
||||||
|
};
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (FlashcardsCreateCardDialog, flashcards_create_card_dialog,
|
||||||
|
ADW_TYPE_ALERT_DIALOG);
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_response (__attribute__ ((unused)) AdwAlertDialog *dialog,
|
||||||
|
const gchar *response, gpointer user_data)
|
||||||
|
{
|
||||||
|
FlashcardsCreateCardDialog *self = user_data;
|
||||||
|
|
||||||
|
const gchar *title = gtk_editable_get_text (self->titleEntry);
|
||||||
|
const gchar *answer = gtk_editable_get_text (self->answerEntry);
|
||||||
|
|
||||||
|
if (strcmp (response, "add") == 0 && strlen (title) > 0
|
||||||
|
&& strlen (answer) > 0)
|
||||||
|
flashcards_app_window_add_card (self->win, title, answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flashcards_create_card_dialog_init (FlashcardsCreateCardDialog *self)
|
||||||
|
{
|
||||||
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flashcards_create_card_dialog_class_init (
|
||||||
|
FlashcardsCreateCardDialogClass *klass)
|
||||||
|
{
|
||||||
|
gtk_widget_class_set_template_from_resource (
|
||||||
|
GTK_WIDGET_CLASS (klass), "/li/sopht/flashcards/create-card.ui");
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (
|
||||||
|
GTK_WIDGET_CLASS (klass), FlashcardsCreateCardDialog, titleEntry);
|
||||||
|
gtk_widget_class_bind_template_child (
|
||||||
|
GTK_WIDGET_CLASS (klass), FlashcardsCreateCardDialog, answerEntry);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass),
|
||||||
|
on_response);
|
||||||
|
}
|
||||||
|
|
||||||
|
FlashcardsCreateCardDialog *
|
||||||
|
flashcards_create_card_dialog_new (FlashcardsAppWindow *win)
|
||||||
|
{
|
||||||
|
FlashcardsCreateCardDialog *self
|
||||||
|
= g_object_new (FLASHCARDS_CREATE_CARD_DIALOG_TYPE, nullptr);
|
||||||
|
self->win = win;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
17
src/create-card.h
Normal file
17
src/create-card.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef __CREATECARDDIALOG_H
|
||||||
|
#define __CREATECARDDIALOG_H
|
||||||
|
|
||||||
|
#include "flashcardsappwin.h"
|
||||||
|
#include <adwaita.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
#define FLASHCARDS_CREATE_CARD_DIALOG_TYPE \
|
||||||
|
(flashcards_create_card_dialog_get_type ())
|
||||||
|
G_DECLARE_FINAL_TYPE (FlashcardsCreateCardDialog,
|
||||||
|
flashcards_create_card_dialog, FLASHCARDS,
|
||||||
|
CREATE_CARD_DIALOG, AdwAlertDialog)
|
||||||
|
|
||||||
|
FlashcardsCreateCardDialog *
|
||||||
|
flashcards_create_card_dialog_new (FlashcardsAppWindow *win);
|
||||||
|
|
||||||
|
#endif /* __CREATECARDDIALOG_H */
|
||||||
@@ -1,8 +1,3 @@
|
|||||||
#include <adwaita.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
|
||||||
|
|
||||||
#include "create-category.h"
|
#include "create-category.h"
|
||||||
|
|
||||||
struct _FlashcardsCreateCategoryDialog
|
struct _FlashcardsCreateCategoryDialog
|
||||||
@@ -18,21 +13,21 @@ G_DEFINE_TYPE (FlashcardsCreateCategoryDialog,
|
|||||||
flashcards_create_category_dialog, ADW_TYPE_ALERT_DIALOG);
|
flashcards_create_category_dialog, ADW_TYPE_ALERT_DIALOG);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
flashcards_create_category_dialog_init (FlashcardsCreateCategoryDialog *self)
|
on_response (__attribute__ ((unused)) AdwAlertDialog *dialog,
|
||||||
{
|
const gchar *response, gpointer user_data)
|
||||||
gtk_widget_init_template (GTK_WIDGET (self));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_response (__attribute__ ((unused)) AdwAlertDialog *dialog, gchar *response,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
FlashcardsCreateCategoryDialog *self = user_data;
|
FlashcardsCreateCategoryDialog *self = user_data;
|
||||||
|
|
||||||
const gchar *category = gtk_editable_get_text (self->entry);
|
const gchar *category = gtk_editable_get_text (self->entry);
|
||||||
|
|
||||||
if (strcmp (response, "add") == 0 && strlen (category) > 0)
|
if (strcmp (response, "add") == 0 && strlen (category) > 0)
|
||||||
flashcards_app_window_test (self->win, category);
|
flashcards_app_window_add_category (self->win, category);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
flashcards_create_category_dialog_init (FlashcardsCreateCategoryDialog *self)
|
||||||
|
{
|
||||||
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#ifndef __CREATECATEGORYDIALOG_H
|
#ifndef __CREATECATEGORYDIALOG_H
|
||||||
#define __CREATECATEGORYDIALOG_H
|
#define __CREATECATEGORYDIALOG_H
|
||||||
|
|
||||||
#include "flashcardsapp.h"
|
|
||||||
#include "flashcardsappwin.h"
|
#include "flashcardsappwin.h"
|
||||||
#include <adwaita.h>
|
#include <adwaita.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|||||||
@@ -35,10 +35,11 @@ database_create_tables (sqlite3 *db)
|
|||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
const char *sql = "CREATE TABLE IF NOT EXISTS `cards` ("
|
const char *sql = "CREATE TABLE IF NOT EXISTS `cards` ("
|
||||||
"`id` INTEGER NOT NULL,"
|
"`id` INTEGER NOT NULL,"
|
||||||
"`category` INTEGER NOT NULL,"
|
"`category` INTEGER NOT NULL,"
|
||||||
"`task` TEXT NOT NULL,"
|
"`title` TEXT NOT NULL,"
|
||||||
"`solution` TEXT NOT NULL,"
|
"`answer` TEXT NOT NULL,"
|
||||||
|
"`next_time` INTEGER NOT NULL DEFAULT (unixepoch()),"
|
||||||
"PRIMARY KEY(`id` AUTOINCREMENT)"
|
"PRIMARY KEY(`id` AUTOINCREMENT)"
|
||||||
")";
|
")";
|
||||||
|
|
||||||
@@ -77,8 +78,11 @@ database_save_category (sqlite3 *db, const char *c)
|
|||||||
printf ("Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
printf ("Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
rc = sqlite3_step (stmt);
|
rc = sqlite3_step (stmt);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_DONE)
|
||||||
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
{
|
||||||
|
fprintf (stderr, "Failed to execute statement: %s\n",
|
||||||
|
sqlite3_errmsg (db));
|
||||||
|
}
|
||||||
sqlite3_finalize (stmt);
|
sqlite3_finalize (stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,7 +122,7 @@ database_delete_category (sqlite3 *db, const int id)
|
|||||||
else
|
else
|
||||||
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
rc = sqlite3_step (stmt);
|
rc = sqlite3_step (stmt);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_DONE)
|
||||||
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
||||||
sqlite3_finalize (stmt);
|
sqlite3_finalize (stmt);
|
||||||
|
|
||||||
@@ -129,30 +133,34 @@ database_delete_category (sqlite3 *db, const int id)
|
|||||||
sqlite3_bind_int (stmt, 1, id);
|
sqlite3_bind_int (stmt, 1, id);
|
||||||
else
|
else
|
||||||
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
rc = sqlite3_step (stmt);
|
rc = sqlite3_step (stmt);
|
||||||
if (rc != SQLITE_OK)
|
if (rc != SQLITE_DONE)
|
||||||
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
||||||
sqlite3_finalize (stmt);
|
sqlite3_finalize (stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
database_save_card (sqlite3 *db, const card c)
|
database_save_card (sqlite3 *db, const int category, const char *title,
|
||||||
|
const char *answer)
|
||||||
{
|
{
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
fprintf (stdout, "%s: %s\n", c.task, c.solution);
|
int rc = sqlite3_prepare_v2 (
|
||||||
int rc = sqlite3_prepare_v2 (db, "INSERT INTO cards VALUES(?, ?, ?)", -1,
|
db, "INSERT INTO cards (category, title, answer) VALUES(?, ?, ?)", -1,
|
||||||
&stmt, nullptr);
|
&stmt, nullptr);
|
||||||
if (rc == SQLITE_OK)
|
if (rc == SQLITE_OK)
|
||||||
{
|
{
|
||||||
sqlite3_bind_int (stmt, 0, c.category);
|
sqlite3_bind_int (stmt, 1, category);
|
||||||
sqlite3_bind_text (stmt, 1, c.task, -1, SQLITE_STATIC);
|
sqlite3_bind_text (stmt, 2, title, -1, SQLITE_STATIC);
|
||||||
sqlite3_bind_text (stmt, 2, c.solution, -1, SQLITE_STATIC);
|
sqlite3_bind_text (stmt, 3, answer, -1, SQLITE_STATIC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
sqlite3_step (stmt);
|
rc = sqlite3_step (stmt);
|
||||||
|
if (rc != SQLITE_DONE)
|
||||||
|
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
||||||
sqlite3_finalize (stmt);
|
sqlite3_finalize (stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,8 +170,11 @@ database_load_cards (sqlite3 *db, const int category)
|
|||||||
GArray *cards = g_array_new (TRUE, FALSE, sizeof (card));
|
GArray *cards = g_array_new (TRUE, FALSE, sizeof (card));
|
||||||
|
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_stmt *stmt;
|
||||||
int rc = sqlite3_prepare_v2 (db, "SELECT * FROM cards WHERE category = ?",
|
int rc
|
||||||
-1, &stmt, nullptr);
|
= sqlite3_prepare_v2 (db,
|
||||||
|
"SELECT * FROM cards WHERE category = ? AND "
|
||||||
|
"next_time <= unixepoch() ORDER BY next_time ASC",
|
||||||
|
-1, &stmt, nullptr);
|
||||||
if (rc == SQLITE_OK)
|
if (rc == SQLITE_OK)
|
||||||
sqlite3_bind_int (stmt, 1, category);
|
sqlite3_bind_int (stmt, 1, category);
|
||||||
else
|
else
|
||||||
@@ -174,8 +185,10 @@ database_load_cards (sqlite3 *db, const int category)
|
|||||||
card c;
|
card c;
|
||||||
c.id = sqlite3_column_int (stmt, 0);
|
c.id = sqlite3_column_int (stmt, 0);
|
||||||
c.category = sqlite3_column_int (stmt, 1);
|
c.category = sqlite3_column_int (stmt, 1);
|
||||||
c.task = strdup ((char *)sqlite3_column_text (stmt, 2));
|
c.title = strdup ((char *)sqlite3_column_text (stmt, 2));
|
||||||
c.solution = strdup ((char *)sqlite3_column_text (stmt, 3));
|
c.answer = strdup ((char *)sqlite3_column_text (stmt, 3));
|
||||||
|
c.next_time
|
||||||
|
= g_date_time_new_from_unix_utc (sqlite3_column_int64 (stmt, 4));
|
||||||
|
|
||||||
g_array_append_val (cards, c);
|
g_array_append_val (cards, c);
|
||||||
}
|
}
|
||||||
@@ -184,6 +197,26 @@ database_load_cards (sqlite3 *db, const int category)
|
|||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
database_schedule_card (sqlite3 *db, const int id, GDateTime *next_time)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
int rc = sqlite3_prepare_v2 (
|
||||||
|
db, "UPDATE cards SET next_time = ? WHERE id = ?", -1, &stmt, nullptr);
|
||||||
|
if (rc == SQLITE_OK)
|
||||||
|
{
|
||||||
|
sqlite3_bind_int64 (stmt, 1, g_date_time_to_unix (next_time));
|
||||||
|
sqlite3_bind_int (stmt, 2, id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
|
rc = sqlite3_step (stmt);
|
||||||
|
if (rc != SQLITE_DONE)
|
||||||
|
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
database_delete_card (sqlite3 *db, const int id)
|
database_delete_card (sqlite3 *db, const int id)
|
||||||
{
|
{
|
||||||
@@ -195,6 +228,8 @@ database_delete_card (sqlite3 *db, const int id)
|
|||||||
else
|
else
|
||||||
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
sqlite3_step (stmt);
|
rc = sqlite3_step (stmt);
|
||||||
|
if (rc != SQLITE_DONE)
|
||||||
|
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
||||||
sqlite3_finalize (stmt);
|
sqlite3_finalize (stmt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ typedef struct card
|
|||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
int category;
|
int category;
|
||||||
char *task;
|
char *title;
|
||||||
char *solution;
|
char *answer;
|
||||||
|
GDateTime *next_time;
|
||||||
} card;
|
} card;
|
||||||
|
|
||||||
sqlite3 *database_connect (const char *path);
|
sqlite3 *database_connect (const char *path);
|
||||||
@@ -30,9 +31,12 @@ GArray *database_load_categories (sqlite3 *db);
|
|||||||
|
|
||||||
void database_delete_category (sqlite3 *db, int id);
|
void database_delete_category (sqlite3 *db, int id);
|
||||||
|
|
||||||
void database_save_card (sqlite3 *db, card c);
|
void database_save_card (sqlite3 *db, int category, const char *title,
|
||||||
|
const char *answer);
|
||||||
|
|
||||||
GArray *database_load_cards (sqlite3 *db, int category);
|
GArray *database_load_cards (sqlite3 *db, int category);
|
||||||
|
|
||||||
|
void database_schedule_card (sqlite3 *db, int id, GDateTime *next_time);
|
||||||
|
|
||||||
void database_delete_card (sqlite3 *db, int id);
|
void database_delete_card (sqlite3 *db, int id);
|
||||||
#endif /* DATABASE_H */
|
#endif /* DATABASE_H */
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
#include <adwaita.h>
|
#include "flashcardsapp.h"
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "flashcardsapp.h"
|
|
||||||
#include "flashcardsappwin.h"
|
#include "flashcardsappwin.h"
|
||||||
|
|
||||||
struct _FlashcardsApp
|
struct _FlashcardsApp
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
#include <adwaita.h>
|
#include "flashcardsappwin.h"
|
||||||
#include <gtk/gtk.h>
|
|
||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
#include "create-category.h"
|
|
||||||
#include "flashcardsapp.h"
|
|
||||||
#include "flashcardsappwin.h"
|
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
|
#include "create-card.h"
|
||||||
|
#include "create-category.h"
|
||||||
|
|
||||||
struct _FlashcardsAppWindow
|
struct _FlashcardsAppWindow
|
||||||
{
|
{
|
||||||
AdwApplicationWindow parent;
|
AdwApplicationWindow parent;
|
||||||
@@ -16,10 +14,15 @@ struct _FlashcardsAppWindow
|
|||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
GArray *categories;
|
GArray *categories;
|
||||||
GQueue *cards;
|
GQueue *cards;
|
||||||
|
category current_category;
|
||||||
card *current_card;
|
card *current_card;
|
||||||
|
|
||||||
AdwWindowTitle *title;
|
AdwWindowTitle *title;
|
||||||
|
|
||||||
|
GtkButton *add_card_button;
|
||||||
|
GtkButton *delete_card_button;
|
||||||
|
GtkButton *delete_category_button;
|
||||||
|
|
||||||
AdwNavigationSplitView *split_view;
|
AdwNavigationSplitView *split_view;
|
||||||
AdwNavigationPage *sidebar;
|
AdwNavigationPage *sidebar;
|
||||||
AdwNavigationPage *content;
|
AdwNavigationPage *content;
|
||||||
@@ -31,6 +34,8 @@ struct _FlashcardsAppWindow
|
|||||||
|
|
||||||
GtkListBox *topics;
|
GtkListBox *topics;
|
||||||
|
|
||||||
|
GtkLabel *card_title;
|
||||||
|
|
||||||
bool started;
|
bool started;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,6 +65,18 @@ load_categories (FlashcardsAppWindow *win)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
next_card (FlashcardsAppWindow *win)
|
||||||
|
{
|
||||||
|
if (win->cards->length <= 0)
|
||||||
|
{
|
||||||
|
adw_view_stack_set_visible_child (win->main_view, win->placeholder_card);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
win->current_card = g_queue_pop_head (win->cards);
|
||||||
|
gtk_label_set_label (win->card_title, win->current_card->title);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_cards (FlashcardsAppWindow *win, category c)
|
load_cards (FlashcardsAppWindow *win, category c)
|
||||||
{
|
{
|
||||||
@@ -73,13 +90,7 @@ load_cards (FlashcardsAppWindow *win, category c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf ("Flashcards: %d\n", win->cards->length);
|
printf ("Flashcards: %d\n", win->cards->length);
|
||||||
if (win->cards->length <= 0)
|
next_card (win);
|
||||||
{
|
|
||||||
adw_view_stack_set_visible_child (win->main_view, win->placeholder_card);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
win->current_card = g_queue_pop_head (win->cards);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -91,14 +102,19 @@ on_select_category (__attribute__ ((unused)) GtkListBox *box,
|
|||||||
adw_navigation_split_view_set_show_content (
|
adw_navigation_split_view_set_show_content (
|
||||||
ADW_NAVIGATION_SPLIT_VIEW (win->split_view), TRUE);
|
ADW_NAVIGATION_SPLIT_VIEW (win->split_view), TRUE);
|
||||||
|
|
||||||
int id = gtk_list_box_row_get_index (row);
|
const int id = gtk_list_box_row_get_index (row);
|
||||||
|
|
||||||
category c = g_array_index (win->categories, category, id);
|
category c = g_array_index (win->categories, category, id);
|
||||||
printf ("%d: %d\n", id, c.id);
|
|
||||||
|
win->current_category = c;
|
||||||
|
|
||||||
adw_window_title_set_subtitle (ADW_WINDOW_TITLE (win->title), c.name);
|
adw_window_title_set_subtitle (ADW_WINDOW_TITLE (win->title), c.name);
|
||||||
|
|
||||||
adw_view_stack_set_visible_child (win->main_view, win->flashcard);
|
adw_view_stack_set_visible_child (win->main_view, win->flashcard);
|
||||||
|
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (win->add_card_button), TRUE);
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (win->delete_card_button), TRUE);
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (win->delete_category_button), TRUE);
|
||||||
|
|
||||||
load_cards (win, c);
|
load_cards (win, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,56 +131,84 @@ on_delete_category (__attribute__ ((unused)) GtkButton *self,
|
|||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
FlashcardsAppWindow *win = user_data;
|
FlashcardsAppWindow *win = user_data;
|
||||||
database_delete_category (win->db, 1);
|
database_delete_category (win->db, win->current_category.id);
|
||||||
|
|
||||||
printf ("Delete category\n");
|
|
||||||
gtk_list_box_unselect_all (win->topics);
|
gtk_list_box_unselect_all (win->topics);
|
||||||
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
||||||
|
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (win->add_card_button), FALSE);
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (win->delete_card_button), FALSE);
|
||||||
|
gtk_widget_set_visible (GTK_WIDGET (win->delete_category_button), FALSE);
|
||||||
|
|
||||||
|
load_categories (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_add_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
on_add_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
{
|
{
|
||||||
/*FlashcardsAppWindow *win = user_data;
|
FlashcardsAppWindow *win = user_data;
|
||||||
FlashcardsCreateCardDialog *dialog = flashcards_create_card_dialog_new(win);
|
FlashcardsCreateCardDialog *dialog = flashcards_create_card_dialog_new (win);
|
||||||
adw_dialog_present(ADW_DIALOG(dialog), GTK_WIDGET(win));*/
|
adw_dialog_present (ADW_DIALOG (dialog), GTK_WIDGET (win));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_delete_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
on_delete_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
{
|
{
|
||||||
/*FlashcardsAppWindow *win = user_data;
|
FlashcardsAppWindow *win = user_data;
|
||||||
database_delete_card(win->db, 1);
|
database_delete_card (win->db, win->current_card->id);
|
||||||
printf("Delete card\n");*/
|
next_card (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_answer_easy (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
on_answer_easy (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
{
|
{
|
||||||
FlashcardsAppWindow *win = user_data;
|
FlashcardsAppWindow *win = user_data;
|
||||||
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
card *c = win->current_card;
|
||||||
|
database_schedule_card (
|
||||||
|
win->db, c->id, g_date_time_add_hours (g_date_time_new_now_utc (), 24));
|
||||||
|
next_card (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_answer_medium (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
on_answer_medium (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
{
|
{
|
||||||
FlashcardsAppWindow *win = user_data;
|
FlashcardsAppWindow *win = user_data;
|
||||||
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
card *c = win->current_card;
|
||||||
|
database_schedule_card (
|
||||||
|
win->db, c->id, g_date_time_add_hours (g_date_time_new_now_utc (), 12));
|
||||||
|
next_card (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_answer_hard (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
on_answer_hard (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
{
|
{
|
||||||
FlashcardsAppWindow *win = user_data;
|
FlashcardsAppWindow *win = user_data;
|
||||||
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
card *c = win->current_card;
|
||||||
|
database_schedule_card (
|
||||||
|
win->db, c->id, g_date_time_add_hours (g_date_time_new_now_utc (), 6));
|
||||||
|
next_card (win);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_flip_card (__attribute__ ((unused)) GtkWidget *self, gpointer user_data)
|
||||||
|
{
|
||||||
|
FlashcardsAppWindow *win = user_data;
|
||||||
|
gtk_label_set_text (GTK_LABEL (win->card_title), win->current_card->answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
flashcards_app_window_test (FlashcardsAppWindow *win, const gchar *test)
|
flashcards_app_window_add_card (FlashcardsAppWindow *win, const gchar *title,
|
||||||
|
const gchar *answer)
|
||||||
{
|
{
|
||||||
GtkWidget *child;
|
database_save_card (win->db, win->current_category.id, title, answer);
|
||||||
|
printf ("Added card\n");
|
||||||
|
}
|
||||||
|
|
||||||
database_save_category (win->db, test);
|
void
|
||||||
|
flashcards_app_window_add_category (FlashcardsAppWindow *win,
|
||||||
|
const gchar *title)
|
||||||
|
{
|
||||||
|
database_save_category (win->db, title);
|
||||||
load_categories (win);
|
load_categories (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +238,13 @@ flashcards_app_window_class_init (FlashcardsAppWindowClass *class)
|
|||||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
FlashcardsAppWindow, title);
|
FlashcardsAppWindow, title);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, add_card_button);
|
||||||
|
gtk_widget_class_bind_template_child (
|
||||||
|
GTK_WIDGET_CLASS (class), FlashcardsAppWindow, delete_card_button);
|
||||||
|
gtk_widget_class_bind_template_child (
|
||||||
|
GTK_WIDGET_CLASS (class), FlashcardsAppWindow, delete_category_button);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
FlashcardsAppWindow, split_view);
|
FlashcardsAppWindow, split_view);
|
||||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
@@ -213,6 +264,9 @@ flashcards_app_window_class_init (FlashcardsAppWindowClass *class)
|
|||||||
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
FlashcardsAppWindow, topics);
|
FlashcardsAppWindow, topics);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, card_title);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
on_flashcards_app_window_show);
|
on_flashcards_app_window_show);
|
||||||
|
|
||||||
@@ -233,6 +287,9 @@ flashcards_app_window_class_init (FlashcardsAppWindowClass *class)
|
|||||||
on_answer_medium);
|
on_answer_medium);
|
||||||
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
on_answer_hard);
|
on_answer_hard);
|
||||||
|
|
||||||
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
|
on_flip_card);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashcardsAppWindow *
|
FlashcardsAppWindow *
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ G_DECLARE_FINAL_TYPE (FlashcardsAppWindow, flashcards_app_window, FLASHCARDS,
|
|||||||
APP_WINDOW, AdwApplicationWindow)
|
APP_WINDOW, AdwApplicationWindow)
|
||||||
|
|
||||||
FlashcardsAppWindow *flashcards_app_window_new (FlashcardsApp *app);
|
FlashcardsAppWindow *flashcards_app_window_new (FlashcardsApp *app);
|
||||||
void flashcards_app_window_test (FlashcardsAppWindow *win, const gchar *test);
|
void flashcards_app_window_add_category (FlashcardsAppWindow *win,
|
||||||
|
const gchar *test);
|
||||||
|
void flashcards_app_window_add_card (FlashcardsAppWindow *win,
|
||||||
|
const gchar *title, const gchar *answer);
|
||||||
|
|
||||||
#endif /* __FLASHCARDSAPPWIN_H */
|
#endif /* __FLASHCARDSAPPWIN_H */
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
sourcefiles = files('main.c',
|
sourcefiles = files('main.c',
|
||||||
'flashcardsapp.c',
|
'flashcardsapp.c',
|
||||||
'flashcardsappwin.c',
|
'flashcardsappwin.c',
|
||||||
'create-category.c',
|
'create-category.c',
|
||||||
'database.c'
|
'create-card.c',
|
||||||
|
'database.c'
|
||||||
)
|
)
|
||||||
Reference in New Issue
Block a user