From b4d8f9d0961b52e96e5c21cf8d3d0a95140ef220 Mon Sep 17 00:00:00 2001 From: Sophie Krause Date: Wed, 5 Feb 2025 20:52:07 +0100 Subject: [PATCH] replace deprecated classes, update code, fix errors, add missing stuff --- .gitignore | 3 +- docs/BO_Logo.svg | 44 ++++++++ docs/main.typ | 18 ++++ docs/template.typ | 100 +++++++++++++++++ gitlab-ci.yml | 7 ++ li.sopht.Flashcards.json | 51 +++++++++ meson.build | 102 ++++++++++++++++-- po/POTFILES | 6 +- po/de.po | 46 ++++++-- po/en.po | 40 +++++-- po/flashcards.pot | 26 +++-- po/meson.build | 2 - resources/flashcards.gresource.xml | 1 + .../scalable/apps}/li.sopht.Flashcards.svg | 0 .../apps/li.sopht.Flashcards-symbolic.svg | 1 + resources/icons/meson.build | 13 +++ resources/li.sopht.Flashcards.desktop.in | 9 ++ resources/li.sopht.Flashcards.gschema.xml | 5 + resources/meson.build | 33 ++++-- resources/ui/create-category.blp | 20 ++++ resources/ui/meson.build | 8 ++ resources/ui/window.blp | 100 +++++++++++++++++ resources/window.blp | 102 ------------------ src/create-category.c | 56 ++++++++++ src/create-category.h | 14 +++ src/database.c | 23 +++- src/flashcardsapp.c | 53 ++++++++- src/flashcardsappwin.c | 52 ++++----- src/flashcardsappwin.h | 1 + src/main.c | 13 ++- src/meson.build | 1 + 31 files changed, 767 insertions(+), 183 deletions(-) create mode 100644 docs/BO_Logo.svg create mode 100644 docs/main.typ create mode 100644 docs/template.typ create mode 100644 gitlab-ci.yml create mode 100644 li.sopht.Flashcards.json rename resources/{ => icons/hicolor/scalable/apps}/li.sopht.Flashcards.svg (100%) create mode 100644 resources/icons/hicolor/symbolic/apps/li.sopht.Flashcards-symbolic.svg create mode 100644 resources/icons/meson.build create mode 100644 resources/li.sopht.Flashcards.desktop.in create mode 100644 resources/li.sopht.Flashcards.gschema.xml create mode 100644 resources/ui/create-category.blp create mode 100644 resources/ui/meson.build create mode 100644 resources/ui/window.blp delete mode 100644 resources/window.blp create mode 100644 src/create-category.c create mode 100644 src/create-category.h 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