diff --git a/.gitignore b/.gitignore
index 774aef0..184665c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
.vscode/
-flashcards
+builddir/
+.flatpak-builder/
# Prerequisites
*.d
diff --git a/docs/BO_Logo.svg b/docs/BO_Logo.svg
new file mode 100644
index 0000000..9dac8c6
--- /dev/null
+++ b/docs/BO_Logo.svg
@@ -0,0 +1,44 @@
+
+
+
+
diff --git a/docs/main.typ b/docs/main.typ
new file mode 100644
index 0000000..0de69f9
--- /dev/null
+++ b/docs/main.typ
@@ -0,0 +1,18 @@
+#import "template.typ": *
+
+#show: project.with(
+ title: "Karteikarten-Anwendung mit GTK und Libadwaita",
+ subtitle: "Hardwarenahe Programmierung",
+ authors: (
+ "Sophie Krause",
+ ),
+ logo: "BO_Logo.svg"
+)
+
+= Einleitung
+#lorem(100)
+
+#pagebreak()
+
+= Fazit
+#lorem(100)
\ No newline at end of file
diff --git a/docs/template.typ b/docs/template.typ
new file mode 100644
index 0000000..db34851
--- /dev/null
+++ b/docs/template.typ
@@ -0,0 +1,100 @@
+// The project function defines how your document looks.
+// It takes your content and some metadata and formats it.
+// Go ahead and customize it to your liking!
+#let project(title: "", subtitle: "", authors: (), logo: none, body) = {
+
+ // Set the document's basic properties.
+ set document(author: authors, title: title)
+ set text(font: "Linux Libertine", lang: "de")
+ set heading(numbering: "1.1")
+
+ set align(center)
+
+ // Title page.
+ v(1fr)
+
+ // Logo
+ if logo != none {
+ image(logo, width: 50%)
+ }
+ v(3em)
+
+ // Title
+ text(2em, weight: 700, title)
+
+ linebreak()
+ v(0.1em)
+
+ // Subtitle
+ text(2em, weight: 400, subtitle)
+
+ v(1em)
+
+ // Author
+ grid(
+ ..authors,
+ )
+
+ v(1fr)
+ pagebreak()
+
+ set align(left)
+
+ set page(numbering: "I", number-align: center)
+
+ let ht-first = state("page-first-section", [])
+ let ht-last = state("page-last-section", [])
+
+ set page(
+ header: {
+ locate(loc => {
+ // find first heading of level 1 on current page
+ let first-heading = query(
+ heading.where(level: 1), loc)
+ .find(h => h.location().page() == loc.page())
+ // find last heading of level 1 on current page
+ let last-heading = query(
+ heading.where(level: 1), loc)
+ .rev()
+ .find(h => h.location().page() == loc.page())
+ // test if the find function returned none (i.e. no headings on this page)
+ {
+ if not first-heading == none {
+ ht-first.update([
+ // change style here if update needed section per section
+ #first-heading.body
+ ])
+ ht-last.update([
+ // change style here if update needed section per section
+ #last-heading.body
+ ])
+
+ // if one or more headings on the page, use first heading
+ // change style here if update needed page per page
+ ht-first.display()
+ } else {
+ // no headings on the page, use last heading from variable
+ // change style here if update needed page per page
+ ht-last.display()
+ }
+ }
+ }
+ )
+
+ v(-0.8em)
+ line(length: 100%, stroke: 0.5pt)
+ }
+ )
+
+ // Table of contents
+ outline(depth: 3, indent: true)
+ pagebreak()
+
+ set page(numbering: "1")
+ counter(page).update(1)
+
+ // Main body
+ set par(justify: true)
+
+ body
+}
\ No newline at end of file
diff --git a/gitlab-ci.yml b/gitlab-ci.yml
new file mode 100644
index 0000000..7a84473
--- /dev/null
+++ b/gitlab-ci.yml
@@ -0,0 +1,7 @@
+build:docs:
+ image: 123marvin123/typst:latest
+ script:
+ - typst compile docs/main.typ Flashcards.pdf
+ artifacts:
+ paths:
+ - ./Flashcards.pdf
diff --git a/li.sopht.Flashcards.json b/li.sopht.Flashcards.json
new file mode 100644
index 0000000..eb98a55
--- /dev/null
+++ b/li.sopht.Flashcards.json
@@ -0,0 +1,51 @@
+{
+ "id": "li.sopht.Flashcards",
+ "runtime": "org.gnome.Platform",
+ "runtime-version": "47",
+ "sdk": "org.gnome.Sdk",
+ "command": "flashcards",
+ "finish-args": [
+ "--share=network",
+ "--share=ipc",
+ "--socket=fallback-x11",
+ "--device=dri",
+ "--socket=wayland"
+ ],
+ "cleanup": [
+ "/include",
+ "/lib/pkgconfig",
+ "/man",
+ "/share/doc",
+ "/share/gtk-doc",
+ "/share/man",
+ "/share/pkgconfig",
+ "*.la",
+ "*.a"
+ ],
+ "modules": [
+ {
+ "name": "blueprint-compiler",
+ "buildsystem": "meson",
+ "cleanup": ["*"],
+ "sources": [
+ {
+ "type": "git",
+ "url": "https://gitlab.gnome.org/jwestman/blueprint-compiler",
+ "tag": "v0.16.0"
+ }
+ ]
+ },
+ {
+ "name": "flashcards",
+ "builddir": true,
+ "buildsystem": "meson",
+ "sources": [
+ {
+ "type": "git",
+ "tag": "main",
+ "url": "file:///home/sophie/Dev/Uni/flashcards"
+ }
+ ]
+ }
+ ]
+}
diff --git a/meson.build b/meson.build
index af8ab37..db55db4 100644
--- a/meson.build
+++ b/meson.build
@@ -1,19 +1,107 @@
-project('flashcards', 'c', version : '1.0')
+project('flashcards', 'c',
+ version: '1.0.0',
+ meson_version: '>= 1.0.0',
+ default_options: [ 'warning_level=2', 'werror=false', 'c_std=gnu11', ],
+)
-gtk_dep = dependency('gtk4')
-libadwaita_dep = dependency('libadwaita-1', version: '>=1.2')
-sqlite_dep = dependency('sqlite3')
+flashcards_deps = [
+ dependency('gtk4'),
+ dependency('libadwaita-1', version: '>= 1.6'),
+ dependency('sqlite3'),
+]
gnome = import('gnome')
+i18n = import('i18n')
-subdir('po')
subdir('src')
subdir('resources')
+subdir('po')
+
+cc = meson.get_compiler('c')
+
+config_h = configuration_data()
+config_h.set_quoted('PACKAGE_VERSION', meson.project_version())
+config_h.set_quoted('GETTEXT_PACKAGE', 'flashcards')
+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,
- schemas,
- dependencies: [gtk_dep, libadwaita_dep, sqlite_dep],
+ #schemas,
+ dependencies: flashcards_deps,
install: true
)
+
+gnome.post_install(
+ glib_compile_schemas: true,
+ gtk_update_icon_cache: true,
+ update_desktop_database: true,
+)
\ No newline at end of file
diff --git a/po/POTFILES b/po/POTFILES
index 39b8c77..1592edb 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -1,4 +1,6 @@
-resources/window.blp
+resources/ui/window.blp
+resources/ui/create-category.blp
src/flashcardsapp.c
src/flashcardsappwin.c
-src/database.c
\ No newline at end of file
+src/create-category.c
+src/database.c
diff --git a/po/de.po b/po/de.po
index eb13700..8458249 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1,15 +1,43 @@
-#: resources/window.blp:5 src/flashcardsappwin.c:28
+msgid ""
+msgstr ""
+"Project-Id-Version: flashcards\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-02-05 18:52+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: resources/ui/window.blp:5 resources/ui/window.blp:54 src/flashcardsapp.c:42
msgid "Flashcards"
msgstr "Karteikarten"
-#: resources/window.blp:20
-msgid "Topics"
-msgstr "Themen"
+#: resources/ui/window.blp:17
+msgid "Categories"
+msgstr "Kategorien"
-#: resources/window.blp:94
-msgid "Upgrade Assistant"
-msgstr ""
-
-#: resources/window.blp:98
+#: resources/ui/window.blp:96
msgid "About Flashcards"
msgstr "Über Karteikarten"
+
+#: resources/ui/create-category.blp:9
+#, fuzzy
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: resources/ui/create-category.blp:10
+msgid "Add"
+msgstr "Hinzufügen"
+
+#: src/flashcardsapp.c:45
+msgid "translator-credits"
+msgstr "Übersetzer-Credits"
+
+#~ msgid "Topics"
+#~ msgstr "Themen"
+
+#~ msgid "_Replace"
+#~ msgstr "Ersetzen"
diff --git a/po/en.po b/po/en.po
index 9c823d5..6d42445 100644
--- a/po/en.po
+++ b/po/en.po
@@ -1,15 +1,39 @@
-#: resources/window.blp:5 src/flashcardsappwin.c:28
+msgid ""
+msgstr ""
+"Project-Id-Version: flashcards\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2025-02-05 18:52+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME \n"
+"Language-Team: LANGUAGE \n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: resources/ui/window.blp:5 resources/ui/window.blp:54 src/flashcardsapp.c:42
msgid "Flashcards"
msgstr "Flashcards"
-#: resources/window.blp:20
-msgid "Topics"
-msgstr "Topics"
-
-#: resources/window.blp:94
-msgid "Upgrade Assistant"
+#: resources/ui/window.blp:17
+msgid "Categories"
msgstr ""
-#: resources/window.blp:98
+#: resources/ui/window.blp:96
msgid "About Flashcards"
msgstr "About Flashcards"
+
+#: resources/ui/create-category.blp:9
+msgid "Cancel"
+msgstr ""
+
+#: resources/ui/create-category.blp:10
+msgid "Add"
+msgstr ""
+
+#: src/flashcardsapp.c:45
+msgid "translator-credits"
+msgstr ""
+
+#~ msgid "Topics"
+#~ msgstr "Topics"
diff --git a/po/flashcards.pot b/po/flashcards.pot
index ee356c8..7009f4f 100644
--- a/po/flashcards.pot
+++ b/po/flashcards.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: flashcards\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-11-28 22:18+0100\n"
+"POT-Creation-Date: 2025-02-05 18:52+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME \n"
"Language-Team: LANGUAGE \n"
@@ -17,18 +17,26 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: resources/window.blp:5 src/flashcardsappwin.c:28
+#: resources/ui/window.blp:5 resources/ui/window.blp:54 src/flashcardsapp.c:42
msgid "Flashcards"
msgstr ""
-#: resources/window.blp:20
-msgid "Topics"
+#: resources/ui/window.blp:17
+msgid "Categories"
msgstr ""
-#: resources/window.blp:94
-msgid "Upgrade Assistant"
-msgstr ""
-
-#: resources/window.blp:98
+#: resources/ui/window.blp:96
msgid "About Flashcards"
msgstr ""
+
+#: resources/ui/create-category.blp:9
+msgid "Cancel"
+msgstr ""
+
+#: resources/ui/create-category.blp:10
+msgid "Add"
+msgstr ""
+
+#: src/flashcardsapp.c:45
+msgid "translator-credits"
+msgstr ""
diff --git a/po/meson.build b/po/meson.build
index b9d2d48..5eab52e 100644
--- a/po/meson.build
+++ b/po/meson.build
@@ -1,3 +1 @@
-i18n = import('i18n')
-
i18n.gettext(meson.project_name(), preset: 'glib')
\ No newline at end of file
diff --git a/resources/flashcards.gresource.xml b/resources/flashcards.gresource.xml
index 64c6155..6c001b2 100644
--- a/resources/flashcards.gresource.xml
+++ b/resources/flashcards.gresource.xml
@@ -2,5 +2,6 @@
window.ui
+ create-category.ui
diff --git a/resources/li.sopht.Flashcards.svg b/resources/icons/hicolor/scalable/apps/li.sopht.Flashcards.svg
similarity index 100%
rename from resources/li.sopht.Flashcards.svg
rename to resources/icons/hicolor/scalable/apps/li.sopht.Flashcards.svg
diff --git a/resources/icons/hicolor/symbolic/apps/li.sopht.Flashcards-symbolic.svg b/resources/icons/hicolor/symbolic/apps/li.sopht.Flashcards-symbolic.svg
new file mode 100644
index 0000000..0444828
--- /dev/null
+++ b/resources/icons/hicolor/symbolic/apps/li.sopht.Flashcards-symbolic.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/icons/meson.build b/resources/icons/meson.build
new file mode 100644
index 0000000..e91a945
--- /dev/null
+++ b/resources/icons/meson.build
@@ -0,0 +1,13 @@
+application_id = 'li.sopht.Flashcards'
+
+scalable_dir = 'hicolor' / 'scalable' / 'apps'
+install_data(
+ scalable_dir / ('@0@.svg').format(application_id),
+ install_dir: get_option('datadir') / 'icons' / scalable_dir
+)
+
+symbolic_dir = 'hicolor' / 'symbolic' / 'apps'
+install_data(
+ symbolic_dir / ('@0@-symbolic.svg').format(application_id),
+ install_dir: get_option('datadir') / 'icons' / symbolic_dir
+)
diff --git a/resources/li.sopht.Flashcards.desktop.in b/resources/li.sopht.Flashcards.desktop.in
new file mode 100644
index 0000000..86e593c
--- /dev/null
+++ b/resources/li.sopht.Flashcards.desktop.in
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=Flashcards
+Exec=flashcards
+Icon=li.sopht.Flashcards
+Terminal=false
+Type=Application
+Categories=Utility;
+Keywords=GTK;
+StartupNotify=true
diff --git a/resources/li.sopht.Flashcards.gschema.xml b/resources/li.sopht.Flashcards.gschema.xml
new file mode 100644
index 0000000..6933b6a
--- /dev/null
+++ b/resources/li.sopht.Flashcards.gschema.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/resources/meson.build b/resources/meson.build
index efbb4ff..a142ae1 100644
--- a/resources/meson.build
+++ b/resources/meson.build
@@ -1,10 +1,4 @@
-blueprints = custom_target('blueprints',
- input: files(
- 'window.blp'
- ),
- output: '.',
- command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
-)
+subdir('ui')
resources = gnome.compile_resources('resources',
'flashcards.gresource.xml',
@@ -12,4 +6,27 @@ resources = gnome.compile_resources('resources',
c_name: 'flashcards'
)
-schemas = gnome.compile_schemas()
\ No newline at end of file
+compile_schemas = find_program('glib-compile-schemas', required: false, disabler: true)
+test('Validate schema file',
+ compile_schemas,
+ args: ['--strict', '--dry-run', meson.current_source_dir()])
+
+install_data('li.sopht.Flashcards.gschema.xml',
+ install_dir: get_option('datadir') / 'glib-2.0/schemas',
+)
+
+desktop_file = i18n.merge_file(
+ input: 'li.sopht.Flashcards.desktop.in',
+ output: 'li.sopht.Flashcards.desktop',
+ type: 'desktop',
+ po_dir: '../po',
+ install: true,
+ install_dir: get_option('datadir') / 'applications'
+)
+
+desktop_utils = find_program('desktop-file-validate', required: false)
+if desktop_utils.found()
+ test('Validate desktop file', desktop_utils, args: [desktop_file])
+endif
+
+subdir('icons')
diff --git a/resources/ui/create-category.blp b/resources/ui/create-category.blp
new file mode 100644
index 0000000..c1f6675
--- /dev/null
+++ b/resources/ui/create-category.blp
@@ -0,0 +1,20 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $FlashcardsCreateCategoryDialog : Adw.AlertDialog {
+ heading: "Create a new category";
+ default-response: "add";
+ close-response: "cancel";
+ responses [
+ cancel: _("Cancel"),
+ add: _("Add") suggested,
+ ]
+ response => $on_response();
+
+ Adw.EntryRow entry {
+ title: "Category name";
+ styles [
+ "card",
+ ]
+ }
+}
\ No newline at end of file
diff --git a/resources/ui/meson.build b/resources/ui/meson.build
new file mode 100644
index 0000000..1d54641
--- /dev/null
+++ b/resources/ui/meson.build
@@ -0,0 +1,8 @@
+blueprints = custom_target('blueprints',
+ input: files(
+ 'window.blp',
+ 'create-category.blp'
+ ),
+ output: '.',
+ command: [find_program('blueprint-compiler'), 'batch-compile', '@OUTPUT@', '@CURRENT_SOURCE_DIR@', '@INPUT@'],
+)
diff --git a/resources/ui/window.blp b/resources/ui/window.blp
new file mode 100644
index 0000000..2e249bb
--- /dev/null
+++ b/resources/ui/window.blp
@@ -0,0 +1,100 @@
+using Gtk 4.0;
+using Adw 1;
+
+template $FlashcardsAppWindow : Adw.ApplicationWindow {
+ title: _("Flashcards");
+
+ Adw.Breakpoint {
+ condition ( "max-width: 400sp" )
+ setters {
+ split_view.collapsed: true;
+ }
+ }
+
+ Adw.NavigationSplitView split_view {
+ [sidebar]
+ Adw.NavigationPage sidebar{
+ title: _("Categories");
+
+ Box {
+ orientation: vertical;
+ hexpand: true;
+ width-request: 360;
+
+ Adw.HeaderBar {
+ [end]
+ Gtk.Button {
+ icon-name: "list-add-symbolic";
+ clicked => $on_add_category();
+ }
+ }
+
+ Adw.Clamp {
+ hexpand: true;
+
+ ListBox topics {
+ hexpand: true;
+ selection-mode: single;
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+ row-selected => $on_category_selected();
+
+ styles [
+ "boxed-list",
+ ]
+ }
+ }
+ }
+ }
+
+ [content]
+ Adw.NavigationPage content {
+ title: _("Flashcards");
+ Box {
+ orientation: vertical;
+ hexpand: true;
+
+ Adw.HeaderBar {
+ [end]
+ Gtk.MenuButton {
+ icon-name: "open-menu-symbolic";
+ menu-model: primary_menu;
+ }
+ }
+
+ Adw.Clamp {
+ hexpand: true;
+ child: Adw.Bin {
+ margin-top: 12;
+ margin-bottom: 12;
+ margin-start: 12;
+ margin-end: 12;
+
+ styles [
+ "card",
+ ]
+ child: Label {
+ margin-top: 24;
+ margin-bottom: 24;
+ margin-start: 24;
+ margin-end: 24;
+ wrap: true;
+ label: "Wie viel Grad hat ein Kreis?";
+ };
+ };
+ }
+ }
+ }
+ }
+}
+
+menu primary_menu {
+ section {
+ item {
+ label: _("About Flashcards");
+ action: "app.about";
+ }
+ }
+}
diff --git a/resources/window.blp b/resources/window.blp
deleted file mode 100644
index a1a61a5..0000000
--- a/resources/window.blp
+++ /dev/null
@@ -1,102 +0,0 @@
-using Gtk 4.0;
-using Adw 1;
-
-template FlashcardsAppWindow : Adw.ApplicationWindow {
- title: _("Flashcards");
-
- Adw.Leaflet leaflet {
- can-navigate-back: true;
-
- Box {
- orientation: vertical;
- hexpand: true;
- width-request: 360;
-
- Adw.HeaderBar {
- show-end-title-buttons: bind leaflet.folded;
-
- [title]
- Adw.WindowTitle {
- title: _("Topics");
- }
- }
-
- Adw.Clamp {
- hexpand: true;
- child: ListBox topics {
- hexpand: true;
- selection-mode: single;
- margin-top: 12;
- margin-bottom: 12;
- margin-start: 12;
- margin-end: 12;
- row-selected => on_category_selected();
-
- styles [
- "boxed-list",
- ]
- };
- }
- }
-
- Adw.LeafletPage {
- navigatable: false;
- child: Separator {};
- }
-
- Box {
- orientation: vertical;
- hexpand: true;
-
- Adw.HeaderBar {
- show-start-title-buttons: bind leaflet.folded;
- Button leaflet_previous {
- visible: bind leaflet.folded;
- icon-name: "go-previous-symbolic";
- clicked => on_navigate_back();
- }
-
- [end]
- Gtk.MenuButton {
- icon-name: "open-menu-symbolic";
- menu-model: primary_menu;
- }
- }
-
- Adw.Clamp {
- hexpand: true;
- child: Adw.Bin {
- margin-top: 12;
- margin-bottom: 12;
- margin-start: 12;
- margin-end: 12;
-
- styles [
- "card",
- ]
- child: Label {
- margin-top: 24;
- margin-bottom: 24;
- margin-start: 24;
- margin-end: 24;
- wrap: true;
- label: "Wie viel Grad hat ein Kreis?";
- };
- };
- }
- }
- }
-}
-
-menu primary_menu {
- section {
- item {
- label: _("Upgrade Assistant");
- action: "win.show-upgrade-assistant";
- }
- item {
- label: _("About Flashcards");
- action: "app.about";
- }
- }
-}
\ No newline at end of file
diff --git a/src/create-category.c b/src/create-category.c
new file mode 100644
index 0000000..ccba37f
--- /dev/null
+++ b/src/create-category.c
@@ -0,0 +1,56 @@
+#include
+#include
+
+#include
+
+#include "create-category.h"
+
+struct _FlashcardsCreateCategoryDialog
+{
+ AdwAlertDialog parent;
+
+ GtkEditable *entry;
+
+ FlashcardsAppWindow *win;
+};
+
+G_DEFINE_TYPE(FlashcardsCreateCategoryDialog, flashcards_create_category_dialog, ADW_TYPE_ALERT_DIALOG);
+
+static void
+flashcards_create_category_dialog_init(FlashcardsCreateCategoryDialog *self)
+{
+ gtk_widget_init_template(GTK_WIDGET(self));
+}
+
+static void
+on_response(AdwAlertDialog *dialog,
+ gchar *response,
+ gpointer user_data)
+{
+ FlashcardsCreateCategoryDialog *self = FLASHCARDS_CREATE_CATEGORY_DIALOG(user_data);
+
+ const gchar *category = gtk_editable_get_text(self->entry);
+
+ 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");
+
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsCreateCategoryDialog, entry);
+
+ gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_response);
+}
+
+FlashcardsCreateCategoryDialog *
+flashcards_create_category_dialog_new(FlashcardsAppWindow *win)
+{
+ FlashcardsCreateCategoryDialog *self = g_object_new(FLASHCARDS_CREATE_CATEGORY_DIALOG_TYPE, NULL);
+ self->win = win;
+ return self;
+}
\ No newline at end of file
diff --git a/src/create-category.h b/src/create-category.h
new file mode 100644
index 0000000..981b2d8
--- /dev/null
+++ b/src/create-category.h
@@ -0,0 +1,14 @@
+#ifndef __CREATECATEGORYDIALOG_H
+#define __CREATECATEGORYDIALOG_H
+
+#include
+#include
+#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)
+
+FlashcardsCreateCategoryDialog *flashcards_create_category_dialog_new(FlashcardsAppWindow *win);
+
+#endif /* __CREATECATEGORYDIALOG_H */
diff --git a/src/database.c b/src/database.c
index 1603834..bbdee75 100644
--- a/src/database.c
+++ b/src/database.c
@@ -69,8 +69,29 @@ void database_create_tables()
sqlite3_finalize(stmt);
}
-void database_save_category()
+void database_save_category(const char *c)
{
+ int rc;
+ sqlite3_stmt *stmt;
+
+ fprintf(stdout, "%s\n", c);
+ rc = sqlite3_prepare_v2(db, "INSERT INTO categories (name) VALUES(?)", -1, &stmt, 0);
+
+ if (rc == SQLITE_OK)
+ {
+ sqlite3_bind_text(stmt, 1, c, -1, SQLITE_STATIC);
+ }
+ else
+ {
+ printf("Failed to execute statement: %s\n", sqlite3_errmsg(db));
+ }
+
+ rc = sqlite3_step(stmt);
+ if (rc != SQLITE_OK)
+ {
+ fprintf(stderr, "Failed to execute statement: %s\n", sqlite3_errmsg(db));
+ }
+ sqlite3_finalize(stmt);
}
GArray *database_load_categories()
diff --git a/src/flashcardsapp.c b/src/flashcardsapp.c
index 1fdbdf4..4d47e94 100644
--- a/src/flashcardsapp.c
+++ b/src/flashcardsapp.c
@@ -1,6 +1,8 @@
#include
#include
+#include
+
#include "flashcardsapp.h"
#include "flashcardsappwin.h"
@@ -13,9 +15,56 @@ struct _FlashcardsApp
G_DEFINE_TYPE(FlashcardsApp, flashcards_app, ADW_TYPE_APPLICATION);
+static void
+flashcards_app_quit_action(GSimpleAction *action,
+ 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_action(GSimpleAction *action,
+ GVariant *parameter,
+ gpointer user_data)
+{
+ static const char *developers[] = {"Sophie Krause", NULL};
+ FlashcardsApp *self = user_data;
+ GtkWindow *window = NULL;
+
+ g_assert(FLASHCARDS_IS_APP(self));
+
+ window = gtk_application_get_active_window(GTK_APPLICATION(self));
+
+ adw_show_about_dialog(GTK_WIDGET(window),
+ "application-name", _("Flashcards"),
+ "application-icon", "li.sopht.Flashcards",
+ "developer-name", "Sophie Krause",
+ "translator-credits", "Sophie Krause",
+ "version", "1.0.0",
+ "developers", developers,
+ "copyright", "© 2025 Sophie Krause",
+ "license-type", GTK_LICENSE_MIT_X11,
+ NULL);
+}
+
+static const GActionEntry app_actions[] = {
+ {"quit", flashcards_app_quit_action},
+ {"about", flashcards_app_about_action},
+};
+
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 *[]){"q", NULL});
}
static void
@@ -59,7 +108,7 @@ FlashcardsApp *
flashcards_app_new(void)
{
return g_object_new(FLASHCARDS_APP_TYPE,
- "application-id", "li.sopht.flashcards",
- "flags", G_APPLICATION_HANDLES_OPEN,
+ "application-id", "li.sopht.Flashcards",
+ "flags", G_APPLICATION_DEFAULT_FLAGS,
NULL);
}
diff --git a/src/flashcardsappwin.c b/src/flashcardsappwin.c
index 3573ca6..b58516b 100644
--- a/src/flashcardsappwin.c
+++ b/src/flashcardsappwin.c
@@ -5,6 +5,7 @@
#include "flashcardsapp.h"
#include "flashcardsappwin.h"
+#include "create-category.h"
#include "database.h"
@@ -14,25 +15,17 @@ struct _FlashcardsAppWindow
GArray *categories;
- AdwLeaflet *leaflet;
- GtkButton *leaflet_previous;
+ AdwNavigationSplitView *split_view;
+ AdwNavigationPage *sidebar;
+ AdwNavigationPage *content;
+
+ AdwDialog *create_category_dialog;
+
GtkListBox *topics;
};
G_DEFINE_TYPE(FlashcardsAppWindow, flashcards_app_window, ADW_TYPE_APPLICATION_WINDOW);
-static void
-show_about (GtkWindow *win)
-{
- adw_show_about_window (win,
- "application-name", _("Flashcards"),
- "application-icon", "org.gnome.Builder",
- "developer-name", "Tobias Krause",
- "version", "1.0",
- "license-type", GTK_LICENSE_MIT_X11,
- NULL);
-}
-
static void
on_category_selected(GtkListBox *box, GtkListBoxRow *row, gpointer user_data)
{
@@ -42,21 +35,28 @@ on_category_selected(GtkListBox *box, GtkListBoxRow *row, gpointer user_data)
}
printf("Test\n");
FlashcardsAppWindow *win = FLASHCARDS_APP_WINDOW(gtk_widget_get_root(GTK_WIDGET(box)));
- adw_leaflet_navigate(win->leaflet, ADW_NAVIGATION_DIRECTION_FORWARD);
+ adw_navigation_split_view_set_show_content(ADW_NAVIGATION_SPLIT_VIEW(win->split_view), TRUE);
int id = gtk_list_box_row_get_index(gtk_list_box_get_selected_row(win->topics));
printf("%d\n", id);
-
- show_about (GTK_WINDOW(gtk_widget_get_root (GTK_WIDGET (box))));
}
static void
-on_navigate_back(GtkButton *button, gpointer user_data)
+on_add_category(GtkButton *self,
+ gpointer user_data)
{
- printf("Test2\n");
- FlashcardsAppWindow *win = FLASHCARDS_APP_WINDOW(gtk_widget_get_root(GTK_WIDGET(button)));
- gtk_list_box_unselect_all(win->topics);
- adw_leaflet_navigate(win->leaflet, ADW_NAVIGATION_DIRECTION_BACK);
+ FlashcardsCreateCategoryDialog *dialog = flashcards_create_category_dialog_new(user_data);
+ adw_dialog_present(ADW_DIALOG(dialog), GTK_WIDGET(user_data));
+}
+
+void flashcards_app_window_test(FlashcardsAppWindow *win, const gchar *test)
+{
+ database_save_category(test);
+
+ GtkWidget *child = adw_action_row_new();
+ adw_preferences_row_set_title(ADW_PREFERENCES_ROW(child), test);
+
+ gtk_list_box_append(GTK_LIST_BOX(win->topics), child);
}
static void
@@ -87,12 +87,14 @@ 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, leaflet);
- gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, leaflet_previous);
+ gtk_widget_class_bind_template_child(GTK_WIDGET_CLASS(class), FlashcardsAppWindow, split_view);
+ 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, topics);
- gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_navigate_back);
gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_category_selected);
+ gtk_widget_class_bind_template_callback(GTK_WIDGET_CLASS(class), on_add_category);
}
FlashcardsAppWindow *
diff --git a/src/flashcardsappwin.h b/src/flashcardsappwin.h
index 88aff90..d3bf7f1 100644
--- a/src/flashcardsappwin.h
+++ b/src/flashcardsappwin.h
@@ -11,5 +11,6 @@ G_DECLARE_FINAL_TYPE(FlashcardsAppWindow, flashcards_app_window, FLASHCARDS, APP
FlashcardsAppWindow *flashcards_app_window_new(FlashcardsApp *app);
void flashcards_app_window_open(FlashcardsAppWindow *win,
GFile *file);
+void flashcards_app_window_test(FlashcardsAppWindow *win, const gchar *test);
#endif /* __FLASHCARDSAPPWIN_H */
diff --git a/src/main.c b/src/main.c
index 7e9924b..7352319 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,4 +1,4 @@
-#define GETTEXT_PACKAGE "flashcards"
+#include "config.h"
#include
#include
@@ -6,12 +6,11 @@
#include "flashcardsapp.h"
-int
-main (int argc, char *argv[])
+int main(int argc, char *argv[])
{
- bindtextdomain (GETTEXT_PACKAGE, "/usr/local/share/locale");
- 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);
}
diff --git a/src/meson.build b/src/meson.build
index 3d272df..f4c09ff 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,5 +1,6 @@
sourcefiles = files('main.c',
'flashcardsapp.c',
'flashcardsappwin.c',
+ 'create-category.c',
'database.c'
)
\ No newline at end of file