mirror of
https://gitlab.cvh-server.de/skrause/flashcards.git
synced 2025-12-12 06:41:38 +01:00
push local changes
This commit is contained in:
136
.clang-format
136
.clang-format
@@ -1,137 +1 @@
|
|||||||
---
|
|
||||||
Language: Cpp
|
|
||||||
BasedOnStyle: GNU
|
BasedOnStyle: GNU
|
||||||
AccessModifierOffset: -4
|
|
||||||
AlignConsecutiveAssignments: false
|
|
||||||
AlignConsecutiveBitFields:
|
|
||||||
Enabled: false
|
|
||||||
AcrossEmptyLines: false
|
|
||||||
AcrossComments: false
|
|
||||||
AlignCompound: false
|
|
||||||
AlignFunctionPointers: false
|
|
||||||
PadOperators: false
|
|
||||||
AlignConsecutiveDeclarations: false
|
|
||||||
AlignConsecutiveMacros:
|
|
||||||
Enabled: false
|
|
||||||
AcrossEmptyLines: false
|
|
||||||
AcrossComments: false
|
|
||||||
AlignCompound: false
|
|
||||||
AlignFunctionPointers: false
|
|
||||||
PadOperators: false
|
|
||||||
AlignConsecutiveShortCaseStatements:
|
|
||||||
Enabled: false
|
|
||||||
AcrossEmptyLines: false
|
|
||||||
AcrossComments: false
|
|
||||||
AlignCaseArrows: false
|
|
||||||
AlignCaseColons: false
|
|
||||||
AlignConsecutiveTableGenBreakingDAGArgColons:
|
|
||||||
Enabled: false
|
|
||||||
AcrossEmptyLines: false
|
|
||||||
AcrossComments: false
|
|
||||||
AlignCompound: false
|
|
||||||
AlignFunctionPointers: false
|
|
||||||
PadOperators: false
|
|
||||||
AlignConsecutiveTableGenCondOperatorColons:
|
|
||||||
Enabled: false
|
|
||||||
AcrossEmptyLines: false
|
|
||||||
AcrossComments: false
|
|
||||||
AlignCompound: false
|
|
||||||
AlignFunctionPointers: false
|
|
||||||
PadOperators: false
|
|
||||||
AlignConsecutiveTableGenDefinitionColons:
|
|
||||||
Enabled: false
|
|
||||||
AcrossEmptyLines: false
|
|
||||||
AcrossComments: false
|
|
||||||
AlignCompound: false
|
|
||||||
AlignFunctionPointers: false
|
|
||||||
PadOperators: false
|
|
||||||
AlignOperands: true
|
|
||||||
AlignTrailingComments: false
|
|
||||||
AllowShortCaseExpressionOnASingleLine: true
|
|
||||||
AllowShortCompoundRequirementOnASingleLine: true
|
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
|
||||||
AlwaysBreakAfterReturnType: None
|
|
||||||
AlwaysBreakTemplateDeclarations: Yes
|
|
||||||
BraceWrapping:
|
|
||||||
AfterCaseLabel: false
|
|
||||||
AfterClass: false
|
|
||||||
AfterControlStatement: false
|
|
||||||
AfterEnum: false
|
|
||||||
AfterFunction: false
|
|
||||||
AfterNamespace: false
|
|
||||||
AfterStruct: false
|
|
||||||
AfterUnion: false
|
|
||||||
AfterExternBlock: false
|
|
||||||
BeforeCatch: false
|
|
||||||
BeforeElse: false
|
|
||||||
BeforeLambdaBody: false
|
|
||||||
BeforeWhile: false
|
|
||||||
SplitEmptyFunction: true
|
|
||||||
SplitEmptyRecord: true
|
|
||||||
SplitEmptyNamespace: true
|
|
||||||
BreakAdjacentStringLiterals: true
|
|
||||||
BreakAfterAttributes: Leave
|
|
||||||
BreakAfterReturnType: None
|
|
||||||
BreakBeforeBinaryOperators: None
|
|
||||||
BreakBeforeBraces: Custom
|
|
||||||
BreakConstructorInitializers: AfterColon
|
|
||||||
BreakConstructorInitializersBeforeComma: false
|
|
||||||
BreakFunctionDefinitionParameters: false
|
|
||||||
BreakTemplateDeclarations: MultiLine
|
|
||||||
ColumnLimit: 120
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
|
||||||
ContinuationIndentWidth: 8
|
|
||||||
Cpp11BracedListStyle: true
|
|
||||||
FixNamespaceComments: true
|
|
||||||
IncludeCategories:
|
|
||||||
- Regex: '^<.*'
|
|
||||||
Priority: 1
|
|
||||||
- Regex: '^".*'
|
|
||||||
Priority: 2
|
|
||||||
- Regex: '.*'
|
|
||||||
Priority: 3
|
|
||||||
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
|
||||||
IndentCaseLabels: true
|
|
||||||
IndentWidth: 4
|
|
||||||
InsertNewlineAtEOF: true
|
|
||||||
KeepEmptyLines:
|
|
||||||
AtEndOfFile: false
|
|
||||||
AtStartOfBlock: true
|
|
||||||
AtStartOfFile: true
|
|
||||||
MacroBlockBegin: ''
|
|
||||||
MacroBlockEnd: ''
|
|
||||||
MainIncludeChar: Quote
|
|
||||||
MaxEmptyLinesToKeep: 2
|
|
||||||
NamespaceIndentation: All
|
|
||||||
PenaltyBreakScopeResolution: 500
|
|
||||||
SkipMacroDefinitionBody: false
|
|
||||||
SpaceAfterCStyleCast: true
|
|
||||||
SpaceAfterTemplateKeyword: false
|
|
||||||
SpaceBeforeParens: ControlStatements
|
|
||||||
SpaceBeforeParensOptions:
|
|
||||||
AfterControlStatements: true
|
|
||||||
AfterForeachMacros: true
|
|
||||||
AfterFunctionDefinitionName: false
|
|
||||||
AfterFunctionDeclarationName: false
|
|
||||||
AfterIfMacros: true
|
|
||||||
AfterOverloadedOperator: false
|
|
||||||
AfterPlacementOperator: true
|
|
||||||
AfterRequiresInClause: false
|
|
||||||
AfterRequiresInExpression: false
|
|
||||||
BeforeNonEmptyParentheses: false
|
|
||||||
SpaceBeforeRangeBasedForLoopColon: false
|
|
||||||
SpaceInEmptyParentheses: false
|
|
||||||
SpacesInAngles: false
|
|
||||||
SpacesInConditionalStatement: false
|
|
||||||
SpacesInCStyleCastParentheses: false
|
|
||||||
SpacesInParensOptions:
|
|
||||||
ExceptDoubleParentheses: false
|
|
||||||
InCStyleCasts: false
|
|
||||||
InConditionalStatements: false
|
|
||||||
InEmptyParentheses: false
|
|
||||||
Other: false
|
|
||||||
SpacesInParentheses: false
|
|
||||||
Standard: Latest
|
|
||||||
TableGenBreakInsideDAGArg: DontBreak
|
|
||||||
TabWidth: 4
|
|
||||||
...
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#import "template.typ": *
|
#import "template.typ": project
|
||||||
|
|
||||||
#show: project.with(
|
#show: project.with(
|
||||||
title: "Karteikarten-Anwendung in C mit GTK4 und Libadwaita",
|
title: "Karteikarten-Anwendung in C mit GTK4 und Libadwaita",
|
||||||
@@ -6,6 +6,9 @@
|
|||||||
authors: (
|
authors: (
|
||||||
"Sophie Krause",
|
"Sophie Krause",
|
||||||
),
|
),
|
||||||
|
profs: (
|
||||||
|
"Prof. Dr. Gerwinski",
|
||||||
|
),
|
||||||
logo: "BO_Logo.svg"
|
logo: "BO_Logo.svg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#import "@preview/hydra:0.6.0": hydra
|
#import "@preview/hydra:0.6.0": hydra
|
||||||
|
|
||||||
#let project(title: "", subtitle: "", authors: (), logo: none, body) = {
|
#let project(title: "", subtitle: "", authors: (), profs: (), logo: none, body) = {
|
||||||
// Basic properties
|
// Basic properties
|
||||||
set document(author: authors, title: title)
|
set document(author: authors, title: title)
|
||||||
set text(lang: "de")
|
set text(lang: "de")
|
||||||
@@ -22,14 +22,21 @@
|
|||||||
|
|
||||||
// Subtitle
|
// Subtitle
|
||||||
text(2em, weight: 400, subtitle)
|
text(2em, weight: 400, subtitle)
|
||||||
|
v(1fr)
|
||||||
|
|
||||||
|
set align(left)
|
||||||
|
|
||||||
// Author
|
// Author
|
||||||
grid(
|
grid(
|
||||||
|
gutter: 1em,
|
||||||
..authors,
|
..authors,
|
||||||
)
|
)
|
||||||
|
|
||||||
v(1fr)
|
// Profs
|
||||||
pagebreak()
|
grid(
|
||||||
|
gutter: 1em,
|
||||||
|
..profs,
|
||||||
|
)
|
||||||
|
|
||||||
// Table of contents
|
// Table of contents
|
||||||
set align(left)
|
set align(left)
|
||||||
|
|||||||
@@ -5,40 +5,55 @@
|
|||||||
|
|
||||||
#include "create-category.h"
|
#include "create-category.h"
|
||||||
|
|
||||||
struct _FlashcardsCreateCategoryDialog {
|
struct _FlashcardsCreateCategoryDialog
|
||||||
AdwAlertDialog parent;
|
{
|
||||||
|
AdwAlertDialog parent;
|
||||||
|
|
||||||
GtkEditable *entry;
|
GtkEditable *entry;
|
||||||
|
|
||||||
FlashcardsAppWindow *win;
|
FlashcardsAppWindow *win;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(FlashcardsCreateCategoryDialog, flashcards_create_category_dialog, ADW_TYPE_ALERT_DIALOG);
|
G_DEFINE_TYPE (FlashcardsCreateCategoryDialog,
|
||||||
|
flashcards_create_category_dialog, ADW_TYPE_ALERT_DIALOG);
|
||||||
|
|
||||||
static void flashcards_create_category_dialog_init(FlashcardsCreateCategoryDialog *self) {
|
static void
|
||||||
gtk_widget_init_template(GTK_WIDGET(self));
|
flashcards_create_category_dialog_init (FlashcardsCreateCategoryDialog *self)
|
||||||
|
{
|
||||||
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_response(__attribute__((unused)) AdwAlertDialog *dialog, gchar *response, gpointer user_data) {
|
static void
|
||||||
FlashcardsCreateCategoryDialog *self = user_data;
|
on_response (__attribute__ ((unused)) AdwAlertDialog *dialog, gchar *response,
|
||||||
|
gpointer 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_test (self->win, category);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flashcards_create_category_dialog_class_init(FlashcardsCreateCategoryDialogClass *klass) {
|
static void
|
||||||
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(klass), "/li/sopht/flashcards/create-category.ui");
|
flashcards_create_category_dialog_class_init (
|
||||||
|
FlashcardsCreateCategoryDialogClass *klass)
|
||||||
|
{
|
||||||
|
gtk_widget_class_set_template_from_resource (
|
||||||
|
GTK_WIDGET_CLASS (klass), "/li/sopht/flashcards/create-category.ui");
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(klass), FlashcardsCreateCategoryDialog, entry);
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (klass),
|
||||||
|
FlashcardsCreateCategoryDialog, entry);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(klass), on_response);
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (klass),
|
||||||
|
on_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashcardsCreateCategoryDialog *flashcards_create_category_dialog_new(FlashcardsAppWindow *win) {
|
FlashcardsCreateCategoryDialog *
|
||||||
FlashcardsCreateCategoryDialog *self = g_object_new(FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE, nullptr);
|
flashcards_create_category_dialog_new (FlashcardsAppWindow *win)
|
||||||
self->win = win;
|
{
|
||||||
return self;
|
FlashcardsCreateCategoryDialog *self
|
||||||
|
= g_object_new (FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE, nullptr);
|
||||||
|
self->win = win;
|
||||||
|
return self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
#ifndef __CREATECATEGORYDIALOG_H
|
#ifndef __CREATECATEGORYDIALOG_H
|
||||||
#define __CREATECATEGORYDIALOG_H
|
#define __CREATECATEGORYDIALOG_H
|
||||||
|
|
||||||
#include <adwaita.h>
|
|
||||||
#include <gtk/gtk.h>
|
|
||||||
#include "flashcardsapp.h"
|
#include "flashcardsapp.h"
|
||||||
#include "flashcardsappwin.h"
|
#include "flashcardsappwin.h"
|
||||||
|
#include <adwaita.h>
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#define FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE (flashcards_create_category_dialog_get_type())
|
#define FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE \
|
||||||
G_DECLARE_FINAL_TYPE(FlashcardsCreateCategoryDialog, flashcards_create_category_dialog, FLASHCARDS,
|
(flashcards_create_category_dialog_get_type ())
|
||||||
CREATE_CATEGORY_DIALOG, AdwAlertDialog)
|
G_DECLARE_FINAL_TYPE (FlashcardsCreateCategoryDialog,
|
||||||
|
flashcards_create_category_dialog, FLASHCARDS,
|
||||||
|
CREATE_CATEGORY_DIALOG, AdwAlertDialog)
|
||||||
|
|
||||||
FlashcardsCreateCategoryDialog *flashcards_create_category_dialog_new(FlashcardsAppWindow *win);
|
FlashcardsCreateCategoryDialog *
|
||||||
|
flashcards_create_category_dialog_new (FlashcardsAppWindow *win);
|
||||||
|
|
||||||
#endif /* __CREATECATEGORYDIALOG_H */
|
#endif /* __CREATECATEGORYDIALOG_H */
|
||||||
|
|||||||
312
src/database.c
312
src/database.c
@@ -2,183 +2,199 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
sqlite3 *database_connect(const char *path) {
|
sqlite3 *
|
||||||
sqlite3 *db;
|
database_connect (const char *path)
|
||||||
|
{
|
||||||
|
sqlite3 *db;
|
||||||
|
|
||||||
gchar *file = g_build_filename(path, "cards.db", NULL);
|
gchar *file = g_build_filename (path, "cards.db", NULL);
|
||||||
int rc = sqlite3_open(file, &db);
|
int rc = sqlite3_open (file, &db);
|
||||||
|
|
||||||
if (rc) {
|
if (rc)
|
||||||
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
{
|
||||||
return nullptr;
|
fprintf (stderr, "Can't open database: %s\n", sqlite3_errmsg (db));
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
fprintf(stdout, "Opened database successfully\n");
|
fprintf (stdout, "Opened database successfully\n");
|
||||||
g_free(file);
|
g_free (file);
|
||||||
|
|
||||||
database_create_tables(db);
|
database_create_tables (db);
|
||||||
|
|
||||||
return db;
|
return db;
|
||||||
}
|
}
|
||||||
|
|
||||||
void database_close(sqlite3 *db) { sqlite3_close(db); }
|
void
|
||||||
|
database_close (sqlite3 *db)
|
||||||
void database_create_tables(sqlite3 *db) {
|
{
|
||||||
sqlite3_stmt *stmt;
|
sqlite3_close (db);
|
||||||
|
|
||||||
const char *sql = "CREATE TABLE IF NOT EXISTS `cards` ("
|
|
||||||
"`id` INTEGER NOT NULL,"
|
|
||||||
"`category` INTEGER NOT NULL,"
|
|
||||||
"`task` TEXT NOT NULL,"
|
|
||||||
"`solution` TEXT NOT NULL,"
|
|
||||||
"PRIMARY KEY(`id` AUTOINCREMENT)"
|
|
||||||
")";
|
|
||||||
|
|
||||||
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
|
|
||||||
|
|
||||||
if (rc != SQLITE_OK) {
|
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_step(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
sql = "CREATE TABLE IF NOT EXISTS `categories` ("
|
|
||||||
"`id` INTEGER NOT NULL,"
|
|
||||||
"`name` TEXT NOT NULL,"
|
|
||||||
"PRIMARY KEY(`id` AUTOINCREMENT)"
|
|
||||||
")";
|
|
||||||
|
|
||||||
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
|
|
||||||
|
|
||||||
if (rc != SQLITE_OK) {
|
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_step(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void database_save_category(sqlite3 *db, const char *c) {
|
void
|
||||||
sqlite3_stmt *stmt;
|
database_create_tables (sqlite3 *db)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
fprintf(stdout, "%s\n", c);
|
const char *sql = "CREATE TABLE IF NOT EXISTS `cards` ("
|
||||||
int rc = sqlite3_prepare_v2(db, "INSERT INTO categories (name) VALUES(?)", -1, &stmt, nullptr);
|
"`id` INTEGER NOT NULL,"
|
||||||
|
"`category` INTEGER NOT NULL,"
|
||||||
|
"`task` TEXT NOT NULL,"
|
||||||
|
"`solution` TEXT NOT NULL,"
|
||||||
|
"PRIMARY KEY(`id` AUTOINCREMENT)"
|
||||||
|
")";
|
||||||
|
|
||||||
if (rc == SQLITE_OK) {
|
int rc = sqlite3_prepare_v2 (db, sql, -1, &stmt, nullptr);
|
||||||
sqlite3_bind_text(stmt, 1, c, -1, SQLITE_STATIC);
|
if (rc != SQLITE_OK)
|
||||||
} else {
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
printf("Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = sqlite3_step(stmt);
|
sqlite3_step (stmt);
|
||||||
if (rc != SQLITE_OK) {
|
sqlite3_finalize (stmt);
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
|
||||||
}
|
sql = "CREATE TABLE IF NOT EXISTS `categories` ("
|
||||||
sqlite3_finalize(stmt);
|
"`id` INTEGER NOT NULL,"
|
||||||
|
"`name` TEXT NOT NULL,"
|
||||||
|
"PRIMARY KEY(`id` AUTOINCREMENT)"
|
||||||
|
")";
|
||||||
|
|
||||||
|
rc = sqlite3_prepare_v2 (db, sql, -1, &stmt, nullptr);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
|
sqlite3_step (stmt);
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
GArray *database_load_categories(sqlite3 *db) {
|
void
|
||||||
sqlite3_stmt *stmt;
|
database_save_category (sqlite3 *db, const char *c)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
GArray *categories = g_array_new(TRUE, FALSE, sizeof(category));
|
fprintf (stdout, "%s\n", c);
|
||||||
int rc = sqlite3_prepare_v2(db, "SELECT * FROM categories", -1, &stmt, nullptr);
|
int rc = sqlite3_prepare_v2 (db, "INSERT INTO categories (name) VALUES(?)",
|
||||||
|
-1, &stmt, nullptr);
|
||||||
|
if (rc == SQLITE_OK)
|
||||||
|
sqlite3_bind_text (stmt, 1, c, -1, SQLITE_STATIC);
|
||||||
|
else
|
||||||
|
printf ("Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
if (rc != SQLITE_OK) {
|
rc = sqlite3_step (stmt);
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
if (rc != SQLITE_OK)
|
||||||
}
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
|
||||||
category c;
|
|
||||||
c.id = sqlite3_column_int(stmt, 0);
|
|
||||||
c.name = strdup((char *) sqlite3_column_text(stmt, 1));
|
|
||||||
g_array_append_val(categories, c);
|
|
||||||
}
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
return categories;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void database_delete_category(sqlite3 *db, const int id) {
|
GArray *
|
||||||
// delete all cards in the category
|
database_load_categories (sqlite3 *db)
|
||||||
sqlite3_stmt *stmt;
|
{
|
||||||
int rc = sqlite3_prepare_v2(db, "DELETE FROM cards WHERE category = ?", -1, &stmt, nullptr);
|
sqlite3_stmt *stmt;
|
||||||
if (rc == SQLITE_OK) {
|
|
||||||
sqlite3_bind_int(stmt, 1, id);
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
|
||||||
}
|
|
||||||
rc = sqlite3_step(stmt);
|
|
||||||
if (rc != SQLITE_OK) {
|
|
||||||
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
|
|
||||||
}
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
// delete the category
|
GArray *categories = g_array_new (TRUE, FALSE, sizeof (category));
|
||||||
rc = sqlite3_prepare_v2(db, "DELETE FROM categories WHERE id = ?", -1, &stmt, nullptr);
|
int rc = sqlite3_prepare_v2 (db, "SELECT * FROM categories", -1, &stmt,
|
||||||
if (rc == SQLITE_OK) {
|
nullptr);
|
||||||
sqlite3_bind_int(stmt, 1, id);
|
|
||||||
} else {
|
if (rc != SQLITE_OK)
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
|
while (sqlite3_step (stmt) == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
category c;
|
||||||
|
c.id = sqlite3_column_int (stmt, 0);
|
||||||
|
c.name = strdup ((char *)sqlite3_column_text (stmt, 1));
|
||||||
|
g_array_append_val (categories, c);
|
||||||
}
|
}
|
||||||
rc = sqlite3_step(stmt);
|
sqlite3_finalize (stmt);
|
||||||
if (rc != SQLITE_OK) {
|
|
||||||
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
|
return categories;
|
||||||
}
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void database_save_card(sqlite3 *db, card c) {
|
void
|
||||||
sqlite3_stmt *stmt;
|
database_delete_category (sqlite3 *db, const int id)
|
||||||
|
{
|
||||||
|
// delete all cards in the category
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
int rc = sqlite3_prepare_v2 (db, "DELETE FROM cards WHERE category = ?", -1,
|
||||||
|
&stmt, nullptr);
|
||||||
|
if (rc == SQLITE_OK)
|
||||||
|
sqlite3_bind_int (stmt, 1, id);
|
||||||
|
else
|
||||||
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
rc = sqlite3_step (stmt);
|
||||||
|
if (rc != SQLITE_OK)
|
||||||
|
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
|
|
||||||
fprintf(stdout, "%s: %s\n", c.task, c.solution);
|
// delete the category
|
||||||
int rc = sqlite3_prepare_v2(db, "INSERT INTO cards VALUES(?, ?, ?)", -1, &stmt, nullptr);
|
rc = sqlite3_prepare_v2 (db, "DELETE FROM categories WHERE id = ?", -1,
|
||||||
|
&stmt, nullptr);
|
||||||
if (rc == SQLITE_OK) {
|
if (rc == SQLITE_OK)
|
||||||
sqlite3_bind_int(stmt, 0, c.category);
|
sqlite3_bind_int (stmt, 1, id);
|
||||||
sqlite3_bind_text(stmt, 1, c.task, -1, SQLITE_STATIC);
|
else
|
||||||
sqlite3_bind_text(stmt, 2, c.solution, -1, SQLITE_STATIC);
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
} else {
|
rc = sqlite3_step (stmt);
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
if (rc != SQLITE_OK)
|
||||||
}
|
fprintf (stderr, "Execution failed: %s\n", sqlite3_errmsg (db));
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
sqlite3_step(stmt);
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GArray *database_load_cards(sqlite3 *db, int category) {
|
void
|
||||||
GArray *cards = g_array_new(TRUE, FALSE, sizeof(card));
|
database_save_card (sqlite3 *db, const card c)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
|
||||||
sqlite3_stmt *stmt;
|
fprintf (stdout, "%s: %s\n", c.task, c.solution);
|
||||||
int rc = sqlite3_prepare_v2(db, "SELECT * FROM cards WHERE category = ?", -1, &stmt, nullptr);
|
int rc = sqlite3_prepare_v2 (db, "INSERT INTO cards VALUES(?, ?, ?)", -1,
|
||||||
|
&stmt, nullptr);
|
||||||
if (rc == SQLITE_OK) {
|
if (rc == SQLITE_OK)
|
||||||
sqlite3_bind_int(stmt, 1, category);
|
{
|
||||||
} else {
|
sqlite3_bind_int (stmt, 0, c.category);
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
sqlite3_bind_text (stmt, 1, c.task, -1, SQLITE_STATIC);
|
||||||
|
sqlite3_bind_text (stmt, 2, c.solution, -1, SQLITE_STATIC);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
while (sqlite3_step(stmt) == SQLITE_ROW) {
|
sqlite3_step (stmt);
|
||||||
card c;
|
sqlite3_finalize (stmt);
|
||||||
c.id = sqlite3_column_int(stmt, 0);
|
|
||||||
c.category = sqlite3_column_int(stmt, 1);
|
|
||||||
c.task = strdup((char *) sqlite3_column_text(stmt, 2));
|
|
||||||
c.solution = strdup((char *) sqlite3_column_text(stmt, 3));
|
|
||||||
|
|
||||||
g_array_append_val(cards, c);
|
|
||||||
}
|
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
|
||||||
return cards;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void database_delete_card(sqlite3 *db, const int id) {
|
GArray *
|
||||||
sqlite3_stmt *stmt;
|
database_load_cards (sqlite3 *db, const int category)
|
||||||
int rc = sqlite3_prepare_v2(db, "DELETE FROM cards WHERE id = ?", -1, &stmt, nullptr);
|
{
|
||||||
if (rc == SQLITE_OK) {
|
GArray *cards = g_array_new (TRUE, FALSE, sizeof (card));
|
||||||
sqlite3_bind_int(stmt, 1, id);
|
|
||||||
} else {
|
sqlite3_stmt *stmt;
|
||||||
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
|
int rc = sqlite3_prepare_v2 (db, "SELECT * FROM cards WHERE category = ?",
|
||||||
|
-1, &stmt, nullptr);
|
||||||
|
if (rc == SQLITE_OK)
|
||||||
|
sqlite3_bind_int (stmt, 1, category);
|
||||||
|
else
|
||||||
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
|
while (sqlite3_step (stmt) == SQLITE_ROW)
|
||||||
|
{
|
||||||
|
card c;
|
||||||
|
c.id = sqlite3_column_int (stmt, 0);
|
||||||
|
c.category = sqlite3_column_int (stmt, 1);
|
||||||
|
c.task = strdup ((char *)sqlite3_column_text (stmt, 2));
|
||||||
|
c.solution = strdup ((char *)sqlite3_column_text (stmt, 3));
|
||||||
|
|
||||||
|
g_array_append_val (cards, c);
|
||||||
}
|
}
|
||||||
sqlite3_step(stmt);
|
sqlite3_finalize (stmt);
|
||||||
sqlite3_finalize(stmt);
|
|
||||||
|
return cards;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
database_delete_card (sqlite3 *db, const int id)
|
||||||
|
{
|
||||||
|
sqlite3_stmt *stmt;
|
||||||
|
int rc = sqlite3_prepare_v2 (db, "DELETE FROM cards WHERE id = ?", -1, &stmt,
|
||||||
|
nullptr);
|
||||||
|
if (rc == SQLITE_OK)
|
||||||
|
sqlite3_bind_int (stmt, 1, id);
|
||||||
|
else
|
||||||
|
fprintf (stderr, "Failed to execute statement: %s\n", sqlite3_errmsg (db));
|
||||||
|
|
||||||
|
sqlite3_step (stmt);
|
||||||
|
sqlite3_finalize (stmt);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,33 +4,35 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
typedef struct category {
|
typedef struct category
|
||||||
int id;
|
{
|
||||||
char *name;
|
int id;
|
||||||
|
char *name;
|
||||||
} category;
|
} category;
|
||||||
|
|
||||||
typedef struct card {
|
typedef struct card
|
||||||
int id;
|
{
|
||||||
int category;
|
int id;
|
||||||
char *task;
|
int category;
|
||||||
char *solution;
|
char *task;
|
||||||
|
char *solution;
|
||||||
} card;
|
} card;
|
||||||
|
|
||||||
sqlite3 *database_connect(const char *path);
|
sqlite3 *database_connect (const char *path);
|
||||||
|
|
||||||
void database_close(sqlite3 *db);
|
void database_close (sqlite3 *db);
|
||||||
|
|
||||||
void database_create_tables(sqlite3 *db);
|
void database_create_tables (sqlite3 *db);
|
||||||
|
|
||||||
void database_save_category(sqlite3 *db, const char *c);
|
void database_save_category (sqlite3 *db, const char *c);
|
||||||
|
|
||||||
GArray *database_load_categories(sqlite3 *db);
|
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, card c);
|
||||||
|
|
||||||
GArray *database_load_cards(sqlite3 *db, int category);
|
GArray *database_load_cards (sqlite3 *db, int category);
|
||||||
|
|
||||||
void database_delete_card(sqlite3 *db, int id);
|
void database_delete_card (sqlite3 *db, int id);
|
||||||
#endif /* DATABASE_H */
|
#endif /* DATABASE_H */
|
||||||
|
|||||||
@@ -6,65 +6,86 @@
|
|||||||
#include "flashcardsapp.h"
|
#include "flashcardsapp.h"
|
||||||
#include "flashcardsappwin.h"
|
#include "flashcardsappwin.h"
|
||||||
|
|
||||||
struct _FlashcardsApp {
|
struct _FlashcardsApp
|
||||||
AdwApplication parent;
|
{
|
||||||
|
AdwApplication parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(FlashcardsApp, flashcards_app, ADW_TYPE_APPLICATION);
|
G_DEFINE_TYPE (FlashcardsApp, flashcards_app, ADW_TYPE_APPLICATION);
|
||||||
|
|
||||||
static void flashcards_app_quit(__attribute__((unused)) GSimpleAction *action,
|
static void
|
||||||
__attribute__((unused)) GVariant *parameter, gpointer user_data) {
|
flashcards_app_quit (__attribute__ ((unused)) GSimpleAction *action,
|
||||||
FlashcardsApp *self = user_data;
|
__attribute__ ((unused)) GVariant *parameter,
|
||||||
g_assert(FLASHCARDS_IS_APP(self));
|
gpointer user_data)
|
||||||
g_application_quit(G_APPLICATION(self));
|
{
|
||||||
|
FlashcardsApp *self = user_data;
|
||||||
|
g_application_quit (G_APPLICATION (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flashcards_app_about(__attribute__((unused)) GSimpleAction *action,
|
static void
|
||||||
__attribute__((unused)) GVariant *parameter, gpointer user_data) {
|
flashcards_app_about (__attribute__ ((unused)) GSimpleAction *action,
|
||||||
FlashcardsApp *self = user_data;
|
__attribute__ ((unused)) GVariant *parameter,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
FlashcardsApp *self = user_data;
|
||||||
|
|
||||||
g_assert(FLASHCARDS_IS_APP(self));
|
GtkWindow *window
|
||||||
|
= gtk_application_get_active_window (GTK_APPLICATION (self));
|
||||||
|
|
||||||
GtkWindow *window = gtk_application_get_active_window(GTK_APPLICATION(self));
|
AdwDialog *dialog = adw_about_dialog_new_from_appdata (
|
||||||
|
"/li/sopht/flashcards/appdata", nullptr);
|
||||||
AdwDialog *dialog = adw_about_dialog_new_from_appdata("/li/sopht/flashcards/appdata", nullptr);
|
adw_dialog_present (dialog, GTK_WIDGET (window));
|
||||||
adw_dialog_present(dialog, GTK_WIDGET(window));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GActionEntry app_actions[] = {
|
static const GActionEntry app_actions[] = {
|
||||||
{"quit", flashcards_app_quit, nullptr, nullptr, nullptr, {0, 0, 0}},
|
{ "quit", flashcards_app_quit, nullptr, nullptr, nullptr, { 0, 0, 0 } },
|
||||||
{"about", flashcards_app_about, nullptr, nullptr, nullptr, {0, 0, 0}},
|
{ "about", flashcards_app_about, nullptr, nullptr, nullptr, { 0, 0, 0 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
static void flashcards_app_init(FlashcardsApp *app) {
|
static void
|
||||||
g_action_map_add_action_entries(G_ACTION_MAP(app), app_actions, G_N_ELEMENTS(app_actions), app);
|
flashcards_app_init (FlashcardsApp *app)
|
||||||
gtk_application_set_accels_for_action(GTK_APPLICATION(app), "app.quit", (const char *[]) {"<primary>q", nullptr});
|
{
|
||||||
|
g_action_map_add_action_entries (G_ACTION_MAP (app), app_actions,
|
||||||
|
G_N_ELEMENTS (app_actions), app);
|
||||||
|
gtk_application_set_accels_for_action (
|
||||||
|
GTK_APPLICATION (app), "app.quit",
|
||||||
|
(const char *[]){ "<primary>q", nullptr });
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flashcards_app_activate(GApplication *app) {
|
static void
|
||||||
FlashcardsAppWindow *win = flashcards_app_window_new(FLASHCARDS_APP(app));
|
flashcards_app_activate (GApplication *app)
|
||||||
gtk_window_present(GTK_WINDOW(win));
|
{
|
||||||
|
FlashcardsAppWindow *win = flashcards_app_window_new (FLASHCARDS_APP (app));
|
||||||
|
gtk_window_present (GTK_WINDOW (win));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flashcards_app_open(GApplication *app, __attribute__((unused)) GFile **files,
|
static void
|
||||||
__attribute__((unused)) int n_files, __attribute__((unused)) const char *hint) {
|
flashcards_app_open (GApplication *app, __attribute__ ((unused)) GFile **files,
|
||||||
FlashcardsAppWindow *win;
|
__attribute__ ((unused)) int n_files,
|
||||||
|
__attribute__ ((unused)) const char *hint)
|
||||||
|
{
|
||||||
|
FlashcardsAppWindow *win;
|
||||||
|
|
||||||
GList *windows = gtk_application_get_windows(GTK_APPLICATION(app));
|
GList *windows = gtk_application_get_windows (GTK_APPLICATION (app));
|
||||||
if (windows)
|
if (windows)
|
||||||
win = FLASHCARDS_APP_WINDOW(windows->data);
|
win = FLASHCARDS_APP_WINDOW (windows->data);
|
||||||
else
|
else
|
||||||
win = flashcards_app_window_new(FLASHCARDS_APP(app));
|
win = flashcards_app_window_new (FLASHCARDS_APP (app));
|
||||||
|
|
||||||
gtk_window_present(GTK_WINDOW(win));
|
gtk_window_present (GTK_WINDOW (win));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flashcards_app_class_init(FlashcardsAppClass *klass) {
|
static void
|
||||||
G_APPLICATION_CLASS(klass)->activate = flashcards_app_activate;
|
flashcards_app_class_init (FlashcardsAppClass *klass)
|
||||||
G_APPLICATION_CLASS(klass)->open = flashcards_app_open;
|
{
|
||||||
|
G_APPLICATION_CLASS (klass)->activate = flashcards_app_activate;
|
||||||
|
G_APPLICATION_CLASS (klass)->open = flashcards_app_open;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashcardsApp *flashcards_app_new(void) {
|
FlashcardsApp *
|
||||||
return g_object_new(FLASHCARDS_APP_TYPE, "application-id", "li.sopht.Flashcards", "flags",
|
flashcards_app_new (void)
|
||||||
G_APPLICATION_DEFAULT_FLAGS, NULL);
|
{
|
||||||
|
return g_object_new (FLASHCARDS_APP_TYPE, "application-id",
|
||||||
|
"li.sopht.Flashcards", "flags",
|
||||||
|
G_APPLICATION_DEFAULT_FLAGS, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,10 @@
|
|||||||
#include <adwaita.h>
|
#include <adwaita.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
#define FLASHCARDS_APP_TYPE (flashcards_app_get_type())
|
#define FLASHCARDS_APP_TYPE (flashcards_app_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE(FlashcardsApp, flashcards_app, FLASHCARDS, APP, AdwApplication)
|
G_DECLARE_FINAL_TYPE (FlashcardsApp, flashcards_app, FLASHCARDS, APP,
|
||||||
|
AdwApplication)
|
||||||
|
|
||||||
FlashcardsApp *flashcards_app_new(void);
|
FlashcardsApp *flashcards_app_new (void);
|
||||||
|
|
||||||
#endif /* __FLASHCARDSAPP_H */
|
#endif /* __FLASHCARDSAPP_H */
|
||||||
|
|||||||
@@ -9,176 +9,234 @@
|
|||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
||||||
struct _FlashcardsAppWindow {
|
struct _FlashcardsAppWindow
|
||||||
AdwApplicationWindow parent;
|
{
|
||||||
|
AdwApplicationWindow parent;
|
||||||
|
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
GArray *categories;
|
GArray *categories;
|
||||||
GQueue *cards;
|
GQueue *cards;
|
||||||
card *current_card;
|
card *current_card;
|
||||||
|
|
||||||
AdwWindowTitle *title;
|
AdwWindowTitle *title;
|
||||||
|
|
||||||
AdwNavigationSplitView *split_view;
|
AdwNavigationSplitView *split_view;
|
||||||
AdwNavigationPage *sidebar;
|
AdwNavigationPage *sidebar;
|
||||||
AdwNavigationPage *content;
|
AdwNavigationPage *content;
|
||||||
|
|
||||||
AdwViewStack *main_view;
|
AdwViewStack *main_view;
|
||||||
GtkWidget *placeholder_category;
|
GtkWidget *placeholder_category;
|
||||||
GtkWidget *placeholder_card;
|
GtkWidget *placeholder_card;
|
||||||
GtkWidget *flashcard;
|
GtkWidget *flashcard;
|
||||||
|
|
||||||
GtkListBox *topics;
|
GtkListBox *topics;
|
||||||
|
|
||||||
bool started;
|
bool started;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE(FlashcardsAppWindow, flashcards_app_window, ADW_TYPE_APPLICATION_WINDOW);
|
G_DEFINE_TYPE (FlashcardsAppWindow, flashcards_app_window,
|
||||||
|
ADW_TYPE_APPLICATION_WINDOW);
|
||||||
|
|
||||||
static void load_categories(FlashcardsAppWindow *win) {
|
static void
|
||||||
gtk_list_box_remove_all(win->topics);
|
load_categories (FlashcardsAppWindow *win)
|
||||||
|
{
|
||||||
|
gtk_list_box_remove_all (win->topics);
|
||||||
|
|
||||||
win->categories = database_load_categories(win->db);
|
win->categories = database_load_categories (win->db);
|
||||||
|
|
||||||
for (guint i = 0; i < win->categories->len; i++) {
|
for (guint i = 0; i < win->categories->len; i++)
|
||||||
category c = g_array_index(win->categories, category, i);
|
{
|
||||||
printf("%d: %s\n", c.id, c.name);
|
category c = g_array_index (win->categories, category, i);
|
||||||
|
printf ("%d: %s\n", c.id, c.name);
|
||||||
|
|
||||||
GtkWidget *child = gtk_list_box_row_new();
|
GtkWidget *child = gtk_list_box_row_new ();
|
||||||
GtkWidget *label = gtk_label_new(c.name);
|
GtkWidget *label = gtk_label_new (c.name);
|
||||||
gtk_widget_set_halign(label, GTK_ALIGN_START);
|
gtk_widget_set_halign (label, GTK_ALIGN_START);
|
||||||
gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
|
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
|
||||||
gtk_widget_set_tooltip_text(label, c.name);
|
gtk_widget_set_tooltip_text (label, c.name);
|
||||||
gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(child), label);
|
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (child), label);
|
||||||
|
|
||||||
gtk_list_box_append(win->topics, child);
|
gtk_list_box_append (win->topics, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_cards(FlashcardsAppWindow *win, category c) {
|
static void
|
||||||
GArray *card_array = database_load_cards(win->db, c.id);
|
load_cards (FlashcardsAppWindow *win, category c)
|
||||||
|
{
|
||||||
|
GArray *card_array = database_load_cards (win->db, c.id);
|
||||||
|
|
||||||
win->cards = g_queue_new();
|
win->cards = g_queue_new ();
|
||||||
for (guint i = 0; i < card_array->len; i++) {
|
for (guint i = 0; i < card_array->len; i++)
|
||||||
g_queue_push_tail(win->cards, &g_array_index(card_array, card, i));
|
{
|
||||||
;
|
g_queue_push_tail (win->cards, &g_array_index (card_array, card, i));
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Flashcards: %d\n", win->cards->length);
|
printf ("Flashcards: %d\n", win->cards->length);
|
||||||
if (win->cards->length <= 0) {
|
if (win->cards->length <= 0)
|
||||||
adw_view_stack_set_visible_child(win->main_view, win->placeholder_card);
|
{
|
||||||
return;
|
adw_view_stack_set_visible_child (win->main_view, win->placeholder_card);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
win->current_card = g_queue_pop_head(win->cards);
|
win->current_card = g_queue_pop_head (win->cards);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_select_category(__attribute__((unused)) GtkListBox *box, GtkListBoxRow *row, gpointer user_data) {
|
static void
|
||||||
FlashcardsAppWindow *win = user_data;
|
on_select_category (__attribute__ ((unused)) GtkListBox *box,
|
||||||
|
GtkListBoxRow *row, gpointer user_data)
|
||||||
|
{
|
||||||
|
FlashcardsAppWindow *win = user_data;
|
||||||
|
|
||||||
adw_navigation_split_view_set_show_content(ADW_NAVIGATION_SPLIT_VIEW(win->split_view), TRUE);
|
adw_navigation_split_view_set_show_content (
|
||||||
|
ADW_NAVIGATION_SPLIT_VIEW (win->split_view), TRUE);
|
||||||
|
|
||||||
int id = gtk_list_box_row_get_index(row);
|
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);
|
printf ("%d: %d\n", id, c.id);
|
||||||
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);
|
||||||
|
|
||||||
load_cards(win, c);
|
load_cards (win, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_add_category(__attribute__((unused)) GtkButton *self, gpointer user_data) {
|
static void
|
||||||
FlashcardsCreateCategoryDialog *dialog = flashcards_create_category_dialog_new(user_data);
|
on_add_category (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
adw_dialog_present(ADW_DIALOG(dialog), GTK_WIDGET(user_data));
|
{
|
||||||
|
FlashcardsCreateCategoryDialog *dialog
|
||||||
|
= flashcards_create_category_dialog_new (user_data);
|
||||||
|
adw_dialog_present (ADW_DIALOG (dialog), GTK_WIDGET (user_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_delete_category(__attribute__((unused)) GtkButton *self, gpointer user_data) {
|
static void
|
||||||
FlashcardsAppWindow *win = user_data;
|
on_delete_category (__attribute__ ((unused)) GtkButton *self,
|
||||||
database_delete_category(win->db, 1);
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
FlashcardsAppWindow *win = user_data;
|
||||||
|
database_delete_category (win->db, 1);
|
||||||
|
|
||||||
printf("Delete category\n");
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_add_card(__attribute__((unused)) GtkButton *self, gpointer user_data) {
|
static void
|
||||||
/*FlashcardsAppWindow *win = user_data;
|
on_add_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
FlashcardsCreateCardDialog *dialog = flashcards_create_card_dialog_new(win);
|
{
|
||||||
adw_dialog_present(ADW_DIALOG(dialog), GTK_WIDGET(win));*/
|
/*FlashcardsAppWindow *win = user_data;
|
||||||
|
FlashcardsCreateCardDialog *dialog = flashcards_create_card_dialog_new(win);
|
||||||
|
adw_dialog_present(ADW_DIALOG(dialog), GTK_WIDGET(win));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_delete_card(__attribute__((unused)) GtkButton *self, gpointer user_data) {
|
static void
|
||||||
/*FlashcardsAppWindow *win = user_data;
|
on_delete_card (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
database_delete_card(win->db, 1);
|
{
|
||||||
printf("Delete card\n");*/
|
/*FlashcardsAppWindow *win = user_data;
|
||||||
|
database_delete_card(win->db, 1);
|
||||||
|
printf("Delete card\n");*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_answer_easy(__attribute__((unused)) GtkButton *self, gpointer user_data) {
|
static void
|
||||||
FlashcardsAppWindow *win = user_data;
|
on_answer_easy (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
adw_view_stack_set_visible_child(win->main_view, win->placeholder_category);
|
{
|
||||||
|
FlashcardsAppWindow *win = user_data;
|
||||||
|
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_answer_medium(__attribute__((unused)) GtkButton *self, gpointer user_data) {
|
static void
|
||||||
FlashcardsAppWindow *win = user_data;
|
on_answer_medium (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
adw_view_stack_set_visible_child(win->main_view, win->placeholder_category);
|
{
|
||||||
|
FlashcardsAppWindow *win = user_data;
|
||||||
|
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_answer_hard(__attribute__((unused)) GtkButton *self, gpointer user_data) {
|
static void
|
||||||
FlashcardsAppWindow *win = user_data;
|
on_answer_hard (__attribute__ ((unused)) GtkButton *self, gpointer user_data)
|
||||||
adw_view_stack_set_visible_child(win->main_view, win->placeholder_category);
|
{
|
||||||
|
FlashcardsAppWindow *win = user_data;
|
||||||
|
adw_view_stack_set_visible_child (win->main_view, win->placeholder_category);
|
||||||
}
|
}
|
||||||
|
|
||||||
void flashcards_app_window_test(FlashcardsAppWindow *win, const gchar *test) {
|
void
|
||||||
GtkWidget *child;
|
flashcards_app_window_test (FlashcardsAppWindow *win, const gchar *test)
|
||||||
|
{
|
||||||
|
GtkWidget *child;
|
||||||
|
|
||||||
database_save_category(win->db, test);
|
database_save_category (win->db, test);
|
||||||
load_categories(win);
|
load_categories (win);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_flashcards_app_window_show(GtkWidget *self, gpointer user_data) {
|
static void
|
||||||
FlashcardsAppWindow *win = user_data;
|
on_flashcards_app_window_show (GtkWidget *self, gpointer user_data)
|
||||||
printf("Show\n");
|
{
|
||||||
|
FlashcardsAppWindow *win = user_data;
|
||||||
|
printf ("Show\n");
|
||||||
|
|
||||||
load_categories(win);
|
load_categories (win);
|
||||||
gtk_list_box_unselect_all(win->topics);
|
gtk_list_box_unselect_all (win->topics);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flashcards_app_window_init(FlashcardsAppWindow *self) {
|
static void
|
||||||
gtk_widget_init_template(GTK_WIDGET(self));
|
flashcards_app_window_init (FlashcardsAppWindow *self)
|
||||||
self->db = database_connect(g_get_user_data_dir());
|
{
|
||||||
|
gtk_widget_init_template (GTK_WIDGET (self));
|
||||||
|
self->db = database_connect (g_get_user_data_dir ());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flashcards_app_window_class_init(FlashcardsAppWindowClass *class) {
|
static void
|
||||||
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), "/li/sopht/flashcards/window.ui");
|
flashcards_app_window_class_init (FlashcardsAppWindowClass *class)
|
||||||
|
{
|
||||||
|
gtk_widget_class_set_template_from_resource (
|
||||||
|
GTK_WIDGET_CLASS (class), "/li/sopht/flashcards/window.ui");
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, title);
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, title);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, split_view);
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, sidebar);
|
FlashcardsAppWindow, split_view);
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, content);
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, sidebar);
|
||||||
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, content);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, main_view);
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, placeholder_category);
|
FlashcardsAppWindow, main_view);
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, placeholder_card);
|
gtk_widget_class_bind_template_child (
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, flashcard);
|
GTK_WIDGET_CLASS (class), FlashcardsAppWindow, placeholder_category);
|
||||||
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, placeholder_card);
|
||||||
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, flashcard);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, topics);
|
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),
|
||||||
|
FlashcardsAppWindow, topics);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_flashcards_app_window_show);
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
|
on_flashcards_app_window_show);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_select_category);
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_add_category);
|
on_select_category);
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_delete_category);
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_add_card);
|
on_add_category);
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_delete_card);
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
|
on_delete_category);
|
||||||
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
|
on_add_card);
|
||||||
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
|
on_delete_card);
|
||||||
|
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_answer_easy);
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_answer_medium);
|
on_answer_easy);
|
||||||
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_answer_hard);
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
|
on_answer_medium);
|
||||||
|
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),
|
||||||
|
on_answer_hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashcardsAppWindow *flashcards_app_window_new(FlashcardsApp *app) {
|
FlashcardsAppWindow *
|
||||||
return g_object_new(FLASHCARDS_APP_WINDOW_TYPE, "application", app, NULL);
|
flashcards_app_window_new (FlashcardsApp *app)
|
||||||
|
{
|
||||||
|
return g_object_new (FLASHCARDS_APP_WINDOW_TYPE, "application", app, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
#ifndef __FLASHCARDSAPPWIN_H
|
#ifndef __FLASHCARDSAPPWIN_H
|
||||||
#define __FLASHCARDSAPPWIN_H
|
#define __FLASHCARDSAPPWIN_H
|
||||||
|
|
||||||
|
#include "flashcardsapp.h"
|
||||||
#include <adwaita.h>
|
#include <adwaita.h>
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include "flashcardsapp.h"
|
|
||||||
|
|
||||||
#define FLASHCARDS_APP_WINDOW_TYPE (flashcards_app_window_get_type())
|
#define FLASHCARDS_APP_WINDOW_TYPE (flashcards_app_window_get_type ())
|
||||||
G_DECLARE_FINAL_TYPE(FlashcardsAppWindow, flashcards_app_window, FLASHCARDS, APP_WINDOW, AdwApplicationWindow)
|
G_DECLARE_FINAL_TYPE (FlashcardsAppWindow, flashcards_app_window, FLASHCARDS,
|
||||||
|
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_test (FlashcardsAppWindow *win, const gchar *test);
|
||||||
|
|
||||||
#endif /* __FLASHCARDSAPPWIN_H */
|
#endif /* __FLASHCARDSAPPWIN_H */
|
||||||
|
|||||||
12
src/main.c
12
src/main.c
@@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
#include "flashcardsapp.h"
|
#include "flashcardsapp.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int
|
||||||
bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
|
main (int argc, char *argv[])
|
||||||
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
|
{
|
||||||
textdomain(GETTEXT_PACKAGE);
|
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
||||||
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
||||||
|
textdomain (GETTEXT_PACKAGE);
|
||||||
|
|
||||||
return g_application_run(G_APPLICATION(flashcards_app_new()), argc, argv);
|
return g_application_run (G_APPLICATION (flashcards_app_new ()), argc, argv);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user