diff --git a/core/Objects/Item.vala b/core/Objects/Item.vala index 2e2b2ee97..4d46cba55 100644 --- a/core/Objects/Item.vala +++ b/core/Objects/Item.vala @@ -410,7 +410,7 @@ public class Objects.Item : Objects.BaseObject { public void update_from_vtodo (string data, string _ics) { patch_from_vtodo (data, _ics, true); } - + public void patch_from_vtodo (string data, string _ics, bool is_update = false) { print ("%s\n".printf (data)); @@ -1638,8 +1638,7 @@ public class Objects.Item : Objects.BaseObject { foreach (Objects.Item subitem in Services.Store.instance ().get_subitems (this)) { subitem.checked = checked; subitem.completed_at = completed_at; - - subitem.complete_item (old_checked); + subitem.complete_item.begin (old_checked); } } } diff --git a/core/Objects/Label.vala b/core/Objects/Label.vala index e2c8ad3c3..923ddff6c 100644 --- a/core/Objects/Label.vala +++ b/core/Objects/Label.vala @@ -1,241 +1,241 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public class Objects.Label : Objects.BaseObject { - public string color { get; set; default = ""; } - public int item_order { get; set; default = 0; } - public bool is_deleted { get; set; default = false; } - public bool is_favorite { get; set; default = false; } - public SourceType backend_type { get; set; default = SourceType.NONE; } - public string source_id { get; set; default = SourceType.LOCAL.to_string (); } - - Objects.Source? _source; - public Objects.Source source { - get { - _source = Services.Store.instance ().get_source (source_id); - return _source; - } - } - - public SourceType source_type { - get { - return source.source_type; - } - } - - int? _label_count = null; - public int label_count { - get { - if (_label_count == null) { - _label_count = update_label_count (); - } - - return _label_count; - } - - set { - _label_count = value; - } - } - - string _short_name; - public string short_name { - get { - _short_name = Util.get_default ().get_short_name (name); - return _short_name; - } - } - - public signal void label_count_updated (); - - construct { - Services.Store.instance ().item_added.connect ((item) => { - if (item.get_label (id) != null) { - _label_count = update_label_count (); - label_count_updated (); - } - }); - - Services.Store.instance ().item_deleted.connect ((item) => { - if (item.get_label (id) != null) { - _label_count = update_label_count (); - label_count_updated (); - } - }); - - Services.Store.instance ().item_updated.connect ((item) => { - if (item.get_label (id) != null) { - _label_count = update_label_count (); - label_count_updated (); - } - }); - - Services.Store.instance ().item_label_added.connect ((label) => { - if (label.id == id) { - _label_count = update_label_count (); - label_count_updated (); - } - }); - - Services.Store.instance ().item_label_deleted.connect ((label) => { - if (label.id == id) { - _label_count = update_label_count (); - label_count_updated (); - } - }); - } - - private int update_label_count () { - return Services.Store.instance ().get_items_by_label (this, false).size; - } - - public Label.from_json (Json.Node node) { - id = node.get_object ().get_string_member ("id"); - update_from_json (node); - backend_type = SourceType.TODOIST; - } - - public Label.from_import_json (Json.Node node) { - id = node.get_object ().get_string_member ("id"); - name = node.get_object ().get_string_member ("name"); - color = node.get_object ().get_string_member ("color"); - backend_type = SourceType.parse (node.get_object ().get_string_member ("backend_type")); - is_deleted = node.get_object ().get_boolean_member ("is_deleted"); - is_favorite = node.get_object ().get_boolean_member ("is_favorite"); - source_id = backend_type.to_string (); - - if (node.get_object ().has_member ("source_id")) { - source_id = node.get_object ().get_string_member ("source_id"); - } - } - - public void update_from_json (Json.Node node) { - name = node.get_object ().get_string_member ("name"); - - if (!node.get_object ().get_null_member ("color")) { - color = node.get_object ().get_string_member ("color"); - } - - if (!node.get_object ().get_null_member ("is_favorite")) { - is_favorite = node.get_object ().get_boolean_member ("is_favorite"); - } - - if (!node.get_object ().get_null_member ("is_deleted")) { - is_deleted = node.get_object ().get_boolean_member ("is_deleted"); - } - - if (!node.get_object ().get_null_member ("item_order")) { - item_order = (int32) node.get_object ().get_int_member ("item_order"); - } - } - - public override string get_add_json (string temp_id, string uuid) { - return get_update_json (uuid, temp_id); - } - public override string get_update_json (string uuid, string? temp_id = null) { - var builder = new Json.Builder (); - builder.begin_object (); - builder.set_member_name ("commands"); - builder.begin_array (); - builder.begin_object (); - - // Set type - builder.set_member_name ("type"); - builder.add_string_value (temp_id == null ? "label_update" : "label_add"); - - builder.set_member_name ("uuid"); - builder.add_string_value (uuid); - - if (temp_id != null) { - builder.set_member_name ("temp_id"); - builder.add_string_value (temp_id); - } - - builder.set_member_name ("args"); - builder.begin_object (); - - if (temp_id == null) { - builder.set_member_name ("id"); - builder.add_string_value (id); - } - - builder.set_member_name ("name"); - builder.add_string_value (name); - - builder.set_member_name ("color"); - builder.add_string_value (color); - - builder.set_member_name ("item_order"); - builder.add_int_value (item_order); - - builder.set_member_name ("is_favorite"); - builder.add_boolean_value (is_favorite); - - builder.end_object (); - builder.end_object (); - builder.end_array (); - builder.end_object (); - - Json.Generator generator = new Json.Generator (); - Json.Node root = builder.get_root (); - generator.set_root (root); - - return generator.to_data (null); - } - - public async void delete_label (Gtk.Window window) { - var dialog = new Adw.AlertDialog ( - _("Delete Label %s".printf (name)), - _("This can not be undone") - ); - - dialog.add_response ("cancel", _("Cancel")); - dialog.add_response ("delete", _("Delete")); - dialog.set_response_appearance ("delete", Adw.ResponseAppearance.DESTRUCTIVE); - dialog.present (window); - - dialog.response.connect ((response) => { - if (response == "delete") { - if (source_type == SourceType.TODOIST) { - loading = true; - Services.Todoist.get_default ().delete.begin (this, (obj, res) => { - Services.Todoist.get_default ().delete.end (res); - Services.Store.instance ().delete_label (this); - }); - } else if (source_type == SourceType.CALDAV) { - loading = true; - foreach (Objects.Item item in Services.Store.instance ().get_items_by_label (this, false)) { - item.delete_item_label (id); - Services.CalDAV.Core.get_default ().add_task.begin (item, true, (obj, res) => { - if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { - Services.Store.instance ().update_item (item); - } - }); - } - - Services.Store.instance ().delete_label (this); - } else { - Services.Store.instance ().delete_label (this); - } - } - }); - } + public string color { get; set; default = ""; } + public int item_order { get; set; default = 0; } + public bool is_deleted { get; set; default = false; } + public bool is_favorite { get; set; default = false; } + public SourceType backend_type { get; set; default = SourceType.NONE; } + public string source_id { get; set; default = SourceType.LOCAL.to_string (); } + + Objects.Source? _source; + public Objects.Source source { + get { + _source = Services.Store.instance ().get_source (source_id); + return _source; + } + } + + public SourceType source_type { + get { + return source.source_type; + } + } + + int? _label_count = null; + public int label_count { + get { + if (_label_count == null) { + _label_count = update_label_count (); + } + + return _label_count; + } + + set { + _label_count = value; + } + } + + string _short_name; + public string short_name { + get { + _short_name = Util.get_default ().get_short_name (name); + return _short_name; + } + } + + public signal void label_count_updated (); + + construct { + Services.Store.instance ().item_added.connect ((item) => { + if (item.get_label (id) != null) { + _label_count = update_label_count (); + label_count_updated (); + } + }); + + Services.Store.instance ().item_deleted.connect ((item) => { + if (item.get_label (id) != null) { + _label_count = update_label_count (); + label_count_updated (); + } + }); + + Services.Store.instance ().item_updated.connect ((item) => { + if (item.get_label (id) != null) { + _label_count = update_label_count (); + label_count_updated (); + } + }); + + Services.Store.instance ().item_label_added.connect ((label) => { + if (label.id == id) { + _label_count = update_label_count (); + label_count_updated (); + } + }); + + Services.Store.instance ().item_label_deleted.connect ((label) => { + if (label.id == id) { + _label_count = update_label_count (); + label_count_updated (); + } + }); + } + + private int update_label_count () { + return Services.Store.instance ().get_items_by_label (this, false).size; + } + + public Label.from_json (Json.Node node) { + id = node.get_object ().get_string_member ("id"); + update_from_json (node); + backend_type = SourceType.TODOIST; + } + + public Label.from_import_json (Json.Node node) { + id = node.get_object ().get_string_member ("id"); + name = node.get_object ().get_string_member ("name"); + color = node.get_object ().get_string_member ("color"); + backend_type = SourceType.parse (node.get_object ().get_string_member ("backend_type")); + is_deleted = node.get_object ().get_boolean_member ("is_deleted"); + is_favorite = node.get_object ().get_boolean_member ("is_favorite"); + source_id = backend_type.to_string (); + + if (node.get_object ().has_member ("source_id")) { + source_id = node.get_object ().get_string_member ("source_id"); + } + } + + public void update_from_json (Json.Node node) { + name = node.get_object ().get_string_member ("name"); + + if (!node.get_object ().get_null_member ("color")) { + color = node.get_object ().get_string_member ("color"); + } + + if (!node.get_object ().get_null_member ("is_favorite")) { + is_favorite = node.get_object ().get_boolean_member ("is_favorite"); + } + + if (!node.get_object ().get_null_member ("is_deleted")) { + is_deleted = node.get_object ().get_boolean_member ("is_deleted"); + } + + if (!node.get_object ().get_null_member ("item_order")) { + item_order = (int32) node.get_object ().get_int_member ("item_order"); + } + } + + public override string get_add_json (string temp_id, string uuid) { + return get_update_json (uuid, temp_id); + } + public override string get_update_json (string uuid, string? temp_id = null) { + var builder = new Json.Builder (); + builder.begin_object (); + builder.set_member_name ("commands"); + builder.begin_array (); + builder.begin_object (); + + // Set type + builder.set_member_name ("type"); + builder.add_string_value (temp_id == null ? "label_update" : "label_add"); + + builder.set_member_name ("uuid"); + builder.add_string_value (uuid); + + if (temp_id != null) { + builder.set_member_name ("temp_id"); + builder.add_string_value (temp_id); + } + + builder.set_member_name ("args"); + builder.begin_object (); + + if (temp_id == null) { + builder.set_member_name ("id"); + builder.add_string_value (id); + } + + builder.set_member_name ("name"); + builder.add_string_value (name); + + builder.set_member_name ("color"); + builder.add_string_value (color); + + builder.set_member_name ("item_order"); + builder.add_int_value (item_order); + + builder.set_member_name ("is_favorite"); + builder.add_boolean_value (is_favorite); + + builder.end_object (); + builder.end_object (); + builder.end_array (); + builder.end_object (); + + Json.Generator generator = new Json.Generator (); + Json.Node root = builder.get_root (); + generator.set_root (root); + + return generator.to_data (null); + } + + public async void delete_label (Gtk.Window window) { + var dialog = new Adw.AlertDialog ( + _("Delete Label %s".printf (name)), + _("This can not be undone") + ); + + dialog.add_response ("cancel", _("Cancel")); + dialog.add_response ("delete", _("Delete")); + dialog.set_response_appearance ("delete", Adw.ResponseAppearance.DESTRUCTIVE); + dialog.present (window); + + dialog.response.connect ((response) => { + if (response == "delete") { + if (source_type == SourceType.TODOIST) { + loading = true; + Services.Todoist.get_default ().delete.begin (this, (obj, res) => { + Services.Todoist.get_default ().delete.end (res); + Services.Store.instance ().delete_label (this); + }); + } else if (source_type == SourceType.CALDAV) { + loading = true; + foreach (Objects.Item item in Services.Store.instance ().get_items_by_label (this, false)) { + item.delete_item_label (id); + Services.CalDAV.Core.get_default ().add_task.begin (item, true, (obj, res) => { + if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { + Services.Store.instance ().update_item (item); + } + }); + } + + Services.Store.instance ().delete_label (this); + } else { + Services.Store.instance ().delete_label (this); + } + } + }); + } } diff --git a/core/Services/Database.vala b/core/Services/Database.vala index b9b748b35..df36dd75a 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -1,55 +1,55 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public class Services.Database : GLib.Object { - private Sqlite.Database db; - private string db_path; - private string errormsg; - private string sql; - - public signal void opened (); - public signal void reset (); - - private static Database? _instance; - public static Database get_default () { - if (_instance == null) { - _instance = new Database (); - } - - return _instance; - } - - public void init_database () { - db_path = Environment.get_user_data_dir () + "/io.github.alainm23.planify/database.db"; - print ("DB: %s\n".printf (db_path)); - Sqlite.Database.open (db_path, out db); - - create_tables (); - create_triggers (); - patch_database (); - opened (); - } - - private void create_tables () { - sql = """ + private Sqlite.Database db; + private string db_path; + private string errormsg; + private string sql; + + public signal void opened (); + public signal void reset (); + + private static Database? _instance; + public static Database get_default () { + if (_instance == null) { + _instance = new Database (); + } + + return _instance; + } + + public void init_database () { + db_path = Environment.get_user_data_dir () + "/io.github.alainm23.planify/database.db"; + print ("DB: %s\n".printf (db_path)); + Sqlite.Database.open (db_path, out db); + + create_tables (); + create_triggers (); + patch_database (); + opened (); + } + + private void create_tables () { + sql = """ CREATE TABLE IF NOT EXISTS Labels ( id TEXT PRIMARY KEY, name TEXT, @@ -63,11 +63,11 @@ public class Services.Database : GLib.Object { ); """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TABLE IF NOT EXISTS Projects ( id TEXT PRIMARY KEY, name TEXT NOT NULL, @@ -95,11 +95,11 @@ public class Services.Database : GLib.Object { ); """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TABLE IF NOT EXISTS Sections ( id TEXT PRIMARY KEY, name TEXT, @@ -117,11 +117,11 @@ public class Services.Database : GLib.Object { ); """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TABLE IF NOT EXISTS Items ( id TEXT PRIMARY KEY, content TEXT NOT NULL, @@ -146,11 +146,11 @@ public class Services.Database : GLib.Object { ); """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TABLE IF NOT EXISTS Reminders ( id TEXT PRIMARY KEY, notify_uid INTEGER, @@ -163,12 +163,12 @@ public class Services.Database : GLib.Object { FOREIGN KEY (item_id) REFERENCES Items (id) ON DELETE CASCADE ); """; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - sql = """ + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + + sql = """ CREATE TABLE IF NOT EXISTS Queue ( uuid TEXT PRIMARY KEY, object_id TEXT, @@ -178,24 +178,24 @@ public class Services.Database : GLib.Object { date_added TEXT ); """; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - sql = """ + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + + sql = """ CREATE TABLE IF NOT EXISTS CurTempIds ( id TEXT PRIMARY KEY, temp_id TEXT, object TEXT ); """; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - sql = """ + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + + sql = """ CREATE TABLE IF NOT EXISTS Attachments ( id TEXT PRIMARY KEY, item_id TEXT, @@ -206,12 +206,12 @@ public class Services.Database : GLib.Object { FOREIGN KEY (item_id) REFERENCES Items (id) ON DELETE CASCADE ); """; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - sql = """ + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + + sql = """ CREATE TABLE IF NOT EXISTS OEvents ( id INTEGER PRIMARY KEY AUTOINCREMENT, event_type TEXT, @@ -225,12 +225,12 @@ public class Services.Database : GLib.Object { parent_project_id TEXT ); """; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - sql = """ + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + + sql = """ CREATE TABLE IF NOT EXISTS Sources ( id TEXT PRIMARY KEY, source_type TEXT NOT NULL, @@ -244,20 +244,20 @@ public class Services.Database : GLib.Object { data TEXT ); """; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - - sql = """PRAGMA foreign_keys = ON;"""; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - } - - private void create_triggers () { - sql = """ + + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + + sql = """PRAGMA foreign_keys = ON;"""; + + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + } + + private void create_triggers () { + sql = """ CREATE TRIGGER IF NOT EXISTS after_insert_item AFTER INSERT ON Items BEGIN @@ -265,14 +265,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("insert", NEW.id, "item", "content", NEW.content, NEW.content, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_content_item AFTER UPDATE ON Items FOR EACH ROW @@ -282,14 +282,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "content", OLD.content, NEW.content, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_description_item AFTER UPDATE ON Items FOR EACH ROW @@ -299,14 +299,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "description", OLD.description, NEW.description, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_due_item AFTER UPDATE ON Items FOR EACH ROW @@ -316,14 +316,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "due", OLD.due, NEW.due, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_priority_item AFTER UPDATE ON Items FOR EACH ROW @@ -333,14 +333,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "priority", OLD.priority, NEW.priority, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_labels_item AFTER UPDATE ON Items FOR EACH ROW @@ -350,14 +350,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "labels", OLD.labels, NEW.labels, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_pinned_item AFTER UPDATE ON Items FOR EACH ROW @@ -367,14 +367,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "pinned", OLD.pinned, NEW.pinned, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_checked_item AFTER UPDATE ON Items FOR EACH ROW @@ -384,10 +384,10 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "checked", OLD.checked, NEW.checked, NEW.project_id); - END; + END; """; - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_section_item AFTER UPDATE ON Items FOR EACH ROW @@ -397,14 +397,14 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "section", OLD.section_id, NEW.section_id, NEW.project_id); - END; + END; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ CREATE TRIGGER IF NOT EXISTS after_update_project_item AFTER UPDATE ON Items FOR EACH ROW @@ -414,185 +414,185 @@ public class Services.Database : GLib.Object { object_type, object_key, object_old_value, object_new_value, parent_project_id) VALUES ("update", NEW.id, "item", "project", OLD.project_id, NEW.project_id, NEW.project_id); - END; - """; - - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - } - - public void patch_database () { - /* - * Planner 3 - Beta 1 - * - Add pinned (0|1) to Items - */ - - add_int_column ("Items", "pinned", 0); - - /* - * Planner 3 - Beta 2 - * - Add show_completed (0|1) to Projects - */ - - add_int_column ("Projects", "show_completed", 0); - - /* - * Planner 3.10 - * - Add description to Projects - * - Add due date to Projects - */ - - add_text_column ("Projects", "description", ""); - - /* - * Planify 4.4 - * - Add labels column to Items - * - Add color column to Section - * - Add description column to Section - */ - - add_item_label_column (); - add_text_column ("Sections", "color", "blue"); - add_text_column ("Sections", "description", ""); - - /* - * Planify 4.5 - * - Add extra data column to Items - */ - - add_text_column ("Items", "extra_data", ""); - add_int_column ("Sections", "hidded", 0); - add_int_column ("Projects", "inbox_section_hidded", 0); - - /* - * Planify 4.5.2 - * - Add sync_id column to Projects - */ - - add_text_column ("Projects", "sync_id", ""); - - /* - * Planify 4.8 - * - Add sync_id column to Projects - */ - - add_text_column ("Items", "item_type", ItemType.TASK.to_string ()); - - /* - * Planify 4.10 - * - Add source_id column to Projects - */ - - add_project_labels_source_id (); - } - - public void clear_database () { - string db_path = Environment.get_user_data_dir () + "/io.github.alainm23.planify/database.db"; - File db_file = File.new_for_path (db_path); - - if (db_file.query_exists ()) { - try { - db_file.delete (); - } catch (Error err) { - warning (err.message); - } - } - } - - /* - Sources - */ - - public Gee.ArrayList get_sources_collection () { - Gee.ArrayList return_value = new Gee.ArrayList (); - - Sqlite.Statement stmt; - - sql = """ + END; + """; + + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + } + + public void patch_database () { + /* + * Planner 3 - Beta 1 + * - Add pinned (0|1) to Items + */ + + add_int_column ("Items", "pinned", 0); + + /* + * Planner 3 - Beta 2 + * - Add show_completed (0|1) to Projects + */ + + add_int_column ("Projects", "show_completed", 0); + + /* + * Planner 3.10 + * - Add description to Projects + * - Add due date to Projects + */ + + add_text_column ("Projects", "description", ""); + + /* + * Planify 4.4 + * - Add labels column to Items + * - Add color column to Section + * - Add description column to Section + */ + + add_item_label_column (); + add_text_column ("Sections", "color", "blue"); + add_text_column ("Sections", "description", ""); + + /* + * Planify 4.5 + * - Add extra data column to Items + */ + + add_text_column ("Items", "extra_data", ""); + add_int_column ("Sections", "hidded", 0); + add_int_column ("Projects", "inbox_section_hidded", 0); + + /* + * Planify 4.5.2 + * - Add sync_id column to Projects + */ + + add_text_column ("Projects", "sync_id", ""); + + /* + * Planify 4.8 + * - Add sync_id column to Projects + */ + + add_text_column ("Items", "item_type", ItemType.TASK.to_string ()); + + /* + * Planify 4.10 + * - Add source_id column to Projects + */ + + add_project_labels_source_id (); + } + + public void clear_database () { + string db_path = Environment.get_user_data_dir () + "/io.github.alainm23.planify/database.db"; + File db_file = File.new_for_path (db_path); + + if (db_file.query_exists ()) { + try { + db_file.delete (); + } catch (Error err) { + warning (err.message); + } + } + } + + /* + Sources + */ + + public Gee.ArrayList get_sources_collection () { + Gee.ArrayList return_value = new Gee.ArrayList (); + + Sqlite.Statement stmt; + + sql = """ SELECT * FROM Sources ORDER BY child_order; """; - db.prepare_v2 (sql, sql.length, out stmt); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_source (stmt)); - } - - return return_value; - } - - private Objects.Source _fill_source (Sqlite.Statement stmt) { - Objects.Source return_value = new Objects.Source (); - return_value.id = stmt.column_text (0); - return_value.source_type = SourceType.parse (stmt.column_text (1)); - return_value.display_name = stmt.column_text (2); - return_value.added_at = stmt.column_text (3); - return_value.updated_at = stmt.column_text (4); - return_value.is_visible = get_parameter_bool (stmt, 5); - return_value.child_order = stmt.column_int (6); - return_value.sync_server = get_parameter_bool (stmt, 7); - return_value.last_sync = stmt.column_text (8); - - if (return_value.source_type == SourceType.TODOIST) { - return_value.data = new Objects.SourceTodoistData.from_json (stmt.column_text (9)); - } else if (return_value.source_type == SourceType.CALDAV) { - return_value.data = new Objects.SourceCalDAVData.from_json (stmt.column_text (9)); - } - - return return_value; - } - - public bool insert_source (Objects.Source source) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_source (stmt)); + } + + return return_value; + } + + private Objects.Source _fill_source (Sqlite.Statement stmt) { + Objects.Source return_value = new Objects.Source (); + return_value.id = stmt.column_text (0); + return_value.source_type = SourceType.parse (stmt.column_text (1)); + return_value.display_name = stmt.column_text (2); + return_value.added_at = stmt.column_text (3); + return_value.updated_at = stmt.column_text (4); + return_value.is_visible = get_parameter_bool (stmt, 5); + return_value.child_order = stmt.column_int (6); + return_value.sync_server = get_parameter_bool (stmt, 7); + return_value.last_sync = stmt.column_text (8); + + if (return_value.source_type == SourceType.TODOIST) { + return_value.data = new Objects.SourceTodoistData.from_json (stmt.column_text (9)); + } else if (return_value.source_type == SourceType.CALDAV) { + return_value.data = new Objects.SourceCalDAVData.from_json (stmt.column_text (9)); + } + + return return_value; + } + + public bool insert_source (Objects.Source source) { + Sqlite.Statement stmt; + + sql = """ INSERT OR IGNORE INTO Sources (id, source_type, display_name, added_at, updated_at, is_visible, child_order, sync_server, last_sync, data) VALUES ($id, $source_type, $display_name, $added_at, $updated_at, $is_visible, $child_order, $sync_server, $last_sync, $data); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", source.id); - set_parameter_str (stmt, "$source_type", source.source_type.to_string ()); - set_parameter_str (stmt, "$display_name", source.display_name); - set_parameter_str (stmt, "$added_at", source.added_at); - set_parameter_str (stmt, "$updated_at", source.updated_at); - set_parameter_bool (stmt, "$is_visible", source.is_visible); - set_parameter_int (stmt, "$child_order", source.child_order); - set_parameter_bool (stmt, "$sync_server", source.sync_server); - set_parameter_str (stmt, "$last_sync", source.last_sync); - set_parameter_str (stmt, "$data", source.data.to_json ()); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", source.id); + set_parameter_str (stmt, "$source_type", source.source_type.to_string ()); + set_parameter_str (stmt, "$display_name", source.display_name); + set_parameter_str (stmt, "$added_at", source.added_at); + set_parameter_str (stmt, "$updated_at", source.updated_at); + set_parameter_bool (stmt, "$is_visible", source.is_visible); + set_parameter_int (stmt, "$child_order", source.child_order); + set_parameter_bool (stmt, "$sync_server", source.sync_server); + set_parameter_str (stmt, "$last_sync", source.last_sync); + set_parameter_str (stmt, "$data", source.data.to_json ()); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool delete_source (Objects.Source source) { - Sqlite.Statement stmt; + public bool delete_source (Objects.Source source) { + Sqlite.Statement stmt; - sql = """ + sql = """ DELETE FROM Sources WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", source.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", source.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool update_source (Objects.Source source) { - Sqlite.Statement stmt; + public bool update_source (Objects.Source source) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Sources SET source_type=$source_type, display_name=$display_name, @@ -605,78 +605,78 @@ public class Services.Database : GLib.Object { WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$source_type", source.source_type.to_string ()); - set_parameter_str (stmt, "$display_name", source.display_name); - set_parameter_str (stmt, "$updated_at", source.updated_at); - set_parameter_bool (stmt, "$is_visible", source.is_visible); - set_parameter_int (stmt, "$child_order", source.child_order); - set_parameter_bool (stmt, "$sync_server", source.sync_server); - set_parameter_str (stmt, "$last_sync", source.last_sync); - set_parameter_str (stmt, "$data", source.data.to_json ()); - set_parameter_str (stmt, "$id", source.id); - - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } - - /* - Projects - */ - - public Gee.ArrayList get_projects_collection () { - Gee.ArrayList return_value = new Gee.ArrayList (); - - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$source_type", source.source_type.to_string ()); + set_parameter_str (stmt, "$display_name", source.display_name); + set_parameter_str (stmt, "$updated_at", source.updated_at); + set_parameter_bool (stmt, "$is_visible", source.is_visible); + set_parameter_int (stmt, "$child_order", source.child_order); + set_parameter_bool (stmt, "$sync_server", source.sync_server); + set_parameter_str (stmt, "$last_sync", source.last_sync); + set_parameter_str (stmt, "$data", source.data.to_json ()); + set_parameter_str (stmt, "$id", source.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + return stmt.step () == Sqlite.DONE; + } + + /* + Projects + */ + + public Gee.ArrayList get_projects_collection () { + Gee.ArrayList return_value = new Gee.ArrayList (); + + Sqlite.Statement stmt; + + sql = """ SELECT * FROM Projects WHERE is_deleted = 0 ORDER BY child_order; """; - db.prepare_v2 (sql, sql.length, out stmt); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_project (stmt)); - } - - return return_value; - } - - public Objects.Project _fill_project (Sqlite.Statement stmt) { - Objects.Project return_value = new Objects.Project (); - return_value.id = stmt.column_text (0); - return_value.name = stmt.column_text (1); - return_value.color = stmt.column_text (2); - return_value.backend_type = SourceType.parse (stmt.column_text (3)); - return_value.inbox_project = get_parameter_bool (stmt, 4); - return_value.team_inbox = get_parameter_bool (stmt, 5); - return_value.child_order = stmt.column_int (6); - return_value.is_deleted = get_parameter_bool (stmt, 7); - return_value.is_archived = get_parameter_bool (stmt, 8); - return_value.is_favorite = get_parameter_bool (stmt, 9); - return_value.shared = get_parameter_bool (stmt, 10); - return_value.view_style = ProjectViewStyle.parse (stmt.column_text (11)); - return_value.sort_order = stmt.column_int (12); - return_value.parent_id = stmt.column_text (13); - return_value.collapsed = get_parameter_bool (stmt, 14); - return_value.icon_style = ProjectIconStyle.parse (stmt.column_text (15)); - return_value.emoji = stmt.column_text (16); - return_value.show_completed = get_parameter_bool (stmt, 17); - return_value.description = stmt.column_text (18); - return_value.due_date = stmt.column_text (19); - return_value.inbox_section_hidded = get_parameter_bool (stmt, 20); - return_value.sync_id = stmt.column_text (21); - return_value.source_id = stmt.column_text (22); - return return_value; - } - - public bool insert_project (Objects.Project project) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_project (stmt)); + } + + return return_value; + } + + public Objects.Project _fill_project (Sqlite.Statement stmt) { + Objects.Project return_value = new Objects.Project (); + return_value.id = stmt.column_text (0); + return_value.name = stmt.column_text (1); + return_value.color = stmt.column_text (2); + return_value.backend_type = SourceType.parse (stmt.column_text (3)); + return_value.inbox_project = get_parameter_bool (stmt, 4); + return_value.team_inbox = get_parameter_bool (stmt, 5); + return_value.child_order = stmt.column_int (6); + return_value.is_deleted = get_parameter_bool (stmt, 7); + return_value.is_archived = get_parameter_bool (stmt, 8); + return_value.is_favorite = get_parameter_bool (stmt, 9); + return_value.shared = get_parameter_bool (stmt, 10); + return_value.view_style = ProjectViewStyle.parse (stmt.column_text (11)); + return_value.sort_order = stmt.column_int (12); + return_value.parent_id = stmt.column_text (13); + return_value.collapsed = get_parameter_bool (stmt, 14); + return_value.icon_style = ProjectIconStyle.parse (stmt.column_text (15)); + return_value.emoji = stmt.column_text (16); + return_value.show_completed = get_parameter_bool (stmt, 17); + return_value.description = stmt.column_text (18); + return_value.due_date = stmt.column_text (19); + return_value.inbox_section_hidded = get_parameter_bool (stmt, 20); + return_value.sync_id = stmt.column_text (21); + return_value.source_id = stmt.column_text (22); + return return_value; + } + + public bool insert_project (Objects.Project project) { + Sqlite.Statement stmt; + + sql = """ INSERT OR IGNORE INTO Projects (id, name, color, backend_type, inbox_project, team_inbox, child_order, is_deleted, is_archived, is_favorite, shared, view_style, sort_order, parent_id, collapsed, icon_style, emoji, show_completed, description, due_date, @@ -687,77 +687,77 @@ public class Services.Database : GLib.Object { $inbox_section_hidded, $sync_id, $source_id); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", project.id); - set_parameter_str (stmt, "$name", project.name); - set_parameter_str (stmt, "$color", project.color); - set_parameter_str (stmt, "$backend_type", project.backend_type.to_string ()); - set_parameter_bool (stmt, "$inbox_project", project.inbox_project); - set_parameter_bool (stmt, "$team_inbox", project.team_inbox); - set_parameter_int (stmt, "$child_order", project.child_order); - set_parameter_bool (stmt, "$is_deleted", project.is_deleted); - set_parameter_bool (stmt, "$is_archived", project.is_archived); - set_parameter_bool (stmt, "$is_favorite", project.is_favorite); - set_parameter_bool (stmt, "$shared", project.shared); - set_parameter_str (stmt, "$view_style", project.view_style.to_string ()); - set_parameter_int (stmt, "$sort_order", project.sort_order); - set_parameter_str (stmt, "$parent_id", project.parent_id); - set_parameter_bool (stmt, "$collapsed", project.collapsed); - set_parameter_str (stmt, "$icon_style", project.icon_style.to_string ()); - set_parameter_str (stmt, "$emoji", project.emoji); - set_parameter_bool (stmt, "$show_completed", project.show_completed); - set_parameter_str (stmt, "$description", project.description); - set_parameter_str (stmt, "$due_date", project.due_date); - set_parameter_bool (stmt, "$inbox_section_hidded", project.inbox_section_hidded); - set_parameter_str (stmt, "$sync_id", project.sync_id); - set_parameter_str (stmt, "$source_id", project.source_id); - - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } - - public bool delete_project (Objects.Project project) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", project.id); + set_parameter_str (stmt, "$name", project.name); + set_parameter_str (stmt, "$color", project.color); + set_parameter_str (stmt, "$backend_type", project.backend_type.to_string ()); + set_parameter_bool (stmt, "$inbox_project", project.inbox_project); + set_parameter_bool (stmt, "$team_inbox", project.team_inbox); + set_parameter_int (stmt, "$child_order", project.child_order); + set_parameter_bool (stmt, "$is_deleted", project.is_deleted); + set_parameter_bool (stmt, "$is_archived", project.is_archived); + set_parameter_bool (stmt, "$is_favorite", project.is_favorite); + set_parameter_bool (stmt, "$shared", project.shared); + set_parameter_str (stmt, "$view_style", project.view_style.to_string ()); + set_parameter_int (stmt, "$sort_order", project.sort_order); + set_parameter_str (stmt, "$parent_id", project.parent_id); + set_parameter_bool (stmt, "$collapsed", project.collapsed); + set_parameter_str (stmt, "$icon_style", project.icon_style.to_string ()); + set_parameter_str (stmt, "$emoji", project.emoji); + set_parameter_bool (stmt, "$show_completed", project.show_completed); + set_parameter_str (stmt, "$description", project.description); + set_parameter_str (stmt, "$due_date", project.due_date); + set_parameter_bool (stmt, "$inbox_section_hidded", project.inbox_section_hidded); + set_parameter_str (stmt, "$sync_id", project.sync_id); + set_parameter_str (stmt, "$source_id", project.source_id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + return stmt.step () == Sqlite.DONE; + } + + public bool delete_project (Objects.Project project) { + Sqlite.Statement stmt; + + sql = """ DELETE FROM Projects WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", project.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", project.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public void delete_project_db (Objects.Project project) { - Sqlite.Statement stmt; + public void delete_project_db (Objects.Project project) { + Sqlite.Statement stmt; - sql = """ + sql = """ DELETE FROM Projects WHERE id=$id; DELETE FROM Items WHERE project_id=$item_project_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", project.id); - set_parameter_str (stmt, "$section_project_id", project.id); - set_parameter_str (stmt, "$item_project_id", project.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", project.id); + set_parameter_str (stmt, "$section_project_id", project.id); + set_parameter_str (stmt, "$item_project_id", project.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + } - public bool update_project (Objects.Project project) { - Sqlite.Statement stmt; + public bool update_project (Objects.Project project) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Projects SET name=$name, color=$color, @@ -784,246 +784,246 @@ public class Services.Database : GLib.Object { WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$name", project.name); - set_parameter_str (stmt, "$color", project.color); - set_parameter_str (stmt, "$backend_type", project.backend_type.to_string ()); - set_parameter_bool (stmt, "$inbox_project", project.inbox_project); - set_parameter_bool (stmt, "$team_inbox", project.team_inbox); - set_parameter_int (stmt, "$child_order", project.child_order); - set_parameter_bool (stmt, "$is_deleted", project.is_deleted); - set_parameter_bool (stmt, "$is_archived", project.is_archived); - set_parameter_bool (stmt, "$is_favorite", project.is_favorite); - set_parameter_bool (stmt, "$shared", project.shared); - set_parameter_str (stmt, "$view_style", project.view_style.to_string ()); - set_parameter_int (stmt, "$sort_order", project.sort_order); - set_parameter_str (stmt, "$parent_id", project.parent_id); - set_parameter_bool (stmt, "$collapsed", project.collapsed); - set_parameter_str (stmt, "$icon_style", project.icon_style.to_string ()); - set_parameter_str (stmt, "$emoji", project.emoji); - set_parameter_bool (stmt, "$show_completed", project.show_completed); - set_parameter_str (stmt, "$description", project.description); - set_parameter_str (stmt, "$due_date", project.due_date); - set_parameter_bool (stmt, "$inbox_section_hidded", project.inbox_section_hidded); - set_parameter_str (stmt, "$sync_id", project.sync_id); - set_parameter_str (stmt, "$source_id", project.source_id); - set_parameter_str (stmt, "$id", project.id); - - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } - - public bool archive_project (Objects.Project project) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$name", project.name); + set_parameter_str (stmt, "$color", project.color); + set_parameter_str (stmt, "$backend_type", project.backend_type.to_string ()); + set_parameter_bool (stmt, "$inbox_project", project.inbox_project); + set_parameter_bool (stmt, "$team_inbox", project.team_inbox); + set_parameter_int (stmt, "$child_order", project.child_order); + set_parameter_bool (stmt, "$is_deleted", project.is_deleted); + set_parameter_bool (stmt, "$is_archived", project.is_archived); + set_parameter_bool (stmt, "$is_favorite", project.is_favorite); + set_parameter_bool (stmt, "$shared", project.shared); + set_parameter_str (stmt, "$view_style", project.view_style.to_string ()); + set_parameter_int (stmt, "$sort_order", project.sort_order); + set_parameter_str (stmt, "$parent_id", project.parent_id); + set_parameter_bool (stmt, "$collapsed", project.collapsed); + set_parameter_str (stmt, "$icon_style", project.icon_style.to_string ()); + set_parameter_str (stmt, "$emoji", project.emoji); + set_parameter_bool (stmt, "$show_completed", project.show_completed); + set_parameter_str (stmt, "$description", project.description); + set_parameter_str (stmt, "$due_date", project.due_date); + set_parameter_bool (stmt, "$inbox_section_hidded", project.inbox_section_hidded); + set_parameter_str (stmt, "$sync_id", project.sync_id); + set_parameter_str (stmt, "$source_id", project.source_id); + set_parameter_str (stmt, "$id", project.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + return stmt.step () == Sqlite.DONE; + } + + public bool archive_project (Objects.Project project) { + Sqlite.Statement stmt; + + sql = """ UPDATE Projects SET is_archived=$is_archived WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_bool (stmt, "$is_archived", project.is_archived); - set_parameter_str (stmt, "$id", project.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_bool (stmt, "$is_archived", project.is_archived); + set_parameter_str (stmt, "$id", project.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - /* - * Labels - */ + /* + * Labels + */ - public Gee.ArrayList get_labels_collection () { - Gee.ArrayList return_value = new Gee.ArrayList (); - Sqlite.Statement stmt; + public Gee.ArrayList get_labels_collection () { + Gee.ArrayList return_value = new Gee.ArrayList (); + Sqlite.Statement stmt; - sql = """ + sql = """ SELECT * FROM Labels; """; - db.prepare_v2 (sql, sql.length, out stmt); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_label (stmt)); - } - - return return_value; - } - - public Objects.Label _fill_label (Sqlite.Statement stmt) { - Objects.Label return_value = new Objects.Label (); - return_value.id = stmt.column_text (0); - return_value.name = stmt.column_text (1); - return_value.color = stmt.column_text (2); - return_value.item_order = stmt.column_int (3); - return_value.is_deleted = get_parameter_bool (stmt, 4); - return_value.is_favorite = get_parameter_bool (stmt, 5); - return_value.backend_type = SourceType.parse (stmt.column_text (6)); - return_value.source_id = stmt.column_text (7); - return return_value; - } - - public bool insert_label (Objects.Label label) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_label (stmt)); + } + + return return_value; + } + + public Objects.Label _fill_label (Sqlite.Statement stmt) { + Objects.Label return_value = new Objects.Label (); + return_value.id = stmt.column_text (0); + return_value.name = stmt.column_text (1); + return_value.color = stmt.column_text (2); + return_value.item_order = stmt.column_int (3); + return_value.is_deleted = get_parameter_bool (stmt, 4); + return_value.is_favorite = get_parameter_bool (stmt, 5); + return_value.backend_type = SourceType.parse (stmt.column_text (6)); + return_value.source_id = stmt.column_text (7); + return return_value; + } + + public bool insert_label (Objects.Label label) { + Sqlite.Statement stmt; + + sql = """ INSERT OR IGNORE INTO Labels (id, name, color, item_order, is_deleted, is_favorite, backend_type, source_id) VALUES ($id, $name, $color, $item_order, $is_deleted, $is_favorite, $backend_type, $source_id); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", label.id); - set_parameter_str (stmt, "$name", label.name); - set_parameter_str (stmt, "$color", label.color); - set_parameter_int (stmt, "$item_order", label.item_order); - set_parameter_bool (stmt, "$is_deleted", label.is_deleted); - set_parameter_bool (stmt, "$is_favorite", label.is_favorite); - set_parameter_str (stmt, "$backend_type", label.backend_type.to_string ()); - set_parameter_str (stmt, "$source_id", label.source_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", label.id); + set_parameter_str (stmt, "$name", label.name); + set_parameter_str (stmt, "$color", label.color); + set_parameter_int (stmt, "$item_order", label.item_order); + set_parameter_bool (stmt, "$is_deleted", label.is_deleted); + set_parameter_bool (stmt, "$is_favorite", label.is_favorite); + set_parameter_str (stmt, "$backend_type", label.backend_type.to_string ()); + set_parameter_str (stmt, "$source_id", label.source_id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool delete_label (Objects.Label label) { - Sqlite.Statement stmt; + public bool delete_label (Objects.Label label) { + Sqlite.Statement stmt; - sql = """ + sql = """ DELETE FROM Labels WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", label.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", label.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool update_label (Objects.Label label) { - Sqlite.Statement stmt; + public bool update_label (Objects.Label label) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Labels SET name=$name, color=$color, item_order=$item_order, is_deleted=$is_deleted, is_favorite=$is_favorite WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$name", label.name); - set_parameter_str (stmt, "$color", label.color); - set_parameter_int (stmt, "$item_order", label.item_order); - set_parameter_bool (stmt, "$is_deleted", label.is_deleted); - set_parameter_bool (stmt, "$is_favorite", label.is_favorite); - set_parameter_str (stmt, "$id", label.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$name", label.name); + set_parameter_str (stmt, "$color", label.color); + set_parameter_int (stmt, "$item_order", label.item_order); + set_parameter_bool (stmt, "$is_deleted", label.is_deleted); + set_parameter_bool (stmt, "$is_favorite", label.is_favorite); + set_parameter_str (stmt, "$id", label.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - /* - Sections - */ + /* + Sections + */ - public bool insert_section (Objects.Section section) { - Sqlite.Statement stmt; + public bool insert_section (Objects.Section section) { + Sqlite.Statement stmt; - sql = """ + sql = """ INSERT OR IGNORE INTO Sections (id, name, archived_at, added_at, project_id, section_order, collapsed, is_deleted, is_archived, color, description, hidded) VALUES ($id, $name, $archived_at, $added_at, $project_id, $section_order, $collapsed, $is_deleted, $is_archived, $color, $description, $hidded); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", section.id); - set_parameter_str (stmt, "$name", section.name); - set_parameter_str (stmt, "$archived_at", section.archived_at); - set_parameter_str (stmt, "$added_at", section.added_at); - set_parameter_str (stmt, "$project_id", section.project_id); - set_parameter_int (stmt, "$section_order", section.section_order); - set_parameter_bool (stmt, "$collapsed", section.collapsed); - set_parameter_bool (stmt, "$is_deleted", section.is_deleted); - set_parameter_bool (stmt, "$is_archived", section.is_archived); - set_parameter_str (stmt, "$color", section.color); - set_parameter_str (stmt, "$description", section.description); - set_parameter_bool (stmt, "$hidded", section.hidded); - - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } - - public Gee.ArrayList get_sections_collection () { - Gee.ArrayList return_value = new Gee.ArrayList (); - - Sqlite.Statement stmt; - sql = "SELECT * FROM Sections WHERE is_deleted = 0;"; - - db.prepare_v2 (sql, sql.length, out stmt); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_section (stmt)); - } - - return return_value; - } - - public Objects.Section _fill_section (Sqlite.Statement stmt) { - Objects.Section return_value = new Objects.Section (); - return_value.id = stmt.column_text (0); - return_value.name = stmt.column_text (1); - return_value.archived_at = stmt.column_text (2); - return_value.added_at = stmt.column_text (3); - return_value.project_id = stmt.column_text (4); - return_value.section_order = stmt.column_int (5); - return_value.collapsed = get_parameter_bool (stmt, 6); - return_value.is_deleted = get_parameter_bool (stmt, 7); - return_value.is_archived = get_parameter_bool (stmt, 8); - return_value.color = stmt.column_text (9); - return_value.description = stmt.column_text (10); - return_value.hidded = get_parameter_bool (stmt, 11); - return return_value; - } - - public bool delete_section (Objects.Section section) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", section.id); + set_parameter_str (stmt, "$name", section.name); + set_parameter_str (stmt, "$archived_at", section.archived_at); + set_parameter_str (stmt, "$added_at", section.added_at); + set_parameter_str (stmt, "$project_id", section.project_id); + set_parameter_int (stmt, "$section_order", section.section_order); + set_parameter_bool (stmt, "$collapsed", section.collapsed); + set_parameter_bool (stmt, "$is_deleted", section.is_deleted); + set_parameter_bool (stmt, "$is_archived", section.is_archived); + set_parameter_str (stmt, "$color", section.color); + set_parameter_str (stmt, "$description", section.description); + set_parameter_bool (stmt, "$hidded", section.hidded); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + return stmt.step () == Sqlite.DONE; + } + + public Gee.ArrayList get_sections_collection () { + Gee.ArrayList return_value = new Gee.ArrayList (); + + Sqlite.Statement stmt; + sql = "SELECT * FROM Sections WHERE is_deleted = 0;"; + + db.prepare_v2 (sql, sql.length, out stmt); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_section (stmt)); + } + + return return_value; + } + + public Objects.Section _fill_section (Sqlite.Statement stmt) { + Objects.Section return_value = new Objects.Section (); + return_value.id = stmt.column_text (0); + return_value.name = stmt.column_text (1); + return_value.archived_at = stmt.column_text (2); + return_value.added_at = stmt.column_text (3); + return_value.project_id = stmt.column_text (4); + return_value.section_order = stmt.column_int (5); + return_value.collapsed = get_parameter_bool (stmt, 6); + return_value.is_deleted = get_parameter_bool (stmt, 7); + return_value.is_archived = get_parameter_bool (stmt, 8); + return_value.color = stmt.column_text (9); + return_value.description = stmt.column_text (10); + return_value.hidded = get_parameter_bool (stmt, 11); + return return_value; + } + + public bool delete_section (Objects.Section section) { + Sqlite.Statement stmt; + + sql = """ DELETE FROM Sections WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", section.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", section.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool update_section (Objects.Section section) { - Sqlite.Statement stmt; + public bool update_section (Objects.Section section) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Sections SET name=$name, archived_at=$archived_at, added_at=$added_at, project_id=$project_id, section_order=$section_order, collapsed=$collapsed, is_deleted=$is_deleted, is_archived=$is_archived, color=$color, description=$description, @@ -1031,91 +1031,91 @@ public class Services.Database : GLib.Object { WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$name", section.name); - set_parameter_str (stmt, "$archived_at", section.archived_at); - set_parameter_str (stmt, "$added_at", section.added_at); - set_parameter_str (stmt, "$project_id", section.project_id); - set_parameter_int (stmt, "$section_order", section.section_order); - set_parameter_bool (stmt, "$collapsed", section.collapsed); - set_parameter_bool (stmt, "$is_deleted", section.is_deleted); - set_parameter_bool (stmt, "$is_archived", section.is_archived); - set_parameter_str (stmt, "$color", section.color); - set_parameter_str (stmt, "$description", section.description); - set_parameter_bool (stmt, "$hidded", section.hidded); - set_parameter_str (stmt, "$id", section.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$name", section.name); + set_parameter_str (stmt, "$archived_at", section.archived_at); + set_parameter_str (stmt, "$added_at", section.added_at); + set_parameter_str (stmt, "$project_id", section.project_id); + set_parameter_int (stmt, "$section_order", section.section_order); + set_parameter_bool (stmt, "$collapsed", section.collapsed); + set_parameter_bool (stmt, "$is_deleted", section.is_deleted); + set_parameter_bool (stmt, "$is_archived", section.is_archived); + set_parameter_str (stmt, "$color", section.color); + set_parameter_str (stmt, "$description", section.description); + set_parameter_bool (stmt, "$hidded", section.hidded); + set_parameter_str (stmt, "$id", section.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool move_section (Objects.Section section, string old_project_id) { - Sqlite.Statement stmt; + public bool move_section (Objects.Section section, string old_project_id) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Sections SET project_id=$project_id WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$project_id", section.project_id); - set_parameter_str (stmt, "$id", section.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$project_id", section.project_id); + set_parameter_str (stmt, "$id", section.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool move_section_items (Objects.Section section) { - Sqlite.Statement stmt; + public bool move_section_items (Objects.Section section) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Items SET project_id=$project_id WHERE section_id=$section_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$project_id", section.project_id); - set_parameter_str (stmt, "$section_id", section.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$project_id", section.project_id); + set_parameter_str (stmt, "$section_id", section.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool archive_section (Objects.Section section) { - Sqlite.Statement stmt; + public bool archive_section (Objects.Section section) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Sections SET is_archived=$is_archived WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_bool (stmt, "$is_archived", section.is_archived); - set_parameter_str (stmt, "$id", section.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_bool (stmt, "$is_archived", section.is_archived); + set_parameter_str (stmt, "$id", section.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - /* - Items - */ + /* + Items + */ - public bool insert_item (Objects.Item item, bool insert = true) { - Sqlite.Statement stmt; + public bool insert_item (Objects.Item item, bool insert = true) { + Sqlite.Statement stmt; - sql = """ + sql = """ INSERT OR IGNORE INTO Items (id, content, description, due, added_at, completed_at, updated_at, section_id, project_id, parent_id, priority, child_order, checked, is_deleted, day_order, collapsed, pinned, labels, extra_data, item_type) @@ -1124,116 +1124,116 @@ public class Services.Database : GLib.Object { $checked, $is_deleted, $day_order, $collapsed, $pinned, $labels, $extra_data, $item_type); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", item.id); - set_parameter_str (stmt, "$content", item.content); - set_parameter_str (stmt, "$description", item.description); - set_parameter_str (stmt, "$due", item.due.to_string ()); - set_parameter_str (stmt, "$added_at", item.added_at); - set_parameter_str (stmt, "$completed_at", item.completed_at); - set_parameter_str (stmt, "$updated_at", item.updated_at); - set_parameter_str (stmt, "$section_id", item.section_id); - set_parameter_str (stmt, "$project_id", item.project_id); - set_parameter_str (stmt, "$parent_id", item.parent_id); - set_parameter_int (stmt, "$priority", item.priority); - set_parameter_int (stmt, "$child_order", item.child_order); - set_parameter_bool (stmt, "$checked", item.checked); - set_parameter_bool (stmt, "$is_deleted", item.is_deleted); - set_parameter_int (stmt, "$day_order", item.day_order); - set_parameter_bool (stmt, "$collapsed", item.collapsed); - set_parameter_bool (stmt, "$pinned", item.pinned); - set_parameter_str (stmt, "$labels", get_labels_ids (item.labels)); - set_parameter_str (stmt, "$extra_data", item.extra_data); - set_parameter_str (stmt, "$item_type", item.item_type.to_string ()); - - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } - - public Gee.ArrayList get_items_collection () { - Gee.ArrayList return_value = new Gee.ArrayList (); - Sqlite.Statement stmt; - - sql = "SELECT * FROM Items WHERE is_deleted = 0;"; - - db.prepare_v2 (sql, sql.length, out stmt); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_item (stmt)); - } - - return return_value; - } - - public Objects.Item get_item_by_id (string id) { - Objects.Item returned = new Objects.Item (); - Sqlite.Statement stmt; - - sql = "SELECT * FROM Items WHERE id = $id LIMIT 1;"; - - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", id); - - if (stmt.step () == Sqlite.ROW) { - returned = _fill_item (stmt); - } - - - return returned; - } - - public Objects.Item _fill_item (Sqlite.Statement stmt) { - Objects.Item return_value = new Objects.Item (); - return_value.id = stmt.column_text (0); - return_value.content = stmt.column_text (1); - return_value.description = stmt.column_text (2); - return_value.due.update_from_json (get_due_parameter (stmt.column_text (3))); - return_value.added_at = stmt.column_text (4); - return_value.completed_at = stmt.column_text (5); - return_value.updated_at = stmt.column_text (6); - return_value.section_id = stmt.column_text (7); - return_value.project_id = stmt.column_text (8); - return_value.parent_id = stmt.column_text (9); - return_value.priority = stmt.column_int (10); - return_value.child_order = stmt.column_int (11); - return_value.checked = get_parameter_bool (stmt, 12); - return_value.is_deleted = get_parameter_bool (stmt, 13); - return_value.day_order = stmt.column_int (14); - return_value.collapsed = get_parameter_bool (stmt, 15); - return_value.pinned = get_parameter_bool (stmt, 16); - return_value.labels = Services.Store.instance ().get_labels_by_item_labels (stmt.column_text (17)); - return_value.extra_data = stmt.column_text (18); - return_value.item_type = ItemType.parse (stmt.column_text (19)); - - return return_value; - } - - public bool delete_item (Objects.Item item) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", item.id); + set_parameter_str (stmt, "$content", item.content); + set_parameter_str (stmt, "$description", item.description); + set_parameter_str (stmt, "$due", item.due.to_string ()); + set_parameter_str (stmt, "$added_at", item.added_at); + set_parameter_str (stmt, "$completed_at", item.completed_at); + set_parameter_str (stmt, "$updated_at", item.updated_at); + set_parameter_str (stmt, "$section_id", item.section_id); + set_parameter_str (stmt, "$project_id", item.project_id); + set_parameter_str (stmt, "$parent_id", item.parent_id); + set_parameter_int (stmt, "$priority", item.priority); + set_parameter_int (stmt, "$child_order", item.child_order); + set_parameter_bool (stmt, "$checked", item.checked); + set_parameter_bool (stmt, "$is_deleted", item.is_deleted); + set_parameter_int (stmt, "$day_order", item.day_order); + set_parameter_bool (stmt, "$collapsed", item.collapsed); + set_parameter_bool (stmt, "$pinned", item.pinned); + set_parameter_str (stmt, "$labels", get_labels_ids (item.labels)); + set_parameter_str (stmt, "$extra_data", item.extra_data); + set_parameter_str (stmt, "$item_type", item.item_type.to_string ()); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + return stmt.step () == Sqlite.DONE; + } + + public Gee.ArrayList get_items_collection () { + Gee.ArrayList return_value = new Gee.ArrayList (); + Sqlite.Statement stmt; + + sql = "SELECT * FROM Items WHERE is_deleted = 0;"; + + db.prepare_v2 (sql, sql.length, out stmt); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_item (stmt)); + } + + return return_value; + } + + public Objects.Item get_item_by_id (string id) { + Objects.Item returned = new Objects.Item (); + Sqlite.Statement stmt; + + sql = "SELECT * FROM Items WHERE id = $id LIMIT 1;"; + + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", id); + + if (stmt.step () == Sqlite.ROW) { + returned = _fill_item (stmt); + } + + + return returned; + } + + public Objects.Item _fill_item (Sqlite.Statement stmt) { + Objects.Item return_value = new Objects.Item (); + return_value.id = stmt.column_text (0); + return_value.content = stmt.column_text (1); + return_value.description = stmt.column_text (2); + return_value.due.update_from_json (get_due_parameter (stmt.column_text (3))); + return_value.added_at = stmt.column_text (4); + return_value.completed_at = stmt.column_text (5); + return_value.updated_at = stmt.column_text (6); + return_value.section_id = stmt.column_text (7); + return_value.project_id = stmt.column_text (8); + return_value.parent_id = stmt.column_text (9); + return_value.priority = stmt.column_int (10); + return_value.child_order = stmt.column_int (11); + return_value.checked = get_parameter_bool (stmt, 12); + return_value.is_deleted = get_parameter_bool (stmt, 13); + return_value.day_order = stmt.column_int (14); + return_value.collapsed = get_parameter_bool (stmt, 15); + return_value.pinned = get_parameter_bool (stmt, 16); + return_value.labels = Services.Store.instance ().get_labels_by_item_labels (stmt.column_text (17)); + return_value.extra_data = stmt.column_text (18); + return_value.item_type = ItemType.parse (stmt.column_text (19)); + + return return_value; + } + + public bool delete_item (Objects.Item item) { + Sqlite.Statement stmt; + + sql = """ DELETE FROM Items WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", item.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", item.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - - return stmt.step () == Sqlite.DONE; - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - public bool update_item (Objects.Item item, string update_id = "") { - item.updated_at = new GLib.DateTime.now_local ().to_string (); - Sqlite.Statement stmt; - sql = """ + return stmt.step () == Sqlite.DONE; + } + + public bool update_item (Objects.Item item, string update_id = "") { + item.updated_at = new GLib.DateTime.now_local ().to_string (); + Sqlite.Statement stmt; + + sql = """ UPDATE Items SET content=$content, description=$description, due=$due, added_at=$added_at, completed_at=$completed_at, updated_at=$updated_at, section_id=$section_id, project_id=$project_id, parent_id=$parent_id, @@ -1243,41 +1243,41 @@ public class Services.Database : GLib.Object { WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$content", item.content); - set_parameter_str (stmt, "$description", item.description); - set_parameter_str (stmt, "$due", item.due.to_string ()); - set_parameter_str (stmt, "$added_at", item.added_at); - set_parameter_str (stmt, "$completed_at", item.completed_at); - set_parameter_str (stmt, "$updated_at", item.updated_at); - set_parameter_str (stmt, "$section_id", item.section_id); - set_parameter_str (stmt, "$project_id", item.project_id); - set_parameter_str (stmt, "$parent_id", item.parent_id); - set_parameter_int (stmt, "$priority", item.priority); - set_parameter_int (stmt, "$child_order", item.child_order); - set_parameter_bool (stmt, "$checked", item.checked); - set_parameter_bool (stmt, "$is_deleted", item.is_deleted); - set_parameter_int (stmt, "$day_order", item.day_order); - set_parameter_bool (stmt, "$collapsed", item.collapsed); - set_parameter_bool (stmt, "$pinned", item.pinned); - set_parameter_str (stmt, "$labels", get_labels_ids (item.labels)); - set_parameter_str (stmt, "$extra_data", item.extra_data); - set_parameter_str (stmt, "$item_type", item.item_type.to_string ()); - set_parameter_str (stmt, "$id", item.id); - - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - - return stmt.step () == Sqlite.DONE; - } - - public bool move_item (Objects.Item item) { - item.updated_at = new GLib.DateTime.now_local ().to_string (); - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$content", item.content); + set_parameter_str (stmt, "$description", item.description); + set_parameter_str (stmt, "$due", item.due.to_string ()); + set_parameter_str (stmt, "$added_at", item.added_at); + set_parameter_str (stmt, "$completed_at", item.completed_at); + set_parameter_str (stmt, "$updated_at", item.updated_at); + set_parameter_str (stmt, "$section_id", item.section_id); + set_parameter_str (stmt, "$project_id", item.project_id); + set_parameter_str (stmt, "$parent_id", item.parent_id); + set_parameter_int (stmt, "$priority", item.priority); + set_parameter_int (stmt, "$child_order", item.child_order); + set_parameter_bool (stmt, "$checked", item.checked); + set_parameter_bool (stmt, "$is_deleted", item.is_deleted); + set_parameter_int (stmt, "$day_order", item.day_order); + set_parameter_bool (stmt, "$collapsed", item.collapsed); + set_parameter_bool (stmt, "$pinned", item.pinned); + set_parameter_str (stmt, "$labels", get_labels_ids (item.labels)); + set_parameter_str (stmt, "$extra_data", item.extra_data); + set_parameter_str (stmt, "$item_type", item.item_type.to_string ()); + set_parameter_str (stmt, "$id", item.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + + return stmt.step () == Sqlite.DONE; + } + + public bool move_item (Objects.Item item) { + item.updated_at = new GLib.DateTime.now_local ().to_string (); + Sqlite.Statement stmt; + + sql = """ UPDATE Items SET section_id=$section_id, project_id=$project_id, @@ -1285,715 +1285,715 @@ public class Services.Database : GLib.Object { WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$section_id", item.section_id); - set_parameter_str (stmt, "$project_id", item.project_id); - set_parameter_str (stmt, "$parent_id", item.parent_id); - set_parameter_str (stmt, "$id", item.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$section_id", item.section_id); + set_parameter_str (stmt, "$project_id", item.project_id); + set_parameter_str (stmt, "$parent_id", item.parent_id); + set_parameter_str (stmt, "$id", item.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool complete_item (Objects.Item item, bool old_checked) { - Sqlite.Statement stmt; + public bool complete_item (Objects.Item item, bool old_checked) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Items SET checked=$checked, completed_at=$completed_at WHERE id=$id OR parent_id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_bool (stmt, "$checked", item.checked); - set_parameter_str (stmt, "$completed_at", item.completed_at); - set_parameter_str (stmt, "$id", item.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_bool (stmt, "$checked", item.checked); + set_parameter_str (stmt, "$completed_at", item.completed_at); + set_parameter_str (stmt, "$id", item.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - - return stmt.step () == Sqlite.DONE; - } - public void update_child_order (Objects.BaseObject base_object) { - Sqlite.Statement stmt; + return stmt.step () == Sqlite.DONE; + } - sql = """ + public void update_child_order (Objects.BaseObject base_object) { + Sqlite.Statement stmt; + + sql = """ UPDATE %s SET %s=$order WHERE id=$id; """.printf (base_object.table_name, base_object.column_order_name); - db.prepare_v2 (sql, sql.length, out stmt); + db.prepare_v2 (sql, sql.length, out stmt); + + if (base_object is Objects.Item) { + set_parameter_int (stmt, "$order", ((Objects.Item) base_object).child_order); + } else if (base_object is Objects.Section) { + set_parameter_int (stmt, "$order", ((Objects.Section) base_object).section_order); + } else if (base_object is Objects.Project) { + set_parameter_int (stmt, "$order", ((Objects.Project) base_object).child_order); + } else if (base_object is Objects.Label) { + set_parameter_int (stmt, "$order", ((Objects.Label) base_object).item_order); + } - if (base_object is Objects.Item) { - set_parameter_int (stmt, "$order", ((Objects.Item) base_object).child_order); - } else if (base_object is Objects.Section) { - set_parameter_int (stmt, "$order", ((Objects.Section) base_object).section_order); - } else if (base_object is Objects.Project) { - set_parameter_int (stmt, "$order", ((Objects.Project) base_object).child_order); - } else if (base_object is Objects.Label) { - set_parameter_int (stmt, "$order", ((Objects.Label) base_object).item_order); - } + set_parameter_str (stmt, "$id", base_object.id); - set_parameter_str (stmt, "$id", base_object.id); + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - } + } - // Reminders - public bool insert_reminder (Objects.Reminder reminder) { - Sqlite.Statement stmt; - string sql; + // Reminders + public bool insert_reminder (Objects.Reminder reminder) { + Sqlite.Statement stmt; + string sql; - sql = """ + sql = """ INSERT OR IGNORE INTO Reminders (id, item_id, type, due, mm_offset) VALUES ($id, $item_id, $type, $due, $mm_offset); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", reminder.id); - set_parameter_str (stmt, "$item_id", reminder.item_id); - set_parameter_str (stmt, "$type", reminder.reminder_type.to_string ()); - set_parameter_str (stmt, "$due", reminder.due.to_string ()); - set_parameter_int (stmt, "$mm_offset", reminder.mm_offset); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", reminder.id); + set_parameter_str (stmt, "$item_id", reminder.item_id); + set_parameter_str (stmt, "$type", reminder.reminder_type.to_string ()); + set_parameter_str (stmt, "$due", reminder.due.to_string ()); + set_parameter_int (stmt, "$mm_offset", reminder.mm_offset); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public Gee.ArrayList get_reminders_collection () { - Gee.ArrayList return_value = new Gee.ArrayList (); - Sqlite.Statement stmt; + public Gee.ArrayList get_reminders_collection () { + Gee.ArrayList return_value = new Gee.ArrayList (); + Sqlite.Statement stmt; - sql = """ + sql = """ SELECT id, item_id, type, due, mm_offset FROM Reminders; """; - db.prepare_v2 (sql, sql.length, out stmt); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_reminder (stmt)); - } - - return return_value; - } - - public Objects.Reminder _fill_reminder (Sqlite.Statement stmt) { - Objects.Reminder return_value = new Objects.Reminder (); - return_value.id = stmt.column_text (0); - return_value.item_id = stmt.column_text (1); - return_value.reminder_type = stmt.column_text (2) == "absolute" ? ReminderType.ABSOLUTE : ReminderType.RELATIVE; - return_value.due.update_from_json (get_due_parameter (stmt.column_text (3))); - return_value.mm_offset = stmt.column_int (4); - return return_value; - } - - public Gee.ArrayList get_reminders_by_item_id (string id) { - Gee.ArrayList return_value = new Gee.ArrayList (); - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_reminder (stmt)); + } + + return return_value; + } + + public Objects.Reminder _fill_reminder (Sqlite.Statement stmt) { + Objects.Reminder return_value = new Objects.Reminder (); + return_value.id = stmt.column_text (0); + return_value.item_id = stmt.column_text (1); + return_value.reminder_type = stmt.column_text (2) == "absolute" ? ReminderType.ABSOLUTE : ReminderType.RELATIVE; + return_value.due.update_from_json (get_due_parameter (stmt.column_text (3))); + return_value.mm_offset = stmt.column_int (4); + return return_value; + } + + public Gee.ArrayList get_reminders_by_item_id (string id) { + Gee.ArrayList return_value = new Gee.ArrayList (); + Sqlite.Statement stmt; + + sql = """ SELECT id, item_id, type, due, mm_offset FROM Reminders WHERE item_id=$item_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$item_id", id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$item_id", id); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_reminder (stmt)); + } + + return return_value; + } - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_reminder (stmt)); - } - - return return_value; - } + public bool delete_reminder (Objects.Reminder reminder) { + Sqlite.Statement stmt; - public bool delete_reminder (Objects.Reminder reminder) { - Sqlite.Statement stmt; - - sql = """ + sql = """ DELETE FROM Reminders WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", reminder.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", reminder.id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - - return stmt.step () == Sqlite.DONE; - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - // Atrachments - public bool insert_attachment (Objects.Attachment attachment) { - Sqlite.Statement stmt; - string sql; - sql = """ + return stmt.step () == Sqlite.DONE; + } + + // Atrachments + public bool insert_attachment (Objects.Attachment attachment) { + Sqlite.Statement stmt; + string sql; + + sql = """ INSERT OR IGNORE INTO Attachments (id, item_id, file_type, file_name, file_size, file_path) VALUES ($id, $item_id, $file_type, $file_name, $file_size, $file_path); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", attachment.id); - set_parameter_str (stmt, "$item_id", attachment.item_id); - set_parameter_str (stmt, "$file_type", attachment.file_type); - set_parameter_str (stmt, "$file_name", attachment.file_name); - set_parameter_int64 (stmt, "$file_size", attachment.file_size); - set_parameter_str (stmt, "$file_path", attachment.file_path); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", attachment.id); + set_parameter_str (stmt, "$item_id", attachment.item_id); + set_parameter_str (stmt, "$file_type", attachment.file_type); + set_parameter_str (stmt, "$file_name", attachment.file_name); + set_parameter_int64 (stmt, "$file_size", attachment.file_size); + set_parameter_str (stmt, "$file_path", attachment.file_path); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public Gee.ArrayList get_attachments_collection () { - Gee.ArrayList return_value = new Gee.ArrayList (); - Sqlite.Statement stmt; + public Gee.ArrayList get_attachments_collection () { + Gee.ArrayList return_value = new Gee.ArrayList (); + Sqlite.Statement stmt; - sql = """ + sql = """ SELECT * FROM Attachments; """; - db.prepare_v2 (sql, sql.length, out stmt); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_attachment (stmt)); - } - - return return_value; - } - - public Objects.Attachment _fill_attachment (Sqlite.Statement stmt) { - Objects.Attachment return_value = new Objects.Attachment (); - return_value.id = stmt.column_text (0); - return_value.item_id = stmt.column_text (1); - return_value.file_type = stmt.column_text (2); - return_value.file_name = stmt.column_text (3); - return_value.file_size = stmt.column_int64 (4); - return_value.file_path = stmt.column_text (5); - return return_value; - } - - public bool delete_attachment (Objects.Attachment attachment) { - Sqlite.Statement stmt; - - sql = """ + db.prepare_v2 (sql, sql.length, out stmt); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_attachment (stmt)); + } + + return return_value; + } + + public Objects.Attachment _fill_attachment (Sqlite.Statement stmt) { + Objects.Attachment return_value = new Objects.Attachment (); + return_value.id = stmt.column_text (0); + return_value.item_id = stmt.column_text (1); + return_value.file_type = stmt.column_text (2); + return_value.file_name = stmt.column_text (3); + return_value.file_size = stmt.column_int64 (4); + return_value.file_path = stmt.column_text (5); + return return_value; + } + + public bool delete_attachment (Objects.Attachment attachment) { + Sqlite.Statement stmt; + + sql = """ DELETE FROM Attachments WHERE id=$id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", attachment.id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", attachment.id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - - return stmt.step () == Sqlite.DONE; - } - /* - * Queue - */ + return stmt.step () == Sqlite.DONE; + } - public void insert_queue (Objects.Queue queue) { - Sqlite.Statement stmt; + /* + * Queue + */ - sql = """ + public void insert_queue (Objects.Queue queue) { + Sqlite.Statement stmt; + + sql = """ INSERT OR IGNORE INTO Queue (uuid, object_id, query, temp_id, args, date_added) VALUES ($uuid, $object_id, $query, $temp_id, $args, $date_added); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$uuid", queue.uuid); - set_parameter_str (stmt, "$object_id", queue.object_id); - set_parameter_str (stmt, "$query", queue.query); - set_parameter_str (stmt, "$temp_id", queue.temp_id); - set_parameter_str (stmt, "$args", queue.args); - set_parameter_str (stmt, "$date_added", queue.date_added); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$uuid", queue.uuid); + set_parameter_str (stmt, "$object_id", queue.object_id); + set_parameter_str (stmt, "$query", queue.query); + set_parameter_str (stmt, "$temp_id", queue.temp_id); + set_parameter_str (stmt, "$args", queue.args); + set_parameter_str (stmt, "$date_added", queue.date_added); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - } + } - public Gee.ArrayList get_all_queue () { - Gee.ArrayList return_value = new Gee.ArrayList (); - Sqlite.Statement stmt; + public Gee.ArrayList get_all_queue () { + Gee.ArrayList return_value = new Gee.ArrayList (); + Sqlite.Statement stmt; - sql = """ + sql = """ SELECT * FROM Queue ORDER BY date_added; """; - db.prepare_v2 (sql, sql.length, out stmt); + db.prepare_v2 (sql, sql.length, out stmt); - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_queue (stmt)); - } - - return return_value; - } + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_queue (stmt)); + } - public Objects.Queue _fill_queue (Sqlite.Statement stmt) { - Objects.Queue return_value = new Objects.Queue (); - return_value.uuid = stmt.column_text (0); - return_value.object_id = stmt.column_text (1); - return_value.query = stmt.column_text (2); - return_value.temp_id = stmt.column_text (3); - return_value.args = stmt.column_text (4); - return_value.date_added = stmt.column_text (5); - return return_value; - } + return return_value; + } - public void insert_CurTempIds (string id, string temp_id, string object) { // vala-lint=naming-convention - Sqlite.Statement stmt; + public Objects.Queue _fill_queue (Sqlite.Statement stmt) { + Objects.Queue return_value = new Objects.Queue (); + return_value.uuid = stmt.column_text (0); + return_value.object_id = stmt.column_text (1); + return_value.query = stmt.column_text (2); + return_value.temp_id = stmt.column_text (3); + return_value.args = stmt.column_text (4); + return_value.date_added = stmt.column_text (5); + return return_value; + } - sql = """ + public void insert_CurTempIds (string id, string temp_id, string object) { // vala-lint=naming-convention + Sqlite.Statement stmt; + + sql = """ INSERT OR IGNORE INTO CurTempIds (id, temp_id, object) VALUES ($id, $temp_id, $object); """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", id); - set_parameter_str (stmt, "$temp_id", temp_id); - set_parameter_str (stmt, "$object", object); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", id); + set_parameter_str (stmt, "$temp_id", temp_id); + set_parameter_str (stmt, "$object", object); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - } + } - public bool curTempIds_exists (string id) { // vala-lint=naming-convention - bool returned = false; - Sqlite.Statement stmt; + public bool curTempIds_exists (string id) { // vala-lint=naming-convention + bool returned = false; + Sqlite.Statement stmt; - sql = """ + sql = """ SELECT COUNT (*) FROM CurTempIds WHERE id = $id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", id); - if (stmt.step () == Sqlite.ROW) { - returned = stmt.column_int (0) > 0; - } + if (stmt.step () == Sqlite.ROW) { + returned = stmt.column_int (0) > 0; + } - - return returned; - } - public string get_temp_id (string id) { - string returned = ""; - Sqlite.Statement stmt; + return returned; + } - sql = """ + public string get_temp_id (string id) { + string returned = ""; + Sqlite.Statement stmt; + + sql = """ SELECT temp_id FROM CurTempIds WHERE id = $id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", id); + + if (stmt.step () == Sqlite.ROW) { + returned = stmt.column_text (0); + } - if (stmt.step () == Sqlite.ROW) { - returned = stmt.column_text (0); - } - - return returned; - } + return returned; + } - public bool update_project_id (string current_id, string new_id) { - Sqlite.Statement stmt; + public bool update_project_id (string current_id, string new_id) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Projects SET id = $new_id WHERE id = $current_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$new_id", new_id); + set_parameter_str (stmt, "$current_id", current_id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool update_project_section_id (string current_id, string new_id) { - Sqlite.Statement stmt; + public bool update_project_section_id (string current_id, string new_id) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Sections SET project_id = $new_id WHERE project_id = $current_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$new_id", new_id); + set_parameter_str (stmt, "$current_id", current_id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - - return stmt.step () == Sqlite.DONE; - } - public bool update_project_item_id (string current_id, string new_id) { - Sqlite.Statement stmt; + return stmt.step () == Sqlite.DONE; + } - sql = """ + public bool update_project_item_id (string current_id, string new_id) { + Sqlite.Statement stmt; + + sql = """ UPDATE Items SET project_id = $new_id WHERE project_id = $current_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$new_id", new_id); + set_parameter_str (stmt, "$current_id", current_id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool update_section_id (string current_id, string new_id) { - Sqlite.Statement stmt; + public bool update_section_id (string current_id, string new_id) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Sections SET id = $new_id WHERE id = $current_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$new_id", new_id); + set_parameter_str (stmt, "$current_id", current_id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool update_section_item_id (string current_id, string new_id) { - Sqlite.Statement stmt; + public bool update_section_item_id (string current_id, string new_id) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Items SET section_id = $new_id WHERE section_id = $current_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$new_id", new_id); + set_parameter_str (stmt, "$current_id", current_id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - - return stmt.step () == Sqlite.DONE; - } - public bool update_item_id (string current_id, string new_id) { - Sqlite.Statement stmt; + return stmt.step () == Sqlite.DONE; + } - sql = """ + public bool update_item_id (string current_id, string new_id) { + Sqlite.Statement stmt; + + sql = """ UPDATE Items SET id = $new_id WHERE id = $current_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$new_id", new_id); + set_parameter_str (stmt, "$current_id", current_id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public bool update_item_child_id (string current_id, string new_id) { - Sqlite.Statement stmt; + public bool update_item_child_id (string current_id, string new_id) { + Sqlite.Statement stmt; - sql = """ + sql = """ UPDATE Items SET parent_id = $new_id WHERE parent_id = $current_id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$new_id", new_id); + set_parameter_str (stmt, "$current_id", current_id); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - return stmt.step () == Sqlite.DONE; - } + return stmt.step () == Sqlite.DONE; + } - public void remove_CurTempIds (string id) { // vala-lint=naming-convention - Sqlite.Statement stmt; + public void remove_CurTempIds (string id) { // vala-lint=naming-convention + Sqlite.Statement stmt; - sql = """ + sql = """ DELETE FROM CurTempIds WHERE id = $id; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$id", id); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", id); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - - } - public void remove_queue (string uuid) { - Sqlite.Statement stmt; + } - sql = """ + public void remove_queue (string uuid) { + Sqlite.Statement stmt; + + sql = """ DELETE FROM Queue WHERE uuid = $uuid; """; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$uuid", uuid); + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$uuid", uuid); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - } + } - public void clear_queue () { - Sqlite.Statement stmt; - string sql; - int res; + public void clear_queue () { + Sqlite.Statement stmt; + string sql; + int res; - sql = """ + sql = """ DELETE FROM Queue; """; - res = db.prepare_v2 (sql, -1, out stmt); - assert (res == Sqlite.OK); + res = db.prepare_v2 (sql, -1, out stmt); + assert (res == Sqlite.OK); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - } + } - public void clear_cur_temp_ids () { - Sqlite.Statement stmt; - string sql; - int res; + public void clear_cur_temp_ids () { + Sqlite.Statement stmt; + string sql; + int res; - sql = """ + sql = """ DELETE FROM CurTempIds; """; - res = db.prepare_v2 (sql, -1, out stmt); - assert (res == Sqlite.OK); + res = db.prepare_v2 (sql, -1, out stmt); + assert (res == Sqlite.OK); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - - } - /* - * ObjectsEvent - */ + } - public Gee.ArrayList get_events_by_item (string id, int start_week, int end_week) { - Gee.ArrayList return_value = new Gee.ArrayList (); + /* + * ObjectsEvent + */ - Sqlite.Statement stmt; - - sql = """ + public Gee.ArrayList get_events_by_item (string id, int start_week, int end_week) { + Gee.ArrayList return_value = new Gee.ArrayList (); + + Sqlite.Statement stmt; + + sql = """ SELECT * FROM OEvents WHERE object_id = $object_id AND (event_date >= DATETIME('now', '-%d days') AND event_date <= DATETIME('now', '-%d days')) ORDER BY event_date DESC """.printf (end_week, start_week); - - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$object_id", id); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_object_event (stmt)); - } - - return return_value; - } - - public Objects.ObjectEvent _fill_object_event (Sqlite.Statement stmt) { - Objects.ObjectEvent return_value = new Objects.ObjectEvent (); - return_value.id = stmt.column_int64 (0); - return_value.event_type = ObjectEventType.parse (stmt.column_text (1)); - return_value.event_date = stmt.column_text (2); - return_value.object_id = stmt.column_text (3); - return_value.object_type = stmt.column_text (4); - return_value.object_key = ObjectEventKeyType.parse (stmt.column_text (5)); - return_value.object_old_value = stmt.column_text (6); - return_value.object_new_value = stmt.column_text (7); - return_value.parent_item_id = stmt.column_text (8); - return_value.parent_project_id = stmt.column_text (9); - return return_value; - } - - // PARAMETER REGION - private void set_parameter_int (Sqlite.Statement? stmt, string par, int val) { - int par_position = stmt.bind_parameter_index (par); - stmt.bind_int (par_position, val); - } - - private void set_parameter_int64 (Sqlite.Statement? stmt, string par, int64 val) { - int par_position = stmt.bind_parameter_index (par); - stmt.bind_int64 (par_position, val); - } - - private void set_parameter_str (Sqlite.Statement? stmt, string par, string val) { - int par_position = stmt.bind_parameter_index (par); - stmt.bind_text (par_position, val); - } - - private void set_parameter_bool (Sqlite.Statement? stmt, string par, bool val) { - int par_position = stmt.bind_parameter_index (par); - stmt.bind_int (par_position, val ? 1 : 0); - } - - private bool get_parameter_bool (Sqlite.Statement stmt, int col) { - return stmt.column_int (col) == 1; - } - - Json.Parser parser; - public Json.Object? get_due_parameter (string data) { - if (parser == null) { - parser = new Json.Parser (); - } - - try { - parser.load_from_data (data, -1); - } catch (Error e) { - debug (e.message); - } - - return parser.get_root ().get_object (); - } - - public string get_labels_ids (Gee.ArrayList labels) { - string return_value = ""; - - foreach (Objects.Label label in labels) { - return_value += label.id + ";"; - } - - if (return_value.length > 0) { - return_value = return_value.substring (0, return_value.length - 1); - } - - return return_value; - } - - public bool column_exists (string table, string column) { - Sqlite.Statement stmt; - bool returned = false; - - sql = """ + + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$object_id", id); + + while (stmt.step () == Sqlite.ROW) { + return_value.add (_fill_object_event (stmt)); + } + + return return_value; + } + + public Objects.ObjectEvent _fill_object_event (Sqlite.Statement stmt) { + Objects.ObjectEvent return_value = new Objects.ObjectEvent (); + return_value.id = stmt.column_int64 (0); + return_value.event_type = ObjectEventType.parse (stmt.column_text (1)); + return_value.event_date = stmt.column_text (2); + return_value.object_id = stmt.column_text (3); + return_value.object_type = stmt.column_text (4); + return_value.object_key = ObjectEventKeyType.parse (stmt.column_text (5)); + return_value.object_old_value = stmt.column_text (6); + return_value.object_new_value = stmt.column_text (7); + return_value.parent_item_id = stmt.column_text (8); + return_value.parent_project_id = stmt.column_text (9); + return return_value; + } + + // PARAMETER REGION + private void set_parameter_int (Sqlite.Statement? stmt, string par, int val) { + int par_position = stmt.bind_parameter_index (par); + stmt.bind_int (par_position, val); + } + + private void set_parameter_int64 (Sqlite.Statement? stmt, string par, int64 val) { + int par_position = stmt.bind_parameter_index (par); + stmt.bind_int64 (par_position, val); + } + + private void set_parameter_str (Sqlite.Statement? stmt, string par, string val) { + int par_position = stmt.bind_parameter_index (par); + stmt.bind_text (par_position, val); + } + + private void set_parameter_bool (Sqlite.Statement? stmt, string par, bool val) { + int par_position = stmt.bind_parameter_index (par); + stmt.bind_int (par_position, val ? 1 : 0); + } + + private bool get_parameter_bool (Sqlite.Statement stmt, int col) { + return stmt.column_int (col) == 1; + } + + Json.Parser parser; + public Json.Object? get_due_parameter (string data) { + if (parser == null) { + parser = new Json.Parser (); + } + + try { + parser.load_from_data (data, -1); + } catch (Error e) { + debug (e.message); + } + + return parser.get_root ().get_object (); + } + + public string get_labels_ids (Gee.ArrayList labels) { + string return_value = ""; + + foreach (Objects.Label label in labels) { + return_value += label.id + ";"; + } + + if (return_value.length > 0) { + return_value = return_value.substring (0, return_value.length - 1); + } + + return return_value; + } + + public bool column_exists (string table, string column) { + Sqlite.Statement stmt; + bool returned = false; + + sql = """ PRAGMA table_info(%s); """.printf (table); - db.prepare_v2 (sql, sql.length, out stmt); + db.prepare_v2 (sql, sql.length, out stmt); - stmt.step (); + stmt.step (); - while (stmt.step () == Sqlite.ROW) { - if (stmt.column_text (1) == column) { - returned = true; - } - } + while (stmt.step () == Sqlite.ROW) { + if (stmt.column_text (1) == column) { + returned = true; + } + } - - return returned; - } - public void add_text_column (string table, string column, string default_value) { - if (column_exists (table, column)) { - return; - } - - Sqlite.Statement stmt; + return returned; + } - sql = """ + public void add_text_column (string table, string column, string default_value) { + if (column_exists (table, column)) { + return; + } + + Sqlite.Statement stmt; + + sql = """ ALTER TABLE %s ADD COLUMN %s TEXT DEFAULT '%s'; """.printf (table, column, default_value); - db.prepare_v2 (sql, sql.length, out stmt); + db.prepare_v2 (sql, sql.length, out stmt); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - } + } - public void add_int_column (string table, string column, int default_value) { - if (column_exists (table, column)) { - return; - } - - Sqlite.Statement stmt; + public void add_int_column (string table, string column, int default_value) { + if (column_exists (table, column)) { + return; + } - sql = """ + Sqlite.Statement stmt; + + sql = """ ALTER TABLE %s ADD COLUMN %s INTEGER DEFAULT %i; """.printf (table, column, default_value); - db.prepare_v2 (sql, sql.length, out stmt); + db.prepare_v2 (sql, sql.length, out stmt); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } - - } + } - public void add_item_label_column () { - if (column_exists ("Items", "labels")) { - return; - } + public void add_item_label_column () { + if (column_exists ("Items", "labels")) { + return; + } - Sqlite.Statement stmt; + Sqlite.Statement stmt; - sql = """ + sql = """ ALTER TABLE Items ADD COLUMN labels TEXT; - + UPDATE Items SET labels = ( SELECT GROUP_CONCAT(label_id, ';') @@ -2002,69 +2002,69 @@ public class Services.Database : GLib.Object { ); """; - db.prepare_v2 (sql, sql.length, out stmt); + db.prepare_v2 (sql, sql.length, out stmt); - if (stmt.step () != Sqlite.DONE) { - warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - } + } - public void add_project_labels_source_id () { - if (column_exists ("Projects", "source_id")) { - return; - } + public void add_project_labels_source_id () { + if (column_exists ("Projects", "source_id")) { + return; + } - sql = """ + sql = """ ALTER TABLE Projects ADD COLUMN source_id TEXT; UPDATE Projects SET source_id = backend_type; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } - sql = """ + sql = """ ALTER TABLE Labels ADD COLUMN source_id TEXT; UPDATE Labels SET source_id = backend_type; """; - if (db.exec (sql, null, out errormsg) != Sqlite.OK) { - warning (errormsg); - } - - Util.get_default ().create_local_source (); - - if (Services.Todoist.get_default ().is_logged_in ()) { - var todoist_source = new Objects.Source (); - todoist_source.id = SourceType.TODOIST.to_string (); - todoist_source.source_type = SourceType.TODOIST; - todoist_source.display_name = Services.Settings.get_default ().settings.get_string ("todoist-user-email"); - todoist_source.data = Utils.AccountMigrate.get_data_from_todoist (); - todoist_source.last_sync = Services.Settings.get_default ().settings.get_string ("todoist-last-sync"); - todoist_source.sync_server = Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server"); - - Services.Store.instance ().insert_source (todoist_source); - } - - if (Services.CalDAV.Core.get_default ().is_logged_in ()) { - var caldav_source = new Objects.Source (); - caldav_source.id = SourceType.CALDAV.to_string (); - caldav_source.source_type = SourceType.CALDAV; - caldav_source.data = Utils.AccountMigrate.get_data_from_caldav (); - caldav_source.last_sync = Services.Settings.get_default ().settings.get_string ("caldav-last-sync"); - caldav_source.sync_server = Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server"); - - if (caldav_source.caldav_data.user_email != "") { - caldav_source.display_name = caldav_source.caldav_data.user_email; - } else if (caldav_source.caldav_data.user_displayname != "") { - caldav_source.display_name = caldav_source.caldav_data.user_displayname; - } else { - caldav_source.display_name = _("Nextcloud"); - } - - Services.Store.instance ().insert_source (caldav_source); - } - } + if (db.exec (sql, null, out errormsg) != Sqlite.OK) { + warning (errormsg); + } + + Util.get_default ().create_local_source (); + + if (Services.Todoist.get_default ().is_logged_in ()) { + var todoist_source = new Objects.Source (); + todoist_source.id = SourceType.TODOIST.to_string (); + todoist_source.source_type = SourceType.TODOIST; + todoist_source.display_name = Services.Settings.get_default ().settings.get_string ("todoist-user-email"); + todoist_source.data = Utils.AccountMigrate.get_data_from_todoist (); + todoist_source.last_sync = Services.Settings.get_default ().settings.get_string ("todoist-last-sync"); + todoist_source.sync_server = Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server"); + + Services.Store.instance ().insert_source (todoist_source); + } + + if (Services.CalDAV.Core.get_default ().is_logged_in ()) { + var caldav_source = new Objects.Source (); + caldav_source.id = SourceType.CALDAV.to_string (); + caldav_source.source_type = SourceType.CALDAV; + caldav_source.data = Utils.AccountMigrate.get_data_from_caldav (); + caldav_source.last_sync = Services.Settings.get_default ().settings.get_string ("caldav-last-sync"); + caldav_source.sync_server = Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server"); + + if (caldav_source.caldav_data.user_email != "") { + caldav_source.display_name = caldav_source.caldav_data.user_email; + } else if (caldav_source.caldav_data.user_displayname != "") { + caldav_source.display_name = caldav_source.caldav_data.user_displayname; + } else { + caldav_source.display_name = _("Nextcloud"); + } + + Services.Store.instance ().insert_source (caldav_source); + } + } } diff --git a/src/Layouts/FilterPaneRow.vala b/src/Layouts/FilterPaneRow.vala index c0a4ad2c4..1037a3674 100644 --- a/src/Layouts/FilterPaneRow.vala +++ b/src/Layouts/FilterPaneRow.vala @@ -1,198 +1,198 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public class Layouts.FilterPaneRow : Gtk.FlowBoxChild { - public FilterType filter_type { get; construct; } - - public string title; - public string icon_name; - - private Gtk.Image title_image; - private Gtk.Label title_label; - private Gtk.Label count_label; - private Gtk.Revealer indicator_revealer; - - public FilterPaneRow (FilterType filter_type) { - Object ( - filter_type: filter_type - ); - } - - construct { - add_css_class ("card"); - add_css_class ("filter-pane-row"); - - title_image = new Gtk.Image.from_icon_name (filter_type.get_icon ()) { - margin_start = 3 - }; - - title_label = new Gtk.Label (filter_type.get_name ()) { - margin_start = 3, - css_classes = { "font-bold" }, - ellipsize = Pango.EllipsizeMode.END - }; - - var indicator_widget = new Adw.Bin () { - width_request = 9, + public FilterType filter_type { get; construct; } + + public string title; + public string icon_name; + + private Gtk.Image title_image; + private Gtk.Label title_label; + private Gtk.Label count_label; + private Gtk.Revealer indicator_revealer; + + public FilterPaneRow (FilterType filter_type) { + Object ( + filter_type: filter_type + ); + } + + construct { + add_css_class ("card"); + add_css_class ("filter-pane-row"); + + title_image = new Gtk.Image.from_icon_name (filter_type.get_icon ()) { + margin_start = 3 + }; + + title_label = new Gtk.Label (filter_type.get_name ()) { + margin_start = 3, + css_classes = { "font-bold" }, + ellipsize = Pango.EllipsizeMode.END + }; + + var indicator_widget = new Adw.Bin () { + width_request = 9, height_request = 9, margin_end = 3, - margin_top = 3, - valign = END, - css_classes = { "indicator" , "bg-danger"} - }; - - indicator_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.CROSSFADE, - child = indicator_widget, - hexpand = true, - halign = END - }; - - var title_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); - title_box.append (title_label); - title_box.append (indicator_revealer); - - count_label = new Gtk.Label (null) { - hexpand = true, - halign = Gtk.Align.END, - margin_end = 3, - css_classes = { "font-bold" } - }; - - var count_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.CROSSFADE, - child = count_label - }; - - var main_grid = new Gtk.Grid () { - column_spacing = 6, - margin_start = 3, - margin_end = 3, - margin_top = 3, - margin_bottom = 3, - width_request = 100 - }; - - main_grid.attach (title_image, 0, 0, 1, 1); - main_grid.attach (count_revealer, 1, 0, 1, 1); - main_grid.attach (title_box, 0, 1, 2, 2); - - child = main_grid; - Util.get_default ().set_widget_color (filter_type.get_color (), this); - Services.Settings.get_default ().settings.bind ("show-tasks-count", count_revealer, "reveal_child", GLib.SettingsBindFlags.DEFAULT); - - var select_gesture = new Gtk.GestureClick (); - add_controller (select_gesture); - select_gesture.pressed.connect (() => { - Services.EventBus.get_default ().pane_selected (PaneType.FILTER, filter_type.to_string ()); - }); - - Services.EventBus.get_default ().pane_selected.connect ((pane_type, id) => { - if (pane_type == PaneType.FILTER && filter_type.to_string () == id) { - add_css_class ("selected"); - - if (!has_css_class ("animation")) { - add_css_class ("animation"); - Timeout.add (700, () => { - remove_css_class ("animation"); - return GLib.Source.REMOVE; - }); - } - } else { - remove_css_class ("selected"); - } - }); - } - - private void update_count_label (int count) { - count_label.label = count <= 0 ? "" : count.to_string (); - } - - public void init () { - if (filter_type == FilterType.TODAY) { - update_count_label (Objects.Filters.Today.get_default ().today_count + Objects.Filters.Today.get_default ().overdeue_count); - indicator_revealer.reveal_child = Objects.Filters.Today.get_default ().overdeue_count > 0; - Objects.Filters.Today.get_default ().today_count_updated.connect (() => { - update_count_label (Objects.Filters.Today.get_default ().today_count + Objects.Filters.Today.get_default ().overdeue_count); - indicator_revealer.reveal_child = Objects.Filters.Today.get_default ().overdeue_count > 0; - }); - } else if (filter_type == FilterType.INBOX) { - init_inbox_count (); - } else if (filter_type == FilterType.SCHEDULED) { - update_count_label (Objects.Filters.Scheduled.get_default ().scheduled_count); - Objects.Filters.Scheduled.get_default ().scheduled_count_updated.connect (() => { - update_count_label (Objects.Filters.Scheduled.get_default ().scheduled_count); - }); - } else if (filter_type == FilterType.PINBOARD) { - update_count_label (Objects.Filters.Pinboard.get_default ().pinboard_count); - Objects.Filters.Pinboard.get_default ().pinboard_count_updated.connect (() => { - update_count_label (Objects.Filters.Pinboard.get_default ().pinboard_count); - }); - } else if (filter_type == FilterType.LABELS) { - update_count_label (Objects.Filters.Labels.get_default ().count); - Objects.Filters.Labels.get_default ().count_updated.connect (() => { - update_count_label (Objects.Filters.Labels.get_default ().count); - }); - } else if (filter_type == FilterType.COMPLETED) { - update_count_label (Objects.Filters.Completed.get_default ().count); - Objects.Filters.Completed.get_default ().count_updated.connect (() => { - update_count_label (Objects.Filters.Completed.get_default ().count); - }); - } - } - private void init_inbox_count () { - Objects.Project inbox_project = Services.Store.instance ().get_project ( - Services.Settings.get_default ().settings.get_string ("local-inbox-project-id") - ); - update_count_label (inbox_project.project_count); - - inbox_project.project_count_updated.connect (() => { - update_count_label (inbox_project.project_count); - }); - } - - public int item_order () { - return find_index (Services.Settings.get_default ().settings.get_strv ("views-order-visible"), filter_type.to_string ()); - } - - public bool active () { - var views_order = Services.Settings.get_default ().settings.get_strv ("views-order-visible"); - - for (int i = 0; i < views_order.length; i++) { - if (views_order [i] == filter_type.to_string ()) { - return true; - } - } - - return false; - } - - private int find_index (string[] array, string elemento) { - for (int i = 0; i < array.length; i++) { - if (array [i] == elemento) { - return i; - } - } - - return -1; - } + margin_top = 3, + valign = END, + css_classes = { "indicator", "bg-danger"} + }; + + indicator_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.CROSSFADE, + child = indicator_widget, + hexpand = true, + halign = END + }; + + var title_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0); + title_box.append (title_label); + title_box.append (indicator_revealer); + + count_label = new Gtk.Label (null) { + hexpand = true, + halign = Gtk.Align.END, + margin_end = 3, + css_classes = { "font-bold" } + }; + + var count_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.CROSSFADE, + child = count_label + }; + + var main_grid = new Gtk.Grid () { + column_spacing = 6, + margin_start = 3, + margin_end = 3, + margin_top = 3, + margin_bottom = 3, + width_request = 100 + }; + + main_grid.attach (title_image, 0, 0, 1, 1); + main_grid.attach (count_revealer, 1, 0, 1, 1); + main_grid.attach (title_box, 0, 1, 2, 2); + + child = main_grid; + Util.get_default ().set_widget_color (filter_type.get_color (), this); + Services.Settings.get_default ().settings.bind ("show-tasks-count", count_revealer, "reveal_child", GLib.SettingsBindFlags.DEFAULT); + + var select_gesture = new Gtk.GestureClick (); + add_controller (select_gesture); + select_gesture.pressed.connect (() => { + Services.EventBus.get_default ().pane_selected (PaneType.FILTER, filter_type.to_string ()); + }); + + Services.EventBus.get_default ().pane_selected.connect ((pane_type, id) => { + if (pane_type == PaneType.FILTER && filter_type.to_string () == id) { + add_css_class ("selected"); + + if (!has_css_class ("animation")) { + add_css_class ("animation"); + Timeout.add (700, () => { + remove_css_class ("animation"); + return GLib.Source.REMOVE; + }); + } + } else { + remove_css_class ("selected"); + } + }); + } + + private void update_count_label (int count) { + count_label.label = count <= 0 ? "" : count.to_string (); + } + + public void init () { + if (filter_type == FilterType.TODAY) { + update_count_label (Objects.Filters.Today.get_default ().today_count + Objects.Filters.Today.get_default ().overdeue_count); + indicator_revealer.reveal_child = Objects.Filters.Today.get_default ().overdeue_count > 0; + Objects.Filters.Today.get_default ().today_count_updated.connect (() => { + update_count_label (Objects.Filters.Today.get_default ().today_count + Objects.Filters.Today.get_default ().overdeue_count); + indicator_revealer.reveal_child = Objects.Filters.Today.get_default ().overdeue_count > 0; + }); + } else if (filter_type == FilterType.INBOX) { + init_inbox_count (); + } else if (filter_type == FilterType.SCHEDULED) { + update_count_label (Objects.Filters.Scheduled.get_default ().scheduled_count); + Objects.Filters.Scheduled.get_default ().scheduled_count_updated.connect (() => { + update_count_label (Objects.Filters.Scheduled.get_default ().scheduled_count); + }); + } else if (filter_type == FilterType.PINBOARD) { + update_count_label (Objects.Filters.Pinboard.get_default ().pinboard_count); + Objects.Filters.Pinboard.get_default ().pinboard_count_updated.connect (() => { + update_count_label (Objects.Filters.Pinboard.get_default ().pinboard_count); + }); + } else if (filter_type == FilterType.LABELS) { + update_count_label (Objects.Filters.Labels.get_default ().count); + Objects.Filters.Labels.get_default ().count_updated.connect (() => { + update_count_label (Objects.Filters.Labels.get_default ().count); + }); + } else if (filter_type == FilterType.COMPLETED) { + update_count_label (Objects.Filters.Completed.get_default ().count); + Objects.Filters.Completed.get_default ().count_updated.connect (() => { + update_count_label (Objects.Filters.Completed.get_default ().count); + }); + } + } + private void init_inbox_count () { + Objects.Project inbox_project = Services.Store.instance ().get_project ( + Services.Settings.get_default ().settings.get_string ("local-inbox-project-id") + ); + update_count_label (inbox_project.project_count); + + inbox_project.project_count_updated.connect (() => { + update_count_label (inbox_project.project_count); + }); + } + + public int item_order () { + return find_index (Services.Settings.get_default ().settings.get_strv ("views-order-visible"), filter_type.to_string ()); + } + + public bool active () { + var views_order = Services.Settings.get_default ().settings.get_strv ("views-order-visible"); + + for (int i = 0; i < views_order.length; i++) { + if (views_order [i] == filter_type.to_string ()) { + return true; + } + } + + return false; + } + + private int find_index (string[] array, string elemento) { + for (int i = 0; i < array.length; i++) { + if (array [i] == elemento) { + return i; + } + } + + return -1; + } } diff --git a/src/Layouts/HeaderBar.vala b/src/Layouts/HeaderBar.vala index a4549f9ee..dbe3182b2 100644 --- a/src/Layouts/HeaderBar.vala +++ b/src/Layouts/HeaderBar.vala @@ -1,143 +1,143 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public class Layouts.HeaderBar : Adw.Bin { - private Adw.HeaderBar headerbar; - private Gtk.Label title_label; - private Gtk.Label title2_label; - private Gtk.Revealer back_button_revealer; - private Gtk.Box start_box; - private Gtk.Button back_button; - private Gtk.Button sidebar_button; - - private string _title; - public string title { - set { - _title = value; - title_label.label = _title; - } - - get { - return _title; - } - } - - private string _title2; - public string title2 { - set { - _title2 = value; - title2_label.label = _title2; - } - - get { - return _title; - } - } - - public bool back_revealer { - set { - back_button_revealer.reveal_child = value; - } - - get { - return back_button_revealer.reveal_child; - } - } - - public signal void back_activated (); - - construct { + private Adw.HeaderBar headerbar; + private Gtk.Label title_label; + private Gtk.Label title2_label; + private Gtk.Revealer back_button_revealer; + private Gtk.Box start_box; + private Gtk.Button back_button; + private Gtk.Button sidebar_button; + + private string _title; + public string title { + set { + _title = value; + title_label.label = _title; + } + + get { + return _title; + } + } + + private string _title2; + public string title2 { + set { + _title2 = value; + title2_label.label = _title2; + } + + get { + return _title; + } + } + + public bool back_revealer { + set { + back_button_revealer.reveal_child = value; + } + + get { + return back_button_revealer.reveal_child; + } + } + + public signal void back_activated (); + + construct { sidebar_button = new Gtk.Button () { valign = Gtk.Align.CENTER, - css_classes = { "flat" }, - tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Open/Close Sidebar"), "M"), + css_classes = { "flat" }, + tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Open/Close Sidebar"), "M"), }; - update_sidebar_icon (); + update_sidebar_icon (); - // Back Button - back_button = new Gtk.Button.from_icon_name ("go-previous-symbolic") { - valign = Gtk.Align.CENTER, - margin_end = 6, - css_classes = { "flat" }, - tooltip_text = _("Back") - }; + // Back Button + back_button = new Gtk.Button.from_icon_name ("go-previous-symbolic") { + valign = Gtk.Align.CENTER, + margin_end = 6, + css_classes = { "flat" }, + tooltip_text = _("Back") + }; - back_button_revealer = new Gtk.Revealer () { + back_button_revealer = new Gtk.Revealer () { transition_type = Gtk.RevealerTransitionType.SLIDE_LEFT, - child = back_button, - reveal_child = false + child = back_button, + reveal_child = false + }; + + // Title + title_label = new Gtk.Label (null) { + css_classes = { "font-bold" }, + ellipsize = Pango.EllipsizeMode.END + }; + + title2_label = new Gtk.Label (null) { + css_classes = { "font-bold", "caption" }, + ellipsize = Pango.EllipsizeMode.END, + margin_start = 6, + margin_top = 3 }; - // Title - title_label = new Gtk.Label (null) { - css_classes = { "font-bold" }, - ellipsize = Pango.EllipsizeMode.END - }; - - title2_label = new Gtk.Label (null) { - css_classes = { "font-bold", "caption" }, - ellipsize = Pango.EllipsizeMode.END, - margin_start = 6, - margin_top = 3 - }; - - start_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3); - start_box.append (sidebar_button); - start_box.append (back_button_revealer); - start_box.append (title_label); - start_box.append (title2_label); - - headerbar = new Adw.HeaderBar () { + start_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 3); + start_box.append (sidebar_button); + start_box.append (back_button_revealer); + start_box.append (title_label); + start_box.append (title2_label); + + headerbar = new Adw.HeaderBar () { hexpand = true, - show_title = false + show_title = false }; - headerbar.pack_start (start_box); + headerbar.pack_start (start_box); - child = headerbar; + child = headerbar; - sidebar_button.clicked.connect (() => { + sidebar_button.clicked.connect (() => { bool slim_mode = Services.Settings.get_default ().settings.get_boolean ("slim-mode"); - Services.Settings.get_default ().settings.set_boolean ("slim-mode", !slim_mode); + Services.Settings.get_default ().settings.set_boolean ("slim-mode", !slim_mode); }); - back_button.clicked.connect (() => { - back_activated (); - }); - - Services.Settings.get_default ().settings.changed["slim-mode"].connect (() => { - update_sidebar_icon (); - }); - } - - private void update_sidebar_icon () { - if (Services.Settings.get_default ().settings.get_boolean ("slim-mode")) { - sidebar_button.icon_name = "dock-left-symbolic"; - } else { - sidebar_button.icon_name = "dock-right-symbolic"; - } - } - - public void pack_end (Gtk.Widget widget) { - headerbar.pack_end (widget); - } + back_button.clicked.connect (() => { + back_activated (); + }); + + Services.Settings.get_default ().settings.changed["slim-mode"].connect (() => { + update_sidebar_icon (); + }); + } + + private void update_sidebar_icon () { + if (Services.Settings.get_default ().settings.get_boolean ("slim-mode")) { + sidebar_button.icon_name = "dock-left-symbolic"; + } else { + sidebar_button.icon_name = "dock-right-symbolic"; + } + } + + public void pack_end (Gtk.Widget widget) { + headerbar.pack_end (widget); + } } diff --git a/src/Layouts/ItemBase.vala b/src/Layouts/ItemBase.vala index 38785e153..a0c6e723d 100644 --- a/src/Layouts/ItemBase.vala +++ b/src/Layouts/ItemBase.vala @@ -1,32 +1,32 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public abstract class Layouts.ItemBase : Gtk.ListBoxRow { - public Objects.Item item { get; construct; } + public Objects.Item item { get; construct; } - public string update_id { get; set; default = Util.get_default ().generate_id (); } + public string update_id { get; set; default = Util.get_default ().generate_id (); } - public abstract void update_request (); - public abstract void hide_destroy (); - public abstract void delete_request (bool undo = true); - public abstract void select_row (bool active); - public abstract void checked_toggled (bool active, uint? time = null); + public abstract void update_request (); + public abstract void hide_destroy (); + public abstract void delete_request (bool undo = true); + public abstract void select_row (bool active); + public abstract void checked_toggled (bool active, uint? time = null); } diff --git a/src/Layouts/ItemBoard.vala b/src/Layouts/ItemBoard.vala index 124362ea2..58d8536e1 100644 --- a/src/Layouts/ItemBoard.vala +++ b/src/Layouts/ItemBoard.vala @@ -789,7 +789,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { if (value.dup_object () is Layouts.ItemBoard) { var picked_widget = (Layouts.ItemBoard) value; - + if (picked_widget.item.id == item.parent_id) { return; } @@ -842,20 +842,20 @@ public class Layouts.ItemBoard : Layouts.ItemBase { signals_map[drop_target.accept.connect ((drop) => { GLib.Value value = Value (typeof (Gtk.Widget)); - try { - drop.drag.content.get_value (ref value); - } catch (Error e) { - debug (e.message); - } + try { + drop.drag.content.get_value (ref value); + } catch (Error e) { + debug (e.message); + } - if (value.dup_object () is Layouts.ItemBoard) { - var picked_widget = (Layouts.ItemBoard) value; - if (picked_widget.item.id != item.parent_id) { - return true; - } - } + if (value.dup_object () is Layouts.ItemBoard) { + var picked_widget = (Layouts.ItemBoard) value; + if (picked_widget.item.id != item.parent_id) { + return true; + } + } - return false; + return false; })] = drop_target; signals_map[drop_target.drop.connect ((value, x, y) => { diff --git a/src/Layouts/ItemRow.vala b/src/Layouts/ItemRow.vala index e7c159ef8..9cfcd3668 100644 --- a/src/Layouts/ItemRow.vala +++ b/src/Layouts/ItemRow.vala @@ -200,7 +200,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { Object ( item: item, is_project_view: is_project_view - ); + ); } ~ItemRow () { diff --git a/src/Layouts/ItemSidebarView.vala b/src/Layouts/ItemSidebarView.vala index 0f0077e41..3d798236c 100644 --- a/src/Layouts/ItemSidebarView.vala +++ b/src/Layouts/ItemSidebarView.vala @@ -1,82 +1,82 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public class Layouts.ItemSidebarView : Adw.Bin { - public Objects.Item item { get; set; } - - private Gtk.Button parent_back_button; - private Gtk.Label parent_label; - private Gtk.Revealer spinner_revealer; - private Widgets.TextView content_textview; - private Widgets.Markdown.Buffer current_buffer; - private Widgets.Markdown.EditView markdown_edit_view = null; - private Gtk.Revealer markdown_revealer; - private Widgets.StatusButton status_button; - private Widgets.ScheduleButton schedule_button; - private Widgets.PriorityButton priority_button; - private Widgets.LabelPicker.LabelButton label_button; - private Widgets.PinButton pin_button; - private Widgets.SectionPicker.SectionButton section_button; - private Widgets.ReminderPicker.ReminderButton reminder_button; - private Widgets.SubItems subitems; - private Widgets.Attachments attachments; - - private Widgets.ContextMenu.MenuItem copy_clipboard_item; - private Widgets.ContextMenu.MenuItem duplicate_item; - private Widgets.ContextMenu.MenuItem move_item; - private Widgets.ContextMenu.MenuItem repeat_item; - - private Gee.HashMap signals_map = new Gee.HashMap (); - public string update_id { get; set; default = Util.get_default ().generate_id (); } - private ulong description_handler_change_id = 0; - - public bool show_completed { - get { - return Services.Settings.get_default ().settings.get_boolean ("always-show-completed-subtasks"); - } - } - - construct { - var previous_icon = new Gtk.Image.from_icon_name ("go-previous-symbolic"); - - parent_label = new Gtk.Label (null) { - css_classes = { "font-bold" }, - ellipsize = Pango.EllipsizeMode.END - }; - - var parent_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - parent_box.append (previous_icon); - parent_box.append (parent_label); - - parent_back_button = new Gtk.Button () { - child = parent_box, - css_classes = { "flat" }, - valign = Gtk.Align.CENTER - }; - - var close_button = new Gtk.Button.from_icon_name ("step-out-symbolic") { - tooltip_text = _("Close Detail") - }; - - var menu_button = new Gtk.MenuButton () { + public Objects.Item item { get; set; } + + private Gtk.Button parent_back_button; + private Gtk.Label parent_label; + private Gtk.Revealer spinner_revealer; + private Widgets.TextView content_textview; + private Widgets.Markdown.Buffer current_buffer; + private Widgets.Markdown.EditView markdown_edit_view = null; + private Gtk.Revealer markdown_revealer; + private Widgets.StatusButton status_button; + private Widgets.ScheduleButton schedule_button; + private Widgets.PriorityButton priority_button; + private Widgets.LabelPicker.LabelButton label_button; + private Widgets.PinButton pin_button; + private Widgets.SectionPicker.SectionButton section_button; + private Widgets.ReminderPicker.ReminderButton reminder_button; + private Widgets.SubItems subitems; + private Widgets.Attachments attachments; + + private Widgets.ContextMenu.MenuItem copy_clipboard_item; + private Widgets.ContextMenu.MenuItem duplicate_item; + private Widgets.ContextMenu.MenuItem move_item; + private Widgets.ContextMenu.MenuItem repeat_item; + + private Gee.HashMap signals_map = new Gee.HashMap (); + public string update_id { get; set; default = Util.get_default ().generate_id (); } + private ulong description_handler_change_id = 0; + + public bool show_completed { + get { + return Services.Settings.get_default ().settings.get_boolean ("always-show-completed-subtasks"); + } + } + + construct { + var previous_icon = new Gtk.Image.from_icon_name ("go-previous-symbolic"); + + parent_label = new Gtk.Label (null) { + css_classes = { "font-bold" }, + ellipsize = Pango.EllipsizeMode.END + }; + + var parent_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); + parent_box.append (previous_icon); + parent_box.append (parent_label); + + parent_back_button = new Gtk.Button () { + child = parent_box, + css_classes = { "flat" }, + valign = Gtk.Align.CENTER + }; + + var close_button = new Gtk.Button.from_icon_name ("step-out-symbolic") { + tooltip_text = _("Close Detail") + }; + + var menu_button = new Gtk.MenuButton () { valign = Gtk.Align.CENTER, halign = Gtk.Align.CENTER, popover = build_context_menu (), @@ -84,582 +84,586 @@ public class Layouts.ItemSidebarView : Adw.Bin { css_classes = { "flat" } }; - pin_button = new Widgets.PinButton (); + pin_button = new Widgets.PinButton (); - var spinner = new Gtk.Spinner () { - valign = Gtk.Align.CENTER, - halign = Gtk.Align.CENTER, - spinning = true - }; - - spinner_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.CROSSFADE, - child = spinner - }; + var spinner = new Gtk.Spinner () { + valign = Gtk.Align.CENTER, + halign = Gtk.Align.CENTER, + spinning = true + }; - var headerbar = new Adw.HeaderBar () { + spinner_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.CROSSFADE, + child = spinner + }; + + var headerbar = new Adw.HeaderBar () { title_widget = new Gtk.Label (null), hexpand = true, - decoration_layout = ":", + decoration_layout = ":", css_classes = { "flat" } }; - headerbar.pack_start (parent_back_button); - headerbar.pack_end (close_button); - headerbar.pack_end (menu_button); - headerbar.pack_end (pin_button); - headerbar.pack_end (spinner_revealer); - - content_textview = new Widgets.TextView () { - left_margin = 12, - right_margin = 12, - top_margin = 12, - bottom_margin = 12, - height_request = 64, - wrap_mode = Gtk.WrapMode.WORD, - accepts_tab = false - }; - - content_textview.remove_css_class ("view"); - content_textview.add_css_class ("card"); - - var content_group = new Adw.PreferencesGroup () { - margin_start = 12, - margin_end = 12 - }; + headerbar.pack_start (parent_back_button); + headerbar.pack_end (close_button); + headerbar.pack_end (menu_button); + headerbar.pack_end (pin_button); + headerbar.pack_end (spinner_revealer); + + content_textview = new Widgets.TextView () { + left_margin = 12, + right_margin = 12, + top_margin = 12, + bottom_margin = 12, + height_request = 64, + wrap_mode = Gtk.WrapMode.WORD, + accepts_tab = false + }; + + content_textview.remove_css_class ("view"); + content_textview.add_css_class ("card"); + + var content_group = new Adw.PreferencesGroup () { + margin_start = 12, + margin_end = 12 + }; content_group.title = _("Title"); - content_group.add (content_textview); - - status_button = new Widgets.StatusButton (); - section_button = new Widgets.SectionPicker.SectionButton (); - schedule_button = new Widgets.ScheduleButton.for_board (); - priority_button = new Widgets.PriorityButton.for_board (); - label_button = new Widgets.LabelPicker.LabelButton.for_board (); - reminder_button = new Widgets.ReminderPicker.ReminderButton.for_board (); - - var properties_grid = new Gtk.Grid () { - column_homogeneous = true, - column_spacing = 12, - row_homogeneous = true, - row_spacing = 12 - }; - - properties_grid.attach (status_button, 0, 0); - properties_grid.attach (section_button, 1, 0); - properties_grid.attach (schedule_button, 0, 1); - properties_grid.attach (priority_button, 1, 1); - properties_grid.attach (label_button, 0, 2); - properties_grid.attach (reminder_button, 1, 2); - - var properties_group = new Adw.PreferencesGroup () { - margin_start = 12, - margin_end = 12, - margin_top = 12 - }; - + content_group.add (content_textview); + + status_button = new Widgets.StatusButton (); + section_button = new Widgets.SectionPicker.SectionButton (); + schedule_button = new Widgets.ScheduleButton.for_board (); + priority_button = new Widgets.PriorityButton.for_board (); + label_button = new Widgets.LabelPicker.LabelButton.for_board (); + reminder_button = new Widgets.ReminderPicker.ReminderButton.for_board (); + + var properties_grid = new Gtk.Grid () { + column_homogeneous = true, + column_spacing = 12, + row_homogeneous = true, + row_spacing = 12 + }; + + properties_grid.attach (status_button, 0, 0); + properties_grid.attach (section_button, 1, 0); + properties_grid.attach (schedule_button, 0, 1); + properties_grid.attach (priority_button, 1, 1); + properties_grid.attach (label_button, 0, 2); + properties_grid.attach (reminder_button, 1, 2); + + var properties_group = new Adw.PreferencesGroup () { + margin_start = 12, + margin_end = 12, + margin_top = 12 + }; + properties_group.title = _("Properties"); - properties_group.add (properties_grid); + properties_group.add (properties_grid); + + current_buffer = new Widgets.Markdown.Buffer (); - current_buffer = new Widgets.Markdown.Buffer (); - - markdown_revealer = new Gtk.Revealer (); + markdown_revealer = new Gtk.Revealer (); - var description_group = new Adw.PreferencesGroup () { - margin_start = 12, - margin_end = 12, - margin_top = 12 - }; + var description_group = new Adw.PreferencesGroup () { + margin_start = 12, + margin_end = 12, + margin_top = 12 + }; description_group.title = _("Description"); - description_group.add (markdown_revealer); - - subitems = new Widgets.SubItems.for_board () { - margin_top = 12 - }; - - attachments = new Widgets.Attachments (true) { - margin_top = 12, - card = true - }; - - var content = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - valign = Gtk.Align.START, - margin_bottom = 24, - margin_start = 6, - margin_end = 6 - }; - - content.append (content_group); - content.append (properties_group); - content.append (description_group); - content.append (subitems); - content.append (attachments); - - var scrolled_window = new Widgets.ScrolledWindow (content); - - var toolbar_view = new Adw.ToolbarView () { + description_group.add (markdown_revealer); + + subitems = new Widgets.SubItems.for_board () { + margin_top = 12 + }; + + attachments = new Widgets.Attachments (true) { + margin_top = 12, + card = true + }; + + var content = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { + valign = Gtk.Align.START, + margin_bottom = 24, + margin_start = 6, + margin_end = 6 + }; + + content.append (content_group); + content.append (properties_group); + content.append (description_group); + content.append (subitems); + content.append (attachments); + + var scrolled_window = new Widgets.ScrolledWindow (content); + + var toolbar_view = new Adw.ToolbarView () { bottom_bar_style = Adw.ToolbarStyle.RAISED_BORDER, reveal_bottom_bars = false }; toolbar_view.add_top_bar (headerbar); toolbar_view.content = scrolled_window; - child = toolbar_view; - - close_button.clicked.connect (() => { - Services.EventBus.get_default ().close_item (); - }); - - var content_controller_key = new Gtk.EventControllerKey (); - content_textview.add_controller (content_controller_key); - content_controller_key.key_released.connect ((keyval, keycode, state) => { - update_content_description (); - }); - - schedule_button.duedate_changed.connect (() => { - update_due (schedule_button.duedate); - }); - - priority_button.changed.connect ((priority) => { - if (item.priority != priority) { - item.priority = priority; - - if (item.project.source_type == SourceType.TODOIST || - item.project.source_type == SourceType.CALDAV) { - item.update_async (""); - } else { - item.update_local (); - } - } - }); - - label_button.labels_changed.connect ((labels) => { - update_labels (labels); - }); - - pin_button.changed.connect (() => { - item.update_pin (!item.pinned); - }); - - section_button.selected.connect ((section) => { - move (item.project, section.id, ""); - }); - - reminder_button.reminder_added.connect ((reminder) => { - reminder.item_id = item.id; - - if (item.project.source_type == SourceType.TODOIST) { - item.loading = true; - Services.Todoist.get_default ().add.begin (reminder, (obj, res) => { - HttpResponse response = Services.Todoist.get_default ().add.end (res); - item.loading = false; - - if (response.status) { - reminder.id = response.data; - } else { - reminder.id = Util.get_default ().generate_id (reminder); - } - - item.add_reminder_if_not_exists (reminder); - }); - } else { - reminder.id = Util.get_default ().generate_id (reminder); - item.add_reminder_if_not_exists (reminder); - } - }); - - status_button.changed.connect ((active) => { - checked_toggled (active); - }); - - parent_back_button.clicked.connect (() => { - if (item.has_parent) { - Services.EventBus.get_default ().open_item (item.parent); - } else { - Services.EventBus.get_default ().close_item (); - } - }); - } - - private void update_content_description () { - if (item.content != content_textview.buffer.text || - item.description != current_buffer.get_all_text ().chomp ()) { - item.content = content_textview.buffer.text; - item.description = current_buffer.get_all_text ().chomp (); - item.update_async_timeout (update_id); - } - } - - public void present_item (Objects.Item _item) { - item = _item; - update_id = Util.get_default ().generate_id (); - - build_markdown_edit_view (); - - label_button.source = item.project.source; - update_request (); - - subitems.present_item (item); - subitems.reveal_child = true; - - attachments.present_item (item); - - if (item.has_parent) { - parent_label.label = item.parent.content; - parent_label.tooltip_text = item.parent.content; - } else { - if (item.section_id != "") { - parent_label.label = item.section.name; - parent_label.tooltip_text = item.section.name; - } else { - parent_label.label = item.project.name; - parent_label.tooltip_text = item.project.name; - } - } - - content_textview.grab_focus (); - - signals_map[Services.EventBus.get_default ().checked_toggled.connect ((_item) => { - if (item.id == _item.id) { - update_request (); - } - })] = Services.EventBus.get_default (); - - signals_map[item.updated.connect ((_update_id) => { - if (update_id != _update_id) { - update_request (); - } - })] = item; - - signals_map[item.pin_updated.connect (() => { - pin_button.update_from_item (item); - })] = item; - - signals_map[item.reminder_added.connect ((reminder) => { - reminder_button.add_reminder (reminder, item.reminders); - })] = item; - - signals_map[item.reminder_deleted.connect ((reminder) => { - reminder_button.delete_reminder (reminder, item.reminders); - })] = item; - - signals_map[item.loading_change.connect (() => { - spinner_revealer.reveal_child = item.loading; - })] = item; - } - - public void disconnect_all () { - foreach (var entry in signals_map.entries) { - entry.value.disconnect (entry.key); - } - - if (description_handler_change_id != 0) { - current_buffer.disconnect (description_handler_change_id); - description_handler_change_id = 0; - } - - signals_map.clear (); - subitems.disconnect_all (); - attachments.disconnect_all (); - - destroy_markdown_edit_view (); - } - - public void update_request () { - content_textview.buffer.text = item.content; - - if (description_handler_change_id != 0) { - current_buffer.disconnect (description_handler_change_id); - description_handler_change_id = 0; - } - - current_buffer.text = item.description; - - if (description_handler_change_id == 0) { - description_handler_change_id = current_buffer.changed.connect (() => { - update_content_description (); - }); - } - - schedule_button.update_from_item (item); - priority_button.update_from_item (item); - status_button.update_from_item (item); - - label_button.labels = item._get_labels (); - label_button.update_from_item (item); - - pin_button.update_from_item (item); - - section_button.set_sections (item.project.sections); - section_button.update_from_item (item); - - reminder_button.set_reminders (item.reminders); - - content_textview.editable = !item.completed; - markdown_edit_view.is_editable = !item.completed; - schedule_button.sensitive = !item.completed; - priority_button.sensitive = !item.completed; - label_button.sensitive = !item.completed; - pin_button.sensitive = !item.completed; - section_button.sensitive = !item.completed; - reminder_button.sensitive = !item.completed; - copy_clipboard_item.sensitive = !item.completed; - duplicate_item.sensitive = !item.completed; - move_item.sensitive = !item.completed; - repeat_item.sensitive = !item.completed; - subitems.add_button.sensitive = !item.completed; - } - - public void update_due (Objects.DueDate duedate) { - if (item == null) { - return; - } - - item.update_due (duedate); - } - - public void update_labels (Gee.HashMap new_labels) { - bool update = false; - - foreach (var entry in new_labels.entries) { - if (item.get_label (entry.key) == null) { - item.add_label_if_not_exists (entry.value); - update = true; - } - } - - foreach (var label in item._get_labels ()) { - if (!new_labels.has_key (label.id)) { - item.delete_item_label (label.id); - update = true; - } - } - - if (!update) { - return; - } - - item.update_async (""); - } - - private Gtk.Popover build_context_menu () { - var use_note_item = new Widgets.ContextMenu.MenuSwitch (_("Use as a Note"), "paper-symbolic"); - use_note_item.active = item.item_type == ItemType.NOTE; - - copy_clipboard_item = new Widgets.ContextMenu.MenuItem (_("Copy to Clipboard"), "clipboard-symbolic"); - duplicate_item = new Widgets.ContextMenu.MenuItem (_("Duplicate"), "tabs-stack-symbolic"); - move_item = new Widgets.ContextMenu.MenuItem (_("Move"), "arrow3-right-symbolic"); - repeat_item = new Widgets.ContextMenu.MenuItem (_("Repeat"), "playlist-repeat-symbolic"); - repeat_item.arrow = true; - - var delete_item = new Widgets.ContextMenu.MenuItem (_("Delete Task"), "user-trash-symbolic"); - delete_item.add_css_class ("menu-item-danger"); - - var more_information_item = new Widgets.ContextMenu.MenuItem (_("Change History"), "rotation-edit-symbolic"); - - var popover = new Gtk.Popover () { - has_arrow = false, - position = Gtk.PositionType.BOTTOM, - width_request = 250 - }; - - var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); - menu_box.margin_top = menu_box.margin_bottom = 3; - - if (!item.completed) { - menu_box.append (use_note_item); - menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); - menu_box.append (copy_clipboard_item); - menu_box.append (duplicate_item); - menu_box.append (move_item); - } - - - menu_box.append (delete_item); - menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); - menu_box.append (more_information_item); - - popover.child = menu_box; - - use_note_item.activate_item.connect (() => { - item.item_type = use_note_item.active ? ItemType.NOTE : ItemType.TASK; - item.update_local (); - }); - - copy_clipboard_item.clicked.connect (() => { - popover.popdown (); - item.copy_clipboard (); - }); - - duplicate_item.clicked.connect (() => { - popover.popdown (); - Util.get_default ().duplicate_item.begin (item, item.project_id, item.section_id, item.parent_id); - }); - - move_item.clicked.connect (() => { - popover.popdown (); - - Dialogs.ProjectPicker.ProjectPicker dialog; - if (item.project.is_inbox_project) { - dialog = new Dialogs.ProjectPicker.ProjectPicker.for_projects (); - } else { - dialog = new Dialogs.ProjectPicker.ProjectPicker.for_project (item.source); - } - - dialog.add_sections (item.project.sections); - dialog.project = item.project; - dialog.section = item.section; - dialog.present (Planify._instance.main_window); - - dialog.changed.connect ((type, id) => { - if (type == "project") { - move (Services.Store.instance ().get_project (id), ""); - } else { - move (item.project, id); - } - }); - }); - - delete_item.activate_item.connect (() => { - popover.popdown (); - delete_request (); - }); - - more_information_item.activate_item.connect (() => { - popover.popdown (); - var dialog = new Dialogs.ItemChangeHistory (item); - dialog.present (Planify._instance.main_window); - }); - - return popover; - } - - public void move (Objects.Project project, string section_id, string parent_id = "") { - string project_id = project.id; - - if (item.project.source_id != project.source_id) { - Util.get_default ().move_backend_type_item.begin (item, project); - } else { - if (item.project_id != project_id || item.section_id != section_id || item.parent_id != parent_id) { - item.move (project, section_id); - } - } - } - - public void delete_request (bool undo = true) { - var dialog = new Adw.AlertDialog ( - _("Are you sure you want to delete?"), - _("This can not be undone") - ); - - dialog.add_response ("cancel", _("Cancel")); - dialog.add_response ("delete", _("Delete")); - dialog.set_response_appearance ("delete", Adw.ResponseAppearance.DESTRUCTIVE); - dialog.present (Planify._instance.main_window); - - dialog.response.connect ((response) => { - if (response == "delete") { - item.delete_item (); - Services.EventBus.get_default ().close_item (); - } - }); - } - - public void prepare_new_item (string content = "") { - var dialog = new Dialogs.QuickAdd (); - dialog.for_base_object (item); - dialog.update_content (content); - dialog.present (Planify._instance.main_window); - } - - public void checked_toggled (bool active) { - bool old_checked = item.checked; - - if (active) { - complete_item (old_checked); - } else { - var old_completed_at = item.completed_at; - - item.checked = false; - item.completed_at = ""; - _complete_item.begin (old_checked, old_completed_at); - } - } - - private void complete_item (bool old_checked) { - if (Services.Settings.get_default ().settings.get_boolean ("task-complete-tone")) { - Util.get_default ().play_audio (); - } - - if (item.due.is_recurring && !item.due.is_recurrency_end) { - update_next_recurrency (); - } else { - var old_completed_at = item.completed_at; - - item.checked = true; - item.completed_at = new GLib.DateTime.now_local ().to_string (); - _complete_item (old_checked, old_completed_at); - } + child = toolbar_view; + + close_button.clicked.connect (() => { + Services.EventBus.get_default ().close_item (); + }); + + var content_controller_key = new Gtk.EventControllerKey (); + content_textview.add_controller (content_controller_key); + content_controller_key.key_released.connect ((keyval, keycode, state) => { + update_content_description (); + }); + + schedule_button.duedate_changed.connect (() => { + update_due (schedule_button.duedate); + }); + + priority_button.changed.connect ((priority) => { + if (item.priority != priority) { + item.priority = priority; + + if (item.project.source_type == SourceType.TODOIST || + item.project.source_type == SourceType.CALDAV) { + item.update_async (""); + } else { + item.update_local (); + } + } + }); + + label_button.labels_changed.connect ((labels) => { + update_labels (labels); + }); + + pin_button.changed.connect (() => { + item.update_pin (!item.pinned); + }); + + section_button.selected.connect ((section) => { + move (item.project, section.id, ""); + }); + + reminder_button.reminder_added.connect ((reminder) => { + reminder.item_id = item.id; + + if (item.project.source_type == SourceType.TODOIST) { + item.loading = true; + Services.Todoist.get_default ().add.begin (reminder, (obj, res) => { + HttpResponse response = Services.Todoist.get_default ().add.end (res); + item.loading = false; + + if (response.status) { + reminder.id = response.data; + } else { + reminder.id = Util.get_default ().generate_id (reminder); + } + + item.add_reminder_if_not_exists (reminder); + }); + } else { + reminder.id = Util.get_default ().generate_id (reminder); + item.add_reminder_if_not_exists (reminder); + } + }); + + status_button.changed.connect ((active) => { + checked_toggled (active); + }); + + parent_back_button.clicked.connect (() => { + if (item.has_parent) { + Services.EventBus.get_default ().open_item (item.parent); + } else { + Services.EventBus.get_default ().close_item (); + } + }); + } + + private void update_content_description () { + if (item.content != content_textview.buffer.text || + item.description != current_buffer.get_all_text ().chomp ()) { + item.content = content_textview.buffer.text; + item.description = current_buffer.get_all_text ().chomp (); + item.update_async_timeout (update_id); + } } - private async void _complete_item (bool old_checked, string old_completed_at) { - HttpResponse response = yield item.complete_item (old_checked); + public void present_item (Objects.Item _item) { + disconnect_all (); + + item = _item; + update_id = Util.get_default ().generate_id (); + + build_markdown_edit_view (); - if (!response.status) { - _complete_item_error (response, old_checked, old_completed_at); - } - } + label_button.source = item.project.source; + update_request (); - private void _complete_item_error (HttpResponse response, bool old_checked, string old_completed_at) { - item.checked = old_checked; - item.completed_at = old_completed_at; - - Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); - } + subitems.present_item (item); + subitems.reveal_child = true; - private void update_next_recurrency () { - var promise = new Services.Promise (); + attachments.present_item (item); - promise.resolved.connect ((result) => { - recurrency_update_complete (result); - }); + if (item.has_parent) { + parent_label.label = item.parent.content; + parent_label.tooltip_text = item.parent.content; + } else { + if (item.section_id != "") { + parent_label.label = item.section.name; + parent_label.tooltip_text = item.section.name; + } else { + parent_label.label = item.project.name; + parent_label.tooltip_text = item.project.name; + } + } - item.update_next_recurrency (promise); - } + content_textview.grab_focus (); + + signals_map[Services.EventBus.get_default ().checked_toggled.connect ((_item) => { + if (item.id == _item.id) { + update_request (); + } + })] = Services.EventBus.get_default (); + + signals_map[item.updated.connect ((_update_id) => { + if (update_id != _update_id) { + update_request (); + } + })] = item; + + signals_map[item.pin_updated.connect (() => { + pin_button.update_from_item (item); + })] = item; + + signals_map[item.reminder_added.connect ((reminder) => { + reminder_button.add_reminder (reminder, item.reminders); + })] = item; + + signals_map[item.reminder_deleted.connect ((reminder) => { + reminder_button.delete_reminder (reminder, item.reminders); + })] = item; + + signals_map[item.loading_change.connect (() => { + spinner_revealer.reveal_child = item.loading; + })] = item; + } + + public void disconnect_all () { + foreach (var entry in signals_map.entries) { + entry.value.disconnect (entry.key); + } + + if (description_handler_change_id != 0) { + current_buffer.disconnect (description_handler_change_id); + description_handler_change_id = 0; + } + + signals_map.clear (); + subitems.disconnect_all (); + attachments.disconnect_all (); + + if (!Services.Settings.get_default ().settings.get_boolean ("always-show-details-sidebar")) { + destroy_markdown_edit_view (); + } + } - private void recurrency_update_complete (GLib.DateTime next_recurrency) { + public void update_request () { + content_textview.buffer.text = item.content; + + if (description_handler_change_id != 0) { + current_buffer.disconnect (description_handler_change_id); + description_handler_change_id = 0; + } + + current_buffer.text = item.description; + + if (description_handler_change_id == 0) { + description_handler_change_id = current_buffer.changed.connect (() => { + update_content_description (); + }); + } + + schedule_button.update_from_item (item); + priority_button.update_from_item (item); + status_button.update_from_item (item); + + label_button.labels = item._get_labels (); + label_button.update_from_item (item); + + pin_button.update_from_item (item); + + section_button.set_sections (item.project.sections); + section_button.update_from_item (item); + + reminder_button.set_reminders (item.reminders); + + content_textview.editable = !item.completed; + markdown_edit_view.is_editable = !item.completed; + schedule_button.sensitive = !item.completed; + priority_button.sensitive = !item.completed; + label_button.sensitive = !item.completed; + pin_button.sensitive = !item.completed; + section_button.sensitive = !item.completed; + reminder_button.sensitive = !item.completed; + copy_clipboard_item.sensitive = !item.completed; + duplicate_item.sensitive = !item.completed; + move_item.sensitive = !item.completed; + repeat_item.sensitive = !item.completed; + subitems.add_button.sensitive = !item.completed; + } + + public void update_due (Objects.DueDate duedate) { + if (item == null) { + return; + } + + item.update_due (duedate); + } + + public void update_labels (Gee.HashMap new_labels) { + bool update = false; + + foreach (var entry in new_labels.entries) { + if (item.get_label (entry.key) == null) { + item.add_label_if_not_exists (entry.value); + update = true; + } + } + + foreach (var label in item._get_labels ()) { + if (!new_labels.has_key (label.id)) { + item.delete_item_label (label.id); + update = true; + } + } + + if (!update) { + return; + } + + item.update_async (""); + } + + private Gtk.Popover build_context_menu () { + var use_note_item = new Widgets.ContextMenu.MenuSwitch (_("Use as a Note"), "paper-symbolic"); + use_note_item.active = item.item_type == ItemType.NOTE; + + copy_clipboard_item = new Widgets.ContextMenu.MenuItem (_("Copy to Clipboard"), "clipboard-symbolic"); + duplicate_item = new Widgets.ContextMenu.MenuItem (_("Duplicate"), "tabs-stack-symbolic"); + move_item = new Widgets.ContextMenu.MenuItem (_("Move"), "arrow3-right-symbolic"); + repeat_item = new Widgets.ContextMenu.MenuItem (_("Repeat"), "playlist-repeat-symbolic"); + repeat_item.arrow = true; + + var delete_item = new Widgets.ContextMenu.MenuItem (_("Delete Task"), "user-trash-symbolic"); + delete_item.add_css_class ("menu-item-danger"); + + var more_information_item = new Widgets.ContextMenu.MenuItem (_("Change History"), "rotation-edit-symbolic"); + + var popover = new Gtk.Popover () { + has_arrow = false, + position = Gtk.PositionType.BOTTOM, + width_request = 250 + }; + + var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + menu_box.margin_top = menu_box.margin_bottom = 3; + + if (!item.completed) { + menu_box.append (use_note_item); + menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); + menu_box.append (copy_clipboard_item); + menu_box.append (duplicate_item); + menu_box.append (move_item); + } + + + menu_box.append (delete_item); + menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); + menu_box.append (more_information_item); + + popover.child = menu_box; + + use_note_item.activate_item.connect (() => { + item.item_type = use_note_item.active ? ItemType.NOTE : ItemType.TASK; + item.update_local (); + }); + + copy_clipboard_item.clicked.connect (() => { + popover.popdown (); + item.copy_clipboard (); + }); + + duplicate_item.clicked.connect (() => { + popover.popdown (); + Util.get_default ().duplicate_item.begin (item, item.project_id, item.section_id, item.parent_id); + }); + + move_item.clicked.connect (() => { + popover.popdown (); + + Dialogs.ProjectPicker.ProjectPicker dialog; + if (item.project.is_inbox_project) { + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_projects (); + } else { + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_project (item.source); + } + + dialog.add_sections (item.project.sections); + dialog.project = item.project; + dialog.section = item.section; + dialog.present (Planify._instance.main_window); + + dialog.changed.connect ((type, id) => { + if (type == "project") { + move (Services.Store.instance ().get_project (id), ""); + } else { + move (item.project, id); + } + }); + }); + + delete_item.activate_item.connect (() => { + popover.popdown (); + delete_request (); + }); + + more_information_item.activate_item.connect (() => { + popover.popdown (); + var dialog = new Dialogs.ItemChangeHistory (item); + dialog.present (Planify._instance.main_window); + }); + + return popover; + } + + public void move (Objects.Project project, string section_id, string parent_id = "") { + string project_id = project.id; + + if (item.project.source_id != project.source_id) { + Util.get_default ().move_backend_type_item.begin (item, project); + } else { + if (item.project_id != project_id || item.section_id != section_id || item.parent_id != parent_id) { + item.move (project, section_id); + } + } + } + + public void delete_request (bool undo = true) { + var dialog = new Adw.AlertDialog ( + _("Are you sure you want to delete?"), + _("This can not be undone") + ); + + dialog.add_response ("cancel", _("Cancel")); + dialog.add_response ("delete", _("Delete")); + dialog.set_response_appearance ("delete", Adw.ResponseAppearance.DESTRUCTIVE); + dialog.present (Planify._instance.main_window); + + dialog.response.connect ((response) => { + if (response == "delete") { + item.delete_item (); + Services.EventBus.get_default ().close_item (); + } + }); + } + + public void prepare_new_item (string content = "") { + var dialog = new Dialogs.QuickAdd (); + dialog.for_base_object (item); + dialog.update_content (content); + dialog.present (Planify._instance.main_window); + } + + public void checked_toggled (bool active) { + bool old_checked = item.checked; + + if (active) { + complete_item (old_checked); + } else { + var old_completed_at = item.completed_at; + + item.checked = false; + item.completed_at = ""; + _complete_item.begin (old_checked, old_completed_at); + } + } + + private void complete_item (bool old_checked) { + if (Services.Settings.get_default ().settings.get_boolean ("task-complete-tone")) { + Util.get_default ().play_audio (); + } + + if (item.due.is_recurring && !item.due.is_recurrency_end) { + update_next_recurrency (); + } else { + var old_completed_at = item.completed_at; + + item.checked = true; + item.completed_at = new GLib.DateTime.now_local ().to_string (); + _complete_item (old_checked, old_completed_at); + } + } + + private async void _complete_item (bool old_checked, string old_completed_at) { + HttpResponse response = yield item.complete_item (old_checked); + + if (!response.status) { + _complete_item_error (response, old_checked, old_completed_at); + } + } + + private void _complete_item_error (HttpResponse response, bool old_checked, string old_completed_at) { + item.checked = old_checked; + item.completed_at = old_completed_at; + + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); + } + + private void update_next_recurrency () { + var promise = new Services.Promise (); + + promise.resolved.connect ((result) => { + recurrency_update_complete (result); + }); + + item.update_next_recurrency (promise); + } + + private void recurrency_update_complete (GLib.DateTime next_recurrency) { var title = _("Completed. Next occurrence: %s".printf (Utils.Datetime.get_default_date_format_from_date (next_recurrency))); var toast = Util.get_default ().create_toast (title, 3); Services.EventBus.get_default ().send_toast (toast); } - private void build_markdown_edit_view () { - if (markdown_edit_view != null) { - return; - } - - markdown_edit_view = new Widgets.Markdown.EditView () { - card = true, - left_margin = 12, - right_margin = 12, - top_margin = 12, - bottom_margin = 12, - margin_top = 3, - margin_bottom = 3, - margin_start = 3, - margin_end = 3 - }; - markdown_edit_view.buffer = current_buffer; - - markdown_revealer.child = markdown_edit_view; - markdown_revealer.reveal_child = true; - } - - private void destroy_markdown_edit_view () { - markdown_revealer.reveal_child = false; - Timeout.add (markdown_revealer.transition_duration, () => { - markdown_revealer.child = null; - markdown_edit_view = null; - return GLib.Source.REMOVE; - }); - } + private void build_markdown_edit_view () { + if (markdown_edit_view != null) { + return; + } + + markdown_edit_view = new Widgets.Markdown.EditView () { + card = true, + left_margin = 12, + right_margin = 12, + top_margin = 12, + bottom_margin = 12, + margin_top = 3, + margin_bottom = 3, + margin_start = 3, + margin_end = 3 + }; + markdown_edit_view.buffer = current_buffer; + + markdown_revealer.child = markdown_edit_view; + markdown_revealer.reveal_child = true; + } + + private void destroy_markdown_edit_view () { + markdown_revealer.reveal_child = false; + Timeout.add (markdown_revealer.transition_duration, () => { + markdown_revealer.child = null; + markdown_edit_view = null; + return GLib.Source.REMOVE; + }); + } } diff --git a/src/Layouts/LabelRow.vala b/src/Layouts/LabelRow.vala index 0b7252741..f34b02a3f 100644 --- a/src/Layouts/LabelRow.vala +++ b/src/Layouts/LabelRow.vala @@ -1,66 +1,65 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public class Layouts.LabelRow : Gtk.ListBoxRow { - public Objects.Label label { get; construct; } - - private Gtk.Label name_label; - private Gtk.Label count_label; - private Gtk.Revealer count_revealer; - private Gtk.Revealer main_revealer; - private Gtk.Image widget_color; - private Gtk.Box handle_grid; - - public LabelRow (Objects.Label label) { - Object ( - label: label - ); - } - - construct { - css_classes = { "row", "transition", "no-padding" }; - - widget_color = new Gtk.Image.from_icon_name ("tag-outline-symbolic") { - css_classes = { "icon-color" }, - valign = Gtk.Align.CENTER, - }; - - name_label = new Gtk.Label (label.name) { - valign = Gtk.Align.CENTER, - ellipsize = Pango.EllipsizeMode.END - }; - - count_label = new Gtk.Label (label.label_count.to_string ()) { - hexpand = true, - halign = Gtk.Align.END - }; - - count_revealer = new Gtk.Revealer () { - reveal_child = int.parse (count_label.label) > 0, - transition_type = Gtk.RevealerTransitionType.CROSSFADE, - child = count_label - - }; - - var menu_button = new Gtk.MenuButton () { + public Objects.Label label { get; construct; } + + private Gtk.Label name_label; + private Gtk.Label count_label; + private Gtk.Revealer count_revealer; + private Gtk.Revealer main_revealer; + private Gtk.Image widget_color; + private Gtk.Box handle_grid; + + public LabelRow (Objects.Label label) { + Object ( + label: label + ); + } + + construct { + css_classes = { "row", "transition", "no-padding" }; + + widget_color = new Gtk.Image.from_icon_name ("tag-outline-symbolic") { + css_classes = { "icon-color" }, + valign = Gtk.Align.CENTER, + }; + + name_label = new Gtk.Label (label.name) { + valign = Gtk.Align.CENTER, + ellipsize = Pango.EllipsizeMode.END + }; + + count_label = new Gtk.Label (label.label_count.to_string ()) { + hexpand = true, + halign = Gtk.Align.END + }; + + count_revealer = new Gtk.Revealer () { + reveal_child = int.parse (count_label.label) > 0, + transition_type = Gtk.RevealerTransitionType.CROSSFADE, + child = count_label + }; + + var menu_button = new Gtk.MenuButton () { valign = Gtk.Align.CENTER, halign = Gtk.Align.CENTER, popover = build_context_menu (), @@ -68,95 +67,95 @@ public class Layouts.LabelRow : Gtk.ListBoxRow { css_classes = { "flat", "header-item-button", "dim-label" } }; - var loading_button = new Widgets.LoadingButton.with_icon ("go-next-symbolic", 16) { - valign = Gtk.Align.CENTER, - css_classes = { "flat", "dim-label", "no-padding" } - }; - - var buttons_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); - buttons_box.append (menu_button); - buttons_box.append (loading_button); - - handle_grid = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { - margin_start = 6, - margin_end = 6, - margin_top = 3, - margin_bottom = 3 - }; - handle_grid.append (widget_color); - handle_grid.append (name_label); - handle_grid.append (count_revealer); - handle_grid.append (buttons_box); - - var reorder_child = new Widgets.ReorderChild (handle_grid, this); - - main_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, - child = reorder_child - }; - - child = main_revealer; - update_request (); - reorder_child.build_drag_and_drop (); - - Timeout.add (main_revealer.transition_duration, () => { - main_revealer.reveal_child = true; - return GLib.Source.REMOVE; - }); - - label.updated.connect (() => { - update_request (); - }); - - label.label_count_updated.connect (() => { - count_label.label = label.label_count.to_string (); - count_revealer.reveal_child = int.parse (count_label.label) > 0; - }); - - reorder_child.on_drop_end.connect ((listbox) => { - update_labels_item_order (listbox); - }); - - label.loading_change.connect (() => { + var loading_button = new Widgets.LoadingButton.with_icon ("go-next-symbolic", 16) { + valign = Gtk.Align.CENTER, + css_classes = { "flat", "dim-label", "no-padding" } + }; + + var buttons_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); + buttons_box.append (menu_button); + buttons_box.append (loading_button); + + handle_grid = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { + margin_start = 6, + margin_end = 6, + margin_top = 3, + margin_bottom = 3 + }; + handle_grid.append (widget_color); + handle_grid.append (name_label); + handle_grid.append (count_revealer); + handle_grid.append (buttons_box); + + var reorder_child = new Widgets.ReorderChild (handle_grid, this); + + main_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, + child = reorder_child + }; + + child = main_revealer; + update_request (); + reorder_child.build_drag_and_drop (); + + Timeout.add (main_revealer.transition_duration, () => { + main_revealer.reveal_child = true; + return GLib.Source.REMOVE; + }); + + label.updated.connect (() => { + update_request (); + }); + + label.label_count_updated.connect (() => { + count_label.label = label.label_count.to_string (); + count_revealer.reveal_child = int.parse (count_label.label) > 0; + }); + + reorder_child.on_drop_end.connect ((listbox) => { + update_labels_item_order (listbox); + }); + + label.loading_change.connect (() => { loading_button.is_loading = label.loading; }); - loading_button.clicked.connect (() => { - Services.EventBus.get_default ().pane_selected (PaneType.LABEL, label.id); - }); - } + loading_button.clicked.connect (() => { + Services.EventBus.get_default ().pane_selected (PaneType.LABEL, label.id); + }); + } - public void update_request () { - name_label.label = label.name; - Util.get_default ().set_widget_color (Util.get_default ().get_color (label.color), widget_color); - } + public void update_request () { + name_label.label = label.name; + Util.get_default ().set_widget_color (Util.get_default ().get_color (label.color), widget_color); + } - private void update_labels_item_order (Gtk.ListBox listbox) { - unowned Layouts.LabelRow? label_row = null; - var row_index = 0; + private void update_labels_item_order (Gtk.ListBox listbox) { + unowned Layouts.LabelRow? label_row = null; + var row_index = 0; - do { - label_row = (Layouts.LabelRow) listbox.get_row_at_index (row_index); + do { + label_row = (Layouts.LabelRow) listbox.get_row_at_index (row_index); - if (label_row != null) { - label_row.label.item_order = row_index; - Services.Store.instance ().update_label (label_row.label); - } + if (label_row != null) { + label_row.label.item_order = row_index; + Services.Store.instance ().update_label (label_row.label); + } - row_index++; - } while (label_row != null); - } + row_index++; + } while (label_row != null); + } - private Gtk.Popover build_context_menu () { + private Gtk.Popover build_context_menu () { var edit_item = new Widgets.ContextMenu.MenuItem (_("Edit Label"), "edit-symbolic"); var delete_item = new Widgets.ContextMenu.MenuItem (_("Delete Label"), "user-trash-symbolic"); delete_item.add_css_class ("menu-item-danger"); var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); menu_box.margin_top = menu_box.margin_bottom = 3; - menu_box.append (edit_item); - menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); - menu_box.append (delete_item); + menu_box.append (edit_item); + menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); + menu_box.append (delete_item); var menu_popover = new Gtk.Popover () { has_arrow = false, @@ -167,23 +166,23 @@ public class Layouts.LabelRow : Gtk.ListBoxRow { edit_item.clicked.connect (() => { menu_popover.popdown (); - var dialog = new Dialogs.Label (label); - dialog.present (Planify._instance.main_window); + var dialog = new Dialogs.Label (label); + dialog.present (Planify._instance.main_window); }); delete_item.clicked.connect (() => { menu_popover.popdown (); - label.delete_label (Planify._instance.main_window); + label.delete_label (Planify._instance.main_window); }); return menu_popover; } - public void hide_destroy () { - main_revealer.reveal_child = false; - Timeout.add (main_revealer.transition_duration, () => { - ((Gtk.ListBox) parent).remove (this); - return GLib.Source.REMOVE; - }); - } + public void hide_destroy () { + main_revealer.reveal_child = false; + Timeout.add (main_revealer.transition_duration, () => { + ((Gtk.ListBox) parent).remove (this); + return GLib.Source.REMOVE; + }); + } } diff --git a/src/Layouts/ProjectContainerRow.vala b/src/Layouts/ProjectContainerRow.vala index feb9eb614..cb24fff15 100644 --- a/src/Layouts/ProjectContainerRow.vala +++ b/src/Layouts/ProjectContainerRow.vala @@ -1,70 +1,70 @@ /* -* Copyright © 2023 Alain M. (https://github.com/alainm23/planify) -* -* 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, write to the -* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -* Boston, MA 02110-1301 USA -* -* Authored by: Alain M. -*/ + * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) + * + * 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, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * Authored by: Alain M. + */ public class Layouts.ProjectContainerRow : Gtk.ListBoxRow { - public Objects.Project project { get; construct; } - public bool show_subprojects { get; construct; } - public bool drag_n_drop { get; construct; } + public Objects.Project project { get; construct; } + public bool show_subprojects { get; construct; } + public bool drag_n_drop { get; construct; } - private Gtk.Revealer main_revealer; + private Gtk.Revealer main_revealer; - public ProjectContainerRow (Objects.Project project, bool show_subprojects = true, bool drag_n_drop = true) { - Object ( - project: project, - show_subprojects: show_subprojects, - drag_n_drop: drag_n_drop - ); - } + public ProjectContainerRow (Objects.Project project, bool show_subprojects = true, bool drag_n_drop = true) { + Object ( + project: project, + show_subprojects: show_subprojects, + drag_n_drop: drag_n_drop + ); + } - ~ProjectContainerRow () { - print ("Destroying Layouts.ProjectContainerRow\n"); - } + ~ProjectContainerRow () { + print ("Destroying Layouts.ProjectContainerRow\n"); + } - construct { - css_classes = { "no-selectable", "no-padding" }; + construct { + css_classes = { "no-selectable", "no-padding" }; - var listbox = new Gtk.ListBox () { - css_classes = { "listbox-background" } - }; + var listbox = new Gtk.ListBox () { + css_classes = { "listbox-background" } + }; - listbox.append (new Layouts.ProjectRow (project, drag_n_drop)); - - main_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, - child = listbox - }; + listbox.append (new Layouts.ProjectRow (project, drag_n_drop)); - child = main_revealer; + main_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, + child = listbox + }; - Timeout.add (main_revealer.transition_duration, () => { - main_revealer.reveal_child = true; - return GLib.Source.REMOVE; - }); - } + child = main_revealer; - public void hide_destroy () { - main_revealer.reveal_child = false; - Timeout.add (main_revealer.transition_duration, () => { - ((Gtk.ListBox) parent).remove (this); - return GLib.Source.REMOVE; - }); - } -} \ No newline at end of file + Timeout.add (main_revealer.transition_duration, () => { + main_revealer.reveal_child = true; + return GLib.Source.REMOVE; + }); + } + + public void hide_destroy () { + main_revealer.reveal_child = false; + Timeout.add (main_revealer.transition_duration, () => { + ((Gtk.ListBox) parent).remove (this); + return GLib.Source.REMOVE; + }); + } +}