Skip to content
Snippets Groups Projects
Verified Commit e5723d6a authored by Sophie Krause's avatar Sophie Krause :rabbit2:
Browse files

formatting, small changes

parent 5f2b933a
No related branches found
No related tags found
No related merge requests found
Pipeline #1823 failed
Showing
with 548 additions and 390 deletions
---
Language: Cpp
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
...
.vscode/
.idea/
builddir/
.flatpak-builder/
repo/
......
......@@ -26,72 +26,6 @@ config_h.set_quoted('LOCALEDIR', get_option('prefix') / get_option('localedir'))
configure_file(output: 'config.h', configuration: config_h)
add_project_arguments(['-I' + meson.project_build_root()], language: 'c')
# project_c_args = []
# test_c_args = [
# '-Wcast-align',
# '-Wdeclaration-after-statement',
# '-Werror=address',
# '-Werror=array-bounds',
# '-Werror=empty-body',
# '-Werror=implicit',
# '-Werror=implicit-function-declaration',
# '-Werror=incompatible-pointer-types',
# '-Werror=init-self',
# '-Werror=int-conversion',
# '-Werror=int-to-pointer-cast',
# '-Werror=main',
# '-Werror=misleading-indentation',
# '-Werror=missing-braces',
# '-Werror=missing-include-dirs',
# '-Werror=nonnull',
# '-Werror=overflow',
# '-Werror=parenthesis',
# '-Werror=pointer-arith',
# '-Werror=pointer-to-int-cast',
# '-Werror=redundant-decls',
# '-Werror=return-type',
# '-Werror=sequence-point',
# '-Werror=shadow',
# '-Werror=strict-prototypes',
# '-Werror=trigraphs',
# '-Werror=undef',
# '-Werror=write-strings',
# '-Wformat-nonliteral',
# '-Wignored-qualifiers',
# '-Wimplicit-function-declaration',
# '-Wlogical-op',
# '-Wmissing-declarations',
# '-Wmissing-format-attribute',
# '-Wmissing-include-dirs',
# '-Wmissing-noreturn',
# '-Wnested-externs',
# '-Wno-cast-function-type',
# '-Wno-dangling-pointer',
# '-Wno-missing-field-initializers',
# '-Wno-sign-compare',
# '-Wno-unused-parameter',
# '-Wold-style-definition',
# '-Wpointer-arith',
# '-Wredundant-decls',
# '-Wstrict-prototypes',
# '-Wswitch-default',
# '-Wswitch-enum',
# '-Wundef',
# '-Wuninitialized',
# '-Wunused',
# '-fno-strict-aliasing',
# ['-Werror=format-security', '-Werror=format=2'],
# ]
# if get_option('buildtype') != 'plain'
# test_c_args += '-fstack-protector-strong'
# endif
# foreach arg: test_c_args
# if cc.has_multi_arguments(arg)
# project_c_args += arg
# endif
# endforeach
# add_project_arguments(project_c_args, language: 'c')
executable('flashcards',
sourcefiles,
resources,
......
resources/ui/window.blp
resources/ui/create-category.blp
resources/ui/create-card.blp
src/flashcardsapp.c
src/flashcardsappwin.c
src/create-category.c
......
......@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: flashcards\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-19 16:20+0100\n"
"POT-Creation-Date: 2025-03-10 16:13+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -42,19 +42,23 @@ msgstr "Über Karteikarten"
msgid "Select a category"
msgstr "Wähle eine Kategorie"
#: resources/ui/window.blp:120
#: resources/ui/window.blp:87
msgid "Add a card"
msgstr "Füge eine Karte hinzu"
#: resources/ui/window.blp:127
msgid "Easy"
msgstr "Einfach"
#: resources/ui/window.blp:125
#: resources/ui/window.blp:133
msgid "Medium"
msgstr "Mittel"
#: resources/ui/window.blp:130
#: resources/ui/window.blp:139
msgid "Hard"
msgstr "Schwer"
#: resources/ui/window.blp:147
#: resources/ui/window.blp:157
msgid "About Flashcards"
msgstr "Über Karteikarten"
......@@ -62,17 +66,26 @@ msgstr "Über Karteikarten"
msgid "Create a new category"
msgstr "Erstelle eine neue Kategorie"
#: resources/ui/create-category.blp:8
#: resources/ui/create-category.blp:8 resources/ui/create-card.blp:8
msgid "Cancel"
msgstr "Abbrechen"
#: resources/ui/create-category.blp:9
#: resources/ui/create-category.blp:9 resources/ui/create-card.blp:9
msgid "Add"
msgstr "Hinzufügen"
#: resources/ui/create-category.blp:14
msgid "Category title"
msgstr "Kategorie-Titel"
#: resources/ui/create-category.blp:14 resources/ui/create-card.blp:14
msgid "Title"
msgstr "Titel"
#: resources/ui/create-card.blp:5
#, fuzzy
msgid "Create a new card"
msgstr "Erstelle eine neue Kategorie"
#: resources/ui/create-card.blp:21
msgid "Answer"
msgstr "Antwort"
#: resources/li.sopht.Flashcards.desktop.in:9
msgid "GTK;"
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: flashcards\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-19 16:20+0100\n"
"POT-Creation-Date: 2025-03-10 16:13+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
......@@ -47,19 +47,23 @@ msgstr ""
msgid "Select a category"
msgstr ""
#: resources/ui/window.blp:120
#: resources/ui/window.blp:87
msgid "Add a card"
msgstr ""
#: resources/ui/window.blp:127
msgid "Easy"
msgstr ""
#: resources/ui/window.blp:125
#: resources/ui/window.blp:133
msgid "Medium"
msgstr ""
#: resources/ui/window.blp:130
#: resources/ui/window.blp:139
msgid "Hard"
msgstr ""
#: resources/ui/window.blp:147
#: resources/ui/window.blp:157
msgid "About Flashcards"
msgstr ""
......@@ -67,16 +71,24 @@ msgstr ""
msgid "Create a new category"
msgstr ""
#: resources/ui/create-category.blp:8
#: resources/ui/create-category.blp:8 resources/ui/create-card.blp:8
msgid "Cancel"
msgstr ""
#: resources/ui/create-category.blp:9
#: resources/ui/create-category.blp:9 resources/ui/create-card.blp:9
msgid "Add"
msgstr ""
#: resources/ui/create-category.blp:14
msgid "Category title"
#: resources/ui/create-category.blp:14 resources/ui/create-card.blp:14
msgid "Title"
msgstr ""
#: resources/ui/create-card.blp:5
msgid "Create a new card"
msgstr ""
#: resources/ui/create-card.blp:21
msgid "Answer"
msgstr ""
#: resources/li.sopht.Flashcards.desktop.in:9
......
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/li/sopht/flashcards">
<file preprocess="xml-stripblanks">ui/window.ui</file>
<file preprocess="xml-stripblanks">ui/create-category.ui</file>
<file preprocess="xml-stripblanks">ui/create-card.ui</file>
<file alias="appdata" compressed="true" preprocess="xml-stripblanks">li.sopht.Flashcards.metainfo.xml</file>
</gresource>
</gresources>
\ No newline at end of file
subdir('ui')
resources = gnome.compile_resources('resources',
'flashcards.gresource.xml',
dependencies : blueprints,
c_name : 'flashcards'
)
compile_schemas = find_program('glib-compile-schemas', required : false, disabler : true)
test('Validate schema file',
compile_schemas,
......
using Gtk 4.0;
using Adw 1;
template $FlashcardsCreateCardDialog : Adw.AlertDialog {
heading: _("Create a new card");
close-response: "cancel";
responses [
cancel: _("Cancel"),
add: _("Add") suggested,
]
response => $on_response();
Adw.EntryRow entry {
title: _("Title");
styles [
"card",
]
}
Adw.EntryRow entry {
title: _("Answer");
styles [
"card",
]
}
}
\ No newline at end of file
......@@ -11,7 +11,7 @@ template $FlashcardsCreateCategoryDialog : Adw.AlertDialog {
response => $on_response();
Adw.EntryRow entry {
title: _("Category title");
title: _("Title");
styles [
"card",
]
......
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/li/sopht/flashcards">
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">create-category.ui</file>
<file alias="appdata" compressed="true" preprocess="xml-stripblanks">../li.sopht.Flashcards.metainfo.xml</file>
</gresource>
</gresources>
......@@ -6,9 +6,3 @@ blueprints = custom_target('blueprints',
output : '.',
command : [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
)
\ No newline at end of file
resources = gnome.compile_resources('resources',
'flashcards.gresource.xml',
dependencies: blueprints,
c_name: 'flashcards'
)
\ No newline at end of file
......@@ -47,7 +47,7 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
valign: start;
selection-mode: single;
activate-on-single-click: true;
row-activated => $on_category_selected();
row-activated => $on_select_category();
styles ["navigation-sidebar"]
}
};
......@@ -61,11 +61,17 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
Adw.ToolbarView {
[top]
Adw.HeaderBar {
[start]
Gtk.Button {
icon-name: "list-add-symbolic";
clicked => $on_add_card();
tooltip-text: _("Add card");
}
[start]
Gtk.Button {
icon-name: "user-trash-symbolic";
clicked => $on_delete_category();
tooltip-text: _("Delete flashcard");
clicked => $on_delete_card();
tooltip-text: _("Delete card");
}
[title]
Adw.WindowTitle title {
......@@ -76,12 +82,19 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
content: Adw.ViewStack main_view {
Adw.ViewStackPage {
child: Adw.StatusPage placeholder {
child: Adw.StatusPage placeholder_category {
title: _("Select a category");
icon-name: "edit-find-symbolic";
};
}
Adw.ViewStackPage {
child: Adw.StatusPage placeholder_card {
title: _("Add a card");
icon-name: "list-add-symbolic";
};
}
Adw.ViewStackPage {
child: Adw.Clamp flashcard {
maximum-size: 800;
......@@ -119,16 +132,19 @@ template $FlashcardsAppWindow : Adw.ApplicationWindow {
styles ["pill"]
label: _("Easy");
hexpand: true;
clicked => $on_answer_easy();
}
Button {
styles ["pill"]
label: _("Medium");
hexpand: true;
clicked => $on_answer_medium();
}
Button {
styles ["pill"]
label: _("Hard");
hexpand: true;
clicked => $on_answer_hard();
}
}
}
......
#include <gtk/gtk.h>
#include <adwaita.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "create-category.h"
struct _FlashcardsCreateCategoryDialog
{
struct _FlashcardsCreateCategoryDialog {
AdwAlertDialog parent;
GtkEditable *entry;
......@@ -16,41 +15,30 @@ struct _FlashcardsCreateCategoryDialog
G_DEFINE_TYPE(FlashcardsCreateCategoryDialog, flashcards_create_category_dialog, ADW_TYPE_ALERT_DIALOG);
static void
flashcards_create_category_dialog_init(FlashcardsCreateCategoryDialog *self)
{
static void 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 on_response(__attribute__((unused)) AdwAlertDialog *dialog, gchar *response, gpointer user_data) {
FlashcardsCreateCategoryDialog *self = user_data;
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);
}
}
static void
flashcards_create_category_dialog_class_init(FlashcardsCreateCategoryDialogClass *class)
{
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class), "/li/sopht/flashcards/create-category.ui");
static void 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(class), FlashcardsCreateCategoryDialog, entry);
gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(klass), FlashcardsCreateCategoryDialog, entry);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_response);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(klass), on_response);
}
FlashcardsCreateCategoryDialog *
flashcards_create_category_dialog_new(FlashcardsAppWindow *win)
{
FlashcardsCreateCategoryDialog *self = g_object_new(FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE, NULL);
FlashcardsCreateCategoryDialog *flashcards_create_category_dialog_new(FlashcardsAppWindow *win) {
FlashcardsCreateCategoryDialog *self = g_object_new(FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE, nullptr);
self->win = win;
return self;
}
#ifndef __CREATECATEGORYDIALOG_H
#define __CREATECATEGORYDIALOG_H
#include <gtk/gtk.h>
#include <adwaita.h>
#include <gtk/gtk.h>
#include "flashcardsapp.h"
#include "flashcardsappwin.h"
#define FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE (flashcards_create_category_dialog_get_type())
G_DECLARE_FINAL_TYPE(FlashcardsCreateCategoryDialog, flashcards_create_category_dialog, FLASHCARDS, 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);
......
......@@ -2,51 +2,40 @@
#include <stdio.h>
sqlite3 *database_connect(const char *path)
{
int rc;
gchar *file;
sqlite3 *database_connect(const char *path) {
sqlite3 *db;
file = g_build_filename(path, "cards.db", NULL);
gchar *file = g_build_filename(path, "cards.db", NULL);
int rc = sqlite3_open(file, &db);
rc = sqlite3_open(file, &db);
if (rc)
{
if (rc) {
fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
return NULL;
}
else
{
fprintf(stderr, "Opened database successfully\n");
return nullptr;
}
fprintf(stdout, "Opened database successfully\n");
g_free(file);
database_create_tables(db);
return db;
}
void database_close(sqlite3 *db)
{
sqlite3_close(db);
}
void database_close(sqlite3 *db) { sqlite3_close(db); }
void database_create_tables(sqlite3 *db)
{
int rc;
void database_create_tables(sqlite3 *db) {
sqlite3_stmt *stmt;
const char *sql;
sql = "CREATE TABLE IF NOT EXISTS `cards` ("
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"
"`solution` TEXT NOT NULL,"
"PRIMARY KEY(`id` AUTOINCREMENT)"
")";
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
if (rc != SQLITE_OK)
{
if (rc != SQLITE_OK) {
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
}
......@@ -59,10 +48,9 @@ void database_create_tables(sqlite3 *db)
"PRIMARY KEY(`id` AUTOINCREMENT)"
")";
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
if (rc != SQLITE_OK)
{
if (rc != SQLITE_OK) {
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
}
......@@ -70,75 +58,86 @@ void database_create_tables(sqlite3 *db)
sqlite3_finalize(stmt);
}
void database_save_category(sqlite3 *db, const char *c)
{
int rc;
void database_save_category(sqlite3 *db, const char *c) {
sqlite3_stmt *stmt;
fprintf(stdout, "%s\n", c);
rc = sqlite3_prepare_v2(db, "INSERT INTO categories (name) VALUES(?)", -1, &stmt, 0);
int rc = sqlite3_prepare_v2(db, "INSERT INTO categories (name) VALUES(?)", -1, &stmt, nullptr);
if (rc == SQLITE_OK)
{
if (rc == SQLITE_OK) {
sqlite3_bind_text(stmt, 1, c, -1, SQLITE_STATIC);
}
else
{
} else {
printf("Failed to execute statement: %s\n", sqlite3_errmsg(db));
}
rc = sqlite3_step(stmt);
if (rc != SQLITE_OK)
{
if (rc != SQLITE_OK) {
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
}
sqlite3_finalize(stmt);
}
GArray *database_load_categories(sqlite3 *db)
{
GArray *categories;
int rc;
GArray *database_load_categories(sqlite3 *db) {
sqlite3_stmt *stmt;
categories = g_array_new(TRUE, FALSE, sizeof(category));
rc = sqlite3_prepare_v2(db, "SELECT * FROM categories", -1, &stmt, 0);
GArray *categories = g_array_new(TRUE, FALSE, sizeof(category));
int rc = sqlite3_prepare_v2(db, "SELECT * FROM categories", -1, &stmt, nullptr);
if (rc != SQLITE_OK)
{
if (rc != SQLITE_OK) {
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
}
while (sqlite3_step(stmt) == SQLITE_ROW)
{
int id = sqlite3_column_int(stmt, 0);
char *name = strdup((const char *)sqlite3_column_text(stmt, 1));
category c = {id, name};
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_save_card(sqlite3 *db, card c)
{
int rc;
void 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);
// delete the category
rc = sqlite3_prepare_v2(db, "DELETE FROM categories 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));
}
rc = sqlite3_step(stmt);
if (rc != SQLITE_OK) {
fprintf(stderr, "Execution failed: %s\n", sqlite3_errmsg(db));
}
sqlite3_finalize(stmt);
}
void database_save_card(sqlite3 *db, card c) {
sqlite3_stmt *stmt;
fprintf(stdout, "%s: %s\n", c.task, c.solution);
rc = sqlite3_prepare_v2(db, "INSERT INTO cards VALUES(?, ?, ?)", -1, &stmt, 0);
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, 0, c.category);
sqlite3_bind_text(stmt, 1, c.task, -1, SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, c.solution, -1, SQLITE_STATIC);
}
else
{
} else {
fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
}
......@@ -146,11 +145,40 @@ void database_save_card(sqlite3 *db, card c)
sqlite3_finalize(stmt);
}
GArray *database_load_cards(sqlite3 *db)
{
GArray *cards;
GArray *database_load_cards(sqlite3 *db, int category) {
GArray *cards = g_array_new(TRUE, FALSE, sizeof(card));
sqlite3_stmt *stmt;
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));
cards = g_array_new(TRUE, FALSE, sizeof(card));
g_array_append_val(cards, c);
}
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);
}
#ifndef DATABASE_H
#define DATABASE_H
#include <glib.h>
#include <sqlite3.h>
typedef struct category
{
typedef struct category {
int id;
char *name;
} category;
typedef struct card
{
typedef struct card {
int id;
int category;
char *task;
char *solution;
......@@ -24,6 +26,11 @@ void database_save_category(sqlite3 *db, const char *c);
GArray *database_load_categories(sqlite3 *db);
void database_delete_category(sqlite3 *db, int id);
void database_save_card(sqlite3 *db, card c);
GArray *database_load_cards(sqlite3 *db);
\ No newline at end of file
GArray *database_load_cards(sqlite3 *db, int category);
void database_delete_card(sqlite3 *db, int id);
#endif /* DATABASE_H */
#include <gtk/gtk.h>
#include <adwaita.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "flashcardsapp.h"
#include "flashcardsappwin.h"
#include "database.h"
struct _FlashcardsApp
{
struct _FlashcardsApp {
AdwApplication parent;
};
G_DEFINE_TYPE(FlashcardsApp, flashcards_app, ADW_TYPE_APPLICATION);
static void
flashcards_app_quit(
__attribute__((unused)) GSimpleAction *action,
__attribute__((unused)) GVariant *parameter,
gpointer user_data)
{
static void flashcards_app_quit(__attribute__((unused)) GSimpleAction *action,
__attribute__((unused)) GVariant *parameter, gpointer user_data) {
FlashcardsApp *self = user_data;
g_assert(FLASHCARDS_IS_APP(self));
g_application_quit(G_APPLICATION(self));
}
static void
flashcards_app_about(
__attribute__((unused)) GSimpleAction *action,
__attribute__((unused)) GVariant *parameter,
gpointer user_data)
{
static void flashcards_app_about(__attribute__((unused)) GSimpleAction *action,
__attribute__((unused)) GVariant *parameter, gpointer user_data) {
FlashcardsApp *self = user_data;
GtkWindow *window;
AdwDialog *dialog;
g_assert(FLASHCARDS_IS_APP(self));
window = gtk_application_get_active_window(GTK_APPLICATION(self));
GtkWindow *window = gtk_application_get_active_window(GTK_APPLICATION(self));
dialog = adw_about_dialog_new_from_appdata("/li/sopht/flashcards/appdata", NULL);
AdwDialog *dialog = adw_about_dialog_new_from_appdata("/li/sopht/flashcards/appdata", nullptr);
adw_dialog_present(dialog, GTK_WIDGET(window));
}
static const GActionEntry app_actions[] = {
{"quit", flashcards_app_quit, NULL, NULL, NULL, {0, 0, 0}},
{"about", flashcards_app_about, NULL, NULL, NULL, {0, 0, 0}},
{"quit", flashcards_app_quit, nullptr, nullptr, nullptr, {0, 0, 0}},
{"about", flashcards_app_about, nullptr, nullptr, nullptr, {0, 0, 0}},
};
static void
flashcards_app_init(FlashcardsApp *app)
{
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", NULL});
static void flashcards_app_init(FlashcardsApp *app) {
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)
{
FlashcardsAppWindow *win;
win = flashcards_app_window_new(FLASHCARDS_APP(app));
static void flashcards_app_activate(GApplication *app) {
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,
__attribute__((unused)) int n_files,
__attribute__((unused)) const char *hint)
{
GList *windows;
static void flashcards_app_open(GApplication *app, __attribute__((unused)) GFile **files,
__attribute__((unused)) int n_files, __attribute__((unused)) const char *hint) {
FlashcardsAppWindow *win;
windows = gtk_application_get_windows(GTK_APPLICATION(app));
GList *windows = gtk_application_get_windows(GTK_APPLICATION(app));
if (windows)
win = FLASHCARDS_APP_WINDOW(windows->data);
else
......@@ -88,18 +59,12 @@ flashcards_app_open(
gtk_window_present(GTK_WINDOW(win));
}
static void
flashcards_app_class_init(FlashcardsAppClass *class)
{
G_APPLICATION_CLASS(class)->activate = flashcards_app_activate;
G_APPLICATION_CLASS(class)->open = flashcards_app_open;
static void flashcards_app_class_init(FlashcardsAppClass *klass) {
G_APPLICATION_CLASS(klass)->activate = flashcards_app_activate;
G_APPLICATION_CLASS(klass)->open = flashcards_app_open;
}
FlashcardsApp *
flashcards_app_new(void)
{
return g_object_new(FLASHCARDS_APP_TYPE,
"application-id", "li.sopht.Flashcards",
"flags", G_APPLICATION_DEFAULT_FLAGS,
NULL);
FlashcardsApp *flashcards_app_new(void) {
return g_object_new(FLASHCARDS_APP_TYPE, "application-id", "li.sopht.Flashcards", "flags",
G_APPLICATION_DEFAULT_FLAGS, NULL);
}
#ifndef __FLASHCARDSAPP_H
#define __FLASHCARDSAPP_H
#include <gtk/gtk.h>
#include <adwaita.h>
#include <gtk/gtk.h>
#define FLASHCARDS_APP_TYPE (flashcards_app_get_type())
G_DECLARE_FINAL_TYPE(FlashcardsApp, flashcards_app, FLASHCARDS, APP, AdwApplication)
......
#include <gtk/gtk.h>
#include <adwaita.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "create-category.h"
#include "flashcardsapp.h"
#include "flashcardsappwin.h"
#include "create-category.h"
#include "database.h"
struct _FlashcardsAppWindow
{
struct _FlashcardsAppWindow {
AdwApplicationWindow parent;
sqlite3 *db;
GArray *categories;
GQueue *cards;
card *current_card;
AdwWindowTitle *title;
......@@ -23,7 +24,8 @@ struct _FlashcardsAppWindow
AdwNavigationPage *content;
AdwViewStack *main_view;
GtkWidget *placeholder;
GtkWidget *placeholder_category;
GtkWidget *placeholder_card;
GtkWidget *flashcard;
GtkListBox *topics;
......@@ -33,102 +35,122 @@ struct _FlashcardsAppWindow
G_DEFINE_TYPE(FlashcardsAppWindow, flashcards_app_window, ADW_TYPE_APPLICATION_WINDOW);
static void on_category_selected(__attribute__((unused)) GtkListBox *box, GtkListBoxRow *row, gpointer user_data)
{
FlashcardsAppWindow *win;
int id;
category c;
static void load_categories(FlashcardsAppWindow *win) {
gtk_list_box_remove_all(win->topics);
win->categories = database_load_categories(win->db);
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);
GtkWidget *child = gtk_list_box_row_new();
GtkWidget *label = gtk_label_new(c.name);
gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
gtk_widget_set_tooltip_text(label, c.name);
gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(child), label);
gtk_list_box_append(win->topics, child);
}
}
static void load_cards(FlashcardsAppWindow *win, category c) {
GArray *card_array = database_load_cards(win->db, c.id);
win->cards = g_queue_new();
for (guint i = 0; i < card_array->len; i++) {
g_queue_push_tail(win->cards, &g_array_index(card_array, card, i));
;
}
printf("Flashcards: %d\n", win->cards->length);
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);
}
win = user_data;
static void 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);
id = gtk_list_box_row_get_index(row);
printf("%d\n", id);
int id = gtk_list_box_row_get_index(row);
c = g_array_index(win->categories, category, id);
category c = g_array_index(win->categories, category, id);
printf("%d: %d\n", id, c.id);
adw_window_title_set_subtitle(ADW_WINDOW_TITLE(win->title), c.name);
adw_view_stack_set_visible_child(win->main_view, win->flashcard);
}
static void on_add_category(__attribute__((unused)) GtkButton *self,
gpointer user_data)
{
FlashcardsCreateCategoryDialog *dialog;
load_cards(win, c);
}
dialog = flashcards_create_category_dialog_new(user_data);
static void on_add_category(__attribute__((unused)) GtkButton *self, gpointer 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)
{
FlashcardsAppWindow *win;
win = user_data;
static void on_delete_category(__attribute__((unused)) GtkButton *self, gpointer user_data) {
FlashcardsAppWindow *win = user_data;
database_delete_category(win->db, 1);
printf("Delete category\n");
gtk_list_box_unselect_all(win->topics);
adw_view_stack_set_visible_child(win->main_view, win->placeholder);
adw_view_stack_set_visible_child(win->main_view, win->placeholder_category);
}
static void load_categories(FlashcardsAppWindow *win)
{
GArray *categories;
gtk_list_box_remove_all(win->topics);
categories = database_load_categories(win->db);
win->categories = categories;
for (guint i = 0; i < categories->len; i++)
{
GtkWidget *child;
GtkWidget *label;
category c;
static void on_add_card(__attribute__((unused)) GtkButton *self, gpointer user_data) {
/*FlashcardsAppWindow *win = user_data;
FlashcardsCreateCardDialog *dialog = flashcards_create_card_dialog_new(win);
adw_dialog_present(ADW_DIALOG(dialog), GTK_WIDGET(win));*/
}
c = g_array_index(categories, category, i);
printf("%d: %s\n", c.id, c.name);
static void on_delete_card(__attribute__((unused)) GtkButton *self, gpointer user_data) {
/*FlashcardsAppWindow *win = user_data;
database_delete_card(win->db, 1);
printf("Delete card\n");*/
}
child = gtk_list_box_row_new();
label = gtk_label_new(c.name);
gtk_widget_set_halign(label, GTK_ALIGN_START);
gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
gtk_widget_set_tooltip_text(label, c.name);
gtk_list_box_row_set_child(GTK_LIST_BOX_ROW(child), label);
static void on_answer_easy(__attribute__((unused)) GtkButton *self, gpointer user_data) {
FlashcardsAppWindow *win = user_data;
adw_view_stack_set_visible_child(win->main_view, win->placeholder_category);
}
gtk_list_box_append(win->topics, child);
static void on_answer_medium(__attribute__((unused)) GtkButton *self, gpointer user_data) {
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) {
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 flashcards_app_window_test(FlashcardsAppWindow *win, const gchar *test) {
GtkWidget *child;
database_save_category(win->db, test);
load_categories(win);
}
static void on_flashcards_app_window_show(GtkWidget *self,
gpointer user_data)
{
FlashcardsAppWindow *win;
win = user_data;
static void on_flashcards_app_window_show(GtkWidget *self, gpointer user_data) {
FlashcardsAppWindow *win = user_data;
printf("Show\n");
load_categories(win);
gtk_list_box_unselect_all(win->topics);
}
static void flashcards_app_window_init(FlashcardsAppWindow *win)
{
gtk_widget_init_template(GTK_WIDGET(win));
win->db = database_connect(g_get_user_data_dir());
static void flashcards_app_window_init(FlashcardsAppWindow *self) {
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 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);
......@@ -138,19 +160,25 @@ static void flashcards_app_window_class_init(FlashcardsAppWindowClass *class)
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), FlashcardsAppWindow, placeholder);
gtk_widget_class_bind_template_child(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_callback(GTK_WIDGET_CLASS(class), on_category_selected);
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), on_add_category);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_delete_category);
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_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), on_answer_medium);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_answer_hard);
}
FlashcardsAppWindow *
flashcards_app_window_new(FlashcardsApp *app)
{
FlashcardsAppWindow *flashcards_app_window_new(FlashcardsApp *app) {
return g_object_new(FLASHCARDS_APP_WINDOW_TYPE, "application", app, NULL);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment