From 82c09a22f21925bb77b840bc7e9375780f63839d Mon Sep 17 00:00:00 2001 From: Leonhard Date: Tue, 28 Nov 2023 22:50:12 +0100 Subject: [PATCH 01/29] Introduce a window and a subject page class --- meson.build | 4 +- src/application.vala | 431 +++++++++++++++++++----------------------- src/subject-page.vala | 121 ++++++++++++ src/window.vala | 51 +++++ 4 files changed, 372 insertions(+), 235 deletions(-) create mode 100644 src/subject-page.vala create mode 100644 src/window.vala diff --git a/meson.build b/meson.build index cd113ae..5d03d80 100644 --- a/meson.build +++ b/meson.build @@ -43,7 +43,9 @@ executable( 'src' / 'edit-subject-button.vala', 'src' / 'edit-subject-dialog.vala', 'src' / 'add-category-dialog.vala', + 'src' / 'subject-page.vala', 'src' / 'subject-parser.vala', + 'src' / 'window.vala', dependencies: [ dependency('gtk4'), dependency('libadwaita-1'), @@ -88,4 +90,4 @@ install_data( 'data' / 'user-trash-symbolic.svg', install_dir: get_option('datadir') / 'icons' / 'hicolor' / 'symbolic' / 'apps', rename: 'user-trash-symbolic.svg' - ) \ No newline at end of file + ) diff --git a/src/application.vala b/src/application.vala index e4cf978..766cc1b 100644 --- a/src/application.vala +++ b/src/application.vala @@ -2,14 +2,10 @@ public class MyApp : Adw.Application { private int number_of_subjects = 20; private Subject[] subjects; private Adw.ToolbarView[] subject_boxes; - private Adw.ApplicationWindow main_window; + private Window main_window; private Gtk.Label[] avg; - private Adw.OverlaySplitView main_box; - private Adw.HeaderBar header_bar; private Gtk.ToggleButton toggle_button; - private Adw.Breakpoint bpoint; private Gtk.Box[] nyabox; - private Gtk.Stack stack; private EditSubjectButton edit_subject_button; @@ -289,241 +285,227 @@ public class MyApp : Adw.Application { - public void window_stack_ui (int index) { - /*if (stack_box.get_last_child ().get_type () == typeof(Adw.ToolbarView)) { - stack_box.remove (stack_box.get_last_child()); - }*/ - stack = new Gtk.Stack (); + public void window_stack_ui (int index) {} + // /*if (stack_box.get_last_child ().get_type () == typeof(Adw.ToolbarView)) { + // stack_box.remove (stack_box.get_last_child()); + // }*/ + // stack = new Gtk.Stack (); - debug (subjects[0].name); - if (subjects[0].name == null) { - var stack_box = new Adw.ToolbarView (); - var header_bar = new Adw.HeaderBar (); + // debug (subjects[0].name); + // if (subjects[0].name == null) { + // var stack_box = new Adw.ToolbarView (); + // var header_bar = new Adw.HeaderBar (); - //PRIMARY MENU - var menu_button = new Gtk.MenuButton () { - icon_name = "open-menu-symbolic" - }; - header_bar.pack_end (menu_button); + // //PRIMARY MENU + // var menu_button = new Gtk.MenuButton () { + // icon_name = "open-menu-symbolic" + // }; + // header_bar.pack_end (menu_button); - var menu = new Menu (); - var menu_section1 = new Menu (); - var menu_section2 = new Menu (); - menu.append_section (null, menu_section1); - menu.append_section (null, menu_section2); + // var menu = new Menu (); + // var menu_section1 = new Menu (); + // var menu_section2 = new Menu (); + // menu.append_section (null, menu_section1); + // menu.append_section (null, menu_section2); - var preferences_item = new MenuItem (_("_Help"), "app.help"); - menu_section1.append_item (preferences_item); + // var preferences_item = new MenuItem (_("_Help"), "app.help"); + // menu_section1.append_item (preferences_item); - var about_item = new MenuItem (_("_About Gradebook"), "app.about"); - menu_section2.append_item (about_item); + // var about_item = new MenuItem (_("_About Gradebook"), "app.about"); + // menu_section2.append_item (about_item); + + + // var menu_popover = new Gtk.PopoverMenu.from_model (menu); + // menu_button.set_popover (menu_popover); + + // toggle_button = new Gtk.ToggleButton () { + // icon_name = "dock-left-symbolic", + // tooltip_text = _("Toggle Sidebar"), + // visible = false + // }; + // toggle_button.bind_property ("active", main_box, "show_sidebar", BindingFlags.BIDIRECTIONAL); + // bpoint.add_setter (toggle_button, "visible", true); + + // header_bar.pack_start (toggle_button); + + // var new_menu_button = new Gtk.Button () { + // icon_name = "list-add-symbolic", + // action_name = "app.newsubject", + // tooltip_text = _("Add a New Subject") + // }; + + // header_bar.pack_start (new_menu_button); + + // stack_box.add_top_bar (header_bar); + + // var placeholderlabel = new Adw.StatusPage () { + // vexpand = true, + // hexpand = true, + // title = _("No Subjects"), + // description = _("Add new subjects using the “+” button in the top left corner.") + // }; + // stack_box.set_content (placeholderlabel); + // stack.add_titled (stack_box , "no_subjects_placeholder", _("Gradebook")); + // } else { + + // //Create StackPages for every subject + // for( int i = 0; subjects[i] != null; i++) + // { + + // subject_boxes[i] = new Adw.ToolbarView (); + // var header_bar = new Adw.HeaderBar (); + + // //PRIMARY MENU + // var menu_button = new Gtk.MenuButton () { + // icon_name = "open-menu-symbolic" + // }; + // header_bar.pack_end (menu_button); + + // var menu = new Menu (); + // var menu_section1 = new Menu (); + // var menu_section2 = new Menu (); + // menu.append_section (null, menu_section1); + // menu.append_section (null, menu_section2); + + // var preferences_item = new MenuItem (_("_Help"), "app.help"); + // menu_section1.append_item (preferences_item); + + // var about_item = new MenuItem (_("_About Gradebook"), "app.about"); + // menu_section2.append_item (about_item); + + + // var menu_popover = new Gtk.PopoverMenu.from_model (menu); + // menu_button.set_popover (menu_popover); + + // toggle_button = new Gtk.ToggleButton () { + // icon_name = "dock-left-symbolic", + // tooltip_text = _("Toggle Sidebar"), + // visible = false + // }; + // toggle_button.bind_property ("active", main_box, "show_sidebar", BindingFlags.BIDIRECTIONAL); + // bpoint.add_setter (toggle_button, "visible", true); + + // header_bar.pack_start (toggle_button); + + // var new_menu_button = new Gtk.Button () { + // icon_name = "list-add-symbolic", + // action_name = "app.newsubject", + // tooltip_text = _("Add a New Subject") + // }; + + // header_bar.pack_start (new_menu_button); + + // // edit subject button + // edit_subject_button = new EditSubjectButton () { + // icon_name = "document-edit-symbolic" + // }; + // header_bar.pack_end (edit_subject_button); + + // subject_boxes[i].add_top_bar (header_bar); + + // //SUBJECT BOX + // var nyttbox = new Gtk.Box (VERTICAL, 0) { + // vexpand = true, + // margin_start = 1, + // margin_end = 1 + // }; + // var gtk_sw = new Gtk.ScrolledWindow (); + // var adw_c = new Adw.Clamp () { + // margin_start = 19, + // margin_end = 19, + // margin_top = 20, + // margin_bottom = 20, + // maximum_size = 600, + // tightening_threshold = 400 + // }; + // gtk_sw.set_child (adw_c); + // adw_c.set_child (nyttbox); + // //TOP BOX + // var top_box = new Gtk.Box (HORIZONTAL, 0) { + // height_request = 40, + // hexpand = true, + // homogeneous = true + // }; + // nyttbox.append (top_box); - var menu_popover = new Gtk.PopoverMenu.from_model (menu); - menu_button.set_popover (menu_popover); + // //AVERAGE LABEL + // var average_box = new Gtk.Box (HORIZONTAL, 10) { + // halign = START + // }; + // top_box.append (average_box); - toggle_button = new Gtk.ToggleButton () { - icon_name = "dock-left-symbolic", - tooltip_text = _("Toggle Sidebar"), - visible = false - }; - toggle_button.bind_property ("active", main_box, "show_sidebar", BindingFlags.BIDIRECTIONAL); - bpoint.add_setter (toggle_button, "visible", true); + // var average_label = new Gtk.Label (_("Average:")) { css_classes = { "title-3" } }; + // average_box.append (average_label); - header_bar.pack_start (toggle_button); + // avg[i] = new Gtk.Label ("0.00") { css_classes = { "title-3" } }; + // average_box.append (avg[i]); - var new_menu_button = new Gtk.Button () { - icon_name = "list-add-symbolic", - action_name = "app.newsubject", - tooltip_text = _("Add a New Subject") - }; - header_bar.pack_start (new_menu_button); - stack_box.add_top_bar (header_bar); + // //NEW GRADE BUTTON + // var new_grade_button = new NewGradeButton (i) { + // icon_name = "add-list-symbolic" + // }; + // new_grade_button.halign = END; + // new_grade_button.label = _("New Grade…"); + // new_grade_button.add_css_class ("suggested-action"); + // new_grade_button.add_css_class ("pill"); - var placeholderlabel = new Adw.StatusPage () { - vexpand = true, - hexpand = true, - title = _("No Subjects"), - description = _("Add new subjects using the “+” button in the top left corner.") - }; - stack_box.set_content (placeholderlabel); - stack.add_titled (stack_box , "no_subjects_placeholder", _("Gradebook")); - } else { - - //Create StackPages for every subject - for( int i = 0; subjects[i] != null; i++) - { - - subject_boxes[i] = new Adw.ToolbarView (); - var header_bar = new Adw.HeaderBar (); - - //PRIMARY MENU - var menu_button = new Gtk.MenuButton () { - icon_name = "open-menu-symbolic" - }; - header_bar.pack_end (menu_button); - - var menu = new Menu (); - var menu_section1 = new Menu (); - var menu_section2 = new Menu (); - menu.append_section (null, menu_section1); - menu.append_section (null, menu_section2); - - var preferences_item = new MenuItem (_("_Help"), "app.help"); - menu_section1.append_item (preferences_item); - - var about_item = new MenuItem (_("_About Gradebook"), "app.about"); - menu_section2.append_item (about_item); - - - var menu_popover = new Gtk.PopoverMenu.from_model (menu); - menu_button.set_popover (menu_popover); - - toggle_button = new Gtk.ToggleButton () { - icon_name = "dock-left-symbolic", - tooltip_text = _("Toggle Sidebar"), - visible = false - }; - toggle_button.bind_property ("active", main_box, "show_sidebar", BindingFlags.BIDIRECTIONAL); - bpoint.add_setter (toggle_button, "visible", true); - - header_bar.pack_start (toggle_button); - - var new_menu_button = new Gtk.Button () { - icon_name = "list-add-symbolic", - action_name = "app.newsubject", - tooltip_text = _("Add a New Subject") - }; - - header_bar.pack_start (new_menu_button); - - // edit subject button - edit_subject_button = new EditSubjectButton () { - icon_name = "document-edit-symbolic" - }; - header_bar.pack_end (edit_subject_button); - - subject_boxes[i].add_top_bar (header_bar); - - //SUBJECT BOX - var nyttbox = new Gtk.Box (VERTICAL, 0) { - vexpand = true, - margin_start = 1, - margin_end = 1 - }; - var gtk_sw = new Gtk.ScrolledWindow (); - var adw_c = new Adw.Clamp () { - margin_start = 19, - margin_end = 19, - margin_top = 20, - margin_bottom = 20, - maximum_size = 600, - tightening_threshold = 400 - }; - gtk_sw.set_child (adw_c); - adw_c.set_child (nyttbox); - - //TOP BOX - var top_box = new Gtk.Box (HORIZONTAL, 0) { - height_request = 40, - hexpand = true, - homogeneous = true - }; - nyttbox.append (top_box); - - //AVERAGE LABEL - var average_box = new Gtk.Box (HORIZONTAL, 10) { - halign = START - }; - top_box.append (average_box); - - var average_label = new Gtk.Label (_("Average:")) { css_classes = { "title-3" } }; - average_box.append (average_label); - - avg[i] = new Gtk.Label ("0.00") { css_classes = { "title-3" } }; - average_box.append (avg[i]); - - - - //NEW GRADE BUTTON - var new_grade_button = new NewGradeButton (i) { - icon_name = "add-list-symbolic" - }; - new_grade_button.halign = END; - new_grade_button.label = _("New Grade…"); - new_grade_button.add_css_class ("suggested-action"); - new_grade_button.add_css_class ("pill"); - - top_box.append (new_grade_button); + // top_box.append (new_grade_button); - /*//FILL BOX - var fill_box = new Gtk.Box (VERTICAL, 0) { - margin_end = 20, - margin_start = 20, - vexpand = true, - hexpand = true - }; - subject_boxes[i].append (fill_box); - - //DELETE SUBJECT BUTTON - var bottom_box = new Gtk.Box (HORIZONTAL, 0) { - margin_end = 20, - margin_start = 20, - margin_bottom = 20, - hexpand = true, - homogeneous = true - }; - subject_boxes[i].append (bottom_box); + // /*//FILL BOX + // var fill_box = new Gtk.Box (VERTICAL, 0) { + // margin_end = 20, + // margin_start = 20, + // vexpand = true, + // hexpand = true + // }; + // subject_boxes[i].append (fill_box); - var bottom_end_box = new Gtk.Box (HORIZONTAL, 0) {halign = END}; - bottom_box.append (bottom_end_box);*/ + // //DELETE SUBJECT BUTTON + // var bottom_box = new Gtk.Box (HORIZONTAL, 0) { + // margin_end = 20, + // margin_start = 20, + // margin_bottom = 20, + // hexpand = true, + // homogeneous = true + // }; + // subject_boxes[i].append (bottom_box); - //CALL LISTBOX WITH GRADES + // var bottom_end_box = new Gtk.Box (HORIZONTAL, 0) {halign = END}; + // bottom_box.append (bottom_end_box);*/ - subject_boxes[i].set_content (gtk_sw); - window_grade_rows_ui (i, nyttbox); - nyabox[i] = nyttbox; + // //CALL LISTBOX WITH GRADES + // subject_boxes[i].set_content (gtk_sw); + // window_grade_rows_ui (i, nyttbox); + // nyabox[i] = nyttbox; - //add SUBJECT BOX to stackpage - stack.add_titled (subject_boxes[i], subjects[i].name, subjects[i].name); + // //add SUBJECT BOX to stackpage + // stack.add_titled (subject_boxes[i], subjects[i].name, subjects[i].name); - //CONNECT BUTTONS - new_grade_button.clicked.connect (() => { - new_grade_dialog (new_grade_button.index); - }); - edit_subject_button.index = i; + // //CONNECT BUTTONS + // new_grade_button.clicked.connect (() => { + // new_grade_dialog (new_grade_button.index); + // }); - edit_subject_button.clicked.connect (() => { - edit_subject_dialog (edit_subject_button.index); - }); + // edit_subject_button.index = i; + // edit_subject_button.clicked.connect (() => { + // edit_subject_dialog (edit_subject_button.index); + // }); - } - stack.set_visible_child_name (subjects[index].name); + // } - } + // stack.set_visible_child_name (subjects[index].name); - //Create Stack Sidebar - var box = new Adw.ToolbarView (); - var hb = new Adw.HeaderBar () {hexpand = true}; - var sw = new Gtk.ScrolledWindow () {vexpand = true}; - var sidebar = new Gtk.StackSidebar (); - sidebar.set_css_classes ({ "" }); - sidebar.set_stack (stack); - sw.set_child (sidebar); - box.add_top_bar (hb); - box.set_content (sw); - main_box.set_sidebar (box); - - main_box.set_content (stack); - } + // } + // } @@ -640,31 +622,12 @@ public class MyApp : Adw.Application { protected override void activate () { - main_window = new Adw.ApplicationWindow (this) { - default_height = 600, - default_width = 900, - width_request = 360, - height_request = 360, - title = _("Gradebook") - }; + main_window = new Window (this); //Variables - read_data (); - subject_boxes = new Adw.ToolbarView[number_of_subjects]; - nyabox = new Gtk.Box[number_of_subjects]; - avg = new Gtk.Label[number_of_subjects]; - - //WINDOW UI ------------------------------------------------------------------------------------------------------------------------------- - //Declare main box - main_box = new Adw.OverlaySplitView (); - main_window.set_content (main_box); - - bpoint = new Adw.Breakpoint (Adw.BreakpointCondition.parse ("max-width: 530px")); - bpoint.add_setter (main_box, "show_sidebar", false); - bpoint.add_setter (main_box, "collapsed", true); - main_window.add_breakpoint (bpoint); - - window_stack_ui (0); + // read_data (); + + // window_stack_ui (0); //PRESENT WINDOW main_window.present (); diff --git a/src/subject-page.vala b/src/subject-page.vala new file mode 100644 index 0000000..3515d47 --- /dev/null +++ b/src/subject-page.vala @@ -0,0 +1,121 @@ +public class SubjectPage : Gtk.Box { + public Subject subject { get; construct; } + + public SubjectPage (Subject subject) { + Object (subject: subject); + } + + construct { + var menu = new Menu (); + var menu_section1 = new Menu (); + var menu_section2 = new Menu (); + menu.append_section (null, menu_section1); + menu.append_section (null, menu_section2); + + var preferences_item = new MenuItem (_("_Help"), "app.help"); + menu_section1.append_item (preferences_item); + + var about_item = new MenuItem (_("_About Gradebook"), "app.about"); + menu_section2.append_item (about_item); + + var menu_button = new Gtk.MenuButton () { + icon_name = "open-menu-symbolic", + menu_model = menu + }; + + var toggle_button = new Gtk.ToggleButton () { + icon_name = "dock-left-symbolic", + tooltip_text = _("Toggle Sidebar"), + visible = false + }; + // toggle_button.bind_property ("active", ((Window) get_root ()).split_view, "show_sidebar", BindingFlags.BIDIRECTIONAL); + // ((Window) get_root ()).bpoint.add_setter (toggle_button, "visible", true); + + // var new_menu_button = new Gtk.Button () { + // icon_name = "list-add-symbolic", + // action_name = "app.newsubject", + // tooltip_text = _("Add a New Subject") + // }; + + var edit_subject_button = new Gtk.Button () { + icon_name = "document-edit-symbolic" + }; + + var header_bar = new Adw.HeaderBar (); + header_bar.pack_end (menu_button); + header_bar.pack_end (edit_subject_button); + + header_bar.pack_start (toggle_button); + // header_bar.pack_start (new_menu_button); + + //SUBJECT BOX + var nyttbox = new Gtk.Box (VERTICAL, 0) { + vexpand = true, + margin_start = 1, + margin_end = 1 + }; + var gtk_sw = new Gtk.ScrolledWindow (); + var adw_c = new Adw.Clamp () { + margin_start = 19, + margin_end = 19, + margin_top = 20, + margin_bottom = 20, + maximum_size = 600, + tightening_threshold = 400 + }; + gtk_sw.set_child (adw_c); + adw_c.set_child (nyttbox); + + //TOP BOX + var top_box = new Gtk.Box (HORIZONTAL, 0) { + height_request = 40, + hexpand = true, + homogeneous = true + }; + nyttbox.append (top_box); + + //AVERAGE LABEL + var average_box = new Gtk.Box (HORIZONTAL, 10) { + halign = START + }; + top_box.append (average_box); + + var average_label = new Gtk.Label (_("Average:")) { css_classes = { "title-3" } }; + average_box.append (average_label); + + var avg_label = new Gtk.Label ("0.00") { css_classes = { "title-3" } }; + average_box.append (avg_label); + + //NEW GRADE BUTTON + var new_grade_button = new NewGradeButton (0) { + icon_name = "add-list-symbolic" + }; + new_grade_button.halign = END; + new_grade_button.label = _("New Grade…"); + new_grade_button.add_css_class ("suggested-action"); + new_grade_button.add_css_class ("pill"); + + top_box.append (new_grade_button); + + var toolbar_view = new Adw.ToolbarView () { + hexpand = true, + content = gtk_sw + }; + toolbar_view.add_top_bar (header_bar); + append (toolbar_view); + // window_grade_rows_ui (i, nyttbox); + + //add SUBJECT BOX to stackpage + // stack.add_titled (subject_boxes[i], subjects[i].name, subjects[i].name); + + + //CONNECT BUTTONS + // new_grade_button.clicked.connect (() => { + // // new_grade_dialog (new_grade_button.index); + // }); + + // edit_subject_button.clicked.connect (() => { + // // edit_subject_dialog (edit_subject_button.index); + // }); + } +} diff --git a/src/window.vala b/src/window.vala new file mode 100644 index 0000000..ddae066 --- /dev/null +++ b/src/window.vala @@ -0,0 +1,51 @@ +public class Window : Adw.ApplicationWindow { + public Adw.OverlaySplitView split_view; + public Adw.Breakpoint bpoint; + private Gtk.Stack stack; + + public Window (MyApp app) { + Object ( + default_height: 600, + default_width: 900, + width_request: 360, + height_request: 360, + title: _("Gradebook"), + application: app + ); + } + + construct { + stack = new Gtk.Stack (); + + var header_bar = new Adw.HeaderBar () { hexpand = true }; + + var stack_sidebar = new Gtk.StackSidebar () { + stack = stack + }; + stack_sidebar.set_css_classes ({ "" }); + + var scrolled_window = new Gtk.ScrolledWindow () { + vexpand = true, + child = stack_sidebar + }; + + var sidebar = new Adw.ToolbarView () { + content = scrolled_window + }; + sidebar.add_top_bar (header_bar); + + split_view = new Adw.OverlaySplitView () { + sidebar = sidebar, + content = stack + }; + + bpoint = new Adw.Breakpoint (Adw.BreakpointCondition.parse ("max-width: 530px")); + bpoint.add_setter (split_view, "show_sidebar", false); + bpoint.add_setter (split_view, "collapsed", true); + add_breakpoint (bpoint); + + content = split_view; + + stack.add_titled (new SubjectPage (new Subject ("English")), "English", "English"); + } +} From 50ca8f0d2e91679684413575166903b62106eecb Mon Sep 17 00:00:00 2001 From: Leonhard Date: Tue, 28 Nov 2023 23:48:46 +0100 Subject: [PATCH 02/29] Works a bit better now --- meson.build | 1 + src/application.vala | 116 ++++++++------------ src/edit-subject-dialog.vala | 118 +++++++++------------ src/new-grade-dialog.vala | 22 ++-- src/subject-page.vala | 199 +++++++++++++++++++++++++++++++++-- src/subject-parser.vala | 72 +++++-------- src/subject.vala | 8 ++ src/window.vala | 8 +- 8 files changed, 337 insertions(+), 207 deletions(-) diff --git a/meson.build b/meson.build index 5d03d80..a7ef02b 100644 --- a/meson.build +++ b/meson.build @@ -43,6 +43,7 @@ executable( 'src' / 'edit-subject-button.vala', 'src' / 'edit-subject-dialog.vala', 'src' / 'add-category-dialog.vala', + 'src' / 'subject-manager.vala', 'src' / 'subject-page.vala', 'src' / 'subject-parser.vala', 'src' / 'window.vala', diff --git a/src/application.vala b/src/application.vala index 766cc1b..c9895b1 100644 --- a/src/application.vala +++ b/src/application.vala @@ -143,18 +143,18 @@ public class MyApp : Adw.Application { public void read_data () { - subjects = new Subject[number_of_subjects]; + subjects = new Subject[number_of_subjects]; - for (int i = 0; i < subjects.length && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { - File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); - - var parser = new SubjectParser (); - Subject sub = parser.to_object (read_from_file (file)); - subjects[i] = sub; - } + for (int i = 0; i < subjects.length && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { + File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); + var parser = new SubjectParser (); + Subject sub = parser.to_object (read_from_file (file)); + subjects[i] = sub; } + } + public void write_data () { int z = 0; File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); @@ -186,24 +186,24 @@ public class MyApp : Adw.Application { - public void new_grade (int index, string grade, string note, int c) { - bool worked = false; + // public void new_grade (int index, string grade, string note, int c) { + // bool worked = false; - for (int i = 0; i < subjects[index].grades.length; i++) { - if (subjects[index].grades[i] == null) { - subjects[index].grades[i] = new Grade (grade, note, c); - i = subjects[index].grades.length; - worked = true; - } - } + // for (int i = 0; i < subjects[index].grades.length; i++) { + // if (subjects[index].grades[i] == null) { + // subjects[index].grades[i] = new Grade (grade, note, c); + // i = subjects[index].grades.length; + // worked = true; + // } + // } - if (worked == false) { - print ("no more grades available"); - } else { - window_grade_rows_ui (index); - } - } + // if (worked == false) { + // print ("no more grades available"); + // } else { + // window_grade_rows_ui (index); + // } + // } @@ -230,59 +230,25 @@ public class MyApp : Adw.Application { - public void new_grade_dialog (int index) { - - if (subjects[index].categories[0] != null){ - var dialog = new NewGradeDialog (main_window, subjects, index); - - dialog.response.connect ((response_id) => { - if (response_id == "add") { - dialog.set_variables (); - new_grade (index, dialog.get_grade (), dialog.get_note (), (int) dialog.choose_cat_row.get_selected ()); - } - dialog.destroy (); - }); - dialog.present (); - } else { - var ErrorDialog = new Adw.MessageDialog (main_window, _("Error"), _("This subject has no categories. Add at least one category in order to add a grade.")); - ErrorDialog.add_css_class ("error"); - ErrorDialog.add_response ("ok", _("OK")); - ErrorDialog.present (); - } - } - - - - public void edit_subject_dialog (int index) { - var dialog = new EditSubjectDialog (main_window, subjects[index], this); - - dialog.close_request.connect ((response_id) => { - if (dialog.accept) { - if (dialog.subject != null) { - subjects[index] = dialog.subject; - } else { - subjects[index] = null; - - for (int i = index; i < subjects.length - 1; i++) { - subjects[i] = subjects[i + 1]; - } - - subjects[subjects.length - 1] = null; - - if (subjects[index] != null) { - window_stack_ui (index); - } else { - window_stack_ui (index - 1); - } - } - } - dialog.destroy (); - return true; - }); - dialog.present (); - } - + // public void new_grade_dialog (int index) { + // if (subjects[index].categories[0] != null){ + // var dialog = new NewGradeDialog (main_window, subjects, index); + // dialog.response.connect ((response_id) => { + // if (response_id == "add") { + // dialog.set_variables (); + // new_grade (index, dialog.get_grade (), dialog.get_note (), (int) dialog.choose_cat_row.get_selected ()); + // } + // dialog.destroy (); + // }); + // dialog.present (); + // } else { + // var ErrorDialog = new Adw.MessageDialog (main_window, _("Error"), _("This subject has no categories. Add at least one category in order to add a grade.")); + // ErrorDialog.add_css_class ("error"); + // ErrorDialog.add_response ("ok", _("OK")); + // ErrorDialog.present (); + // } + // } public void window_stack_ui (int index) {} diff --git a/src/edit-subject-dialog.vala b/src/edit-subject-dialog.vala index 4f4447d..6b63d00 100644 --- a/src/edit-subject-dialog.vala +++ b/src/edit-subject-dialog.vala @@ -3,11 +3,11 @@ public class EditSubjectDialog : Adw.Window { public Gtk.Box main_box; public Adw.EntryRow name_entry_box; private Gtk.Button new_cat_button; - private Gtk.Button subject_delete_button; + private Gtk.Button subject_delete_button; public bool accept = false; -public Subject subject; + public Subject subject; - public EditSubjectDialog (Adw.ApplicationWindow parent, Subject s, Adw.Application app) { + public EditSubjectDialog (Adw.ApplicationWindow parent, Subject s) { Object ( modal: true, title: _("Edit Subject"), @@ -18,64 +18,64 @@ public Subject subject; height_request: 360 ); - subject = s; + subject = s; categories = new Category[5]; - var tbv = new Adw.ToolbarView (); - this.set_content (tbv); + var tbv = new Adw.ToolbarView (); + this.set_content (tbv); - var hb = new Adw.HeaderBar () { - show_end_title_buttons = false, - show_start_title_buttons = false, - }; + var hb = new Adw.HeaderBar () { + show_end_title_buttons = false, + show_start_title_buttons = false, + }; - var cb = new Gtk.Button.with_label (_("Cancel")); - cb.clicked.connect (() => { - accept = false; - this.close (); - }); + var cb = new Gtk.Button.with_label (_("Cancel")); + cb.clicked.connect (() => { + accept = false; + this.close (); + }); - var ab = new Gtk.Button.with_label (_("Save")) { css_classes = { "suggested-action" } }; - ab.clicked.connect (() => { - accept = true; - this.close (); - }); + var ab = new Gtk.Button.with_label (_("Save")) { css_classes = { "suggested-action" } }; + ab.clicked.connect (() => { + accept = true; + this.close (); + }); - hb.pack_start (cb); - hb.pack_end (ab); + hb.pack_start (cb); + hb.pack_end (ab); - tbv.add_top_bar (hb); + tbv.add_top_bar (hb); Adw.Clamp ac = new Adw.Clamp () { - margin_start = 19, - margin_end = 19, - maximum_size = 500, - tightening_threshold = 400 - }; - - var sw = new Gtk.ScrolledWindow (); - main_box = new Gtk.Box (VERTICAL, 0) { - margin_top = 20, - margin_bottom = 20 - }; - tbv.set_content (sw); - - this.set_content (tbv); - sw.set_child (ac); - ac.set_child (main_box); + margin_start = 19, + margin_end = 19, + maximum_size = 500, + tightening_threshold = 400 + }; + + var sw = new Gtk.ScrolledWindow (); + main_box = new Gtk.Box (VERTICAL, 0) { + margin_top = 20, + margin_bottom = 20 + }; + tbv.set_content (sw); + + this.set_content (tbv); + sw.set_child (ac); + ac.set_child (main_box); load_list (); - subject_delete_button = new Gtk.Button.with_label (_("Delete Subject…")) { hexpand = false, halign = Gtk.Align.START, margin_top = 20 }; + subject_delete_button = new Gtk.Button.with_label (_("Delete Subject…")) { hexpand = false, halign = Gtk.Align.START, margin_top = 20 }; subject_delete_button.add_css_class ("destructive-action"); - main_box.append (subject_delete_button); + main_box.append (subject_delete_button); subject_delete_button.clicked.connect (() => { string n = s.name; ///TRANSLATORS: %s is the name of a school subject var message_dialog = new Adw.MessageDialog( this, _("Delete %s?").printf( n), null); - message_dialog.set_body (_("If you delete %s, its information will be deleted permanently.").printf( n)); + message_dialog.set_body (_("If you delete %s, its information will be deleted permanently.").printf( n)); message_dialog.add_response ("0", _("Cancel")); message_dialog.add_response ("1", _("Delete")); message_dialog.set_response_appearance ("1", DESTRUCTIVE); @@ -92,28 +92,6 @@ public Subject subject; } }); }); - /*var cat_list_box = new Gtk.ListBox (); - cat_list_box.add_css_class("boxed-list"); - - var scroll_main_box = new Gtk.ScrolledWindow () { - margin_bottom = 20, - margin_top = 20, - margin_start = 20, - margin_end = 20, - hexpand = true, - vexpand = true - }; - scroll_main_box.set_child(cat_list_box); - main_box.append(scroll_main_box); - - - for (int i = 0; i < subject.categories.length && subject.categories[i] != null; i++) { - var cat_row = new Adw.ActionRow () { - title = subject.categories[i].name, - subtitle = subject.categories[i].percentage.to_string () + "%" - }; - cat_list_box.append(cat_row); - }*/ } public void add_cat (string n, double p) { @@ -127,8 +105,8 @@ public Subject subject; } public void load_list () { - main_box.remove (main_box.get_first_child ()); - main_box.remove (main_box.get_first_child ()); + main_box.remove (main_box.get_first_child ()); + main_box.remove (main_box.get_first_child ()); var cat_list_box = new Adw.PreferencesGroup () { margin_start = 1, @@ -138,13 +116,13 @@ public Subject subject; title = _("Subject Categories"), }; - new_cat_button = new Gtk.Button () { + new_cat_button = new Gtk.Button () { icon_name = "list-add-symbolic", tooltip_text = _("Add New Category"), css_classes = { "flat" } }; - new_cat_button.clicked.connect (() => { + new_cat_button.clicked.connect (() => { var dialog = new AddCategoryDialog (this); dialog.response.connect ((response_id) => { @@ -157,10 +135,10 @@ public Subject subject; dialog.present (); }); - cat_list_box.set_header_suffix (new_cat_button); + cat_list_box.set_header_suffix (new_cat_button); main_box.append (cat_list_box); - main_box.append (subject_delete_button); + main_box.append (subject_delete_button); for (int i = 0; i < subject.categories.length && subject.categories[i] != null; i++) { var cat_row = new Adw.ActionRow () { diff --git a/src/new-grade-dialog.vala b/src/new-grade-dialog.vala index 5b3f139..bfaa12f 100644 --- a/src/new-grade-dialog.vala +++ b/src/new-grade-dialog.vala @@ -6,7 +6,7 @@ public class NewGradeDialog : Adw.MessageDialog { //private Adw.EntryRow note_entry; public Adw.ComboRow choose_cat_row; - public NewGradeDialog (Adw.ApplicationWindow parent, Subject[] subjects, int index) { + public NewGradeDialog (Adw.ApplicationWindow parent, Subject subject) { Object ( heading: _("Add New Grade"), transient_for: parent, @@ -17,28 +17,28 @@ public class NewGradeDialog : Adw.MessageDialog { this.add_response ("cancel", _("Cancel")); this.add_response ("add", _("Add")); this.set_close_response ("cancel"); - this.set_response_appearance ("add", SUGGESTED); - this.set_response_enabled ("add", false); + this.set_response_appearance ("add", SUGGESTED); + this.set_response_enabled ("add", false); var grade_adjustment = new Gtk.Adjustment (0, 0, 100, 1, 0, 0); //CATEGORY var cat_model = new Gtk.StringList (null); - for (int i = 0; subjects[index].categories[i] != null; i++) { - cat_model.append (subjects[index].categories[i].name); + for (int i = 0; subject.categories[i] != null; i++) { + cat_model.append (subject.categories[i].name); } - grade_spinbutton = new Adw.SpinRow (grade_adjustment, 1, 2) { - title = _("Grade") + grade_spinbutton = new Adw.SpinRow (grade_adjustment, 1, 2) { + title = _("Grade") }; choose_cat_row = new Adw.ComboRow () { title = _("Category"), model = cat_model }; - entry = new Adw.EntryRow () { - input_hints = SPELLCHECK, - title = _("Note") - }; + entry = new Adw.EntryRow () { + input_hints = SPELLCHECK, + title = _("Note") + }; var preferences_group = new Adw.PreferencesGroup (); preferences_group.add (grade_spinbutton); preferences_group.add (choose_cat_row); diff --git a/src/subject-page.vala b/src/subject-page.vala index 3515d47..957ab20 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -97,6 +97,20 @@ public class SubjectPage : Gtk.Box { top_box.append (new_grade_button); + var status_page = new Adw.StatusPage () { + title = _("No Grades"), + description = _("Add new grades by clicking the “New Grade…” button."), + vexpand = true + }; + + var list_box = new Gtk.ListBox () {vexpand = true, margin_top = 20}; + list_box.add_css_class ("boxed-list"); + list_box.set_placeholder (status_page); + list_box.bind_model (subject.grades_model, widget_create_func); + //list_box.set_sort_func (sort_list); + //list_box.set_filter_func (filter_list); + nyttbox.append (list_box); + var toolbar_view = new Adw.ToolbarView () { hexpand = true, content = gtk_sw @@ -110,12 +124,185 @@ public class SubjectPage : Gtk.Box { //CONNECT BUTTONS - // new_grade_button.clicked.connect (() => { - // // new_grade_dialog (new_grade_button.index); - // }); + new_grade_button.clicked.connect (new_grade_dialog); + + edit_subject_button.clicked.connect (() => { + edit_subject_dialog (); + }); + + subject.grades_model.items_changed.connect (() => { + // double percentage_divider = 0; + + // int i = 0; + // for (; i < subject.grades_model.get_n_items (), i++) { + // if (number_of_grades[j] != 0) { + // avg_calculated[j] = average[j] / number_of_grades[j]; + // final_avg += avg_calculated[j] * subjects[i].categories[j].percentage; + // percentage_divider += subjects[i].categories[j].percentage; + // } + // } + // if (percentage_divider != 0) { + // string average_string = "%.2f".printf (final_avg / percentage_divider); + // avg[i].set_label (average_string); + // } + }); + } + + public void new_grade_dialog () { + if (subject.categories[0] != null){ + var dialog = new NewGradeDialog ((Window) get_root (), subject); + + dialog.response.connect ((response_id) => { + if (response_id == "add") { + dialog.set_variables (); + subject.new_grade (dialog.get_grade (), dialog.get_note (), (int) dialog.choose_cat_row.get_selected ()); + } + dialog.destroy (); + }); + dialog.present (); + } else { + var ErrorDialog = new Adw.MessageDialog ((Window) get_root (), _("Error"), _("This subject has no categories. Add at least one category in order to add a grade.")); + ErrorDialog.add_css_class ("error"); + ErrorDialog.add_response ("ok", _("OK")); + ErrorDialog.present (); + } + } - // edit_subject_button.clicked.connect (() => { - // // edit_subject_dialog (edit_subject_button.index); - // }); + + public void edit_subject_dialog () { + new EditSubjectDialog ((Window) get_root (), subject).present (); + } + + private static Gtk.Widget widget_create_func (Object obj) { + var grade = (Grade) obj; + + var expander_row = new Adw.ActionRow (); + expander_row.set_title (grade.grade.to_string ()); + + // if (subjects[i].grades[j].note == "") { + // expander_row.set_subtitle (subject.categories[grade.cat].name); + // } else { + // expander_row.set_subtitle (subject.categories[grade.cat].name + " — " + grade.note); + // } + + var delete_button = new Gtk.Button (); + expander_row.add_suffix (delete_button); + + delete_button.clicked.connect (() => { + Adw.MessageDialog msg = new Adw.MessageDialog ( + null, //TODO + _("Delete Grade?"), + _("If you delete this grade, its information will be deleted permanently.") + ); + msg.add_response ("cancel", _("Cancel")); + msg.add_response ("delete", _("Delete")); + msg.set_response_appearance ("delete", DESTRUCTIVE); + msg.set_close_response ("cancel"); + msg.response.connect ((response) => { + if (response == "delete") { + // delete_grade (delete_button.subject_index, delete_button.grade_index); + } + msg.destroy (); + }); + + msg.present (); + }); + + return expander_row; } + + + + // public Gtk.Box window_grade_rows_ui (int i, Gtk.Box? nyttbox = null) { + // nyttbox = nyttbox ?? nyabox[i]; + // if ((nyttbox.get_first_child ().get_next_sibling ().name == "GtkListBox") || (nyttbox.get_first_child ().get_next_sibling ().name == "AdwStatusPage")) { + // nyttbox.remove (nyttbox.get_first_child ().get_next_sibling ()); + // } + + + // int[] average = new int[subjects[i].categories.length]; + // double[] number_of_grades = new double[subjects[i].categories.length]; + // double[] avg_calculated = new double[subjects[i].categories.length]; + // double final_avg = 0.00; + + // //LIST BOX + // if (subjects[i].grades[0] == null) { + // var adw_page = new Adw.StatusPage () { + // title = _("No Grades"), + // description = _("Add new grades by clicking the “New Grade…” button."), + // vexpand = true + // }; + // nyttbox.append (adw_page); + // return nyttbox; + // } else { + + // var list_box = new Gtk.ListBox () {vexpand = false, margin_top = 20}; + // list_box.add_css_class ("boxed-list"); + // //list_box.set_sort_func (sort_list); + // //list_box.set_filter_func (filter_list); + // nyttbox.append (list_box); + + // for (int j = 0; subjects[i].grades[j] != null; j++) { + // average[subjects[i].grades[j].cat] += int.parse (subjects[i].grades[j].grade); + // number_of_grades[subjects[i].grades[j].cat]++; + + + + // //expander row + // var expander_row = new Adw.ActionRow (); + // expander_row.set_title (subjects[i].grades[j].grade.to_string ()); + // if (subjects[i].grades[j].note == "") { + // expander_row.set_subtitle (subjects[i].categories[subjects[i].grades[j].cat].name); + // } else { + // expander_row.set_subtitle (subjects[i].categories[subjects[i].grades[j].cat].name + " — " + subjects[i].grades[j].note); + // } + // var delete_button = new DeleteButton (i, j); + // expander_row.add_suffix (delete_button); + + + + // //put everything together + // list_box.append (expander_row); + + + + // //CONNECT BUTTONS + // delete_button.clicked.connect (() => { + // Adw.MessageDialog msg = new Adw.MessageDialog ( + // main_window, + // _("Delete Grade?"), + // _("If you delete this grade, its information will be deleted permanently.") + // ); + // msg.add_response ("cancel", _("Cancel")); + // msg.add_response ("delete", _("Delete")); + // msg.set_response_appearance ("delete", DESTRUCTIVE); + // msg.set_close_response ("cancel"); + // msg.response.connect ((response) => { + // if (response == "delete") { + // delete_grade (delete_button.subject_index, delete_button.grade_index); + // } + // msg.destroy (); + // }); + + // msg.present (); + // }); + // // } + + // double percentage_divider = 0; + + // for (int j = 0; j < subjects[i].categories.length && subjects[i].categories[j] != null; j++) { + // if (number_of_grades[j] != 0) { + // avg_calculated[j] = average[j] / number_of_grades[j]; + // final_avg += avg_calculated[j] * subjects[i].categories[j].percentage; + // percentage_divider += subjects[i].categories[j].percentage; + // } + // } + // if (percentage_divider != 0) { + // string average_string = "%.2f".printf (final_avg / percentage_divider); + // avg[i].set_label (average_string); + // } + + // return nyttbox; + // } + // } } diff --git a/src/subject-parser.vala b/src/subject-parser.vala index 76ef2b9..01f7369 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -5,53 +5,37 @@ public class SubjectParser : Object { public SubjectParser () {} public Subject? to_object (string str) { - Regex regex_for_main; - Regex regex_for_sub; - - try { - regex_for_main = new Regex ("%"); - regex_for_sub = new Regex ("#"); - } catch (Error e) { - print (e.message); - return null; - } - - var subject_string_arr = new string[3]; - var cat_string_arr = new string[10]; - var grade_string_arr = new string[10]; - - subject_string_arr = regex_for_main.split (str); - cat_string_arr = regex_for_sub.split (subject_string_arr[1]); - grade_string_arr = regex_for_sub.split (subject_string_arr[2]); + var subject_string_arr = str.split_set ("%"); + var cat_string_arr = subject_string_arr[1].split_set ("#"); + var grade_string_arr = subject_string_arr[2].split_set ("#"); var result_subject = new Subject (subject_string_arr[0]); - - var cats = new Category[cat_arr_size]; - int j1 = 0; - for (int i = 0; i < cat_string_arr.length && cat_string_arr[j1] != null; i++) { - cats[i] = new Category ("", 0); - cats[i].name = cat_string_arr[j1]; - j1++; - cats[i].percentage = int.parse (cat_string_arr[j1]); - j1++; - } - - - var grades = new Grade[grade_arr_size]; - int j2 = 0; - for (int i = 0; i < grade_string_arr.length && grade_string_arr[j2] != null; i++) { - grades[i] = new Grade ("", "", 0); - grades[i].grade = grade_string_arr[j2]; - j2++; - grades[i].note = grade_string_arr[j2]; - j2++; - grades[i].cat = int.parse (grade_string_arr[j2]); - j2++; - } - - result_subject.categories = cats; - result_subject.grades = grades; + // var cats = new Category[cat_arr_size]; + // int j1 = 0; + // for (int i = 0; i < cat_string_arr.length && cat_string_arr[j1] != null; i++) { + // cats[i] = new Category ("", 0); + // cats[i].name = cat_string_arr[j1]; + // j1++; + // cats[i].percentage = int.parse (cat_string_arr[j1]); + // j1++; + // } + + + // var grades = new Grade[grade_arr_size]; + // int j2 = 0; + // for (int i = 0; i < grade_string_arr.length && grade_string_arr[j2] != null; i++) { + // grades[i] = new Grade ("", "", 0); + // grades[i].grade = grade_string_arr[j2]; + // j2++; + // grades[i].note = grade_string_arr[j2]; + // j2++; + // grades[i].cat = int.parse (grade_string_arr[j2]); + // j2++; + // } + + // result_subject.categories = cats; + // result_subject.grades = grades; return result_subject; } diff --git a/src/subject.vala b/src/subject.vala index 30f59a1..cc1a6ca 100644 --- a/src/subject.vala +++ b/src/subject.vala @@ -1,13 +1,21 @@ public class Subject : Object{ public string name { get; set; } public Grade[] grades { get; set; } + public ListStore grades_model { get; set; } public Category[] categories { get; set; } + public ListStore categories_model { get; set; } public int cat_arr_size = 5; public int grade_arr_size = 20; public Subject (string n) { name = n; grades = new Grade[grade_arr_size]; + grades_model = new ListStore (typeof (Grade)); categories = new Category[cat_arr_size]; + categories_model = new ListStore (typeof (Category)); + } + + public void new_grade (string grade, string note, int c) { + grades_model.append (new Grade (grade, note, c)); } } diff --git a/src/window.vala b/src/window.vala index ddae066..a7f0b05 100644 --- a/src/window.vala +++ b/src/window.vala @@ -46,6 +46,12 @@ public class Window : Adw.ApplicationWindow { content = split_view; - stack.add_titled (new SubjectPage (new Subject ("English")), "English", "English"); + var subject_manager = SubjectManager.get_default (); + + subject_manager.read_data (); + + foreach (var subject in subject_manager.subjects.get_values ()) { + stack.add_titled (new SubjectPage (subject), subject.name, subject.name); + } } } From ac141468ab3fe2b93849e06304bed7e1a9a26e1e Mon Sep 17 00:00:00 2001 From: Leonhard Date: Tue, 28 Nov 2023 23:56:46 +0100 Subject: [PATCH 03/29] Edit subject kinda works now --- src/edit-subject-dialog.vala | 22 +++++++--------------- src/grade.vala | 1 + src/subject.vala | 4 ++-- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/edit-subject-dialog.vala b/src/edit-subject-dialog.vala index 6b63d00..03bc053 100644 --- a/src/edit-subject-dialog.vala +++ b/src/edit-subject-dialog.vala @@ -1,5 +1,4 @@ public class EditSubjectDialog : Adw.Window { - public Category[] categories; public Gtk.Box main_box; public Adw.EntryRow name_entry_box; private Gtk.Button new_cat_button; @@ -20,8 +19,6 @@ public class EditSubjectDialog : Adw.Window { subject = s; - categories = new Category[5]; - var tbv = new Adw.ToolbarView (); this.set_content (tbv); @@ -74,7 +71,7 @@ public class EditSubjectDialog : Adw.Window { subject_delete_button.clicked.connect (() => { string n = s.name; ///TRANSLATORS: %s is the name of a school subject - var message_dialog = new Adw.MessageDialog( this, _("Delete %s?").printf( n), null); + var message_dialog = new Adw.MessageDialog(this, _("Delete %s?").printf( n), null); message_dialog.set_body (_("If you delete %s, its information will be deleted permanently.").printf( n)); message_dialog.add_response ("0", _("Cancel")); message_dialog.add_response ("1", _("Delete")); @@ -86,7 +83,7 @@ public class EditSubjectDialog : Adw.Window { break; case "1": subject = null; - accept = true; + accept = true; this.close (); break; } @@ -95,13 +92,8 @@ public class EditSubjectDialog : Adw.Window { } public void add_cat (string n, double p) { - for (int i = 0; i < categories.length; i++) { - if (categories[i] == null) { - categories[i] = new Category (n, p); - i = categories.length; - load_list (); - } - } + subject.categories_by_name[n] = new Category (n, p); + load_list (); } public void load_list () { @@ -140,10 +132,10 @@ public class EditSubjectDialog : Adw.Window { main_box.append (cat_list_box); main_box.append (subject_delete_button); - for (int i = 0; i < subject.categories.length && subject.categories[i] != null; i++) { + foreach (var category in subject.categories_by_name.get_values ()) { var cat_row = new Adw.ActionRow () { - title = subject.categories[i].name, - subtitle = subject.categories[i].percentage.to_string () + "%" + title = category.name, + subtitle = category.percentage.to_string () + "%" }; cat_list_box.add (cat_row); } diff --git a/src/grade.vala b/src/grade.vala index e3ff103..1e6de12 100644 --- a/src/grade.vala +++ b/src/grade.vala @@ -1,6 +1,7 @@ public class Grade : Object{ public string grade { get; set; } public string note { get; set; } + public string category_name { get; set; } public int cat { get; set; } public Grade (string g, string n, int c) { diff --git a/src/subject.vala b/src/subject.vala index cc1a6ca..348a514 100644 --- a/src/subject.vala +++ b/src/subject.vala @@ -3,7 +3,7 @@ public class Subject : Object{ public Grade[] grades { get; set; } public ListStore grades_model { get; set; } public Category[] categories { get; set; } - public ListStore categories_model { get; set; } + public HashTable categories_by_name { get; set; } public int cat_arr_size = 5; public int grade_arr_size = 20; @@ -12,7 +12,7 @@ public class Subject : Object{ grades = new Grade[grade_arr_size]; grades_model = new ListStore (typeof (Grade)); categories = new Category[cat_arr_size]; - categories_model = new ListStore (typeof (Category)); + categories_by_name = new HashTable (str_hash, str_equal); } public void new_grade (string grade, string note, int c) { From 0d8d4534187c939cd85dc01a0f38e22942957915 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 00:00:45 +0100 Subject: [PATCH 04/29] Some more improvements --- src/subject-page.vala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/subject-page.vala b/src/subject-page.vala index 957ab20..c2a834e 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -31,11 +31,11 @@ public class SubjectPage : Gtk.Box { // toggle_button.bind_property ("active", ((Window) get_root ()).split_view, "show_sidebar", BindingFlags.BIDIRECTIONAL); // ((Window) get_root ()).bpoint.add_setter (toggle_button, "visible", true); - // var new_menu_button = new Gtk.Button () { - // icon_name = "list-add-symbolic", - // action_name = "app.newsubject", - // tooltip_text = _("Add a New Subject") - // }; + var new_menu_button = new Gtk.Button () { + icon_name = "list-add-symbolic", + action_name = "app.newsubject", + tooltip_text = _("Add a New Subject") + }; var edit_subject_button = new Gtk.Button () { icon_name = "document-edit-symbolic" @@ -46,7 +46,7 @@ public class SubjectPage : Gtk.Box { header_bar.pack_end (edit_subject_button); header_bar.pack_start (toggle_button); - // header_bar.pack_start (new_menu_button); + header_bar.pack_start (new_menu_button); //SUBJECT BOX var nyttbox = new Gtk.Box (VERTICAL, 0) { From 49eb03f8cfed1ad439ef464c837636c643b80e8a Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 00:32:05 +0100 Subject: [PATCH 05/29] Various improvements --- src/application.vala | 65 +---------------------------------------- src/subject-page.vala | 27 +++++++++-------- src/subject-parser.vala | 47 +++++++++++++---------------- src/window.vala | 6 ++++ 4 files changed, 43 insertions(+), 102 deletions(-) diff --git a/src/application.vala b/src/application.vala index c9895b1..831f1ec 100644 --- a/src/application.vala +++ b/src/application.vala @@ -184,73 +184,10 @@ public class MyApp : Adw.Application { main_window.destroy (); } - - - // public void new_grade (int index, string grade, string note, int c) { - // bool worked = false; - - // for (int i = 0; i < subjects[index].grades.length; i++) { - // if (subjects[index].grades[i] == null) { - // subjects[index].grades[i] = new Grade (grade, note, c); - // i = subjects[index].grades.length; - // worked = true; - // } - // } - - - // if (worked == false) { - // print ("no more grades available"); - // } else { - // window_grade_rows_ui (index); - // } - // } - - - - public void new_subject (string name, Category[] c) { - bool worked = false; - - for (int i = 0; i < subjects.length; i++) { - if (subjects[i] == null) { - subjects[i] = new Subject (name); - subjects[i].categories = c; - i = subjects.length; - worked = true; - } - } - - if (worked == true) { - window_stack_ui (0); - } else { - print ("No more subjects available!"); - } + SubjectManager.get_default ().new_subject (name, c); } - - - - // public void new_grade_dialog (int index) { - // if (subjects[index].categories[0] != null){ - // var dialog = new NewGradeDialog (main_window, subjects, index); - - // dialog.response.connect ((response_id) => { - // if (response_id == "add") { - // dialog.set_variables (); - // new_grade (index, dialog.get_grade (), dialog.get_note (), (int) dialog.choose_cat_row.get_selected ()); - // } - // dialog.destroy (); - // }); - // dialog.present (); - // } else { - // var ErrorDialog = new Adw.MessageDialog (main_window, _("Error"), _("This subject has no categories. Add at least one category in order to add a grade.")); - // ErrorDialog.add_css_class ("error"); - // ErrorDialog.add_response ("ok", _("OK")); - // ErrorDialog.present (); - // } - // } - - public void window_stack_ui (int index) {} // /*if (stack_box.get_last_child ().get_type () == typeof(Adw.ToolbarView)) { // stack_box.remove (stack_box.get_last_child()); diff --git a/src/subject-page.vala b/src/subject-page.vala index c2a834e..41e5eb3 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -103,13 +103,15 @@ public class SubjectPage : Gtk.Box { vexpand = true }; - var list_box = new Gtk.ListBox () {vexpand = true, margin_top = 20}; + var list_box = new Gtk.ListBox () {vexpand = false, margin_top = 20}; list_box.add_css_class ("boxed-list"); - list_box.set_placeholder (status_page); list_box.bind_model (subject.grades_model, widget_create_func); - //list_box.set_sort_func (sort_list); - //list_box.set_filter_func (filter_list); - nyttbox.append (list_box); + + if (subject.grades_model.get_n_items () > 0) { + nyttbox.append (list_box); + } else { + nyttbox.append (status_page); + } var toolbar_view = new Adw.ToolbarView () { hexpand = true, @@ -117,13 +119,7 @@ public class SubjectPage : Gtk.Box { }; toolbar_view.add_top_bar (header_bar); append (toolbar_view); - // window_grade_rows_ui (i, nyttbox); - - //add SUBJECT BOX to stackpage - // stack.add_titled (subject_boxes[i], subjects[i].name, subjects[i].name); - - //CONNECT BUTTONS new_grade_button.clicked.connect (new_grade_dialog); edit_subject_button.clicked.connect (() => { @@ -131,6 +127,13 @@ public class SubjectPage : Gtk.Box { }); subject.grades_model.items_changed.connect (() => { + if (subject.grades_model.get_n_items () > 0 && nyttbox.get_last_child () == status_page) { + nyttbox.remove (status_page); + nyttbox.append (list_box); + } else if (subject.grades_model.get_n_items () == 0 && nyttbox.get_last_child () == list_box) { + nyttbox.remove (list_box); + nyttbox.append (status_page); + } // double percentage_divider = 0; // int i = 0; @@ -149,7 +152,7 @@ public class SubjectPage : Gtk.Box { } public void new_grade_dialog () { - if (subject.categories[0] != null){ + if (subject.categories_by_name.length > 0){ var dialog = new NewGradeDialog ((Window) get_root (), subject); dialog.response.connect ((response_id) => { diff --git a/src/subject-parser.vala b/src/subject-parser.vala index 01f7369..1fb6b6d 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -13,25 +13,15 @@ public class SubjectParser : Object { // var cats = new Category[cat_arr_size]; // int j1 = 0; - // for (int i = 0; i < cat_string_arr.length && cat_string_arr[j1] != null; i++) { - // cats[i] = new Category ("", 0); - // cats[i].name = cat_string_arr[j1]; - // j1++; - // cats[i].percentage = int.parse (cat_string_arr[j1]); - // j1++; + // for (int i = 0; i < cat_string_arr.length; i++) { + // result_subject.categories_by_name[cat_string_arr[j1]] = new Category (cat_string_arr[j1++], int.parse (cat_string_arr[j1++])); // } // var grades = new Grade[grade_arr_size]; // int j2 = 0; - // for (int i = 0; i < grade_string_arr.length && grade_string_arr[j2] != null; i++) { - // grades[i] = new Grade ("", "", 0); - // grades[i].grade = grade_string_arr[j2]; - // j2++; - // grades[i].note = grade_string_arr[j2]; - // j2++; - // grades[i].cat = int.parse (grade_string_arr[j2]); - // j2++; + // for (int i = 0; i < grade_string_arr.length; i++) { + // result_subject.grades_model.append (new Grade (grade_string_arr[j2++], grade_string_arr[j2++], int.parse (grade_string_arr[j2++]))); // } // result_subject.categories = cats; @@ -41,26 +31,31 @@ public class SubjectParser : Object { } public string to_string (Subject sub) { - string result; + string result = sub.name + "%"; - result = sub.name + "%"; - - for (int i = 0; i < sub.categories.length && sub.categories[i] != null; i++) { - result = result + sub.categories[i].name + "#"; - result = result + sub.categories[i].percentage.to_string (); - if (sub.categories[i + 1] != null) { + bool first = true; + foreach (var category in sub.categories_by_name.get_values ()) { + if (!first) { result = result + "#"; + } else { + first = false; } + result = result + category.name + "#"; + result = result + category.percentage.to_string (); } + result = result + "%"; - for (int i = 0; i < sub.grades.length && sub.grades[i] != null; i++) { - result = result + sub.grades[i].grade + "#"; - result = result + sub.grades[i].note + "#"; - result = result + sub.grades[i].cat.to_string () + "#"; - if (sub.grades[i + 1] != null) { + first = true; + for (int i = 0; i < sub.grades_model.get_n_items (); i++) { + if (!first) { result = result + "#"; + } else { + first = false; } + result = result + ((Grade) sub.grades_model.get_item (i)).grade + "#"; + result = result + ((Grade) sub.grades_model.get_item (i)).note + "#"; + result = result + ((Grade) sub.grades_model.get_item (i)).cat.to_string () + "#"; } return result; diff --git a/src/window.vala b/src/window.vala index a7f0b05..139a71f 100644 --- a/src/window.vala +++ b/src/window.vala @@ -53,5 +53,11 @@ public class Window : Adw.ApplicationWindow { foreach (var subject in subject_manager.subjects.get_values ()) { stack.add_titled (new SubjectPage (subject), subject.name, subject.name); } + + close_request.connect (() => { + set_visible (false); + subject_manager.write_data (); + return true; + }); } } From 177a599b07a03e2055ed5883c4da8b4d64202073 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 00:32:22 +0100 Subject: [PATCH 06/29] Add missing file --- src/subject-manager.vala | 119 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/subject-manager.vala diff --git a/src/subject-manager.vala b/src/subject-manager.vala new file mode 100644 index 0000000..e24c344 --- /dev/null +++ b/src/subject-manager.vala @@ -0,0 +1,119 @@ +public class SubjectManager : Object { + private static Once instance; + public static SubjectManager get_default () { + return instance.once (() => new SubjectManager ()); + } + + public HashTable subjects; + + construct { + subjects = new HashTable (str_hash, str_equal); + } + + public void write_to_file (File file, string write_data) { + uint8[] write_bytes = (uint8[]) write_data.to_utf8 (); + + try { + file.replace_contents (write_bytes, null, false, FileCreateFlags.NONE, null, null); + } catch (Error e) { + print (e.message); + } + } + + + + + public string read_from_file (File file) + { + try { + string file_content = ""; + uint8[] contents; + string etag_out; + + + file.load_contents (null, out contents, out etag_out); + + file_content = (string) contents; + + return file_content; + } catch (Error e) { + print ("Error: %s\n", e.message); + } + return "-1"; + } + + + public void read_data () { + for (int i = 0; i < 20 && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { + File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); + + var parser = new SubjectParser (); + Subject sub = parser.to_object (read_from_file (file)); + subjects[sub.name] = sub; + } + } + + public void write_data () { + int z = 0; + File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); + if (!dir.query_exists ()) { + try { + dir.make_directory_with_parents (); + } catch (Error e) { + print (e.message); + } + } + int i = 0; + foreach (var subject in subjects.get_values ()) { + var parser = new SubjectParser (); + File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); + //TODO: Delete old files + write_to_file (file, parser.to_string (subject)); + z = i + 1; + i++; + } + } + + + + // public void new_grade (int index, string grade, string note, int c) { + // bool worked = false; + + // for (int i = 0; i < subjects[index].grades.length; i++) { + // if (subjects[index].grades[i] == null) { + // subjects[index].grades[i] = new Grade (grade, note, c); + // i = subjects[index].grades.length; + // worked = true; + // } + // } + + + // if (worked == false) { + // print ("no more grades available"); + // } else { + // window_grade_rows_ui (index); + // } + // } + + + + + public void new_subject (string name, Category[] c) { + bool worked = false; + + subjects[name] = new Subject (name); + } + + // public void delete_grade (int sub_index, int gra_index) { + // subjects[sub_index].grades[gra_index] = null; + + + // for (int i = gra_index; i < subjects[sub_index].grades.length - 1; i++) { + // subjects[sub_index].grades[i] = subjects[sub_index].grades[i + 1]; + // } + + // subjects[sub_index].grades[subjects[sub_index].grades.length - 1] = null; + + // window_grade_rows_ui (sub_index); + // } +} From d5a5a949a389e601c6c86636a405e539afab01fd Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 00:36:07 +0100 Subject: [PATCH 07/29] Fix category selection in NewGradeDialog --- src/new-grade-dialog.vala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/new-grade-dialog.vala b/src/new-grade-dialog.vala index bfaa12f..0aba80a 100644 --- a/src/new-grade-dialog.vala +++ b/src/new-grade-dialog.vala @@ -24,8 +24,8 @@ public class NewGradeDialog : Adw.MessageDialog { //CATEGORY var cat_model = new Gtk.StringList (null); - for (int i = 0; subject.categories[i] != null; i++) { - cat_model.append (subject.categories[i].name); + foreach (var category in subject.categories_by_name.get_keys ()) { + cat_model.append (category); } grade_spinbutton = new Adw.SpinRow (grade_adjustment, 1, 2) { From a43dd2611964cb7c2b0c05f58f06ee819021671d Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 00:41:17 +0100 Subject: [PATCH 08/29] Various visual improvements --- meson.build | 1 - src/application.vala | 487 +---------------------------------- src/edit-subject-button.vala | 3 - src/subject-page.vala | 7 - src/window.vala | 7 + 5 files changed, 10 insertions(+), 495 deletions(-) delete mode 100644 src/edit-subject-button.vala diff --git a/meson.build b/meson.build index a7ef02b..3d7c979 100644 --- a/meson.build +++ b/meson.build @@ -40,7 +40,6 @@ executable( 'src' / 'new-subject-dialog.vala', 'src' / 'delete-subject-button.vala', 'src' / 'category.vala', - 'src' / 'edit-subject-button.vala', 'src' / 'edit-subject-dialog.vala', 'src' / 'add-category-dialog.vala', 'src' / 'subject-manager.vala', diff --git a/src/application.vala b/src/application.vala index 831f1ec..fd9f6f1 100644 --- a/src/application.vala +++ b/src/application.vala @@ -1,14 +1,5 @@ public class MyApp : Adw.Application { - private int number_of_subjects = 20; - private Subject[] subjects; - private Adw.ToolbarView[] subject_boxes; private Window main_window; - private Gtk.Label[] avg; - private Gtk.ToggleButton toggle_button; - private Gtk.Box[] nyabox; - private EditSubjectButton edit_subject_button; - - public MyApp () { Object ( @@ -17,8 +8,6 @@ public class MyApp : Adw.Application { ); } - - construct { ActionEntry[] action_entries = { { "test", this.on_test_action }, @@ -29,26 +18,20 @@ public class MyApp : Adw.Application { this.add_action_entries (action_entries, this); } - - - public void on_test_action () { print ("test_action"); } public void on_help_action () { - Gtk.show_uri (main_window, "https://github.com/leolost2605/Gradebook/wiki", 0); - } - - - + Gtk.show_uri (main_window, "https://github.com/leolost2605/Gradebook/wiki", 0); + } public void on_newsubject_action () { var dialog = new NewSubjectDialog (main_window); dialog.close_request.connect (() => { if (dialog.accept) { - new_subject (dialog.name_entry_box.get_text (), dialog.categories); + SubjectManager.get_default ().new_subject (dialog.name_entry_box.get_text (), dialog.categories); } dialog.destroy (); return true; @@ -56,9 +39,6 @@ public class MyApp : Adw.Application { dialog.present (); } - - - public void on_about_action () { var about_window = new Adw.AboutWindow () { developer_name = "Leonhard Kargl", @@ -77,470 +57,9 @@ public class MyApp : Adw.Application { about_window.present (); } - - - /* - public int sort_list (Gtk.ListBoxRow row1, Gtk.ListBoxRow row2) { - //Adw.ExpanderRow awidget = row1.get_child (); - return 0; - }*/ - - - - /* - public bool filter_list (Gtk.ListBoxRow row) { - //TO DO: replace with switch/case and first of all get it to work - if(filter_type == 0) { - return true; - } else if(filter_type == 1) { - if(row.get_index () == 0) { - return false; - } else { - return true; - } - - } else { - return true; - } - - }*/ - - - - - public void write_to_file (File file, string write_data) - { - uint8[] write_bytes = (uint8[]) write_data.to_utf8 (); - - try { - file.replace_contents (write_bytes, null, false, FileCreateFlags.NONE, null, null); - } catch (Error e) { - print (e.message); - } - } - - - - - public string read_from_file (File file) - { - try { - string file_content = ""; - uint8[] contents; - string etag_out; - - - file.load_contents (null, out contents, out etag_out); - - file_content = (string) contents; - - return file_content; - } catch (Error e) { - print ("Error: %s\n", e.message); - } - return "-1"; - } - - - public void read_data () { - subjects = new Subject[number_of_subjects]; - - for (int i = 0; i < subjects.length && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { - File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); - - var parser = new SubjectParser (); - Subject sub = parser.to_object (read_from_file (file)); - subjects[i] = sub; - } - - } - - public void write_data () { - int z = 0; - File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); - if (!dir.query_exists ()) { - try { - dir.make_directory_with_parents (); - } catch (Error e) { - print (e.message); - } - } - for (int i = 0; i < subjects.length && subjects[i] != null; i++) { - var parser = new SubjectParser (); - File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); - - write_to_file (file, parser.to_string (subjects[i])); - z = i + 1; - } - for (int i = z; i < subjects.length && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { - File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); - - try { - file.delete (); - } catch (Error e) { - print (e.message); - } - } - main_window.destroy (); - } - - public void new_subject (string name, Category[] c) { - SubjectManager.get_default ().new_subject (name, c); - } - - public void window_stack_ui (int index) {} - // /*if (stack_box.get_last_child ().get_type () == typeof(Adw.ToolbarView)) { - // stack_box.remove (stack_box.get_last_child()); - // }*/ - // stack = new Gtk.Stack (); - - // debug (subjects[0].name); - // if (subjects[0].name == null) { - // var stack_box = new Adw.ToolbarView (); - // var header_bar = new Adw.HeaderBar (); - - // //PRIMARY MENU - // var menu_button = new Gtk.MenuButton () { - // icon_name = "open-menu-symbolic" - // }; - // header_bar.pack_end (menu_button); - - // var menu = new Menu (); - // var menu_section1 = new Menu (); - // var menu_section2 = new Menu (); - // menu.append_section (null, menu_section1); - // menu.append_section (null, menu_section2); - - // var preferences_item = new MenuItem (_("_Help"), "app.help"); - // menu_section1.append_item (preferences_item); - - // var about_item = new MenuItem (_("_About Gradebook"), "app.about"); - // menu_section2.append_item (about_item); - - - // var menu_popover = new Gtk.PopoverMenu.from_model (menu); - // menu_button.set_popover (menu_popover); - - // toggle_button = new Gtk.ToggleButton () { - // icon_name = "dock-left-symbolic", - // tooltip_text = _("Toggle Sidebar"), - // visible = false - // }; - // toggle_button.bind_property ("active", main_box, "show_sidebar", BindingFlags.BIDIRECTIONAL); - // bpoint.add_setter (toggle_button, "visible", true); - - // header_bar.pack_start (toggle_button); - - // var new_menu_button = new Gtk.Button () { - // icon_name = "list-add-symbolic", - // action_name = "app.newsubject", - // tooltip_text = _("Add a New Subject") - // }; - - // header_bar.pack_start (new_menu_button); - - // stack_box.add_top_bar (header_bar); - - // var placeholderlabel = new Adw.StatusPage () { - // vexpand = true, - // hexpand = true, - // title = _("No Subjects"), - // description = _("Add new subjects using the “+” button in the top left corner.") - // }; - // stack_box.set_content (placeholderlabel); - // stack.add_titled (stack_box , "no_subjects_placeholder", _("Gradebook")); - // } else { - - // //Create StackPages for every subject - // for( int i = 0; subjects[i] != null; i++) - // { - - // subject_boxes[i] = new Adw.ToolbarView (); - // var header_bar = new Adw.HeaderBar (); - - // //PRIMARY MENU - // var menu_button = new Gtk.MenuButton () { - // icon_name = "open-menu-symbolic" - // }; - // header_bar.pack_end (menu_button); - - // var menu = new Menu (); - // var menu_section1 = new Menu (); - // var menu_section2 = new Menu (); - // menu.append_section (null, menu_section1); - // menu.append_section (null, menu_section2); - - // var preferences_item = new MenuItem (_("_Help"), "app.help"); - // menu_section1.append_item (preferences_item); - - // var about_item = new MenuItem (_("_About Gradebook"), "app.about"); - // menu_section2.append_item (about_item); - - - // var menu_popover = new Gtk.PopoverMenu.from_model (menu); - // menu_button.set_popover (menu_popover); - - // toggle_button = new Gtk.ToggleButton () { - // icon_name = "dock-left-symbolic", - // tooltip_text = _("Toggle Sidebar"), - // visible = false - // }; - // toggle_button.bind_property ("active", main_box, "show_sidebar", BindingFlags.BIDIRECTIONAL); - // bpoint.add_setter (toggle_button, "visible", true); - - // header_bar.pack_start (toggle_button); - - // var new_menu_button = new Gtk.Button () { - // icon_name = "list-add-symbolic", - // action_name = "app.newsubject", - // tooltip_text = _("Add a New Subject") - // }; - - // header_bar.pack_start (new_menu_button); - - // // edit subject button - // edit_subject_button = new EditSubjectButton () { - // icon_name = "document-edit-symbolic" - // }; - // header_bar.pack_end (edit_subject_button); - - // subject_boxes[i].add_top_bar (header_bar); - - // //SUBJECT BOX - // var nyttbox = new Gtk.Box (VERTICAL, 0) { - // vexpand = true, - // margin_start = 1, - // margin_end = 1 - // }; - // var gtk_sw = new Gtk.ScrolledWindow (); - // var adw_c = new Adw.Clamp () { - // margin_start = 19, - // margin_end = 19, - // margin_top = 20, - // margin_bottom = 20, - // maximum_size = 600, - // tightening_threshold = 400 - // }; - // gtk_sw.set_child (adw_c); - // adw_c.set_child (nyttbox); - - // //TOP BOX - // var top_box = new Gtk.Box (HORIZONTAL, 0) { - // height_request = 40, - // hexpand = true, - // homogeneous = true - // }; - // nyttbox.append (top_box); - - // //AVERAGE LABEL - // var average_box = new Gtk.Box (HORIZONTAL, 10) { - // halign = START - // }; - // top_box.append (average_box); - - // var average_label = new Gtk.Label (_("Average:")) { css_classes = { "title-3" } }; - // average_box.append (average_label); - - // avg[i] = new Gtk.Label ("0.00") { css_classes = { "title-3" } }; - // average_box.append (avg[i]); - - - - // //NEW GRADE BUTTON - // var new_grade_button = new NewGradeButton (i) { - // icon_name = "add-list-symbolic" - // }; - // new_grade_button.halign = END; - // new_grade_button.label = _("New Grade…"); - // new_grade_button.add_css_class ("suggested-action"); - // new_grade_button.add_css_class ("pill"); - - // top_box.append (new_grade_button); - - - // /*//FILL BOX - // var fill_box = new Gtk.Box (VERTICAL, 0) { - // margin_end = 20, - // margin_start = 20, - // vexpand = true, - // hexpand = true - // }; - // subject_boxes[i].append (fill_box); - - // //DELETE SUBJECT BUTTON - // var bottom_box = new Gtk.Box (HORIZONTAL, 0) { - // margin_end = 20, - // margin_start = 20, - // margin_bottom = 20, - // hexpand = true, - // homogeneous = true - // }; - // subject_boxes[i].append (bottom_box); - - // var bottom_end_box = new Gtk.Box (HORIZONTAL, 0) {halign = END}; - // bottom_box.append (bottom_end_box);*/ - - // //CALL LISTBOX WITH GRADES - - // subject_boxes[i].set_content (gtk_sw); - // window_grade_rows_ui (i, nyttbox); - // nyabox[i] = nyttbox; - - - // //add SUBJECT BOX to stackpage - // stack.add_titled (subject_boxes[i], subjects[i].name, subjects[i].name); - - - // //CONNECT BUTTONS - // new_grade_button.clicked.connect (() => { - // new_grade_dialog (new_grade_button.index); - // }); - - // edit_subject_button.index = i; - - // edit_subject_button.clicked.connect (() => { - // edit_subject_dialog (edit_subject_button.index); - // }); - - - // } - - // stack.set_visible_child_name (subjects[index].name); - - // } - // } - - - - - - public Gtk.Box window_grade_rows_ui (int i, Gtk.Box? nyttbox = null) { - nyttbox = nyttbox ?? nyabox[i]; - if ((nyttbox.get_first_child ().get_next_sibling ().name == "GtkListBox") || (nyttbox.get_first_child ().get_next_sibling ().name == "AdwStatusPage")) { - nyttbox.remove (nyttbox.get_first_child ().get_next_sibling ()); - } - - - int[] average = new int[subjects[i].categories.length]; - double[] number_of_grades = new double[subjects[i].categories.length]; - double[] avg_calculated = new double[subjects[i].categories.length]; - double final_avg = 0.00; - - //LIST BOX - if (subjects[i].grades[0] == null) { - var adw_page = new Adw.StatusPage () { - title = _("No Grades"), - description = _("Add new grades by clicking the “New Grade…” button."), - vexpand = true - }; - nyttbox.append (adw_page); - return nyttbox; - } else { - - var list_box = new Gtk.ListBox () {vexpand = false, margin_top = 20}; - list_box.add_css_class ("boxed-list"); - //list_box.set_sort_func (sort_list); - //list_box.set_filter_func (filter_list); - nyttbox.append (list_box); - - for (int j = 0; subjects[i].grades[j] != null; j++) { - average[subjects[i].grades[j].cat] += int.parse (subjects[i].grades[j].grade); - number_of_grades[subjects[i].grades[j].cat]++; - - - - //expander row - var expander_row = new Adw.ActionRow (); - expander_row.set_title (subjects[i].grades[j].grade.to_string ()); - if (subjects[i].grades[j].note == "") { - expander_row.set_subtitle (subjects[i].categories[subjects[i].grades[j].cat].name); - } else { - expander_row.set_subtitle (subjects[i].categories[subjects[i].grades[j].cat].name + " — " + subjects[i].grades[j].note); - } - var delete_button = new DeleteButton (i, j); - expander_row.add_suffix (delete_button); - - - - //put everything together - list_box.append (expander_row); - - - - //CONNECT BUTTONS - delete_button.clicked.connect (() => { - Adw.MessageDialog msg = new Adw.MessageDialog ( - main_window, - _("Delete Grade?"), - _("If you delete this grade, its information will be deleted permanently.") - ); - msg.add_response ("cancel", _("Cancel")); - msg.add_response ("delete", _("Delete")); - msg.set_response_appearance ("delete", DESTRUCTIVE); - msg.set_close_response ("cancel"); - msg.response.connect ((response) => { - if (response == "delete") { - delete_grade (delete_button.subject_index, delete_button.grade_index); - } - msg.destroy (); - }); - - msg.present (); - }); - } - - double percentage_divider = 0; - - for (int j = 0; j < subjects[i].categories.length && subjects[i].categories[j] != null; j++) { - if (number_of_grades[j] != 0) { - avg_calculated[j] = average[j] / number_of_grades[j]; - final_avg += avg_calculated[j] * subjects[i].categories[j].percentage; - percentage_divider += subjects[i].categories[j].percentage; - } - } - if (percentage_divider != 0) { - string average_string = "%.2f".printf (final_avg / percentage_divider); - avg[i].set_label (average_string); - } - - return nyttbox; - } - } - - - - - public void delete_grade (int sub_index, int gra_index) { - subjects[sub_index].grades[gra_index] = null; - - - for (int i = gra_index; i < subjects[sub_index].grades.length - 1; i++) { - subjects[sub_index].grades[i] = subjects[sub_index].grades[i + 1]; - } - - subjects[sub_index].grades[subjects[sub_index].grades.length - 1] = null; - - window_grade_rows_ui (sub_index); - } - - protected override void activate () { main_window = new Window (this); - - //Variables - // read_data (); - - // window_stack_ui (0); - - //PRESENT WINDOW main_window.present (); - - - main_window.close_request.connect (() => { - main_window.set_visible (false); - write_data (); - return true; - }); } public static int main (string[] args) diff --git a/src/edit-subject-button.vala b/src/edit-subject-button.vala deleted file mode 100644 index 59c054a..0000000 --- a/src/edit-subject-button.vala +++ /dev/null @@ -1,3 +0,0 @@ -public class EditSubjectButton : Gtk.Button { - public int index; -} diff --git a/src/subject-page.vala b/src/subject-page.vala index 41e5eb3..dded627 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -31,12 +31,6 @@ public class SubjectPage : Gtk.Box { // toggle_button.bind_property ("active", ((Window) get_root ()).split_view, "show_sidebar", BindingFlags.BIDIRECTIONAL); // ((Window) get_root ()).bpoint.add_setter (toggle_button, "visible", true); - var new_menu_button = new Gtk.Button () { - icon_name = "list-add-symbolic", - action_name = "app.newsubject", - tooltip_text = _("Add a New Subject") - }; - var edit_subject_button = new Gtk.Button () { icon_name = "document-edit-symbolic" }; @@ -46,7 +40,6 @@ public class SubjectPage : Gtk.Box { header_bar.pack_end (edit_subject_button); header_bar.pack_start (toggle_button); - header_bar.pack_start (new_menu_button); //SUBJECT BOX var nyttbox = new Gtk.Box (VERTICAL, 0) { diff --git a/src/window.vala b/src/window.vala index 139a71f..055870f 100644 --- a/src/window.vala +++ b/src/window.vala @@ -17,7 +17,14 @@ public class Window : Adw.ApplicationWindow { construct { stack = new Gtk.Stack (); + var new_subject_button = new Gtk.Button () { + icon_name = "list-add-symbolic", + action_name = "app.newsubject", + tooltip_text = _("Add a New Subject") + }; + var header_bar = new Adw.HeaderBar () { hexpand = true }; + header_bar.pack_end (new_subject_button); var stack_sidebar = new Gtk.StackSidebar () { stack = stack From d137e9b52d576ebf977a08c846506ce2fbaade26 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 14:50:55 +0100 Subject: [PATCH 09/29] Fix delete button style --- src/deletebutton.vala | 8 +------- src/subject-page.vala | 10 +++++++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/deletebutton.vala b/src/deletebutton.vala index 2e394f5..bf5f3ab 100644 --- a/src/deletebutton.vala +++ b/src/deletebutton.vala @@ -3,11 +3,5 @@ public class DeleteButton : Gtk.Button{ public int grade_index; public DeleteButton (int si, int gi) { - this.icon_name = "user-trash-symbolic"; - subject_index = si; - grade_index = gi; - add_css_class ("flat"); - this.vexpand = false; - this.valign = CENTER; } -} \ No newline at end of file +} diff --git a/src/subject-page.vala b/src/subject-page.vala index dded627..498ebb4 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -172,8 +172,15 @@ public class SubjectPage : Gtk.Box { private static Gtk.Widget widget_create_func (Object obj) { var grade = (Grade) obj; + var delete_button = new Gtk.Button () { + icon_name = "user-trash-symbolic", + valign = CENTER + }; + delete_button.add_css_class ("flat"); + var expander_row = new Adw.ActionRow (); expander_row.set_title (grade.grade.to_string ()); + expander_row.add_suffix (delete_button); // if (subjects[i].grades[j].note == "") { // expander_row.set_subtitle (subject.categories[grade.cat].name); @@ -181,9 +188,6 @@ public class SubjectPage : Gtk.Box { // expander_row.set_subtitle (subject.categories[grade.cat].name + " — " + grade.note); // } - var delete_button = new Gtk.Button (); - expander_row.add_suffix (delete_button); - delete_button.clicked.connect (() => { Adw.MessageDialog msg = new Adw.MessageDialog ( null, //TODO From 569688beb9326871858e8b327bd0e07e1fee50d3 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 21:09:34 +0100 Subject: [PATCH 10/29] Saving works again --- src/subject-manager.vala | 1 + src/subject-page.vala | 10 +++++----- src/subject-parser.vala | 24 +++++++++--------------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index e24c344..120478b 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -69,6 +69,7 @@ public class SubjectManager : Object { File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); //TODO: Delete old files write_to_file (file, parser.to_string (subject)); + warning ("write: %s", parser.to_string (subject)); z = i + 1; i++; } diff --git a/src/subject-page.vala b/src/subject-page.vala index 498ebb4..f1fe33b 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -182,11 +182,11 @@ public class SubjectPage : Gtk.Box { expander_row.set_title (grade.grade.to_string ()); expander_row.add_suffix (delete_button); - // if (subjects[i].grades[j].note == "") { - // expander_row.set_subtitle (subject.categories[grade.cat].name); - // } else { - // expander_row.set_subtitle (subject.categories[grade.cat].name + " — " + grade.note); - // } + if (grade.note == "") { + expander_row.set_subtitle (grade.category_name); + } else { + expander_row.set_subtitle (grade.category_name + " — " + grade.note); + } delete_button.clicked.connect (() => { Adw.MessageDialog msg = new Adw.MessageDialog ( diff --git a/src/subject-parser.vala b/src/subject-parser.vala index 1fb6b6d..8bc1bb8 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -11,21 +11,15 @@ public class SubjectParser : Object { var result_subject = new Subject (subject_string_arr[0]); - // var cats = new Category[cat_arr_size]; - // int j1 = 0; - // for (int i = 0; i < cat_string_arr.length; i++) { - // result_subject.categories_by_name[cat_string_arr[j1]] = new Category (cat_string_arr[j1++], int.parse (cat_string_arr[j1++])); - // } - - - // var grades = new Grade[grade_arr_size]; - // int j2 = 0; - // for (int i = 0; i < grade_string_arr.length; i++) { - // result_subject.grades_model.append (new Grade (grade_string_arr[j2++], grade_string_arr[j2++], int.parse (grade_string_arr[j2++]))); - // } + int j1 = 0; + while (j1 < cat_string_arr.length) { + result_subject.categories_by_name[cat_string_arr[j1]] = new Category (cat_string_arr[j1++], int.parse (cat_string_arr[j1++])); + } - // result_subject.categories = cats; - // result_subject.grades = grades; + int j2 = 0; + while (j2 < grade_string_arr.length) { + result_subject.grades_model.append (new Grade (grade_string_arr[j2++], grade_string_arr[j2++], int.parse (grade_string_arr[j2++]))); + } return result_subject; } @@ -55,7 +49,7 @@ public class SubjectParser : Object { } result = result + ((Grade) sub.grades_model.get_item (i)).grade + "#"; result = result + ((Grade) sub.grades_model.get_item (i)).note + "#"; - result = result + ((Grade) sub.grades_model.get_item (i)).cat.to_string () + "#"; + result = result + ((Grade) sub.grades_model.get_item (i)).cat.to_string (); } return result; From 0dbae3f39b64a9218dc5166e71e628af44948e2d Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 21:39:12 +0100 Subject: [PATCH 11/29] Various improvements --- meson.build | 2 - src/deletebutton.vala | 7 -- src/edit-subject-dialog.vala | 138 ++++++++++++++++++----------------- src/grade.vala | 12 +-- src/new-grade-dialog.vala | 33 +++------ src/newgradebutton.vala | 7 -- src/subject-page.vala | 10 +-- src/subject-parser.vala | 4 +- src/subject.vala | 21 +++--- 9 files changed, 101 insertions(+), 133 deletions(-) delete mode 100644 src/deletebutton.vala delete mode 100644 src/newgradebutton.vala diff --git a/meson.build b/meson.build index 3d7c979..fd79ce8 100644 --- a/meson.build +++ b/meson.build @@ -34,8 +34,6 @@ executable( 'src' / 'application.vala', 'src' / 'grade.vala', 'src' / 'subject.vala', - 'src' / 'newgradebutton.vala', - 'src' / 'deletebutton.vala', 'src' / 'new-grade-dialog.vala', 'src' / 'new-subject-dialog.vala', 'src' / 'delete-subject-button.vala', diff --git a/src/deletebutton.vala b/src/deletebutton.vala deleted file mode 100644 index bf5f3ab..0000000 --- a/src/deletebutton.vala +++ /dev/null @@ -1,7 +0,0 @@ -public class DeleteButton : Gtk.Button{ - public int subject_index; - public int grade_index; - - public DeleteButton (int si, int gi) { - } -} diff --git a/src/edit-subject-dialog.vala b/src/edit-subject-dialog.vala index 03bc053..49fa49e 100644 --- a/src/edit-subject-dialog.vala +++ b/src/edit-subject-dialog.vala @@ -1,10 +1,8 @@ public class EditSubjectDialog : Adw.Window { - public Gtk.Box main_box; - public Adw.EntryRow name_entry_box; - private Gtk.Button new_cat_button; - private Gtk.Button subject_delete_button; + private Adw.PreferencesGroup cat_list_box; public bool accept = false; public Subject subject; + private List cat_rows; public EditSubjectDialog (Adw.ApplicationWindow parent, Subject s) { Object ( @@ -19,8 +17,7 @@ public class EditSubjectDialog : Adw.Window { subject = s; - var tbv = new Adw.ToolbarView (); - this.set_content (tbv); + cat_rows = new List (); var hb = new Adw.HeaderBar () { show_end_title_buttons = false, @@ -42,77 +39,75 @@ public class EditSubjectDialog : Adw.Window { hb.pack_start (cb); hb.pack_end (ab); - tbv.add_top_bar (hb); + var new_cat_button = new Gtk.Button () { + icon_name = "list-add-symbolic", + tooltip_text = _("Add New Category"), + css_classes = { "flat" } + }; - Adw.Clamp ac = new Adw.Clamp () { - margin_start = 19, - margin_end = 19, - maximum_size = 500, - tightening_threshold = 400 - }; + cat_list_box = new Adw.PreferencesGroup () { + margin_start = 1, + margin_end = 1, + hexpand = true, + vexpand = true, + title = _("Subject Categories"), + }; + cat_list_box.set_header_suffix (new_cat_button); - var sw = new Gtk.ScrolledWindow (); - main_box = new Gtk.Box (VERTICAL, 0) { + var subject_delete_button = new Gtk.Button.with_label (_("Delete Subject…")) { hexpand = false, halign = Gtk.Align.START, margin_top = 20 }; + subject_delete_button.add_css_class ("destructive-action"); + + var main_box = new Gtk.Box (VERTICAL, 0) { margin_top = 20, margin_bottom = 20 }; - tbv.set_content (sw); + main_box.append (cat_list_box); + main_box.append (subject_delete_button); - this.set_content (tbv); - sw.set_child (ac); - ac.set_child (main_box); - load_list (); + var clamp = new Adw.Clamp () { + margin_start = 19, + margin_end = 19, + maximum_size = 500, + tightening_threshold = 400, + child = main_box + }; - subject_delete_button = new Gtk.Button.with_label (_("Delete Subject…")) { hexpand = false, halign = Gtk.Align.START, margin_top = 20 }; - subject_delete_button.add_css_class ("destructive-action"); - main_box.append (subject_delete_button); + var scrolled_window = new Gtk.ScrolledWindow () { + child = clamp + }; - subject_delete_button.clicked.connect (() => { - string n = s.name; - ///TRANSLATORS: %s is the name of a school subject - var message_dialog = new Adw.MessageDialog(this, _("Delete %s?").printf( n), null); - message_dialog.set_body (_("If you delete %s, its information will be deleted permanently.").printf( n)); - message_dialog.add_response ("0", _("Cancel")); - message_dialog.add_response ("1", _("Delete")); - message_dialog.set_response_appearance ("1", DESTRUCTIVE); - message_dialog.present (); - message_dialog.response.connect ((id) => { - switch (id) { - case "0": - break; - case "1": - subject = null; - accept = true; - this.close (); - break; - } - }); - }); - } - public void add_cat (string n, double p) { - subject.categories_by_name[n] = new Category (n, p); - load_list (); - } + var tbv = new Adw.ToolbarView () { + content = scrolled_window + }; + tbv.add_top_bar (hb); - public void load_list () { - main_box.remove (main_box.get_first_child ()); - main_box.remove (main_box.get_first_child ()); + content = tbv; - var cat_list_box = new Adw.PreferencesGroup () { - margin_start = 1, - margin_end = 1, - hexpand = true, - vexpand = true, - title = _("Subject Categories"), - }; + load_list (); - new_cat_button = new Gtk.Button () { - icon_name = "list-add-symbolic", - tooltip_text = _("Add New Category"), - css_classes = { "flat" } - }; + subject_delete_button.clicked.connect (() => { + string n = s.name; + ///TRANSLATORS: %s is the name of a school subject + var message_dialog = new Adw.MessageDialog(this, _("Delete %s?").printf( n), null); + message_dialog.set_body (_("If you delete %s, its information will be deleted permanently.").printf( n)); + message_dialog.add_response ("0", _("Cancel")); + message_dialog.add_response ("1", _("Delete")); + message_dialog.set_response_appearance ("1", DESTRUCTIVE); + message_dialog.present (); + message_dialog.response.connect ((id) => { + switch (id) { + case "0": + break; + case "1": + subject = null; + accept = true; + this.close (); + break; + } + }); + }); new_cat_button.clicked.connect (() => { var dialog = new AddCategoryDialog (this); @@ -126,17 +121,26 @@ public class EditSubjectDialog : Adw.Window { dialog.present (); }); + } - cat_list_box.set_header_suffix (new_cat_button); + public void add_cat (string n, double p) { + subject.categories_by_name[n] = new Category (n, p); + load_list (); + } - main_box.append (cat_list_box); - main_box.append (subject_delete_button); + public void load_list () { + foreach (var row in cat_rows) { + cat_list_box.remove (row); + } + + cat_rows = new List (); foreach (var category in subject.categories_by_name.get_values ()) { var cat_row = new Adw.ActionRow () { title = category.name, subtitle = category.percentage.to_string () + "%" }; + cat_rows.append (cat_row); cat_list_box.add (cat_row); } } diff --git a/src/grade.vala b/src/grade.vala index 1e6de12..03e3d2c 100644 --- a/src/grade.vala +++ b/src/grade.vala @@ -2,12 +2,12 @@ public class Grade : Object{ public string grade { get; set; } public string note { get; set; } public string category_name { get; set; } - public int cat { get; set; } - public Grade (string g, string n, int c) { - this.grade = g; - this.note = n; - this.cat = c; + public Grade (string grade, string note, string category) { + Object ( + grade: grade, + note: note, + category_name: category + ); } - } diff --git a/src/new-grade-dialog.vala b/src/new-grade-dialog.vala index 0aba80a..273ea2a 100644 --- a/src/new-grade-dialog.vala +++ b/src/new-grade-dialog.vala @@ -1,10 +1,7 @@ public class NewGradeDialog : Adw.MessageDialog { - public string grade; - public string note; private Adw.SpinRow grade_spinbutton; private Adw.EntryRow entry; - //private Adw.EntryRow note_entry; - public Adw.ComboRow choose_cat_row; + private Adw.ComboRow choose_cat_row; public NewGradeDialog (Adw.ApplicationWindow parent, Subject subject) { Object ( @@ -40,27 +37,21 @@ public class NewGradeDialog : Adw.MessageDialog { title = _("Note") }; var preferences_group = new Adw.PreferencesGroup (); - preferences_group.add (grade_spinbutton); + preferences_group.add (grade_spinbutton); preferences_group.add (choose_cat_row); preferences_group.add (entry); - this.set_extra_child (preferences_group); + this.set_extra_child (preferences_group); - grade_spinbutton.changed.connect (() => { - this.set_response_enabled ("add", true); - }); - } - - public bool set_variables () { - grade = grade_spinbutton.get_value ().to_string (); - note = (string) entry.get_text (); - return true; - } + response.connect ((response_id) => { + if (response_id == "add") { + subject.new_grade (grade_spinbutton.get_value ().to_string (), (string) entry.get_text (), cat_model.get_string (choose_cat_row.get_selected ())); + } - public string get_grade () { - return grade; - } + destroy (); + }); - public string get_note () { - return note; + grade_spinbutton.changed.connect (() => { + set_response_enabled ("add", true); + }); } } diff --git a/src/newgradebutton.vala b/src/newgradebutton.vala deleted file mode 100644 index f0f177c..0000000 --- a/src/newgradebutton.vala +++ /dev/null @@ -1,7 +0,0 @@ -public class NewGradeButton : Gtk.Button{ - public int index; - - public NewGradeButton (int i) { - index = i; - } -} \ No newline at end of file diff --git a/src/subject-page.vala b/src/subject-page.vala index f1fe33b..7d8b8d1 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -80,7 +80,7 @@ public class SubjectPage : Gtk.Box { average_box.append (avg_label); //NEW GRADE BUTTON - var new_grade_button = new NewGradeButton (0) { + var new_grade_button = new Gtk.Button () { icon_name = "add-list-symbolic" }; new_grade_button.halign = END; @@ -147,14 +147,6 @@ public class SubjectPage : Gtk.Box { public void new_grade_dialog () { if (subject.categories_by_name.length > 0){ var dialog = new NewGradeDialog ((Window) get_root (), subject); - - dialog.response.connect ((response_id) => { - if (response_id == "add") { - dialog.set_variables (); - subject.new_grade (dialog.get_grade (), dialog.get_note (), (int) dialog.choose_cat_row.get_selected ()); - } - dialog.destroy (); - }); dialog.present (); } else { var ErrorDialog = new Adw.MessageDialog ((Window) get_root (), _("Error"), _("This subject has no categories. Add at least one category in order to add a grade.")); diff --git a/src/subject-parser.vala b/src/subject-parser.vala index 8bc1bb8..f978b89 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -18,7 +18,7 @@ public class SubjectParser : Object { int j2 = 0; while (j2 < grade_string_arr.length) { - result_subject.grades_model.append (new Grade (grade_string_arr[j2++], grade_string_arr[j2++], int.parse (grade_string_arr[j2++]))); + result_subject.grades_model.append (new Grade (grade_string_arr[j2++], grade_string_arr[j2++], grade_string_arr[j2++])); } return result_subject; @@ -49,7 +49,7 @@ public class SubjectParser : Object { } result = result + ((Grade) sub.grades_model.get_item (i)).grade + "#"; result = result + ((Grade) sub.grades_model.get_item (i)).note + "#"; - result = result + ((Grade) sub.grades_model.get_item (i)).cat.to_string (); + result = result + ((Grade) sub.grades_model.get_item (i)).category_name; } return result; diff --git a/src/subject.vala b/src/subject.vala index 348a514..fc243a8 100644 --- a/src/subject.vala +++ b/src/subject.vala @@ -1,21 +1,18 @@ public class Subject : Object{ public string name { get; set; } - public Grade[] grades { get; set; } - public ListStore grades_model { get; set; } - public Category[] categories { get; set; } - public HashTable categories_by_name { get; set; } - public int cat_arr_size = 5; - public int grade_arr_size = 20; + public ListStore grades_model { get; construct; } + public HashTable categories_by_name { get; construct; } - public Subject (string n) { - name = n; - grades = new Grade[grade_arr_size]; + public Subject (string name) { + Object (name: name); + } + + construct { grades_model = new ListStore (typeof (Grade)); - categories = new Category[cat_arr_size]; categories_by_name = new HashTable (str_hash, str_equal); } - public void new_grade (string grade, string note, int c) { - grades_model.append (new Grade (grade, note, c)); + public void new_grade (string grade, string note, string c) { + grades_model.insert (0, new Grade (grade, note, c)); } } From 83670871b676142c66f92083e89343a415e067c9 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 22:01:39 +0100 Subject: [PATCH 12/29] add average calculation --- src/subject-manager.vala | 37 ------------------------------ src/subject-page.vala | 49 ++++++++++++++++++++++++++-------------- src/subject.vala | 7 ++++++ 3 files changed, 39 insertions(+), 54 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index 120478b..d0219ea 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -75,46 +75,9 @@ public class SubjectManager : Object { } } - - - // public void new_grade (int index, string grade, string note, int c) { - // bool worked = false; - - // for (int i = 0; i < subjects[index].grades.length; i++) { - // if (subjects[index].grades[i] == null) { - // subjects[index].grades[i] = new Grade (grade, note, c); - // i = subjects[index].grades.length; - // worked = true; - // } - // } - - - // if (worked == false) { - // print ("no more grades available"); - // } else { - // window_grade_rows_ui (index); - // } - // } - - - - public void new_subject (string name, Category[] c) { bool worked = false; subjects[name] = new Subject (name); } - - // public void delete_grade (int sub_index, int gra_index) { - // subjects[sub_index].grades[gra_index] = null; - - - // for (int i = gra_index; i < subjects[sub_index].grades.length - 1; i++) { - // subjects[sub_index].grades[i] = subjects[sub_index].grades[i + 1]; - // } - - // subjects[sub_index].grades[subjects[sub_index].grades.length - 1] = null; - - // window_grade_rows_ui (sub_index); - // } } diff --git a/src/subject-page.vala b/src/subject-page.vala index 7d8b8d1..b0df5c9 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -119,6 +119,31 @@ public class SubjectPage : Gtk.Box { edit_subject_dialog (); }); + void calculate_average () { + if (subject.grades_model.get_n_items () == 0) { + avg_label.label = "0.00"; + return; + } + + var table = new HashTable (str_hash, str_equal); + var table2 = new HashTable (str_hash, str_equal); + + for (int i = 0; i < subject.grades_model.get_n_items (); i++) { + var grade = (Grade) subject.grades_model.get_item (i); + table[grade.category_name] = table[grade.category_name] == null ? double.parse (grade.grade) : table[grade.category_name] + double.parse (grade.grade); + table2[grade.category_name] += table2[grade.category_name] == null ? 1 : table2[grade.category_name] + 1; + } + + double percentage_divider = 0; + double avg = 0; + foreach (var cat in table.get_keys ()) { + avg += (table[cat] / table2[cat]) * subject.categories_by_name[cat].percentage; + percentage_divider += subject.categories_by_name[cat].percentage; + } + + avg_label.label = "%.2f".printf (avg / percentage_divider); + } + subject.grades_model.items_changed.connect (() => { if (subject.grades_model.get_n_items () > 0 && nyttbox.get_last_child () == status_page) { nyttbox.remove (status_page); @@ -127,21 +152,11 @@ public class SubjectPage : Gtk.Box { nyttbox.remove (list_box); nyttbox.append (status_page); } - // double percentage_divider = 0; - - // int i = 0; - // for (; i < subject.grades_model.get_n_items (), i++) { - // if (number_of_grades[j] != 0) { - // avg_calculated[j] = average[j] / number_of_grades[j]; - // final_avg += avg_calculated[j] * subjects[i].categories[j].percentage; - // percentage_divider += subjects[i].categories[j].percentage; - // } - // } - // if (percentage_divider != 0) { - // string average_string = "%.2f".printf (final_avg / percentage_divider); - // avg[i].set_label (average_string); - // } + + calculate_average (); }); + + calculate_average (); } public void new_grade_dialog () { @@ -161,7 +176,7 @@ public class SubjectPage : Gtk.Box { new EditSubjectDialog ((Window) get_root (), subject).present (); } - private static Gtk.Widget widget_create_func (Object obj) { + private Gtk.Widget widget_create_func (Object obj) { var grade = (Grade) obj; var delete_button = new Gtk.Button () { @@ -182,7 +197,7 @@ public class SubjectPage : Gtk.Box { delete_button.clicked.connect (() => { Adw.MessageDialog msg = new Adw.MessageDialog ( - null, //TODO + (Window) get_root (), _("Delete Grade?"), _("If you delete this grade, its information will be deleted permanently.") ); @@ -192,7 +207,7 @@ public class SubjectPage : Gtk.Box { msg.set_close_response ("cancel"); msg.response.connect ((response) => { if (response == "delete") { - // delete_grade (delete_button.subject_index, delete_button.grade_index); + subject.delete_grade (grade); } msg.destroy (); }); diff --git a/src/subject.vala b/src/subject.vala index fc243a8..8f32a99 100644 --- a/src/subject.vala +++ b/src/subject.vala @@ -15,4 +15,11 @@ public class Subject : Object{ public void new_grade (string grade, string note, string c) { grades_model.insert (0, new Grade (grade, note, c)); } + + public void delete_grade (Grade grade) { + uint pos; + if (grades_model.find (grade, out pos)) { + grades_model.remove (pos); + } + } } From ac32b736f3a284f6e76a538d70efac9ddaac3c86 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 22:32:42 +0100 Subject: [PATCH 13/29] Add subject deletion that doesn't work --- src/edit-subject-dialog.vala | 5 ++--- src/subject.vala | 1 + src/window.vala | 6 ++++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/edit-subject-dialog.vala b/src/edit-subject-dialog.vala index 49fa49e..2eca63f 100644 --- a/src/edit-subject-dialog.vala +++ b/src/edit-subject-dialog.vala @@ -101,9 +101,8 @@ public class EditSubjectDialog : Adw.Window { case "0": break; case "1": - subject = null; - accept = true; - this.close (); + subject.deleted = true; + close (); break; } }); diff --git a/src/subject.vala b/src/subject.vala index 8f32a99..9ca204e 100644 --- a/src/subject.vala +++ b/src/subject.vala @@ -2,6 +2,7 @@ public class Subject : Object{ public string name { get; set; } public ListStore grades_model { get; construct; } public HashTable categories_by_name { get; construct; } + public bool deleted { get; set; default = false; } public Subject (string name) { Object (name: name); diff --git a/src/window.vala b/src/window.vala index 055870f..cdab0eb 100644 --- a/src/window.vala +++ b/src/window.vala @@ -58,6 +58,12 @@ public class Window : Adw.ApplicationWindow { subject_manager.read_data (); foreach (var subject in subject_manager.subjects.get_values ()) { + subject.notify["deleted"].connect (() => { + if (subject.deleted) { + //TODO: Remove without crash + } + warning ("removed"); + }); stack.add_titled (new SubjectPage (subject), subject.name, subject.name); } From b98879cd35386571208a3efb89bef1ee6acb73ba Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 23:22:05 +0100 Subject: [PATCH 14/29] Some spaces instead of tabs --- src/window.vala | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/window.vala b/src/window.vala index cdab0eb..c6ce9c9 100644 --- a/src/window.vala +++ b/src/window.vala @@ -23,18 +23,18 @@ public class Window : Adw.ApplicationWindow { tooltip_text = _("Add a New Subject") }; - var header_bar = new Adw.HeaderBar () { hexpand = true }; - header_bar.pack_end (new_subject_button); + var header_bar = new Adw.HeaderBar () { hexpand = true }; + header_bar.pack_end (new_subject_button); var stack_sidebar = new Gtk.StackSidebar () { stack = stack }; stack_sidebar.set_css_classes ({ "" }); - var scrolled_window = new Gtk.ScrolledWindow () { - vexpand = true, - child = stack_sidebar - }; + var scrolled_window = new Gtk.ScrolledWindow () { + vexpand = true, + child = stack_sidebar + }; var sidebar = new Adw.ToolbarView () { content = scrolled_window @@ -46,14 +46,14 @@ public class Window : Adw.ApplicationWindow { content = stack }; - bpoint = new Adw.Breakpoint (Adw.BreakpointCondition.parse ("max-width: 530px")); - bpoint.add_setter (split_view, "show_sidebar", false); - bpoint.add_setter (split_view, "collapsed", true); - add_breakpoint (bpoint); + bpoint = new Adw.Breakpoint (Adw.BreakpointCondition.parse ("max-width: 530px")); + bpoint.add_setter (split_view, "show_sidebar", false); + bpoint.add_setter (split_view, "collapsed", true); + add_breakpoint (bpoint); - content = split_view; + content = split_view; - var subject_manager = SubjectManager.get_default (); + var subject_manager = SubjectManager.get_default (); subject_manager.read_data (); From 711134875e7b1be996222144eb8c4d68bf1560c9 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 23:40:52 +0100 Subject: [PATCH 15/29] Get live subject adding working --- src/application.vala | 2 +- src/new-subject-dialog.vala | 17 +++++++---------- src/subject-manager.vala | 9 +++++++++ src/window.vala | 10 +++++----- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/application.vala b/src/application.vala index fd9f6f1..e74e118 100644 --- a/src/application.vala +++ b/src/application.vala @@ -31,7 +31,7 @@ public class MyApp : Adw.Application { var dialog = new NewSubjectDialog (main_window); dialog.close_request.connect (() => { if (dialog.accept) { - SubjectManager.get_default ().new_subject (dialog.name_entry_box.get_text (), dialog.categories); + SubjectManager.get_default ().new_subject (dialog.name_entry_box.get_text (), dialog.get_categories ()); } dialog.destroy (); return true; diff --git a/src/new-subject-dialog.vala b/src/new-subject-dialog.vala index f21ce68..74ac871 100644 --- a/src/new-subject-dialog.vala +++ b/src/new-subject-dialog.vala @@ -1,5 +1,5 @@ public class NewSubjectDialog : Adw.Window { - public Category[] categories; + private Category[] categories = {}; public Gtk.Box main_box; public Adw.EntryRow name_entry_box; private Gtk.Button new_cat_button; @@ -16,8 +16,6 @@ public class NewSubjectDialog : Adw.Window { height_request: 360 ); - categories = new Category[5]; - var tbv = new Adw.ToolbarView (); this.set_content (tbv); @@ -101,13 +99,12 @@ public class NewSubjectDialog : Adw.Window { } public void add_cat (string n, double p) { - for (int i = 0; i < categories.length; i++) { - if (categories[i] == null) { - categories[i] = new Category (n, p); - i = categories.length; - categories_list_ui (); - } - } + categories += new Category (n, p); + categories_list_ui (); + } + + public Category[] get_categories () { + return categories; } public void categories_list_ui () { diff --git a/src/subject-manager.vala b/src/subject-manager.vala index d0219ea..704b8fe 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -4,6 +4,8 @@ public class SubjectManager : Object { return instance.once (() => new SubjectManager ()); } + public signal void subject_added (Subject subject); + public HashTable subjects; construct { @@ -50,6 +52,7 @@ public class SubjectManager : Object { var parser = new SubjectParser (); Subject sub = parser.to_object (read_from_file (file)); subjects[sub.name] = sub; + subject_added (sub); } } @@ -79,5 +82,11 @@ public class SubjectManager : Object { bool worked = false; subjects[name] = new Subject (name); + + foreach (var cat in c) { + subjects[name].categories_by_name[cat.name] = cat; + } + + subject_added (subjects[name]); } } diff --git a/src/window.vala b/src/window.vala index c6ce9c9..94e9678 100644 --- a/src/window.vala +++ b/src/window.vala @@ -55,9 +55,7 @@ public class Window : Adw.ApplicationWindow { var subject_manager = SubjectManager.get_default (); - subject_manager.read_data (); - - foreach (var subject in subject_manager.subjects.get_values ()) { + subject_manager.subject_added.connect ((subject) => { subject.notify["deleted"].connect (() => { if (subject.deleted) { //TODO: Remove without crash @@ -65,12 +63,14 @@ public class Window : Adw.ApplicationWindow { warning ("removed"); }); stack.add_titled (new SubjectPage (subject), subject.name, subject.name); - } + }); + + subject_manager.read_data (); close_request.connect (() => { set_visible (false); subject_manager.write_data (); - return true; + return false; }); } } From 1ca099c009c0358c645040268496ab8b7b2416f5 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Wed, 29 Nov 2023 23:58:42 +0100 Subject: [PATCH 16/29] Make cancel work in edit subject dialog --- src/edit-subject-dialog.vala | 44 ++++++++++++++++++++---------------- src/subject.vala | 2 +- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/edit-subject-dialog.vala b/src/edit-subject-dialog.vala index 2eca63f..4784b27 100644 --- a/src/edit-subject-dialog.vala +++ b/src/edit-subject-dialog.vala @@ -1,8 +1,8 @@ public class EditSubjectDialog : Adw.Window { - private Adw.PreferencesGroup cat_list_box; - public bool accept = false; - public Subject subject; + private Subject subject; private List cat_rows; + private HashTable categories; + private Adw.PreferencesGroup cat_list_box; public EditSubjectDialog (Adw.ApplicationWindow parent, Subject s) { Object ( @@ -19,23 +19,25 @@ public class EditSubjectDialog : Adw.Window { cat_rows = new List (); + var cb = new Gtk.Button.with_label (_("Cancel")); + cb.clicked.connect (() => { + close (); + }); + + var ab = new Gtk.Button.with_label (_("Save")) { css_classes = { "suggested-action" } }; + ab.clicked.connect (() => { + subject.categories_by_name = categories; + close (); + }); + + var size_group = new Gtk.SizeGroup (BOTH); + size_group.add_widget (cb); + size_group.add_widget (ab); + var hb = new Adw.HeaderBar () { show_end_title_buttons = false, show_start_title_buttons = false, }; - - var cb = new Gtk.Button.with_label (_("Cancel")); - cb.clicked.connect (() => { - accept = false; - this.close (); - }); - - var ab = new Gtk.Button.with_label (_("Save")) { css_classes = { "suggested-action" } }; - ab.clicked.connect (() => { - accept = true; - this.close (); - }); - hb.pack_start (cb); hb.pack_end (ab); @@ -77,7 +79,6 @@ public class EditSubjectDialog : Adw.Window { child = clamp }; - var tbv = new Adw.ToolbarView () { content = scrolled_window }; @@ -85,6 +86,11 @@ public class EditSubjectDialog : Adw.Window { content = tbv; + categories = new HashTable (str_hash, str_equal); + subject.categories_by_name.@foreach ((key, val) => { + categories[key] = val; + }); + load_list (); subject_delete_button.clicked.connect (() => { @@ -123,7 +129,7 @@ public class EditSubjectDialog : Adw.Window { } public void add_cat (string n, double p) { - subject.categories_by_name[n] = new Category (n, p); + categories[n] = new Category (n, p); load_list (); } @@ -134,7 +140,7 @@ public class EditSubjectDialog : Adw.Window { cat_rows = new List (); - foreach (var category in subject.categories_by_name.get_values ()) { + foreach (var category in categories.get_values ()) { var cat_row = new Adw.ActionRow () { title = category.name, subtitle = category.percentage.to_string () + "%" diff --git a/src/subject.vala b/src/subject.vala index 9ca204e..77784c8 100644 --- a/src/subject.vala +++ b/src/subject.vala @@ -1,7 +1,7 @@ public class Subject : Object{ public string name { get; set; } public ListStore grades_model { get; construct; } - public HashTable categories_by_name { get; construct; } + public HashTable categories_by_name { get; set; } public bool deleted { get; set; default = false; } public Subject (string name) { From f95f3a057a9d962bff785d4c600b902e70c75e3d Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 3 Dec 2023 16:18:27 +0100 Subject: [PATCH 17/29] Various improvements --- meson.build | 1 - src/delete-subject-button.vala | 10 ---------- src/new-subject-dialog.vala | 22 ---------------------- src/subject-manager.vala | 6 +----- src/subject-parser.vala | 13 +++++++++++++ src/window.vala | 4 +++- 6 files changed, 17 insertions(+), 39 deletions(-) delete mode 100644 src/delete-subject-button.vala diff --git a/meson.build b/meson.build index fd79ce8..e403352 100644 --- a/meson.build +++ b/meson.build @@ -36,7 +36,6 @@ executable( 'src' / 'subject.vala', 'src' / 'new-grade-dialog.vala', 'src' / 'new-subject-dialog.vala', - 'src' / 'delete-subject-button.vala', 'src' / 'category.vala', 'src' / 'edit-subject-dialog.vala', 'src' / 'add-category-dialog.vala', diff --git a/src/delete-subject-button.vala b/src/delete-subject-button.vala deleted file mode 100644 index fac2a7c..0000000 --- a/src/delete-subject-button.vala +++ /dev/null @@ -1,10 +0,0 @@ -public class DeleteSubjectButton : Gtk.Button { - public int index; - - public DeleteSubjectButton (int i) { - label = "Delete this subject"; - index = i; - halign = END; - vexpand = false; - } -} diff --git a/src/new-subject-dialog.vala b/src/new-subject-dialog.vala index 74ac871..5f83fe2 100644 --- a/src/new-subject-dialog.vala +++ b/src/new-subject-dialog.vala @@ -74,28 +74,6 @@ public class NewSubjectDialog : Adw.Window { }); categories_list_ui (); - /*var cat_list_box = new Gtk.ListBox (); - cat_list_box.add_css_class("boxed-list"); - - var scroll_container = new Gtk.ScrolledWindow () { - margin_bottom = 20, - margin_top = 20, - margin_start = 20, - margin_end = 20, - hexpand = true, - vexpand = true - }; - scroll_container.set_child(cat_list_box); - main_box.append(scroll_container); - - - for (int i = 0; i < subject.categories.length && subject.categories[i] != null; i++) { - var cat_row = new Adw.ActionRow () { - title = subject.categories[i].name, - subtitle = subject.categories[i].percentage.to_string () + "%" - }; - cat_list_box.append(cat_row); - }*/ } public void add_cat (string n, double p) { diff --git a/src/subject-manager.vala b/src/subject-manager.vala index 704b8fe..93fa0d7 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -22,11 +22,7 @@ public class SubjectManager : Object { } } - - - - public string read_from_file (File file) - { + public string read_from_file (File file) { try { string file_content = ""; uint8[] contents; diff --git a/src/subject-parser.vala b/src/subject-parser.vala index f978b89..0173b94 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -24,7 +24,20 @@ public class SubjectParser : Object { return result_subject; } + public string to_json (Subject subject) { + var node = Json.gobject_serialize (subject); + + var generator = new Json.Generator () { + root = node, + pretty = true + }; + + print (generator.to_data (null)); + return ""; + } + public string to_string (Subject sub) { + to_json (sub); string result = sub.name + "%"; bool first = true; diff --git a/src/window.vala b/src/window.vala index 94e9678..74aae34 100644 --- a/src/window.vala +++ b/src/window.vala @@ -23,7 +23,9 @@ public class Window : Adw.ApplicationWindow { tooltip_text = _("Add a New Subject") }; - var header_bar = new Adw.HeaderBar () { hexpand = true }; + var header_bar = new Adw.HeaderBar () { + hexpand = true + }; header_bar.pack_end (new_subject_button); var stack_sidebar = new Gtk.StackSidebar () { From 077a1f710e24b75912b28f225e551855d24cbd21 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 3 Dec 2023 17:08:05 +0100 Subject: [PATCH 18/29] Dont use a stack --- src/subject-manager.vala | 7 ++- src/subject-page.vala | 133 +++++++++++++++++++++------------------ src/window.vala | 42 +++++++------ 3 files changed, 100 insertions(+), 82 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index 93fa0d7..f05488f 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -7,9 +7,12 @@ public class SubjectManager : Object { public signal void subject_added (Subject subject); public HashTable subjects; + public ListStore subjects_model; construct { subjects = new HashTable (str_hash, str_equal); + + subjects_model = new ListStore (typeof (Subject)); } public void write_to_file (File file, string write_data) { @@ -48,7 +51,7 @@ public class SubjectManager : Object { var parser = new SubjectParser (); Subject sub = parser.to_object (read_from_file (file)); subjects[sub.name] = sub; - subject_added (sub); + subjects_model.append (sub); } } @@ -83,6 +86,6 @@ public class SubjectManager : Object { subjects[name].categories_by_name[cat.name] = cat; } - subject_added (subjects[name]); + subjects_model.append (subjects[name]); } } diff --git a/src/subject-page.vala b/src/subject-page.vala index b0df5c9..ac3bb8a 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -1,10 +1,26 @@ public class SubjectPage : Gtk.Box { - public Subject subject { get; construct; } + private Subject _subject; + public Subject subject { + get { + return _subject; + } set { + if (_subject != null) { + _subject.grades_model.items_changed.disconnect (on_items_changed); + } + + _subject = value; + _subject.grades_model.items_changed.connect (on_items_changed); + list_box.bind_model (_subject.grades_model, widget_create_func); - public SubjectPage (Subject subject) { - Object (subject: subject); + on_items_changed (); + } } + private Gtk.Label avg_label; + private Gtk.Box content_box; + private Gtk.ListBox list_box; + private Adw.StatusPage status_page; + construct { var menu = new Menu (); var menu_section1 = new Menu (); @@ -41,31 +57,12 @@ public class SubjectPage : Gtk.Box { header_bar.pack_start (toggle_button); - //SUBJECT BOX - var nyttbox = new Gtk.Box (VERTICAL, 0) { - vexpand = true, - margin_start = 1, - margin_end = 1 - }; - var gtk_sw = new Gtk.ScrolledWindow (); - var adw_c = new Adw.Clamp () { - margin_start = 19, - margin_end = 19, - margin_top = 20, - margin_bottom = 20, - maximum_size = 600, - tightening_threshold = 400 - }; - gtk_sw.set_child (adw_c); - adw_c.set_child (nyttbox); - //TOP BOX var top_box = new Gtk.Box (HORIZONTAL, 0) { height_request = 40, hexpand = true, homogeneous = true }; - nyttbox.append (top_box); //AVERAGE LABEL var average_box = new Gtk.Box (HORIZONTAL, 10) { @@ -76,7 +73,7 @@ public class SubjectPage : Gtk.Box { var average_label = new Gtk.Label (_("Average:")) { css_classes = { "title-3" } }; average_box.append (average_label); - var avg_label = new Gtk.Label ("0.00") { css_classes = { "title-3" } }; + avg_label = new Gtk.Label ("0.00") { css_classes = { "title-3" } }; average_box.append (avg_label); //NEW GRADE BUTTON @@ -90,21 +87,36 @@ public class SubjectPage : Gtk.Box { top_box.append (new_grade_button); - var status_page = new Adw.StatusPage () { + status_page = new Adw.StatusPage () { title = _("No Grades"), description = _("Add new grades by clicking the “New Grade…” button."), vexpand = true }; - var list_box = new Gtk.ListBox () {vexpand = false, margin_top = 20}; + list_box = new Gtk.ListBox () {vexpand = false, margin_top = 20}; list_box.add_css_class ("boxed-list"); - list_box.bind_model (subject.grades_model, widget_create_func); - if (subject.grades_model.get_n_items () > 0) { - nyttbox.append (list_box); - } else { - nyttbox.append (status_page); - } + content_box = new Gtk.Box (VERTICAL, 0) { + vexpand = true, + margin_start = 1, + margin_end = 1 + }; + content_box.append (top_box); + content_box.append (status_page); + + var adw_c = new Adw.Clamp () { + margin_start = 19, + margin_end = 19, + margin_top = 20, + margin_bottom = 20, + maximum_size = 600, + tightening_threshold = 400, + child = content_box + }; + + var gtk_sw = new Gtk.ScrolledWindow () { + child = adw_c + }; var toolbar_view = new Adw.ToolbarView () { hexpand = true, @@ -118,43 +130,41 @@ public class SubjectPage : Gtk.Box { edit_subject_button.clicked.connect (() => { edit_subject_dialog (); }); + } - void calculate_average () { - if (subject.grades_model.get_n_items () == 0) { - avg_label.label = "0.00"; - return; - } - - var table = new HashTable (str_hash, str_equal); - var table2 = new HashTable (str_hash, str_equal); + private void calculate_average () { + if (subject.grades_model.get_n_items () == 0) { + avg_label.label = "0.00"; + return; + } - for (int i = 0; i < subject.grades_model.get_n_items (); i++) { - var grade = (Grade) subject.grades_model.get_item (i); - table[grade.category_name] = table[grade.category_name] == null ? double.parse (grade.grade) : table[grade.category_name] + double.parse (grade.grade); - table2[grade.category_name] += table2[grade.category_name] == null ? 1 : table2[grade.category_name] + 1; - } + var table = new HashTable (str_hash, str_equal); + var table2 = new HashTable (str_hash, str_equal); - double percentage_divider = 0; - double avg = 0; - foreach (var cat in table.get_keys ()) { - avg += (table[cat] / table2[cat]) * subject.categories_by_name[cat].percentage; - percentage_divider += subject.categories_by_name[cat].percentage; - } + for (int i = 0; i < subject.grades_model.get_n_items (); i++) { + var grade = (Grade) subject.grades_model.get_item (i); + table[grade.category_name] = table[grade.category_name] == null ? double.parse (grade.grade) : table[grade.category_name] + double.parse (grade.grade); + table2[grade.category_name] += table2[grade.category_name] == null ? 1 : table2[grade.category_name] + 1; + } - avg_label.label = "%.2f".printf (avg / percentage_divider); + double percentage_divider = 0; + double avg = 0; + foreach (var cat in table.get_keys ()) { + avg += (table[cat] / table2[cat]) * subject.categories_by_name[cat].percentage; + percentage_divider += subject.categories_by_name[cat].percentage; } - subject.grades_model.items_changed.connect (() => { - if (subject.grades_model.get_n_items () > 0 && nyttbox.get_last_child () == status_page) { - nyttbox.remove (status_page); - nyttbox.append (list_box); - } else if (subject.grades_model.get_n_items () == 0 && nyttbox.get_last_child () == list_box) { - nyttbox.remove (list_box); - nyttbox.append (status_page); - } + avg_label.label = "%.2f".printf (avg / percentage_divider); + } - calculate_average (); - }); + private void on_items_changed () { + if (subject.grades_model.get_n_items () > 0 && content_box.get_last_child () == status_page) { + content_box.remove (status_page); + content_box.append (list_box); + } else if (subject.grades_model.get_n_items () == 0 && content_box.get_last_child () == list_box) { + content_box.remove (list_box); + content_box.append (status_page); + } calculate_average (); } @@ -171,7 +181,6 @@ public class SubjectPage : Gtk.Box { } } - public void edit_subject_dialog () { new EditSubjectDialog ((Window) get_root (), subject).present (); } diff --git a/src/window.vala b/src/window.vala index 74aae34..d28dcc5 100644 --- a/src/window.vala +++ b/src/window.vala @@ -1,7 +1,7 @@ public class Window : Adw.ApplicationWindow { public Adw.OverlaySplitView split_view; public Adw.Breakpoint bpoint; - private Gtk.Stack stack; + private SubjectPage subject_page; public Window (MyApp app) { Object ( @@ -15,7 +15,7 @@ public class Window : Adw.ApplicationWindow { } construct { - stack = new Gtk.Stack (); + var subject_manager = SubjectManager.get_default (); var new_subject_button = new Gtk.Button () { icon_name = "list-add-symbolic", @@ -28,14 +28,16 @@ public class Window : Adw.ApplicationWindow { }; header_bar.pack_end (new_subject_button); - var stack_sidebar = new Gtk.StackSidebar () { - stack = stack - }; - stack_sidebar.set_css_classes ({ "" }); + var navigation_sidebar = new Gtk.ListBox (); + navigation_sidebar.add_css_class ("navigation-sidebar"); + navigation_sidebar.bind_model (subject_manager.subjects_model, (obj) => { + var sub = (Subject) obj; + return new Gtk.Label (sub.name) { xalign = 0 }; + }); var scrolled_window = new Gtk.ScrolledWindow () { vexpand = true, - child = stack_sidebar + child = navigation_sidebar }; var sidebar = new Adw.ToolbarView () { @@ -43,9 +45,11 @@ public class Window : Adw.ApplicationWindow { }; sidebar.add_top_bar (header_bar); + subject_page = new SubjectPage (); + split_view = new Adw.OverlaySplitView () { sidebar = sidebar, - content = stack + content = subject_page }; bpoint = new Adw.Breakpoint (Adw.BreakpointCondition.parse ("max-width: 530px")); @@ -55,18 +59,20 @@ public class Window : Adw.ApplicationWindow { content = split_view; - var subject_manager = SubjectManager.get_default (); - - subject_manager.subject_added.connect ((subject) => { - subject.notify["deleted"].connect (() => { - if (subject.deleted) { - //TODO: Remove without crash - } - warning ("removed"); - }); - stack.add_titled (new SubjectPage (subject), subject.name, subject.name); + navigation_sidebar.row_activated.connect ((row) => { + subject_page.subject = (Subject) subject_manager.subjects_model.get_item (row.get_index ()); }); + // subject_manager.subject_added.connect ((subject) => { + // subject.notify["deleted"].connect (() => { + // if (subject.deleted) { + // //TODO: Remove without crash + // } + // warning ("removed"); + // }); + // stack.add_titled (new SubjectPage (), subject.name, subject.name); + // }); + subject_manager.read_data (); close_request.connect (() => { From f9638c98b821a65d6e028accb04650c221b5c5b5 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 3 Dec 2023 17:18:56 +0100 Subject: [PATCH 19/29] remove subjects hashtable --- src/subject-manager.vala | 39 ++++++++++++++++++++------------------- src/window.vala | 14 ++------------ 2 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index f05488f..d7f26a1 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -4,15 +4,10 @@ public class SubjectManager : Object { return instance.once (() => new SubjectManager ()); } - public signal void subject_added (Subject subject); - - public HashTable subjects; - public ListStore subjects_model; + public ListStore subjects { get; construct; } construct { - subjects = new HashTable (str_hash, str_equal); - - subjects_model = new ListStore (typeof (Subject)); + subjects = new ListStore (typeof (Subject)); } public void write_to_file (File file, string write_data) { @@ -50,13 +45,11 @@ public class SubjectManager : Object { var parser = new SubjectParser (); Subject sub = parser.to_object (read_from_file (file)); - subjects[sub.name] = sub; - subjects_model.append (sub); + add_subject (sub); } } public void write_data () { - int z = 0; File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); if (!dir.query_exists ()) { try { @@ -65,27 +58,35 @@ public class SubjectManager : Object { print (e.message); } } - int i = 0; - foreach (var subject in subjects.get_values ()) { + + for (int i = 0; i < subjects.get_n_items (); i++) { + var subject = (Subject) subjects.get_item (i); + var parser = new SubjectParser (); File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); //TODO: Delete old files write_to_file (file, parser.to_string (subject)); warning ("write: %s", parser.to_string (subject)); - z = i + 1; - i++; } } public void new_subject (string name, Category[] c) { - bool worked = false; - - subjects[name] = new Subject (name); + var subject = new Subject (name); foreach (var cat in c) { - subjects[name].categories_by_name[cat.name] = cat; + subject.categories_by_name[cat.name] = cat; } - subjects_model.append (subjects[name]); + add_subject (subject); + } + + private void add_subject (Subject subject) { + subjects.append (subject); + subject.notify["deleted"].connect (() => { + uint pos; + if (subjects.find (subject, out pos)) { + subjects.remove (pos); + } + }); } } diff --git a/src/window.vala b/src/window.vala index d28dcc5..ac9d31e 100644 --- a/src/window.vala +++ b/src/window.vala @@ -30,7 +30,7 @@ public class Window : Adw.ApplicationWindow { var navigation_sidebar = new Gtk.ListBox (); navigation_sidebar.add_css_class ("navigation-sidebar"); - navigation_sidebar.bind_model (subject_manager.subjects_model, (obj) => { + navigation_sidebar.bind_model (subject_manager.subjects, (obj) => { var sub = (Subject) obj; return new Gtk.Label (sub.name) { xalign = 0 }; }); @@ -60,19 +60,9 @@ public class Window : Adw.ApplicationWindow { content = split_view; navigation_sidebar.row_activated.connect ((row) => { - subject_page.subject = (Subject) subject_manager.subjects_model.get_item (row.get_index ()); + subject_page.subject = (Subject) subject_manager.subjects.get_item (row.get_index ()); }); - // subject_manager.subject_added.connect ((subject) => { - // subject.notify["deleted"].connect (() => { - // if (subject.deleted) { - // //TODO: Remove without crash - // } - // warning ("removed"); - // }); - // stack.add_titled (new SubjectPage (), subject.name, subject.name); - // }); - subject_manager.read_data (); close_request.connect (() => { From 3514bb95f7bd3c6ae03897778c83e6c76fca4c89 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 3 Dec 2023 17:37:01 +0100 Subject: [PATCH 20/29] Add placeholder --- src/subject-page.vala | 132 ++++++++++-------------------------------- 1 file changed, 32 insertions(+), 100 deletions(-) diff --git a/src/subject-page.vala b/src/subject-page.vala index ac3bb8a..19d9f5d 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -1,5 +1,5 @@ public class SubjectPage : Gtk.Box { - private Subject _subject; + private Subject? _subject = null; public Subject subject { get { return _subject; @@ -9,10 +9,13 @@ public class SubjectPage : Gtk.Box { } _subject = value; - _subject.grades_model.items_changed.connect (on_items_changed); - list_box.bind_model (_subject.grades_model, widget_create_func); - on_items_changed (); + if (_subject != null) { + _subject.grades_model.items_changed.connect (on_items_changed); + list_box.bind_model (_subject.grades_model, widget_create_func); + + on_items_changed (); + } } } @@ -118,9 +121,20 @@ public class SubjectPage : Gtk.Box { child = adw_c }; + var placeholder = new Adw.StatusPage () { + hexpand = true, + vexpand = true, + title = _("No Subjects"), + description = _("Add new subjects using the “+” button in the top left corner.") + }; + + var placeholder_stack = new Gtk.Stack (); + placeholder_stack.add_named (placeholder, "placeholder"); + placeholder_stack.add_named (gtk_sw, "content"); + var toolbar_view = new Adw.ToolbarView () { hexpand = true, - content = gtk_sw + content = placeholder_stack }; toolbar_view.add_top_bar (header_bar); append (toolbar_view); @@ -130,6 +144,19 @@ public class SubjectPage : Gtk.Box { edit_subject_button.clicked.connect (() => { edit_subject_dialog (); }); + + void check_placeholder () { + if (subject == null) { + placeholder_stack.visible_child = placeholder; + edit_subject_button.visible = false; + } else { + placeholder_stack.visible_child = gtk_sw; + edit_subject_button.visible = true; + } + } + + notify["subject"].connect (() => check_placeholder ()); + check_placeholder (); } private void calculate_average () { @@ -226,99 +253,4 @@ public class SubjectPage : Gtk.Box { return expander_row; } - - - - // public Gtk.Box window_grade_rows_ui (int i, Gtk.Box? nyttbox = null) { - // nyttbox = nyttbox ?? nyabox[i]; - // if ((nyttbox.get_first_child ().get_next_sibling ().name == "GtkListBox") || (nyttbox.get_first_child ().get_next_sibling ().name == "AdwStatusPage")) { - // nyttbox.remove (nyttbox.get_first_child ().get_next_sibling ()); - // } - - - // int[] average = new int[subjects[i].categories.length]; - // double[] number_of_grades = new double[subjects[i].categories.length]; - // double[] avg_calculated = new double[subjects[i].categories.length]; - // double final_avg = 0.00; - - // //LIST BOX - // if (subjects[i].grades[0] == null) { - // var adw_page = new Adw.StatusPage () { - // title = _("No Grades"), - // description = _("Add new grades by clicking the “New Grade…” button."), - // vexpand = true - // }; - // nyttbox.append (adw_page); - // return nyttbox; - // } else { - - // var list_box = new Gtk.ListBox () {vexpand = false, margin_top = 20}; - // list_box.add_css_class ("boxed-list"); - // //list_box.set_sort_func (sort_list); - // //list_box.set_filter_func (filter_list); - // nyttbox.append (list_box); - - // for (int j = 0; subjects[i].grades[j] != null; j++) { - // average[subjects[i].grades[j].cat] += int.parse (subjects[i].grades[j].grade); - // number_of_grades[subjects[i].grades[j].cat]++; - - - - // //expander row - // var expander_row = new Adw.ActionRow (); - // expander_row.set_title (subjects[i].grades[j].grade.to_string ()); - // if (subjects[i].grades[j].note == "") { - // expander_row.set_subtitle (subjects[i].categories[subjects[i].grades[j].cat].name); - // } else { - // expander_row.set_subtitle (subjects[i].categories[subjects[i].grades[j].cat].name + " — " + subjects[i].grades[j].note); - // } - // var delete_button = new DeleteButton (i, j); - // expander_row.add_suffix (delete_button); - - - - // //put everything together - // list_box.append (expander_row); - - - - // //CONNECT BUTTONS - // delete_button.clicked.connect (() => { - // Adw.MessageDialog msg = new Adw.MessageDialog ( - // main_window, - // _("Delete Grade?"), - // _("If you delete this grade, its information will be deleted permanently.") - // ); - // msg.add_response ("cancel", _("Cancel")); - // msg.add_response ("delete", _("Delete")); - // msg.set_response_appearance ("delete", DESTRUCTIVE); - // msg.set_close_response ("cancel"); - // msg.response.connect ((response) => { - // if (response == "delete") { - // delete_grade (delete_button.subject_index, delete_button.grade_index); - // } - // msg.destroy (); - // }); - - // msg.present (); - // }); - // // } - - // double percentage_divider = 0; - - // for (int j = 0; j < subjects[i].categories.length && subjects[i].categories[j] != null; j++) { - // if (number_of_grades[j] != 0) { - // avg_calculated[j] = average[j] / number_of_grades[j]; - // final_avg += avg_calculated[j] * subjects[i].categories[j].percentage; - // percentage_divider += subjects[i].categories[j].percentage; - // } - // } - // if (percentage_divider != 0) { - // string average_string = "%.2f".printf (final_avg / percentage_divider); - // avg[i].set_label (average_string); - // } - - // return nyttbox; - // } - // } } From c3554ed5b0da07a1fe96b51283387a082c5e9227 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 3 Dec 2023 17:42:40 +0100 Subject: [PATCH 21/29] Select a new subject on deletion --- src/window.vala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/window.vala b/src/window.vala index ac9d31e..6fb734c 100644 --- a/src/window.vala +++ b/src/window.vala @@ -63,6 +63,10 @@ public class Window : Adw.ApplicationWindow { subject_page.subject = (Subject) subject_manager.subjects.get_item (row.get_index ()); }); + subject_manager.subjects.items_changed.connect ((pos, rem, added) => { + subject_page.subject = (Subject) subject_manager.subjects.get_item (pos); + }); + subject_manager.read_data (); close_request.connect (() => { From bb9f78d645e1690990f1ef44fea63209ab3487f3 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sun, 10 Dec 2023 15:28:27 +0100 Subject: [PATCH 22/29] New saving process --- src/subject-manager.vala | 41 +++++++++++++++++++++++++++++++++++++--- src/window.vala | 6 ++++-- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index d7f26a1..38f3444 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -6,15 +6,18 @@ public class SubjectManager : Object { public ListStore subjects { get; construct; } + private ListStore deleted_subjects; + construct { subjects = new ListStore (typeof (Subject)); + deleted_subjects = new ListStore (typeof (Subject)); } - public void write_to_file (File file, string write_data) { + public async void write_to_file (File file, string write_data) { uint8[] write_bytes = (uint8[]) write_data.to_utf8 (); try { - file.replace_contents (write_bytes, null, false, FileCreateFlags.NONE, null, null); + yield file.replace_contents_async (write_bytes, null, false, FileCreateFlags.NONE, null, null); } catch (Error e) { print (e.message); } @@ -49,7 +52,7 @@ public class SubjectManager : Object { } } - public void write_data () { + public void writes_data () { File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); if (!dir.query_exists ()) { try { @@ -70,6 +73,37 @@ public class SubjectManager : Object { } } + public async void write_data_new () { + File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); + if (!dir.query_exists ()) { + try { + dir.make_directory_with_parents (); + } catch (Error e) { + critical ("Failed to save subjects: Failed to create savedata directory: %s", e.message); + } + } + + var parser = new SubjectParser (); + for (int i = 0; i < subjects.get_n_items (); i++) { + var subject = (Subject) subjects.get_item (i); + + var file = dir.get_child (subject.name); + yield write_to_file (file, parser.to_string (subject)); + } + + for (int i = 0; i < deleted_subjects.get_n_items (); i++) { + var subject = (Subject) subjects.get_item (i); + + var file = dir.get_child (subject.name); + + try { + yield file.delete_async (); + } catch (Error e) { + warning ("Failed to delete save file for subject '%s': %s", subject.name, e.message); + } + } + } + public void new_subject (string name, Category[] c) { var subject = new Subject (name); @@ -87,6 +121,7 @@ public class SubjectManager : Object { if (subjects.find (subject, out pos)) { subjects.remove (pos); } + deleted_subjects.append (subject); }); } } diff --git a/src/window.vala b/src/window.vala index 6fb734c..c7cc543 100644 --- a/src/window.vala +++ b/src/window.vala @@ -71,8 +71,10 @@ public class Window : Adw.ApplicationWindow { close_request.connect (() => { set_visible (false); - subject_manager.write_data (); - return false; + subject_manager.write_data_new.begin (() => { + destroy (); + }); + return Gdk.EVENT_STOP; }); } } From 4f82d9a6e755ce5d11d0e9aa70a8c9d42f3e2588 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 23 Dec 2023 12:14:06 +0100 Subject: [PATCH 23/29] Commit for transfer --- src/subject-manager.vala | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index 38f3444..67fff34 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -41,8 +41,7 @@ public class SubjectManager : Object { return "-1"; } - - public void read_data () { + public void read_data_legacy () { for (int i = 0; i < 20 && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); @@ -52,6 +51,30 @@ public class SubjectManager : Object { } } + public async void read_data () { + File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); + if (!dir.query_exists ()) { + try { + dir.make_directory_with_parents (); + } catch (Error e) { + critical ("Failed to save subjects: Failed to create savedata directory: %s", e.message); + } + } + + try { + var enumerator = yield dir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); + FileInfo info; + while ((info = enumerator.next_file (null)) != null) { + print ("%s\n", info.get_name ()); + print ("\t%s\n", info.get_file_type ().to_string ()); + print ("\t%s\n", info.get_is_symlink ().to_string ()); + print ("\t%s\n", info.get_is_hidden ().to_string ()); + print ("\t%s\n", info.get_is_backup ().to_string ()); + print ("\t%"+int64.FORMAT+"\n", info.get_size ()); + } + } + } + public void writes_data () { File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); if (!dir.query_exists ()) { From d4cb5fae2f234743c91696ee5baa02793a8142a0 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 23 Dec 2023 12:33:35 +0100 Subject: [PATCH 24/29] make loading save data work --- src/subject-manager.vala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index 67fff34..2f75a83 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -65,13 +65,14 @@ public class SubjectManager : Object { var enumerator = yield dir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); FileInfo info; while ((info = enumerator.next_file (null)) != null) { - print ("%s\n", info.get_name ()); - print ("\t%s\n", info.get_file_type ().to_string ()); - print ("\t%s\n", info.get_is_symlink ().to_string ()); - print ("\t%s\n", info.get_is_hidden ().to_string ()); - print ("\t%s\n", info.get_is_backup ().to_string ()); - print ("\t%"+int64.FORMAT+"\n", info.get_size ()); + var file = dir.get_child (info.get_name ()); + + var parser = new SubjectParser (); + var subject = parser.to_object (read_from_file (file)); + add_subject (subject); } + } catch (Error e) { + warning ("Failed to read data: %s", e.message); } } From 363e048148c78eae405870338fa75ff61e90a2a9 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 23 Dec 2023 12:40:07 +0100 Subject: [PATCH 25/29] Make toggling sidebar work --- src/subject-manager.vala | 2 +- src/subject-page.vala | 6 +++--- src/window.vala | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index 2f75a83..3982d5c 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -36,7 +36,7 @@ public class SubjectManager : Object { return file_content; } catch (Error e) { - print ("Error: %s\n", e.message); + warning ("Error: %s\n", e.message); } return "-1"; } diff --git a/src/subject-page.vala b/src/subject-page.vala index 19d9f5d..00184c7 100644 --- a/src/subject-page.vala +++ b/src/subject-page.vala @@ -19,6 +19,8 @@ public class SubjectPage : Gtk.Box { } } + public Gtk.ToggleButton toggle_button { get; construct; } + private Gtk.Label avg_label; private Gtk.Box content_box; private Gtk.ListBox list_box; @@ -42,13 +44,11 @@ public class SubjectPage : Gtk.Box { menu_model = menu }; - var toggle_button = new Gtk.ToggleButton () { + toggle_button = new Gtk.ToggleButton () { icon_name = "dock-left-symbolic", tooltip_text = _("Toggle Sidebar"), visible = false }; - // toggle_button.bind_property ("active", ((Window) get_root ()).split_view, "show_sidebar", BindingFlags.BIDIRECTIONAL); - // ((Window) get_root ()).bpoint.add_setter (toggle_button, "visible", true); var edit_subject_button = new Gtk.Button () { icon_name = "document-edit-symbolic" diff --git a/src/window.vala b/src/window.vala index c7cc543..5b7414e 100644 --- a/src/window.vala +++ b/src/window.vala @@ -55,10 +55,13 @@ public class Window : Adw.ApplicationWindow { bpoint = new Adw.Breakpoint (Adw.BreakpointCondition.parse ("max-width: 530px")); bpoint.add_setter (split_view, "show_sidebar", false); bpoint.add_setter (split_view, "collapsed", true); + bpoint.add_setter (subject_page.toggle_button, "visible", true); add_breakpoint (bpoint); content = split_view; + subject_page.toggle_button.bind_property ("active", split_view, "show-sidebar", BIDIRECTIONAL); + navigation_sidebar.row_activated.connect ((row) => { subject_page.subject = (Subject) subject_manager.subjects.get_item (row.get_index ()); }); From 1ad01e90af98862183d41dd38ee5516bbb604029 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 23 Dec 2023 14:10:30 +0100 Subject: [PATCH 26/29] Use keyfile for storage + select row in sidebar when subjects change --- src/subject-manager.vala | 98 +++++++++----------------------- src/subject-parser.vala | 117 +++++++++++++++++++++++++++------------ src/subject.vala | 12 +++- src/window.vala | 3 +- 4 files changed, 120 insertions(+), 110 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index 3982d5c..bf50f2e 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -6,21 +6,8 @@ public class SubjectManager : Object { public ListStore subjects { get; construct; } - private ListStore deleted_subjects; - construct { subjects = new ListStore (typeof (Subject)); - deleted_subjects = new ListStore (typeof (Subject)); - } - - public async void write_to_file (File file, string write_data) { - uint8[] write_bytes = (uint8[]) write_data.to_utf8 (); - - try { - yield file.replace_contents_async (write_bytes, null, false, FileCreateFlags.NONE, null, null); - } catch (Error e) { - print (e.message); - } } public string read_from_file (File file) { @@ -45,86 +32,54 @@ public class SubjectManager : Object { for (int i = 0; i < 20 && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); - var parser = new SubjectParser (); - Subject sub = parser.to_object (read_from_file (file)); + Subject sub = SubjectParser.to_object (read_from_file (file)); add_subject (sub); } } public async void read_data () { - File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); - if (!dir.query_exists ()) { - try { - dir.make_directory_with_parents (); - } catch (Error e) { - critical ("Failed to save subjects: Failed to create savedata directory: %s", e.message); - } + var keyfile = new KeyFile (); + + try { + keyfile.load_from_file (Environment.get_user_data_dir () + "/gradebook/subjects", NONE); + } catch (Error e) { + warning ("Failed to load keyfile: %s", e.message); + return; } try { - var enumerator = yield dir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NOFOLLOW_SYMLINKS); - FileInfo info; - while ((info = enumerator.next_file (null)) != null) { - var file = dir.get_child (info.get_name ()); + foreach (var group in keyfile.get_groups ()) { + var subject = new Subject (group); + SubjectParser.load_categories (subject, keyfile.get_string_list (group, "categories")); + SubjectParser.load_grades (subject, keyfile.get_string_list (group, "grades")); - var parser = new SubjectParser (); - var subject = parser.to_object (read_from_file (file)); add_subject (subject); - } + } } catch (Error e) { - warning ("Failed to read data: %s", e.message); + critical ("Failed to read data: %s", e.message); } } - public void writes_data () { - File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); - if (!dir.query_exists ()) { - try { - dir.make_directory_with_parents (); - } catch (Error e) { - print (e.message); - } - } + public async void write_data () { + var keyfile = new KeyFile (); + var parser = new SubjectParser (); for (int i = 0; i < subjects.get_n_items (); i++) { var subject = (Subject) subjects.get_item (i); - var parser = new SubjectParser (); - File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); - //TODO: Delete old files - write_to_file (file, parser.to_string (subject)); - warning ("write: %s", parser.to_string (subject)); - } - } - - public async void write_data_new () { - File dir = File.new_for_path (Environment.get_user_data_dir () + "/gradebook/savedata/"); - if (!dir.query_exists ()) { - try { - dir.make_directory_with_parents (); - } catch (Error e) { - critical ("Failed to save subjects: Failed to create savedata directory: %s", e.message); + if (subject.deleted) { + continue; } - } - var parser = new SubjectParser (); - for (int i = 0; i < subjects.get_n_items (); i++) { - var subject = (Subject) subjects.get_item (i); - - var file = dir.get_child (subject.name); - yield write_to_file (file, parser.to_string (subject)); + keyfile.set_string (subject.name, "name", subject.name); + keyfile.set_string_list (subject.name, "categories", SubjectParser.categories_to_string_list (subject)); + keyfile.set_string_list (subject.name, "grades", SubjectParser.grades_to_string_list (subject)); } - for (int i = 0; i < deleted_subjects.get_n_items (); i++) { - var subject = (Subject) subjects.get_item (i); - - var file = dir.get_child (subject.name); - - try { - yield file.delete_async (); - } catch (Error e) { - warning ("Failed to delete save file for subject '%s': %s", subject.name, e.message); - } + try { + keyfile.save_to_file (Environment.get_user_data_dir () + "/gradebook/subjects"); + } catch (Error e) { + critical ("Failed to save keyfile: %s", e.message); } } @@ -145,7 +100,6 @@ public class SubjectManager : Object { if (subjects.find (subject, out pos)) { subjects.remove (pos); } - deleted_subjects.append (subject); }); } } diff --git a/src/subject-parser.vala b/src/subject-parser.vala index 0173b94..aea3c59 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -1,10 +1,56 @@ public class SubjectParser : Object { - public int cat_arr_size = 5; - public int grade_arr_size = 20; + // public static Subject? legacy_to_object (string str) { + // Regex regex_for_main; + // Regex regex_for_sub; - public SubjectParser () {} + // try { + // regex_for_main = new Regex ("%"); + // regex_for_sub = new Regex ("#"); + // } catch (Error e) { + // print (e.message); + // return null; + // } - public Subject? to_object (string str) { + // var subject_string_arr = new string[3]; + // var cat_string_arr = new string[10]; + // var grade_string_arr = new string[10]; + + // subject_string_arr = str.split_set ("%"); + // cat_string_arr = regex_for_sub.split (subject_string_arr[1]); + // grade_string_arr = regex_for_sub.split (subject_string_arr[2]); + + // var result_subject = new Subject (subject_string_arr[0]); + + // var cats = new Category[cat_arr_size]; + // int j1 = 0; + // for (int i = 0; i < cat_string_arr.length && cat_string_arr[j1] != null; i++) { + // cats[i] = new Category ("", 0); + // cats[i].name = cat_string_arr[j1]; + // j1++; + // cats[i].percentage = int.parse (cat_string_arr[j1]); + // j1++; + // } + + + // var grades = new Grade[grade_arr_size]; + // int j2 = 0; + // for (int i = 0; i < grade_string_arr.length && grade_string_arr[j2] != null; i++) { + // grades[i] = new Grade ("", "", 0); + // grades[i].grade = grade_string_arr[j2]; + // j2++; + // grades[i].note = grade_string_arr[j2]; + // j2++; + // grades[i].cat = int.parse (grade_string_arr[j2]); + // j2++; + // } + + // result_subject.categories = cats; + // result_subject.grades = grades; + + // return result_subject; + // } + + public static Subject? to_object (string str) { var subject_string_arr = str.split_set ("%"); var cat_string_arr = subject_string_arr[1].split_set ("#"); var grade_string_arr = subject_string_arr[2].split_set ("#"); @@ -24,47 +70,48 @@ public class SubjectParser : Object { return result_subject; } - public string to_json (Subject subject) { - var node = Json.gobject_serialize (subject); + public static string[] categories_to_string_list (Subject subject) { + string[] result = {}; - var generator = new Json.Generator () { - root = node, - pretty = true - }; + foreach (var category in subject.categories_by_name.get_values ()) { + var node = Json.gobject_serialize (category); + var generator = new Json.Generator () { + root = node + }; + result += generator.to_data (null); + print (generator.to_data (null)); + } - print (generator.to_data (null)); - return ""; + return result; } - public string to_string (Subject sub) { - to_json (sub); - string result = sub.name + "%"; + public static string[] grades_to_string_list (Subject subject) { + string[] result = {}; - bool first = true; - foreach (var category in sub.categories_by_name.get_values ()) { - if (!first) { - result = result + "#"; - } else { - first = false; - } - result = result + category.name + "#"; - result = result + category.percentage.to_string (); + for (int i = 0; i < subject.grades_model.get_n_items (); i++) { + result += Json.gobject_to_data (subject.grades_model.get_item (i), null); } - result = result + "%"; + return result; + } - first = true; - for (int i = 0; i < sub.grades_model.get_n_items (); i++) { - if (!first) { - result = result + "#"; - } else { - first = false; + public static void load_grades (Subject subject, string[] grades) { + foreach (var grade_str in grades) { + try { + subject.add_grade ((Grade) Json.gobject_from_data (typeof (Grade), grade_str)); + } catch (Error e) { + warning ("Failed to load grade %s: %s", grade_str, e.message); } - result = result + ((Grade) sub.grades_model.get_item (i)).grade + "#"; - result = result + ((Grade) sub.grades_model.get_item (i)).note + "#"; - result = result + ((Grade) sub.grades_model.get_item (i)).category_name; } + } - return result; + public static void load_categories (Subject subject, string[] categories) { + foreach (var category_str in categories) { + try { + subject.add_category ((Category) Json.gobject_from_data (typeof (Category), category_str)); + } catch (Error e) { + warning ("Failed to load category %s: %s", category_str, e.message); + } + } } } diff --git a/src/subject.vala b/src/subject.vala index 77784c8..527e1c7 100644 --- a/src/subject.vala +++ b/src/subject.vala @@ -13,8 +13,16 @@ public class Subject : Object{ categories_by_name = new HashTable (str_hash, str_equal); } - public void new_grade (string grade, string note, string c) { - grades_model.insert (0, new Grade (grade, note, c)); + public void new_grade (string grade, string note, string category) { + grades_model.insert (0, new Grade (grade, note, category)); + } + + public void add_grade (Grade grade) { + grades_model.insert (0, grade); + } + + public void add_category (Category category) { + categories_by_name[category.name] = category; } public void delete_grade (Grade grade) { diff --git a/src/window.vala b/src/window.vala index 5b7414e..42f5d98 100644 --- a/src/window.vala +++ b/src/window.vala @@ -68,13 +68,14 @@ public class Window : Adw.ApplicationWindow { subject_manager.subjects.items_changed.connect ((pos, rem, added) => { subject_page.subject = (Subject) subject_manager.subjects.get_item (pos); + navigation_sidebar.select_row (navigation_sidebar.get_row_at_index ((int) pos)); }); subject_manager.read_data (); close_request.connect (() => { set_visible (false); - subject_manager.write_data_new.begin (() => { + subject_manager.write_data.begin (() => { destroy (); }); return Gdk.EVENT_STOP; From 265e0a9385a0a70e9b1c897baa5dfff7eb3d5fc9 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 23 Dec 2023 15:15:49 +0100 Subject: [PATCH 27/29] Implement to_object_legacy --- src/subject-parser.vala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/subject-parser.vala b/src/subject-parser.vala index aea3c59..0e12839 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -50,7 +50,7 @@ public class SubjectParser : Object { // return result_subject; // } - public static Subject? to_object (string str) { + public static Subject? legacy_to_object (string str) { var subject_string_arr = str.split_set ("%"); var cat_string_arr = subject_string_arr[1].split_set ("#"); var grade_string_arr = subject_string_arr[2].split_set ("#"); @@ -64,7 +64,8 @@ public class SubjectParser : Object { int j2 = 0; while (j2 < grade_string_arr.length) { - result_subject.grades_model.append (new Grade (grade_string_arr[j2++], grade_string_arr[j2++], grade_string_arr[j2++])); + result_subject.grades_model.append (new Grade (grade_string_arr[j2++], grade_string_arr[j2++], cat_string_arr[int.parse (grade_string_arr[j2++]) * 2])); + j2 += 3; //SKIP OLD DATE FORMATTING } return result_subject; From a1e37a22c696f65218a59bbefdb3bad6609d1531 Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 23 Dec 2023 15:19:37 +0100 Subject: [PATCH 28/29] Implement legacy import --- src/subject-manager.vala | 12 +++++++++--- src/subject-parser.vala | 1 - 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/subject-manager.vala b/src/subject-manager.vala index bf50f2e..0cb7fb6 100644 --- a/src/subject-manager.vala +++ b/src/subject-manager.vala @@ -28,16 +28,23 @@ public class SubjectManager : Object { return "-1"; } - public void read_data_legacy () { + public async void read_data_legacy () { for (int i = 0; i < 20 && FileUtils.test (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i", FileTest.EXISTS); i++) { File file = File.new_for_path (Environment.get_user_data_dir () + @"/gradebook/savedata/subjectsave$i"); - Subject sub = SubjectParser.to_object (read_from_file (file)); + Subject sub = SubjectParser.legacy_to_object (read_from_file (file)); add_subject (sub); + try { + yield file.delete_async (); + } catch (Error e) { + warning ("Failed to delete old save file: %s", e.message); + } } } public async void read_data () { + yield read_data_legacy (); + var keyfile = new KeyFile (); try { @@ -71,7 +78,6 @@ public class SubjectManager : Object { continue; } - keyfile.set_string (subject.name, "name", subject.name); keyfile.set_string_list (subject.name, "categories", SubjectParser.categories_to_string_list (subject)); keyfile.set_string_list (subject.name, "grades", SubjectParser.grades_to_string_list (subject)); } diff --git a/src/subject-parser.vala b/src/subject-parser.vala index 0e12839..fc9f3e1 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -80,7 +80,6 @@ public class SubjectParser : Object { root = node }; result += generator.to_data (null); - print (generator.to_data (null)); } return result; From 209c302473dcbe71ef3024bfe31499b123de770e Mon Sep 17 00:00:00 2001 From: Leonhard Date: Sat, 23 Dec 2023 15:19:54 +0100 Subject: [PATCH 29/29] Cleanup --- src/subject-parser.vala | 51 ----------------------------------------- 1 file changed, 51 deletions(-) diff --git a/src/subject-parser.vala b/src/subject-parser.vala index fc9f3e1..0951154 100644 --- a/src/subject-parser.vala +++ b/src/subject-parser.vala @@ -1,55 +1,4 @@ public class SubjectParser : Object { - // public static Subject? legacy_to_object (string str) { - // Regex regex_for_main; - // Regex regex_for_sub; - - // try { - // regex_for_main = new Regex ("%"); - // regex_for_sub = new Regex ("#"); - // } catch (Error e) { - // print (e.message); - // return null; - // } - - // var subject_string_arr = new string[3]; - // var cat_string_arr = new string[10]; - // var grade_string_arr = new string[10]; - - // subject_string_arr = str.split_set ("%"); - // cat_string_arr = regex_for_sub.split (subject_string_arr[1]); - // grade_string_arr = regex_for_sub.split (subject_string_arr[2]); - - // var result_subject = new Subject (subject_string_arr[0]); - - // var cats = new Category[cat_arr_size]; - // int j1 = 0; - // for (int i = 0; i < cat_string_arr.length && cat_string_arr[j1] != null; i++) { - // cats[i] = new Category ("", 0); - // cats[i].name = cat_string_arr[j1]; - // j1++; - // cats[i].percentage = int.parse (cat_string_arr[j1]); - // j1++; - // } - - - // var grades = new Grade[grade_arr_size]; - // int j2 = 0; - // for (int i = 0; i < grade_string_arr.length && grade_string_arr[j2] != null; i++) { - // grades[i] = new Grade ("", "", 0); - // grades[i].grade = grade_string_arr[j2]; - // j2++; - // grades[i].note = grade_string_arr[j2]; - // j2++; - // grades[i].cat = int.parse (grade_string_arr[j2]); - // j2++; - // } - - // result_subject.categories = cats; - // result_subject.grades = grades; - - // return result_subject; - // } - public static Subject? legacy_to_object (string str) { var subject_string_arr = str.split_set ("%"); var cat_string_arr = subject_string_arr[1].split_set ("#");