about summary refs log tree commit diff
path: root/src/ui/tasks_group.rs
blob: 2453991fab15c56dccb2e0added00ce4fa1627ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Furtherance - Track your time without being tracked
// Copyright (C) 2022  Ricky Kresslein <rk@lakoliu.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use adw::subclass::prelude::*;
use gtk::subclass::prelude::*;
use gtk::{glib, prelude::*};

use crate::ui::FurTaskRow;
use crate::database;
use crate::settings_manager;

mod imp {
    use super::*;
    use glib::subclass;
    use gtk::CompositeTemplate;

    use std::cell::RefCell;

    #[derive(Default, Debug, CompositeTemplate)]
    #[template(resource = "/com/lakoliu/Furtherance/gtk/tasks_group.ui")]
    pub struct FurTasksGroup {
        #[template_child]
        pub listbox_box: TemplateChild<gtk::Box>,

        pub models: RefCell<Vec<gtk::SortListModel>>,
        pub day_total_time: RefCell<i64>,
    }

    #[glib::object_subclass]
    impl ObjectSubclass for FurTasksGroup {
        const NAME: &'static str = "FurTasksGroup";
        type ParentType = adw::PreferencesGroup;
        type Type = super::FurTasksGroup;

        fn class_init(klass: &mut Self::Class) {
            Self::bind_template(klass);
        }

        fn instance_init(obj: &subclass::InitializingObject<Self>) {
            obj.init_template();
        }
    }

    impl ObjectImpl for FurTasksGroup {}
    impl WidgetImpl for FurTasksGroup {}
    impl PreferencesGroupImpl for FurTasksGroup {}
}

glib::wrapper! {
    pub struct FurTasksGroup(
        ObjectSubclass<imp::FurTasksGroup>)
        @extends gtk::Widget, adw::PreferencesGroup;
}

impl FurTasksGroup {
    pub fn new() -> Self {
        glib::Object::new(&[]).expect("Failed to create `FurTaskGroup`.")
    }

    pub fn add_task_model(&self, tasks: Vec<database::Task>) {
        let imp = imp::FurTasksGroup::from_instance(&self);

        let listbox = gtk::ListBox::new();
        listbox.add_css_class("content");
        listbox.set_selection_mode(gtk::SelectionMode::None);
        imp.listbox_box.append(&listbox);

        // Check if tasks have the same name. If they do, make one listbox row for all of them.
        // If they don't, move on.
        let mut tasks_by_name: Vec<Vec<database::Task>> = Vec::new();
        let mut unique: bool;

        for task in &tasks {
            unique = true;
            for i in 0..tasks_by_name.len() {
                if tasks_by_name[i][0].task_name == task.task_name
                    && ( ( settings_manager::get_bool("show-tags")
                        && tasks_by_name[i][0].tags == task.tags ) ||
                            !settings_manager::get_bool("show-tags") ) {
                    tasks_by_name[i].push(task.clone());
                    unique = false;
                }
            }
            if unique {
                // Add unique task to list for group name
                let mut new_name_list: Vec<database::Task> = Vec::new();
                new_name_list.push(task.clone());
                tasks_by_name.push(new_name_list);
            }
        }

        for same_name in tasks_by_name {
            let listbox_row = FurTaskRow::new();
            listbox_row.set_row_labels(same_name);
            *imp.day_total_time.borrow_mut() += listbox_row.get_total_time();
            listbox.append(&listbox_row);
        }

        listbox.connect_row_activated(move |_, row| {
            row.activate_action("task-row.open-details", None).unwrap();
        });
    }

    pub fn get_total_day_time(&self) -> i64 {
        let imp = imp::FurTasksGroup::from_instance(&self);
        *imp.day_total_time.borrow()
    }
}