From edfd9b78f7e3097f7fd9a05a0e2c4950d695d70f Mon Sep 17 00:00:00 2001 From: Alain Date: Fri, 12 Jul 2024 04:08:33 -0500 Subject: [PATCH 01/14] feat: add source object --- core/Objects/Source.vala | 24 ++++++++++++++++++++++++ core/meson.build | 1 + 2 files changed, 25 insertions(+) create mode 100644 core/Objects/Source.vala diff --git a/core/Objects/Source.vala b/core/Objects/Source.vala new file mode 100644 index 000000000..e03e5a5a0 --- /dev/null +++ b/core/Objects/Source.vala @@ -0,0 +1,24 @@ +/* +* 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.Section : Objects.BaseObject { + +} \ No newline at end of file diff --git a/core/meson.build b/core/meson.build index 9fb667bb7..ed5c67ef0 100644 --- a/core/meson.build +++ b/core/meson.build @@ -63,6 +63,7 @@ core_files = files( 'Objects/Reminder.vala', 'Objects/Section.vala', 'Objects/Promise.vala', + 'Objects/Source.vala', 'Objects/Filters/Pinboard.vala', 'Objects/Filters/Scheduled.vala', From 5135e2e97c3aaa6da15bb5e174796e8f6d777b0f Mon Sep 17 00:00:00 2001 From: Alain Date: Tue, 16 Jul 2024 05:57:56 -0500 Subject: [PATCH 02/14] feat: multiple account --- core/Enum.vala | 19 + core/Layouts/HeaderItem.vala | 45 ++- core/Objects/BaseObject.vala | 35 +- core/Objects/Item.vala | 4 +- core/Objects/Project.vala | 29 +- core/Objects/Section.vala | 2 +- core/Objects/Source.vala | 251 ++++++++++++- core/Services/CalDAV/Core.vala | 2 +- core/Services/CalDAV/_Core.vala | 2 +- core/Services/Database.vala | 230 +++++++++++- core/Services/Todoist.vala | 235 ++++++------- core/Util/Migrate.vala | 36 ++ core/Util/Util.vala | 12 +- core/Widgets/Entries.vala | 2 +- core/meson.build | 5 +- .../Preferences/PreferencesWindow.vala | 265 +++++--------- src/Dialogs/Project.vala | 29 +- src/Layouts/ProjectRow.vala | 2 +- src/Layouts/Sidebar.vala | 331 ++---------------- src/Layouts/SidebarSourceRow.vala | 189 ++++++++++ src/MainWindow.vala | 26 +- src/Services/ActionManager.vala | 15 +- src/Views/Label/Labels.vala | 12 +- src/Widgets/SourceRow.vala | 145 ++++++++ src/meson.build | 2 + 25 files changed, 1219 insertions(+), 706 deletions(-) create mode 100644 core/Util/Migrate.vala create mode 100644 src/Layouts/SidebarSourceRow.vala create mode 100644 src/Widgets/SourceRow.vala diff --git a/core/Enum.vala b/core/Enum.vala index 7ab10c95d..5e1b5a522 100644 --- a/core/Enum.vala +++ b/core/Enum.vala @@ -177,6 +177,25 @@ public enum BackendType { assert_not_reached (); } } + + public static BackendType parse (string value) { + switch (value) { + case "local": + return BackendType.LOCAL; + + case "todoist": + return BackendType.TODOIST; + + case "google-tasks": + return BackendType.GOOGLE_TASKS; + + case "caldav": + return BackendType.CALDAV; + + default: + return BackendType.NONE; + } + } } public enum PaneType { diff --git a/core/Layouts/HeaderItem.vala b/core/Layouts/HeaderItem.vala index c2ed51e26..728c42089 100644 --- a/core/Layouts/HeaderItem.vala +++ b/core/Layouts/HeaderItem.vala @@ -30,8 +30,21 @@ public class Layouts.HeaderItem : Adw.Bin { set { _header_title = value; - name_label.label = _header_title; - name_label.visible = value != null; + header_label.label = _header_title; + header_label.visible = value != null; + } + } + + public string _subheader_title; + public string subheader_title { + get { + return _subheader_title; + } + + set { + _subheader_title = value; + subheader_label.label = _subheader_title; + subheader_revealer.reveal_child = value != null; } } @@ -63,7 +76,9 @@ public class Layouts.HeaderItem : Adw.Bin { } } - private Gtk.Label name_label; + private Gtk.Label header_label; + private Gtk.Label subheader_label; + private Gtk.Revealer subheader_revealer; private Gtk.Label placeholder_label; private Gtk.ListBox listbox; private Adw.Bin content_grid; @@ -143,12 +158,26 @@ public class Layouts.HeaderItem : Adw.Bin { } construct { - name_label = new Gtk.Label (null) { + header_label = new Gtk.Label (null) { halign = Gtk.Align.START }; - name_label.add_css_class ("h4"); - name_label.add_css_class ("heading"); + header_label.add_css_class ("h4"); + header_label.add_css_class ("heading"); + + subheader_label = new Gtk.Label (null) { + halign = Gtk.Align.START, + css_classes = { "caption" } + }; + + subheader_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, + child = subheader_label + }; + + var header_label_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + header_label_box.append (header_label); + header_label_box.append (subheader_revealer); listbox = new Gtk.ListBox () { hexpand = true, @@ -173,11 +202,11 @@ public class Layouts.HeaderItem : Adw.Bin { margin_end = 6 }; - header_box.append (name_label); + header_box.append (header_label_box); header_box.append (action_box); var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL) { - margin_top = 3, + margin_top = 6, margin_start = 3, margin_bottom = 3 }; diff --git a/core/Objects/BaseObject.vala b/core/Objects/BaseObject.vala index 530dae443..1a3b1ba3f 100644 --- a/core/Objects/BaseObject.vala +++ b/core/Objects/BaseObject.vala @@ -175,15 +175,40 @@ public class Objects.BaseObject : GLib.Object { get { if (this is Objects.Item) { return "child_order"; - } else if (this is Objects.Section) { + } + + if (this is Objects.Section) { return "section_order"; - } else if (this is Objects.Project) { + } + + if (this is Objects.Project) { return "child_order"; - } else if (this is Objects.Label) { + } + + if (this is Objects.Label) { return "item_order"; - } else { - return ""; + } + + return ""; + } + } + + Objects.Source? _source; + public Objects.Source source { + get { + if (this is Objects.Project) { + return ((Objects.Project) this).source; + } + + if (this is Objects.Section) { + return ((Objects.Section) this).project.source; } + + if (this is Objects.Item) { + return ((Objects.Item) this).project.source; + } + + return _source; } } diff --git a/core/Objects/Item.vala b/core/Objects/Item.vala index 25fcc8406..9254ff2c0 100644 --- a/core/Objects/Item.vala +++ b/core/Objects/Item.vala @@ -711,7 +711,7 @@ public class Objects.Item : Objects.BaseObject { public void update (string update_id = "") { if (update_timeout_id != 0) { - Source.remove (update_timeout_id); + GLib.Source.remove (update_timeout_id); } update_timeout_id = Timeout.add (Constants.UPDATE_TIMEOUT, () => { @@ -740,7 +740,7 @@ public class Objects.Item : Objects.BaseObject { public void update_async_timeout (string update_id = "") { if (update_timeout_id != 0) { - Source.remove (update_timeout_id); + GLib.Source.remove (update_timeout_id); } update_timeout_id = Timeout.add (Constants.UPDATE_TIMEOUT, () => { diff --git a/core/Objects/Project.vala b/core/Objects/Project.vala index 7e4f73d38..5c5a53092 100644 --- a/core/Objects/Project.vala +++ b/core/Objects/Project.vala @@ -36,6 +36,7 @@ public class Objects.Project : Objects.BaseObject { public bool collapsed { get; set; default = false; } public bool inbox_section_hidded { get; set; default = false; } public string sync_id { get; set; default = ""; } + public string source_id { get; set; default = BackendType.LOCAL.to_string (); } ProjectViewStyle _view_style = ProjectViewStyle.LIST; public ProjectViewStyle view_style { @@ -49,6 +50,20 @@ public class Objects.Project : Objects.BaseObject { } } + public BackendType source_type { + get { + return source.source_type; + } + } + + Objects.Source? _source; + public Objects.Source source { + get { + _source = Services.Database.get_default ().get_source (source_id); + return _source; + } + } + string _color_hex; public string color_hex { get { @@ -420,7 +435,7 @@ public class Objects.Project : Objects.BaseObject { public void update (bool use_timeout = true, bool show_loading = true) { if (update_timeout_id != 0) { - Source.remove (update_timeout_id); + GLib.Source.remove (update_timeout_id); } uint timeout = Constants.UPDATE_TIMEOUT; @@ -801,27 +816,29 @@ public class Objects.Project : Objects.BaseObject { dialog.response.connect ((response) => { if (response == "delete") { loading = true; - if (backend_type == BackendType.LOCAL) { + if (source_type == BackendType.LOCAL) { Services.Database.get_default ().delete_project (this); - } else if (backend_type == BackendType.TODOIST) { + } else if (source_type == BackendType.TODOIST) { dialog.set_response_enabled ("cancel", false); dialog.set_response_enabled ("delete", false); Services.Todoist.get_default ().delete.begin (this, (obj, res) => { if (Services.Todoist.get_default ().delete.end (res).status) { Services.Database.get_default ().delete_project (this); - loading = false; } + + loading = false; }); - } else if (backend_type == BackendType.CALDAV) { + } else if (source_type == BackendType.CALDAV) { dialog.set_response_enabled ("cancel", false); dialog.set_response_enabled ("delete", false); Services.CalDAV.Core.get_default ().delete_tasklist.begin (this, (obj, res) => { if (Services.CalDAV.Core.get_default ().delete_tasklist.end (res)) { Services.Database.get_default ().delete_project (this); - loading = false; } + + loading = false; }); } } diff --git a/core/Objects/Section.vala b/core/Objects/Section.vala index 6ffafad3a..d5739ab9e 100644 --- a/core/Objects/Section.vala +++ b/core/Objects/Section.vala @@ -185,7 +185,7 @@ public class Objects.Section : Objects.BaseObject { public void update (bool cloud=true) { if (update_timeout_id != 0) { - Source.remove (update_timeout_id); + GLib.Source.remove (update_timeout_id); } update_timeout_id = Timeout.add (Constants.UPDATE_TIMEOUT, () => { diff --git a/core/Objects/Source.vala b/core/Objects/Source.vala index e03e5a5a0..717c8b661 100644 --- a/core/Objects/Source.vala +++ b/core/Objects/Source.vala @@ -19,6 +19,255 @@ * Authored by: Alain M. */ -public class Objects.Section : Objects.BaseObject { +public class Objects.Source : Objects.BaseObject { + public BackendType source_type { get; set; default = BackendType.NONE; } + public string added_at { get; set; default = new GLib.DateTime.now_local ().to_string (); } + public string updated_at { get; set; default = ""; } + public bool is_visible { get; set; default = true; } + public int child_order { get; set; default = 0; } + public bool sync_server { get; set; default = false; } + public string last_sync { get; set; default = ""; } + public Objects.SourceData data { get; set; } + public bool legacy { get; set; default = false; } + + Objects.SourceTodoistData _todoist_data; + public Objects.SourceTodoistData todoist_data { + get { + _todoist_data = data as Objects.SourceTodoistData ; + return _todoist_data; + } + } + + public string header_text { + get { + if (source_type == BackendType.TODOIST) { + return todoist_data.user_email; + } + + if (source_type == BackendType.LOCAL) { + return _("On This Computer"); + } + + return ""; + } + } + + public string? subheader_text { + get { + if (source_type == BackendType.TODOIST) { + return _("Todoist"); + } + + return null; + } + } + + public string avatar_path { + get { + if (legacy) { + return "todoist-user"; + } + + return todoist_data.user_image_id; + } + } + + private uint server_timeout = 0; + + public signal void sync_started (); + public signal void sync_finished (); + + construct { + deleted.connect (() => { + Idle.add (() => { + Services.Database.get_default ().source_deleted (this); + return false; + }); + }); + } + + public void run_server () { + Services.Todoist.get_default ().sync.begin (this); + + server_timeout = Timeout.add_seconds (15 * 60, () => { + if (sync_server) { + Services.Todoist.get_default ().sync.begin (this); + } + + return true; + }); + } + + public void save () { + if (source_type == BackendType.TODOIST && legacy) { + Services.Settings.get_default ().settings.set_string ("todoist-sync-token", todoist_data.sync_token); + Services.Settings.get_default ().settings.set_string ("todoist-last-sync", last_sync); + Services.Settings.get_default ().settings.set_string ("todoist-user-email", todoist_data.user_email); + Services.Settings.get_default ().settings.set_string ("todoist-user-name", todoist_data.user_name); + Services.Settings.get_default ().settings.set_string ("todoist-user-avatar", todoist_data.user_avatar); + Services.Settings.get_default ().settings.set_string ("todoist-user-image-id", todoist_data.user_image_id); + Services.Settings.get_default ().settings.set_boolean ("todoist-sync-server", sync_server); + Services.Settings.get_default ().settings.set_boolean ("todoist-user-is-premium", todoist_data.user_is_premium); + return; + } + + if (source_type == BackendType.TODOIST && !legacy) { + + } + } + + public void delete_source (Gtk.Window window) { + var dialog = new Adw.AlertDialog ( + _("Delete Source?"), + _("This can not be undone") + ); + + dialog.add_response ("cancel", _("Cancel")); + dialog.add_response ("delete", _("Delete")); + dialog.close_response = "cancel"; + dialog.set_response_appearance ("delete", Adw.ResponseAppearance.DESTRUCTIVE); + dialog.present (window); + + dialog.response.connect ((response) => { + if (response == "delete") { + if (legacy) { + _delete_source (); + return; + } + + Services.Database.get_default ().delete_source (this); + } + }); + } + + private void _delete_source () { + Services.Settings.get_default ().settings.set_string ("todoist-sync-token", ""); + Services.Settings.get_default ().settings.set_string ("todoist-access-token", ""); + Services.Settings.get_default ().settings.set_string ("todoist-last-sync", ""); + Services.Settings.get_default ().settings.set_string ("todoist-user-email", ""); + Services.Settings.get_default ().settings.set_string ("todoist-user-name", ""); + Services.Settings.get_default ().settings.set_string ("todoist-user-avatar", ""); + Services.Settings.get_default ().settings.set_string ("todoist-user-image-id", ""); + Services.Settings.get_default ().settings.set_boolean ("todoist-sync-server", false); + Services.Settings.get_default ().settings.set_boolean ("todoist-user-is-premium", false); + + // Delete all projects, sections and items + foreach (var project in Services.Database.get_default ().get_projects_by_source (id)) { + Services.Database.get_default ().delete_project (project); + } + + // Delete all labels; + // foreach (var label in Services.Database.get_default ().get_all_labels_by_todoist ()) { + // Services.Database.get_default ().delete_label (label); + // } + + // Clear Queue + Services.Database.get_default ().clear_queue (); + + // Clear CurTempIds + Services.Database.get_default ().clear_cur_temp_ids (); + + deleted (); + } +} + +public class Objects.SourceData : GLib.Object { + Json.Builder _builder; + public Json.Builder builder { + get { + if (_builder == null) { + _builder = new Json.Builder (); + } + + return _builder; + } + } + public virtual string to_json () { + return ""; + } +} + +public class Objects.SourceTodoistData : Objects.SourceData { + public string access_token { get; set; default = ""; } + public string sync_token { get; set; default = ""; } + public string user_image_id { get; set; default = ""; } + public string user_email { get; set; default = ""; } + public string user_name { get; set; default = ""; } + public string user_avatar { get; set; default = ""; } + public bool user_is_premium { get; set; default = false; } + + public SourceTodoistData.from_json (string json) { + Json.Parser parser = new Json.Parser (); + + try { + parser.load_from_data (json, -1); + var object = parser.get_root ().get_object (); + + if (object.has_member ("access_token")) { + access_token = object.get_string_member ("access_token"); + } + + if (object.has_member ("sync_token")) { + sync_token = object.get_string_member ("sync_token"); + } + + if (object.has_member ("user_image_id")) { + user_image_id = object.get_string_member ("user_image_id"); + } + + if (object.has_member ("user_email")) { + user_email = object.get_string_member ("user_email"); + } + + if (object.has_member ("user_name")) { + user_name = object.get_string_member ("user_name"); + } + + if (object.has_member ("user_avatar")) { + user_avatar = object.get_string_member ("user_avatar"); + } + + if (object.has_member ("user_is_premium")) { + user_is_premium = object.get_boolean_member ("user_is_premium"); + } + } catch (Error e) { + debug (e.message); + } + } + + public override string to_json () { + builder.reset (); + + builder.begin_object (); + + builder.set_member_name ("access_token"); + builder.add_string_value (access_token); + + builder.set_member_name ("sync_token"); + builder.add_string_value (sync_token); + + builder.set_member_name ("user_image_id"); + builder.add_string_value (user_image_id); + + builder.set_member_name ("user_email"); + builder.add_string_value (user_email); + + builder.set_member_name ("user_name"); + builder.add_string_value (user_name); + + builder.set_member_name ("user_avatar"); + builder.add_string_value (user_avatar); + + builder.set_member_name ("user_is_premium"); + builder.add_boolean_value (user_is_premium); + + builder.end_object (); + + Json.Generator generator = new Json.Generator (); + Json.Node root = builder.get_root (); + generator.set_root (root); + + return generator.to_data (null); + } } \ No newline at end of file diff --git a/core/Services/CalDAV/Core.vala b/core/Services/CalDAV/Core.vala index b4b11024e..7ebf108d2 100644 --- a/core/Services/CalDAV/Core.vala +++ b/core/Services/CalDAV/Core.vala @@ -1065,7 +1065,7 @@ public class Services.CalDAV.Core : GLib.Object { } // Remove server_timeout - Source.remove (server_timeout); + GLib.Source.remove (server_timeout); server_timeout = 0; log_out (); diff --git a/core/Services/CalDAV/_Core.vala b/core/Services/CalDAV/_Core.vala index 9ad423171..031cbbfde 100644 --- a/core/Services/CalDAV/_Core.vala +++ b/core/Services/CalDAV/_Core.vala @@ -1084,7 +1084,7 @@ public class Services.CalDAV.Core : GLib.Object { } // Remove server_timeout - Source.remove (server_timeout); + GLib.Source.remove (server_timeout); server_timeout = 0; log_out (); diff --git a/core/Services/Database.vala b/core/Services/Database.vala index ff37564a1..5da7387ff 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -28,6 +28,9 @@ public class Services.Database : GLib.Object { public signal void opened (); public signal void reset (); + public signal void source_added (Objects.Source source); + public signal void source_deleted (Objects.Source source); + public signal void project_added (Objects.Project project); public signal void project_updated (Objects.Project project); public signal void project_deleted (Objects.Project project); @@ -66,6 +69,17 @@ public class Services.Database : GLib.Object { return _instance; } + Gee.ArrayList _sources = null; + public Gee.ArrayList sources { + get { + if (_sources == null) { + _sources = get_sources_collection (); + } + + return _sources; + } + } + Gee.ArrayList _projects = null; public Gee.ArrayList projects { get { @@ -135,9 +149,15 @@ public class Services.Database : GLib.Object { } }); + source_deleted.connect ((source) => { + if (_sources.remove (source)) { + debug ("Source Removed: %s", source.header_text); + } + }); + project_deleted.connect ((project) => { if (_projects.remove (project)) { - debug ("Project Removed: %s", project.name); + debug ("Prodeleteject Removed: %s", project.name); } }); @@ -232,6 +252,13 @@ public class Services.Database : GLib.Object { */ add_text_column ("Items", "item_type", ItemType.TASK.to_string ()); + + /* + * Planify 4.10 + * - Add source_id column to Projects + */ + + add_project_source_id (); } private void create_tables () { @@ -275,7 +302,8 @@ public class Services.Database : GLib.Object { description TEXT, due_date TEXT, inbox_section_hidded INTEGER, - sync_id TEXT + sync_id TEXT, + source_id TEXT ); """; @@ -415,17 +443,16 @@ public class Services.Database : GLib.Object { } sql = """ - CREATE TABLE IF NOT EXISTS OEvents ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - event_type TEXT, - event_date DATETIME DEFAULT (datetime('now','localtime')), - object_id TEXT, - object_type TEXT, - object_key TEXT, - object_old_value TEXT, - object_new_value TEXT, - parent_item_id TEXT, - parent_project_id TEXT + CREATE TABLE IF NOT EXISTS Sources ( + id TEXT PRIMARY KEY, + source_type TEXT NOT NULL, + added_at TEXT, + updated_at TEXT, + is_visible INTEGER, + child_order INTEGER, + sync_server INTEGER, + last_sync TEXT, + data TEXT ); """; @@ -576,6 +603,10 @@ public class Services.Database : GLib.Object { return projects.size <= 0; } + public bool is_sources_empty () { + return get_sources_collection ().size <= 0; + } + public Gee.ArrayList get_collection_by_type (Objects.BaseObject base_object) { if (base_object is Objects.Project) { return projects; @@ -590,6 +621,115 @@ public class Services.Database : GLib.Object { return new Gee.ArrayList (); } + /* + 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)); + } + stmt.reset (); + return return_value; + } + + public 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 = BackendType.parse (stmt.column_text (1)); + return_value.added_at = stmt.column_text (2); + return_value.updated_at = stmt.column_text (3); + return_value.is_visible = get_parameter_bool (stmt, 4); + return_value.child_order = stmt.column_int (5); + return_value.sync_server = get_parameter_bool (stmt, 6); + return_value.last_sync = stmt.column_text (7); + + if (return_value.source_type == BackendType.TODOIST) { + return_value.data = new Objects.SourceTodoistData.from_json (stmt.column_text (8)); + } + + return return_value; + } + + public bool insert_source (Objects.Source source) { + Sqlite.Statement stmt; + + sql = """ + INSERT OR IGNORE INTO Sources (id, source_type, added_at, + updated_at, is_visible, child_order, sync_server, last_sync, data) + VALUES ($id, $source_type, $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, "$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) { + sources.add (source); + source_added (source); + } else { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + stmt.reset (); + return stmt.step () == Sqlite.DONE; + } + + public Objects.Source get_source (string id) { + Objects.Source? return_value = null; + lock (_sources) { + foreach (var source in sources) { + if (source.id == id) { + return_value = source; + break; + } + } + + return return_value; + } + } + + public void delete_source (Objects.Source source) { + Sqlite.Statement stmt; + + sql = """ + DELETE FROM Sources WHERE id=$id; + """; + + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", source.id); + + if (stmt.step () == Sqlite.DONE) { + foreach (Objects.Project project in get_projects_by_source (source.id)) { + delete_project (project); + } + + source.deleted (); + } else { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + stmt.reset (); + } + /* Projects */ @@ -638,6 +778,19 @@ public class Services.Database : GLib.Object { } } + public Gee.ArrayList get_projects_by_source (string source_id) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (project.source_id == source_id) { + return_value.add (project); + } + } + + return return_value; + } + } + public Gee.ArrayList get_subitems (Objects.Item i) { Gee.ArrayList return_value = new Gee.ArrayList (); lock (_items) { @@ -675,6 +828,7 @@ public class Services.Database : GLib.Object { 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; } @@ -713,11 +867,11 @@ public class Services.Database : GLib.Object { 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, - inbox_section_hidded, sync_id) + inbox_section_hidded, sync_id, source_id) VALUES ($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, - $inbox_section_hidded, $sync_id); + $inbox_section_hidded, $sync_id, $source_id); """; db.prepare_v2 (sql, sql.length, out stmt); @@ -743,6 +897,7 @@ public class Services.Database : GLib.Object { 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) { projects.add (project); @@ -850,7 +1005,8 @@ public class Services.Database : GLib.Object { description=$description, due_date=$due_date, inbox_section_hidded=$inbox_section_hidded, - sync_id=$sync_id + sync_id=$sync_id, + source_id=$source_id WHERE id=$id; """; @@ -876,6 +1032,7 @@ public class Services.Database : GLib.Object { 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) { @@ -2709,7 +2866,7 @@ public class Services.Database : GLib.Object { bool returned = false; sql = """ - SELECT * FROM %s LIMIT 1; + PRAGMA table_info(%s); """.printf (table); db.prepare_v2 (sql, sql.length, out stmt); @@ -2717,11 +2874,12 @@ public class Services.Database : GLib.Object { stmt.step (); for (int i = 0; i < stmt.column_count (); i++) { - if (stmt.column_name (i) == column) { + if (stmt.column_text (1) == column) { returned = true; } } + stmt.reset (); return returned; } @@ -2791,4 +2949,40 @@ public class Services.Database : GLib.Object { stmt.reset (); } + + public void add_project_source_id () { + if (column_exists ("Projects", "source_id")) { + return; + } + + 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 (Services.Todoist.get_default ().is_logged_in ()) { + var todoist_source = new Objects.Source (); + todoist_source.id = BackendType.TODOIST.to_string (); + todoist_source.source_type = BackendType.TODOIST; + 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"); + + insert_source (todoist_source); + } + + if (Services.CalDAV.Core.get_default ().is_logged_in ()) { + var caldav_source = new Objects.Source (); + caldav_source.id = BackendType.CALDAV.to_string (); + caldav_source.source_type = BackendType.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"); + + insert_source (caldav_source); + } + } } diff --git a/core/Services/Todoist.vala b/core/Services/Todoist.vala index 73f3e52af..ab647b28c 100644 --- a/core/Services/Todoist.vala +++ b/core/Services/Todoist.vala @@ -43,71 +43,31 @@ public class Services.Todoist : GLib.Object { public signal void sync_finished (); public signal void first_sync_started (); - public signal void first_sync_finished (string inbox_project_id); - public signal void first_sync_progress (double value); - - public signal void log_out (); - public signal void log_in (); - - private uint server_timeout = 0; + public signal void first_sync_finished (); public Todoist () { session = new Soup.Session (); parser = new Json.Parser (); - var network_monitor = GLib.NetworkMonitor.get_default (); - network_monitor.network_changed.connect (() => { - if (GLib.NetworkMonitor.get_default ().network_available && is_logged_in () && - Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server")) { - sync_async (); - } - }); + // var network_monitor = GLib.NetworkMonitor.get_default (); + // network_monitor.network_changed.connect (() => { + // if (GLib.NetworkMonitor.get_default ().network_available && is_logged_in () && + // Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server")) { + // sync_async (); + // } + // }); } public void run_server () { - sync_async (); - - server_timeout = Timeout.add_seconds (15 * 60, () => { - if (Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server")) { - sync_async (); - } - - return true; - }); - } - - public void remove_items () { - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", ""); - Services.Settings.get_default ().settings.set_string ("todoist-access-token", ""); - Services.Settings.get_default ().settings.set_string ("todoist-last-sync", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-email", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-name", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-avatar", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-image-id", ""); - Services.Settings.get_default ().settings.set_boolean ("todoist-sync-server", false); - Services.Settings.get_default ().settings.set_boolean ("todoist-user-is-premium", false); - - // Delete all projects, sections and items - foreach (var project in Services.Database.get_default ().get_all_projects_by_todoist ()) { - Services.Database.get_default ().delete_project (project); - } - - // Delete all labels; - foreach (var label in Services.Database.get_default ().get_all_labels_by_todoist ()) { - Services.Database.get_default ().delete_label (label); - } - - // Clear Queue - Services.Database.get_default ().clear_queue (); - - // Clear CurTempIds - Services.Database.get_default ().clear_cur_temp_ids (); + // sync_async (); - // Remove server_timeout - Source.remove (server_timeout); - server_timeout = 0; + // server_timeout = Timeout.add_seconds (15 * 60, () => { + // if (Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server")) { + // sync_async (); + // } - log_out (); + // return true; + // }); } public bool invalid_token () { @@ -137,13 +97,13 @@ public class Services.Todoist : GLib.Object { var root = parser.get_root ().get_object (); var token = root.get_string_member ("access_token"); - yield first_sync (token); + yield add_todoist_account (token); } catch (Error e) { - + error (e.message); } } - public async void first_sync (string token) { + public async void add_todoist_account (string token) { first_sync_started (); string url = TODOIST_SYNC_URL; @@ -159,24 +119,31 @@ public class Services.Todoist : GLib.Object { // Debug print_root (parser.get_root ()); - first_sync_progress (0.15); - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", parser.get_root ().get_object ().get_string_member ("sync_token")); - Services.Settings.get_default ().settings.set_string ("todoist-access-token", token); - Services.Settings.get_default ().settings.set_boolean ("todoist-sync-server", true); + var source = new Objects.Source (); + source.id = Util.get_default ().generate_id (); + source.source_type = BackendType.TODOIST; + Objects.SourceTodoistData todoist_data = new Objects.SourceTodoistData (); + + todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); + todoist_data.access_token = token; + source.sync_server = true; // Create user var user_object = parser.get_root ().get_object ().get_object_member ("user"); if (user_object.get_null_member ("image_id") == false) { - Services.Settings.get_default ().settings.set_string ("todoist-user-image-id", user_object.get_string_member ("image_id")); - Services.Settings.get_default ().settings.set_string ("todoist-user-avatar", user_object.get_string_member ("avatar_s640")); + todoist_data.user_image_id = user_object.get_string_member ("image_id"); + todoist_data.user_avatar = user_object.get_string_member ("avatar_s640"); } // Set Inbox - string inbox_project_id = user_object.get_string_member ("inbox_project_id"); - Services.Settings.get_default ().settings.set_string ("todoist-user-name", user_object.get_string_member ("full_name")); - Services.Settings.get_default ().settings.set_string ("todoist-user-email", user_object.get_string_member ("email")); - Services.Settings.get_default ().settings.set_boolean ("todoist-user-is-premium", user_object.get_boolean_member ("is_premium")); + todoist_data.user_name = user_object.get_string_member ("full_name"); + todoist_data.user_email = user_object.get_string_member ("email"); + todoist_data.user_is_premium = user_object.get_boolean_member ("is_premium"); + + source.data = todoist_data; + + Services.Database.get_default ().insert_source (source); // Create Labels unowned Json.Array labels = parser.get_root ().get_object ().get_array_member (LABELS_COLLECTION); @@ -184,31 +151,28 @@ public class Services.Todoist : GLib.Object { Services.Database.get_default ().insert_label (new Objects.Label.from_json (_node)); } - first_sync_progress (0.35); - // Create Projects unowned Json.Array projects = parser.get_root ().get_object ().get_array_member (PROJECTS_COLLECTION); foreach (unowned Json.Node _node in projects.get_elements ()) { + var _project = new Objects.Project.from_json (_node); + _project.source_id = source.id; + if (!_node.get_object ().get_null_member ("parent_id")) { Objects.Project? project = Services.Database.get_default ().get_project (_node.get_object ().get_string_member ("parent_id")); if (project != null) { - project.add_subproject_if_not_exists (new Objects.Project.from_json (_node)); + project.add_subproject_if_not_exists (_project); } } else { - Services.Database.get_default ().insert_project (new Objects.Project.from_json (_node)); + Services.Database.get_default ().insert_project (_project); } } - first_sync_progress (0.50); - // Create Sections unowned Json.Array sections = parser.get_root ().get_object ().get_array_member (SECTIONS_COLLECTION); foreach (unowned Json.Node _node in sections.get_elements ()) { add_section_if_not_exists (_node); } - first_sync_progress (0.75); - // Create Items unowned Json.Array items = parser.get_root ().get_object ().get_array_member (ITEMS_COLLECTION); foreach (unowned Json.Node _node in items.get_elements ()) { @@ -225,19 +189,17 @@ public class Services.Todoist : GLib.Object { } } - first_sync_progress (0.85); - // Download Profile Image if (user_object.get_null_member ("image_id") == false) { Util.get_default ().download_profile_image ( - "todoist-user", user_object.get_string_member ("avatar_s640") + source.todoist_data.user_image_id, user_object.get_string_member ("avatar_s640") ); } - first_sync_progress (1); - first_sync_finished (inbox_project_id); - log_in (); - Services.Settings.get_default ().settings.set_string ("todoist-last-sync", new GLib.DateTime.now_local ().to_string ()); + source.last_sync = new GLib.DateTime.now_local ().to_string (); + source.save (); + + first_sync_finished (); } catch (Error e) { debug (e.message); } @@ -247,24 +209,23 @@ public class Services.Todoist : GLib.Object { * Sync */ - public void sync_async () { - sync_started (); - sync.begin ((obj, res) => { - sync.end (res); - queue.begin ((obj, res) => { - queue.end (res); - sync_finished (); - }); - }); - } + public async void sync (Objects.Source source) { + if (source.todoist_data.access_token == null) { + return; + } - public async void sync () { + source.sync_started (); + string url = TODOIST_SYNC_URL; - url = url + "?sync_token=" + Services.Settings.get_default ().settings.get_string ("todoist-sync-token"); + url = url + "?sync_token=" + source.todoist_data.sync_token; url = url + "&resource_types=" + "[\"all\"]"; + print ("URL: %s\n".printf (url)); + var message = new Soup.Message ("POST", url); - message.request_headers.append ("Authorization", "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token"))); + message.request_headers.append ("Authorization", "Bearer %s".printf (source.todoist_data.access_token)); + + print ("TOKEN: %s\n".printf (source.todoist_data.access_token)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.LOW, null); @@ -275,14 +236,14 @@ public class Services.Todoist : GLib.Object { if (!parser.get_root ().get_object ().has_member ("error")) { // Update sync token - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", parser.get_root ().get_object ().get_string_member ("sync_token")); + source.todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); // Update user if (parser.get_root ().get_object ().has_member ("user")) { var user_object = parser.get_root ().get_object ().get_object_member ("user"); - Services.Settings.get_default ().settings.set_boolean ("todoist-user-is-premium", user_object.get_boolean_member ("is_premium")); - Services.Settings.get_default ().settings.set_string ("todoist-user-name", user_object.get_string_member ("full_name")); - Services.Settings.get_default ().settings.set_string ("todoist-user-email", user_object.get_string_member ("email")); + source.todoist_data.user_is_premium = user_object.get_boolean_member ("is_premium"); + source.todoist_data.user_email = user_object.get_string_member ("email"); + source.todoist_data.user_name = user_object.get_string_member ("full_name"); } // Labels @@ -394,31 +355,29 @@ public class Services.Todoist : GLib.Object { } } - Services.Settings.get_default ().settings.set_string ("todoist-last-sync", new GLib.DateTime.now_local ().to_string ()); + yield queue (source); + + source.last_sync = new GLib.DateTime.now_local ().to_string (); } } catch (Error e) { debug (e.message); } + + source.sync_finished (); } /* * Queue */ - public void queue_async () { - queue.begin ((obj, res) => { - queue.end (res); - }); - } - - public async void queue () { + public async void queue (Objects.Source source) { Gee.ArrayList queue = Services.Database.get_default ().get_all_queue (); string json = get_queue_json (queue); var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); @@ -431,7 +390,7 @@ public class Services.Todoist : GLib.Object { var node = parser.get_root ().get_object (); string sync_token = node.get_string_member ("sync_token"); - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", sync_token); + source.todoist_data.sync_token = sync_token; foreach (var q in queue) { var uuid_member = node.get_object_member ("sync_status").get_member (q.uuid); @@ -808,7 +767,7 @@ public class Services.Todoist : GLib.Object { var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (object.source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); @@ -833,7 +792,10 @@ public class Services.Todoist : GLib.Object { var uuid_member = sync_status.get_member (uuid); if (uuid_member.get_node_type () == Json.NodeType.VALUE) { - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", parser.get_root ().get_object ().get_string_member ("sync_token")); + object.source.todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); + object.source.last_sync = new GLib.DateTime.now_local ().to_string (); + object.source.save (); + id = parser.get_root ().get_object ().get_object_member ("temp_id_mapping").get_string_member (temp_id); response.status = true; @@ -883,11 +845,12 @@ public class Services.Todoist : GLib.Object { public async HttpResponse update (Objects.BaseObject object) { string uuid = Util.get_default ().generate_string (); string json = object.get_update_json (uuid); + Objects.Source source = object.source; var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); @@ -912,8 +875,11 @@ public class Services.Todoist : GLib.Object { var uuid_member = sync_status.get_member (uuid); if (uuid_member.get_node_type () == Json.NodeType.VALUE) { - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", parser.get_root ().get_object ().get_string_member ("sync_token")); + source.todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); response.status = true; + + source.last_sync = new GLib.DateTime.now_local ().to_string (); + source.save (); } else { response.error = sync_status.get_object_member (uuid).get_string_member ("error"); @@ -975,7 +941,7 @@ public class Services.Todoist : GLib.Object { ); } } catch (Error e) { - + error (e.message); } } @@ -1052,7 +1018,7 @@ public class Services.Todoist : GLib.Object { var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (object.source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); @@ -1077,7 +1043,10 @@ public class Services.Todoist : GLib.Object { var uuid_member = sync_status.get_member (uuid); if (uuid_member.get_node_type () == Json.NodeType.VALUE) { - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", parser.get_root ().get_object ().get_string_member ("sync_token")); + object.source.todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); + object.source.last_sync = new GLib.DateTime.now_local ().to_string (); + object.source.save (); + response.status = true; } else { response.error = sync_status.get_object_member (uuid).get_string_member ("error"); @@ -1110,6 +1079,7 @@ public class Services.Todoist : GLib.Object { return response; } + /* Sections */ @@ -1129,11 +1099,12 @@ public class Services.Todoist : GLib.Object { public async HttpResponse complete_item (Objects.Item item) { string uuid = Util.get_default ().generate_string (); string json = item.get_check_json (uuid, item.checked ? "item_complete" : "item_uncomplete"); + Objects.Source source = item.source; var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); @@ -1158,8 +1129,11 @@ public class Services.Todoist : GLib.Object { var uuid_member = sync_status.get_member (uuid); if (uuid_member.get_node_type () == Json.NodeType.VALUE) { - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", parser.get_root ().get_object ().get_string_member ("sync_token")); + source.todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); response.status = true; + + source.last_sync = new GLib.DateTime.now_local ().to_string (); + source.save (); } else { response.error = sync_status.get_object_member (uuid).get_string_member ("error"); @@ -1234,11 +1208,12 @@ public class Services.Todoist : GLib.Object { public async HttpResponse move_item (Objects.Item item, string type, string id) { string uuid = Util.get_default ().generate_string (); string json = item.get_move_item (uuid, type, id); + Objects.Source source = item.source; var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); @@ -1262,11 +1237,11 @@ public class Services.Todoist : GLib.Object { var uuid_member = sync_status.get_member (uuid); if (uuid_member.get_node_type () == Json.NodeType.VALUE) { - Services.Settings.get_default ().settings.set_string ( - "todoist-sync-token", - parser.get_root ().get_object ().get_string_member ("sync_token") - ); + source.todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); response.status = true; + + source.last_sync = new GLib.DateTime.now_local ().to_string (); + source.save (); } else { response.error = sync_status.get_object_member (uuid).get_string_member ("error"); @@ -1306,7 +1281,7 @@ public class Services.Todoist : GLib.Object { var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (base_object.source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); @@ -1330,11 +1305,11 @@ public class Services.Todoist : GLib.Object { var uuid_member = sync_status.get_member (uuid); if (uuid_member.get_node_type () == Json.NodeType.VALUE) { - Services.Settings.get_default ().settings.set_string ( - "todoist-sync-token", - parser.get_root ().get_object ().get_string_member ("sync_token") - ); + base_object.source.todoist_data.access_token = parser.get_root ().get_object ().get_string_member ("sync_token"); response.status = true; + + base_object.source.last_sync = new GLib.DateTime.now_local ().to_string (); + base_object.source.save (); } else { response.error = sync_status.get_object_member (uuid).get_string_member ("error"); @@ -1378,7 +1353,7 @@ public class Services.Todoist : GLib.Object { var message = new Soup.Message ("POST", TODOIST_SYNC_URL); message.request_headers.append ( "Authorization", - "Bearer %s".printf (Services.Settings.get_default ().settings.get_string ("todoist-access-token")) + "Bearer %s".printf (project.source.todoist_data.access_token) ); message.set_request_body_from_bytes ("application/json", new Bytes (json.data)); diff --git a/core/Util/Migrate.vala b/core/Util/Migrate.vala new file mode 100644 index 000000000..14902181d --- /dev/null +++ b/core/Util/Migrate.vala @@ -0,0 +1,36 @@ +/* +* 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 Utils.AccountMigrate { + public static Objects.SourceTodoistData get_data_from_todoist () { + Objects.SourceTodoistData return_value = new Objects.SourceTodoistData (); + + return_value.sync_token = Services.Settings.get_default ().settings.get_string ("todoist-sync-token"); + return_value.access_token = Services.Settings.get_default ().settings.get_string ("todoist-access-token"); + return_value.user_email = Services.Settings.get_default ().settings.get_string ("todoist-user-email"); + return_value.user_name = Services.Settings.get_default ().settings.get_string ("todoist-user-name"); + return_value.user_avatar = Services.Settings.get_default ().settings.get_string ("todoist-user-avatar"); + return_value.user_image_id = Services.Settings.get_default ().settings.get_string ("todoist-user-image-id"); + return_value.user_is_premium = Services.Settings.get_default ().settings.get_boolean ("todoist-user-is-premium"); + + return return_value; + } +} \ No newline at end of file diff --git a/core/Util/Util.vala b/core/Util/Util.vala index 9b61d8705..a37c9fa09 100644 --- a/core/Util/Util.vala +++ b/core/Util/Util.vala @@ -567,8 +567,17 @@ public class Util : GLib.Object { } } + public Objects.Source create_local_source () { + Objects.Source local_source = new Objects.Source (); + local_source.id = BackendType.LOCAL.to_string (); + local_source.source_type = BackendType.LOCAL; + Services.Database.get_default ().insert_source (local_source); + return local_source; + } + public Objects.Project create_inbox_project () { Objects.Project inbox_project = new Objects.Project (); + inbox_project.source_id = BackendType.LOCAL.to_string (); inbox_project.id = Util.get_default ().generate_id (inbox_project); inbox_project.backend_type = BackendType.LOCAL; inbox_project.name = _("Inbox"); @@ -585,6 +594,7 @@ public class Util : GLib.Object { public void create_tutorial_project () { Objects.Project project = new Objects.Project (); project.id = Util.get_default ().generate_id (project); + project.source_id = BackendType.LOCAL.to_string (); project.backend_type = BackendType.LOCAL; project.icon_style = ProjectIconStyle.EMOJI; project.emoji = "🚀️"; @@ -1042,7 +1052,7 @@ We hope you’ll enjoy using Planify!"""); project.loading = false; if (Services.Todoist.get_default ().duplicate_project.end (res).status) { - Services.Todoist.get_default ().sync_async (); + Services.Todoist.get_default ().sync.begin (project.source); } }); } else if (project.backend_type == BackendType.CALDAV) { diff --git a/core/Widgets/Entries.vala b/core/Widgets/Entries.vala index 41fe220cd..659091b55 100644 --- a/core/Widgets/Entries.vala +++ b/core/Widgets/Entries.vala @@ -150,7 +150,7 @@ public class Widgets.HyperTextView : Granite.HyperTextView { private void changed_timeout () { if (changed_timeout_id != 0) { - Source.remove (changed_timeout_id); + GLib.Source.remove (changed_timeout_id); } changed_timeout_id = Timeout.add (Constants.UPDATE_TIMEOUT, () => { diff --git a/core/meson.build b/core/meson.build index 48a3b5b28..e29144715 100644 --- a/core/meson.build +++ b/core/meson.build @@ -5,6 +5,7 @@ core_files = files( 'Util/Util.vala', 'Util/Datetime.vala', + 'Util/Migrate.vala', 'Services/Settings.vala', 'Services/EventBus.vala', @@ -81,8 +82,10 @@ core_files = files( 'Objects/Reminder.vala', 'Objects/Section.vala', 'Objects/Promise.vala', + 'Objects/Attachment.vala', + 'Objects/ObjectEvent.vala', 'Objects/Source.vala', - 'Objects/Attachment.vala', + 'Objects/Filters/Pinboard.vala', 'Objects/Filters/Scheduled.vala', 'Objects/Filters/Today.vala', diff --git a/src/Dialogs/Preferences/PreferencesWindow.vala b/src/Dialogs/Preferences/PreferencesWindow.vala index 763885d27..6c409d4e6 100644 --- a/src/Dialogs/Preferences/PreferencesWindow.vala +++ b/src/Dialogs/Preferences/PreferencesWindow.vala @@ -824,71 +824,42 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { private Adw.NavigationPage get_accounts_page () { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Accounts")); - - // Todoist - var todoist_switch = new Gtk.Switch () { - valign = Gtk.Align.CENTER, - active = Services.Todoist.get_default ().is_logged_in () - }; - - var todoist_setting_button = new Gtk.Button.from_icon_name ("settings-symbolic") { - margin_end = 6, - valign = Gtk.Align.CENTER, - halign = Gtk.Align.CENTER, - css_classes = { "flat" } - }; - - var todoist_setting_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.CROSSFADE, - reveal_child = Services.Todoist.get_default ().is_logged_in () - }; - todoist_setting_revealer.child = todoist_setting_button; + // var local_item = new Widgets.ContextMenu.MenuItem (_("On This Computer")); + var todoist_item = new Widgets.ContextMenu.MenuItem (_("Todoist")); + var caldav_item = new Widgets.ContextMenu.MenuItem (_("CalDAV")); - var todoist_row = new Adw.ActionRow (); - todoist_row.title = _("Todoist"); - todoist_row.subtitle = _("Synchronize with your Todoist Account"); - todoist_row.add_suffix (todoist_setting_revealer); - todoist_row.add_suffix (todoist_switch); - todoist_row.add_prefix (new Gtk.Image.from_icon_name ("todoist") { - pixel_size = 32 - }); + var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + menu_box.margin_top = menu_box.margin_bottom = 3; + // menu_box.append (local_item); + menu_box.append (todoist_item); + menu_box.append (caldav_item); - // CalDAV - var caldav_switch = new Gtk.Switch () { - valign = Gtk.Align.CENTER, - active = Services.CalDAV.Core.get_default ().is_logged_in () + var popover = new Gtk.Popover () { + has_arrow = true, + child = menu_box, + width_request = 250, + position = Gtk.PositionType.BOTTOM }; - var caldav_setting_button = new Gtk.Button.from_icon_name ("settings-symbolic") { - margin_end = 6, - valign = Gtk.Align.CENTER, - halign = Gtk.Align.CENTER, - css_classes = { "flat" } - }; + var add_source_button = new Gtk.MenuButton () { + valign = Gtk.Align.CENTER, + icon_name = "plus-large-symbolic", + css_classes = { "flat", "dim-label" }, + tooltip_markup = _("Add Source"), + popover = popover + }; - var caldav_setting_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.CROSSFADE, - reveal_child = Services.CalDAV.Core.get_default ().is_logged_in (), - child = caldav_setting_button + var sources_group = new Layouts.HeaderItem (_("Sources")) { + card = true, + reveal = true, + margin_top = 12 }; - var caldav_row = new Adw.ActionRow (); - caldav_row.title = _("Nextcloud"); - caldav_row.subtitle = _("Synchronization based on open Internet standards"); - caldav_row.add_suffix (caldav_setting_revealer); - caldav_row.add_suffix (caldav_switch); - caldav_row.add_prefix (new Gtk.Image.from_icon_name ("cloud") { - pixel_size = 32 - }); - - var accounts_group = new Adw.PreferencesGroup (); - accounts_group.title = _("Accounts"); - accounts_group.add (todoist_row); - accounts_group.add (caldav_row); + sources_group.add_widget_end (add_source_button); var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12); - content_box.append (accounts_group); + content_box.append (sources_group); var content_clamp = new Adw.Clamp () { maximum_size = 600, @@ -903,111 +874,75 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { toolbar_view.add_top_bar (settings_header); toolbar_view.content = content_clamp; - var page = new Adw.NavigationPage (toolbar_view, "account"); - - var todoist_switch_gesture = new Gtk.GestureClick (); - todoist_switch_gesture.set_button (1); - todoist_switch.add_controller (todoist_switch_gesture); - todoist_switch_gesture.pressed.connect (() => { - todoist_switch.active = !todoist_switch.active; - - if (todoist_switch.active) { - todoist_switch.active = false; - if (!Services.Todoist.get_default ().is_logged_in ()) { - push_subpage (get_oauth_todoist_page (todoist_switch)); - } - } else { - confirm_log_out (todoist_switch, BackendType.TODOIST); - } - }); - - var caldav_switch_gesture = new Gtk.GestureClick (); - caldav_switch.add_controller (caldav_switch_gesture); - caldav_switch_gesture.pressed.connect (() => { - caldav_switch.active = !caldav_switch.active; + Gee.HashMap sources_hashmap = new Gee.HashMap (); + foreach (Objects.Source source in Services.Database.get_default ().sources) { + sources_hashmap[source.id] = new Widgets.SourceRow (source); - if (caldav_switch.active) { - caldav_switch.active = false; - push_subpage (get_caldav_setup_page (caldav_switch)); - } else { - confirm_log_out (caldav_switch, BackendType.CALDAV); - } - }); - - Services.Todoist.get_default ().first_sync_finished.connect (() => { - todoist_setting_revealer.reveal_child = Services.Todoist.get_default ().is_logged_in (); - todoist_switch.active = Services.Todoist.get_default ().is_logged_in (); - - Timeout.add (250, () => { - close (); - return GLib.Source.REMOVE; + sources_hashmap[source.id].view_detail.connect (() => { + push_subpage (get_todoist_view (source)); }); - }); - Services.CalDAV.Core.get_default ().first_sync_finished.connect (() => { - caldav_setting_revealer.reveal_child = Services.CalDAV.Core.get_default ().is_logged_in (); - caldav_switch.active = Services.CalDAV.Core.get_default ().is_logged_in (); - - Timeout.add (250, () => { - close (); - return GLib.Source.REMOVE; - }); - }); + sources_group.add_child (sources_hashmap[source.id]); + } - Services.Todoist.get_default ().log_out.connect (() => { - todoist_setting_revealer.reveal_child = Services.Todoist.get_default ().is_logged_in (); - todoist_switch.active = Services.Todoist.get_default ().is_logged_in (); - }); + Services.Database.get_default ().source_added.connect ((source) => { + sources_hashmap[source.id] = new Widgets.SourceRow (source); - Services.CalDAV.Core.get_default ().log_out.connect (() => { - caldav_setting_revealer.reveal_child = Services.CalDAV.Core.get_default ().is_logged_in (); - caldav_switch.active = Services.CalDAV.Core.get_default ().is_logged_in (); - }); + sources_hashmap[source.id].view_detail.connect (() => { + push_subpage (get_todoist_view (source)); + }); - todoist_setting_button.clicked.connect (() => { - push_subpage (get_todoist_view ()); + sources_group.add_child (sources_hashmap[source.id]); }); - caldav_setting_button.clicked.connect (() => { - push_subpage (get_caldav_view ()); + Services.Database.get_default ().source_deleted.connect ((source) => { + if (sources_hashmap.has_key (source.id)) { + sources_hashmap[source.id].hide_destroy (); + sources_hashmap.unset (source.id); + } }); settings_header.back_activated.connect (() => { pop_subpage (); }); - return page; - } + todoist_item.clicked.connect (() => { + popover.popdown (); + push_subpage (get_oauth_todoist_page ()); + }); - private Adw.NavigationPage get_todoist_view () { + return new Adw.NavigationPage (toolbar_view, "account"); + } + + private Adw.NavigationPage get_todoist_view (Objects.Source source) { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Todoist")); - var todoist_avatar = new Adw.Avatar (84, Services.Settings.get_default ().settings.get_string ("todoist-user-name"), true); + var avatar = new Adw.Avatar (84, source.todoist_data.user_name, true); - var file = File.new_for_path (Util.get_default ().get_avatar_path ("todoist-user")); + var file = File.new_for_path (Util.get_default ().get_avatar_path (source.avatar_path)); if (file.query_exists ()) { var image = new Gtk.Image.from_file (file.get_path ()); - todoist_avatar.custom_image = image.get_paintable (); + avatar.custom_image = image.get_paintable (); } - var todoist_user = new Gtk.Label (Services.Settings.get_default ().settings.get_string ("todoist-user-name")) { + var user_label = new Gtk.Label (source.todoist_data.user_name) { margin_top = 12 }; - todoist_user.add_css_class ("title-1"); + user_label.add_css_class ("title-1"); - var todoist_email = new Gtk.Label (Services.Settings.get_default ().settings.get_string ("todoist-user-email")); - todoist_email.add_css_class ("dim-label"); + var email_label = new Gtk.Label (source.todoist_data.user_email); + email_label.add_css_class ("dim-label"); var user_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { margin_top = 24 }; - user_box.append (todoist_avatar); - user_box.append (todoist_user); - user_box.append (todoist_email); + user_box.append (avatar); + user_box.append (user_label); + user_box.append (email_label); var sync_server_switch = new Gtk.Switch () { valign = Gtk.Align.CENTER, - active = Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server") + active = source.sync_server }; var sync_server_row = new Adw.ActionRow (); @@ -1017,12 +952,12 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { sync_server_row.add_suffix (sync_server_switch); var last_sync_date = new GLib.DateTime.from_iso8601 ( - Services.Settings.get_default ().settings.get_string ("todoist-last-sync"), new GLib.TimeZone.local () - ); + source.last_sync, new GLib.TimeZone.local () + ); - var last_sync_label = new Gtk.Label (Utils.Datetime.get_relative_date_from_date ( - last_sync_date - )); + var last_sync_label = new Gtk.Label ( + Utils.Datetime.get_relative_date_from_date (last_sync_date) + ); var last_sync_row = new Adw.ActionRow (); last_sync_row.activatable = false; @@ -1062,7 +997,8 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { }); sync_server_row.notify["active"].connect (() => { - Services.Settings.get_default ().settings.set_boolean ("todoist-sync-server", sync_server_switch.active); + source.sync_server = sync_server_switch.active; + source.save (); }); return page; @@ -1259,7 +1195,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return page; } - private Adw.NavigationPage get_oauth_todoist_page (Gtk.Switch switch_widget) { + private Adw.NavigationPage get_oauth_todoist_page () { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Loading…")); string oauth_open_url = "https://todoist.com/oauth/authorize?client_id=%s&scope=%s&state=%s"; @@ -1276,18 +1212,19 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { webview.load_uri (oauth_open_url); - var sync_image = new Gtk.Image.from_icon_name ("cloud-outline-thick-symbolic") { + var sync_image = new Gtk.Spinner () { valign = Gtk.Align.CENTER, halign = Gtk.Align.CENTER, - pixel_size = 128 + height_request = 64, + width_request = 64, + spinning = true }; // Loading - var progress_bar = new Gtk.ProgressBar () { - margin_top = 6 - }; - var sync_label = new Gtk.Label (_("Planify is is syncing your tasks, this may take a few minutes")); + var sync_label = new Gtk.Label (_("Planify is is syncing your tasks, this may take a few minutes")) { + css_classes = { "dim-label" } + }; sync_label.wrap = true; sync_label.justify = Gtk.Justification.CENTER; sync_label.margin_top = 12; @@ -1295,12 +1232,11 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { sync_label.margin_end = 12; var sync_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - margin_top = 24, + margin_top = 128, margin_start = 64, margin_end = 64 }; sync_box.append (sync_image); - sync_box.append (progress_bar); sync_box.append (sync_label); var stack = new Gtk.Stack (); @@ -1309,7 +1245,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { stack.transition_type = Gtk.StackTransitionType.CROSSFADE; stack.add_named (webview, "web_view"); - stack.add_named (sync_box, "spinner-view"); + stack.add_named (sync_box, "loading"); var scrolled_window = new Gtk.ScrolledWindow () { hexpand = true, @@ -1326,7 +1262,6 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { var page = new Adw.NavigationPage (toolbar_view, "oauth-todoist"); settings_header.back_activated.connect (() => { - switch_widget.active = false; pop_subpage (); }); @@ -1341,7 +1276,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { if ("https://github.com/alainm23/planner?error=access_denied" in redirect_uri) { debug ("access_denied"); - switch_widget.active = false; + webview.get_network_session ().get_website_data_manager ().clear.begin (WebKit.WebsiteDataTypes.ALL, 0, null); pop_subpage (); } @@ -1370,7 +1305,6 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { toast.timeout = 0; toast.button_clicked.connect (() => { - switch_widget.active = false; pop_subpage (); }); @@ -1381,17 +1315,14 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { }); Services.Todoist.get_default ().first_sync_started.connect (() => { - stack.visible_child_name = "spinner-view"; + stack.visible_child_name = "loading"; }); Services.Todoist.get_default ().first_sync_finished.connect (() => { + webview.get_network_session ().get_website_data_manager ().clear.begin (WebKit.WebsiteDataTypes.ALL, 0, null); pop_subpage (); }); - Services.Todoist.get_default ().first_sync_progress.connect ((progress) => { - progress_bar.fraction = progress; - }); - return page; } @@ -1847,36 +1778,6 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return true; } - private void confirm_log_out (Gtk.Switch switch_widget, BackendType backend_type) { - string message = ""; - - if (backend_type == BackendType.TODOIST) { - message = _("Are you sure you want to remove the Todoist sync? This action will delete all your tasks and settings."); - } else if (backend_type == BackendType.CALDAV) { - message = _("Are you sure you want to remove the CalDAV sync? This action will delete all your tasks and settings."); - } - - var dialog = new Adw.AlertDialog (_("Sign Off"), message); - - dialog.body_use_markup = true; - 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") { - if (backend_type == BackendType.TODOIST) { - Services.Todoist.get_default ().remove_items (); - } else if (backend_type == BackendType.CALDAV) { - Services.CalDAV.Core.get_default ().remove_items (); - } - } else { - switch_widget.active = true; - } - }); - } - private Gtk.Widget generate_icon (string icon_name, int size = 16) { return new Gtk.Image.from_icon_name (icon_name) { pixel_size = size diff --git a/src/Dialogs/Project.vala b/src/Dialogs/Project.vala index 00126085f..b468a5649 100644 --- a/src/Dialogs/Project.vala +++ b/src/Dialogs/Project.vala @@ -35,13 +35,13 @@ public class Dialogs.Project : Adw.Dialog { } } - public Project.new (BackendType backend_type, bool backend_picker = false, string parent_id = "") { + public Project.new (string source_id, bool backend_picker = false, string parent_id = "") { var project = new Objects.Project (); project.color = "blue"; project.emoji = "🚀️"; project.id = ""; project.parent_id = parent_id; - project.backend_type = backend_type; + project.source_id = source_id; Object ( project: project, @@ -123,8 +123,9 @@ public class Dialogs.Project : Adw.Dialog { name_group.add (emoji_switch_row); var backend_model = new Gtk.StringList (null); - backend_model.append (_("On This Computer")); - backend_model.append (_("Todoist")); + foreach (Objects.Source source in Services.Database.get_default ().sources) { + backend_model.append (source.header_text); + } var backend_row = new Adw.ComboRow (); backend_row.title = _("Source"); @@ -141,7 +142,7 @@ public class Dialogs.Project : Adw.Dialog { var backend_revealer = new Gtk.Revealer () { transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, - reveal_child = backend_picker && Services.Todoist.get_default ().is_logged_in () + reveal_child = backend_picker }; backend_revealer.child = backend_group; @@ -292,16 +293,16 @@ public class Dialogs.Project : Adw.Dialog { private void update_project () { - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_project (project); hide_destroy (); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (project, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Database.get_default ().update_project (project); hide_destroy (); }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().update_tasklist.begin (project, (obj, res) => { if (Services.CalDAV.Core.get_default ().update_tasklist.end (res)) { Services.Database.get_default ().update_project (project); @@ -313,14 +314,12 @@ public class Dialogs.Project : Adw.Dialog { private void add_project () { project.child_order = Services.Database.get_default ().get_projects_by_backend_type (project.backend_type).size; - - if (project.backend_type == BackendType.LOCAL || project.backend_type == BackendType.NONE) { + + if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.NONE) { project.id = Util.get_default ().generate_id (project); - project.backend_type = BackendType.LOCAL; - Services.Database.get_default ().insert_project (project); go_project (project.id_string); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().add.begin (project, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -330,10 +329,8 @@ public class Dialogs.Project : Adw.Dialog { go_project (project.id_string); } }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == BackendType.CALDAV) { project.id = Util.get_default ().generate_id (project); - project.backend_type = BackendType.CALDAV; - Services.CalDAV.Core.get_default ().add_tasklist.begin (project, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_tasklist.end (res)) { Services.CalDAV.Core.get_default ().get_sync_token.begin (project, (obj, res) => { diff --git a/src/Layouts/ProjectRow.vala b/src/Layouts/ProjectRow.vala index c2d279fc8..b0df37957 100644 --- a/src/Layouts/ProjectRow.vala +++ b/src/Layouts/ProjectRow.vala @@ -349,7 +349,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { var drop_magic_button_target = new Gtk.DropTarget (typeof (Widgets.MagicButton), Gdk.DragAction.MOVE); handle_grid.add_controller (drop_magic_button_target); drop_magic_button_target.drop.connect ((value, x, y) => { - var dialog = new Dialogs.Project.new (project.backend_type, false, project.id); + var dialog = new Dialogs.Project.new (project.source_id, false, project.id); dialog.present (Planify._instance.main_window); return true; }); diff --git a/src/Layouts/Sidebar.vala b/src/Layouts/Sidebar.vala index f5450efc3..4b71bec19 100644 --- a/src/Layouts/Sidebar.vala +++ b/src/Layouts/Sidebar.vala @@ -28,17 +28,12 @@ public class Layouts.Sidebar : Adw.Bin { private Layouts.FilterPaneRow labels_filter; private Layouts.FilterPaneRow pinboard_filter; private Layouts.FilterPaneRow completed_filter; + + private Gtk.ListBox sources_listbox; private Layouts.HeaderItem favorites_header; - private Layouts.HeaderItem local_projects_header; - private Layouts.HeaderItem todoist_projects_header; - private Layouts.HeaderItem caldav_projects_header; - private Layouts.HeaderItem google_projects_header; - - public Gee.HashMap local_hashmap = new Gee.HashMap (); - public Gee.HashMap todoist_hashmap = new Gee.HashMap (); - public Gee.HashMap caldav_hashmap = new Gee.HashMap (); public Gee.HashMap favorites_hashmap = new Gee.HashMap (); + public Gee.HashMap sources_hashmap = new Gee.HashMap (); public Sidebar () { Object (); @@ -101,18 +96,11 @@ public class Layouts.Sidebar : Adw.Bin { favorites_header.placeholder_message = _("No favorites available. Create one by clicking on the '+' button"); favorites_header.margin_top = 6; - local_projects_header = new Layouts.HeaderItem (_("On This Computer")); - local_projects_header.placeholder_message = _("No project available. Create one by clicking on the '+' button"); - local_projects_header.margin_top = 6; - - todoist_projects_header = new Layouts.HeaderItem (_("Todoist")); - todoist_projects_header.margin_top = 6; - - caldav_projects_header = new Layouts.HeaderItem (_("Nextcloud")); - caldav_projects_header.margin_top = 6; - - google_projects_header = new Layouts.HeaderItem (); - google_projects_header.margin_top = 6; + sources_listbox = new Gtk.ListBox () { + hexpand = true, + valign = Gtk.Align.START, + css_classes = { "listbox-background" } + }; var whats_new_icon = new Gtk.Image.from_icon_name ("star-outline-thick-symbolic") { css_classes = { "gift-animation" } @@ -158,9 +146,7 @@ public class Layouts.Sidebar : Adw.Bin { content_box.append (filters_flow); content_box.append (favorites_header); - content_box.append (local_projects_header); - content_box.append (todoist_projects_header); - content_box.append (caldav_projects_header); + content_box.append (sources_listbox); if (Constants.SHOW_WHATSNEW) { content_box.append (whats_new_revealer); @@ -169,124 +155,14 @@ public class Layouts.Sidebar : Adw.Bin { var scrolled_window = new Widgets.ScrolledWindow (content_box); child = scrolled_window; - update_projects_sort (); - - var add_local_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { - valign = Gtk.Align.CENTER, - css_classes = { "flat", "header-item-button", "dim-label" }, - tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Add Project"), "P") - }; - - local_projects_header.add_widget_end (add_local_button); - add_local_button.clicked.connect (() => { - prepare_new_project (BackendType.LOCAL); - }); - - var todoist_sync_button = new Widgets.SyncButton () { - reveal_child = Services.Todoist.get_default ().is_logged_in () - }; - todoist_projects_header.add_widget_end (todoist_sync_button); - - var add_todoist_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { - valign = Gtk.Align.CENTER, - css_classes = { "flat", "header-item-button", "dim-label" }, - tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Add Project"), "P") - }; - - todoist_projects_header.add_widget_end (add_todoist_button); - add_todoist_button.clicked.connect (() => { - bool is_logged_in = Services.Todoist.get_default ().is_logged_in (); - - if (is_logged_in) { - prepare_new_project (BackendType.TODOIST); - } - }); - - var caldav_sync_button = new Widgets.SyncButton () { - reveal_child = Services.CalDAV.Core.get_default ().is_logged_in () - }; - caldav_projects_header.add_widget_end (caldav_sync_button); - - var add_caldav_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { - valign = Gtk.Align.CENTER, - css_classes = { "flat", "header-item-button", "dim-label" }, - tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Add Project"), "P") - }; - - caldav_projects_header.add_widget_end (add_caldav_button); - add_caldav_button.clicked.connect (() => { - bool is_logged_in = Services.CalDAV.Core.get_default ().is_logged_in (); - - if (is_logged_in) { - prepare_new_project (BackendType.CALDAV); - } - }); Services.Settings.get_default ().settings.changed.connect ((key) => { - if (key == "projects-sort-by" || key == "projects-ordered") { - update_projects_sort (); - } else if (key == "views-order-visible") { + if (key == "views-order-visible") { filters_flow.invalidate_sort (); filters_flow.invalidate_filter (); } }); - Services.Todoist.get_default ().log_in.connect (() => { - todoist_projects_header.reveal = true; - todoist_sync_button.reveal_child = true; - }); - - Services.Todoist.get_default ().log_out.connect (() => { - todoist_projects_header.reveal = false; - todoist_sync_button.reveal_child = false; - }); - - Services.CalDAV.Core.get_default ().log_in.connect (() => { - caldav_projects_header.reveal = true; - caldav_sync_button.reveal_child = true; - }); - - Services.CalDAV.Core.get_default ().log_out.connect (() => { - caldav_projects_header.reveal = false; - caldav_sync_button.reveal_child = false; - }); - - Services.Database.get_default ().project_deleted.connect ((project) => { - if (favorites_hashmap.has_key (project.id)) { - favorites_hashmap.unset (project.id); - } - - if (local_hashmap.has_key (project.id)) { - local_hashmap.unset (project.id); - } - - if (todoist_hashmap.has_key (project.id)) { - todoist_hashmap.unset (project.id); - } - - if (caldav_hashmap.has_key (project.id)) { - caldav_hashmap.unset (project.id); - } - }); - - Services.Database.get_default ().project_archived.connect ((project) => { - if (favorites_hashmap.has_key (project.id)) { - favorites_hashmap.unset (project.id); - } - - if (local_hashmap.has_key (project.id)) { - local_hashmap.unset (project.id); - } - - if (todoist_hashmap.has_key (project.id)) { - todoist_hashmap.unset (project.id); - } - - if (caldav_hashmap.has_key (project.id)) { - caldav_hashmap.unset (project.id); - } - }); - var whats_new_gesture = new Gtk.GestureClick (); whats_new_box.add_controller (whats_new_gesture); @@ -306,30 +182,6 @@ public class Layouts.Sidebar : Adw.Bin { update_version (); whats_new_revealer.reveal_child = verify_new_version (); }); - - todoist_sync_button.clicked.connect (() => { - Services.Todoist.get_default ().sync_async (); - }); - - Services.Todoist.get_default ().sync_started.connect (() => { - todoist_sync_button.sync_started (); - }); - - Services.Todoist.get_default ().sync_finished.connect (() => { - todoist_sync_button.sync_finished (); - }); - - caldav_sync_button.clicked.connect (() => { - Services.CalDAV.Core.get_default ().sync_async (); - }); - - Services.CalDAV.Core.get_default ().sync_started.connect (() => { - caldav_sync_button.sync_started (); - }); - - Services.CalDAV.Core.get_default ().sync_finished.connect (() => { - caldav_sync_button.sync_finished (); - }); } public void update_version () { @@ -340,39 +192,6 @@ public class Layouts.Sidebar : Adw.Bin { return Services.Settings.get_default ().settings.get_string ("version") != Build.VERSION; } - public void verify_todoist_account () { - bool is_logged_in = Services.Todoist.get_default ().is_logged_in (); - - if (is_logged_in) { - todoist_projects_header.reveal = true; - todoist_projects_header.placeholder_message = _("No project available. Create one by clicking on the '+' button"); - } else { - todoist_projects_header.placeholder_message = _("No account available, Sync one by clicking the '+' button"); - } - } - - public void verify_google_account () { - bool is_logged_in = Services.GoogleTasks.get_default ().is_logged_in (); - - if (is_logged_in) { - google_projects_header.reveal = true; - google_projects_header.placeholder_message = _("No project available. Create one by clicking on the '+' button"); - } else { - google_projects_header.placeholder_message = _("No account available, Sync one by clicking the '+' button"); - } - } - - public void verify_caldav_account () { - bool is_logged_in = Services.CalDAV.Core.get_default ().is_logged_in (); - - if (is_logged_in) { - caldav_projects_header.reveal = true; - caldav_projects_header.placeholder_message = _("No project available. Create one by clicking on the '+' button"); - } else { - caldav_projects_header.placeholder_message = _("No account available, Sync one by clicking the '+' button"); - } - } - public void select_project (Objects.Project project) { Services.EventBus.get_default ().pane_selected (PaneType.PROJECT, project.id); } @@ -382,64 +201,11 @@ public class Layouts.Sidebar : Adw.Bin { } public void init () { - Services.Database.get_default ().project_added.connect (add_row_project); - Services.Database.get_default ().project_updated.connect (update_projects_sort); - Services.Database.get_default ().project_unarchived.connect (add_row_project); - - Services.EventBus.get_default ().project_parent_changed.connect ((project, old_parent_id) => { - if (old_parent_id == "") { - if (local_hashmap.has_key (project.id)) { - local_hashmap [project.id].hide_destroy (); - local_hashmap.unset (project.id); - } - - if (todoist_hashmap.has_key (project.id)) { - todoist_hashmap [project.id].hide_destroy (); - todoist_hashmap.unset (project.id); - } - - if (caldav_hashmap.has_key (project.id)) { - caldav_hashmap [project.id].hide_destroy (); - caldav_hashmap.unset (project.id); - } - } + Services.Database.get_default ().source_added.connect (add_source_row); - if (project.parent_id == "") { - add_row_project (project); - } - }); - - Services.EventBus.get_default ().update_inserted_project_map.connect ((_row, old_parent_id) => { - var row = (Layouts.ProjectRow) _row; - - if (old_parent_id == "") { - if (local_hashmap.has_key (row.project.id)) { - local_hashmap.unset (row.project.id); - } - - if (todoist_hashmap.has_key (row.project.id)) { - todoist_hashmap.unset (row.project.id); - } - - if (caldav_hashmap.has_key (row.project.id)) { - caldav_hashmap.unset (row.project.id); - } - } - - if (!row.project.is_inbox_project && row.project.parent_id == "") { - if (row.project.backend_type == BackendType.TODOIST) { - if (!todoist_hashmap.has_key (row.project.id)) { - todoist_hashmap[row.project.id] = row; - } - } else if (row.project.backend_type == BackendType.LOCAL) { - if (!local_hashmap.has_key (row.project.id)) { - local_hashmap[row.project.id] = row; - } - } else if (row.project.backend_type == BackendType.CALDAV) { - if (!caldav_hashmap.has_key (row.project.id)) { - caldav_hashmap[row.project.id] = row; - } - } + Services.Database.get_default ().source_deleted.connect ((source) => { + if (sources_hashmap.has_key (source.id)) { + sources_hashmap.get (source.id).hide_destroy (); } }); @@ -453,27 +219,25 @@ public class Layouts.Sidebar : Adw.Bin { favorites_header.reveal = favorites_hashmap.size > 0; }); - + inbox_filter.init (); today_filter.init (); scheduled_filter.init (); labels_filter.init (); pinboard_filter.init (); completed_filter.init (); - - local_projects_header.reveal = true; - add_all_projects (); add_all_favorites (); - verify_todoist_account (); - verify_google_account (); - verify_caldav_account (); + foreach (Objects.Source source in Services.Database.get_default ().sources) { + add_source_row (source); + } } - private void add_all_projects () { - foreach (Objects.Project project in Services.Database.get_default ().projects) { - add_row_project (project); + private void add_source_row (Objects.Source source) { + if (!sources_hashmap.has_key (source.id)) { + sources_hashmap[source.id] = new Layouts.SidebarSourceRow (source); + sources_listbox.append (sources_hashmap[source.id]); } } @@ -486,54 +250,15 @@ public class Layouts.Sidebar : Adw.Bin { } private void add_row_favorite (Objects.Project project) { - if (project.is_favorite) { - if (!favorites_hashmap.has_key (project.id)) { - favorites_hashmap [project.id] = new Layouts.ProjectRow (project, false, false); - favorites_header.add_child (favorites_hashmap [project.id]); - } - } - } - - private void add_row_project (Objects.Project project) { - if (!project.is_inbox_project && project.parent_id == "" && !project.is_archived) { - if (project.backend_type == BackendType.TODOIST) { - if (!todoist_hashmap.has_key (project.id)) { - todoist_hashmap [project.id] = new Layouts.ProjectRow (project); - todoist_projects_header.add_child (todoist_hashmap [project.id]); - } - } else if (project.backend_type == BackendType.LOCAL) { - if (!local_hashmap.has_key (project.id)) { - local_hashmap [project.id] = new Layouts.ProjectRow (project); - local_projects_header.add_child (local_hashmap [project.id]); - } - } else if (project.backend_type == BackendType.CALDAV) { - if (!caldav_hashmap.has_key (project.id)) { - caldav_hashmap [project.id] = new Layouts.ProjectRow (project); - caldav_projects_header.add_child (caldav_hashmap [project.id]); - } - } + if (!project.is_favorite) { + return; } - } - private void prepare_new_project (BackendType backend_type) { - var dialog = new Dialogs.Project.new (backend_type); - dialog.present (Planify._instance.main_window); - } - - private void update_projects_sort () { - if (Services.Settings.get_default ().settings.get_enum ("projects-sort-by") == 1) { - local_projects_header.set_sort_func (projects_sort_func); - todoist_projects_header.set_sort_func (projects_sort_func); - } else { - local_projects_header.set_sort_func (null); - todoist_projects_header.set_sort_func (null); + if (favorites_hashmap.has_key (project.id)) { + return; } - } - private int projects_sort_func (Gtk.ListBoxRow lbrow, Gtk.ListBoxRow lbbefore) { - Objects.Project project1 = ((Layouts.ProjectRow) lbrow).project; - Objects.Project project2 = ((Layouts.ProjectRow) lbbefore).project; - int ordered = Services.Settings.get_default ().settings.get_enum ("projects-ordered"); - return ordered == 0 ? project2.name.collate (project1.name) : project1.name.collate (project2.name); + favorites_hashmap [project.id] = new Layouts.ProjectRow (project, false, false); + favorites_header.add_child (favorites_hashmap [project.id]); } } diff --git a/src/Layouts/SidebarSourceRow.vala b/src/Layouts/SidebarSourceRow.vala new file mode 100644 index 000000000..88789f138 --- /dev/null +++ b/src/Layouts/SidebarSourceRow.vala @@ -0,0 +1,189 @@ +/* +* 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.SidebarSourceRow : Gtk.ListBoxRow { + public Objects.Source source { get; construct; } + + private Layouts.HeaderItem group; + private Gtk.Revealer main_revealer; + public Gee.HashMap projects_hashmap = new Gee.HashMap (); + + public SidebarSourceRow (Objects.Source source) { + Object ( + source: source + ); + } + + construct { + css_classes = { "no-selectable", "no-padding" }; + + group = new Layouts.HeaderItem (source.header_text) { + reveal = true, + show_separator = true, + subheader_title = source.subheader_text + }; + group.placeholder_message = _("No project available. Create one by clicking on the '+' button"); + group.margin_top = 6; + + if (source.source_type == BackendType.TODOIST || source.source_type == BackendType.CALDAV) { + var sync_button = new Widgets.SyncButton () { + reveal_child = true + }; + group.add_widget_end (sync_button); + + sync_button.clicked.connect (() => { + Services.Todoist.get_default ().sync.begin (source); + }); + + source.sync_started.connect (() => { + sync_button.sync_started (); + }); + + source.sync_finished.connect (() => { + sync_button.sync_finished (); + }); + } + + var add_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { + valign = Gtk.Align.CENTER, + css_classes = { "flat", "header-item-button", "dim-label" }, + tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Add Project"), "P") + }; + + group.add_widget_end (add_button); + + main_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, + child = group + }; + + child = main_revealer; + + Timeout.add (main_revealer.transition_duration, () => { + main_revealer.reveal_child = true; + return GLib.Source.REMOVE; + }); + + add_all_projects (); + update_projects_sort (); + + add_button.clicked.connect (() => { + prepare_new_project (source.id); + }); + + Services.Database.get_default ().project_added.connect (add_row_project); + Services.Database.get_default ().project_updated.connect (update_projects_sort); + Services.Database.get_default ().project_unarchived.connect (add_row_project); + + Services.Database.get_default ().project_deleted.connect ((project) => { + if (projects_hashmap.has_key (project.id)) { + projects_hashmap.unset (project.id); + } + }); + + Services.Database.get_default ().project_archived.connect ((project) => { + if (projects_hashmap.has_key (project.id)) { + projects_hashmap.unset (project.id); + } + }); + + + Services.EventBus.get_default ().project_parent_changed.connect ((project, old_parent_id) => { + if (old_parent_id == "") { + if (projects_hashmap.has_key (project.id)) { + projects_hashmap [project.id].hide_destroy (); + projects_hashmap.unset (project.id); + } + } + + if (project.parent_id == "") { + add_row_project (project); + } + }); + + Services.EventBus.get_default ().update_inserted_project_map.connect ((_row, old_parent_id) => { + var row = (Layouts.ProjectRow) _row; + + if (old_parent_id == "") { + if (projects_hashmap.has_key (row.project.id)) { + projects_hashmap.unset (row.project.id); + } + } + + if (!row.project.is_inbox_project && row.project.parent_id == "") { + if (row.project.source_id == source.id) { + if (!projects_hashmap.has_key (row.project.id)) { + projects_hashmap[row.project.id] = row; + } + } + } + }); + + Services.Settings.get_default ().settings.changed.connect ((key) => { + if (key == "projects-sort-by" || key == "projects-ordered") { + update_projects_sort (); + } + }); + } + + public void hide_destroy () { + main_revealer.reveal_child = false; + Timeout.add (main_revealer.transition_duration, () => { + ((Gtk.ListBox) parent).remove (this); + return GLib.Source.REMOVE; + }); + } + + private void prepare_new_project (string id) { + var dialog = new Dialogs.Project.new (id); + dialog.present (Planify._instance.main_window); + } + + private void add_all_projects () { + foreach (Objects.Project project in Services.Database.get_default ().get_projects_by_source (source.id)) { + add_row_project (project); + } + } + + private void add_row_project (Objects.Project project) { + if (project.source_id == source.id && !project.is_inbox_project && project.parent_id == "" && !project.is_archived) { + if (!projects_hashmap.has_key (project.id)) { + projects_hashmap [project.id] = new Layouts.ProjectRow (project); + group.add_child (projects_hashmap [project.id]); + } + } + } + + private void update_projects_sort () { + if (Services.Settings.get_default ().settings.get_enum ("projects-sort-by") == 1) { + group.set_sort_func (projects_sort_func); + } else { + group.set_sort_func (null); + } + } + + private int projects_sort_func (Gtk.ListBoxRow lbrow, Gtk.ListBoxRow lbbefore) { + Objects.Project project1 = ((Layouts.ProjectRow) lbrow).project; + Objects.Project project2 = ((Layouts.ProjectRow) lbbefore).project; + int ordered = Services.Settings.get_default ().settings.get_enum ("projects-ordered"); + return ordered == 0 ? project2.name.collate (project1.name) : project1.name.collate (project2.name); + } +} \ No newline at end of file diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 085483c07..c29069385 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -294,6 +294,10 @@ public class MainWindow : Adw.ApplicationWindow { private void init_backend () { Services.Database.get_default ().init_database (); + if (Services.Database.get_default ().is_sources_empty ()) { + Util.get_default ().create_local_source (); + } + if (Services.Database.get_default ().is_database_empty ()) { Util.get_default ().create_inbox_project (); Util.get_default ().create_tutorial_project (); @@ -310,21 +314,15 @@ public class MainWindow : Adw.ApplicationWindow { Services.Database.get_default ().project_deleted.connect (valid_view_removed); Services.Database.get_default ().project_archived.connect (valid_view_removed); - if (Services.Todoist.get_default ().is_logged_in ()) { - Timeout.add (Constants.SYNC_TIMEOUT, () => { - Services.Todoist.get_default ().run_server (); - return GLib.Source.REMOVE; - }); - } - - if (Services.CalDAV.Core.get_default ().is_logged_in ()) { - Timeout.add (Constants.SYNC_TIMEOUT, () => { - Services.CalDAV.Core.get_default ().run_server (); - return GLib.Source.REMOVE; - }); - } - check_archived (); + + Timeout.add (Constants.SYNC_TIMEOUT, () => { + foreach (Objects.Source source in Services.Database.get_default ().sources) { + source.run_server (); + } + + return GLib.Source.REMOVE; + }); } private void check_archived () { diff --git a/src/Services/ActionManager.vala b/src/Services/ActionManager.vala index c061b9177..90a9e3f79 100644 --- a/src/Services/ActionManager.vala +++ b/src/Services/ActionManager.vala @@ -142,18 +142,17 @@ public class Services.ActionManager : Object { } private void action_sync_manually () { - if (Services.Todoist.get_default ().is_logged_in ()) { - Services.Todoist.get_default ().sync_async (); - } + // if (Services.Todoist.get_default ().is_logged_in ()) { + // Services.Todoist.get_default ().sync_async (); + // } - if (Services.CalDAV.Core.get_default ().is_logged_in ()) { - Services.CalDAV.Core.get_default ().sync_async (); - } + // if (Services.CalDAV.Core.get_default ().is_logged_in ()) { + // Services.CalDAV.Core.get_default ().sync_async (); + // } } private void action_new_project () { - // TODO: Update Backend Type instance default by user // vala-lint=note - var dialog = new Dialogs.Project.new (BackendType.LOCAL, true); + var dialog = new Dialogs.Project.new (BackendType.LOCAL.to_string (), true); dialog.present (Planify._instance.main_window); } diff --git a/src/Views/Label/Labels.vala b/src/Views/Label/Labels.vala index 0c0e081fa..0fce32cc8 100644 --- a/src/Views/Label/Labels.vala +++ b/src/Views/Label/Labels.vala @@ -158,13 +158,13 @@ public class Views.Labels : Adw.Bin { } }); - Services.Todoist.get_default ().log_in.connect (() => { - labels_todoist_header.reveal = Services.Todoist.get_default ().is_logged_in (); - }); + // Services.Todoist.get_default ().log_in.connect (() => { + // labels_todoist_header.reveal = Services.Todoist.get_default ().is_logged_in (); + // }); - Services.Todoist.get_default ().log_out.connect (() => { - labels_todoist_header.reveal = Services.Todoist.get_default ().is_logged_in (); - }); + // Services.Todoist.get_default ().log_out.connect (() => { + // labels_todoist_header.reveal = Services.Todoist.get_default ().is_logged_in (); + // }); Services.CalDAV.Core.get_default ().log_in.connect (() => { labels_caldav_header.reveal = Services.CalDAV.Core.get_default ().is_logged_in (); diff --git a/src/Widgets/SourceRow.vala b/src/Widgets/SourceRow.vala new file mode 100644 index 000000000..64fe2b46e --- /dev/null +++ b/src/Widgets/SourceRow.vala @@ -0,0 +1,145 @@ +/* +* 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 Widgets.SourceRow : Gtk.ListBoxRow { + public Objects.Source source { get; construct; } + + private Gtk.Revealer main_revealer; + + public signal void view_detail (); + + public SourceRow (Objects.Source source) { + Object ( + source: source + ); + } + + construct { + add_css_class ("no-selectable"); + + var visible_checkbutton = new Gtk.CheckButton () { + active = source.is_visible + }; + + var header_label = new Gtk.Label (source.header_text); + + var subheader_label = new Gtk.Label (source.subheader_text) { + halign = Gtk.Align.START, + css_classes = { "caption" }, + visible = source.subheader_text != null + }; + + var header_label_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { + valign = Gtk.Align.CENTER + }; + header_label_box.append (header_label); + header_label_box.append (subheader_label); + + var setting_button = new Gtk.Button.from_icon_name ("settings-symbolic") { + valign = Gtk.Align.CENTER, + halign = Gtk.Align.CENTER, + css_classes = { "flat" }, + visible = source.source_type != BackendType.LOCAL + }; + + var renove_item = new Widgets.ContextMenu.MenuItem (_("Remove"), "user-trash-symbolic"); + + var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + menu_box.margin_top = menu_box.margin_bottom = 3; + menu_box.append (renove_item); + + var popover = new Gtk.Popover () { + has_arrow = true, + child = menu_box, + width_request = 250, + position = Gtk.PositionType.BOTTOM + }; + + var menu_button = new Gtk.MenuButton () { + valign = Gtk.Align.CENTER, + icon_name = "view-more-symbolic", + css_classes = { "flat", "dim-label" }, + tooltip_markup = _("Add Source"), + popover = popover, + visible = source.source_type != BackendType.LOCAL + }; + + var end_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { + hexpand = true, + halign = END + }; + end_box.append (setting_button); + end_box.append (menu_button); + + var content_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { + margin_top = 6, + margin_bottom = 6, + margin_start = 6, + margin_end = 6 + }; + + content_box.append (visible_checkbutton); + content_box.append (header_label_box); + content_box.append (end_box); + + var card = new Adw.Bin () { + child = content_box, + margin_top = 3, + margin_bottom = 3, + margin_start = 3, + margin_end = 3 + }; + + main_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, + child = card + }; + + child = main_revealer; + + Timeout.add (main_revealer.transition_duration, () => { + main_revealer.reveal_child = true; + return GLib.Source.REMOVE; + }); + + visible_checkbutton.toggled.connect (() => { + source.is_visible = visible_checkbutton.active; + source.save (); + }); + + setting_button.clicked.connect (() => { + view_detail (); + }); + + renove_item.clicked.connect (() => { + popover.popdown (); + source.delete_source (Planify._instance.main_window); + }); + } + + 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 diff --git a/src/meson.build b/src/meson.build index 12d230a4d..1eaf8d5b1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -37,6 +37,7 @@ sources = files( 'Layouts/ItemSidebarView.vala', 'Layouts/SectionBoard.vala', 'Layouts/HeaderBar.vala', + 'Layouts/SidebarSourceRow.vala', 'Widgets/ColorPickerRow.vala', 'Widgets/MagicButton.vala', @@ -55,6 +56,7 @@ sources = files( 'Widgets/FilterFlowBox.vala', 'Widgets/Attachments.vala', 'Widgets/ItemChangeHistoryRow.vala', + 'Widgets/SourceRow.vala', 'Views/Project/Project.vala', 'Views/Project/List.vala', From 1fd449ba68d5206e8dcce2ac5518669fc597dfa4 Mon Sep 17 00:00:00 2001 From: Alain Date: Tue, 16 Jul 2024 06:16:03 -0500 Subject: [PATCH 03/14] feat: creare local source --- core/Services/Database.vala | 132 ++++++++++++++++++------------------ src/Layouts/Sidebar.vala | 25 +++---- 2 files changed, 80 insertions(+), 77 deletions(-) diff --git a/core/Services/Database.vala b/core/Services/Database.vala index 5da7387ff..ab77e9f37 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -196,71 +196,6 @@ public class Services.Database : GLib.Object { opened (); } - 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_source_id (); - } - private void create_tables () { sql = """ CREATE TABLE IF NOT EXISTS Labels ( @@ -586,6 +521,71 @@ public class Services.Database : GLib.Object { } } + 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_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); @@ -2964,6 +2964,8 @@ public class Services.Database : GLib.Object { 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 = BackendType.TODOIST.to_string (); diff --git a/src/Layouts/Sidebar.vala b/src/Layouts/Sidebar.vala index 4b71bec19..ddaa843a1 100644 --- a/src/Layouts/Sidebar.vala +++ b/src/Layouts/Sidebar.vala @@ -49,18 +49,6 @@ public class Layouts.Sidebar : Adw.Bin { min_children_per_line = 2 }; - filters_flow.set_sort_func ((child1, child2) => { - int item1 = ((Layouts.FilterPaneRow) child1).item_order (); - int item2 = ((Layouts.FilterPaneRow) child2).item_order (); - - return item1 - item2; - }); - - filters_flow.set_filter_func ((child) => { - var row = ((Layouts.FilterPaneRow) child); - return row.active (); - }); - inbox_filter = new Layouts.FilterPaneRow (FilterType.INBOX) { tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Go to Inbox"), "Ctrl+I") }; @@ -163,6 +151,19 @@ public class Layouts.Sidebar : Adw.Bin { } }); + + filters_flow.set_sort_func ((child1, child2) => { + int item1 = ((Layouts.FilterPaneRow) child1).item_order (); + int item2 = ((Layouts.FilterPaneRow) child2).item_order (); + + return item1 - item2; + }); + + filters_flow.set_filter_func ((child) => { + var row = ((Layouts.FilterPaneRow) child); + return row.active (); + }); + var whats_new_gesture = new Gtk.GestureClick (); whats_new_box.add_controller (whats_new_gesture); From 46cba7fe6fc0382906245e80270d309104b643f6 Mon Sep 17 00:00:00 2001 From: Alain Date: Thu, 18 Jul 2024 17:48:36 -0500 Subject: [PATCH 04/14] feat: add labels --- core/Objects/Item.vala | 9 +-- core/Objects/Label.vala | 1 + core/QuickAdd.vala | 18 +++--- core/Services/CalDAV/Core.vala | 3 +- core/Services/Database.vala | 43 ++++++++++--- core/Widgets/LabelPicker/LabelButton.vala | 10 ++-- core/Widgets/LabelPicker/LabelPicker.vala | 4 +- core/Widgets/LabelsPickerCore.vala | 23 ++++--- .../ProjectPicker/ProjectPickerPopover.vala | 60 ++++++++----------- src/Dialogs/Label.vala | 2 +- src/Dialogs/LabelPicker.vala | 4 +- .../Preferences/PreferencesWindow.vala | 30 ++++++---- src/Dialogs/Project.vala | 4 +- src/Dialogs/ProjectPicker/ProjectPicker.vala | 6 +- src/Dialogs/Section.vala | 8 +-- src/Layouts/ItemBoard.vala | 22 +++---- src/Layouts/ItemRow.vala | 30 +++++----- src/Layouts/ItemSidebarView.vala | 20 +++---- src/Layouts/ProjectRow.vala | 18 +++--- src/Layouts/SectionBoard.vala | 12 ++-- src/Layouts/SectionRow.vala | 14 ++--- src/Services/Migrate.vala | 2 +- src/Views/Project/Project.vala | 10 ++-- src/Views/Scheduled/Scheduled.vala | 2 +- src/Views/Today.vala | 2 +- src/Widgets/MultiSelectToolbar.vala | 6 +- 26 files changed, 195 insertions(+), 168 deletions(-) diff --git a/core/Objects/Item.vala b/core/Objects/Item.vala index 9254ff2c0..8230d2a76 100644 --- a/core/Objects/Item.vala +++ b/core/Objects/Item.vala @@ -572,7 +572,8 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV); + // TODO: VERIFICAR CALDAV + Objects.Label label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); if (label != null) { return_value.add (label); } @@ -598,7 +599,7 @@ public class Objects.Item : Objects.BaseObject { public Gee.ArrayList get_labels_from_json (Json.Node node) { Gee.ArrayList return_value = new Gee.ArrayList (); foreach (unowned Json.Node element in node.get_object ().get_array_member ("labels").get_elements ()) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (element.get_string (), true, project.backend_type); + Objects.Label label = Services.Database.get_default ().get_label_by_name (element.get_string (), true, project.source_id); return_value.add (label); } return return_value; @@ -626,7 +627,7 @@ public class Objects.Item : Objects.BaseObject { public Gee.HashMap get_labels_maps_from_json (Json.Node node) { Gee.HashMap return_value = new Gee.HashMap (); foreach (unowned Json.Node element in node.get_object ().get_array_member ("labels").get_elements ()) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (element.get_string (), true, project.backend_type); + Objects.Label label = Services.Database.get_default ().get_label_by_name (element.get_string (), true, project.source_id); return_value [label.id] = label; } return return_value; @@ -637,7 +638,7 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV); + Objects.Label label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); if (label != null) { return_value [label.id] = label; } else { diff --git a/core/Objects/Label.vala b/core/Objects/Label.vala index e92fe6811..2fc059e42 100644 --- a/core/Objects/Label.vala +++ b/core/Objects/Label.vala @@ -25,6 +25,7 @@ public class Objects.Label : Objects.BaseObject { public bool is_deleted { get; set; default = false; } public bool is_favorite { get; set; default = false; } public BackendType backend_type { get; set; default = BackendType.NONE; } + public string source_id { get; set; default = BackendType.LOCAL.to_string (); } int? _label_count = null; public int label_count { diff --git a/core/QuickAdd.vala b/core/QuickAdd.vala index 0cbf9caa5..512e3037f 100644 --- a/core/QuickAdd.vala +++ b/core/QuickAdd.vala @@ -110,8 +110,8 @@ public class Layouts.QuickAdd : Adw.Bin { priority_button = new Widgets.PriorityButton (); priority_button.update_from_item (item); label_button = new Widgets.LabelPicker.LabelButton (); + label_button.source = item.project.source; reminder_button = new Widgets.ReminderPicker.ReminderButton (true); - label_button.backend_type = item.project.backend_type; var action_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 12) { margin_start = 3, @@ -243,7 +243,7 @@ public class Layouts.QuickAdd : Adw.Bin { project_picker_button.project_change.connect ((project) => { item.project_id = project.id; - label_button.backend_type = project.backend_type; + label_button.source = project.source; if (Services.Settings.get_default ().settings.get_boolean ("quick-add-save-last-project")) { Services.Settings.get_default ().settings.set_string ("quick-add-project-selected", project.id); @@ -365,10 +365,10 @@ public class Layouts.QuickAdd : Adw.Bin { item.content = content_entry.get_text (); item.description = description_textview.get_text (); - if (item.project.backend_type == BackendType.LOCAL) { + if (item.project.source_type == BackendType.LOCAL) { item.id = Util.get_default ().generate_id (); _add_item (item); - } else if (item.project.backend_type == BackendType.TODOIST) { + } else if (item.project.source_type == BackendType.TODOIST) { is_loading = true; Services.Todoist.get_default ().add.begin (item, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -379,7 +379,7 @@ public class Layouts.QuickAdd : Adw.Bin { _add_item (item); } }); - } else if (item.project.backend_type == BackendType.CALDAV) { + } else if (item.project.source_type == BackendType.CALDAV) { is_loading = true; item.id = Util.get_default ().generate_id (); Services.CalDAV.Core.get_default ().add_task.begin (item, false, (obj, res) => { @@ -439,7 +439,7 @@ public class Layouts.QuickAdd : Adw.Bin { item.section_id = old_section_id; item.parent_id = old_parent_id; - label_button.backend_type = item.project.backend_type; + label_button.source = item.project.source; } public void update_content (string content = "") { @@ -487,7 +487,7 @@ public class Layouts.QuickAdd : Adw.Bin { public void for_project (Objects.Project project) { item.project_id = project.id; project_picker_button.project = project; - label_button.backend_type = project.backend_type; + label_button.source = project.source; } public void for_section (Objects.Section section) { @@ -496,7 +496,7 @@ public class Layouts.QuickAdd : Adw.Bin { project_picker_button.project = section.project; project_picker_button.section = section; - label_button.backend_type = section.project.backend_type; + label_button.source = section.project.source; } public void for_parent (Objects.Item _item) { @@ -505,7 +505,7 @@ public class Layouts.QuickAdd : Adw.Bin { item.parent_id = _item.id; project_picker_button.project = _item.project; - label_button.backend_type = _item.project.backend_type; + label_button.source = _item.project.source; project_picker_button.sensitive = false; } diff --git a/core/Services/CalDAV/Core.vala b/core/Services/CalDAV/Core.vala index 7ebf108d2..574c45381 100644 --- a/core/Services/CalDAV/Core.vala +++ b/core/Services/CalDAV/Core.vala @@ -499,7 +499,8 @@ public class Services.CalDAV.Core : GLib.Object { } foreach (string category in labels_map.values) { - var label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV); + // TODO: VERIFICAR CALDAV + var label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); if (label == null) { label = new Objects.Label (); label.id = Util.get_default ().generate_id (label); diff --git a/core/Services/Database.vala b/core/Services/Database.vala index ab77e9f37..4363ba5c0 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -206,6 +206,7 @@ public class Services.Database : GLib.Object { is_deleted INTEGER, is_favorite INTEGER, backend_type TEXT, + source_id TEXT, CONSTRAINT unique_label UNIQUE (name) ); """; @@ -583,7 +584,7 @@ public class Services.Database : GLib.Object { * - Add source_id column to Projects */ - add_project_source_id (); + add_project_labels_source_id (); } public void clear_database () { @@ -1114,6 +1115,19 @@ public class Services.Database : GLib.Object { } } + public Gee.ArrayList get_labels_by_source (string source_id) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_labels) { + foreach (var label in labels) { + if (label.source_id == source_id) { + return_value.add (label); + } + } + + return return_value; + } + } + public Gee.ArrayList get_all_labels_by_search (string search_text) { Gee.ArrayList return_value = new Gee.ArrayList (); lock (_labels) { @@ -1136,6 +1150,7 @@ public class Services.Database : GLib.Object { return_value.is_deleted = get_parameter_bool (stmt, 4); return_value.is_favorite = get_parameter_bool (stmt, 5); return_value.backend_type = get_backend_type_by_text (stmt, 6); + return_value.source_id = stmt.column_text (7); return return_value; } @@ -1143,8 +1158,10 @@ public class Services.Database : GLib.Object { Sqlite.Statement stmt; sql = """ - INSERT OR IGNORE INTO Labels (id, name, color, item_order, is_deleted, is_favorite, backend_type) - VALUES ($id, $name, $color, $item_order, $is_deleted, $is_favorite, $backend_type); + 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); @@ -1155,6 +1172,7 @@ public class Services.Database : GLib.Object { 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) { labels.add (label); @@ -1195,13 +1213,13 @@ public class Services.Database : GLib.Object { } } - public Objects.Label? get_label_by_name (string name, bool lowercase = false, BackendType backend_type) { + public Objects.Label? get_label_by_name (string name, bool lowercase = false, string source_id) { lock (_labels) { string compare_name = lowercase ? name.down () : name; foreach (var label in labels) { string label_name = lowercase ? label.name.down () : label.name; - if (label.backend_type == backend_type && label_name == compare_name) { + if (label.source_id == source_id && label_name == compare_name) { return label; } } @@ -1234,7 +1252,8 @@ public class Services.Database : GLib.Object { sql = """ UPDATE Labels SET name=$name, color=$color, item_order=$item_order, - is_deleted=$is_deleted, is_favorite=$is_favorite, backend_type=$backend_type + is_deleted=$is_deleted, is_favorite=$is_favorite, backend_type=$backend_type, + source_id=$source_id WHERE id=$id; """; @@ -1245,6 +1264,7 @@ public class Services.Database : GLib.Object { 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); set_parameter_str (stmt, "$id", label.id); if (stmt.step () == Sqlite.DONE) { @@ -2950,7 +2970,7 @@ public class Services.Database : GLib.Object { stmt.reset (); } - public void add_project_source_id () { + public void add_project_labels_source_id () { if (column_exists ("Projects", "source_id")) { return; } @@ -2964,6 +2984,15 @@ public class Services.Database : GLib.Object { warning (errormsg); } + 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 ()) { diff --git a/core/Widgets/LabelPicker/LabelButton.vala b/core/Widgets/LabelPicker/LabelButton.vala index 4cc09efc0..5a7e972bf 100644 --- a/core/Widgets/LabelPicker/LabelButton.vala +++ b/core/Widgets/LabelPicker/LabelButton.vala @@ -32,15 +32,15 @@ public class Widgets.LabelPicker.LabelButton : Adw.Bin { } } - BackendType _backend_type; - public BackendType backend_type { + Objects.Source _source; + public Objects.Source source { set { - _backend_type = value; - labels_picker.backend_type = _backend_type; + _source = value; + labels_picker.source = _source; } get { - return _backend_type; + return _source; } } diff --git a/core/Widgets/LabelPicker/LabelPicker.vala b/core/Widgets/LabelPicker/LabelPicker.vala index 38a6d03a1..abffc9e52 100644 --- a/core/Widgets/LabelPicker/LabelPicker.vala +++ b/core/Widgets/LabelPicker/LabelPicker.vala @@ -28,9 +28,9 @@ public class Widgets.LabelPicker.LabelPicker : Gtk.Popover { } } - public BackendType backend_type { + public Objects.Source source { set { - picker.backend_type = value; + picker.source = value; } } diff --git a/core/Widgets/LabelsPickerCore.vala b/core/Widgets/LabelsPickerCore.vala index 7043ea30a..c59522073 100644 --- a/core/Widgets/LabelsPickerCore.vala +++ b/core/Widgets/LabelsPickerCore.vala @@ -37,15 +37,15 @@ public class Widgets.LabelsPickerCore : Adw.Bin { } } - BackendType _backend_type; - public BackendType backend_type { + Objects.Source _source; + public Objects.Source source { set { - _backend_type = value; - add_labels (_backend_type); + _source = value; + add_labels (_source); } get { - return _backend_type; + return _source; } } @@ -152,7 +152,7 @@ public class Widgets.LabelsPickerCore : Adw.Bin { search_entry.activate.connect (() => { if (search_entry.text.length > 0) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (search_entry.text, true, backend_type); + Objects.Label label = Services.Database.get_default ().get_label_by_name (search_entry.text, true, source.id); if (label != null) { if (labels_widgets_map.has_key (label.id_string)) { labels_widgets_map [label.id_string].update_checked_toggled (); @@ -172,18 +172,17 @@ public class Widgets.LabelsPickerCore : Adw.Bin { var label = new Objects.Label (); label.color = Util.get_default ().get_random_color (); label.name = search_entry.text; + label.source_id = source.id; - if (backend_type == BackendType.LOCAL || backend_type == BackendType.CALDAV) { + if (source.source_type == BackendType.LOCAL || source.source_type == BackendType.CALDAV) { label.id = Util.get_default ().generate_id (label); - label.backend_type = BackendType.LOCAL; Services.Database.get_default ().insert_label (label); checked_toggled (label, true); search_entry.text = ""; close (); - } else if (backend_type == BackendType.TODOIST) { + } else if (source.source_type == BackendType.TODOIST) { is_loading = true; - label.backend_type = BackendType.TODOIST; Services.Todoist.get_default ().add.begin (label, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -200,14 +199,14 @@ public class Widgets.LabelsPickerCore : Adw.Bin { } } - private void add_labels (BackendType backend_type) { + private void add_labels (Objects.Source source) { labels_widgets_map.clear (); foreach (unowned Gtk.Widget child in Util.get_default ().get_children (listbox) ) { listbox.remove (child); } - foreach (Objects.Label label in Services.Database.get_default ().get_labels_by_backend_type (backend_type)) { + foreach (Objects.Label label in Services.Database.get_default ().get_labels_by_source (source.id)) { add_label (label); } } diff --git a/core/Widgets/ProjectPicker/ProjectPickerPopover.vala b/core/Widgets/ProjectPicker/ProjectPickerPopover.vala index a6340e925..419268fb4 100644 --- a/core/Widgets/ProjectPicker/ProjectPickerPopover.vala +++ b/core/Widgets/ProjectPicker/ProjectPickerPopover.vala @@ -1,6 +1,9 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover { public signal void selected (Objects.Project project); + public Gee.HashMap sources_hashmap = new Gee.HashMap (); + + public ProjectPickerPopover () { Object ( height_request: 300, @@ -23,29 +26,20 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover { show_separator = false }; - var local_group = new Layouts.HeaderItem (_("On this Computer")) { - reveal_child = Services.Database.get_default ().get_projects_by_backend_type (BackendType.LOCAL).size > 0, - card = true, - show_separator = false - }; - - var todoist_group = new Layouts.HeaderItem (_("Todoist")) { - reveal_child = Services.Database.get_default ().get_projects_by_backend_type (BackendType.TODOIST).size > 0, - card = true, - show_separator = false - }; - - var nextcloud_group = new Layouts.HeaderItem (_("Nextcloud")) { - reveal_child = Services.Database.get_default ().get_projects_by_backend_type (BackendType.CALDAV).size > 0, - card = true, - show_separator = false - }; - var scrolled_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); scrolled_box.append (inbox_group); - scrolled_box.append (local_group); - scrolled_box.append (todoist_group); - scrolled_box.append (nextcloud_group); + + foreach (Objects.Source source in Services.Database.get_default ().sources) { + if (!sources_hashmap.has_key (source.id)) { + sources_hashmap[source.id] = new Layouts.HeaderItem (source.header_text) { + reveal_child = Services.Database.get_default ().get_projects_by_source (source.id).size > 0, + card = true, + show_separator = false + }; + + scrolled_box.append (sources_hashmap[source.id]); + } + } var listbox = new Gtk.ListBox () { hexpand = true, @@ -80,31 +74,29 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover { search_entry.grab_focus (); foreach (Objects.Project project in Services.Database.get_default ().projects) { - var row = new Widgets.ProjectPicker.ProjectPickerRow (project); - var row_2 = new Widgets.ProjectPicker.ProjectPickerRow (project); + var row_listbox = new Widgets.ProjectPicker.ProjectPickerRow (project); - row.selected.connect (() => { - selected (row.project); + row_listbox.selected.connect (() => { + selected (row_listbox.project); popdown (); }); - row_2.selected.connect (() => { + listbox.append (row_listbox); + + var row = new Widgets.ProjectPicker.ProjectPickerRow (project); + + row.selected.connect (() => { selected (row.project); popdown (); }); - listbox.append (row_2); - if (project.is_inbox_project) { inbox_group.add_child (row); } else { - if (project.backend_type == BackendType.LOCAL) { - local_group.add_child (row); - } else if (project.backend_type == BackendType.TODOIST) { - todoist_group.add_child (row); - } else if (project.backend_type == BackendType.CALDAV) { - nextcloud_group.add_child (row); + if (sources_hashmap.has_key (project.source_id)) { + sources_hashmap.get (project.source_id).add_child (row); } + } } diff --git a/src/Dialogs/Label.vala b/src/Dialogs/Label.vala index 829fec62b..83a1b357f 100644 --- a/src/Dialogs/Label.vala +++ b/src/Dialogs/Label.vala @@ -136,7 +136,7 @@ public class Dialogs.Label : Adw.Dialog { } private bool is_duplicate (string text) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (text, true, label.backend_type); + Objects.Label label = Services.Database.get_default ().get_label_by_name (text, true, label.source_id); return label != null; } diff --git a/src/Dialogs/LabelPicker.vala b/src/Dialogs/LabelPicker.vala index 552a34cdc..2ab6f60c2 100644 --- a/src/Dialogs/LabelPicker.vala +++ b/src/Dialogs/LabelPicker.vala @@ -83,8 +83,8 @@ public class Dialogs.LabelPicker : Adw.Dialog { }); } - public void add_labels (BackendType backend_type) { - picker.backend_type = backend_type; + public void add_labels (Objects.Source source) { + picker.source = source; } public void hide_destroy () { diff --git a/src/Dialogs/Preferences/PreferencesWindow.vala b/src/Dialogs/Preferences/PreferencesWindow.vala index 6c409d4e6..c668b3884 100644 --- a/src/Dialogs/Preferences/PreferencesWindow.vala +++ b/src/Dialogs/Preferences/PreferencesWindow.vala @@ -876,23 +876,27 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { Gee.HashMap sources_hashmap = new Gee.HashMap (); foreach (Objects.Source source in Services.Database.get_default ().sources) { - sources_hashmap[source.id] = new Widgets.SourceRow (source); + if (!sources_hashmap.has_key (source.id)) { + sources_hashmap[source.id] = new Widgets.SourceRow (source); - sources_hashmap[source.id].view_detail.connect (() => { - push_subpage (get_todoist_view (source)); - }); - - sources_group.add_child (sources_hashmap[source.id]); + sources_hashmap[source.id].view_detail.connect (() => { + push_subpage (get_todoist_view (source)); + }); + + sources_group.add_child (sources_hashmap[source.id]); + } } Services.Database.get_default ().source_added.connect ((source) => { - sources_hashmap[source.id] = new Widgets.SourceRow (source); - - sources_hashmap[source.id].view_detail.connect (() => { - push_subpage (get_todoist_view (source)); - }); + if (!sources_hashmap.has_key (source.id)) { + sources_hashmap[source.id] = new Widgets.SourceRow (source); - sources_group.add_child (sources_hashmap[source.id]); + sources_hashmap[source.id].view_detail.connect (() => { + push_subpage (get_todoist_view (source)); + }); + + sources_group.add_child (sources_hashmap[source.id]); + } }); Services.Database.get_default ().source_deleted.connect ((source) => { @@ -913,7 +917,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return new Adw.NavigationPage (toolbar_view, "account"); } - + private Adw.NavigationPage get_todoist_view (Objects.Source source) { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Todoist")); diff --git a/src/Dialogs/Project.vala b/src/Dialogs/Project.vala index b468a5649..88746eb24 100644 --- a/src/Dialogs/Project.vala +++ b/src/Dialogs/Project.vala @@ -212,9 +212,9 @@ public class Dialogs.Project : Adw.Dialog { progress_bar.color = project.color; color_picker_row.color = project.color; - if (project.backend_type == BackendType.LOCAL || project.backend_type == BackendType.NONE) { + if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.NONE) { backend_row.selected = 0; - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == BackendType.TODOIST) { backend_row.selected = 1; } diff --git a/src/Dialogs/ProjectPicker/ProjectPicker.vala b/src/Dialogs/ProjectPicker/ProjectPicker.vala index 8b5682392..6b1a1756e 100644 --- a/src/Dialogs/ProjectPicker/ProjectPicker.vala +++ b/src/Dialogs/ProjectPicker/ProjectPicker.vala @@ -260,11 +260,11 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Dialog { if (project.is_inbox_project) { inbox_group.add_child (projects_hashmap [project.id]); } else { - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == BackendType.LOCAL) { local_group.add_child (projects_hashmap [project.id]); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == BackendType.TODOIST) { todoist_group.add_child (projects_hashmap [project.id]); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == BackendType.CALDAV) { caldav_group.add_child (projects_hashmap [project.id]); } } diff --git a/src/Dialogs/Section.vala b/src/Dialogs/Section.vala index 743e1095a..1caa2797d 100644 --- a/src/Dialogs/Section.vala +++ b/src/Dialogs/Section.vala @@ -157,19 +157,19 @@ public class Dialogs.Section : Adw.Dialog { if (!is_creating) { submit_button.is_loading = true; - if (section.project.backend_type == BackendType.TODOIST) { + if (section.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (section, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Database.get_default ().update_section (section); submit_button.is_loading = false; hide_destroy (); }); - } else if (section.project.backend_type == BackendType.LOCAL) { + } else if (section.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_section (section); hide_destroy (); } } else { - if (section.project.backend_type == BackendType.TODOIST) { + if (section.project.source_type == BackendType.TODOIST) { submit_button.is_loading = true; Services.Todoist.get_default ().add.begin (section, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -180,7 +180,7 @@ public class Dialogs.Section : Adw.Dialog { hide_destroy (); } }); - } else if (section.project.backend_type == BackendType.LOCAL) { + } else if (section.project.source_type == BackendType.LOCAL) { section.id = Util.get_default ().generate_id (section); section.project.add_section_if_not_exists (section); hide_destroy (); diff --git a/src/Layouts/ItemBoard.vala b/src/Layouts/ItemBoard.vala index e1bbe412d..3ae564baf 100644 --- a/src/Layouts/ItemBoard.vala +++ b/src/Layouts/ItemBoard.vala @@ -485,9 +485,9 @@ public class Layouts.ItemBoard : Layouts.ItemBase { } private void _complete_item (bool old_checked) { - if (item.project.backend_type == BackendType.LOCAL) { + if (item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().checked_toggled (item, old_checked); - } else if (item.project.backend_type == BackendType.TODOIST) { + } else if (item.project.source_type == BackendType.TODOIST) { checked_button.sensitive = false; is_loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { @@ -497,7 +497,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { checked_button.sensitive = true; } }); - } else if (item.project.backend_type == BackendType.CALDAV) { + } else if (item.project.source_type == BackendType.CALDAV) { checked_button.sensitive = false; is_loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { @@ -676,7 +676,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { if (item.project.is_inbox_project) { backend_type = BackendType.ALL; } else { - backend_type = item.project.backend_type; + backend_type = item.project.source_type; } var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, backend_type); @@ -832,17 +832,17 @@ public class Layouts.ItemBoard : Layouts.ItemBase { picked_item.section_id = ""; picked_item.parent_id = target_item.id; - if (picked_item.project.backend_type == BackendType.LOCAL) { + if (picked_item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_item (picked_item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); - } else if (picked_item.project.backend_type == BackendType.TODOIST) { + } else if (picked_item.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_item.begin (picked_item, "parent_id", picked_item.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { Services.Database.get_default ().update_item (picked_widget.item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); - } else if (picked_item.project.backend_type == BackendType.CALDAV) { + } else if (picked_item.project.source_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { Services.Database.get_default ().update_item (picked_widget.item); @@ -928,7 +928,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { picked_widget.item.parent_id = target_widget.item.parent_id; } - if (picked_widget.item.project.backend_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == BackendType.TODOIST) { string move_id = picked_widget.item.project_id; string move_type = "project_id"; @@ -947,7 +947,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { Services.Database.get_default ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.backend_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_item (picked_widget.item); } } @@ -1024,7 +1024,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { public void move (Objects.Project project, string section_id) { string project_id = project.id; - if (item.project.backend_type != project.backend_type) { + 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) { @@ -1048,7 +1048,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { public void update_pinned (bool pinned) { item.pinned = pinned; - if (item.project.backend_type == BackendType.CALDAV) { + if (item.project.source_type == BackendType.CALDAV) { item.update_async (""); } else { item.update_local (); diff --git a/src/Layouts/ItemRow.vala b/src/Layouts/ItemRow.vala index 308181494..357d4bcb8 100644 --- a/src/Layouts/ItemRow.vala +++ b/src/Layouts/ItemRow.vala @@ -409,7 +409,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { sensitive = !item.completed }; - label_button.backend_type = item.project.backend_type; + label_button.source = item.project.source; pin_button = new Widgets.PinButton () { sensitive = !item.completed @@ -653,8 +653,8 @@ public class Layouts.ItemRow : Layouts.ItemBase { if (item.priority != priority) { item.priority = priority; - if (item.project.backend_type == BackendType.TODOIST || - item.project.backend_type == BackendType.CALDAV) { + if (item.project.source_type == BackendType.TODOIST || + item.project.source_type == BackendType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -960,7 +960,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { public void update_pinned (bool pinned) { item.pinned = pinned; - if (item.project.backend_type == BackendType.CALDAV) { + if (item.project.source_type == BackendType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -1041,7 +1041,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { if (item.project.is_inbox_project) { backend_type = BackendType.ALL; } else { - backend_type = item.project.backend_type; + backend_type = item.project.source_type; } var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, backend_type); @@ -1372,9 +1372,9 @@ public class Layouts.ItemRow : Layouts.ItemBase { } private void _complete_item (bool old_checked) { - if (item.project.backend_type == BackendType.LOCAL) { + if (item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().checked_toggled (item, old_checked); - } else if (item.project.backend_type == BackendType.TODOIST) { + } else if (item.project.source_type == BackendType.TODOIST) { checked_button.sensitive = false; is_loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { @@ -1384,7 +1384,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { checked_button.sensitive = true; } }); - } else if (item.project.backend_type == BackendType.CALDAV) { + } else if (item.project.source_type == BackendType.CALDAV) { checked_button.sensitive = false; is_loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { @@ -1490,7 +1490,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { public void move (Objects.Project project, string section_id) { string project_id = project.id; - if (item.project.backend_type != project.backend_type) { + 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) { @@ -1592,11 +1592,11 @@ public class Layouts.ItemRow : Layouts.ItemBase { picked_item.section_id = ""; picked_item.parent_id = target_item.id; - if (picked_item.project.backend_type == BackendType.LOCAL) { + if (picked_item.project.source_type == BackendType.LOCAL) { target_item.collapsed = true; Services.Database.get_default ().update_item (picked_item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); - } else if (picked_item.project.backend_type == BackendType.TODOIST) { + } else if (picked_item.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_item.begin (picked_item, "parent_id", picked_item.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { target_item.collapsed = true; @@ -1604,7 +1604,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); - } else if (picked_item.project.backend_type == BackendType.CALDAV) { + } else if (picked_item.project.source_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { target_item.collapsed = true; @@ -1694,9 +1694,9 @@ public class Layouts.ItemRow : Layouts.ItemBase { picked_widget.item.parent_id = target_widget.item.parent_id; } - if (picked_widget.item.project.backend_type == BackendType.LOCAL) { + if (picked_widget.item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_item (picked_widget.item); - } else if (picked_widget.item.project.backend_type == BackendType.TODOIST) { + } else if (picked_widget.item.project.source_type == BackendType.TODOIST) { string move_id = picked_widget.item.project_id; string move_type = "project_id"; @@ -1715,7 +1715,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { Services.Database.get_default ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.backend_type == BackendType.CALDAV) { + } else if (picked_widget.item.project.source_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_widget.item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { Services.Database.get_default ().update_item (picked_widget.item); diff --git a/src/Layouts/ItemSidebarView.vala b/src/Layouts/ItemSidebarView.vala index e322efdf3..f2621e037 100644 --- a/src/Layouts/ItemSidebarView.vala +++ b/src/Layouts/ItemSidebarView.vala @@ -232,8 +232,8 @@ public class Layouts.ItemSidebarView : Adw.Bin { if (item.priority != priority) { item.priority = priority; - if (item.project.backend_type == BackendType.TODOIST || - item.project.backend_type == BackendType.CALDAV) { + if (item.project.source_type == BackendType.TODOIST || + item.project.source_type == BackendType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -256,7 +256,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { reminder_button.reminder_added.connect ((reminder) => { reminder.item_id = item.id; - if (item.project.backend_type == BackendType.TODOIST) { + if (item.project.source_type == BackendType.TODOIST) { item.loading = true; Services.Todoist.get_default ().add.begin (reminder, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -302,7 +302,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { item = _item; update_id = Util.get_default ().generate_id (); - label_button.backend_type = item.project.backend_type; + label_button.source = item.project.source; update_request (); subitems.present_item (item); attachments.present_item (item); @@ -441,7 +441,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { public void update_pinned (bool pinned) { item.pinned = pinned; - if (item.project.backend_type == BackendType.CALDAV) { + if (item.project.source_type == BackendType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -521,7 +521,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { if (item.project.is_inbox_project) { backend_type = BackendType.ALL; } else { - backend_type = item.project.backend_type; + backend_type = item.project.source_type; } var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, backend_type); @@ -661,7 +661,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { public void move (Objects.Project project, string section_id, string parent_id = "") { string project_id = project.id; - if (item.project.backend_type != project.backend_type) { + 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) { @@ -725,9 +725,9 @@ public class Layouts.ItemSidebarView : Adw.Bin { } private void _complete_item (bool old_checked) { - if (item.project.backend_type == BackendType.LOCAL) { + if (item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().checked_toggled (item, old_checked); - } else if (item.project.backend_type == BackendType.TODOIST) { + } else if (item.project.source_type == BackendType.TODOIST) { item.loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { if (Services.Todoist.get_default ().complete_item.end (res).status) { @@ -736,7 +736,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { item.loading = false; }); - } else if (item.project.backend_type == BackendType.CALDAV) { + } else if (item.project.source_type == BackendType.CALDAV) { item.loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { if (Services.CalDAV.Core.get_default ().complete_item.end (res).status) { diff --git a/src/Layouts/ProjectRow.vala b/src/Layouts/ProjectRow.vala index b0df37957..d3c48b2f8 100644 --- a/src/Layouts/ProjectRow.vala +++ b/src/Layouts/ProjectRow.vala @@ -388,7 +388,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (picked_project.parent_id != target_project.parent_id) { picked_project.parent_id = target_project.parent_id; - if (picked_project.backend_type == BackendType.TODOIST) { + if (picked_project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (picked_project, target_project.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { Services.Database.get_default ().update_project (picked_project); @@ -421,7 +421,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (value.dup_object () is Layouts.ProjectRow) { var picked_widget = (Layouts.ProjectRow) value; - if (picked_widget.project.backend_type == project.backend_type) { + if (picked_widget.project.source_id == project.source_id) { motion_top_revealer.reveal_child = drop_motion_ctrl.contains_pointer; } } @@ -474,7 +474,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (value.dup_object () is Layouts.ProjectRow) { var picked_widget = (Layouts.ProjectRow) value; - if (picked_widget.project.backend_type == project.backend_type) { + if (picked_widget.project.source_id == project.source_id) { return true; } } @@ -496,7 +496,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { string old_parent_id = picked_project.parent_id; picked_project.parent_id = target_project.id; - if (picked_project.backend_type == BackendType.TODOIST) { + if (picked_project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (picked_project, target_project.id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { Services.Database.get_default ().update_project (picked_project); @@ -532,7 +532,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { return true; } - if (picked_widget.item.project.backend_type == project.backend_type) { + if (picked_widget.item.project.source_id == project.source_id) { return true; } } @@ -544,7 +544,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { var picked_widget = (Layouts.ItemBoard) value; var target_widget = this; - if (picked_widget.item.project.backend_type != target_widget.project.backend_type) { + if (picked_widget.item.project.source_id != target_widget.project.source_id) { Util.get_default ().move_backend_type_item.begin (picked_widget.item, target_widget.project); } else { picked_widget.item.move (target_widget.project, ""); @@ -572,7 +572,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { return true; } - if (picked_widget.item.project.backend_type == project.backend_type) { + if (picked_widget.item.project.source_id == project.source_id) { return true; } } @@ -584,7 +584,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { var picked_widget = (Layouts.ItemBoard) value; var target_widget = this; - if (picked_widget.item.project.backend_type != target_widget.project.backend_type) { + if (picked_widget.item.project.source_id != target_widget.project.source_id) { Util.get_default ().move_backend_type_item.begin (picked_widget.item, target_widget.project); } else { picked_widget.item.move (target_widget.project, ""); @@ -650,7 +650,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { menu_box.append (edit_item); } - if (project.backend_type == BackendType.CALDAV) { + if (project.source_type == BackendType.CALDAV) { menu_box.append (refresh_item); } diff --git a/src/Layouts/SectionBoard.vala b/src/Layouts/SectionBoard.vala index f93e154be..cc884bfb0 100644 --- a/src/Layouts/SectionBoard.vala +++ b/src/Layouts/SectionBoard.vala @@ -536,7 +536,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { move_item.clicked.connect (() => { menu_popover.popdown (); - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, section.project.backend_type); + var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, section.project.source_type); dialog.project = section.project; dialog.present (Planify._instance.main_window); @@ -571,7 +571,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { if (response == "delete") { is_loading = true; - if (section.project.backend_type == BackendType.TODOIST) { + if (section.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().delete.begin (section, (obj, res) => { Services.Todoist.get_default ().delete.end (res); Services.Database.get_default ().delete_section (section); @@ -602,7 +602,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { string old_section_id = section.project_id; section.project_id = project_id; - if (section.project.backend_type == BackendType.TODOIST) { + if (section.project.source_type == BackendType.TODOIST) { is_loading = true; Services.Todoist.get_default ().move_project_section.begin (section, project_id, (obj, res) => { @@ -611,7 +611,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { is_loading = false; } }); - } else if (section.project.backend_type == BackendType.LOCAL) { + } else if (section.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().move_section (section, project_id); is_loading = false; } @@ -637,7 +637,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { picked_widget.item.section_id = section.id; picked_widget.item.parent_id = ""; - if (picked_widget.item.project.backend_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == BackendType.TODOIST) { string type = "section_id"; string id = section.id; @@ -651,7 +651,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { Services.Database.get_default ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.backend_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_item (picked_widget.item); } diff --git a/src/Layouts/SectionRow.vala b/src/Layouts/SectionRow.vala index 53be3c360..c22082bf2 100644 --- a/src/Layouts/SectionRow.vala +++ b/src/Layouts/SectionRow.vala @@ -711,7 +711,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { move_item.clicked.connect (() => { menu_popover.popdown (); - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, section.project.backend_type); + var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, section.project.source_type); dialog.project = section.project; dialog.present (Planify._instance.main_window); @@ -762,7 +762,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { picked_widget.item.section_id = section.id; picked_widget.item.parent_id = ""; - if (picked_widget.item.project.backend_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == BackendType.TODOIST) { string type = "section_id"; string id = section.id; @@ -776,7 +776,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { Services.Database.get_default ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.backend_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_item (picked_widget.item); } @@ -804,7 +804,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { picked_widget.item.section_id = section.id; picked_widget.item.parent_id = ""; - if (picked_widget.item.project.backend_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == BackendType.TODOIST) { string type = "section_id"; string id = section.id; @@ -818,7 +818,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { Services.Database.get_default ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.backend_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().update_item (picked_widget.item); } @@ -876,7 +876,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { is_loading = true; - if (section.project.backend_type == BackendType.TODOIST) { + if (section.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (section, project_id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { Services.Database.get_default ().move_section (section, old_section_id); @@ -884,7 +884,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { is_loading = false; }); - } else if (section.project.backend_type == BackendType.LOCAL) { + } else if (section.project.source_type == BackendType.LOCAL) { Services.Database.get_default ().move_section (section, project_id); is_loading = false; } diff --git a/src/Services/Migrate.vala b/src/Services/Migrate.vala index 5829bf57e..7235e54d2 100644 --- a/src/Services/Migrate.vala +++ b/src/Services/Migrate.vala @@ -78,7 +78,7 @@ public class Services.Migrate : GLib.Object { project.id = stmt.column_text (0); project.name = "(Planner) %s".printf (stmt.column_text (1)); project.color = stmt.column_text (2); - project.backend_type = BackendType.LOCAL; + project.source_id = BackendType.LOCAL.to_string (); Services.Database.get_default ().insert_project (project); } diff --git a/src/Views/Project/Project.vala b/src/Views/Project/Project.vala index 8bf1226a8..f5fbbcfab 100644 --- a/src/Views/Project/Project.vala +++ b/src/Views/Project/Project.vala @@ -36,7 +36,7 @@ public class Views.Project : Adw.Bin { public ProjectViewStyle view_style { get { - return project.backend_type == BackendType.CALDAV ? ProjectViewStyle.LIST : project.view_style; + return project.source_type == BackendType.CALDAV ? ProjectViewStyle.LIST : project.view_style; } } @@ -295,7 +295,7 @@ public class Views.Project : Adw.Bin { menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); } - if (project.backend_type == BackendType.LOCAL || project.backend_type == BackendType.TODOIST) { + if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.TODOIST) { menu_box.append (add_section_item); menu_box.append (manage_sections); menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); @@ -516,7 +516,7 @@ public class Views.Project : Adw.Bin { var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); menu_box.margin_top = menu_box.margin_bottom = 3; - if (project.backend_type == BackendType.LOCAL || project.backend_type == BackendType.TODOIST) { + if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.TODOIST) { menu_box.append (view_box); menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); } @@ -669,7 +669,7 @@ public class Views.Project : Adw.Bin { } var dialog = new Dialogs.LabelPicker (); - dialog.add_labels (project.backend_type); + dialog.add_labels (project.source); dialog.labels = _labels; dialog.present (Planify._instance.main_window); @@ -702,7 +702,7 @@ public class Views.Project : Adw.Bin { } public void prepare_new_section () { - if (project.backend_type == BackendType.CALDAV) { + if (project.source_type == BackendType.CALDAV) { return; } diff --git a/src/Views/Scheduled/Scheduled.vala b/src/Views/Scheduled/Scheduled.vala index 3f4dfea70..6c412bb94 100644 --- a/src/Views/Scheduled/Scheduled.vala +++ b/src/Views/Scheduled/Scheduled.vala @@ -270,7 +270,7 @@ public class Views.Scheduled.Scheduled : Adw.Bin { } var dialog = new Dialogs.LabelPicker (); - dialog.add_labels (BackendType.ALL); + // TODO: dialog.add_labels (BackendType.ALL); dialog.labels = _labels; dialog.present (Planify._instance.main_window); diff --git a/src/Views/Today.vala b/src/Views/Today.vala index 3820cf7a0..0ce2358d2 100644 --- a/src/Views/Today.vala +++ b/src/Views/Today.vala @@ -635,7 +635,7 @@ public class Views.Today : Adw.Bin { } var dialog = new Dialogs.LabelPicker (); - dialog.add_labels (BackendType.ALL); + // TODO: dialog.add_labels (BackendType.ALL); dialog.labels = _labels; dialog.present (Planify._instance.main_window); diff --git a/src/Widgets/MultiSelectToolbar.vala b/src/Widgets/MultiSelectToolbar.vala index 0f69361ce..23c7b627b 100644 --- a/src/Widgets/MultiSelectToolbar.vala +++ b/src/Widgets/MultiSelectToolbar.vala @@ -61,7 +61,7 @@ public class Widgets.MultiSelectToolbar : Adw.Bin { label_button = new Widgets.LabelPicker.LabelButton () { sensitive = false }; - label_button.backend_type = project.backend_type; + label_button.source = project.source; priority_button = new Widgets.PriorityButton () { sensitive = false @@ -148,13 +148,13 @@ public class Widgets.MultiSelectToolbar : Adw.Bin { } private void update_items (Gee.ArrayList objects) { - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == BackendType.LOCAL) { foreach (Objects.Item item in objects) { item.update_async (""); } unselect_all (); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == BackendType.TODOIST) { done_button.is_loading = true; Services.Todoist.get_default ().update_items.begin (objects, (obj, res) => { Services.Todoist.get_default ().update_items.end (res); From ad80147a29c4b0cbfd5456ce0c32fa5b8d37f10b Mon Sep 17 00:00:00 2001 From: Alain Date: Sat, 20 Jul 2024 06:31:10 -0500 Subject: [PATCH 05/14] feat: add caldav setup page --- core/Enum.vala | 39 + core/Layouts/HeaderItem.vala | 2 +- core/Objects/Attachment.vala | 6 +- core/Objects/Filters/Completed.vala | 22 +- core/Objects/Filters/Labels.vala | 34 +- core/Objects/Filters/Pinboard.vala | 22 +- core/Objects/Filters/Priority.vala | 22 +- core/Objects/Filters/Scheduled.vala | 22 +- core/Objects/Filters/Today.vala | 34 +- core/Objects/Item.vala | 80 +- core/Objects/Label.vala | 14 +- core/Objects/ObjectEvent.vala | 2 +- core/Objects/Project.vala | 62 +- core/Objects/Reminder.vala | 8 +- core/Objects/Section.vala | 24 +- core/Objects/Source.vala | 175 ++- core/QuickAdd.vala | 4 +- core/Services/CalDAV/Core.vala | 185 ++- core/Services/CalDAV/_Core.vala | 1154 -------------- core/Services/Database.vala | 1396 +++-------------- core/Services/Store.vala | 1277 +++++++++++++++ core/Services/Todoist.vala | 76 +- core/Util/Util.vala | 223 ++- core/Widgets/LabelsPickerCore.vala | 10 +- .../ProjectPicker/ProjectPickerPopover.vala | 6 +- core/meson.build | 1 + quick-add/MainWindow.vala | 28 +- src/Dialogs/Label.vala | 12 +- src/Dialogs/ManageProjects.vala | 6 +- src/Dialogs/ManageSectionOrder.vala | 6 +- .../Preferences/PreferencesWindow.vala | 19 +- src/Dialogs/Project.vala | 16 +- src/Dialogs/ProjectPicker/ProjectPicker.vala | 140 +- .../ProjectPicker/ProjectPickerSourceRow.vala | 53 + src/Dialogs/QuickFind/QuickFind.vala | 8 +- src/Dialogs/Section.vala | 4 +- src/Layouts/FilterPaneRow.vala | 2 +- src/Layouts/ItemBoard.vala | 31 +- src/Layouts/ItemRow.vala | 40 +- src/Layouts/ItemSidebarView.vala | 15 +- src/Layouts/LabelRow.vala | 6 +- src/Layouts/ProjectRow.vala | 12 +- src/Layouts/SectionBoard.vala | 20 +- src/Layouts/SectionRow.vala | 20 +- src/Layouts/Sidebar.vala | 8 +- src/Layouts/SidebarSourceRow.vala | 21 +- src/MainWindow.vala | 35 +- src/Services/Backups.vala | 22 +- src/Services/GoogleTasks.vala | 4 +- src/Services/Migrate.vala | 14 +- src/Services/Notification.vala | 10 +- src/Views/Filter.vala | 30 +- src/Views/Label/Label.vala | 12 +- src/Views/Label/LabelSourceRow.vala | 117 ++ src/Views/Label/Labels.vala | 164 +- src/Views/Project/Board.vala | 8 +- src/Views/Project/List.vala | 8 +- src/Views/Project/Project.vala | 8 +- src/Views/Scheduled/Scheduled.vala | 4 +- src/Views/Scheduled/ScheduledDay.vala | 16 +- src/Views/Scheduled/ScheduledMonth.vala | 16 +- src/Views/Scheduled/ScheduledRange.vala | 16 +- src/Views/Today.vala | 26 +- src/Widgets/SourceRow.vala | 4 +- src/Widgets/SubItems.vala | 8 +- src/meson.build | 2 + 66 files changed, 2591 insertions(+), 3300 deletions(-) delete mode 100644 core/Services/CalDAV/_Core.vala create mode 100644 core/Services/Store.vala create mode 100644 src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala create mode 100644 src/Views/Label/LabelSourceRow.vala diff --git a/core/Enum.vala b/core/Enum.vala index 5e1b5a522..c492b9b6a 100644 --- a/core/Enum.vala +++ b/core/Enum.vala @@ -352,6 +352,45 @@ public enum CalDAVType { assert_not_reached (); } } + + public string title () { + switch (this) { + case NEXTCLOUD: + return _("Nextcloud"); + + case RADICALE: + return _("Radicale"); + + default: + assert_not_reached (); + } + } + + public static CalDAVType parse_index (uint value) { + switch (value) { + case 0: + return CalDAVType.NEXTCLOUD; + + case 1: + return CalDAVType.RADICALE; + + default: + return CalDAVType.NEXTCLOUD; + } + } + + public static CalDAVType parse (string value) { + switch (value) { + case "nextcloud": + return CalDAVType.NEXTCLOUD; + + case "radicale": + return CalDAVType.RADICALE; + + default: + return CalDAVType.NEXTCLOUD; + } + } } public enum FilterItemType { diff --git a/core/Layouts/HeaderItem.vala b/core/Layouts/HeaderItem.vala index 728c42089..8c866eadd 100644 --- a/core/Layouts/HeaderItem.vala +++ b/core/Layouts/HeaderItem.vala @@ -44,7 +44,7 @@ public class Layouts.HeaderItem : Adw.Bin { set { _subheader_title = value; subheader_label.label = _subheader_title; - subheader_revealer.reveal_child = value != null; + subheader_revealer.reveal_child = value != ""; } } diff --git a/core/Objects/Attachment.vala b/core/Objects/Attachment.vala index 636dfa6f6..4151c6d5e 100644 --- a/core/Objects/Attachment.vala +++ b/core/Objects/Attachment.vala @@ -32,7 +32,7 @@ public class Objects.Attachment : GLib.Object { Objects.Item? _item; public Objects.Item item { get { - _item = Services.Database.get_default ().get_item (item_id); + _item = Services.Store.instance ().get_item (item_id); return _item; } @@ -43,7 +43,7 @@ public class Objects.Attachment : GLib.Object { construct { deleted.connect (() => { - Services.Database.get_default ().attachment_deleted (this); + Services.Store.instance ().attachment_deleted (this); }); } @@ -68,7 +68,7 @@ public class Objects.Attachment : GLib.Object { } public void delete () { - Services.Database.get_default ().delete_attachment (this); + Services.Store.instance ().delete_attachment (this); } public Objects.Attachment duplicate () { diff --git a/core/Objects/Filters/Completed.vala b/core/Objects/Filters/Completed.vala index 47090bdb1..56d8d7429 100644 --- a/core/Objects/Filters/Completed.vala +++ b/core/Objects/Filters/Completed.vala @@ -33,7 +33,7 @@ public class Objects.Filters.Completed : Objects.BaseObject { public int count { get { if (_count == null) { - _count = Services.Database.get_default ().get_items_completed ().size; + _count = Services.Store.instance ().get_items_completed ().size; } return _count; @@ -52,28 +52,28 @@ public class Objects.Filters.Completed : Objects.BaseObject { icon_name = "check-round-outline-symbolic"; view_id = FilterType.COMPLETED.to_string (); - Services.Database.get_default ().item_added.connect (() => { - _count = Services.Database.get_default ().get_items_completed ().size; + Services.Store.instance ().item_added.connect (() => { + _count = Services.Store.instance ().get_items_completed ().size; count_updated (); }); - Services.Database.get_default ().item_deleted.connect (() => { - _count = Services.Database.get_default ().get_items_completed ().size; + Services.Store.instance ().item_deleted.connect (() => { + _count = Services.Store.instance ().get_items_completed ().size; count_updated (); }); - Services.Database.get_default ().item_updated.connect (() => { - _count = Services.Database.get_default ().get_items_completed ().size; + Services.Store.instance ().item_updated.connect (() => { + _count = Services.Store.instance ().get_items_completed ().size; count_updated (); }); - Services.Database.get_default ().item_archived.connect (() => { - _count = Services.Database.get_default ().get_items_completed ().size; + Services.Store.instance ().item_archived.connect (() => { + _count = Services.Store.instance ().get_items_completed ().size; count_updated (); }); - Services.Database.get_default ().item_unarchived.connect (() => { - _count = Services.Database.get_default ().get_items_completed ().size; + Services.Store.instance ().item_unarchived.connect (() => { + _count = Services.Store.instance ().get_items_completed ().size; count_updated (); }); } diff --git a/core/Objects/Filters/Labels.vala b/core/Objects/Filters/Labels.vala index e77dabeb5..9ae552f1f 100644 --- a/core/Objects/Filters/Labels.vala +++ b/core/Objects/Filters/Labels.vala @@ -33,7 +33,7 @@ public class Objects.Filters.Labels : Objects.BaseObject { public int count { get { if (_count == null) { - _count = Services.Database.get_default ().get_items_has_labels ().size; + _count = Services.Store.instance ().get_items_has_labels ().size; } return _count; @@ -52,43 +52,43 @@ public class Objects.Filters.Labels : Objects.BaseObject { icon_name = "tag-outline-symbolic"; view_id = FilterType.LABELS.to_string (); - Services.Database.get_default ().label_added.connect (() => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().label_added.connect (() => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); - Services.Database.get_default ().label_deleted.connect (() => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().label_deleted.connect (() => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); - Services.Database.get_default ().label_updated.connect (() => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().label_updated.connect (() => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); - Services.Database.get_default ().item_added.connect (() => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().item_added.connect (() => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); - Services.Database.get_default ().item_deleted.connect (() => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().item_deleted.connect (() => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); - Services.Database.get_default ().item_archived.connect (() => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().item_archived.connect (() => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); - Services.Database.get_default ().item_unarchived.connect ((item) => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().item_unarchived.connect ((item) => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); - Services.Database.get_default ().item_updated.connect (() => { - _count = Services.Database.get_default ().get_items_has_labels ().size; + Services.Store.instance ().item_updated.connect (() => { + _count = Services.Store.instance ().get_items_has_labels ().size; count_updated (); }); } diff --git a/core/Objects/Filters/Pinboard.vala b/core/Objects/Filters/Pinboard.vala index 7edf3a569..741488352 100644 --- a/core/Objects/Filters/Pinboard.vala +++ b/core/Objects/Filters/Pinboard.vala @@ -33,7 +33,7 @@ public class Objects.Filters.Pinboard : Objects.BaseObject { public int pinboard_count { get { if (_pinboard_count == null) { - _pinboard_count = Services.Database.get_default ().get_items_pinned (false).size; + _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; } return _pinboard_count; @@ -52,28 +52,28 @@ public class Objects.Filters.Pinboard : Objects.BaseObject { icon_name = "pin-symbolic"; view_id = FilterType.PINBOARD.to_string (); - Services.Database.get_default ().item_added.connect (() => { - _pinboard_count = Services.Database.get_default ().get_items_pinned (false).size; + Services.Store.instance ().item_added.connect (() => { + _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; pinboard_count_updated (); }); - Services.Database.get_default ().item_deleted.connect (() => { - _pinboard_count = Services.Database.get_default ().get_items_pinned (false).size; + Services.Store.instance ().item_deleted.connect (() => { + _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; pinboard_count_updated (); }); - Services.Database.get_default ().item_updated.connect (() => { - _pinboard_count = Services.Database.get_default ().get_items_pinned (false).size; + Services.Store.instance ().item_updated.connect (() => { + _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; pinboard_count_updated (); }); - Services.Database.get_default ().item_archived.connect (() => { - _pinboard_count = Services.Database.get_default ().get_items_pinned (false).size; + Services.Store.instance ().item_archived.connect (() => { + _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; pinboard_count_updated (); }); - Services.Database.get_default ().item_unarchived.connect (() => { - _pinboard_count = Services.Database.get_default ().get_items_pinned (false).size; + Services.Store.instance ().item_unarchived.connect (() => { + _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; pinboard_count_updated (); }); } diff --git a/core/Objects/Filters/Priority.vala b/core/Objects/Filters/Priority.vala index 1ca594ed7..1941bc011 100644 --- a/core/Objects/Filters/Priority.vala +++ b/core/Objects/Filters/Priority.vala @@ -41,7 +41,7 @@ public class Objects.Filters.Priority : Objects.BaseObject { public int count { get { if (_count == null) { - _count = Services.Database.get_default ().get_items_by_priority (priority, false).size; + _count = Services.Store.instance ().get_items_by_priority (priority, false).size; } return _count; @@ -59,28 +59,28 @@ public class Objects.Filters.Priority : Objects.BaseObject { keywords = Util.get_default ().get_priority_keywords (priority) + ";" + _("filters"); view_id = "priority-%d".printf (priority); - Services.Database.get_default ().item_added.connect (() => { - _count = Services.Database.get_default ().get_items_by_priority (priority, false).size; + Services.Store.instance ().item_added.connect (() => { + _count = Services.Store.instance ().get_items_by_priority (priority, false).size; count_updated (); }); - Services.Database.get_default ().item_deleted.connect (() => { - _count = Services.Database.get_default ().get_items_by_priority (priority, false).size; + Services.Store.instance ().item_deleted.connect (() => { + _count = Services.Store.instance ().get_items_by_priority (priority, false).size; count_updated (); }); - Services.Database.get_default ().item_updated.connect (() => { - _count = Services.Database.get_default ().get_items_by_priority (priority, false).size; + Services.Store.instance ().item_updated.connect (() => { + _count = Services.Store.instance ().get_items_by_priority (priority, false).size; count_updated (); }); - Services.Database.get_default ().item_archived.connect (() => { - _count = Services.Database.get_default ().get_items_by_priority (priority, false).size; + Services.Store.instance ().item_archived.connect (() => { + _count = Services.Store.instance ().get_items_by_priority (priority, false).size; count_updated (); }); - Services.Database.get_default ().item_unarchived.connect (() => { - _count = Services.Database.get_default ().get_items_by_priority (priority, false).size; + Services.Store.instance ().item_unarchived.connect (() => { + _count = Services.Store.instance ().get_items_by_priority (priority, false).size; count_updated (); }); } diff --git a/core/Objects/Filters/Scheduled.vala b/core/Objects/Filters/Scheduled.vala index a12045820..8046be78a 100644 --- a/core/Objects/Filters/Scheduled.vala +++ b/core/Objects/Filters/Scheduled.vala @@ -33,7 +33,7 @@ public class Objects.Filters.Scheduled : Objects.BaseObject { public int scheduled_count { get { if (_scheduled_count == null) { - _scheduled_count = Services.Database.get_default ().get_items_by_scheduled (false).size; + _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; } return _scheduled_count; @@ -52,28 +52,28 @@ public class Objects.Filters.Scheduled : Objects.BaseObject { icon_name = "month-symbolic"; view_id = FilterType.SCHEDULED.to_string (); - Services.Database.get_default ().item_added.connect (() => { - _scheduled_count = Services.Database.get_default ().get_items_by_scheduled (false).size; + Services.Store.instance ().item_added.connect (() => { + _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; scheduled_count_updated (); }); - Services.Database.get_default ().item_deleted.connect (() => { - _scheduled_count = Services.Database.get_default ().get_items_by_scheduled (false).size; + Services.Store.instance ().item_deleted.connect (() => { + _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; scheduled_count_updated (); }); - Services.Database.get_default ().item_updated.connect (() => { - _scheduled_count = Services.Database.get_default ().get_items_by_scheduled (false).size; + Services.Store.instance ().item_updated.connect (() => { + _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; scheduled_count_updated (); }); - Services.Database.get_default ().item_archived.connect (() => { - _scheduled_count = Services.Database.get_default ().get_items_by_scheduled (false).size; + Services.Store.instance ().item_archived.connect (() => { + _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; scheduled_count_updated (); }); - Services.Database.get_default ().item_unarchived.connect (() => { - _scheduled_count = Services.Database.get_default ().get_items_by_scheduled (false).size; + Services.Store.instance ().item_unarchived.connect (() => { + _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; scheduled_count_updated (); }); } diff --git a/core/Objects/Filters/Today.vala b/core/Objects/Filters/Today.vala index 30ed731af..97099e3a3 100644 --- a/core/Objects/Filters/Today.vala +++ b/core/Objects/Filters/Today.vala @@ -33,7 +33,7 @@ public class Objects.Filters.Today : Objects.BaseObject { public int today_count { get { if (_today_count == null) { - _today_count = Services.Database.get_default ().get_items_by_date ( + _today_count = Services.Store.instance ().get_items_by_date ( new GLib.DateTime.now_local (), false).size; } @@ -49,7 +49,7 @@ public class Objects.Filters.Today : Objects.BaseObject { public int overdeue_count { get { if (_overdeue_count == null) { - _overdeue_count = Services.Database.get_default ().get_items_by_overdeue_view (false).size; + _overdeue_count = Services.Store.instance ().get_items_by_overdeue_view (false).size; } return _overdeue_count; @@ -68,38 +68,38 @@ public class Objects.Filters.Today : Objects.BaseObject { icon_name = "star-outline-thick-symbolic"; view_id = FilterType.TODAY.to_string (); - Services.Database.get_default ().item_added.connect (() => { - _today_count = Services.Database.get_default ().get_items_by_date ( + Services.Store.instance ().item_added.connect (() => { + _today_count = Services.Store.instance ().get_items_by_date ( new GLib.DateTime.now_local (), false).size; - _overdeue_count = Services.Database.get_default ().get_items_by_overdeue_view (false).size; + _overdeue_count = Services.Store.instance ().get_items_by_overdeue_view (false).size; today_count_updated (); }); - Services.Database.get_default ().item_deleted.connect (() => { - _today_count = Services.Database.get_default ().get_items_by_date ( + Services.Store.instance ().item_deleted.connect (() => { + _today_count = Services.Store.instance ().get_items_by_date ( new GLib.DateTime.now_local (), false).size; - _overdeue_count = Services.Database.get_default ().get_items_by_overdeue_view (false).size; + _overdeue_count = Services.Store.instance ().get_items_by_overdeue_view (false).size; today_count_updated (); }); - Services.Database.get_default ().item_archived.connect (() => { - _today_count = Services.Database.get_default ().get_items_by_date ( + Services.Store.instance ().item_archived.connect (() => { + _today_count = Services.Store.instance ().get_items_by_date ( new GLib.DateTime.now_local (), false).size; - _overdeue_count = Services.Database.get_default ().get_items_by_overdeue_view (false).size; + _overdeue_count = Services.Store.instance ().get_items_by_overdeue_view (false).size; today_count_updated (); }); - Services.Database.get_default ().item_unarchived.connect (() => { - _today_count = Services.Database.get_default ().get_items_by_date ( + Services.Store.instance ().item_unarchived.connect (() => { + _today_count = Services.Store.instance ().get_items_by_date ( new GLib.DateTime.now_local (), false).size; - _overdeue_count = Services.Database.get_default ().get_items_by_overdeue_view (false).size; + _overdeue_count = Services.Store.instance ().get_items_by_overdeue_view (false).size; today_count_updated (); }); - Services.Database.get_default ().item_updated.connect (() => { - _today_count = Services.Database.get_default ().get_items_by_date ( + Services.Store.instance ().item_updated.connect (() => { + _today_count = Services.Store.instance ().get_items_by_date ( new GLib.DateTime.now_local (), false).size; - _overdeue_count = Services.Database.get_default ().get_items_by_overdeue_view (false).size; + _overdeue_count = Services.Store.instance ().get_items_by_overdeue_view (false).size; today_count_updated (); }); } diff --git a/core/Objects/Item.vala b/core/Objects/Item.vala index 8230d2a76..0dea6a1e3 100644 --- a/core/Objects/Item.vala +++ b/core/Objects/Item.vala @@ -155,13 +155,13 @@ public class Objects.Item : Objects.BaseObject { public bool has_parent { get { - return Services.Database.get_default ().get_item (parent_id) != null; + return Services.Store.instance ().get_item (parent_id) != null; } } public bool has_section { get { - return Services.Database.get_default ().get_section (section_id) != null; + return Services.Store.instance ().get_section (section_id) != null; } } @@ -223,7 +223,7 @@ public class Objects.Item : Objects.BaseObject { Objects.Item? _parent; public Objects.Item parent { get { - _parent = Services.Database.get_default ().get_item (parent_id); + _parent = Services.Store.instance ().get_item (parent_id); return _parent; } } @@ -231,7 +231,7 @@ public class Objects.Item : Objects.BaseObject { Objects.Project? _project; public Objects.Project project { get { - _project = Services.Database.get_default ().get_project (project_id); + _project = Services.Store.instance ().get_project (project_id); return _project; } } @@ -239,7 +239,7 @@ public class Objects.Item : Objects.BaseObject { Objects.Section? _section; public Objects.Section section { get { - _section = Services.Database.get_default ().get_section (section_id); + _section = Services.Store.instance ().get_section (section_id); return _section; } } @@ -247,7 +247,7 @@ public class Objects.Item : Objects.BaseObject { Gee.ArrayList _items; public Gee.ArrayList items { get { - _items = Services.Database.get_default ().get_subitems (this); + _items = Services.Store.instance ().get_subitems (this); _items.sort ((a, b) => { if (a.child_order > b.child_order) { return 1; @@ -264,7 +264,7 @@ public class Objects.Item : Objects.BaseObject { Gee.ArrayList _reminders; public Gee.ArrayList reminders { get { - _reminders = Services.Database.get_default ().get_reminders_by_item (this); + _reminders = Services.Store.instance ().get_reminders_by_item (this); return _reminders; } } @@ -273,7 +273,7 @@ public class Objects.Item : Objects.BaseObject { public Gee.ArrayList attachments { get { if (_attachments == null) { - _attachments = Services.Database.get_default ().get_attachments_by_item (this); + _attachments = Services.Store.instance ().get_attachments_by_item (this); } return _attachments; @@ -293,7 +293,7 @@ public class Objects.Item : Objects.BaseObject { construct { deleted.connect (() => { Idle.add (() => { - Services.Database.get_default ().item_deleted (this); + Services.Store.instance ().item_deleted (this); return false; }); }); @@ -573,7 +573,7 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { // TODO: VERIFICAR CALDAV - Objects.Label label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); + Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); if (label != null) { return_value.add (label); } @@ -599,7 +599,7 @@ public class Objects.Item : Objects.BaseObject { public Gee.ArrayList get_labels_from_json (Json.Node node) { Gee.ArrayList return_value = new Gee.ArrayList (); foreach (unowned Json.Node element in node.get_object ().get_array_member ("labels").get_elements ()) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (element.get_string (), true, project.source_id); + Objects.Label label = Services.Store.instance ().get_label_by_name (element.get_string (), true, project.source_id); return_value.add (label); } return return_value; @@ -627,7 +627,7 @@ public class Objects.Item : Objects.BaseObject { public Gee.HashMap get_labels_maps_from_json (Json.Node node) { Gee.HashMap return_value = new Gee.HashMap (); foreach (unowned Json.Node element in node.get_object ().get_array_member ("labels").get_elements ()) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (element.get_string (), true, project.source_id); + Objects.Label label = Services.Store.instance ().get_label_by_name (element.get_string (), true, project.source_id); return_value [label.id] = label; } return return_value; @@ -638,7 +638,7 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); + Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); if (label != null) { return_value [label.id] = label; } else { @@ -647,9 +647,9 @@ public class Objects.Item : Objects.BaseObject { label.color = Util.get_default ().get_random_color (); label.name = category; label.backend_type = BackendType.CALDAV; - if (Services.Database.get_default ().insert_label (label)) { - return_value [label.id] = label; - } + + Services.Store.instance ().insert_label (label); + return_value [label.id] = label; } } @@ -707,7 +707,7 @@ public class Objects.Item : Objects.BaseObject { } public void update_local () { - Services.Database.get_default ().update_item (this, ""); + Services.Store.instance ().update_item (this, ""); } public void update (string update_id = "") { @@ -719,18 +719,18 @@ public class Objects.Item : Objects.BaseObject { update_timeout_id = 0; if (project.backend_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); } else if (project.backend_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); }); } else if (project.backend_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (this, true, (obj, res) => { HttpResponse response = Services.CalDAV.Core.get_default ().add_task.end (res); if (response.status) { - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); } }); } @@ -749,12 +749,12 @@ public class Objects.Item : Objects.BaseObject { loading = true; if (project.backend_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); loading = false; } else if (project.backend_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); loading = false; }); } else if (project.backend_type == BackendType.CALDAV) { @@ -762,7 +762,7 @@ public class Objects.Item : Objects.BaseObject { HttpResponse response = Services.CalDAV.Core.get_default ().add_task.end (res); if (response.status) { - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); } loading = false; @@ -777,12 +777,12 @@ public class Objects.Item : Objects.BaseObject { loading = true; if (project.backend_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); loading = false; } else if (project.backend_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); loading = false; }); } else if (project.backend_type == BackendType.CALDAV) { @@ -790,7 +790,7 @@ public class Objects.Item : Objects.BaseObject { HttpResponse response = Services.CalDAV.Core.get_default ().add_task.end (res); if (response.status) { - Services.Database.get_default ().update_item (this, update_id); + Services.Store.instance ().update_item (this, update_id); } loading = false; @@ -804,7 +804,7 @@ public class Objects.Item : Objects.BaseObject { return_value = get_reminder (reminder); if (return_value == null) { if (insert_db) { - Services.Database.get_default ().insert_reminder (reminder); + Services.Store.instance ().insert_reminder (reminder); } else { reminder_added (reminder); } @@ -837,7 +837,7 @@ public class Objects.Item : Objects.BaseObject { lock (_attachments) { return_value = get_attachment (attachment); if (return_value == null) { - Services.Database.get_default ().insert_attachment (attachment); + Services.Store.instance ().insert_attachment (attachment); add_attachment (attachment); } @@ -869,7 +869,7 @@ public class Objects.Item : Objects.BaseObject { return_value = get_label (label.id); if (return_value == null) { return_value = label; - Services.Database.get_default ().item_label_added (return_value); + Services.Store.instance ().item_label_added (return_value); add_item_label (return_value); } @@ -915,7 +915,7 @@ public class Objects.Item : Objects.BaseObject { return_value = get_label (id); if (return_value != null) { - Services.Database.get_default ().item_label_deleted (return_value); + Services.Store.instance ().item_label_deleted (return_value); item_label_deleted (return_value); labels.remove (return_value); @@ -1295,7 +1295,7 @@ public class Objects.Item : Objects.BaseObject { if (return_value == null) { new_item.set_parent (this); add_item (new_item); - Services.Database.get_default ().insert_item (new_item, insert); + Services.Store.instance ().insert_item (new_item, insert); return_value = new_item; } return return_value; @@ -1360,12 +1360,12 @@ public class Objects.Item : Objects.BaseObject { public void delete_item () { if (project.backend_type == BackendType.LOCAL) { - Services.Database.get_default ().delete_item (this); + Services.Store.instance ().delete_item (this); } else if (project.backend_type == BackendType.TODOIST) { loading = true; Services.Todoist.get_default ().delete.begin (this, (obj, res) => { if (Services.Todoist.get_default ().delete.end (res).status) { - Services.Database.get_default ().delete_item (this); + Services.Store.instance ().delete_item (this); } loading = false; @@ -1374,7 +1374,7 @@ public class Objects.Item : Objects.BaseObject { loading = true; Services.CalDAV.Core.get_default ().delete_task.begin (this, (obj, res) => { if (Services.CalDAV.Core.get_default ().delete_task.end (res).status) { - Services.Database.get_default ().delete_item (this); + Services.Store.instance ().delete_item (this); foreach (Objects.Item subitem in this.items) { subitem.delete_item (); } @@ -1467,7 +1467,7 @@ public class Objects.Item : Objects.BaseObject { } if (project.backend_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (this); + Services.Store.instance ().update_item (this); promise.resolve (next_recurrency); } else if (project.backend_type == BackendType.TODOIST) { loading = true; @@ -1476,7 +1476,7 @@ public class Objects.Item : Objects.BaseObject { loading = false; if (response.status) { - Services.Database.get_default ().update_item (this); + Services.Store.instance ().update_item (this); promise.resolve (next_recurrency); } }); @@ -1487,7 +1487,7 @@ public class Objects.Item : Objects.BaseObject { loading = false; if (response.status) { - Services.Database.get_default ().update_item (this); + Services.Store.instance ().update_item (this); promise.resolve (next_recurrency); } }); @@ -1539,7 +1539,7 @@ public class Objects.Item : Objects.BaseObject { this.section_id = _section_id; this.parent_id = ""; - Services.Database.get_default ().move_item (this); + Services.Store.instance ().move_item (this); Services.EventBus.get_default ().item_moved (this, old_project_id, old_section_id, old_parent_id); Services.EventBus.get_default ().drag_n_drop_active (old_project_id, false); Services.EventBus.get_default ().send_notification ( @@ -1624,8 +1624,8 @@ public class Objects.Item : Objects.BaseObject { } public void add_reminder_events (Objects.Reminder reminder) { - Services.Database.get_default ().reminder_added (reminder); - Services.Database.get_default ().reminders.add (reminder); + Services.Store.instance ().reminder_added (reminder); + Services.Store.instance ().reminders.add (reminder); reminder.item.reminder_added (reminder); _add_reminder (reminder); } diff --git a/core/Objects/Label.vala b/core/Objects/Label.vala index 2fc059e42..23dd8fc5b 100644 --- a/core/Objects/Label.vala +++ b/core/Objects/Label.vala @@ -55,40 +55,40 @@ public class Objects.Label : Objects.BaseObject { construct { deleted.connect (() => { Idle.add (() => { - Services.Database.get_default ().label_deleted (this); + Services.Store.instance ().label_deleted (this); return false; }); }); - Services.Database.get_default ().item_added.connect ((item) => { + Services.Store.instance ().item_added.connect ((item) => { if (item.get_label (id) != null) { _label_count = update_label_count (); label_count_updated (); } }); - Services.Database.get_default ().item_deleted.connect ((item) => { + Services.Store.instance ().item_deleted.connect ((item) => { if (item.get_label (id) != null) { _label_count = update_label_count (); label_count_updated (); } }); - Services.Database.get_default ().item_updated.connect ((item) => { + Services.Store.instance ().item_updated.connect ((item) => { if (item.get_label (id) != null) { _label_count = update_label_count (); label_count_updated (); } }); - Services.Database.get_default ().item_label_added.connect ((label) => { + Services.Store.instance ().item_label_added.connect ((label) => { if (label.id == id) { _label_count = update_label_count (); label_count_updated (); } }); - Services.Database.get_default ().item_label_deleted.connect ((label) => { + Services.Store.instance ().item_label_deleted.connect ((label) => { if (label.id == id) { _label_count = update_label_count (); label_count_updated (); @@ -97,7 +97,7 @@ public class Objects.Label : Objects.BaseObject { } private int update_label_count () { - return Services.Database.get_default ().get_items_by_label (this, false).size; + return Services.Store.instance ().get_items_by_label (this, false).size; } public Label.from_json (Json.Node node) { diff --git a/core/Objects/ObjectEvent.vala b/core/Objects/ObjectEvent.vala index 52d166185..7642d1373 100644 --- a/core/Objects/ObjectEvent.vala +++ b/core/Objects/ObjectEvent.vala @@ -102,7 +102,7 @@ public class Objects.ObjectEvent : GLib.Object { public string get_labels_value (string value) { string return_value = ""; - Gee.ArrayList labels = Services.Database.get_default ().get_labels_by_item_labels (value); + Gee.ArrayList labels = Services.Store.instance ().get_labels_by_item_labels (value); if (labels.size > 0) { for (int index = 0; index < labels.size; index++) { diff --git a/core/Objects/Project.vala b/core/Objects/Project.vala index 5c5a53092..5bc4af5e2 100644 --- a/core/Objects/Project.vala +++ b/core/Objects/Project.vala @@ -59,7 +59,7 @@ public class Objects.Project : Objects.BaseObject { Objects.Source? _source; public Objects.Source source { get { - _source = Services.Database.get_default ().get_source (source_id); + _source = Services.Store.instance ().get_source (source_id); return _source; } } @@ -131,7 +131,7 @@ public class Objects.Project : Objects.BaseObject { Gee.ArrayList _sections; public Gee.ArrayList sections { get { - _sections = Services.Database.get_default ().get_sections_by_project (this); + _sections = Services.Store.instance ().get_sections_by_project (this); return _sections; } } @@ -139,7 +139,7 @@ public class Objects.Project : Objects.BaseObject { Gee.ArrayList _sections_archived; public Gee.ArrayList sections_archived { get { - _sections_archived = Services.Database.get_default ().get_sections_archived_by_project (this); + _sections_archived = Services.Store.instance ().get_sections_archived_by_project (this); return _sections_archived; } } @@ -147,7 +147,7 @@ public class Objects.Project : Objects.BaseObject { Gee.ArrayList _items; public Gee.ArrayList items { get { - _items = Services.Database.get_default ().get_item_by_baseobject (this); + _items = Services.Store.instance ().get_item_by_baseobject (this); _items.sort ((a, b) => { if (a.child_order > b.child_order) { return 1; @@ -165,7 +165,7 @@ public class Objects.Project : Objects.BaseObject { Gee.ArrayList _all_items; public Gee.ArrayList all_items { get { - _all_items = Services.Database.get_default ().get_items_by_project (this); + _all_items = Services.Store.instance ().get_items_by_project (this); return _all_items; } } @@ -173,7 +173,7 @@ public class Objects.Project : Objects.BaseObject { Gee.ArrayList _items_checked; public Gee.ArrayList items_checked { get { - _items_checked = Services.Database.get_default ().get_items_checked_by_project (this); + _items_checked = Services.Store.instance ().get_items_checked_by_project (this); return _items_checked; } } @@ -181,7 +181,7 @@ public class Objects.Project : Objects.BaseObject { Gee.ArrayList _subprojects; public Gee.ArrayList subprojects { get { - _subprojects = Services.Database.get_default ().get_subprojects (this); + _subprojects = Services.Store.instance ().get_subprojects (this); return _subprojects; } } @@ -189,7 +189,7 @@ public class Objects.Project : Objects.BaseObject { Objects.Project? _parent; public Objects.Project parent { get { - _parent = Services.Database.get_default ().get_project (parent_id); + _parent = Services.Store.instance ().get_project (parent_id); return _parent; } } @@ -253,7 +253,7 @@ public class Objects.Project : Objects.BaseObject { construct { deleted.connect (() => { Idle.add (() => { - Services.Database.get_default ().project_deleted (this); + Services.Store.instance ().project_deleted (this); return false; }); }); @@ -266,7 +266,7 @@ public class Objects.Project : Objects.BaseObject { } }); - Services.Database.get_default ().item_deleted.connect ((item) => { + Services.Store.instance ().item_deleted.connect ((item) => { if (item.project_id == id) { _project_count = update_project_count (); _percentage = update_percentage (); @@ -274,7 +274,7 @@ public class Objects.Project : Objects.BaseObject { } }); - Services.Database.get_default ().item_added.connect ((item) => { + Services.Store.instance ().item_added.connect ((item) => { if (item.project_id == id) { _project_count = update_project_count (); _percentage = update_percentage (); @@ -290,7 +290,7 @@ public class Objects.Project : Objects.BaseObject { } }); - Services.Database.get_default ().section_moved.connect ((section, old_project_id) => { + Services.Store.instance ().section_moved.connect ((section, old_project_id) => { if (section.project_id == id || old_project_id == id) { _project_count = update_project_count (); _percentage = update_percentage (); @@ -298,7 +298,7 @@ public class Objects.Project : Objects.BaseObject { } }); - Services.Database.get_default ().item_archived.connect ((item) => { + Services.Store.instance ().item_archived.connect ((item) => { if (item.project_id == id) { _project_count = update_project_count (); _percentage = update_percentage (); @@ -306,7 +306,7 @@ public class Objects.Project : Objects.BaseObject { } }); - Services.Database.get_default ().item_unarchived.connect ((item) => { + Services.Store.instance ().item_unarchived.connect ((item) => { if (item.project_id == id) { _project_count = update_project_count (); _percentage = update_percentage (); @@ -430,7 +430,7 @@ public class Objects.Project : Objects.BaseObject { } public void update_local () { - Services.Database.get_default ().update_project (this); + Services.Store.instance ().update_project (this); } public void update (bool use_timeout = true, bool show_loading = true) { @@ -447,7 +447,7 @@ public class Objects.Project : Objects.BaseObject { update_timeout_id = 0; if (backend_type == BackendType.LOCAL) { - Services.Database.get_default ().update_project (this); + Services.Store.instance ().update_project (this); } else if (backend_type == BackendType.TODOIST) { if (show_loading) { loading = true; @@ -455,7 +455,7 @@ public class Objects.Project : Objects.BaseObject { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); - Services.Database.get_default ().update_project (this); + Services.Store.instance ().update_project (this); loading = false; }); } else if (backend_type == BackendType.CALDAV) { @@ -465,7 +465,7 @@ public class Objects.Project : Objects.BaseObject { Services.CalDAV.Core.get_default ().update_tasklist.begin (this, (obj, res) => { Services.CalDAV.Core.get_default ().update_tasklist.end (res); - Services.Database.get_default ().update_project (this); + Services.Store.instance ().update_project (this); loading = false; }); } @@ -480,7 +480,7 @@ public class Objects.Project : Objects.BaseObject { return_value = get_subproject (new_project.id); if (return_value == null) { new_project.set_parent (this); - Services.Database.get_default ().insert_project (new_project); + Services.Store.instance ().insert_project (new_project); return_value = new_project; } return return_value; @@ -512,7 +512,7 @@ public class Objects.Project : Objects.BaseObject { new_section.set_project (this); new_section.section_order = new_section.project.sections.size; add_section (new_section); - Services.Database.get_default ().insert_section (new_section); + Services.Store.instance ().insert_section (new_section); return_value = new_section; } return return_value; @@ -546,7 +546,7 @@ public class Objects.Project : Objects.BaseObject { if (return_value == null) { new_item.set_project (this); add_item (new_item); - Services.Database.get_default ().insert_item (new_item, insert); + Services.Store.instance ().insert_item (new_item, insert); return_value = new_item; } return return_value; @@ -718,9 +718,10 @@ public class Objects.Project : Objects.BaseObject { SORT ORDER: %i COLLAPSED: %s PARENT ID: %s + SOURCE ID: %s --------------------------------- """.printf ( - id.to_string (), + id, name, description, color, @@ -736,13 +737,14 @@ public class Objects.Project : Objects.BaseObject { show_completed.to_string (), sort_order, collapsed.to_string (), - parent_id.to_string () + parent_id.to_string (), + source_id ); } private int update_project_count () { int returned = 0; - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_project (this)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_project (this)) { if (!item.checked && !item.was_archived ()) { returned++; } @@ -753,7 +755,7 @@ public class Objects.Project : Objects.BaseObject { public double update_percentage () { int items_total = 0; int items_checked = 0; - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_project (this)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_project (this)) { items_total++; if (!item.checked && !item.was_archived ()) { items_checked++; @@ -817,14 +819,14 @@ public class Objects.Project : Objects.BaseObject { if (response == "delete") { loading = true; if (source_type == BackendType.LOCAL) { - Services.Database.get_default ().delete_project (this); + Services.Store.instance ().delete_project (this); } else if (source_type == BackendType.TODOIST) { dialog.set_response_enabled ("cancel", false); dialog.set_response_enabled ("delete", false); Services.Todoist.get_default ().delete.begin (this, (obj, res) => { if (Services.Todoist.get_default ().delete.end (res).status) { - Services.Database.get_default ().delete_project (this); + Services.Store.instance ().delete_project (this); } loading = false; @@ -835,7 +837,7 @@ public class Objects.Project : Objects.BaseObject { Services.CalDAV.Core.get_default ().delete_tasklist.begin (this, (obj, res) => { if (Services.CalDAV.Core.get_default ().delete_tasklist.end (res)) { - Services.Database.get_default ().delete_project (this); + Services.Store.instance ().delete_project (this); } loading = false; @@ -860,14 +862,14 @@ public class Objects.Project : Objects.BaseObject { dialog.response.connect ((response) => { if (response == "archive") { is_archived = true; - Services.Database.get_default ().archive_project (this); + Services.Store.instance ().archive_project (this); } }); } public void unarchive_project () { is_archived = false; - Services.Database.get_default ().archive_project (this); + Services.Store.instance ().archive_project (this); } public Objects.Project duplicate () { diff --git a/core/Objects/Reminder.vala b/core/Objects/Reminder.vala index cd65e9561..fe97a84f1 100644 --- a/core/Objects/Reminder.vala +++ b/core/Objects/Reminder.vala @@ -31,7 +31,7 @@ public class Objects.Reminder : Objects.BaseObject { Objects.Item? _item; public Objects.Item item { get { - _item = Services.Database.get_default ().get_item (item_id); + _item = Services.Store.instance ().get_item (item_id); return _item; } @@ -82,7 +82,7 @@ public class Objects.Reminder : Objects.BaseObject { construct { deleted.connect (() => { - Services.Database.get_default ().reminder_deleted (this); + Services.Store.instance ().reminder_deleted (this); }); } @@ -152,12 +152,12 @@ public class Objects.Reminder : Objects.BaseObject { loading = true; Services.Todoist.get_default ().delete.begin (this, (obj, res) => { if (Services.Todoist.get_default ().delete.end (res).status) { - Services.Database.get_default ().delete_reminder (this); + Services.Store.instance ().delete_reminder (this); loading = false; } }); } else { - Services.Database.get_default ().delete_reminder (this); + Services.Store.instance ().delete_reminder (this); loading = false; } } diff --git a/core/Objects/Section.vala b/core/Objects/Section.vala index d5739ab9e..593366082 100644 --- a/core/Objects/Section.vala +++ b/core/Objects/Section.vala @@ -45,7 +45,7 @@ public class Objects.Section : Objects.BaseObject { Objects.Project? _project; public Objects.Project project { get { - _project = Services.Database.get_default ().get_project (project_id); + _project = Services.Store.instance ().get_project (project_id); return _project; } } @@ -53,7 +53,7 @@ public class Objects.Section : Objects.BaseObject { Gee.ArrayList _items; public Gee.ArrayList items { get { - _items = Services.Database.get_default ().get_item_by_baseobject (this); + _items = Services.Store.instance ().get_item_by_baseobject (this); _items.sort ((a, b) => { if (a.child_order > b.child_order) { return 1; @@ -89,7 +89,7 @@ public class Objects.Section : Objects.BaseObject { construct { deleted.connect (() => { Idle.add (() => { - Services.Database.get_default ().section_deleted (this); + Services.Store.instance ().section_deleted (this); return false; }); }); @@ -102,14 +102,14 @@ public class Objects.Section : Objects.BaseObject { } }); - Services.Database.get_default ().item_deleted.connect ((item) => { + Services.Store.instance ().item_deleted.connect ((item) => { if (item.section_id == id) { _section_count = update_section_count (); section_count_updated (); } }); - Services.Database.get_default ().item_added.connect ((item) => { + Services.Store.instance ().item_added.connect ((item) => { if (item.section_id == id) { _section_count = update_section_count (); section_count_updated (); @@ -159,7 +159,7 @@ public class Objects.Section : Objects.BaseObject { if (return_value == null) { new_item.set_section (this); add_item (new_item); - Services.Database.get_default ().insert_item (new_item, insert); + Services.Store.instance ().insert_item (new_item, insert); return_value = new_item; } return return_value; @@ -191,7 +191,7 @@ public class Objects.Section : Objects.BaseObject { update_timeout_id = Timeout.add (Constants.UPDATE_TIMEOUT, () => { update_timeout_id = 0; - Services.Database.get_default ().update_section (this); + Services.Store.instance ().update_section (this); if (project.backend_type == BackendType.TODOIST && cloud) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); @@ -314,7 +314,7 @@ public class Objects.Section : Objects.BaseObject { private int update_section_count () { int returned = 0; - foreach (Objects.Item item in Services.Database.get_default ().get_item_by_baseobject (this)) { + foreach (Objects.Item item in Services.Store.instance ().get_item_by_baseobject (this)) { if (!item.checked) { returned++; } @@ -348,10 +348,10 @@ public class Objects.Section : Objects.BaseObject { if (project.backend_type == BackendType.TODOIST) { Services.Todoist.get_default ().delete.begin (this, (obj, res) => { Services.Todoist.get_default ().delete.end (res); - Services.Database.get_default ().delete_section (this); + Services.Store.instance ().delete_section (this); }); } else { - Services.Database.get_default ().delete_section (this); + Services.Store.instance ().delete_section (this); } } }); @@ -372,14 +372,14 @@ public class Objects.Section : Objects.BaseObject { dialog.response.connect ((response) => { if (response == "archive") { is_archived = true; - Services.Database.get_default ().archive_section (this); + Services.Store.instance ().archive_section (this); } }); } public void unarchive_section () { is_archived = false; - Services.Database.get_default ().archive_section (this); + Services.Store.instance ().archive_section (this); } public bool was_archived () { diff --git a/core/Objects/Source.vala b/core/Objects/Source.vala index 717c8b661..a3f157d9d 100644 --- a/core/Objects/Source.vala +++ b/core/Objects/Source.vala @@ -28,7 +28,6 @@ public class Objects.Source : Objects.BaseObject { public bool sync_server { get; set; default = false; } public string last_sync { get; set; default = ""; } public Objects.SourceData data { get; set; } - public bool legacy { get; set; default = false; } Objects.SourceTodoistData _todoist_data; public Objects.SourceTodoistData todoist_data { @@ -38,36 +37,50 @@ public class Objects.Source : Objects.BaseObject { } } + Objects.SourceCalDAVData _caldav_data; + public Objects.SourceCalDAVData caldav_data { + get { + _caldav_data = data as Objects.SourceCalDAVData ; + return _caldav_data; + } + } + public string header_text { get { + if (source_type == BackendType.LOCAL) { + return _("On This Computer"); + } + if (source_type == BackendType.TODOIST) { return todoist_data.user_email; } - if (source_type == BackendType.LOCAL) { - return _("On This Computer"); + if (source_type == BackendType.CALDAV) { + return caldav_data.user_email; } return ""; } } - public string? subheader_text { + string _subheader_text; + public string subheader_text { get { if (source_type == BackendType.TODOIST) { return _("Todoist"); } - return null; + if (source_type == BackendType.CALDAV) { + _subheader_text = _("CalDAV - ") + caldav_data.caldav_type.title (); + return _subheader_text; + } + + return ""; } } public string avatar_path { get { - if (legacy) { - return "todoist-user"; - } - return todoist_data.user_image_id; } } @@ -80,7 +93,7 @@ public class Objects.Source : Objects.BaseObject { construct { deleted.connect (() => { Idle.add (() => { - Services.Database.get_default ().source_deleted (this); + Services.Store.instance ().source_deleted (this); return false; }); }); @@ -99,21 +112,8 @@ public class Objects.Source : Objects.BaseObject { } public void save () { - if (source_type == BackendType.TODOIST && legacy) { - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", todoist_data.sync_token); - Services.Settings.get_default ().settings.set_string ("todoist-last-sync", last_sync); - Services.Settings.get_default ().settings.set_string ("todoist-user-email", todoist_data.user_email); - Services.Settings.get_default ().settings.set_string ("todoist-user-name", todoist_data.user_name); - Services.Settings.get_default ().settings.set_string ("todoist-user-avatar", todoist_data.user_avatar); - Services.Settings.get_default ().settings.set_string ("todoist-user-image-id", todoist_data.user_image_id); - Services.Settings.get_default ().settings.set_boolean ("todoist-sync-server", sync_server); - Services.Settings.get_default ().settings.set_boolean ("todoist-user-is-premium", todoist_data.user_is_premium); - return; - } - - if (source_type == BackendType.TODOIST && !legacy) { - - } + updated_at = new GLib.DateTime.now_local ().to_string (); + Services.Store.instance ().update_source (this); } public void delete_source (Gtk.Window window) { @@ -129,45 +129,24 @@ public class Objects.Source : Objects.BaseObject { dialog.present (window); dialog.response.connect ((response) => { - if (response == "delete") { - if (legacy) { - _delete_source (); - return; - } - - Services.Database.get_default ().delete_source (this); + if (response == "delete") { + Services.Store.instance ().delete_source (this); } }); } - private void _delete_source () { - Services.Settings.get_default ().settings.set_string ("todoist-sync-token", ""); - Services.Settings.get_default ().settings.set_string ("todoist-access-token", ""); - Services.Settings.get_default ().settings.set_string ("todoist-last-sync", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-email", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-name", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-avatar", ""); - Services.Settings.get_default ().settings.set_string ("todoist-user-image-id", ""); - Services.Settings.get_default ().settings.set_boolean ("todoist-sync-server", false); - Services.Settings.get_default ().settings.set_boolean ("todoist-user-is-premium", false); - - // Delete all projects, sections and items - foreach (var project in Services.Database.get_default ().get_projects_by_source (id)) { - Services.Database.get_default ().delete_project (project); - } - - // Delete all labels; - // foreach (var label in Services.Database.get_default ().get_all_labels_by_todoist ()) { - // Services.Database.get_default ().delete_label (label); - // } - - // Clear Queue - Services.Database.get_default ().clear_queue (); - - // Clear CurTempIds - Services.Database.get_default ().clear_cur_temp_ids (); - - deleted (); + public string to_string () { + return """ + _________________________________ + ID: %s + DATA: %s + TYPE: %s + --------------------------------- + """.printf ( + id, + data.to_json (), + source_type.to_string () + ); } } @@ -268,6 +247,82 @@ public class Objects.SourceTodoistData : Objects.SourceData { Json.Node root = builder.get_root (); generator.set_root (root); + return generator.to_data (null); + } +} + +public class Objects.SourceCalDAVData : Objects.SourceData { + public string server_url { get; set; default = ""; } + public string username { get; set; default = ""; } + public string credentials { get; set; default = ""; } + public string user_displayname { get; set; default = ""; } + public string user_email { get; set; default = ""; } + public CalDAVType caldav_type { get; set; default = CalDAVType.NEXTCLOUD; } + + public SourceCalDAVData.from_json (string json) { + Json.Parser parser = new Json.Parser (); + + try { + parser.load_from_data (json, -1); + var object = parser.get_root ().get_object (); + + if (object.has_member ("server_url")) { + server_url = object.get_string_member ("server_url"); + } + + if (object.has_member ("username")) { + username = object.get_string_member ("username"); + } + + if (object.has_member ("credentials")) { + credentials = object.get_string_member ("credentials"); + } + + if (object.has_member ("user_displayname")) { + user_displayname = object.get_string_member ("user_displayname"); + } + + if (object.has_member ("user_email")) { + user_email = object.get_string_member ("user_email"); + } + + if (object.has_member ("caldav_type")) { + caldav_type = CalDAVType.parse (object.get_string_member ("caldav_type")); + } + } catch (Error e) { + debug (e.message); + } + } + + public override string to_json () { + builder.reset (); + + builder.begin_object (); + + builder.set_member_name ("server_url"); + builder.add_string_value (server_url); + + builder.set_member_name ("username"); + builder.add_string_value (username); + + builder.set_member_name ("credentials"); + builder.add_string_value (credentials); + + builder.set_member_name ("caldav_type"); + builder.add_string_value (caldav_type.to_string ()); + + builder.set_member_name ("user_displayname"); + builder.add_string_value (user_displayname); + + builder.set_member_name ("user_email"); + builder.add_string_value (user_email); + + builder.end_object (); + + Json.Generator generator = new Json.Generator (); + Json.Node root = builder.get_root (); + generator.set_root (root); + return generator.to_data (null); } } \ No newline at end of file diff --git a/core/QuickAdd.vala b/core/QuickAdd.vala index 512e3037f..abdd5ee3e 100644 --- a/core/QuickAdd.vala +++ b/core/QuickAdd.vala @@ -47,7 +47,7 @@ public class Layouts.QuickAdd : Adw.Bin { if (is_window_quick_add && Services.Settings.get_default ().settings.get_boolean ("quick-add-save-last-project")) { - var project = Services.Database.get_default ().get_project (Services.Settings.get_default ().settings.get_string ("quick-add-project-selected")); + var project = Services.Store.instance ().get_project (Services.Settings.get_default ().settings.get_string ("quick-add-project-selected")); if (project != null) { item.project_id = project.id; @@ -229,7 +229,7 @@ public class Layouts.QuickAdd : Adw.Bin { child = window; Timeout.add (225, () => { - if (Services.Database.get_default ().is_database_empty ()) { + if (Services.Store.instance ().is_database_empty ()) { main_stack.visible_child_name = "warning"; } else { main_stack.visible_child_name = "main"; diff --git a/core/Services/CalDAV/Core.vala b/core/Services/CalDAV/Core.vala index 574c45381..208f99711 100644 --- a/core/Services/CalDAV/Core.vala +++ b/core/Services/CalDAV/Core.vala @@ -43,6 +43,7 @@ public class Services.CalDAV.Core : GLib.Object { public signal void log_in (); private uint server_timeout = 0; + private Gee.HashMap request_map; // vala-lint=naming-convention public static string USER_PRINCIPAL_REQUEST = """ @@ -303,6 +304,10 @@ public class Services.CalDAV.Core : GLib.Object { sync_async (); } }); + + request_map = new Gee.HashMap (); + request_map.set (CalDAVType.NEXTCLOUD.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); + request_map.set (CalDAVType.RADICALE.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); } public void run_server () { @@ -317,35 +322,72 @@ public class Services.CalDAV.Core : GLib.Object { }); } - public async HttpResponse login (string server_url, string username, string password, GLib.Cancellable cancellable) { - var url = "%s/remote.php/dav/".printf (server_url); + public string get_request_data (CalDAVType caldav_type, string method) { + if (request_map.has_key (caldav_type.to_string () + method)) { + return request_map[caldav_type.to_string () + method]; + } + + return ""; + } + + public async HttpResponse login (CalDAVType caldav_type, string server_url, string username, string password, GLib.Cancellable cancellable) { + HttpResponse response = new HttpResponse (); + string _server_url = ""; + + try { + var uri = GLib.Uri.parse (server_url, GLib.UriFlags.NONE); + + if (caldav_type == CalDAVType.NEXTCLOUD) { + _server_url = "%s://%s".printf (uri.get_scheme (), uri.get_host ()); + } else if (caldav_type == CalDAVType.RADICALE) { + _server_url = uri.get_host (); + } + } catch (Error e) { + response.error_code = e.code; + response.error = e.message; + return response; + } + + string url = Services.CalDAV.Backend.generate_server_url (caldav_type, _server_url, username, GLib.Uri.escape_string (password)); + print ("Server URL: %s\n".printf (url)); + string credentials = "%s:%s".printf (username, password); string base64_credentials = Base64.encode (credentials.data); var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (base64_credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes (USER_PRINCIPAL_REQUEST.data)); - - HttpResponse response = new HttpResponse (); + message.set_request_body_from_bytes ("application/xml", new Bytes (get_request_data (caldav_type, "login").data)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, cancellable); - print_root ("login", (string) stream.get_data ()); + // print_root ("login", (string) stream.get_data ()); + // print ("login status_code: %s\n".printf (message.status_code.to_string ())); if (message.status_code == 207) { - Services.Settings.get_default ().settings.set_string ("caldav-server-url", server_url); - Services.Settings.get_default ().settings.set_string ("caldav-username", username); - - yield Secret.password_storev (schema, get_attributes (), Secret.COLLECTION_DEFAULT, username, password, cancellable); + var source = new Objects.Source (); + source.id = Util.get_default ().generate_id (); + source.source_type = BackendType.CALDAV; + Objects.SourceCalDAVData caldav_data = new Objects.SourceCalDAVData (); + caldav_data.server_url = url; + caldav_data.username = username; + caldav_data.caldav_type = caldav_type; + caldav_data.credentials = base64_credentials; + + source.data = caldav_data; + + GLib.Value _data_object = Value (typeof (Objects.Source)); + _data_object.set_object (source); + + response.data_object = _data_object; response.status = true; } else { response.error_code = (int) message.status_code; response.error = (string) stream.get_data (); } } catch (Error e) { - debug (e.message); + print ("login error: %s".printf (e.message)); response.error_code = e.code; response.error = e.message; } @@ -353,56 +395,54 @@ public class Services.CalDAV.Core : GLib.Object { return response; } - public async void first_sync () { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/principals/users/%s/".printf (server_url, username); + public async void add_caldav_account (Objects.Source source) { + var url = "%s/principals/users/%s/".printf (source.caldav_data.server_url, source.caldav_data.username); var message = new Soup.Message ("PROPFIND", url); + message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes (USER_DATA_REQUEST.data)); - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (USER_DATA_REQUEST.data)); - first_sync_started (); + first_sync_started (); + try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - print_root ("first_sync", (string) stream.get_data ()); + // print_root ("first_sync", (string) stream.get_data ()); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); GXml.DomElement d_displayname = doc.get_elements_by_tag_name ("d:displayname").get_element (0); GXml.DomElement d_email = doc.get_elements_by_tag_name ("s:email-address").get_element (0); - Services.Settings.get_default ().settings.set_string ("caldav-user-displayname", d_displayname.text_content); - Services.Settings.get_default ().settings.set_string ("caldav-user-email", d_email.text_content); + source.caldav_data.user_displayname = d_displayname.text_content; + source.caldav_data.user_email = d_email.text_content; + + print ("Source: %s\n".printf (source.to_string ())); + Services.Store.instance ().insert_source (source); - yield get_all_tasklist (); + yield get_all_tasklist (source); } catch (Error e) { debug (e.message); } } - public async void get_all_tasklist () { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/".printf (server_url, username); + public async void get_all_tasklist (Objects.Source source) { + var url = "%s/calendars/%s/".printf (source.caldav_data.server_url, source.caldav_data.username); var message = new Soup.Message ("PROPFIND", url); + message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - print_root ("get_all_tasklist", (string) stream.get_data ()); + // print_root ("get_all_tasklist", (string) stream.get_data ()); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); foreach (GXml.DomElement element in response) { if (is_vtodo_calendar (element)) { var project = new Objects.Project.from_caldav_xml (element); - Services.Database.get_default ().insert_project (project); + project.source_id = source.id; + + Services.Store.instance ().insert_project (project); yield get_all_tasks_by_tasklist (project); } } @@ -415,20 +455,21 @@ public class Services.CalDAV.Core : GLib.Object { } public async void get_all_tasks_by_tasklist (Objects.Project project) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/%s/".printf (server_url, username, project.id); + var url = "%s/calendars/%s/%s/".printf ( + project.source.caldav_data.server_url, + project.source.caldav_data.username, + project.id + ); + var message = new Soup.Message ("REPORT", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.request_headers.append ("Depth", "1"); + message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); try { - yield set_credential (message); - message.request_headers.append ("Depth", "1"); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - print_root ("get_all_tasks_by_tasklist", (string) stream.get_data ()); + // print_root ("get_all_tasks_by_tasklist", (string) stream.get_data ()); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); @@ -445,7 +486,7 @@ public class Services.CalDAV.Core : GLib.Object { label.name = category; label.color = Util.get_default ().get_random_color (); label.backend_type = BackendType.CALDAV; - Services.Database.get_default ().insert_label (label); + Services.Store.instance ().insert_label (label); } foreach (GXml.DomElement element in response) { @@ -500,20 +541,20 @@ public class Services.CalDAV.Core : GLib.Object { foreach (string category in labels_map.values) { // TODO: VERIFICAR CALDAV - var label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); + var label = Services.Store.instance ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); if (label == null) { label = new Objects.Label (); label.id = Util.get_default ().generate_id (label); label.name = category; label.color = Util.get_default ().get_random_color (); label.backend_type = BackendType.CALDAV; - Services.Database.get_default ().insert_label (label); + Services.Store.instance ().insert_label (label); } } Gee.HashMap items_map = new Gee.HashMap (); foreach (GXml.DomElement element in response) { - Objects.Item? item = Services.Database.get_default ().get_item ( + Objects.Item? item = Services.Store.instance ().get_item ( Util.get_task_uid (element) ); @@ -525,7 +566,7 @@ public class Services.CalDAV.Core : GLib.Object { item.update_from_caldav_xml (element); item.project_id = project.id; - Services.Database.get_default ().update_item (item); + Services.Store.instance ().update_item (item); if (old_project_id != item.project_id || old_parent_id != item.parent_id) { Services.EventBus.get_default ().item_moved (item, old_project_id, "", old_parent_id); @@ -533,7 +574,7 @@ public class Services.CalDAV.Core : GLib.Object { bool old_checked = item.checked; if (old_checked != item.checked) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } } else { item = add_item_if_not_exists (element, project); @@ -543,7 +584,7 @@ public class Services.CalDAV.Core : GLib.Object { foreach (Objects.Item item in project.all_items) { if (!items_map.has_key (item.id)) { - Services.Database.get_default ().delete_item (item); + Services.Store.instance ().delete_item (item); } } } catch (Error e) { @@ -556,7 +597,7 @@ public class Services.CalDAV.Core : GLib.Object { string parent_id = Util.get_related_to_uid (element); if (parent_id != "") { - Objects.Item? parent_item = Services.Database.get_default ().get_item (parent_id); + Objects.Item? parent_item = Services.Store.instance ().get_item (parent_id); if (parent_item != null) { return_value = new Objects.Item.from_caldav_xml (element); return_value.project_id = project.id; @@ -603,19 +644,19 @@ public class Services.CalDAV.Core : GLib.Object { foreach (GXml.DomElement element in response) { if (is_vtodo_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); + Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); if (project == null) { project = new Objects.Project.from_caldav_xml (element); - Services.Database.get_default ().insert_project (project); + Services.Store.instance ().insert_project (project); yield get_all_tasks_by_tasklist (project); } else { project.update_from_xml (element, false); - Services.Database.get_default ().update_project (project); + Services.Store.instance ().update_project (project); } } else if (is_deleted_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); + Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); if (project != null) { - Services.Database.get_default ().delete_project (project); + Services.Store.instance ().delete_project (project); } } } @@ -623,7 +664,7 @@ public class Services.CalDAV.Core : GLib.Object { debug (e.message); } - foreach (Objects.Project project in Services.Database.get_default ().get_all_projects_by_backend_type (BackendType.CALDAV)) { + foreach (Objects.Project project in Services.Store.instance ().get_all_projects_by_backend_type (BackendType.CALDAV)) { yield sync_tasklist (project); } @@ -658,9 +699,9 @@ public class Services.CalDAV.Core : GLib.Object { string ics = get_task_ics_from_url (element); if (status.length > 0 && status.get_element (0).text_content == "HTTP/1.1 404 Not Found") { - Objects.Item? item = Services.Database.get_default ().get_item_by_ics (ics); + Objects.Item? item = Services.Store.instance ().get_item_by_ics (ics); if (item != null) { - Services.Database.get_default ().delete_item (item); + Services.Store.instance ().delete_item (item); } } else { if (!is_vtodo (element)) { @@ -670,7 +711,7 @@ public class Services.CalDAV.Core : GLib.Object { string vtodo = yield get_vtodo_by_url (project.id, ics); ICal.Component ical = new ICal.Component.from_string (vtodo); - Objects.Item? item = Services.Database.get_default ().get_item (ical.get_uid ()); + Objects.Item? item = Services.Store.instance ().get_item (ical.get_uid ()); if (item != null) { string old_project_id = item.project_id; @@ -678,7 +719,7 @@ public class Services.CalDAV.Core : GLib.Object { item.update_from_vtodo (vtodo, ics); item.project_id = project.id; - Services.Database.get_default ().update_item (item); + Services.Store.instance ().update_item (item); if (old_project_id != item.project_id || old_parent_id != item.parent_id) { Services.EventBus.get_default ().item_moved (item, old_project_id, "", old_parent_id); @@ -686,12 +727,12 @@ public class Services.CalDAV.Core : GLib.Object { bool old_checked = item.checked; if (old_checked != item.checked) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } } else { string parent_id = Util.find_string_value ("RELATED-TO", vtodo); if (parent_id != "") { - Objects.Item? parent_item = Services.Database.get_default ().get_item (parent_id); + Objects.Item? parent_item = Services.Store.instance ().get_item (parent_id); if (parent_item != null) { var new_item = new Objects.Item.from_vtodo (vtodo, ics); new_item.project_id = project.id; @@ -743,20 +784,20 @@ public class Services.CalDAV.Core : GLib.Object { private async void add_project_if_not_exists (GXml.DomElement element, Gee.HashMap labels_map) { if (is_vtodo_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); + Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); if (project == null) { project = new Objects.Project.from_caldav_xml (element); - Services.Database.get_default ().insert_project (project); + Services.Store.instance ().insert_project (project); yield get_all_tasks_by_tasklist (project); } else { project.update_from_xml (element); - Services.Database.get_default ().update_project (project); + Services.Store.instance ().update_project (project); yield update_all_tasks_by_tasklist (project, labels_map); } } else if (is_deleted_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); + Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); if (project != null) { - Services.Database.get_default ().delete_project (project); + Services.Store.instance ().delete_project (project); } } } @@ -1056,13 +1097,13 @@ public class Services.CalDAV.Core : GLib.Object { Services.Settings.get_default ().settings.set_string ("caldav-user-displayname", ""); // Delete all projects, sections and items - foreach (var project in Services.Database.get_default ().get_all_projects_by_backend_type (BackendType.CALDAV)) { - Services.Database.get_default ().delete_project (project); + foreach (var project in Services.Store.instance ().get_all_projects_by_backend_type (BackendType.CALDAV)) { + Services.Store.instance ().delete_project (project); } // Delete all labels; - foreach (var label in Services.Database.get_default ().get_labels_by_backend_type (BackendType.CALDAV)) { - Services.Database.get_default ().delete_label (label); + foreach (var label in Services.Store.instance ().get_labels_by_backend_type (BackendType.CALDAV)) { + Services.Store.instance ().delete_label (label); } // Remove server_timeout diff --git a/core/Services/CalDAV/_Core.vala b/core/Services/CalDAV/_Core.vala deleted file mode 100644 index 031cbbfde..000000000 --- a/core/Services/CalDAV/_Core.vala +++ /dev/null @@ -1,1154 +0,0 @@ -/* -* Copyright © 2024 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.CalDAV.Core : GLib.Object { - private Soup.Session session; - private Json.Parser parser; - private Secret.Schema schema; - - private static Core? _instance; - public static Core get_default () { - if (_instance == null) { - _instance = new Core (); - } - - return _instance; - } - - public signal void first_sync_started (); - public signal void first_sync_finished (); - - public signal void sync_started (); - public signal void sync_finished (); - - public signal void log_out (); - public signal void log_in (); - - private uint server_timeout = 0; - private Gee.HashMap request_map; - - // vala-lint=naming-convention - public static string USER_DATA_REQUEST = """ - - - - - - - """; - - // vala-lint=naming-convention - public static string TASKLIST_REQUEST = """ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - """; - - // vala-lint=naming-convention - public static string CREATE_TASKLIST_REQUEST = """ - - - - - - - 0 - %s - %s - 1 - - - - - - - """; - - // vala-lint=naming-convention - public static string UPDATE_TASKLIST_REQUEST = """ - - - - %s - %s - - - - """; - - // vala-lint=naming-convention - public static string SYNC_TOKEN_REQUEST = """ - - %s - 1 - - - - - - """; - - // vala-lint=naming-convention - public static string TASKS_REQUEST = """ - - - - - - - - - - - - - - - - - - - - - - - """; - - public Core () { - session = new Soup.Session (); - parser = new Json.Parser (); - - schema = new Secret.Schema ("io.github.alainm23.planify", Secret.SchemaFlags.NONE, - "username", Secret.SchemaAttributeType.STRING, - "server_url", Secret.SchemaAttributeType.STRING - ); - - var network_monitor = GLib.NetworkMonitor.get_default (); - network_monitor.network_changed.connect (() => { - if (GLib.NetworkMonitor.get_default ().network_available && - is_logged_in () && - Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server")) { - sync_async (); - } - }); - - request_map = new Gee.HashMap (); - request_map.set (CalDAVType.NEXTCLOUD.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); - request_map.set (CalDAVType.RADICALE.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); - } - - public void run_server () { - sync_async (); - - server_timeout = Timeout.add_seconds (15 * 60, () => { - if (Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server")) { - sync_async (); - } - - return true; - }); - } - - public string get_request_data (CalDAVType caldav_type, string method) { - if (request_map.has_key (caldav_type.to_string () + method)) { - return request_map[caldav_type.to_string () + method]; - } - - return ""; - } - - public async HttpResponse login (CalDAVType caldav_type, string server_url, string username, string password, GLib.Cancellable cancellable) { - HttpResponse response = new HttpResponse (); - string _server_url = ""; - - try { - var uri = GLib.Uri.parse (server_url, GLib.UriFlags.NONE); - - if (caldav_type == CalDAVType.NEXTCLOUD) { - _server_url = "%s://%s".printf (uri.get_scheme (), uri.get_host ()); - } else if (caldav_type == CalDAVType.RADICALE) { - _server_url = uri.get_host (); - } - } catch (Error e) { - response.error_code = e.code; - response.error = e.message; - return response; - } - - string url = Services.CalDAV.Backend.generate_server_url (caldav_type, _server_url, username, GLib.Uri.escape_string (password)); - print ("Server URL: %s\n".printf (url)); - - string credentials = "%s:%s".printf (username, password); - string base64_credentials = Base64.encode (credentials.data); - - var message = new Soup.Message ("PROPFIND", url); - message.request_headers.append ("Authorization", "Basic %s".printf (base64_credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes (get_request_data (caldav_type, "login").data)); - - try { - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, cancellable); - - print_root ("login", (string) stream.get_data ()); - print ("login status_code: %s\n".printf (message.status_code.to_string ())); - - if (message.status_code == 207) { - Services.Settings.get_default ().settings.set_string ("caldav-server-url", url); - Services.Settings.get_default ().settings.set_string ("caldav-username", username); - Services.Settings.get_default ().settings.set_enum ("caldav-type", caldav_type); - - yield Secret.password_storev (schema, get_attributes (), Secret.COLLECTION_DEFAULT, username, password, cancellable); - - response.status = true; - } else { - response.error_code = (int) message.status_code; - response.error = (string) stream.get_data (); - } - } catch (Error e) { - print ("login error: %s".printf (e.message)); - response.error_code = e.code; - response.error = e.message; - } - - return response; - } - - public CalDAVType get_backend_type () { - return (CalDAVType) Services.Settings.get_default ().settings.get_enum ("caldav-type"); - } - - public async void first_sync () { - if (get_backend_type () == CalDAVType.NEXTCLOUD) { - string url = "%s/principals/users/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username") - ); - - var message = new Soup.Message ("PROPFIND", url); - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (USER_DATA_REQUEST.data)); - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("first_sync", (string) stream.get_data ()); - - GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomElement d_displayname = doc.get_elements_by_tag_name ("d:displayname").get_element (0); - GXml.DomElement d_email = doc.get_elements_by_tag_name ("s:email-address").get_element (0); - - Services.Settings.get_default ().settings.set_string ("caldav-user-displayname", d_displayname.text_content); - Services.Settings.get_default ().settings.set_string ("caldav-user-email", d_email.text_content); - - yield get_all_tasklist (); - } catch (Error e) { - debug (e.message); - } - } else { - yield get_all_tasklist (); - } - } - - public async void get_all_tasklist () { - var url = "%s/calendars/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username") - ); - - var message = new Soup.Message ("PROPFIND", url); - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("get_all_tasklist", (string) stream.get_data ()); - - GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - foreach (GXml.DomElement element in response) { - if (is_vtodo_calendar (element)) { - var project = new Objects.Project.from_caldav_xml (element); - Services.Database.get_default ().insert_project (project); - yield get_all_tasks_by_tasklist (project); - } - } - - first_sync_finished (); - log_in (); - } catch (Error e) { - debug (e.message); - } - } - - public async void get_all_tasks_by_tasklist (Objects.Project project) { - var url = "%s/calendars/%s/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project.id - ); - - var message = new Soup.Message ("REPORT", url); - - try { - yield set_credential (message); - message.request_headers.append ("Depth", "1"); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("get_all_tasks_by_tasklist", (string) stream.get_data ()); - - GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - - // Categories - Gee.HashMap labels_map = new Gee.HashMap (); - foreach (GXml.DomElement element in response) { - setup_categories (element, labels_map); - } - - foreach (string category in labels_map.values) { - var label = new Objects.Label (); - label.id = Util.get_default ().generate_id (label); - label.name = category; - label.color = Util.get_default ().get_random_color (); - label.backend_type = BackendType.CALDAV; - Services.Database.get_default ().insert_label (label); - } - - foreach (GXml.DomElement element in response) { - add_item_if_not_exists (element, project); - } - } catch (Error e) { - debug (e.message); - } - } - - private void setup_categories (GXml.DomElement element, Gee.HashMap labels_map) { - GXml.DomElement propstat = element.get_elements_by_tag_name ("d:propstat").get_element (0); - GXml.DomElement prop = propstat.get_elements_by_tag_name ("d:prop").get_element (0); - string data = prop.get_elements_by_tag_name ("cal:calendar-data").get_element (0).text_content; - - var categories = Util.find_string_value ("CATEGORIES", data); - if (categories != "") { - string _categories = categories.replace ("\\,", ";"); - string[] categories_list = _categories.split (","); - foreach (unowned string str in categories_list) { - string category = str.replace (";", ","); - - if (!labels_map.has_key (category)) { - labels_map.set (category, category); - } - } - } - } - - public async void update_all_tasks_by_tasklist (Objects.Project project, Gee.HashMap labels_map) { - var url = "%s/calendars/%s/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project.id - ); - var message = new Soup.Message ("REPORT", url); - - try { - yield set_credential (message); - message.request_headers.append ("Depth", "1"); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("update_all_tasks_by_tasklist", (string) stream.get_data ()); - - GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - - foreach (GXml.DomElement element in response) { - setup_categories (element, labels_map); - } - - foreach (string category in labels_map.values) { - var label = Services.Database.get_default ().get_label_by_name (category, true, BackendType.CALDAV); - if (label == null) { - label = new Objects.Label (); - label.id = Util.get_default ().generate_id (label); - label.name = category; - label.color = Util.get_default ().get_random_color (); - label.backend_type = BackendType.CALDAV; - Services.Database.get_default ().insert_label (label); - } - } - - Gee.HashMap items_map = new Gee.HashMap (); - foreach (GXml.DomElement element in response) { - Objects.Item? item = Services.Database.get_default ().get_item ( - Util.get_task_uid (element) - ); - - if (item != null) { - items_map.set (item.id, item); - - string old_project_id = item.project_id; - string old_parent_id = item.parent_id; - - item.update_from_caldav_xml (element); - item.project_id = project.id; - Services.Database.get_default ().update_item (item); - - if (old_project_id != item.project_id || old_parent_id != item.parent_id) { - Services.EventBus.get_default ().item_moved (item, old_project_id, "", old_parent_id); - } - - bool old_checked = item.checked; - if (old_checked != item.checked) { - Services.Database.get_default ().checked_toggled (item, old_checked); - } - } else { - item = add_item_if_not_exists (element, project); - items_map.set (item.id, item); - } - } - - foreach (Objects.Item item in project.all_items) { - if (!items_map.has_key (item.id)) { - Services.Database.get_default ().delete_item (item); - } - } - } catch (Error e) { - debug (e.message); - } - } - - private Objects.Item add_item_if_not_exists (GXml.DomElement element, Objects.Project project) { - Objects.Item return_value; - - string parent_id = Util.get_related_to_uid (element); - if (parent_id != "") { - Objects.Item? parent_item = Services.Database.get_default ().get_item (parent_id); - if (parent_item != null) { - return_value = new Objects.Item.from_caldav_xml (element); - return_value.project_id = project.id; - parent_item.add_item_if_not_exists (return_value); - } else { - return_value = new Objects.Item.from_caldav_xml (element); - return_value.project_id = project.id; - project.add_item_if_not_exists (return_value); - } - } else { - return_value = new Objects.Item.from_caldav_xml (element); - return_value.project_id = project.id; - project.add_item_if_not_exists (return_value); - } - - return return_value; - } - - public void sync_async () { - sync.begin ((obj, res) => { - sync.end (res); - }); - } - - private async void sync () { - sync_started (); - - var url = "%s/calendars/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username") - ); - var message = new Soup.Message ("PROPFIND", url); - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("sync", (string) stream.get_data ()); - - GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - - foreach (GXml.DomElement element in response) { - if (is_vtodo_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); - if (project == null) { - project = new Objects.Project.from_caldav_xml (element); - Services.Database.get_default ().insert_project (project); - yield get_all_tasks_by_tasklist (project); - } else { - project.update_from_xml (element, false); - Services.Database.get_default ().update_project (project); - } - } else if (is_deleted_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); - if (project != null) { - Services.Database.get_default ().delete_project (project); - } - } - } - } catch (Error e) { - debug (e.message); - } - - foreach (Objects.Project project in Services.Database.get_default ().get_all_projects_by_backend_type (BackendType.CALDAV)) { - yield sync_tasklist (project); - } - - Services.Settings.get_default ().settings.set_string ("caldav-last-sync", new GLib.DateTime.now_local ().to_string ()); - sync_finished (); - } - - public async void sync_tasklist (Objects.Project project) { - var url = "%s/calendars/%s/%s".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project.id - ); - - var message = new Soup.Message ("REPORT", url); - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((SYNC_TOKEN_REQUEST.printf (project.sync_id)).data)); - - if (project.sync_id == "") { - return; - } - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("sync_tasklist", (string) stream.get_data ()); - - GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - - foreach (GXml.DomElement element in response) { - GXml.DomHTMLCollection status = element.get_elements_by_tag_name ("d:status"); - string ics = get_task_ics_from_url (element); - bool is_vtodo = is_vtodo (element); - - if (!is_vtodo) { - continue; - } - - if (status.length > 0 && status.get_element (0).text_content == "HTTP/1.1 404 Not Found") { - Objects.Item? item = Services.Database.get_default ().get_item_by_ics (ics); - if (item != null) { - Services.Database.get_default ().delete_item (item); - } - } else { - string vtodo = yield get_vtodo_by_url (project.id, ics); - - ICal.Component ical = new ICal.Component.from_string (vtodo); - Objects.Item? item = Services.Database.get_default ().get_item (ical.get_uid ()); - - if (item != null) { - string old_project_id = item.project_id; - string old_parent_id = item.parent_id; - - item.update_from_vtodo (vtodo, ics); - item.project_id = project.id; - Services.Database.get_default ().update_item (item); - - if (old_project_id != item.project_id || old_parent_id != item.parent_id) { - Services.EventBus.get_default ().item_moved (item, old_project_id, "", old_parent_id); - } - - bool old_checked = item.checked; - if (old_checked != item.checked) { - Services.Database.get_default ().checked_toggled (item, old_checked); - } - } else { - string parent_id = Util.find_string_value ("RELATED-TO", vtodo); - if (parent_id != "") { - Objects.Item? parent_item = Services.Database.get_default ().get_item (parent_id); - if (parent_item != null) { - var new_item = new Objects.Item.from_vtodo (vtodo, ics); - new_item.project_id = project.id; - parent_item.add_item_if_not_exists (new_item); - } else { - var new_item = new Objects.Item.from_vtodo (vtodo, ics); - new_item.project_id = project.id; - project.add_item_if_not_exists (new_item); - } - } else { - var new_item = new Objects.Item.from_vtodo (vtodo, ics); - new_item.project_id = project.id; - project.add_item_if_not_exists (new_item); - } - } - } - } - - GXml.DomHTMLCollection sync_token = doc.get_elements_by_tag_name ("d:sync-token"); - if (sync_token.length > 0) { - project.sync_id = sync_token.get_element (0).text_content; - project.update_local (); - } - } catch (Error e) { - debug (e.message); - } - } - - private async string? get_vtodo_by_url (string tasklist_id, string task_ics) { - var url = "%s/calendars/%s/%s/%s".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - tasklist_id, - task_ics - ); - - var message = new Soup.Message ("GET", url); - string return_value = null; - - try { - yield set_credential (message); - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - print_root ("get_vtodo_by_url", (string) stream.get_data ()); - return_value = (string) stream.get_data (); - } catch (Error e) { - debug (e.message); - } - - return return_value; - } - - private async void add_project_if_not_exists (GXml.DomElement element, Gee.HashMap labels_map) { - if (is_vtodo_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); - if (project == null) { - project = new Objects.Project.from_caldav_xml (element); - Services.Database.get_default ().insert_project (project); - yield get_all_tasks_by_tasklist (project); - } else { - project.update_from_xml (element); - Services.Database.get_default ().update_project (project); - yield update_all_tasks_by_tasklist (project, labels_map); - } - } else if (is_deleted_calendar (element)) { - Objects.Project? project = Services.Database.get_default ().get_project (get_tasklist_id_from_url (element)); - if (project != null) { - Services.Database.get_default ().delete_project (project); - } - } - } - - public string get_tasklist_id_from_url (GXml.DomElement element) { - GXml.DomElement href = element.get_elements_by_tag_name ("d:href").get_element (0); - string[] parts = href.text_content.split ("/"); - return parts[parts.length - 2]; - } - - public string get_task_ics_from_url (GXml.DomElement element) { - GXml.DomElement href = element.get_elements_by_tag_name ("d:href").get_element (0); - string[] parts = href.text_content.split ("/"); - return parts[parts.length - 1]; - } - - public bool is_vtodo (GXml.DomElement element) { - GXml.DomHTMLCollection propstat = element.get_elements_by_tag_name ("d:propstat"); - - if (propstat.length <= 0) { - return false; - } - - GXml.DomHTMLCollection prop = propstat.get_element (0).get_elements_by_tag_name ("d:prop"); - - if (prop.length <= 0) { - return false; - } - - GXml.DomHTMLCollection getcontenttype = prop.get_element (0).get_elements_by_tag_name ("d:getcontenttype"); - - if (getcontenttype.length <= 0) { - return false; - } - - if (getcontenttype.get_element (0).text_content.index_of ("vtodo") > -1) { - return true; - } - - return false; - } - - /* - * Tasklist - */ - - public async bool add_tasklist (Objects.Project project) { - var url = "%s/calendars/%s/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project.id - ); - - var message = new Soup.Message ("MKCOL", url); - bool status = false; - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((CREATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); - - - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - status = true; - } catch (Error e) { - debug (e.message); - } - - return status; - } - - public async bool update_tasklist (Objects.Project project) { - var url = "%s/calendars/%s/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project.id - ); - - var message = new Soup.Message ("PROPPATCH", url); - bool status = false; - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((UPDATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); - - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - status = true; - } catch (Error e) { - debug (e.message); - } - - return status; - } - - public async bool delete_tasklist (Objects.Project project) { - var url = "%s/calendars/%s/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project.id - ); - - var message = new Soup.Message ("DELETE", url); - bool status = false; - - try { - yield set_credential (message); - - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - status = true; - } catch (Error e) { - debug (e.message); - } - - return status; - } - - public async HttpResponse refresh_tasklist (Objects.Project project) { - var url = "%s/calendars/%s/%s/".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project.id - ); - var message = new Soup.Message ("PROPFIND", url); - - HttpResponse return_value = new HttpResponse (); - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((TASKLIST_REQUEST).data)); - - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("refresh_tasklist", (string) stream.get_data ()); - - GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - - // Categories - Gee.HashMap labels_map = new Gee.HashMap (); - - foreach (GXml.DomElement element in response) { - yield add_project_if_not_exists (element, labels_map); - } - - return_value.status = true; - } catch (Error e) { - debug (e.message); - } - - return return_value; - } - - /* - * Task - */ - - public async HttpResponse add_task (Objects.Item item, bool update = false) { - var ics = update ? item.ics : "%s.ics".printf (item.id); - - var url = "%s/calendars/%s/%s/%s".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - item.project.id, - ics - ); - var message = new Soup.Message ("PUT", url); - - HttpResponse response = new HttpResponse (); - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (item.to_vtodo ().data)); - - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - if (update ? message.status_code == 204 : message.status_code == 201) { - response.status = true; - item.extra_data = Util.generate_extra_data (ics, "", item.to_vtodo ()); - } - } catch (Error e) { - debug (e.message); - } - - return response; - } - - public async HttpResponse delete_task (Objects.Item item) { - var url = "%s/calendars/%s/%s/%s".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - item.project.id, - item.ics - ); - var message = new Soup.Message ("DELETE", url); - - HttpResponse response = new HttpResponse (); - - try { - yield set_credential (message); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("delete_task", (string) stream.get_data ()); - - if (message.status_code == 204) { - response.status = true; - } else { - response.error_code = (int) message.status_code; - response.error = (string) stream.get_data (); - print ("Code: %d, Error: %s\n".printf (response.error_code, response.error)); - } - } catch (Error e) { - debug (e.message); - } - - return response; - } - - public async HttpResponse complete_item (Objects.Item item) { - var ics = item.ics; - var body = item.to_vtodo (); - - var url = "%s/calendars/%s/%s/%s".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - item.project.id, - ics - ); - var message = new Soup.Message ("PUT", url); - - HttpResponse response = new HttpResponse (); - - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (body.data)); - - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - if (message.status_code == 204) { - response.status = true; - item.extra_data = Util.generate_extra_data (ics, "", body); - } - } catch (Error e) { - debug (e.message); - } - - return response; - } - - public async HttpResponse move_task (Objects.Item item, string project_id) { - var url = "%s/calendars/%s/%s/%s".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-server-url"), - Services.Settings.get_default ().settings.get_string ("caldav-username"), - item.project.id, - item.ics - ); - var destination = "/remote.php/dav/calendars/%s/%s/%s".printf ( - Services.Settings.get_default ().settings.get_string ("caldav-username"), - project_id, - item.ics - ); - var message = new Soup.Message ("MOVE", url); - - HttpResponse response = new HttpResponse (); - - try { - yield set_credential (message); - message.request_headers.append ("Destination", destination); - - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - if (message.status_code == 201 || message.status_code == 204) { - response.status = true; - } - } catch (Error e) { - debug (e.message); - } - - return response; - } - - public void remove_items () { - Services.Settings.get_default ().settings.set_string ("caldav-server-url", ""); - Services.Settings.get_default ().settings.set_string ("caldav-username", ""); - Services.Settings.get_default ().settings.set_string ("caldav-user-email", ""); - Services.Settings.get_default ().settings.set_string ("caldav-user-displayname", ""); - - // Delete all projects, sections and items - foreach (var project in Services.Database.get_default ().get_all_projects_by_backend_type (BackendType.CALDAV)) { - Services.Database.get_default ().delete_project (project); - } - - // Delete all labels; - foreach (var label in Services.Database.get_default ().get_labels_by_backend_type (BackendType.CALDAV)) { - Services.Database.get_default ().delete_label (label); - } - - // Remove server_timeout - GLib.Source.remove (server_timeout); - server_timeout = 0; - - log_out (); - } - - /* - * Utils - */ - - public bool is_logged_in () { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - return server_url != "" && username != ""; - } - - public bool is_vtodo_calendar (GXml.DomElement element) { - GXml.DomElement propstat = element.get_elements_by_tag_name ("d:propstat").get_element (0); - GXml.DomElement prop = propstat.get_elements_by_tag_name ("d:prop").get_element (0); - GXml.DomElement resourcetype = prop.get_elements_by_tag_name ("d:resourcetype").get_element (0); - - bool is_calendar = resourcetype.get_elements_by_tag_name ("cal:calendar").length > 0; - bool is_vtodo = false; - - if (is_calendar) { - GXml.DomElement supported_calendar = prop.get_elements_by_tag_name ("cal:supported-calendar-component-set").get_element (0); - GXml.DomHTMLCollection calendar_comps = supported_calendar.get_elements_by_tag_name ("cal:comp"); - foreach (GXml.DomElement calendar_comp in calendar_comps) { - if (calendar_comp.get_attribute ("name") == "VTODO") { - is_vtodo = true; - } - } - } - - return is_vtodo; - } - - public bool is_deleted_calendar (GXml.DomElement element) { - GXml.DomElement propstat = element.get_elements_by_tag_name ("d:propstat").get_element (0); - GXml.DomElement prop = propstat.get_elements_by_tag_name ("d:prop").get_element (0); - GXml.DomElement resourcetype = prop.get_elements_by_tag_name ("d:resourcetype").get_element (0); - return resourcetype.get_elements_by_tag_name ("x2:deleted-calendar").length > 0; - } - - private GLib.HashTable get_attributes () { - var attributes = new GLib.HashTable (str_hash, str_equal); - attributes["username"] = Services.Settings.get_default ().settings.get_string ("caldav-username"); - attributes["server_url"] = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - - print ("get_attributes - username: %s\n".printf (attributes["username"])); - print ("get_attributes - server_url: %s\n".printf (attributes["server_url"])); - - return attributes; - } - - private async void set_credential (Soup.Message message) throws Error { - string username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - string password = yield Secret.password_lookupv (schema, get_attributes (), null); - string credentials = "%s:%s".printf (username, password); - string base64_credentials = Base64.encode (credentials.data); - message.request_headers.append ("Authorization", "Basic %s".printf (base64_credentials)); - } - - private void print_root (string fuction, string data) { - print (fuction + "\n"); - print (data + "\n"); - } -} diff --git a/core/Services/Database.vala b/core/Services/Database.vala index 4363ba5c0..09ca73307 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -28,38 +28,6 @@ public class Services.Database : GLib.Object { public signal void opened (); public signal void reset (); - public signal void source_added (Objects.Source source); - public signal void source_deleted (Objects.Source source); - - public signal void project_added (Objects.Project project); - public signal void project_updated (Objects.Project project); - public signal void project_deleted (Objects.Project project); - public signal void project_archived (Objects.Project project); - public signal void project_unarchived (Objects.Project project); - - public signal void label_added (Objects.Label label); - public signal void label_updated (Objects.Label label); - public signal void label_deleted (Objects.Label label); - - public signal void section_deleted (Objects.Section section); - public signal void section_moved (Objects.Section section, string old_project_id); - public signal void section_archived (Objects.Section section); - public signal void section_unarchived (Objects.Section section); - - public signal void item_deleted (Objects.Item item); - public signal void item_added (Objects.Item item, bool insert = true); - public signal void item_updated (Objects.Item item, string update_id); - public signal void item_archived (Objects.Item item); - public signal void item_unarchived (Objects.Item item); - - public signal void item_label_added (Objects.Label label); - public signal void item_label_deleted (Objects.Label label); - - public signal void reminder_added (Objects.Reminder reminder); - public signal void reminder_deleted (Objects.Reminder reminder); - - public signal void attachment_deleted (Objects.Attachment attachment); - private static Database? _instance; public static Database get_default () { if (_instance == null) { @@ -69,123 +37,6 @@ public class Services.Database : GLib.Object { return _instance; } - Gee.ArrayList _sources = null; - public Gee.ArrayList sources { - get { - if (_sources == null) { - _sources = get_sources_collection (); - } - - return _sources; - } - } - - Gee.ArrayList _projects = null; - public Gee.ArrayList projects { - get { - if (_projects == null) { - _projects = get_projects_collection (); - } - return _projects; - } - } - - Gee.ArrayList _sections = null; - public Gee.ArrayList sections { - get { - if (_sections == null) { - _sections = get_sections_collection (); - } - return _sections; - } - } - - Gee.ArrayList _items = null; - public Gee.ArrayList items { - get { - if (_items == null) { - _items = get_items_collection (); - } - return _items; - } - } - - Gee.ArrayList _labels = null; - public Gee.ArrayList labels { - get { - if (_labels == null) { - _labels = get_labels_collection (); - } - return _labels; - } - } - - Gee.ArrayList _reminders = null; - public Gee.ArrayList reminders { - get { - if (_reminders == null) { - _reminders = get_reminders_collection (); - } - - return _reminders; - } - } - - Gee.ArrayList _attachments = null; - public Gee.ArrayList attachments { - get { - if (_attachments == null) { - _attachments = get_attachments_collection (); - } - - return _attachments; - } - } - - construct { - label_deleted.connect ((label) => { - if (_labels.remove (label)) { - debug ("Label Removed: %s", label.name); - } - }); - - source_deleted.connect ((source) => { - if (_sources.remove (source)) { - debug ("Source Removed: %s", source.header_text); - } - }); - - project_deleted.connect ((project) => { - if (_projects.remove (project)) { - debug ("Prodeleteject Removed: %s", project.name); - } - }); - - section_deleted.connect ((section) => { - if (_sections.remove (section)) { - debug ("Section Removed: %s", section.name); - } - }); - - item_deleted.connect ((item) => { - if (_items.remove (item)) { - debug ("item Removed: %s", item.content); - } - }); - - reminder_deleted.connect ((reminder) => { - if (_reminders.remove (reminder)) { - debug ("Reminder Removed: %s", reminder.id.to_string ()); - } - }); - - attachment_deleted.connect ((attachment) => { - if (_attachments.remove (attachment)) { - debug ("Attachment Removed: %s", attachment.id.to_string ()); - } - }); - } - public void init_database () { db_path = Environment.get_user_data_dir () + "/io.github.alainm23.planify/database.db"; Sqlite.Database.open (db_path, out db); @@ -600,28 +451,6 @@ public class Services.Database : GLib.Object { } } - public bool is_database_empty () { - return projects.size <= 0; - } - - public bool is_sources_empty () { - return get_sources_collection ().size <= 0; - } - - public Gee.ArrayList get_collection_by_type (Objects.BaseObject base_object) { - if (base_object is Objects.Project) { - return projects; - } else if (base_object is Objects.Section) { - return sections; - } else if (base_object is Objects.Item) { - return items; - } else if (base_object is Objects.Label) { - return labels; - } - - return new Gee.ArrayList (); - } - /* Sources */ @@ -644,7 +473,7 @@ public class Services.Database : GLib.Object { return return_value; } - public Objects.Source _fill_source (Sqlite.Statement stmt) { + 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 = BackendType.parse (stmt.column_text (1)); @@ -657,6 +486,8 @@ public class Services.Database : GLib.Object { if (return_value.source_type == BackendType.TODOIST) { return_value.data = new Objects.SourceTodoistData.from_json (stmt.column_text (8)); + } else if (return_value.source_type == BackendType.CALDAV) { + return_value.data = new Objects.SourceCalDAVData.from_json (stmt.column_text (8)); } return return_value; @@ -683,10 +514,7 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$last_sync", source.last_sync); set_parameter_str (stmt, "$data", source.data.to_json ()); - if (stmt.step () == Sqlite.DONE) { - sources.add (source); - source_added (source); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } @@ -694,41 +522,55 @@ public class Services.Database : GLib.Object { return stmt.step () == Sqlite.DONE; } - public Objects.Source get_source (string id) { - Objects.Source? return_value = null; - lock (_sources) { - foreach (var source in sources) { - if (source.id == id) { - return_value = source; - break; - } - } + public bool delete_source (Objects.Source source) { + Sqlite.Statement stmt; + + sql = """ + DELETE FROM Sources WHERE id=$id; + """; + + db.prepare_v2 (sql, sql.length, out stmt); + set_parameter_str (stmt, "$id", source.id); - return return_value; + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } + + stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void delete_source (Objects.Source source) { + public bool update_source (Objects.Source source) { Sqlite.Statement stmt; sql = """ - DELETE FROM Sources WHERE id=$id; + UPDATE Sources SET + source_type=$source_type, + updated_at=$updated_at, + is_visible=$is_visible, + child_order=$child_order, + sync_server=$sync_server, + last_sync=$last_sync, + data=$data + 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, "$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) { - foreach (Objects.Project project in get_projects_by_source (source.id)) { - delete_project (project); - } - - source.deleted (); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - + stmt.reset (); + return stmt.step () == Sqlite.DONE; } /* @@ -753,58 +595,6 @@ public class Services.Database : GLib.Object { return return_value; } - public Gee.ArrayList get_subprojects (Objects.Project _project) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.parent_id == _project.id) { - return_value.add (project); - } - } - } - - return return_value; - } - - public Gee.ArrayList get_projects_by_backend_type (BackendType backend_type) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.backend_type == backend_type && !project.is_inbox_project) { - return_value.add (project); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_projects_by_source (string source_id) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.source_id == source_id) { - return_value.add (project); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_subitems (Objects.Item i) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (var item in items) { - if (item.parent_id == i.id) { - return_value.add (item); - } - } - } - - 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); @@ -847,20 +637,6 @@ public class Services.Database : GLib.Object { } } - public int next_project_child_order (BackendType backend_type) { - int child_order = 0; - - lock (_projects) { - foreach (var project in projects) { - if (project.backend_type == backend_type && !project.is_deleted) { - child_order++; - } - } - - return child_order; - } - } - public bool insert_project (Objects.Project project) { Sqlite.Statement stmt; @@ -901,36 +677,14 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$source_id", project.source_id); if (stmt.step () == Sqlite.DONE) { - projects.add (project); - - if (project.parent == null) { - project_added (project); - } else { - project.parent.subproject_added (project); - } - } else { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); return stmt.step () == Sqlite.DONE; } - - public Objects.Project get_project (string id) { - Objects.Project? return_value = null; - lock (_projects) { - foreach (var project in projects) { - if (project.id == id) { - return_value = project; - break; - } - } - - return return_value; - } - } - public void delete_project (Objects.Project project) { + public bool delete_project (Objects.Project project) { Sqlite.Statement stmt; sql = """ @@ -940,25 +694,12 @@ public class Services.Database : GLib.Object { db.prepare_v2 (sql, sql.length, out stmt); set_parameter_str (stmt, "$id", project.id); - if (stmt.step () == Sqlite.DONE) { - foreach (Objects.Section section in get_sections_by_project (project)) { - delete_section (section); - } - - foreach (Objects.Item item in get_items_by_project (project)) { - delete_item (item); - } - - foreach (Objects.Project subproject in get_subprojects (project)) { - delete_project (subproject); - } - - project.deleted (); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } public void delete_project_db (Objects.Project project) { @@ -981,7 +722,7 @@ public class Services.Database : GLib.Object { stmt.reset (); } - public void update_project (Objects.Project project) { + public bool update_project (Objects.Project project) { Sqlite.Statement stmt; sql = """ @@ -1036,17 +777,15 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$source_id", project.source_id); set_parameter_str (stmt, "$id", project.id); - if (stmt.step () == Sqlite.DONE) { - project.updated (); - project_updated (project); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void archive_project (Objects.Project project) { + public bool archive_project (Objects.Project project) { Sqlite.Statement stmt; sql = """ @@ -1057,33 +796,17 @@ public class Services.Database : GLib.Object { set_parameter_bool (stmt, "$is_archived", project.is_archived); set_parameter_str (stmt, "$id", project.id); - if (stmt.step () == Sqlite.DONE) { - foreach (Objects.Item item in project.items) { - archive_item (item, project.is_archived); - } - - foreach (Objects.Section section in project.sections) { - section.is_archived = project.is_archived; - archive_section (section); - } - - if (project.is_archived) { - project.archived (); - project_archived (project); - } else { - project.unarchived (); - project_unarchived (project); - } - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } /* - * Labels - */ + * Labels + */ public Gee.ArrayList get_labels_collection () { Gee.ArrayList return_value = new Gee.ArrayList (); @@ -1101,46 +824,7 @@ public class Services.Database : GLib.Object { stmt.reset (); return return_value; } - - public Gee.ArrayList get_labels_by_backend_type (BackendType backend_type) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_labels) { - foreach (var label in labels) { - if (backend_type == BackendType.ALL ? true : label.backend_type == backend_type) { - return_value.add (label); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_labels_by_source (string source_id) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_labels) { - foreach (var label in labels) { - if (label.source_id == source_id) { - return_value.add (label); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_labels_by_search (string search_text) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_labels) { - foreach (var label in labels) { - if (search_text.down () in label.name.down ()) { - return_value.add (label); - } - } - - 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); @@ -1174,10 +858,7 @@ public class Services.Database : GLib.Object { 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) { - labels.add (label); - label_added (label); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } @@ -1185,50 +866,7 @@ public class Services.Database : GLib.Object { return stmt.step () == Sqlite.DONE; } - public bool label_exists (string id) { - bool return_value = false; - lock (_labels) { - foreach (var label in _labels) { - if (label.id == id) { - return_value = true; - break; - } - } - - return return_value; - } - } - - public Objects.Label get_label (string id) { - Objects.Label? return_value = null; - lock (_labels) { - foreach (var label in labels) { - if (label.id == id) { - return_value = label; - break; - } - } - - return return_value; - } - } - - public Objects.Label? get_label_by_name (string name, bool lowercase = false, string source_id) { - lock (_labels) { - string compare_name = lowercase ? name.down () : name; - - foreach (var label in labels) { - string label_name = lowercase ? label.name.down () : label.name; - if (label.source_id == source_id && label_name == compare_name) { - return label; - } - } - - return null; - } - } - - public void delete_label (Objects.Label label) { + public bool delete_label (Objects.Label label) { Sqlite.Statement stmt; sql = """ @@ -1238,16 +876,15 @@ public class Services.Database : GLib.Object { db.prepare_v2 (sql, sql.length, out stmt); set_parameter_str (stmt, "$id", label.id); - if (stmt.step () == Sqlite.DONE) { - label.deleted (); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void update_label (Objects.Label label) { + public bool update_label (Objects.Label label) { Sqlite.Statement stmt; sql = """ @@ -1267,67 +904,12 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$source_id", label.source_id); set_parameter_str (stmt, "$id", label.id); - if (stmt.step () == Sqlite.DONE) { - label.updated (); - label_updated (label); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); - } - - public Gee.ArrayList get_labels_by_item_labels (string labels) { - Gee.ArrayList return_value = new Gee.ArrayList (); - - foreach (string id in labels.split (";")) { - Objects.Label? label = get_label (id); - if (label != null) { - return_value.add (label); - } - } - - return return_value; - } - - 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 int next_item_child_order (string project_id, string section_id) { - int child_order = 0; - - lock (_items) { - foreach (var item in items) { - if (item.project_id == project_id && item.section_id == section_id) { - child_order++; - } - } - - return child_order; - } - } - - public Gee.ArrayList get_items_has_labels () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.has_labels () && !item.completed && !item.was_archived ()) { - return_value.add (item); - } - } - return return_value; - } + stmt.reset (); + return stmt.step () == Sqlite.DONE; } /* @@ -1358,10 +940,7 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$description", section.description); set_parameter_bool (stmt, "$hidded", section.hidded); - if (stmt.step () == Sqlite.DONE) { - sections.add (section); - section.project.section_added (section); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } @@ -1384,46 +963,6 @@ public class Services.Database : GLib.Object { return return_value; } - public Gee.ArrayList get_sections_by_project (Objects.Project project) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_sections) { - foreach (var section in sections) { - if (section.project_id == project.id) { - return_value.add (section); - } - } - } - - return return_value; - } - - public Gee.ArrayList get_sections_archived_by_project (Objects.Project project) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_sections) { - foreach (var section in sections) { - if (section.project_id == project.id && section.was_archived ()) { - return_value.add (section); - } - } - } - - return return_value; - } - - public Objects.Section get_section (string id) { - Objects.Section? return_value = null; - lock (_sections) { - foreach (var section in sections) { - if (section.id == id) { - return_value = section; - break; - } - } - - 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); @@ -1441,7 +980,7 @@ public class Services.Database : GLib.Object { return return_value; } - public void delete_section (Objects.Section section) { + public bool delete_section (Objects.Section section) { Sqlite.Statement stmt; sql = """ @@ -1451,20 +990,15 @@ public class Services.Database : GLib.Object { db.prepare_v2 (sql, sql.length, out stmt); set_parameter_str (stmt, "$id", section.id); - if (stmt.step () == Sqlite.DONE) { - foreach (Objects.Item item in section.items) { - delete_item (item); - } - - section.deleted (); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void update_section (Objects.Section section) { + public bool update_section (Objects.Section section) { Sqlite.Statement stmt; sql = """ @@ -1489,16 +1023,15 @@ public class Services.Database : GLib.Object { set_parameter_bool (stmt, "$hidded", section.hidded); set_parameter_str (stmt, "$id", section.id); - if (stmt.step () == Sqlite.DONE) { - section.updated (); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void move_section (Objects.Section section, string old_project_id) { + public bool move_section (Objects.Section section, string old_project_id) { Sqlite.Statement stmt; sql = """ @@ -1509,32 +1042,34 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$project_id", section.project_id); set_parameter_str (stmt, "$id", section.id); - if (stmt.step () == Sqlite.DONE) { - stmt.reset (); + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - sql = """ - UPDATE Items SET project_id=$project_id WHERE section_id=$section_id; - """; + stmt.reset (); + return stmt.step () == Sqlite.DONE; + } - 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) { - foreach (Objects.Item item in section.items) { - item.project_id = section.project_id; - } + public bool move_section_items (Objects.Section section) { + Sqlite.Statement stmt; - section_moved (section, old_project_id); - } + sql = """ + UPDATE Items SET project_id=$project_id WHERE section_id=$section_id; + """; - stmt.reset (); - } else { + 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 ()); } + + stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void archive_section (Objects.Section section) { + public bool archive_section (Objects.Section section) { Sqlite.Statement stmt; sql = """ @@ -1545,23 +1080,12 @@ public class Services.Database : GLib.Object { set_parameter_bool (stmt, "$is_archived", section.is_archived); set_parameter_str (stmt, "$id", section.id); - if (stmt.step () == Sqlite.DONE) { - foreach (Objects.Item item in section.items) { - archive_item (item, section.is_archived); - } - - if (section.is_archived) { - section.archived (); - section_archived (section); - } else { - section.unarchived (); - section_unarchived (section); - } - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } /* @@ -1598,13 +1122,11 @@ public class Services.Database : GLib.Object { 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)); + // TODO: 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) { - add_item (item, insert); - } else { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } @@ -1612,25 +1134,6 @@ public class Services.Database : GLib.Object { return stmt.step () == Sqlite.DONE; } - public void add_item (Objects.Item item, bool insert = true) { - items.add (item); - item_added (item, insert); - - if (insert) { - if (item.parent_id != "") { - item.parent.item_added (item); - } else { - if (item.section_id == "") { - item.project.item_added (item); - } else { - item.section.item_added (item); - } - } - } - - Services.EventBus.get_default ().update_items_position (item.project_id, item.section_id); - } - public Gee.ArrayList get_items_collection () { Gee.ArrayList return_value = new Gee.ArrayList (); Sqlite.Statement stmt; @@ -1646,34 +1149,6 @@ public class Services.Database : GLib.Object { return return_value; } - public Objects.Item get_item (string id) { - Objects.Item? return_value = null; - lock (_items) { - foreach (var item in items) { - if (item.id == id) { - return_value = item; - break; - } - } - - return return_value; - } - } - - public Objects.Item get_item_by_ics (string ics) { - Objects.Item? return_value = null; - lock (_items) { - foreach (var item in items) { - if (item.ics == ics) { - return_value = item; - break; - } - } - - return return_value; - } - } - public Objects.Item get_item_by_id (string id) { Objects.Item returned = new Objects.Item (); Sqlite.Statement stmt; @@ -1691,84 +1166,6 @@ public class Services.Database : GLib.Object { return returned; } - 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); - - while (stmt.step () == Sqlite.ROW) { - return_value.add (_fill_reminder (stmt)); - } - stmt.reset (); - return return_value; - } - - public Gee.ArrayList get_item_by_baseobject (Objects.BaseObject object) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (var item in items) { - if (object is Objects.Project) { - if (item.project_id == object.id && item.section_id == "" && !item.has_parent) { - return_value.add (item); - } - } - - if (object is Objects.Section) { - if (item.section_id == object.id && !item.has_parent) { - return_value.add (item); - } - } - } - } - - return return_value; - } - - public Gee.ArrayList get_items_by_project (Objects.Project project) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.exists_project (project)) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_checked_by_project (Objects.Project project) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.project_id == project.id && item.checked) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_checked () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.checked) { - return_value.add (item); - } - } - - return return_value; - } - } - public Objects.Item _fill_item (Sqlite.Statement stmt) { Objects.Item return_value = new Objects.Item (); return_value.id = stmt.column_text (0); @@ -1788,232 +1185,14 @@ public class Services.Database : GLib.Object { 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 = get_labels_by_item_labels (stmt.column_text (17)); + // TODO: return_value.labels = 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 Gee.ArrayList get_items_by_date (GLib.DateTime date, bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (valid_item_by_date (item, date, checked)) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_no_date (bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (!item.has_due && item.checked == checked) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_repeating (bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.has_due && item.due.is_recurring && item.checked == checked && !item.was_archived ()) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_by_date_range (GLib.DateTime start_date, GLib.DateTime end_date, bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (valid_item_by_date_range (item, start_date, end_date, checked)) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_by_month (GLib.DateTime date, bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (valid_item_by_month (item, date, checked)) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_pinned (bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.pinned && item.checked == checked && !item.was_archived ()) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_by_priority (int priority, bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.priority == priority && item.checked == checked && !item.was_archived ()) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_completed () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.checked && !item.was_archived ()) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_by_label (Objects.Label label, bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.has_label (label.id) && item.checked == checked && !item.was_archived ()) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_unlabeled (bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.labels.size <= 0 && item.checked == checked && !item.was_archived ()) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_by_scheduled (bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.has_due && - !item.was_archived () && - item.checked == checked && - item.due.datetime.compare (new GLib.DateTime.now_local ()) > 0) { - return_value.add (item); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_items_no_parent (bool checked = true) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (!item.was_archived () && - item.checked == checked && - !item.has_parent) { - return_value.add (item); - } - } - - return return_value; - } - } - - public bool valid_item_by_date (Objects.Item item, GLib.DateTime date, bool checked = true) { - if (!item.has_due || item.was_archived ()) { - return false; - } - - return (item.checked == checked && Utils.Datetime.is_same_day (item.due.datetime, date)); - } - - public bool valid_item_by_date_range (Objects.Item item, GLib.DateTime start_date, GLib.DateTime end_date, bool checked = true) { - if (!item.has_due || item.was_archived ()) { - return false; - } - - var date = Utils.Datetime.get_format_date (item.due.datetime); - var start = Utils.Datetime.get_format_date (start_date); - var end = Utils.Datetime.get_format_date (end_date); - - return (item.checked == checked && date.compare (start) >= 0 && date.compare (end) <= 0); - } - - public bool valid_item_by_month (Objects.Item item, GLib.DateTime date, bool checked = true) { - if (!item.has_due || item.was_archived ()) { - return false; - } - - return (item.checked == checked && item.due.datetime.get_month () == date.get_month () && - item.due.datetime.get_year () == date.get_year ()); - } - - public Gee.ArrayList get_items_by_overdeue_view (bool checked = true) { - GLib.DateTime date_now = new GLib.DateTime.now_local (); - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (Objects.Item item in items) { - if (item.has_due && - !item.was_archived () && - item.checked == checked && - item.due.datetime.compare (date_now) < 0 && - !Utils.Datetime.is_same_day (item.due.datetime, date_now)) { - return_value.add (item); - } - } - - return return_value; - } - } - - public bool valid_item_by_overdue (Objects.Item item, GLib.DateTime date, bool checked = true) { - if (!item.has_due || item.was_archived ()) { - return false; - } - - return (item.checked == checked && - item.due.datetime.compare (new GLib.DateTime.now_local ()) < 0 && - !Utils.Datetime.is_same_day (item.due.datetime, new GLib.DateTime.now_local ())); - } - - public void delete_item (Objects.Item item) { + public bool delete_item (Objects.Item item) { Sqlite.Statement stmt; sql = """ @@ -2023,22 +1202,15 @@ public class Services.Database : GLib.Object { db.prepare_v2 (sql, sql.length, out stmt); set_parameter_str (stmt, "$id", item.id); - if (stmt.step () == Sqlite.DONE) { - if (item.project.backend_type == BackendType.LOCAL || item.project.backend_type == BackendType.TODOIST) { - foreach (Objects.Item subitem in item.items) { - delete_item (subitem); - } - } - - item.deleted (); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void update_item (Objects.Item item, string update_id = "") { + public bool update_item (Objects.Item item, string update_id = "") { item.updated_at = new GLib.DateTime.now_local ().to_string (); Sqlite.Statement stmt; @@ -2069,22 +1241,20 @@ public class Services.Database : GLib.Object { 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, "$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) { - item.updated (update_id); - item_updated (item, update_id); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void move_item (Objects.Item item) { + public bool move_item (Objects.Item item) { item.updated_at = new GLib.DateTime.now_local ().to_string (); Sqlite.Statement stmt; @@ -2103,21 +1273,14 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$id", item.id); if (stmt.step () == Sqlite.DONE) { - foreach (Objects.Item subitem in item.items) { - subitem.project_id = item.project_id; - move_item (subitem); - } - - item.updated (); - item_updated (item, ""); - } else { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void checked_toggled (Objects.Item item, bool old_checked) { + public bool checked_toggled (Objects.Item item, bool old_checked) { Sqlite.Statement stmt; sql = """ @@ -2130,22 +1293,12 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$completed_at", item.completed_at); set_parameter_str (stmt, "$id", item.id); - if (stmt.step () == Sqlite.DONE) { - foreach (Objects.Item subitem in item.items) { - subitem.checked = item.checked; - subitem.completed_at = item.completed_at; - checked_toggled (subitem, old_checked); - } - - item.updated (); - item_updated (item, ""); - - Services.EventBus.get_default ().checked_toggled (item, old_checked); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } public void update_child_order (Objects.BaseObject base_object) { @@ -2176,118 +1329,8 @@ public class Services.Database : GLib.Object { stmt.reset (); } - public void archive_item (Objects.Item item, bool is_archived) { - if (is_archived) { - item.archived (); - item_archived (item); - } else { - item.unarchived (); - item_unarchived (item); - } - - foreach (Objects.Item subitem in item.items) { - archive_item (subitem, is_archived); - } - } - - /* - Quick Find - */ - - public Gee.ArrayList get_all_projects_by_search (string search_text) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (search_text.down () in project.name.down () && !project.is_archived) { - return_value.add (project); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_sections_by_search (string search_text) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var section in sections) { - if (search_text.down () in section.name.down () && !section.was_archived ()) { - return_value.add (section); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_projects_by_todoist () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.backend_type == BackendType.TODOIST) { - return_value.add (project); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_projects_by_backend_type (BackendType backend_type) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.backend_type == backend_type) { - return_value.add (project); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_projects_archived () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.is_archived) { - return_value.add (project); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_labels_by_todoist () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_labels) { - foreach (var label in labels) { - if (label.backend_type == BackendType.TODOIST) { - return_value.add (label); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_items_by_search (string search_text) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_items) { - foreach (var item in items) { - if (!item.checked && !item.was_archived () && (search_text.down () in item.content.down () || - search_text.down () in item.description.down ())) { - return_value.add (item); - } - } - - return return_value; - } - } - // Reminders - public void insert_reminder (Objects.Reminder reminder) { + public bool insert_reminder (Objects.Reminder reminder) { Sqlite.Statement stmt; string sql; @@ -2305,13 +1348,10 @@ public class Services.Database : GLib.Object { if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } else { - reminder_added (reminder); - reminders.add (reminder); - reminder.item.reminder_added (reminder); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } public Gee.ArrayList get_reminders_collection () { @@ -2341,34 +1381,25 @@ public class Services.Database : GLib.Object { return return_value; } - public Gee.ArrayList get_reminders_by_item (Objects.Item item) { + public Gee.ArrayList get_reminders_by_item_id (string id) { Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_reminders) { - foreach (var reminder in reminders) { - if (reminder.item_id == item.id) { - return_value.add (reminder); - } - } + Sqlite.Statement stmt; - return return_value; - } - } + sql = """ + SELECT id, item_id, type, due, mm_offset FROM Reminders WHERE item_id=$item_id; + """; - public Objects.Reminder get_reminder (string id) { - Objects.Reminder? return_value = null; - lock (_reminders) { - foreach (var reminder in reminders) { - if (reminder.id == id) { - return_value = reminder; - break; - } - } - - return return_value; + 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)); } + stmt.reset (); + return return_value; } - public void delete_reminder (Objects.Reminder reminder) { + public bool delete_reminder (Objects.Reminder reminder) { Sqlite.Statement stmt; sql = """ @@ -2378,18 +1409,16 @@ public class Services.Database : GLib.Object { db.prepare_v2 (sql, sql.length, out stmt); set_parameter_str (stmt, "$id", reminder.id); - if (stmt.step () == Sqlite.DONE) { - reminder.deleted (); - reminder.item.reminder_deleted (reminder); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } // Atrachments - public void insert_attachment (Objects.Attachment attachment) { + public bool insert_attachment (Objects.Attachment attachment) { Sqlite.Statement stmt; string sql; @@ -2408,12 +1437,10 @@ public class Services.Database : GLib.Object { if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); - } else { - attachments.add (attachment); - attachment.item.attachment_added (attachment); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } public Gee.ArrayList get_attachments_collection () { @@ -2444,20 +1471,7 @@ public class Services.Database : GLib.Object { return return_value; } - public Gee.ArrayList get_attachments_by_item (Objects.Item item) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_attachments) { - foreach (var attachment in attachments) { - if (attachment.item_id == item.id) { - return_value.add (attachment); - } - } - - return return_value; - } - } - - public void delete_attachment (Objects.Attachment attachment) { + public bool delete_attachment (Objects.Attachment attachment) { Sqlite.Statement stmt; sql = """ @@ -2467,14 +1481,12 @@ public class Services.Database : GLib.Object { db.prepare_v2 (sql, sql.length, out stmt); set_parameter_str (stmt, "$id", attachment.id); - if (stmt.step () == Sqlite.DONE) { - attachment.deleted (); - attachment.item.attachment_deleted (attachment); - } else { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } /* @@ -2590,7 +1602,7 @@ public class Services.Database : GLib.Object { return returned; } - public void update_project_id (string current_id, string new_id) { + public bool update_project_id (string current_id, string new_id) { Sqlite.Statement stmt; sql = """ @@ -2601,53 +1613,53 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$new_id", new_id); set_parameter_str (stmt, "$current_id", current_id); - if (stmt.step () == Sqlite.DONE) { - Objects.Project? project = get_project (current_id); - if (project != null) { - project.id = new_id; - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - stmt.reset (); + stmt.reset (); + return stmt.step () == Sqlite.DONE; + } + + 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); - - if (stmt.step () == Sqlite.DONE) { - foreach (var section in sections) { - if (section.project_id == current_id) { - section.project_id = new_id; - } - } - - stmt.reset (); - - 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); - - if (stmt.step () == Sqlite.DONE) { - foreach (var item in items) { - if (item.project_id == current_id) { - item.project_id = new_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 ()); + } + + stmt.reset (); + return stmt.step () == Sqlite.DONE; + } + + 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); + + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void update_section_id (string current_id, string new_id) { + public bool update_section_id (string current_id, string new_id) { Sqlite.Statement stmt; sql = """ @@ -2658,36 +1670,34 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$new_id", new_id); set_parameter_str (stmt, "$current_id", current_id); - if (stmt.step () == Sqlite.DONE) { - foreach (var section in sections) { - if (section.id == current_id) { - section.id = new_id; - } - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } + + stmt.reset (); + return stmt.step () == Sqlite.DONE; + } - stmt.reset (); + public bool update_section_item_id (string current_id, string new_id) { + Sqlite.Statement stmt; - sql = """ - UPDATE Items SET section_id = $new_id WHERE section_id = $current_id; - """; + 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) { - foreach (var item in items) { - if (item.section_id == current_id) { - item.section_id = new_id; - } - } - } + if (stmt.step () != Sqlite.DONE) { + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } - public void update_item_id (string current_id, string new_id) { + public bool update_item_id (string current_id, string new_id) { Sqlite.Statement stmt; sql = """ @@ -2699,32 +1709,30 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$current_id", current_id); if (stmt.step () == Sqlite.DONE) { - foreach (var item in items) { - if (item.id == current_id) { - item.id = new_id; - } - } + warning ("Error: %d: %s", db.errcode (), db.errmsg ()); + } - stmt.reset (); + stmt.reset (); + return stmt.step () == Sqlite.DONE; + } - sql = """ - UPDATE Items SET parent_id = $new_id WHERE parent_id = $current_id; - """; + public bool update_item_child_id (string current_id, string new_id) { + Sqlite.Statement stmt; - db.prepare_v2 (sql, sql.length, out stmt); - set_parameter_str (stmt, "$new_id", new_id); - set_parameter_str (stmt, "$current_id", current_id); + sql = """ + UPDATE Items SET parent_id = $new_id WHERE parent_id = $current_id; + """; - if (stmt.step () == Sqlite.DONE) { - foreach (var item in items) { - if (item.parent_id == current_id) { - item.parent_id = new_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 ()); } stmt.reset (); + return stmt.step () == Sqlite.DONE; } public void remove_CurTempIds (string id) { // vala-lint=naming-convention @@ -2800,10 +1808,10 @@ public class Services.Database : GLib.Object { } /* - * ObjectsEvent - */ + * ObjectsEvent + */ - public Gee.ArrayList get_events_by_item (string id, int start_week, int end_week) { + 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; @@ -2893,7 +1901,7 @@ public class Services.Database : GLib.Object { stmt.step (); - for (int i = 0; i < stmt.column_count (); i++) { + while (stmt.step () == Sqlite.ROW) { if (stmt.column_text (1) == column) { returned = true; } diff --git a/core/Services/Store.vala b/core/Services/Store.vala new file mode 100644 index 000000000..4f5cf4897 --- /dev/null +++ b/core/Services/Store.vala @@ -0,0 +1,1277 @@ +/* +* Copyright © 2024 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.Store : GLib.Object { + static GLib.Once _instance; + public static unowned Services.Store instance () { + return _instance.once (() => { + return new Services.Store (); + }); + } + + public signal void source_added (Objects.Source source); + public signal void source_deleted (Objects.Source source); + public signal void source_updated (Objects.Source source); + + public signal void project_added (Objects.Project project); + public signal void project_updated (Objects.Project project); + public signal void project_deleted (Objects.Project project); + public signal void project_archived (Objects.Project project); + public signal void project_unarchived (Objects.Project project); + + public signal void label_added (Objects.Label label); + public signal void label_updated (Objects.Label label); + public signal void label_deleted (Objects.Label label); + + public signal void section_deleted (Objects.Section section); + public signal void section_moved (Objects.Section section, string old_project_id); + public signal void section_archived (Objects.Section section); + public signal void section_unarchived (Objects.Section section); + + public signal void item_deleted (Objects.Item item); + public signal void item_added (Objects.Item item, bool insert = true); + public signal void item_updated (Objects.Item item, string update_id); + public signal void item_archived (Objects.Item item); + public signal void item_unarchived (Objects.Item item); + + public signal void item_label_added (Objects.Label label); + public signal void item_label_deleted (Objects.Label label); + + public signal void reminder_added (Objects.Reminder reminder); + public signal void reminder_deleted (Objects.Reminder reminder); + + public signal void attachment_deleted (Objects.Attachment attachment); + + Gee.ArrayList _sources = null; + public Gee.ArrayList sources { + get { + if (_sources == null) { + _sources = Services.Database.get_default ().get_sources_collection (); + } + + return _sources; + } + } + + Gee.ArrayList _projects = null; + public Gee.ArrayList projects { + get { + if (_projects == null) { + _projects = Services.Database.get_default ().get_projects_collection (); + } + return _projects; + } + } + + Gee.ArrayList _sections = null; + public Gee.ArrayList sections { + get { + if (_sections == null) { + _sections = Services.Database.get_default ().get_sections_collection (); + } + return _sections; + } + } + + Gee.ArrayList _items = null; + public Gee.ArrayList items { + get { + if (_items == null) { + _items = Services.Database.get_default ().get_items_collection (); + } + return _items; + } + } + + Gee.ArrayList _labels = null; + public Gee.ArrayList labels { + get { + if (_labels == null) { + _labels = Services.Database.get_default ().get_labels_collection (); + } + return _labels; + } + } + + Gee.ArrayList _reminders = null; + public Gee.ArrayList reminders { + get { + if (_reminders == null) { + _reminders = Services.Database.get_default ().get_reminders_collection (); + } + + return _reminders; + } + } + + Gee.ArrayList _attachments = null; + public Gee.ArrayList attachments { + get { + if (_attachments == null) { + _attachments = Services.Database.get_default ().get_attachments_collection (); + } + + return _attachments; + } + } + + construct { + label_deleted.connect ((label) => { + if (_labels.remove (label)) { + debug ("Label Removed: %s", label.name); + } + }); + + source_deleted.connect ((source) => { + if (_sources.remove (source)) { + debug ("Source Removed: %s", source.header_text); + } + }); + + project_deleted.connect ((project) => { + if (_projects.remove (project)) { + debug ("Prodeleteject Removed: %s", project.name); + } + }); + + section_deleted.connect ((section) => { + if (_sections.remove (section)) { + debug ("Section Removed: %s", section.name); + } + }); + + item_deleted.connect ((item) => { + if (_items.remove (item)) { + debug ("item Removed: %s", item.content); + } + }); + + reminder_deleted.connect ((reminder) => { + if (_reminders.remove (reminder)) { + debug ("Reminder Removed: %s", reminder.id.to_string ()); + } + }); + + attachment_deleted.connect ((attachment) => { + if (_attachments.remove (attachment)) { + debug ("Attachment Removed: %s", attachment.id.to_string ()); + } + }); + } + + public bool is_database_empty () { + return projects.size <= 0; + } + + public bool is_sources_empty () { + return sources.size <= 0; + } + + + public Gee.ArrayList get_collection_by_type (Objects.BaseObject base_object) { + if (base_object is Objects.Project) { + return projects; + } else if (base_object is Objects.Section) { + return sections; + } else if (base_object is Objects.Item) { + return items; + } else if (base_object is Objects.Label) { + return labels; + } + + return new Gee.ArrayList (); + } + + /* + * Sources + */ + + public void insert_source (Objects.Source source) { + if (Services.Database.get_default ().insert_source (source)) { + sources.add (source); + source_added (source); + } + } + + public void delete_source (Objects.Source source) { + if (Services.Database.get_default ().delete_source (source)) { + foreach (Objects.Project project in get_projects_by_source (source.id)) { + delete_project (project); + } + + source.deleted (); + } + } + + public void update_source (Objects.Source source) { + if (Services.Database.get_default ().update_source (source)) { + source.updated (); + source_updated (source); + } + } + + public Objects.Source get_source (string id) { + Objects.Source? return_value = null; + lock (_sources) { + foreach (var source in sources) { + if (source.id == id) { + return_value = source; + break; + } + } + + return return_value; + } + } + + /* + * Projects + */ + + public void insert_project (Objects.Project project) { + if (Services.Database.get_default ().insert_project (project)) { + projects.add (project); + + if (project.parent == null) { + project_added (project); + } else { + project.parent.subproject_added (project); + } + } + } + + public Gee.ArrayList get_projects_by_source (string source_id) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (project.source_id == source_id) { + return_value.add (project); + } + } + + return return_value; + } + } + + public void delete_project (Objects.Project project) { + if (Services.Database.get_default ().delete_project (project)) { + foreach (Objects.Section section in get_sections_by_project (project)) { + delete_section (section); + } + + foreach (Objects.Item item in get_items_by_project (project)) { + delete_item (item); + } + + foreach (Objects.Project subproject in get_subprojects (project)) { + delete_project (subproject); + } + + project.deleted (); + } + } + + public void archive_project (Objects.Project project) { + if (Services.Database.get_default ().archive_project (project)) { + foreach (Objects.Item item in project.items) { + archive_item (item, project.is_archived); + } + + foreach (Objects.Section section in project.sections) { + section.is_archived = project.is_archived; + archive_section (section); + } + + if (project.is_archived) { + project.archived (); + project_archived (project); + } else { + project.unarchived (); + project_unarchived (project); + } + } + } + + public void update_project (Objects.Project project) { + if (Services.Database.get_default ().update_project (project)) { + project.updated (); + project_updated (project); + } + } + + public void update_project_id (string current_id, string new_id) { + if (Services.Database.get_default ().update_project_id (current_id, new_id)) { + Objects.Project? project = get_project (current_id); + if (project != null) { + project.id = new_id; + } + + if (Services.Database.get_default ().update_project_section_id (current_id, new_id)) { + foreach (var section in sections) { + if (section.project_id == current_id) { + section.project_id = new_id; + } + } + + if (Services.Database.get_default ().update_project_item_id (current_id, new_id)) { + foreach (var item in items) { + if (item.project_id == current_id) { + item.project_id = new_id; + } + } + } + } + } + } + + public Objects.Project get_inbox_project () { + Objects.Project? return_value = null; + + lock (_projects) { + foreach (var project in projects) { + if (project.is_inbox_project) { + return_value = project; + break; + } + } + + return return_value; + } + } + + public Objects.Project get_project (string id) { + Objects.Project? return_value = null; + lock (_projects) { + foreach (var project in projects) { + if (project.id == id) { + return_value = project; + break; + } + } + + return return_value; + } + } + + public Gee.ArrayList get_subprojects (Objects.Project _project) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (project.parent_id == _project.id) { + return_value.add (project); + } + } + } + + return return_value; + } + + public Gee.ArrayList get_projects_by_backend_type (BackendType backend_type) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (project.backend_type == backend_type && !project.is_inbox_project) { + return_value.add (project); + } + } + + return return_value; + } + } + + public int next_project_child_order (Objects.Source source) { + int child_order = 0; + + lock (_projects) { + foreach (var project in projects) { + if (project.source_id == source.id && !project.is_deleted) { + child_order++; + } + } + + return child_order; + } + } + + /* + * Sections + */ + + public void insert_section (Objects.Section section) { + if (Services.Database.get_default ().insert_section (section)) { + sections.add (section); + section.project.section_added (section); + } + } + + public void update_section (Objects.Section section) { + if (Services.Database.get_default ().update_section (section)) { + section.updated (); + } + } + + public void delete_section (Objects.Section section) { + if (Services.Database.get_default ().delete_section (section)) { + foreach (Objects.Item item in section.items) { + delete_item (item); + } + + section.deleted (); + } + } + + public void move_section (Objects.Section section, string old_project_id) { + if (Services.Database.get_default ().move_section (section, old_project_id)) { + if (Services.Database.get_default ().move_section_items (section)) { + foreach (Objects.Item item in section.items) { + item.project_id = section.project_id; + } + + section_moved (section, old_project_id); + } + } + } + + public void update_section_id (string current_id, string new_id) { + if (Services.Database.get_default ().update_section_id (current_id, new_id)) { + foreach (var section in sections) { + if (section.id == current_id) { + section.id = new_id; + } + } + + if (Services.Database.get_default ().update_section_item_id (current_id, new_id)) { + foreach (var item in items) { + if (item.section_id == current_id) { + item.section_id = new_id; + } + } + } + } + } + + public void archive_section (Objects.Section section) { + if (Services.Database.get_default ().archive_section (section)) { + foreach (Objects.Item item in section.items) { + archive_item (item, section.is_archived); + } + + if (section.is_archived) { + section.archived (); + section_archived (section); + } else { + section.unarchived (); + section_unarchived (section); + } + } + } + + public Gee.ArrayList get_sections_by_project (Objects.Project project) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_sections) { + foreach (var section in sections) { + if (section.project_id == project.id) { + return_value.add (section); + } + } + } + + return return_value; + } + + public Gee.ArrayList get_sections_archived_by_project (Objects.Project project) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_sections) { + foreach (var section in sections) { + if (section.project_id == project.id && section.was_archived ()) { + return_value.add (section); + } + } + } + + return return_value; + } + + public Objects.Section get_section (string id) { + Objects.Section? return_value = null; + lock (_sections) { + foreach (var section in sections) { + if (section.id == id) { + return_value = section; + break; + } + } + + return return_value; + } + } + + /* + * Items + */ + + public void insert_item (Objects.Item item, bool insert = true) { + if (Services.Database.get_default ().insert_item (item, insert)) { + add_item (item, insert); + } + } + + public void add_item (Objects.Item item, bool insert = true) { + items.add (item); + item_added (item, insert); + + if (insert) { + if (item.parent_id != "") { + item.parent.item_added (item); + } else { + if (item.section_id == "") { + item.project.item_added (item); + } else { + item.section.item_added (item); + } + } + } + + Services.EventBus.get_default ().update_items_position (item.project_id, item.section_id); + } + + public void update_item (Objects.Item item, string update_id = "") { + if (Services.Database.get_default ().update_item (item, update_id)) { + item.updated (update_id); + item_updated (item, update_id); + } + } + + public void delete_item (Objects.Item item) { + if (Services.Database.get_default ().delete_item (item)) { + foreach (Objects.Item subitem in item.items) { + delete_item (subitem); + } + + item.deleted (); + } + } + + public void move_item (Objects.Item item) { + if (Services.Database.get_default ().move_item (item)) { + foreach (Objects.Item subitem in item.items) { + subitem.project_id = item.project_id; + move_item (subitem); + } + + item.updated (); + item_updated (item, ""); + } + } + + public void checked_toggled (Objects.Item item, bool old_checked) { + if (Services.Database.get_default ().checked_toggled (item, old_checked)) { + foreach (Objects.Item subitem in item.items) { + subitem.checked = item.checked; + subitem.completed_at = item.completed_at; + checked_toggled (subitem, old_checked); + } + + item.updated (); + item_updated (item, ""); + + Services.EventBus.get_default ().checked_toggled (item, old_checked); + } + } + + public void archive_item (Objects.Item item, bool is_archived) { + if (is_archived) { + item.archived (); + item_archived (item); + } else { + item.unarchived (); + item_unarchived (item); + } + + foreach (Objects.Item subitem in item.items) { + archive_item (subitem, is_archived); + } + } + + public void update_item_id (string current_id, string new_id) { + if (Services.Database.get_default ().update_item_id (current_id, new_id)) { + foreach (var item in items) { + if (item.id == current_id) { + item.id = new_id; + } + } + + if (Services.Database.get_default ().update_item_child_id (current_id, new_id)) { + foreach (var item in items) { + if (item.parent_id == current_id) { + item.parent_id = new_id; + } + } + } + } + } + + public int next_item_child_order (string project_id, string section_id) { + int child_order = 0; + + lock (_items) { + foreach (var item in items) { + if (item.project_id == project_id && item.section_id == section_id) { + child_order++; + } + } + + return child_order; + } + } + + public Objects.Item get_item (string id) { + Objects.Item? return_value = null; + lock (_items) { + foreach (var item in items) { + if (item.id == id) { + return_value = item; + break; + } + } + + return return_value; + } + } + + public Objects.Item get_item_by_ics (string ics) { + Objects.Item? return_value = null; + lock (_items) { + foreach (var item in items) { + if (item.ics == ics) { + return_value = item; + break; + } + } + + return return_value; + } + } + + public Gee.ArrayList get_item_by_baseobject (Objects.BaseObject object) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (var item in items) { + if (object is Objects.Project) { + if (item.project_id == object.id && item.section_id == "" && !item.has_parent) { + return_value.add (item); + } + } + + if (object is Objects.Section) { + if (item.section_id == object.id && !item.has_parent) { + return_value.add (item); + } + } + } + } + + return return_value; + } + + public Gee.ArrayList get_items_checked () { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.checked) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_checked_by_project (Objects.Project project) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.project_id == project.id && item.checked) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_subitems (Objects.Item i) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (var item in items) { + if (item.parent_id == i.id) { + return_value.add (item); + } + } + } + + return return_value; + } + + public Gee.ArrayList get_items_by_project (Objects.Project project) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.exists_project (project)) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_by_date (GLib.DateTime date, bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (valid_item_by_date (item, date, checked)) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_no_date (bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (!item.has_due && item.checked == checked) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_repeating (bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.has_due && item.due.is_recurring && item.checked == checked && !item.was_archived ()) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_by_date_range (GLib.DateTime start_date, GLib.DateTime end_date, bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (valid_item_by_date_range (item, start_date, end_date, checked)) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_by_month (GLib.DateTime date, bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (valid_item_by_month (item, date, checked)) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_pinned (bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.pinned && item.checked == checked && !item.was_archived ()) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_by_priority (int priority, bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.priority == priority && item.checked == checked && !item.was_archived ()) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_completed () { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.checked && !item.was_archived ()) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_by_label (Objects.Label label, bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.has_label (label.id) && item.checked == checked && !item.was_archived ()) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_unlabeled (bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.labels.size <= 0 && item.checked == checked && !item.was_archived ()) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_by_scheduled (bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.has_due && + !item.was_archived () && + item.checked == checked && + item.due.datetime.compare (new GLib.DateTime.now_local ()) > 0) { + return_value.add (item); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_items_no_parent (bool checked = true) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (!item.was_archived () && + item.checked == checked && + !item.has_parent) { + return_value.add (item); + } + } + + return return_value; + } + } + + public bool valid_item_by_date (Objects.Item item, GLib.DateTime date, bool checked = true) { + if (!item.has_due || item.was_archived ()) { + return false; + } + + return (item.checked == checked && Utils.Datetime.is_same_day (item.due.datetime, date)); + } + + public bool valid_item_by_date_range (Objects.Item item, GLib.DateTime start_date, GLib.DateTime end_date, bool checked = true) { + if (!item.has_due || item.was_archived ()) { + return false; + } + + var date = Utils.Datetime.get_format_date (item.due.datetime); + var start = Utils.Datetime.get_format_date (start_date); + var end = Utils.Datetime.get_format_date (end_date); + + return (item.checked == checked && date.compare (start) >= 0 && date.compare (end) <= 0); + } + + public bool valid_item_by_month (Objects.Item item, GLib.DateTime date, bool checked = true) { + if (!item.has_due || item.was_archived ()) { + return false; + } + + return (item.checked == checked && item.due.datetime.get_month () == date.get_month () && + item.due.datetime.get_year () == date.get_year ()); + } + + public Gee.ArrayList get_items_by_overdeue_view (bool checked = true) { + GLib.DateTime date_now = new GLib.DateTime.now_local (); + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.has_due && + !item.was_archived () && + item.checked == checked && + item.due.datetime.compare (date_now) < 0 && + !Utils.Datetime.is_same_day (item.due.datetime, date_now)) { + return_value.add (item); + } + } + + return return_value; + } + } + + public bool valid_item_by_overdue (Objects.Item item, GLib.DateTime date, bool checked = true) { + if (!item.has_due || item.was_archived ()) { + return false; + } + + return (item.checked == checked && + item.due.datetime.compare (new GLib.DateTime.now_local ()) < 0 && + !Utils.Datetime.is_same_day (item.due.datetime, new GLib.DateTime.now_local ())); + } + + /* + * Labels + */ + + public void insert_label (Objects.Label label) { + if (Services.Database.get_default ().insert_label (label)) { + labels.add (label); + label_added (label); + } + } + + public void delete_label (Objects.Label label) { + if (Services.Database.get_default ().delete_label (label)) { + label.deleted (); + } + } + + public void update_label (Objects.Label label) { + if (Services.Database.get_default ().update_label (label)) { + label.updated (); + label_updated (label); + } + } + + public Gee.ArrayList get_labels_by_item_labels (string labels) { + Gee.ArrayList return_value = new Gee.ArrayList (); + + foreach (string id in labels.split (";")) { + Objects.Label? label = get_label (id); + if (label != null) { + return_value.add (label); + } + } + + return return_value; + } + + 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 Gee.ArrayList get_items_has_labels () { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (Objects.Item item in items) { + if (item.has_labels () && !item.completed && !item.was_archived ()) { + return_value.add (item); + } + } + + return return_value; + } + } + + public bool label_exists (string id) { + bool return_value = false; + lock (_labels) { + foreach (var label in _labels) { + if (label.id == id) { + return_value = true; + break; + } + } + + return return_value; + } + } + + public Objects.Label get_label (string id) { + Objects.Label? return_value = null; + lock (_labels) { + foreach (var label in labels) { + if (label.id == id) { + return_value = label; + break; + } + } + + return return_value; + } + } + + public Objects.Label? get_label_by_name (string name, bool lowercase = false, string source_id) { + lock (_labels) { + string compare_name = lowercase ? name.down () : name; + + foreach (var label in labels) { + string label_name = lowercase ? label.name.down () : label.name; + if (label.source_id == source_id && label_name == compare_name) { + return label; + } + } + + return null; + } + } + + public Gee.ArrayList get_labels_by_backend_type (BackendType backend_type) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_labels) { + foreach (var label in labels) { + if (backend_type == BackendType.ALL ? true : label.backend_type == backend_type) { + return_value.add (label); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_labels_by_source (string source_id) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_labels) { + foreach (var label in labels) { + if (label.source_id == source_id) { + return_value.add (label); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_all_labels_by_search (string search_text) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_labels) { + foreach (var label in labels) { + if (search_text.down () in label.name.down ()) { + return_value.add (label); + } + } + + return return_value; + } + } + + /* + * Quick Find + */ + + public Gee.ArrayList get_all_projects_by_search (string search_text) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (search_text.down () in project.name.down () && !project.is_archived) { + return_value.add (project); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_all_sections_by_search (string search_text) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var section in sections) { + if (search_text.down () in section.name.down () && !section.was_archived ()) { + return_value.add (section); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_all_projects_by_todoist () { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (project.backend_type == BackendType.TODOIST) { + return_value.add (project); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_all_projects_by_backend_type (BackendType backend_type) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (project.backend_type == backend_type) { + return_value.add (project); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_all_projects_archived () { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_projects) { + foreach (var project in projects) { + if (project.is_archived) { + return_value.add (project); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_all_labels_by_todoist () { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_labels) { + foreach (var label in labels) { + if (label.backend_type == BackendType.TODOIST) { + return_value.add (label); + } + } + + return return_value; + } + } + + public Gee.ArrayList get_all_items_by_search (string search_text) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_items) { + foreach (var item in items) { + if (!item.checked && !item.was_archived () && (search_text.down () in item.content.down () || + search_text.down () in item.description.down ())) { + return_value.add (item); + } + } + + return return_value; + } + } + + // Reminders + public void insert_reminder (Objects.Reminder reminder) { + if (Services.Database.get_default ().insert_reminder (reminder)) { + reminder_added (reminder); + reminders.add (reminder); + reminder.item.reminder_added (reminder); + } + } + + public void delete_reminder (Objects.Reminder reminder) { + if (Services.Database.get_default ().delete_reminder (reminder)) { + reminder.deleted (); + reminder.item.reminder_deleted (reminder); + } + } + + public Gee.ArrayList get_reminders_by_item (Objects.Item item) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_reminders) { + foreach (var reminder in reminders) { + if (reminder.item_id == item.id) { + return_value.add (reminder); + } + } + + return return_value; + } + } + + public Objects.Reminder get_reminder (string id) { + Objects.Reminder? return_value = null; + lock (_reminders) { + foreach (var reminder in reminders) { + if (reminder.id == id) { + return_value = reminder; + break; + } + } + + return return_value; + } + } + + // Atrachments + public void insert_attachment (Objects.Attachment attachment) { + if (Services.Database.get_default ().insert_attachment (attachment)) { + attachments.add (attachment); + attachment.item.attachment_added (attachment); + } + } + + public void delete_attachment (Objects.Attachment attachment) { + if (Services.Database.get_default ().delete_attachment (attachment)) { + attachment.deleted (); + attachment.item.attachment_deleted (attachment); + } + } + + public Gee.ArrayList get_attachments_by_item (Objects.Item item) { + Gee.ArrayList return_value = new Gee.ArrayList (); + lock (_attachments) { + foreach (var attachment in attachments) { + if (attachment.item_id == item.id) { + return_value.add (attachment); + } + } + + return return_value; + } + } +} \ No newline at end of file diff --git a/core/Services/Todoist.vala b/core/Services/Todoist.vala index ab647b28c..4c614bf3c 100644 --- a/core/Services/Todoist.vala +++ b/core/Services/Todoist.vala @@ -58,18 +58,6 @@ public class Services.Todoist : GLib.Object { // }); } - public void run_server () { - // sync_async (); - - // server_timeout = Timeout.add_seconds (15 * 60, () => { - // if (Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server")) { - // sync_async (); - // } - - // return true; - // }); - } - public bool invalid_token () { return Services.Settings.get_default ().settings.get_string ("todoist-access-token").strip () == ""; } @@ -143,12 +131,12 @@ public class Services.Todoist : GLib.Object { source.data = todoist_data; - Services.Database.get_default ().insert_source (source); + Services.Store.instance ().insert_source (source); // Create Labels unowned Json.Array labels = parser.get_root ().get_object ().get_array_member (LABELS_COLLECTION); foreach (unowned Json.Node _node in labels.get_elements ()) { - Services.Database.get_default ().insert_label (new Objects.Label.from_json (_node)); + Services.Store.instance ().insert_label (new Objects.Label.from_json (_node)); } // Create Projects @@ -158,12 +146,12 @@ public class Services.Todoist : GLib.Object { _project.source_id = source.id; if (!_node.get_object ().get_null_member ("parent_id")) { - Objects.Project? project = Services.Database.get_default ().get_project (_node.get_object ().get_string_member ("parent_id")); + Objects.Project? project = Services.Store.instance ().get_project (_node.get_object ().get_string_member ("parent_id")); if (project != null) { project.add_subproject_if_not_exists (_project); } } else { - Services.Database.get_default ().insert_project (_project); + Services.Store.instance ().insert_project (_project); } } @@ -183,7 +171,7 @@ public class Services.Todoist : GLib.Object { unowned Json.Array reminders = parser.get_root ().get_object ().get_array_member (REMINDERS_COLLECTION); foreach (unowned Json.Node _node in reminders.get_elements ()) { Objects.Reminder reminder = new Objects.Reminder.from_json (_node); - Objects.Item? item = Services.Database.get_default ().get_item (reminder.item_id); + Objects.Item? item = Services.Store.instance ().get_item (reminder.item_id); if (item != null) { item.add_reminder_if_not_exists (reminder); } @@ -250,32 +238,32 @@ public class Services.Todoist : GLib.Object { unowned Json.Array _labels = parser.get_root ().get_object ().get_array_member (LABELS_COLLECTION); foreach (unowned Json.Node _node in _labels.get_elements ()) { string _id = _node.get_object ().get_string_member ("id"); - Objects.Label? label = Services.Database.get_default ().get_label (_id); + Objects.Label? label = Services.Store.instance ().get_label (_id); if (label != null) { if (_node.get_object ().get_boolean_member ("is_deleted")) { - Services.Database.get_default ().delete_label (label); + Services.Store.instance ().delete_label (label); } else { label.update_from_json (_node); - Services.Database.get_default ().update_label (label); + Services.Store.instance ().update_label (label); } } else { - Services.Database.get_default ().insert_label (new Objects.Label.from_json (_node)); + Services.Store.instance ().insert_label (new Objects.Label.from_json (_node)); } } // Projects unowned Json.Array projects = parser.get_root ().get_object ().get_array_member (PROJECTS_COLLECTION); foreach (unowned Json.Node _node in projects.get_elements ()) { - Objects.Project? project = Services.Database.get_default ().get_project (_node.get_object ().get_string_member ("id")); + Objects.Project? project = Services.Store.instance ().get_project (_node.get_object ().get_string_member ("id")); if (project != null) { if (_node.get_object ().get_boolean_member ("is_deleted")) { - Services.Database.get_default ().delete_project (project); + Services.Store.instance ().delete_project (project); } else { string old_parent_id = project.parent_id; bool old_is_favorite = project.is_favorite; project.update_from_json (_node); - Services.Database.get_default ().update_project (project); + Services.Store.instance ().update_project (project); if (project.parent_id != old_parent_id) { Services.EventBus.get_default ().project_parent_changed (project, old_parent_id); @@ -286,20 +274,23 @@ public class Services.Todoist : GLib.Object { } } } else { - Services.Database.get_default ().insert_project (new Objects.Project.from_json (_node)); + var _project = new Objects.Project.from_json (_node); + _project.source_id = source.id; + + Services.Store.instance ().insert_project (_project); } } // Sections unowned Json.Array sections = parser.get_root ().get_object ().get_array_member (SECTIONS_COLLECTION); foreach (unowned Json.Node _node in sections.get_elements ()) { - Objects.Section? section = Services.Database.get_default ().get_section (_node.get_object ().get_string_member ("id")); + Objects.Section? section = Services.Store.instance ().get_section (_node.get_object ().get_string_member ("id")); if (section != null) { if (_node.get_object ().get_boolean_member ("is_deleted")) { - Services.Database.get_default ().delete_section (section); + Services.Store.instance ().delete_section (section); } else { section.update_from_json (_node); - Services.Database.get_default ().update_section (section); + Services.Store.instance ().update_section (section); } } else { add_section_if_not_exists (_node); @@ -309,17 +300,17 @@ public class Services.Todoist : GLib.Object { // Items unowned Json.Array items = parser.get_root ().get_object ().get_array_member (ITEMS_COLLECTION); foreach (unowned Json.Node _node in items.get_elements ()) { - Objects.Item? item = Services.Database.get_default ().get_item (_node.get_object ().get_string_member ("id")); + Objects.Item? item = Services.Store.instance ().get_item (_node.get_object ().get_string_member ("id")); if (item != null) { if (_node.get_object ().get_boolean_member ("is_deleted")) { - Services.Database.get_default ().delete_item (item); + Services.Store.instance ().delete_item (item); } else { string old_project_id = item.project_id; string old_section_id = item.section_id; string old_parent_id = item.parent_id; item.update_from_json (_node); - Services.Database.get_default ().update_item (item); + Services.Store.instance ().update_item (item); if (old_project_id != item.project_id || old_section_id != item.section_id || old_parent_id != item.parent_id) { @@ -328,7 +319,7 @@ public class Services.Todoist : GLib.Object { bool old_checked = item.checked; if (old_checked != item.checked) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } } } else { @@ -339,16 +330,16 @@ public class Services.Todoist : GLib.Object { // Reminders unowned Json.Array reminders = parser.get_root ().get_object ().get_array_member (REMINDERS_COLLECTION); foreach (unowned Json.Node _node in reminders.get_elements ()) { - Objects.Reminder? reminder = Services.Database.get_default ().get_reminder (_node.get_object ().get_string_member ("id")); + Objects.Reminder? reminder = Services.Store.instance ().get_reminder (_node.get_object ().get_string_member ("id")); if (reminder != null) { if (_node.get_object ().get_boolean_member ("is_deleted")) { - Services.Database.get_default ().delete_reminder (reminder); + Services.Store.instance ().delete_reminder (reminder); } } else { reminder = new Objects.Reminder.from_json (_node); - Objects.Item? item = Services.Database.get_default ().get_item (reminder.item_id); + Objects.Item? item = Services.Store.instance ().get_item (reminder.item_id); if (item != null) { item.add_reminder_if_not_exists (reminder); } @@ -397,19 +388,19 @@ public class Services.Todoist : GLib.Object { if (uuid_member.get_node_type () == Json.NodeType.VALUE) { if (q.query == "project_add") { var id = node.get_object_member ("temp_id_mapping").get_string_member (q.temp_id); - Services.Database.get_default ().update_project_id (q.object_id, id); + Services.Store.instance ().update_project_id (q.object_id, id); Services.Database.get_default ().remove_CurTempIds (q.object_id); } if (q.query == "section_add") { var id = node.get_object_member ("temp_id_mapping").get_string_member (q.temp_id); - Services.Database.get_default ().update_section_id (q.object_id, id); + Services.Store.instance ().update_section_id (q.object_id, id); Services.Database.get_default ().remove_CurTempIds (q.object_id); } if (q.query == "item_add") { var id = node.get_object_member ("temp_id_mapping").get_string_member (q.temp_id); - Services.Database.get_default ().update_item_id (q.object_id, id); + Services.Store.instance ().update_item_id (q.object_id, id); Services.Database.get_default ().remove_CurTempIds (q.object_id); } @@ -737,7 +728,7 @@ public class Services.Todoist : GLib.Object { private void add_item_if_not_exists (Json.Node node) { if (!node.get_object ().get_null_member ("parent_id")) { - Objects.Item? item = Services.Database.get_default ().get_item (node.get_object ().get_string_member ("parent_id")); + Objects.Item? item = Services.Store.instance ().get_item (node.get_object ().get_string_member ("parent_id")); if (item != null) { item.add_item_if_not_exists (new Objects.Item.from_json (node)); } @@ -746,12 +737,12 @@ public class Services.Todoist : GLib.Object { } if (!node.get_object ().get_null_member ("section_id")) { - Objects.Section? section = Services.Database.get_default ().get_section (node.get_object ().get_string_member ("section_id")); + Objects.Section? section = Services.Store.instance ().get_section (node.get_object ().get_string_member ("section_id")); if (section != null) { section.add_item_if_not_exists (new Objects.Item.from_json (node)); } } else { - Objects.Project? project = Services.Database.get_default ().get_project (node.get_object ().get_string_member ("project_id")); + Objects.Project? project = Services.Store.instance ().get_project (node.get_object ().get_string_member ("project_id")); if (project != null) { project.add_item_if_not_exists (new Objects.Item.from_json (node)); } @@ -1086,7 +1077,7 @@ public class Services.Todoist : GLib.Object { private void add_section_if_not_exists (Json.Node node) { string _id = node.get_object ().get_string_member ("project_id"); - Objects.Project? project = Services.Database.get_default ().get_project (_id); + Objects.Project? project = Services.Store.instance ().get_project (_id); if (project != null) { project.add_section_if_not_exists (new Objects.Section.from_json (node)); } @@ -1535,6 +1526,7 @@ public class HttpResponse { public int http_code { get; set; default = 0; } public string data { get; set; } + public GLib.Value data_object { get; set; } public void from_error_json (Json.Node node) { status = false; diff --git a/core/Util/Util.vala b/core/Util/Util.vala index a37c9fa09..55f4e2614 100644 --- a/core/Util/Util.vala +++ b/core/Util/Util.vala @@ -165,7 +165,7 @@ public class Util : GLib.Object { return Uuid.string_random (); } - var collection = Services.Database.get_default ().get_collection_by_type (base_object); + var collection = Services.Store.instance ().get_collection_by_type (base_object); var id = Uuid.string_random (); if (check_id_exists (collection, id)) { @@ -571,7 +571,7 @@ public class Util : GLib.Object { Objects.Source local_source = new Objects.Source (); local_source.id = BackendType.LOCAL.to_string (); local_source.source_type = BackendType.LOCAL; - Services.Database.get_default ().insert_source (local_source); + Services.Store.instance ().insert_source (local_source); return local_source; } @@ -583,10 +583,9 @@ public class Util : GLib.Object { inbox_project.name = _("Inbox"); inbox_project.inbox_project = true; inbox_project.color = "blue"; - - if (Services.Database.get_default ().insert_project (inbox_project)) { - Services.Settings.get_default ().settings.set_string ("local-inbox-project-id", inbox_project.id); - } + + Services.Store.instance ().insert_project (inbox_project); + Services.Settings.get_default ().settings.set_string ("local-inbox-project-id", inbox_project.id); return inbox_project; } @@ -603,108 +602,108 @@ public class Util : GLib.Object { project.show_completed = true; project.description = _("This project shows you everything you need to know to hit the ground running. Don’t hesitate to play around in it – you can always create a new one from settings."); - if (Services.Database.get_default ().insert_project (project)) { - var item_01 = new Objects.Item (); - item_01.id = Util.get_default ().generate_id (item_01); - item_01.project_id = project.id; - item_01.content = _("Tap this to-do"); - item_01.description = _("You're looking at a to-do! Complete it by tapping the checkbox on the left. Completed to-dos are collected at the bottom of your project."); - - var item_02 = new Objects.Item (); - item_02.id = Util.get_default ().generate_id (item_02); - item_02.project_id = project.id; - item_02.content = _("Create a new to-do"); - item_02.description = _("Now it's your turn, tap the '+' button at the bottom of your project, enter any pending and tap the blue 'Save' button."); - - var item_03 = new Objects.Item (); - item_03.id = Util.get_default ().generate_id (item_03); - item_03.project_id = project.id; - item_03.content = _("Plan this to-do by today or later"); - item_03.description = _("Tap the calendar button at the bottom to decide when to do this to-do."); - - var item_04 = new Objects.Item (); - item_04.id = Util.get_default ().generate_id (item_04); - item_04.project_id = project.id; - item_04.content = _("Reorder yours to-dos"); - item_04.description = _("To reorder your list, tap and hold a to-do, then drag it to where it should go."); - - var item_05 = new Objects.Item (); - item_05.id = Util.get_default ().generate_id (item_05); - item_05.project_id = project.id; - item_05.content = _("Create a project"); - item_05.description = _("Organize your to-dos better! Go to the left panel and click the '+' button in the 'On This Computer' section and add a project of your own."); - - var item_06 = new Objects.Item (); - item_06.id = Util.get_default ().generate_id (item_06); - item_06.project_id = project.id; - item_06.content = _("You’re done!"); - item_06.description = _("""That’s all you really need to know. Feel free to start adding your own projects and to-dos. + Services.Store.instance ().insert_project (project); + + var item_01 = new Objects.Item (); + item_01.id = Util.get_default ().generate_id (item_01); + item_01.project_id = project.id; + item_01.content = _("Tap this to-do"); + item_01.description = _("You're looking at a to-do! Complete it by tapping the checkbox on the left. Completed to-dos are collected at the bottom of your project."); + + var item_02 = new Objects.Item (); + item_02.id = Util.get_default ().generate_id (item_02); + item_02.project_id = project.id; + item_02.content = _("Create a new to-do"); + item_02.description = _("Now it's your turn, tap the '+' button at the bottom of your project, enter any pending and tap the blue 'Save' button."); + + var item_03 = new Objects.Item (); + item_03.id = Util.get_default ().generate_id (item_03); + item_03.project_id = project.id; + item_03.content = _("Plan this to-do by today or later"); + item_03.description = _("Tap the calendar button at the bottom to decide when to do this to-do."); + + var item_04 = new Objects.Item (); + item_04.id = Util.get_default ().generate_id (item_04); + item_04.project_id = project.id; + item_04.content = _("Reorder yours to-dos"); + item_04.description = _("To reorder your list, tap and hold a to-do, then drag it to where it should go."); + + var item_05 = new Objects.Item (); + item_05.id = Util.get_default ().generate_id (item_05); + item_05.project_id = project.id; + item_05.content = _("Create a project"); + item_05.description = _("Organize your to-dos better! Go to the left panel and click the '+' button in the 'On This Computer' section and add a project of your own."); + + var item_06 = new Objects.Item (); + item_06.id = Util.get_default ().generate_id (item_06); + item_06.project_id = project.id; + item_06.content = _("You’re done!"); + item_06.description = _("""That’s all you really need to know. Feel free to start adding your own projects and to-dos. You can come back to this project later to learn the advanced features below.. We hope you’ll enjoy using Planify!"""); - project.add_item_if_not_exists (item_01); - project.add_item_if_not_exists (item_02); - project.add_item_if_not_exists (item_03); - project.add_item_if_not_exists (item_04); - project.add_item_if_not_exists (item_05); - project.add_item_if_not_exists (item_06); - - var section_01 = new Objects.Section (); - section_01.id = Util.get_default ().generate_id (section_01); - section_01.project_id = project.id; - section_01.name = _("Tune your setup"); - - project.add_section_if_not_exists (section_01); - - var item_02_01 = new Objects.Item (); - item_02_01.id = Util.get_default ().generate_id (item_02_01); - item_02_01.project_id = project.id; - item_02_01.section_id = section_01.id; - item_02_01.content = _("Show your calendar events"); - item_02_01.description = _("You can display your system's calendar events in Planify. Go to 'Preferences' 🡒 General 🡒 Calendar Events to turn it on."); - - var item_02_02 = new Objects.Item (); - item_02_02.id = Util.get_default ().generate_id (item_02_02); - item_02_02.project_id = project.id; - item_02_02.section_id = section_01.id; - item_02_02.content = _("Enable synchronization with third-party service."); - item_02_02.description = _("Planify not only creates tasks locally, it can also synchronize your Todoist account. Go to 'Preferences' 🡒 'Accounts'."); - - section_01.add_item_if_not_exists (item_02_01); - section_01.add_item_if_not_exists (item_02_02); - - var section_02 = new Objects.Section (); - section_02.id = Util.get_default ().generate_id (section_01); - section_02.project_id = project.id; - section_02.name = _("Boost your productivity"); - - project.add_section_if_not_exists (section_02); - - var item_03_01 = new Objects.Item (); - item_03_01.id = Util.get_default ().generate_id (item_03_01); - item_03_01.project_id = project.id; - item_03_01.section_id = section_02.id; - item_03_01.content = _("Drag the plus button!"); - item_03_01.description = _("That blue button you see at the bottom of each screen is more powerful than it looks: it's made to move! Drag it up to create a task wherever you want."); - - var item_03_02 = new Objects.Item (); - item_03_02.id = Util.get_default ().generate_id (item_03_02); - item_03_02.project_id = project.id; - item_03_02.section_id = section_02.id; - item_03_02.content = _("Tag your to-dos!"); - item_03_02.description = _("Tags allow you to improve your workflow in Planify. To add a Tag click on the tag button at the bottom."); - - var item_03_03 = new Objects.Item (); - item_03_03.id = Util.get_default ().generate_id (item_03_03); - item_03_03.project_id = project.id; - item_03_03.section_id = section_02.id; - item_03_03.content = _("Set timely reminders!"); - item_03_03.description = _("You want Planify to send you a notification to remind you of an important event or something special. Tap the bell button below to add a reminder."); - - section_02.add_item_if_not_exists (item_03_01); - section_02.add_item_if_not_exists (item_03_02); - section_02.add_item_if_not_exists (item_03_03); - } + project.add_item_if_not_exists (item_01); + project.add_item_if_not_exists (item_02); + project.add_item_if_not_exists (item_03); + project.add_item_if_not_exists (item_04); + project.add_item_if_not_exists (item_05); + project.add_item_if_not_exists (item_06); + + var section_01 = new Objects.Section (); + section_01.id = Util.get_default ().generate_id (section_01); + section_01.project_id = project.id; + section_01.name = _("Tune your setup"); + + project.add_section_if_not_exists (section_01); + + var item_02_01 = new Objects.Item (); + item_02_01.id = Util.get_default ().generate_id (item_02_01); + item_02_01.project_id = project.id; + item_02_01.section_id = section_01.id; + item_02_01.content = _("Show your calendar events"); + item_02_01.description = _("You can display your system's calendar events in Planify. Go to 'Preferences' 🡒 General 🡒 Calendar Events to turn it on."); + + var item_02_02 = new Objects.Item (); + item_02_02.id = Util.get_default ().generate_id (item_02_02); + item_02_02.project_id = project.id; + item_02_02.section_id = section_01.id; + item_02_02.content = _("Enable synchronization with third-party service."); + item_02_02.description = _("Planify not only creates tasks locally, it can also synchronize your Todoist account. Go to 'Preferences' 🡒 'Accounts'."); + + section_01.add_item_if_not_exists (item_02_01); + section_01.add_item_if_not_exists (item_02_02); + + var section_02 = new Objects.Section (); + section_02.id = Util.get_default ().generate_id (section_01); + section_02.project_id = project.id; + section_02.name = _("Boost your productivity"); + + project.add_section_if_not_exists (section_02); + + var item_03_01 = new Objects.Item (); + item_03_01.id = Util.get_default ().generate_id (item_03_01); + item_03_01.project_id = project.id; + item_03_01.section_id = section_02.id; + item_03_01.content = _("Drag the plus button!"); + item_03_01.description = _("That blue button you see at the bottom of each screen is more powerful than it looks: it's made to move! Drag it up to create a task wherever you want."); + + var item_03_02 = new Objects.Item (); + item_03_02.id = Util.get_default ().generate_id (item_03_02); + item_03_02.project_id = project.id; + item_03_02.section_id = section_02.id; + item_03_02.content = _("Tag your to-dos!"); + item_03_02.description = _("Tags allow you to improve your workflow in Planify. To add a Tag click on the tag button at the bottom."); + + var item_03_03 = new Objects.Item (); + item_03_03.id = Util.get_default ().generate_id (item_03_03); + item_03_03.project_id = project.id; + item_03_03.section_id = section_02.id; + item_03_03.content = _("Set timely reminders!"); + item_03_03.description = _("You want Planify to send you a notification to remind you of an important event or something special. Tap the bell button below to add a reminder."); + + section_02.add_item_if_not_exists (item_03_01); + section_02.add_item_if_not_exists (item_03_02); + section_02.add_item_if_not_exists (item_03_03); } public void create_default_labels () { @@ -738,11 +737,11 @@ We hope you’ll enjoy using Planify!"""); label_05.name = _("🏃‍♀️️Follow Up"); label_05.color = "grey"; - Services.Database.get_default ().insert_label (label_01); - Services.Database.get_default ().insert_label (label_02); - Services.Database.get_default ().insert_label (label_03); - Services.Database.get_default ().insert_label (label_04); - Services.Database.get_default ().insert_label (label_05); + Services.Store.instance ().insert_label (label_01); + Services.Store.instance ().insert_label (label_02); + Services.Store.instance ().insert_label (label_03); + Services.Store.instance ().insert_label (label_04); + Services.Store.instance ().insert_label (label_05); } public BackendType get_backend_type_by_text (string backend_type) { @@ -1032,7 +1031,7 @@ We hope you’ll enjoy using Planify!"""); if (project.backend_type == BackendType.LOCAL) { new_project.id = Util.get_default ().generate_id (new_project); new_project.backend_type = BackendType.LOCAL; - Services.Database.get_default ().insert_project (new_project); + Services.Store.instance ().insert_project (new_project); foreach (Objects.Item item in project.items) { yield duplicate_item (item, new_project.id, item.section_id, item.parent_id, false); @@ -1062,7 +1061,7 @@ We hope you’ll enjoy using Planify!"""); bool status = yield Services.CalDAV.Core.get_default ().add_tasklist (new_project); if (status) { - Services.Database.get_default ().insert_project (new_project); + Services.Store.instance ().insert_project (new_project); foreach (Objects.Item item in project.items) { yield duplicate_item (item, new_project.id, "", item.parent_id, false); diff --git a/core/Widgets/LabelsPickerCore.vala b/core/Widgets/LabelsPickerCore.vala index c59522073..d4d714567 100644 --- a/core/Widgets/LabelsPickerCore.vala +++ b/core/Widgets/LabelsPickerCore.vala @@ -152,7 +152,7 @@ public class Widgets.LabelsPickerCore : Adw.Bin { search_entry.activate.connect (() => { if (search_entry.text.length > 0) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (search_entry.text, true, source.id); + Objects.Label label = Services.Store.instance ().get_label_by_name (search_entry.text, true, source.id); if (label != null) { if (labels_widgets_map.has_key (label.id_string)) { labels_widgets_map [label.id_string].update_checked_toggled (); @@ -163,7 +163,7 @@ public class Widgets.LabelsPickerCore : Adw.Bin { } }); - Services.Database.get_default ().label_added.connect ((label) => { + Services.Store.instance ().label_added.connect ((label) => { add_label (label); }); } @@ -176,7 +176,7 @@ public class Widgets.LabelsPickerCore : Adw.Bin { if (source.source_type == BackendType.LOCAL || source.source_type == BackendType.CALDAV) { label.id = Util.get_default ().generate_id (label); - Services.Database.get_default ().insert_label (label); + Services.Store.instance ().insert_label (label); checked_toggled (label, true); search_entry.text = ""; @@ -188,7 +188,7 @@ public class Widgets.LabelsPickerCore : Adw.Bin { if (response.status) { label.id = response.data; - Services.Database.get_default ().insert_label (label); + Services.Store.instance ().insert_label (label); checked_toggled (label, true); } @@ -206,7 +206,7 @@ public class Widgets.LabelsPickerCore : Adw.Bin { listbox.remove (child); } - foreach (Objects.Label label in Services.Database.get_default ().get_labels_by_source (source.id)) { + foreach (Objects.Label label in Services.Store.instance ().get_labels_by_source (source.id)) { add_label (label); } } diff --git a/core/Widgets/ProjectPicker/ProjectPickerPopover.vala b/core/Widgets/ProjectPicker/ProjectPickerPopover.vala index 419268fb4..54c6b8aac 100644 --- a/core/Widgets/ProjectPicker/ProjectPickerPopover.vala +++ b/core/Widgets/ProjectPicker/ProjectPickerPopover.vala @@ -29,10 +29,10 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover { var scrolled_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); scrolled_box.append (inbox_group); - foreach (Objects.Source source in Services.Database.get_default ().sources) { + foreach (Objects.Source source in Services.Store.instance ().sources) { if (!sources_hashmap.has_key (source.id)) { sources_hashmap[source.id] = new Layouts.HeaderItem (source.header_text) { - reveal_child = Services.Database.get_default ().get_projects_by_source (source.id).size > 0, + reveal_child = Services.Store.instance ().get_projects_by_source (source.id).size > 0, card = true, show_separator = false }; @@ -73,7 +73,7 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover { add_css_class ("popover-no-content"); search_entry.grab_focus (); - foreach (Objects.Project project in Services.Database.get_default ().projects) { + foreach (Objects.Project project in Services.Store.instance ().projects) { var row_listbox = new Widgets.ProjectPicker.ProjectPickerRow (project); row_listbox.selected.connect (() => { diff --git a/core/meson.build b/core/meson.build index e29144715..1e72ded3b 100644 --- a/core/meson.build +++ b/core/meson.build @@ -10,6 +10,7 @@ core_files = files( 'Services/Settings.vala', 'Services/EventBus.vala', 'Services/Database.vala', + 'Services/Store.vala', 'Services/Todoist.vala', 'Services/CalDAV/Core.vala', 'Services/CalDAV/Constants.vala', diff --git a/quick-add/MainWindow.vala b/quick-add/MainWindow.vala index 331a7a613..a1a25bdf4 100644 --- a/quick-add/MainWindow.vala +++ b/quick-add/MainWindow.vala @@ -29,25 +29,25 @@ public class MainWindow : Adw.ApplicationWindow { } private void add_item_db (Objects.Item item, Gee.ArrayList reminders) { - if (Services.Database.get_default ().insert_item (item)) { - if (reminders.size > 0) { - quick_add_widget.is_loading = true; - - foreach (Objects.Reminder reminder in reminders) { - item.add_reminder (reminder); - } - } + Services.Store.instance ().insert_item (item); + + if (reminders.size > 0) { + quick_add_widget.is_loading = true; - if (Services.Settings.get_default ().get_boolean ("automatic-reminders-enabled") && item.has_time) { - var reminder = new Objects.Reminder (); - reminder.mm_offset = Util.get_reminders_mm_offset (); - reminder.reminder_type = ReminderType.RELATIVE; + foreach (Objects.Reminder reminder in reminders) { item.add_reminder (reminder); } + } - send_interface_id (item.id); - quick_add_widget.added_successfully (); + if (Services.Settings.get_default ().get_boolean ("automatic-reminders-enabled") && item.has_time) { + var reminder = new Objects.Reminder (); + reminder.mm_offset = Util.get_reminders_mm_offset (); + reminder.reminder_type = ReminderType.RELATIVE; + item.add_reminder (reminder); } + + send_interface_id (item.id); + quick_add_widget.added_successfully (); } private void send_interface_id (string id) { diff --git a/src/Dialogs/Label.vala b/src/Dialogs/Label.vala index 83a1b357f..4b0459757 100644 --- a/src/Dialogs/Label.vala +++ b/src/Dialogs/Label.vala @@ -136,7 +136,7 @@ public class Dialogs.Label : Adw.Dialog { } private bool is_duplicate (string text) { - Objects.Label label = Services.Database.get_default ().get_label_by_name (text, true, label.source_id); + Objects.Label label = Services.Store.instance ().get_label_by_name (text, true, label.source_id); return label != null; } @@ -157,22 +157,22 @@ public class Dialogs.Label : Adw.Dialog { if (!is_creating) { submit_button.is_loading = true; if (label.backend_type == BackendType.LOCAL || label.backend_type == BackendType.CALDAV) { - Services.Database.get_default ().update_label (label); + Services.Store.instance ().update_label (label); hide_destroy (); } else if (label.backend_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (label, (obj, res) => { Services.Todoist.get_default ().update.end (res); - Services.Database.get_default ().update_label (label); + Services.Store.instance ().update_label (label); submit_button.is_loading = false; hide_destroy (); }); } } else { - label.item_order = Services.Database.get_default ().get_labels_by_backend_type (label.backend_type).size; + label.item_order = Services.Store.instance ().get_labels_by_backend_type (label.backend_type).size; if (label.backend_type == BackendType.LOCAL || label.backend_type == BackendType.CALDAV) { label.id = Util.get_default ().generate_id (label); - Services.Database.get_default ().insert_label (label); + Services.Store.instance ().insert_label (label); hide_destroy (); } else if (label.backend_type == BackendType.TODOIST) { submit_button.is_loading = true; @@ -181,7 +181,7 @@ public class Dialogs.Label : Adw.Dialog { if (response.status) { label.id = response.data; - Services.Database.get_default ().insert_label (label); + Services.Store.instance ().insert_label (label); hide_destroy (); } else { diff --git a/src/Dialogs/ManageProjects.vala b/src/Dialogs/ManageProjects.vala index 535b82ce0..442c22013 100644 --- a/src/Dialogs/ManageProjects.vala +++ b/src/Dialogs/ManageProjects.vala @@ -63,14 +63,14 @@ public class Dialogs.ManageProjects : Adw.Dialog { child = toolbar_view; Services.EventBus.get_default ().disconnect_typing_accel (); - foreach (Objects.Project project in Services.Database.get_default ().get_all_projects_archived ()) { + foreach (Objects.Project project in Services.Store.instance ().get_all_projects_archived ()) { if (project.is_archived) { listbox.append (new Dialogs.ProjectPicker.ProjectPickerRow (project, "menu")); } } - Services.Database.get_default ().project_unarchived.connect (() => { - if (Services.Database.get_default ().get_all_projects_archived ().size <= 0) { + Services.Store.instance ().project_unarchived.connect (() => { + if (Services.Store.instance ().get_all_projects_archived ().size <= 0) { hide_destroy (); } }); diff --git a/src/Dialogs/ManageSectionOrder.vala b/src/Dialogs/ManageSectionOrder.vala index 7348dfc1b..c7420d480 100644 --- a/src/Dialogs/ManageSectionOrder.vala +++ b/src/Dialogs/ManageSectionOrder.vala @@ -108,13 +108,13 @@ public class Dialogs.ManageSectionOrder : Adw.Dialog { return GLib.Source.REMOVE; }); - Services.Database.get_default ().section_deleted.connect ((section) => { + Services.Store.instance ().section_deleted.connect ((section) => { if (section.project_id == project.id) { archived_revealer.reveal_child = project.sections_archived.size > 0; } }); - Services.Database.get_default ().section_unarchived.connect ((section) => { + Services.Store.instance ().section_unarchived.connect ((section) => { if (section.project_id == project.id) { archived_revealer.reveal_child = project.sections_archived.size > 0; } @@ -149,7 +149,7 @@ public class Dialogs.ManageSectionOrder : Adw.Dialog { if (section_row != null) { section_row.section.section_order = row_index; - Services.Database.get_default ().update_section (section_row.section); + Services.Store.instance ().update_section (section_row.section); } row_index++; diff --git a/src/Dialogs/Preferences/PreferencesWindow.vala b/src/Dialogs/Preferences/PreferencesWindow.vala index c668b3884..3333633ce 100644 --- a/src/Dialogs/Preferences/PreferencesWindow.vala +++ b/src/Dialogs/Preferences/PreferencesWindow.vala @@ -875,7 +875,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { toolbar_view.content = content_clamp; Gee.HashMap sources_hashmap = new Gee.HashMap (); - foreach (Objects.Source source in Services.Database.get_default ().sources) { + foreach (Objects.Source source in Services.Store.instance ().sources) { if (!sources_hashmap.has_key (source.id)) { sources_hashmap[source.id] = new Widgets.SourceRow (source); @@ -887,7 +887,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { } } - Services.Database.get_default ().source_added.connect ((source) => { + Services.Store.instance ().source_added.connect ((source) => { if (!sources_hashmap.has_key (source.id)) { sources_hashmap[source.id] = new Widgets.SourceRow (source); @@ -899,7 +899,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { } }); - Services.Database.get_default ().source_deleted.connect ((source) => { + Services.Store.instance ().source_deleted.connect ((source) => { if (sources_hashmap.has_key (source.id)) { sources_hashmap[source.id].hide_destroy (); sources_hashmap.unset (source.id); @@ -915,6 +915,11 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { push_subpage (get_oauth_todoist_page ()); }); + caldav_item.clicked.connect (() => { + popover.popdown (); + push_subpage (get_caldav_setup_page ()); + }); + return new Adw.NavigationPage (toolbar_view, "account"); } @@ -1330,7 +1335,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return page; } - private Adw.NavigationPage get_caldav_setup_page (Gtk.Switch switch_widget) { + private Adw.NavigationPage get_caldav_setup_page () { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Nextcloud Setup")); var server_entry = new Adw.EntryRow (); @@ -1420,7 +1425,6 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { var page = new Adw.NavigationPage (toolbar_view, "oauth-todoist"); settings_header.back_activated.connect (() => { - switch_widget.active = false; pop_subpage (); }); @@ -1480,10 +1484,11 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { cancellable.cancel (); }); - Services.CalDAV.Core.get_default ().login.begin (server_entry.text, username_entry.text, password_entry.text, cancellable, (obj, res) => { + Services.CalDAV.Core.get_default ().login.begin (CalDAVType.parse_index (providers_row.selected), server_entry.text, username_entry.text, password_entry.text, cancellable, (obj, res) => { HttpResponse response = Services.CalDAV.Core.get_default ().login.end (res); if (response.status) { - Services.CalDAV.Core.get_default ().first_sync.begin (); + Objects.Source source = (Objects.Source) response.data_object.get_object (); + Services.CalDAV.Core.get_default ().add_caldav_account.begin (source); } else { login_button.is_loading = false; cancel_button.visible = false; diff --git a/src/Dialogs/Project.vala b/src/Dialogs/Project.vala index 88746eb24..7ab15e4b6 100644 --- a/src/Dialogs/Project.vala +++ b/src/Dialogs/Project.vala @@ -123,7 +123,7 @@ public class Dialogs.Project : Adw.Dialog { name_group.add (emoji_switch_row); var backend_model = new Gtk.StringList (null); - foreach (Objects.Source source in Services.Database.get_default ().sources) { + foreach (Objects.Source source in Services.Store.instance ().sources) { backend_model.append (source.header_text); } @@ -294,18 +294,18 @@ public class Dialogs.Project : Adw.Dialog { private void update_project () { if (project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_project (project); + Services.Store.instance ().update_project (project); hide_destroy (); } else if (project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (project, (obj, res) => { Services.Todoist.get_default ().update.end (res); - Services.Database.get_default ().update_project (project); + Services.Store.instance ().update_project (project); hide_destroy (); }); } else if (project.source_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().update_tasklist.begin (project, (obj, res) => { if (Services.CalDAV.Core.get_default ().update_tasklist.end (res)) { - Services.Database.get_default ().update_project (project); + Services.Store.instance ().update_project (project); hide_destroy (); } }); @@ -313,11 +313,11 @@ public class Dialogs.Project : Adw.Dialog { } private void add_project () { - project.child_order = Services.Database.get_default ().get_projects_by_backend_type (project.backend_type).size; + project.child_order = Services.Store.instance ().get_projects_by_backend_type (project.backend_type).size; if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.NONE) { project.id = Util.get_default ().generate_id (project); - Services.Database.get_default ().insert_project (project); + Services.Store.instance ().insert_project (project); go_project (project.id_string); } else if (project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().add.begin (project, (obj, res) => { @@ -325,7 +325,7 @@ public class Dialogs.Project : Adw.Dialog { if (response.status) { project.id = response.data; - Services.Database.get_default ().insert_project (project); + Services.Store.instance ().insert_project (project); go_project (project.id_string); } }); @@ -340,7 +340,7 @@ public class Dialogs.Project : Adw.Dialog { project.sync_id = response.data; } - Services.Database.get_default ().insert_project (project); + Services.Store.instance ().insert_project (project); go_project (project.id_string); }); } diff --git a/src/Dialogs/ProjectPicker/ProjectPicker.vala b/src/Dialogs/ProjectPicker/ProjectPicker.vala index 6b1a1756e..c8038d0b8 100644 --- a/src/Dialogs/ProjectPicker/ProjectPicker.vala +++ b/src/Dialogs/ProjectPicker/ProjectPicker.vala @@ -20,18 +20,14 @@ */ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Dialog { - public BackendType backend_type { get; construct; } public PickerType picker_type { get; construct; } + public Objects.Source? source { get; construct; } + public bool all_sources { get; construct; } private Gtk.SearchEntry search_entry; private Gtk.ListBox sections_listbox; private Layouts.HeaderItem inbox_group; - private Layouts.HeaderItem local_group; - private Layouts.HeaderItem todoist_group; - private Layouts.HeaderItem caldav_group; - - public Gee.HashMap projects_hashmap; Objects.Project _project; public Objects.Project project { @@ -64,19 +60,40 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Dialog { public signal void changed (string type, string id); - public ProjectPicker (PickerType picker_type = PickerType.PROJECTS, BackendType backend_type = BackendType.ALL) { + public ProjectPicker.for_project (Objects.Source source) { Object ( - picker_type: picker_type, - backend_type: backend_type, + picker_type: PickerType.PROJECTS, + source: source, + all_sources: false, title: _("Move"), - content_width: 320, - content_height: 450 + content_width: 400, + content_height: 550 ); } - construct { - projects_hashmap = new Gee.HashMap (); + public ProjectPicker.for_projects () { + Object ( + picker_type: PickerType.PROJECTS, + source: null, + all_sources: true, + title: _("Move"), + content_width: 400, + content_height: 550 + ); + } + + public ProjectPicker.for_sections (Objects.Source source) { + Object ( + picker_type: PickerType.SECTIONS, + source: source, + all_sources: false, + title: _("Move"), + content_width: 400, + content_height: 550 + ); + } + construct { var headerbar = new Adw.HeaderBar (); headerbar.add_css_class ("flat"); @@ -109,26 +126,25 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Dialog { var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); content_box.append (headerbar); - content_box.append (search_entry); + // content_box.append (search_entry); content_box.append (main_stack); content_box.append (submit_button); child = content_box; - add_projects (); Services.EventBus.get_default ().disconnect_typing_accel (); - search_entry.search_changed.connect (() => { - local_group.invalidate_filter (); - todoist_group.invalidate_filter (); - caldav_group.invalidate_filter (); - }); + // search_entry.search_changed.connect (() => { + // local_group.invalidate_filter (); + // todoist_group.invalidate_filter (); + // caldav_group.invalidate_filter (); + // }); Services.EventBus.get_default ().project_picker_changed.connect ((id) => { - _project = Services.Database.get_default ().get_project (id); + _project = Services.Store.instance ().get_project (id); }); Services.EventBus.get_default ().section_picker_changed.connect ((id) => { - _section = Services.Database.get_default ().get_section (id); + _section = Services.Store.instance ().get_section (id); }); submit_button.clicked.connect (() => { @@ -162,62 +178,35 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Dialog { private Gtk.Widget build_projects_view () { inbox_group = new Layouts.HeaderItem (null) { margin_top = 12, - card = true - }; - - local_group = new Layouts.HeaderItem (_("On this Computer")) { - card = true - }; - - todoist_group = new Layouts.HeaderItem (_("Todoist")) { - card = true + card = true, + reveal = true }; - caldav_group = new Layouts.HeaderItem (_("Nextcloud")) { - card = true - }; - - inbox_group.reveal = true; - - if (backend_type == BackendType.ALL) { - local_group.reveal = true; - todoist_group.reveal = true; - caldav_group.reveal = true; - } else if (backend_type == BackendType.LOCAL) { - local_group.reveal = true; - todoist_group.reveal = false; - caldav_group.reveal = false; - } else if (backend_type == BackendType.TODOIST) { - local_group.reveal = false; - todoist_group.reveal = true; - caldav_group.reveal = false; - } else if (backend_type == BackendType.CALDAV) { - local_group.reveal = false; - todoist_group.reveal = false; - caldav_group.reveal = true; - } + inbox_group.add_child ( + new Dialogs.ProjectPicker.ProjectPickerRow (Services.Store.instance ().get_inbox_project ()) + ); - local_group.set_filter_func (filter_func); - todoist_group.set_filter_func (filter_func); - caldav_group.set_filter_func (filter_func); - var scrolled_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 6) { margin_start = 12, margin_end = 12 }; scrolled_box.append (inbox_group); - scrolled_box.append (local_group); - scrolled_box.append (todoist_group); - scrolled_box.append (caldav_group); + if (all_sources) { + foreach (Objects.Source source in Services.Store.instance ().sources) { + scrolled_box.append (new Dialogs.ProjectPicker.ProjectPickerSourceRow (source)); + } + } else { + scrolled_box.append (new Dialogs.ProjectPicker.ProjectPickerSourceRow (source)); + } + var scrolled = new Gtk.ScrolledWindow () { hexpand = true, vexpand = true, - hscrollbar_policy = Gtk.PolicyType.NEVER + hscrollbar_policy = Gtk.PolicyType.NEVER, + child = scrolled_box }; - scrolled.child = scrolled_box; - return scrolled; } @@ -253,24 +242,6 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Dialog { return scrolled; } - private void add_projects () { - foreach (Objects.Project project in Services.Database.get_default ().projects) { - projects_hashmap [project.id] = new Dialogs.ProjectPicker.ProjectPickerRow (project); - - if (project.is_inbox_project) { - inbox_group.add_child (projects_hashmap [project.id]); - } else { - if (project.source_type == BackendType.LOCAL) { - local_group.add_child (projects_hashmap [project.id]); - } else if (project.source_type == BackendType.TODOIST) { - todoist_group.add_child (projects_hashmap [project.id]); - } else if (project.source_type == BackendType.CALDAV) { - caldav_group.add_child (projects_hashmap [project.id]); - } - } - } - } - public void add_sections (Gee.ArrayList sections) { var no_section = new Objects.Section (); no_section.name = _("No Section"); @@ -283,11 +254,6 @@ public class Dialogs.ProjectPicker.ProjectPicker : Adw.Dialog { } } - private bool filter_func (Gtk.ListBoxRow row) { - var project = ((Dialogs.ProjectPicker.ProjectPickerRow) row).project; - return search_entry.text.down () in project.name.down (); - } - public void hide_destroy () { close (); } diff --git a/src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala b/src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala new file mode 100644 index 000000000..827dca633 --- /dev/null +++ b/src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala @@ -0,0 +1,53 @@ +/* +* 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 Dialogs.ProjectPicker.ProjectPickerSourceRow : Gtk.ListBoxRow { + public Objects.Source source { get; construct; } + + private Layouts.HeaderItem group; + + public ProjectPickerSourceRow (Objects.Source source) { + Object ( + source: source + ); + } + + construct { + css_classes = { "no-selectable", "no-padding" }; + + group = new Layouts.HeaderItem (source.header_text) { + card = true, + reveal = true + }; + + child = group; + + add_projects (); + } + + private void add_projects () { + foreach (Objects.Project project in Services.Store.instance ().get_projects_by_source (source.id)) { + if (!project.is_inbox_project) { + group.add_child (new Dialogs.ProjectPicker.ProjectPickerRow (project)); + } + } + } +} \ No newline at end of file diff --git a/src/Dialogs/QuickFind/QuickFind.vala b/src/Dialogs/QuickFind/QuickFind.vala index c1f6cca66..f31cb8198 100644 --- a/src/Dialogs/QuickFind/QuickFind.vala +++ b/src/Dialogs/QuickFind/QuickFind.vala @@ -180,19 +180,19 @@ public class Dialogs.QuickFind.QuickFind : Adw.Dialog { } } - foreach (Objects.Project project in Services.Database.get_default ().get_all_projects_by_search (search_entry.text)) { + foreach (Objects.Project project in Services.Store.instance ().get_all_projects_by_search (search_entry.text)) { var row = new Dialogs.QuickFind.QuickFindItem (project, search_entry.text); listbox.append (row); items.add (row); } - foreach (Objects.Section section in Services.Database.get_default ().get_all_sections_by_search (search_entry.text)) { + foreach (Objects.Section section in Services.Store.instance ().get_all_sections_by_search (search_entry.text)) { var row = new Dialogs.QuickFind.QuickFindItem (section, search_entry.text); listbox.append (row); items.add (row); } - foreach (Objects.Item item in Services.Database.get_default ().get_all_items_by_search (search_entry.text)) { + foreach (Objects.Item item in Services.Store.instance ().get_all_items_by_search (search_entry.text)) { if (item.project != null) { var row = new Dialogs.QuickFind.QuickFindItem (item, search_entry.text); listbox.append (row); @@ -200,7 +200,7 @@ public class Dialogs.QuickFind.QuickFind : Adw.Dialog { } } - foreach (Objects.Label label in Services.Database.get_default ().get_all_labels_by_search (search_entry.text)) { + foreach (Objects.Label label in Services.Store.instance ().get_all_labels_by_search (search_entry.text)) { var row = new Dialogs.QuickFind.QuickFindItem (label, search_entry.text); listbox.append (row); items.add (row); diff --git a/src/Dialogs/Section.vala b/src/Dialogs/Section.vala index 1caa2797d..d3089ec58 100644 --- a/src/Dialogs/Section.vala +++ b/src/Dialogs/Section.vala @@ -160,12 +160,12 @@ public class Dialogs.Section : Adw.Dialog { if (section.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().update.begin (section, (obj, res) => { Services.Todoist.get_default ().update.end (res); - Services.Database.get_default ().update_section (section); + Services.Store.instance ().update_section (section); submit_button.is_loading = false; hide_destroy (); }); } else if (section.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_section (section); + Services.Store.instance ().update_section (section); hide_destroy (); } } else { diff --git a/src/Layouts/FilterPaneRow.vala b/src/Layouts/FilterPaneRow.vala index 53c3334c8..c2fde13a8 100644 --- a/src/Layouts/FilterPaneRow.vala +++ b/src/Layouts/FilterPaneRow.vala @@ -171,7 +171,7 @@ public class Layouts.FilterPaneRow : Gtk.FlowBoxChild { } } private void init_inbox_count () { - Objects.Project inbox_project = Services.Database.get_default ().get_project (Services.Settings.get_default ().settings.get_string ("local-inbox-project-id")); + 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 (() => { diff --git a/src/Layouts/ItemBoard.vala b/src/Layouts/ItemBoard.vala index 3ae564baf..46fde5b52 100644 --- a/src/Layouts/ItemBoard.vala +++ b/src/Layouts/ItemBoard.vala @@ -361,13 +361,13 @@ public class Layouts.ItemBoard : Layouts.ItemBase { update_request (); }); - Services.Database.get_default ().item_updated.connect ((_item, _update_id) => { + Services.Store.instance ().item_updated.connect ((_item, _update_id) => { if (item.id == _item.id && update_id != _update_id) { update_request (); } }); - Services.Database.get_default ().item_deleted.connect ((_item) => { + Services.Store.instance ().item_deleted.connect ((_item) => { if (item.id == _item.parent_id) { update_request (); } @@ -486,13 +486,13 @@ public class Layouts.ItemBoard : Layouts.ItemBase { private void _complete_item (bool old_checked) { if (item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } else if (item.project.source_type == BackendType.TODOIST) { checked_button.sensitive = false; is_loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { if (Services.Todoist.get_default ().complete_item.end (res).status) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); is_loading = false; checked_button.sensitive = true; } @@ -502,7 +502,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { is_loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { if (Services.CalDAV.Core.get_default ().complete_item.end (res).status) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); is_loading = false; checked_button.sensitive = true; } @@ -672,14 +672,13 @@ public class Layouts.ItemBoard : Layouts.ItemBase { move_item.activate_item.connect (() => { menu_handle_popover.popdown (); - BackendType backend_type; + Dialogs.ProjectPicker.ProjectPicker dialog; if (item.project.is_inbox_project) { - backend_type = BackendType.ALL; + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_projects (); } else { - backend_type = item.project.source_type; + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_project (item.source); } - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, backend_type); dialog.add_sections (item.project.sections); dialog.project = item.project; dialog.section = item.section; @@ -687,7 +686,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { dialog.changed.connect ((type, id) => { if (type == "project") { - move (Services.Database.get_default ().get_project (id), ""); + move (Services.Store.instance ().get_project (id), ""); } else { move (item.project, id); } @@ -833,19 +832,19 @@ public class Layouts.ItemBoard : Layouts.ItemBase { picked_item.parent_id = target_item.id; if (picked_item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (picked_item); + Services.Store.instance ().update_item (picked_item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } else if (picked_item.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_item.begin (picked_item, "parent_id", picked_item.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); } else if (picked_item.project.source_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); @@ -944,11 +943,11 @@ public class Layouts.ItemBoard : Layouts.ItemBase { Services.Todoist.get_default ().move_item.begin (picked_widget.item, move_type, move_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } }); } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } } @@ -985,7 +984,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { if (item_row != null) { item_row.item.child_order = row_index; - Services.Database.get_default ().update_item (item_row.item); + Services.Store.instance ().update_item (item_row.item); } row_index++; diff --git a/src/Layouts/ItemRow.vala b/src/Layouts/ItemRow.vala index 357d4bcb8..8e3ce6db1 100644 --- a/src/Layouts/ItemRow.vala +++ b/src/Layouts/ItemRow.vala @@ -1037,14 +1037,13 @@ public class Layouts.ItemRow : Layouts.ItemBase { move_item.activate_item.connect (() => { menu_handle_popover.popdown (); - BackendType backend_type; + Dialogs.ProjectPicker.ProjectPicker dialog; if (item.project.is_inbox_project) { - backend_type = BackendType.ALL; + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_projects (); } else { - backend_type = item.project.source_type; + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_project (item.source); } - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, backend_type); dialog.add_sections (item.project.sections); dialog.project = item.project; dialog.section = item.section; @@ -1052,7 +1051,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { dialog.changed.connect ((type, id) => { if (type == "project") { - move (Services.Database.get_default ().get_project (id), ""); + move (Services.Store.instance ().get_project (id), ""); } else { move (item.project, id); } @@ -1178,15 +1177,20 @@ public class Layouts.ItemRow : Layouts.ItemBase { move_item.clicked.connect (() => { popover.popdown (); - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, item.project.backend_type); - dialog.add_sections (item.project.sections); + 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.project = item.project; dialog.section = item.section; dialog.present (Planify._instance.main_window); dialog.changed.connect ((type, id) => { if (type == "project") { - move (Services.Database.get_default ().get_project (id), ""); + move (Services.Store.instance ().get_project (id), ""); } else { move (item.project, id); } @@ -1373,13 +1377,13 @@ public class Layouts.ItemRow : Layouts.ItemBase { private void _complete_item (bool old_checked) { if (item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } else if (item.project.source_type == BackendType.TODOIST) { checked_button.sensitive = false; is_loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { if (Services.Todoist.get_default ().complete_item.end (res).status) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); is_loading = false; checked_button.sensitive = true; } @@ -1389,7 +1393,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { is_loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { if (Services.CalDAV.Core.get_default ().complete_item.end (res).status) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); is_loading = false; checked_button.sensitive = true; } @@ -1594,13 +1598,13 @@ public class Layouts.ItemRow : Layouts.ItemBase { if (picked_item.project.source_type == BackendType.LOCAL) { target_item.collapsed = true; - Services.Database.get_default ().update_item (picked_item); + Services.Store.instance ().update_item (picked_item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } else if (picked_item.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_item.begin (picked_item, "parent_id", picked_item.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { target_item.collapsed = true; - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); @@ -1608,7 +1612,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { Services.CalDAV.Core.get_default ().add_task.begin (picked_item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { target_item.collapsed = true; - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); @@ -1695,7 +1699,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { } if (picked_widget.item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } else if (picked_widget.item.project.source_type == BackendType.TODOIST) { string move_id = picked_widget.item.project_id; string move_type = "project_id"; @@ -1712,13 +1716,13 @@ public class Layouts.ItemRow : Layouts.ItemBase { Services.Todoist.get_default ().move_item.begin (picked_widget.item, move_type, move_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } }); } else if (picked_widget.item.project.source_type == BackendType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_widget.item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } }); } @@ -1777,7 +1781,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { if (item_row != null) { item_row.item.child_order = row_index; - Services.Database.get_default ().update_item (item_row.item); + Services.Store.instance ().update_item (item_row.item); } row_index++; diff --git a/src/Layouts/ItemSidebarView.vala b/src/Layouts/ItemSidebarView.vala index f2621e037..5285972fa 100644 --- a/src/Layouts/ItemSidebarView.vala +++ b/src/Layouts/ItemSidebarView.vala @@ -517,14 +517,13 @@ public class Layouts.ItemSidebarView : Adw.Bin { move_item.clicked.connect (() => { popover.popdown (); - BackendType backend_type; + Dialogs.ProjectPicker.ProjectPicker dialog; if (item.project.is_inbox_project) { - backend_type = BackendType.ALL; + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_projects (); } else { - backend_type = item.project.source_type; + dialog = new Dialogs.ProjectPicker.ProjectPicker.for_project (item.source); } - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, backend_type); dialog.add_sections (item.project.sections); dialog.project = item.project; dialog.section = item.section; @@ -532,7 +531,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { dialog.changed.connect ((type, id) => { if (type == "project") { - move (Services.Database.get_default ().get_project (id), ""); + move (Services.Store.instance ().get_project (id), ""); } else { move (item.project, id); } @@ -726,12 +725,12 @@ public class Layouts.ItemSidebarView : Adw.Bin { private void _complete_item (bool old_checked) { if (item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } else if (item.project.source_type == BackendType.TODOIST) { item.loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { if (Services.Todoist.get_default ().complete_item.end (res).status) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } item.loading = false; @@ -740,7 +739,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { item.loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { if (Services.CalDAV.Core.get_default ().complete_item.end (res).status) { - Services.Database.get_default ().checked_toggled (item, old_checked); + Services.Store.instance ().checked_toggled (item, old_checked); } item.loading = false; diff --git a/src/Layouts/LabelRow.vala b/src/Layouts/LabelRow.vala index 6c289a48d..28147fbff 100644 --- a/src/Layouts/LabelRow.vala +++ b/src/Layouts/LabelRow.vala @@ -131,7 +131,7 @@ public class Layouts.LabelRow : Gtk.ListBoxRow { if (label_row != null) { label_row.label.item_order = row_index; - Services.Database.get_default ().update_label (label_row.label); + Services.Store.instance ().update_label (label_row.label); } row_index++; @@ -184,10 +184,10 @@ public class Layouts.LabelRow : Gtk.ListBoxRow { if (label.backend_type == BackendType.TODOIST) { Services.Todoist.get_default ().delete.begin (label, (obj, res) => { Services.Todoist.get_default ().delete.end (res); - Services.Database.get_default ().delete_label (label); + Services.Store.instance ().delete_label (label); }); } else if (label.backend_type == BackendType.LOCAL) { - Services.Database.get_default ().delete_label (label); + Services.Store.instance ().delete_label (label); } } }); diff --git a/src/Layouts/ProjectRow.vala b/src/Layouts/ProjectRow.vala index d3c48b2f8..cf57eca37 100644 --- a/src/Layouts/ProjectRow.vala +++ b/src/Layouts/ProjectRow.vala @@ -391,12 +391,12 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (picked_project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (picked_project, target_project.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { - Services.Database.get_default ().update_project (picked_project); + Services.Store.instance ().update_project (picked_project); Services.EventBus.get_default ().update_inserted_project_map (picked_widget, old_parent_id); } }); } else { - Services.Database.get_default ().update_project (picked_project); + Services.Store.instance ().update_project (picked_project); Services.EventBus.get_default ().update_inserted_project_map (picked_widget, old_parent_id); } } @@ -499,12 +499,12 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (picked_project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (picked_project, target_project.id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { - Services.Database.get_default ().update_project (picked_project); + Services.Store.instance ().update_project (picked_project); Services.EventBus.get_default ().project_parent_changed (picked_project, old_parent_id, true); } }); } else { - Services.Database.get_default ().update_project (picked_project); + Services.Store.instance ().update_project (picked_project); Services.EventBus.get_default ().project_parent_changed (picked_project, old_parent_id, true); } @@ -615,7 +615,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (project_row != null) { project_row.project.child_order = row_index; - Services.Database.get_default ().update_project (project_row.project); + Services.Store.instance ().update_project (project_row.project); } row_index++; @@ -680,7 +680,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { menu_popover.popdown (); project.is_favorite = !project.is_favorite; - Services.Database.get_default ().update_project (project); + Services.Store.instance ().update_project (project); Services.EventBus.get_default ().favorite_toggled (project); project.update (); }); diff --git a/src/Layouts/SectionBoard.vala b/src/Layouts/SectionBoard.vala index cc884bfb0..caa932447 100644 --- a/src/Layouts/SectionBoard.vala +++ b/src/Layouts/SectionBoard.vala @@ -264,7 +264,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { } }); - Services.Database.get_default ().item_updated.connect ((item, update_id) => { + Services.Store.instance ().item_updated.connect ((item, update_id) => { if (items.has_key (item.id_string)) { listbox.invalidate_filter (); } @@ -274,7 +274,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { } }); - Services.Database.get_default ().item_deleted.connect ((item) => { + Services.Store.instance ().item_deleted.connect ((item) => { if (items.has_key (item.id_string)) { items [item.id_string].hide_destroy (); items.unset (item.id_string); @@ -536,7 +536,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { move_item.clicked.connect (() => { menu_popover.popdown (); - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, section.project.source_type); + var dialog = new Dialogs.ProjectPicker.ProjectPicker.for_project (section.source); dialog.project = section.project; dialog.present (Planify._instance.main_window); @@ -574,10 +574,10 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { if (section.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().delete.begin (section, (obj, res) => { Services.Todoist.get_default ().delete.end (res); - Services.Database.get_default ().delete_section (section); + Services.Store.instance ().delete_section (section); }); } else { - Services.Database.get_default ().delete_section (section); + Services.Store.instance ().delete_section (section); } } }); @@ -607,12 +607,12 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { Services.Todoist.get_default ().move_project_section.begin (section, project_id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { - Services.Database.get_default ().move_section (section, old_section_id); + Services.Store.instance ().move_section (section, old_section_id); is_loading = false; } }); } else if (section.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().move_section (section, project_id); + Services.Store.instance ().move_section (section, project_id); is_loading = false; } } @@ -648,11 +648,11 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { Services.Todoist.get_default ().move_item.begin (picked_widget.item, type, id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } }); } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } var source_list = (Gtk.ListBox) picked_widget.parent; @@ -675,7 +675,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { if (item_row != null) { item_row.item.child_order = row_index; - Services.Database.get_default ().update_item (item_row.item); + Services.Store.instance ().update_item (item_row.item); } row_index++; diff --git a/src/Layouts/SectionRow.vala b/src/Layouts/SectionRow.vala index c22082bf2..03fb0284e 100644 --- a/src/Layouts/SectionRow.vala +++ b/src/Layouts/SectionRow.vala @@ -306,7 +306,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { } }); - Services.Database.get_default ().item_updated.connect ((item, update_id) => { + Services.Store.instance ().item_updated.connect ((item, update_id) => { if (items.has_key (item.id)) { if (items [item.id].update_id != update_id) { items [item.id].update_request (); @@ -321,7 +321,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { listbox.invalidate_filter (); }); - Services.Database.get_default ().item_deleted.connect ((item) => { + Services.Store.instance ().item_deleted.connect ((item) => { if (items.has_key (item.id)) { items [item.id].hide_destroy (); items.unset (item.id); @@ -711,7 +711,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { move_item.clicked.connect (() => { menu_popover.popdown (); - var dialog = new Dialogs.ProjectPicker.ProjectPicker (PickerType.PROJECTS, section.project.source_type); + var dialog = new Dialogs.ProjectPicker.ProjectPicker.for_project (section.source); dialog.project = section.project; dialog.present (Planify._instance.main_window); @@ -773,11 +773,11 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { Services.Todoist.get_default ().move_item.begin (picked_widget.item, type, id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } }); } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } var source_list = (Gtk.ListBox) picked_widget.parent; @@ -815,11 +815,11 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { Services.Todoist.get_default ().move_item.begin (picked_widget.item, type, id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } }); } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().update_item (picked_widget.item); + Services.Store.instance ().update_item (picked_widget.item); } var source_list = (Gtk.ListBox) picked_widget.parent; @@ -852,7 +852,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { if (item_row != null) { item_row.item.child_order = row_index; - Services.Database.get_default ().update_item (item_row.item); + Services.Store.instance ().update_item (item_row.item); } row_index++; @@ -879,13 +879,13 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { if (section.project.source_type == BackendType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (section, project_id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { - Services.Database.get_default ().move_section (section, old_section_id); + Services.Store.instance ().move_section (section, old_section_id); } is_loading = false; }); } else if (section.project.source_type == BackendType.LOCAL) { - Services.Database.get_default ().move_section (section, project_id); + Services.Store.instance ().move_section (section, project_id); is_loading = false; } } diff --git a/src/Layouts/Sidebar.vala b/src/Layouts/Sidebar.vala index ddaa843a1..202652408 100644 --- a/src/Layouts/Sidebar.vala +++ b/src/Layouts/Sidebar.vala @@ -202,9 +202,9 @@ public class Layouts.Sidebar : Adw.Bin { } public void init () { - Services.Database.get_default ().source_added.connect (add_source_row); + Services.Store.instance ().source_added.connect (add_source_row); - Services.Database.get_default ().source_deleted.connect ((source) => { + Services.Store.instance ().source_deleted.connect ((source) => { if (sources_hashmap.has_key (source.id)) { sources_hashmap.get (source.id).hide_destroy (); } @@ -230,7 +230,7 @@ public class Layouts.Sidebar : Adw.Bin { add_all_favorites (); - foreach (Objects.Source source in Services.Database.get_default ().sources) { + foreach (Objects.Source source in Services.Store.instance ().sources) { add_source_row (source); } } @@ -243,7 +243,7 @@ public class Layouts.Sidebar : Adw.Bin { } private void add_all_favorites () { - foreach (Objects.Project project in Services.Database.get_default ().projects) { + foreach (Objects.Project project in Services.Store.instance ().projects) { add_row_favorite (project); } diff --git a/src/Layouts/SidebarSourceRow.vala b/src/Layouts/SidebarSourceRow.vala index 88789f138..5c187aad5 100644 --- a/src/Layouts/SidebarSourceRow.vala +++ b/src/Layouts/SidebarSourceRow.vala @@ -64,8 +64,7 @@ public class Layouts.SidebarSourceRow : Gtk.ListBoxRow { var add_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { valign = Gtk.Align.CENTER, - css_classes = { "flat", "header-item-button", "dim-label" }, - tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Add Project"), "P") + css_classes = { "flat", "header-item-button", "dim-label" } }; group.add_widget_end (add_button); @@ -78,28 +77,32 @@ public class Layouts.SidebarSourceRow : Gtk.ListBoxRow { child = main_revealer; Timeout.add (main_revealer.transition_duration, () => { - main_revealer.reveal_child = true; + main_revealer.reveal_child = source.is_visible; return GLib.Source.REMOVE; }); add_all_projects (); update_projects_sort (); + source.updated.connect (() => { + main_revealer.reveal_child = source.is_visible; + }); + add_button.clicked.connect (() => { prepare_new_project (source.id); }); - Services.Database.get_default ().project_added.connect (add_row_project); - Services.Database.get_default ().project_updated.connect (update_projects_sort); - Services.Database.get_default ().project_unarchived.connect (add_row_project); + Services.Store.instance ().project_added.connect (add_row_project); + Services.Store.instance ().project_updated.connect (update_projects_sort); + Services.Store.instance ().project_unarchived.connect (add_row_project); - Services.Database.get_default ().project_deleted.connect ((project) => { + Services.Store.instance ().project_deleted.connect ((project) => { if (projects_hashmap.has_key (project.id)) { projects_hashmap.unset (project.id); } }); - Services.Database.get_default ().project_archived.connect ((project) => { + Services.Store.instance ().project_archived.connect ((project) => { if (projects_hashmap.has_key (project.id)) { projects_hashmap.unset (project.id); } @@ -158,7 +161,7 @@ public class Layouts.SidebarSourceRow : Gtk.ListBoxRow { } private void add_all_projects () { - foreach (Objects.Project project in Services.Database.get_default ().get_projects_by_source (source.id)) { + foreach (Objects.Project project in Services.Store.instance ().get_projects_by_source (source.id)) { add_row_project (project); } } diff --git a/src/MainWindow.vala b/src/MainWindow.vala index c29069385..1625e9a1e 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -23,7 +23,7 @@ public class MainWindow : Adw.ApplicationWindow { public weak Planify app { get; construct; } private Layouts.Sidebar sidebar; - private Gtk.Stack views_stack; + private Adw.ViewStack views_stack; private Adw.OverlaySplitView overlay_split_view; private Gtk.MenuButton settings_button; private Layouts.ItemSidebarView item_sidebar_view; @@ -60,7 +60,7 @@ public class MainWindow : Adw.ApplicationWindow { Objects.Item item = Services.Database.get_default ().get_item_by_id (id); Gee.ArrayList reminders = Services.Database.get_default ().get_reminders_by_item_id (id); - Services.Database.get_default ().add_item (item); + Services.Store.instance ().add_item (item); foreach (Objects.Reminder reminder in reminders) { item.add_reminder_events (reminder); } @@ -100,10 +100,11 @@ public class MainWindow : Adw.ApplicationWindow { sidebar_view.add_top_bar (sidebar_header); sidebar_view.content = sidebar; - views_stack = new Gtk.Stack () { + views_stack = new Adw.ViewStack () { hexpand = true, vexpand = true, - transition_type = Gtk.StackTransitionType.SLIDE_RIGHT + vhomogeneous = false, + hhomogeneous = false }; item_sidebar_view = new Layouts.ItemSidebarView (); @@ -190,7 +191,7 @@ public class MainWindow : Adw.ApplicationWindow { Services.EventBus.get_default ().pane_selected.connect ((pane_type, id) => { if (pane_type == PaneType.PROJECT) { - add_project_view (Services.Database.get_default ().get_project (id)); + add_project_view (Services.Store.instance ().get_project (id)); } else if (pane_type == PaneType.FILTER) { if (id == FilterType.INBOX.to_string ()) { add_inbox_view (); @@ -283,8 +284,8 @@ public class MainWindow : Adw.ApplicationWindow { } }); - Services.Database.get_default ().project_archived.connect (check_archived); - Services.Database.get_default ().project_unarchived.connect (check_archived); + Services.Store.instance ().project_archived.connect (check_archived); + Services.Store.instance ().project_unarchived.connect (check_archived); } public void show_hide_sidebar () { @@ -294,11 +295,11 @@ public class MainWindow : Adw.ApplicationWindow { private void init_backend () { Services.Database.get_default ().init_database (); - if (Services.Database.get_default ().is_sources_empty ()) { + if (Services.Store.instance ().is_sources_empty ()) { Util.get_default ().create_local_source (); } - if (Services.Database.get_default ().is_database_empty ()) { + if (Services.Store.instance ().is_database_empty ()) { Util.get_default ().create_inbox_project (); Util.get_default ().create_tutorial_project (); Util.get_default ().create_default_labels (); @@ -311,14 +312,14 @@ public class MainWindow : Adw.ApplicationWindow { go_homepage (); - Services.Database.get_default ().project_deleted.connect (valid_view_removed); - Services.Database.get_default ().project_archived.connect (valid_view_removed); + Services.Store.instance ().project_deleted.connect (valid_view_removed); + Services.Store.instance ().project_archived.connect (valid_view_removed); check_archived (); Timeout.add (Constants.SYNC_TIMEOUT, () => { - foreach (Objects.Source source in Services.Database.get_default ().sources) { - source.run_server (); + foreach (Objects.Source source in Services.Store.instance ().sources) { + // source.run_server (); } return GLib.Source.REMOVE; @@ -326,13 +327,13 @@ public class MainWindow : Adw.ApplicationWindow { } private void check_archived () { - archive_item.visible = Services.Database.get_default ().get_all_projects_archived ().size > 0; - archive_separator.visible = Services.Database.get_default ().get_all_projects_archived ().size > 0; + archive_item.visible = Services.Store.instance ().get_all_projects_archived ().size > 0; + archive_separator.visible = Services.Store.instance ().get_all_projects_archived ().size > 0; } private void add_inbox_view () { add_project_view ( - Services.Database.get_default ().get_project ( + Services.Store.instance ().get_project ( Services.Settings.get_default ().settings.get_string ("local-inbox-project-id") ) ); @@ -391,7 +392,7 @@ public class MainWindow : Adw.ApplicationWindow { views_stack.add_named (label_view, "label-view"); } - label_view.label = Services.Database.get_default ().get_label (id); + label_view.label = Services.Store.instance ().get_label (id); views_stack.set_visible_child_name ("label-view"); } diff --git a/src/Services/Backups.vala b/src/Services/Backups.vala index ce0e63b34..9bb4592c5 100644 --- a/src/Services/Backups.vala +++ b/src/Services/Backups.vala @@ -145,7 +145,7 @@ public class Services.Backups : Object { builder.set_member_name ("labels"); builder.begin_array (); - foreach (Objects.Label label in Services.Database.get_default ().labels) { + foreach (Objects.Label label in Services.Store.instance ().labels) { builder.begin_object (); builder.set_member_name ("id"); @@ -174,7 +174,7 @@ public class Services.Backups : Object { // Projects builder.set_member_name ("projects"); builder.begin_array (); - foreach (Objects.Project project in Services.Database.get_default ().projects) { + foreach (Objects.Project project in Services.Store.instance ().projects) { builder.begin_object (); builder.set_member_name ("id"); @@ -247,7 +247,7 @@ public class Services.Backups : Object { // Sections builder.set_member_name ("sections"); builder.begin_array (); - foreach (Objects.Section section in Services.Database.get_default ().sections) { + foreach (Objects.Section section in Services.Store.instance ().sections) { builder.begin_object (); builder.set_member_name ("id"); @@ -284,7 +284,7 @@ public class Services.Backups : Object { // Items builder.set_member_name ("items"); builder.begin_array (); - foreach (Objects.Item item in Services.Database.get_default ().items) { + foreach (Objects.Item item in Services.Store.instance ().items) { builder.begin_object (); builder.set_member_name ("id"); @@ -446,24 +446,24 @@ public class Services.Backups : Object { // Create Labels foreach (Objects.Label item in backup.labels) { - Services.Database.get_default ().insert_label (item); + Services.Store.instance ().insert_label (item); } // Create Projects foreach (Objects.Project item in backup.projects) { if (item.parent_id != "") { - Objects.Project? project = Services.Database.get_default ().get_project (item.parent_id); + Objects.Project? project = Services.Store.instance ().get_project (item.parent_id); if (project != null) { project.add_subproject_if_not_exists (item); } } else { - Services.Database.get_default ().insert_project (item); + Services.Store.instance ().insert_project (item); } } // Create Sections foreach (Objects.Section item in backup.sections) { - Objects.Project? project = Services.Database.get_default ().get_project (item.project_id); + Objects.Project? project = Services.Store.instance ().get_project (item.project_id); if (project != null) { project.add_section_if_not_exists (item); } @@ -472,18 +472,18 @@ public class Services.Backups : Object { // Create Items foreach (Objects.Item item in backup.items) { if (item.has_parent) { - Objects.Item? _item = Services.Database.get_default ().get_item (item.parent_id); + Objects.Item? _item = Services.Store.instance ().get_item (item.parent_id); if (_item != null) { _item.add_item_if_not_exists (item); } } else { if (item.section_id != "") { - Objects.Section? section = Services.Database.get_default ().get_section (item.section_id); + Objects.Section? section = Services.Store.instance ().get_section (item.section_id); if (section != null) { section.add_item_if_not_exists (item); } } else { - Objects.Project? project = Services.Database.get_default ().get_project (item.project_id); + Objects.Project? project = Services.Store.instance ().get_project (item.project_id); if (project != null) { project.add_item_if_not_exists (item); } diff --git a/src/Services/GoogleTasks.vala b/src/Services/GoogleTasks.vala index 0391620d1..ed80e47de 100644 --- a/src/Services/GoogleTasks.vala +++ b/src/Services/GoogleTasks.vala @@ -139,7 +139,7 @@ public class Services.GoogleTasks : GLib.Object { unowned Json.Array _taskslist = parser.get_root ().get_object ().get_array_member ("items"); foreach (unowned Json.Node _node in _taskslist.get_elements ()) { - Objects.Project? project = Services.Database.get_default ().get_project (_node.get_object ().get_string_member ("id")); + Objects.Project? project = Services.Store.instance ().get_project (_node.get_object ().get_string_member ("id")); if (project != null) { // if (_node.get_object ().get_boolean_member ("is_deleted")) { // Services.Database.get_default ().delete_project (project); @@ -159,7 +159,7 @@ public class Services.GoogleTasks : GLib.Object { // } // } } else { - Services.Database.get_default ().insert_project (new Objects.Project.from_google_tasklist_json (_node)); + Services.Store.instance ().insert_project (new Objects.Project.from_google_tasklist_json (_node)); } } } catch (Error e) { diff --git a/src/Services/Migrate.vala b/src/Services/Migrate.vala index 7235e54d2..ccd14fed6 100644 --- a/src/Services/Migrate.vala +++ b/src/Services/Migrate.vala @@ -58,7 +58,7 @@ public class Services.Migrate : GLib.Object { label.color = stmt.column_text (2); label.backend_type = BackendType.LOCAL; - Services.Database.get_default ().insert_label (label); + Services.Store.instance ().insert_label (label); } stmt.reset (); @@ -80,7 +80,7 @@ public class Services.Migrate : GLib.Object { project.color = stmt.column_text (2); project.source_id = BackendType.LOCAL.to_string (); - Services.Database.get_default ().insert_project (project); + Services.Store.instance ().insert_project (project); } stmt.reset (); @@ -101,7 +101,7 @@ public class Services.Migrate : GLib.Object { section.name = stmt.column_text (1); section.project_id = stmt.column_text (4); - Objects.Project? project = Services.Database.get_default ().get_project (section.project_id); + Objects.Project? project = Services.Store.instance ().get_project (section.project_id); if (project != null) { project.add_section_if_not_exists (section); } @@ -134,18 +134,18 @@ public class Services.Migrate : GLib.Object { item.labels = get_labels_by_item (db, item.id); if (item.parent_id != "") { - Objects.Item? parent_item = Services.Database.get_default ().get_item (item.parent_id); + Objects.Item? parent_item = Services.Store.instance ().get_item (item.parent_id); if (parent_item != null) { parent_item.add_item_if_not_exists (item); } } else { if (item.section_id != "") { - Objects.Section? section = Services.Database.get_default ().get_section (item.section_id); + Objects.Section? section = Services.Store.instance ().get_section (item.section_id); if (section != null) { section.add_item_if_not_exists (item); } } else { - Objects.Project? project = Services.Database.get_default ().get_project (item.project_id); + Objects.Project? project = Services.Store.instance ().get_project (item.project_id); if (project != null) { project.add_item_if_not_exists (item); } @@ -168,7 +168,7 @@ public class Services.Migrate : GLib.Object { set_parameter_str (stmt, "$item_id", id); while (stmt.step () == Sqlite.ROW) { - Objects.Label? label = Services.Database.get_default ().get_label (stmt.column_text (2)); + Objects.Label? label = Services.Store.instance ().get_label (stmt.column_text (2)); if (label != null) { return_value.add (label); } diff --git a/src/Services/Notification.vala b/src/Services/Notification.vala index cd39bf45d..192c93783 100644 --- a/src/Services/Notification.vala +++ b/src/Services/Notification.vala @@ -42,15 +42,15 @@ public class Services.Notification : GLib.Object { reminders.clear (); } - foreach (var reminder in Services.Database.get_default ().reminders) { + foreach (var reminder in Services.Store.instance ().reminders) { reminder_added (reminder); } - Services.Database.get_default ().reminder_added.connect ((reminder) => { + Services.Store.instance ().reminder_added.connect ((reminder) => { reminder_added (reminder); }); - Services.Database.get_default ().reminder_deleted.connect ((reminder) => { + Services.Store.instance ().reminder_deleted.connect ((reminder) => { if (reminders.has_key (reminder.id)) { reminders.unset (reminder.id); } @@ -61,7 +61,7 @@ public class Services.Notification : GLib.Object { if (reminder.datetime.compare (new GLib.DateTime.now_local ()) <= 0) { GLib.Notification notification = build_notification (reminder); Planify.instance.send_notification (reminder.id, notification); - Services.Database.get_default ().delete_reminder (reminder); + Services.Store.instance ().delete_reminder (reminder); } else if (Utils.Datetime.is_same_day (reminder.datetime, new GLib.DateTime.now_local ())) { uint interval = (uint) time_until_now (reminder.datetime); string uid = "%u-%u".printf (interval, GLib.Random.next_int ()); @@ -86,7 +86,7 @@ public class Services.Notification : GLib.Object { GLib.Notification notification = build_notification (reminder); Planify.instance.send_notification (uid, notification); - Services.Database.get_default ().delete_reminder (reminder); + Services.Store.instance ().delete_reminder (reminder); } private GLib.Notification build_notification (Objects.Reminder reminder) { diff --git a/src/Views/Filter.vala b/src/Views/Filter.vala index a9c34bc8d..7b330f81e 100644 --- a/src/Views/Filter.vala +++ b/src/Views/Filter.vala @@ -137,12 +137,12 @@ public class Views.Filter : Adw.Bin { return GLib.Source.REMOVE; }); - Services.Database.get_default ().item_added.connect (valid_add_item); - Services.Database.get_default ().item_deleted.connect (valid_delete_item); - Services.Database.get_default ().item_updated.connect (valid_update_item); + Services.Store.instance ().item_added.connect (valid_add_item); + Services.Store.instance ().item_deleted.connect (valid_delete_item); + Services.Store.instance ().item_updated.connect (valid_update_item); Services.EventBus.get_default ().checked_toggled.connect (valid_checked_item); - Services.Database.get_default ().item_archived.connect (valid_delete_item); - Services.Database.get_default ().item_unarchived.connect ((item) => { + Services.Store.instance ().item_archived.connect (valid_delete_item); + Services.Store.instance ().item_unarchived.connect ((item) => { valid_add_item (item); }); @@ -160,7 +160,7 @@ public class Views.Filter : Adw.Bin { } public void prepare_new_item (string content = "") { - var inbox_project = Services.Database.get_default ().get_project ( + var inbox_project = Services.Store.instance ().get_project ( Services.Settings.get_default ().settings.get_string ("local-inbox-project-id") ); @@ -246,35 +246,35 @@ public class Views.Filter : Adw.Bin { if (filter is Objects.Filters.Priority) { Objects.Filters.Priority priority = ((Objects.Filters.Priority) filter); - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_priority (priority.priority, false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_priority (priority.priority, false)) { add_item (item); } } else if (filter is Objects.Filters.Completed) { - foreach (Objects.Item item in Services.Database.get_default ().get_items_completed ()) { + foreach (Objects.Item item in Services.Store.instance ().get_items_completed ()) { add_item (item); } } else if (filter is Objects.Filters.Tomorrow) { - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_date (new GLib.DateTime.now_local ().add_days (1), false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_date (new GLib.DateTime.now_local ().add_days (1), false)) { add_item (item); } } else if (filter is Objects.Filters.Pinboard) { - foreach (Objects.Item item in Services.Database.get_default ().get_items_pinned (false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_pinned (false)) { add_item (item); } } else if (filter is Objects.Filters.Anytime) { - foreach (Objects.Item item in Services.Database.get_default ().get_items_no_date (false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_no_date (false)) { add_item (item); } } else if (filter is Objects.Filters.Repeating) { - foreach (Objects.Item item in Services.Database.get_default ().get_items_repeating (false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_repeating (false)) { add_item (item); } } else if (filter is Objects.Filters.Unlabeled) { - foreach (Objects.Item item in Services.Database.get_default ().get_items_unlabeled (false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_unlabeled (false)) { add_item (item); } } else if (filter is Objects.Filters.AllItems) { - foreach (Objects.Item item in Services.Database.get_default ().get_items_no_parent (false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_no_parent (false)) { add_item (item); } } @@ -528,7 +528,7 @@ public class Views.Filter : Adw.Bin { delete_all_completed.activate_item.connect (() => { popover.popdown (); - var items = Services.Database.get_default ().get_items_checked (); + var items = Services.Store.instance ().get_items_checked (); var dialog = new Adw.AlertDialog ( _("Delete All Completed Tasks"), diff --git a/src/Views/Label/Label.vala b/src/Views/Label/Label.vala index 4a83a8da6..bb563d292 100644 --- a/src/Views/Label/Label.vala +++ b/src/Views/Label/Label.vala @@ -111,11 +111,11 @@ public class Views.Label : Adw.Bin { return GLib.Source.REMOVE; }); - Services.Database.get_default ().item_added.connect (valid_add_item); - Services.Database.get_default ().item_deleted.connect (valid_delete_item); - Services.Database.get_default ().item_updated.connect (valid_update_item); - Services.Database.get_default ().item_archived.connect (valid_delete_item); - Services.Database.get_default ().item_unarchived.connect ((item) => { + Services.Store.instance ().item_added.connect (valid_add_item); + Services.Store.instance ().item_deleted.connect (valid_delete_item); + Services.Store.instance ().item_updated.connect (valid_update_item); + Services.Store.instance ().item_archived.connect (valid_delete_item); + Services.Store.instance ().item_unarchived.connect ((item) => { valid_add_item (item); }); @@ -170,7 +170,7 @@ public class Views.Label : Adw.Bin { items.clear (); - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_label (label, false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_label (label, false)) { add_item (item); } diff --git a/src/Views/Label/LabelSourceRow.vala b/src/Views/Label/LabelSourceRow.vala new file mode 100644 index 000000000..365fbbd80 --- /dev/null +++ b/src/Views/Label/LabelSourceRow.vala @@ -0,0 +1,117 @@ +/* +* 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 Views.LabelSourceRow : Gtk.ListBoxRow { + public Objects.Source source { get; construct; } + + private Layouts.HeaderItem group; + private Gtk.Revealer main_revealer; + public Gee.HashMap labels_hashmap = new Gee.HashMap (); + + public LabelSourceRow (Objects.Source source) { + Object ( + source: source + ); + } + + construct { + css_classes = { "no-selectable", "no-padding" }; + + group = new Layouts.HeaderItem (source.header_text) { + reveal = true, + show_separator = true, + subheader_title = source.subheader_text + }; + group.placeholder_message = _("No labels available. Create one by clicking on the '+' button"); + group.margin_top = 6; + group.show_separator = true; + group.set_sort_func (sort_func); + + var add_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { + valign = Gtk.Align.CENTER, + css_classes = { "flat", "header-item-button", "dim-label" }, + tooltip_markup = Util.get_default ().markup_accel_tooltip (_("Add Project"), "P") + }; + + group.add_widget_end (add_button); + + main_revealer = new Gtk.Revealer () { + transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, + child = group + }; + + child = main_revealer; + add_labels (); + + Timeout.add (main_revealer.transition_duration, () => { + main_revealer.reveal_child = true; + group.set_sort_func (null); + return GLib.Source.REMOVE; + }); + + add_button.clicked.connect (() => { + var dialog = new Dialogs.Label.new (BackendType.LOCAL); + dialog.present (Planify._instance.main_window); + }); + + group.row_activated.connect ((row) => { + Services.EventBus.get_default ().pane_selected (PaneType.LABEL, ((Layouts.LabelRow) row).label.id); + }); + + Services.Store.instance ().label_added.connect ((label) => { + add_label (label); + }); + + Services.Store.instance ().label_deleted.connect ((label) => { + if (labels_hashmap.has_key (label.id)) { + labels_hashmap[label.id].hide_destroy (); + labels_hashmap.unset (label.id); + } + }); + } + + private void add_labels () { + foreach (Objects.Label label in Services.Store.instance ().get_labels_by_source (source.id)) { + add_label (label); + } + } + + private void add_label (Objects.Label label) { + if (label.source_id == source.id && !labels_hashmap.has_key (label.id)) { + labels_hashmap[label.id] = new Layouts.LabelRow (label); + group.add_child (labels_hashmap[label.id]); + } + } + + private int sort_func (Gtk.ListBoxRow lbrow, Gtk.ListBoxRow lbbefore) { + Objects.Label label1 = ((Layouts.LabelRow) lbrow).label; + Objects.Label label2 = ((Layouts.LabelRow) lbbefore).label; + return label1.item_order - label2.item_order; + } + + 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 diff --git a/src/Views/Label/Labels.vala b/src/Views/Label/Labels.vala index 0fce32cc8..8624387f0 100644 --- a/src/Views/Label/Labels.vala +++ b/src/Views/Label/Labels.vala @@ -20,45 +20,27 @@ */ public class Views.Labels : Adw.Bin { - private Layouts.HeaderItem labels_local_header; - private Layouts.HeaderItem labels_todoist_header; - private Layouts.HeaderItem labels_caldav_header; - public Gee.HashMap labels_local_map; - public Gee.HashMap labels_todoist_map; - public Gee.HashMap labels_caldav_map; + private Gtk.ListBox sources_listbox; + public Gee.HashMap sources_hashmap = new Gee.HashMap (); - construct { - labels_local_map = new Gee.HashMap (); - labels_todoist_map = new Gee.HashMap (); - labels_caldav_map = new Gee.HashMap (); + construct { var headerbar = new Layouts.HeaderBar (); headerbar.title = _("Labels"); - labels_local_header = new Layouts.HeaderItem (_("Labels: On This Computer")); - labels_local_header.reveal = true; - labels_local_header.show_separator = true; - labels_local_header.set_sort_func (sort_func); - - labels_todoist_header = new Layouts.HeaderItem (_("Labels: Todoist")); - labels_todoist_header.reveal = Services.Todoist.get_default ().is_logged_in (); - labels_todoist_header.show_separator = true; - labels_todoist_header.set_sort_func (sort_func); - - labels_caldav_header = new Layouts.HeaderItem (_("Labels: Nextcloud")); - labels_caldav_header.reveal = Services.CalDAV.Core.get_default ().is_logged_in (); - labels_caldav_header.show_separator = true; - labels_caldav_header.set_sort_func (sort_func); + sources_listbox = new Gtk.ListBox () { + hexpand = true, + valign = Gtk.Align.START, + css_classes = { "listbox-background" } + }; var content = new Gtk.Box (Gtk.Orientation.VERTICAL, 12) { hexpand = true, vexpand = true }; - content.append (labels_local_header); - content.append (labels_todoist_header); - content.append (labels_caldav_header); + content.append (sources_listbox); var content_clamp = new Adw.Clamp () { maximum_size = 1024, @@ -83,126 +65,24 @@ public class Views.Labels : Adw.Bin { toolbar_view.content = scrolled_window; child = toolbar_view; - add_labels (); - - Timeout.add (225, () => { - labels_local_header.set_sort_func (null); - labels_todoist_header.set_sort_func (null); - labels_caldav_header.set_sort_func (null); - return GLib.Source.REMOVE; - }); - - var add_local_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { - valign = Gtk.Align.CENTER, - css_classes = { "flat", "header-item-button" } - }; - - labels_local_header.add_widget_end (add_local_button); - add_local_button.clicked.connect (() => { - var dialog = new Dialogs.Label.new (BackendType.LOCAL); - dialog.present (Planify._instance.main_window); - }); - - var add_todoist_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { - valign = Gtk.Align.CENTER, - css_classes = { "flat", "header-item-button" } - }; - - labels_todoist_header.add_widget_end (add_todoist_button); - add_todoist_button.clicked.connect (() => { - var dialog = new Dialogs.Label.new (BackendType.TODOIST); - dialog.present (Planify._instance.main_window); - }); - - var add_caldav_button = new Gtk.Button.from_icon_name ("plus-large-symbolic") { - valign = Gtk.Align.CENTER, - css_classes = { "flat", "header-item-button" } - }; - - labels_caldav_header.add_widget_end (add_caldav_button); - add_caldav_button.clicked.connect (() => { - var dialog = new Dialogs.Label.new (BackendType.CALDAV); - dialog.present (Planify._instance.main_window); - }); - - labels_local_header.row_activated.connect ((row) => { - Services.EventBus.get_default ().pane_selected (PaneType.LABEL, ((Layouts.LabelRow) row).label.id); - }); - - labels_todoist_header.row_activated.connect ((row) => { - Services.EventBus.get_default ().pane_selected (PaneType.LABEL, ((Layouts.LabelRow) row).label.id); - }); - - labels_caldav_header.row_activated.connect ((row) => { - Services.EventBus.get_default ().pane_selected (PaneType.LABEL, ((Layouts.LabelRow) row).label.id); - }); - - Services.Database.get_default ().label_added.connect ((label) => { - add_label (label); - }); - - Services.Database.get_default ().label_deleted.connect ((label) => { - if (labels_local_map.has_key (label.id)) { - labels_local_map[label.id].hide_destroy (); - labels_local_map.unset (label.id); - } - - if (labels_todoist_map.has_key (label.id)) { - labels_todoist_map[label.id].hide_destroy (); - labels_todoist_map.unset (label.id); - } - - if (labels_caldav_map.has_key (label.id)) { - labels_caldav_map[label.id].hide_destroy (); - labels_caldav_map.unset (label.id); + + foreach (Objects.Source source in Services.Store.instance ().sources) { + add_source_row (source); + } + + Services.Store.instance ().source_deleted.connect ((source) => { + if (sources_hashmap.has_key (source.id)) { + sources_hashmap.get (source.id).hide_destroy (); } }); - // Services.Todoist.get_default ().log_in.connect (() => { - // labels_todoist_header.reveal = Services.Todoist.get_default ().is_logged_in (); - // }); - - // Services.Todoist.get_default ().log_out.connect (() => { - // labels_todoist_header.reveal = Services.Todoist.get_default ().is_logged_in (); - // }); - - Services.CalDAV.Core.get_default ().log_in.connect (() => { - labels_caldav_header.reveal = Services.CalDAV.Core.get_default ().is_logged_in (); - }); - - Services.CalDAV.Core.get_default ().log_out.connect (() => { - labels_caldav_header.reveal = Services.CalDAV.Core.get_default ().is_logged_in (); - }); - } - - private void add_labels () { - foreach (Objects.Label label in Services.Database.get_default ().labels) { - add_label (label); - } + Services.Store.instance ().source_added.connect (add_source_row); } - private int sort_func (Gtk.ListBoxRow lbrow, Gtk.ListBoxRow lbbefore) { - Objects.Label label1 = ((Layouts.LabelRow) lbrow).label; - Objects.Label label2 = ((Layouts.LabelRow) lbbefore).label; - return label1.item_order - label2.item_order; - } - - private void add_label (Objects.Label label) { - if (label.backend_type == BackendType.LOCAL) { - if (!labels_local_map.has_key (label.id)) { - labels_local_map[label.id] = new Layouts.LabelRow (label); - labels_local_header.add_child (labels_local_map[label.id]); - } - } else if (label.backend_type == BackendType.TODOIST) { - if (!labels_todoist_map.has_key (label.id)) { - labels_todoist_map[label.id] = new Layouts.LabelRow (label); - labels_todoist_header.add_child (labels_todoist_map[label.id]); - } - } else if (label.backend_type == BackendType.CALDAV) { - if (!labels_caldav_map.has_key (label.id)) { - labels_caldav_map[label.id] = new Layouts.LabelRow (label); - labels_caldav_header.add_child (labels_caldav_map[label.id]); - } + private void add_source_row (Objects.Source source) { + if (!sources_hashmap.has_key (source.id)) { + sources_hashmap[source.id] = new Views.LabelSourceRow (source); + sources_listbox.append (sources_hashmap[source.id]); } } } diff --git a/src/Views/Project/Board.vala b/src/Views/Project/Board.vala index c8f2320ce..618e80df2 100644 --- a/src/Views/Project/Board.vala +++ b/src/Views/Project/Board.vala @@ -136,7 +136,7 @@ public class Views.Board : Adw.Bin { flowbox.invalidate_filter (); }); - Services.Database.get_default ().section_moved.connect ((section, old_project_id) => { + Services.Store.instance ().section_moved.connect ((section, old_project_id) => { if (project.id == old_project_id && sections_map.has_key (section.id)) { sections_map [section.id].hide_destroy (); sections_map.unset (section.id); @@ -148,7 +148,7 @@ public class Views.Board : Adw.Bin { } }); - Services.Database.get_default ().section_deleted.connect ((section) => { + Services.Store.instance ().section_deleted.connect ((section) => { if (sections_map.has_key (section.id)) { sections_map [section.id].hide_destroy (); sections_map.unset (section.id); @@ -164,14 +164,14 @@ public class Views.Board : Adw.Bin { project.update_local (); }); - Services.Database.get_default ().section_archived.connect ((section) => { + Services.Store.instance ().section_archived.connect ((section) => { if (sections_map.has_key (section.id)) { sections_map [section.id].hide_destroy (); sections_map.unset (section.id); } }); - Services.Database.get_default ().section_unarchived.connect ((section) => { + Services.Store.instance ().section_unarchived.connect ((section) => { if (project.id == section.project_id) { add_section (section); } diff --git a/src/Views/Project/List.vala b/src/Views/Project/List.vala index be495dfc1..785d3852f 100644 --- a/src/Views/Project/List.vala +++ b/src/Views/Project/List.vala @@ -135,7 +135,7 @@ public class Views.List : Adw.Bin { listbox.invalidate_filter (); }); - Services.Database.get_default ().section_moved.connect ((section, old_project_id) => { + Services.Store.instance ().section_moved.connect ((section, old_project_id) => { if (project.id == old_project_id && sections_map.has_key (section.id)) { sections_map [section.id].hide_destroy (); sections_map.unset (section.id); @@ -147,7 +147,7 @@ public class Views.List : Adw.Bin { } }); - Services.Database.get_default ().section_deleted.connect ((section) => { + Services.Store.instance ().section_deleted.connect ((section) => { if (sections_map.has_key (section.id)) { sections_map [section.id].hide_destroy (); sections_map.unset (section.id); @@ -206,7 +206,7 @@ public class Views.List : Adw.Bin { project.update_local (); }); - Services.Database.get_default ().section_archived.connect ((section) => { + Services.Store.instance ().section_archived.connect ((section) => { if (sections_map.has_key (section.id)) { sections_map [section.id].hide_destroy (); sections_map.unset (section.id); @@ -215,7 +215,7 @@ public class Views.List : Adw.Bin { check_placeholder (); }); - Services.Database.get_default ().section_unarchived.connect ((section) => { + Services.Store.instance ().section_unarchived.connect ((section) => { if (project.id == section.project_id) { add_section (section); } diff --git a/src/Views/Project/Project.vala b/src/Views/Project/Project.vala index f5fbbcfab..49a8db445 100644 --- a/src/Views/Project/Project.vala +++ b/src/Views/Project/Project.vala @@ -509,7 +509,7 @@ public class Views.Project : Adw.Bin { ); delete_all_completed = new Widgets.ContextMenu.MenuItem (_("Delete All Completed Tasks") ,"user-trash-symbolic") { - visible = project.show_completed && Services.Database.get_default ().get_items_checked_by_project (project).size > 0 + visible = project.show_completed && Services.Store.instance ().get_items_checked_by_project (project).size > 0 }; delete_all_completed.add_css_class ("menu-item-danger"); @@ -564,7 +564,7 @@ public class Views.Project : Adw.Bin { project.update_local (); show_completed_item.title = project.show_completed ? _("Hide Completed Tasks") : _("Show Completed Tasks"); - delete_all_completed.visible = project.show_completed && Services.Database.get_default ().get_items_checked_by_project (project).size > 0; + delete_all_completed.visible = project.show_completed && Services.Store.instance ().get_items_checked_by_project (project).size > 0; check_default_filters (); }); @@ -590,7 +590,7 @@ public class Views.Project : Adw.Bin { delete_all_completed.activate_item.connect (() => { popover.popdown (); - var items = Services.Database.get_default ().get_items_checked_by_project (project); + var items = Services.Store.instance ().get_items_checked_by_project (project); var dialog = new Adw.AlertDialog ( _("Delete All Completed Tasks"), @@ -664,7 +664,7 @@ public class Views.Project : Adw.Bin { Gee.ArrayList _labels = new Gee.ArrayList (); foreach (Objects.Filters.FilterItem filter in project.filters.values) { if (filter.filter_type == FilterItemType.LABEL) { - _labels.add (Services.Database.get_default ().get_label (filter.value)); + _labels.add (Services.Store.instance ().get_label (filter.value)); } } diff --git a/src/Views/Scheduled/Scheduled.vala b/src/Views/Scheduled/Scheduled.vala index 6c412bb94..b6af413fa 100644 --- a/src/Views/Scheduled/Scheduled.vala +++ b/src/Views/Scheduled/Scheduled.vala @@ -171,7 +171,7 @@ public class Views.Scheduled.Scheduled : Adw.Bin { } public void prepare_new_item (string content = "") { - var inbox_project = Services.Database.get_default ().get_project ( + var inbox_project = Services.Store.instance ().get_project ( Services.Settings.get_default ().settings.get_string ("local-inbox-project-id") ); @@ -265,7 +265,7 @@ public class Views.Scheduled.Scheduled : Adw.Bin { Gee.ArrayList _labels = new Gee.ArrayList (); foreach (Objects.Filters.FilterItem filter in Objects.Filters.Scheduled.get_default ().filters.values) { if (filter.filter_type == FilterItemType.LABEL) { - _labels.add (Services.Database.get_default ().get_label (filter.value)); + _labels.add (Services.Store.instance ().get_label (filter.value)); } } diff --git a/src/Views/Scheduled/ScheduledDay.vala b/src/Views/Scheduled/ScheduledDay.vala index 8b418466e..d6cc7d267 100644 --- a/src/Views/Scheduled/ScheduledDay.vala +++ b/src/Views/Scheduled/ScheduledDay.vala @@ -130,11 +130,11 @@ public class Views.Scheduled.ScheduledDay : Gtk.ListBoxRow { return GLib.Source.REMOVE; }); - Services.Database.get_default ().item_added.connect (valid_add_item); - Services.Database.get_default ().item_deleted.connect (valid_delete_item); - Services.Database.get_default ().item_updated.connect (valid_update_item); - Services.Database.get_default ().item_archived.connect (valid_delete_item); - Services.Database.get_default ().item_unarchived.connect (valid_add_item); + Services.Store.instance ().item_added.connect (valid_add_item); + Services.Store.instance ().item_deleted.connect (valid_delete_item); + Services.Store.instance ().item_updated.connect (valid_update_item); + Services.Store.instance ().item_archived.connect (valid_delete_item); + Services.Store.instance ().item_unarchived.connect (valid_add_item); Services.EventBus.get_default ().item_moved.connect ((item) => { if (items.has_key (item.id)) { @@ -225,7 +225,7 @@ public class Views.Scheduled.ScheduledDay : Gtk.ListBoxRow { } private void add_items () { - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_date (date, false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_date (date, false)) { add_item (item); } } @@ -240,7 +240,7 @@ public class Views.Scheduled.ScheduledDay : Gtk.ListBoxRow { private void valid_add_item (Objects.Item item) { if (!items.has_key (item.id) && - Services.Database.get_default ().valid_item_by_date (item, date, false)) { + Services.Store.instance ().valid_item_by_date (item, date, false)) { items [item.id] = new Layouts.ItemRow (item); items [item.id].disable_drag_and_drop (); listbox.append (items [item.id]); @@ -271,7 +271,7 @@ public class Views.Scheduled.ScheduledDay : Gtk.ListBoxRow { if (items.has_key (item.id) && item.has_due) { - if (!Services.Database.get_default ().valid_item_by_date (item, date, false)) { + if (!Services.Store.instance ().valid_item_by_date (item, date, false)) { items[item.id].hide_destroy (); items.unset (item.id); } diff --git a/src/Views/Scheduled/ScheduledMonth.vala b/src/Views/Scheduled/ScheduledMonth.vala index f0b9421c9..c290bad44 100644 --- a/src/Views/Scheduled/ScheduledMonth.vala +++ b/src/Views/Scheduled/ScheduledMonth.vala @@ -121,11 +121,11 @@ public class Views.Scheduled.ScheduledMonth : Gtk.ListBoxRow { return GLib.Source.REMOVE; }); - Services.Database.get_default ().item_added.connect (valid_add_item); - Services.Database.get_default ().item_deleted.connect (valid_delete_item); - Services.Database.get_default ().item_updated.connect (valid_update_item); - Services.Database.get_default ().item_archived.connect (valid_delete_item); - Services.Database.get_default ().item_unarchived.connect (valid_add_item); + Services.Store.instance ().item_added.connect (valid_add_item); + Services.Store.instance ().item_deleted.connect (valid_delete_item); + Services.Store.instance ().item_updated.connect (valid_update_item); + Services.Store.instance ().item_archived.connect (valid_delete_item); + Services.Store.instance ().item_unarchived.connect (valid_add_item); Services.EventBus.get_default ().item_moved.connect ((item) => { if (items.has_key (item.id)) { @@ -214,7 +214,7 @@ public class Views.Scheduled.ScheduledMonth : Gtk.ListBoxRow { } private void add_items () { - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_month (date, false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_month (date, false)) { add_item (item); } } @@ -227,7 +227,7 @@ public class Views.Scheduled.ScheduledMonth : Gtk.ListBoxRow { private void valid_add_item (Objects.Item item) { if (!items.has_key (item.id) && - Services.Database.get_default ().valid_item_by_month (item, date, false)) { + Services.Store.instance ().valid_item_by_month (item, date, false)) { items [item.id] = new Layouts.ItemRow (item); items [item.id].disable_drag_and_drop (); listbox.append (items [item.id]); @@ -257,7 +257,7 @@ public class Views.Scheduled.ScheduledMonth : Gtk.ListBoxRow { if (items.has_key (item.id) && item.has_due) { - if (!Services.Database.get_default ().valid_item_by_date (item, date, false)) { + if (!Services.Store.instance ().valid_item_by_date (item, date, false)) { items[item.id].hide_destroy (); items.unset (item.id); } diff --git a/src/Views/Scheduled/ScheduledRange.vala b/src/Views/Scheduled/ScheduledRange.vala index 9228e293f..5d78ba821 100644 --- a/src/Views/Scheduled/ScheduledRange.vala +++ b/src/Views/Scheduled/ScheduledRange.vala @@ -132,11 +132,11 @@ public class Views.Scheduled.ScheduledRange : Gtk.ListBoxRow { return GLib.Source.REMOVE; }); - Services.Database.get_default ().item_added.connect (valid_add_item); - Services.Database.get_default ().item_deleted.connect (valid_delete_item); - Services.Database.get_default ().item_updated.connect (valid_update_item); - Services.Database.get_default ().item_archived.connect (valid_delete_item); - Services.Database.get_default ().item_unarchived.connect (valid_add_item); + Services.Store.instance ().item_added.connect (valid_add_item); + Services.Store.instance ().item_deleted.connect (valid_delete_item); + Services.Store.instance ().item_updated.connect (valid_update_item); + Services.Store.instance ().item_archived.connect (valid_delete_item); + Services.Store.instance ().item_unarchived.connect (valid_add_item); Services.EventBus.get_default ().item_moved.connect ((item) => { if (items.has_key (item.id)) { @@ -225,7 +225,7 @@ public class Views.Scheduled.ScheduledRange : Gtk.ListBoxRow { } private void add_items () { - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_date_range (start_date, end_date, false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_date_range (start_date, end_date, false)) { add_item (item); } } @@ -238,7 +238,7 @@ public class Views.Scheduled.ScheduledRange : Gtk.ListBoxRow { private void valid_add_item (Objects.Item item) { if (!items.has_key (item.id) && - Services.Database.get_default ().valid_item_by_date_range (item, start_date, end_date, false)) { + Services.Store.instance ().valid_item_by_date_range (item, start_date, end_date, false)) { items [item.id] = new Layouts.ItemRow (item); items [item.id].disable_drag_and_drop (); listbox.append (items [item.id]); @@ -268,7 +268,7 @@ public class Views.Scheduled.ScheduledRange : Gtk.ListBoxRow { if (items.has_key (item.id) && item.has_due) { - if (!Services.Database.get_default ().valid_item_by_date_range (item, start_date, end_date, false)) { + if (!Services.Store.instance ().valid_item_by_date_range (item, start_date, end_date, false)) { items[item.id].hide_destroy (); items.unset (item.id); } diff --git a/src/Views/Today.vala b/src/Views/Today.vala index 0ce2358d2..46b0fbbcd 100644 --- a/src/Views/Today.vala +++ b/src/Views/Today.vala @@ -286,11 +286,11 @@ public class Views.Today : Adw.Bin { add_today_items (); }); - Services.Database.get_default ().item_added.connect (valid_add_item); - Services.Database.get_default ().item_deleted.connect (valid_delete_item); - Services.Database.get_default ().item_updated.connect (valid_update_item); - Services.Database.get_default ().item_archived.connect (valid_delete_item); - Services.Database.get_default ().item_unarchived.connect (valid_add_item); + Services.Store.instance ().item_added.connect (valid_add_item); + Services.Store.instance ().item_deleted.connect (valid_delete_item); + Services.Store.instance ().item_updated.connect (valid_update_item); + Services.Store.instance ().item_archived.connect (valid_delete_item); + Services.Store.instance ().item_unarchived.connect (valid_add_item); Services.EventBus.get_default ().item_moved.connect ((item) => { if (items.has_key (item.id)) { @@ -399,7 +399,7 @@ public class Views.Today : Adw.Bin { overdue_listbox.remove (child); } - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_overdeue_view (false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_overdeue_view (false)) { add_overdue_item (item); } @@ -409,7 +409,7 @@ public class Views.Today : Adw.Bin { listbox.remove (child); } - foreach (Objects.Item item in Services.Database.get_default ().get_items_by_date (date, false)) { + foreach (Objects.Item item in Services.Store.instance ().get_items_by_date (date, false)) { add_item (item); } @@ -438,12 +438,12 @@ public class Views.Today : Adw.Bin { private void valid_add_item (Objects.Item item) { if (!items.has_key (item.id) && - Services.Database.get_default ().valid_item_by_date (item, date, false)) { + Services.Store.instance ().valid_item_by_date (item, date, false)) { add_item (item); } if (!overdue_items.has_key (item.id) && - Services.Database.get_default ().valid_item_by_overdue (item, date, false)) { + Services.Store.instance ().valid_item_by_overdue (item, date, false)) { add_overdue_item (item); } @@ -490,14 +490,14 @@ public class Views.Today : Adw.Bin { } if (items.has_key (item.id) && item.has_due) { - if (!Services.Database.get_default ().valid_item_by_date (item, date, false)) { + if (!Services.Store.instance ().valid_item_by_date (item, date, false)) { items[item.id].hide_destroy (); items.unset (item.id); } } if (overdue_items.has_key (item.id) && item.has_due) { - if (!Services.Database.get_default ().valid_item_by_overdue (item, date, false)) { + if (!Services.Store.instance ().valid_item_by_overdue (item, date, false)) { overdue_items[item.id].hide_destroy (); overdue_items.unset (item.id); } @@ -514,7 +514,7 @@ public class Views.Today : Adw.Bin { } public void prepare_new_item (string content = "") { - var inbox_project = Services.Database.get_default ().get_project ( + var inbox_project = Services.Store.instance ().get_project ( Services.Settings.get_default ().settings.get_string ("local-inbox-project-id") ); @@ -630,7 +630,7 @@ public class Views.Today : Adw.Bin { Gee.ArrayList _labels = new Gee.ArrayList (); foreach (Objects.Filters.FilterItem filter in Objects.Filters.Today.get_default ().filters.values) { if (filter.filter_type == FilterItemType.LABEL) { - _labels.add (Services.Database.get_default ().get_label (filter.value)); + _labels.add (Services.Store.instance ().get_label (filter.value)); } } diff --git a/src/Widgets/SourceRow.vala b/src/Widgets/SourceRow.vala index 64fe2b46e..2284b4adc 100644 --- a/src/Widgets/SourceRow.vala +++ b/src/Widgets/SourceRow.vala @@ -35,6 +35,8 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { construct { add_css_class ("no-selectable"); + print ("%s\n".printf (source.to_string ())); + var visible_checkbutton = new Gtk.CheckButton () { active = source.is_visible }; @@ -44,7 +46,7 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { var subheader_label = new Gtk.Label (source.subheader_text) { halign = Gtk.Align.START, css_classes = { "caption" }, - visible = source.subheader_text != null + visible = source.source_type != BackendType.LOCAL }; var header_label_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { diff --git a/src/Widgets/SubItems.vala b/src/Widgets/SubItems.vala index 4502955cf..d8e778dda 100644 --- a/src/Widgets/SubItems.vala +++ b/src/Widgets/SubItems.vala @@ -151,7 +151,7 @@ public class Widgets.SubItems : Adw.Bin { signals_map[item_parent.item_added.connect (add_item)] = item_parent; - signals_map[Services.Database.get_default ().item_updated.connect ((item, update_id) => { + signals_map[Services.Store.instance ().item_updated.connect ((item, update_id) => { if (items.has_key (item.id_string)) { if (items [item.id_string].update_id != update_id) { items [item.id_string].update_request (); @@ -161,9 +161,9 @@ public class Widgets.SubItems : Adw.Bin { if (items_checked.has_key (item.id_string)) { items_checked [item.id_string].update_request (); } - })] = Services.Database.get_default (); + })] = Services.Store.instance (); - signals_map[Services.Database.get_default ().item_deleted.connect ((item) => { + signals_map[Services.Store.instance ().item_deleted.connect ((item) => { if (items.has_key (item.id_string)) { items [item.id_string].hide_destroy (); items.unset (item.id_string); @@ -175,7 +175,7 @@ public class Widgets.SubItems : Adw.Bin { } children_changes (); - })] = Services.Database.get_default (); + })] = Services.Store.instance (); signals_map[Services.EventBus.get_default ().item_moved.connect ((item, old_project_id, old_section_id, old_parent_id) => { if (old_parent_id == item_parent.id) { diff --git a/src/meson.build b/src/meson.build index 1eaf8d5b1..d43b1406c 100644 --- a/src/meson.build +++ b/src/meson.build @@ -64,6 +64,7 @@ sources = files( 'Views/Today.vala', 'Views/Label/Label.vala', 'Views/Label/Labels.vala', + 'Views/Label/LabelSourceRow.vala', 'Views/Filter.vala', 'Views/Scheduled/Scheduled.vala', @@ -81,6 +82,7 @@ sources = files( 'Dialogs/ProjectPicker/ProjectPicker.vala', 'Dialogs/ProjectPicker/ProjectPickerRow.vala', 'Dialogs/ProjectPicker/SectionPickerRow.vala', + 'Dialogs/ProjectPicker/ProjectPickerSourceRow.vala', 'Dialogs/ManageProjects.vala', 'Dialogs/DatePicker.vala', 'Dialogs/LabelPicker.vala', From 709d2d21d47bdbd9933e8a7c769da9d04a14981d Mon Sep 17 00:00:00 2001 From: Alain Date: Sun, 21 Jul 2024 05:43:37 -0500 Subject: [PATCH 06/14] fix #1172 --- core/Enum.vala | 18 +- core/Objects/BaseObject.vala | 4 + core/Objects/Item.vala | 44 +-- core/Objects/Label.vala | 20 +- core/Objects/Project.vala | 25 +- core/Objects/Reminder.vala | 2 +- core/Objects/Section.vala | 4 +- core/Objects/Source.vala | 46 ++- core/QuickAdd.vala | 6 +- core/Services/CalDAV/Core.vala | 263 ++++++------------ core/Services/Database.vala | 55 ++-- core/Services/EventBus.vala | 1 + core/Services/Store.vala | 79 ------ core/Services/Todoist.vala | 12 +- core/Util/Migrate.vala | 36 +++ core/Util/Util.vala | 58 ++-- core/Widgets/LabelsPickerCore.vala | 4 +- .../ProjectPicker/ProjectPickerButton.vala | 2 +- data/resources/stylesheet/stylesheet.css | 8 +- src/Dialogs/Label.vala | 20 +- .../Preferences/PreferencesWindow.vala | 119 ++------ src/Dialogs/Project.vala | 22 +- src/Dialogs/Section.vala | 8 +- src/Layouts/ItemBoard.vala | 18 +- src/Layouts/ItemRow.vala | 24 +- src/Layouts/ItemSidebarView.vala | 14 +- src/Layouts/LabelRow.vala | 4 +- src/Layouts/ProjectRow.vala | 30 +- src/Layouts/SectionBoard.vala | 10 +- src/Layouts/SectionRow.vala | 12 +- src/Layouts/SidebarSourceRow.vala | 10 +- src/Services/ActionManager.vala | 2 +- src/Services/Migrate.vala | 4 +- src/Views/Label/LabelSourceRow.vala | 4 +- src/Views/Project/Project.vala | 8 +- src/Views/Scheduled/Scheduled.vala | 2 +- src/Views/Today.vala | 2 +- src/Widgets/MultiSelectToolbar.vala | 4 +- src/Widgets/SourceRow.vala | 6 +- 39 files changed, 425 insertions(+), 585 deletions(-) diff --git a/core/Enum.vala b/core/Enum.vala index c492b9b6a..068f1b710 100644 --- a/core/Enum.vala +++ b/core/Enum.vala @@ -145,8 +145,7 @@ public enum FilterType { } } -public enum BackendType { - ALL, +public enum SourceType { NONE, LOCAL, TODOIST, @@ -155,9 +154,6 @@ public enum BackendType { public string to_string () { switch (this) { - case ALL: - return "all"; - case NONE: return "none"; @@ -178,22 +174,22 @@ public enum BackendType { } } - public static BackendType parse (string value) { + public static SourceType parse (string value) { switch (value) { case "local": - return BackendType.LOCAL; + return SourceType.LOCAL; case "todoist": - return BackendType.TODOIST; + return SourceType.TODOIST; case "google-tasks": - return BackendType.GOOGLE_TASKS; + return SourceType.GOOGLE_TASKS; case "caldav": - return BackendType.CALDAV; + return SourceType.CALDAV; default: - return BackendType.NONE; + return SourceType.NONE; } } } diff --git a/core/Objects/BaseObject.vala b/core/Objects/BaseObject.vala index 1a3b1ba3f..46bb95a2e 100644 --- a/core/Objects/BaseObject.vala +++ b/core/Objects/BaseObject.vala @@ -208,6 +208,10 @@ public class Objects.BaseObject : GLib.Object { return ((Objects.Item) this).project.source; } + if (this is Objects.Label) { + return ((Objects.Label) this).source; + } + return _source; } } diff --git a/core/Objects/Item.vala b/core/Objects/Item.vala index 0dea6a1e3..f03d7f15b 100644 --- a/core/Objects/Item.vala +++ b/core/Objects/Item.vala @@ -573,7 +573,7 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { // TODO: VERIFICAR CALDAV - Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); + Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, SourceType.CALDAV.to_string ()); if (label != null) { return_value.add (label); } @@ -638,7 +638,7 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { - Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); + Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, SourceType.CALDAV.to_string ()); if (label != null) { return_value [label.id] = label; } else { @@ -646,7 +646,7 @@ public class Objects.Item : Objects.BaseObject { label.id = Util.get_default ().generate_id (label); label.color = Util.get_default ().get_random_color (); label.name = category; - label.backend_type = BackendType.CALDAV; + label.backend_type = SourceType.CALDAV; Services.Store.instance ().insert_label (label); return_value [label.id] = label; @@ -718,14 +718,14 @@ public class Objects.Item : Objects.BaseObject { update_timeout_id = Timeout.add (Constants.UPDATE_TIMEOUT, () => { update_timeout_id = 0; - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (this, update_id); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Store.instance ().update_item (this, update_id); }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (this, true, (obj, res) => { HttpResponse response = Services.CalDAV.Core.get_default ().add_task.end (res); @@ -748,16 +748,16 @@ public class Objects.Item : Objects.BaseObject { update_timeout_id = 0; loading = true; - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (this, update_id); loading = false; - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Store.instance ().update_item (this, update_id); loading = false; }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (this, true, (obj, res) => { HttpResponse response = Services.CalDAV.Core.get_default ().add_task.end (res); @@ -776,16 +776,16 @@ public class Objects.Item : Objects.BaseObject { public void update_async (string update_id = "") { loading = true; - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (this, update_id); loading = false; - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Store.instance ().update_item (this, update_id); loading = false; }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (this, true, (obj, res) => { HttpResponse response = Services.CalDAV.Core.get_default ().add_task.end (res); @@ -1359,9 +1359,9 @@ public class Objects.Item : Objects.BaseObject { } public void delete_item () { - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { Services.Store.instance ().delete_item (this); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { loading = true; Services.Todoist.get_default ().delete.begin (this, (obj, res) => { if (Services.Todoist.get_default ().delete.end (res).status) { @@ -1370,7 +1370,7 @@ public class Objects.Item : Objects.BaseObject { loading = false; }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { loading = true; Services.CalDAV.Core.get_default ().delete_task.begin (this, (obj, res) => { if (Services.CalDAV.Core.get_default ().delete_task.end (res).status) { @@ -1466,10 +1466,10 @@ public class Objects.Item : Objects.BaseObject { due.recurrency_count = due.recurrency_count - 1; } - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (this); promise.resolve (next_recurrency); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { loading = true; Services.Todoist.get_default ().update.begin (this, (obj, res) => { var response = Services.Todoist.get_default ().update.end (res); @@ -1480,7 +1480,7 @@ public class Objects.Item : Objects.BaseObject { promise.resolve (next_recurrency); } }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { loading = true; Services.CalDAV.Core.get_default ().add_task.begin (this, true, (obj, res) => { var response = Services.CalDAV.Core.get_default ().add_task.end (res); @@ -1498,9 +1498,9 @@ public class Objects.Item : Objects.BaseObject { loading = true; show_item = false; - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { _move (project.id, _section_id); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { string move_id = project.id; string move_type = "project_id"; if (_section_id != "") { @@ -1517,7 +1517,7 @@ public class Objects.Item : Objects.BaseObject { _move (project.id, _section_id); } }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().move_task.begin (this, project.id, (obj, res) => { var response = Services.CalDAV.Core.get_default ().move_task.end (res); loading = false; @@ -1604,7 +1604,7 @@ public class Objects.Item : Objects.BaseObject { public void add_reminder (Objects.Reminder reminder) { reminder.item_id = id; - if (project.backend_type == BackendType.TODOIST) { + if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().add.begin (reminder, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); loading = false; diff --git a/core/Objects/Label.vala b/core/Objects/Label.vala index 23dd8fc5b..c10d6c86e 100644 --- a/core/Objects/Label.vala +++ b/core/Objects/Label.vala @@ -24,8 +24,22 @@ public class Objects.Label : Objects.BaseObject { 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 BackendType backend_type { get; set; default = BackendType.NONE; } - public string source_id { get; set; default = BackendType.LOCAL.to_string (); } + 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 { @@ -103,7 +117,7 @@ public class Objects.Label : Objects.BaseObject { public Label.from_json (Json.Node node) { id = node.get_object ().get_string_member ("id"); update_from_json (node); - backend_type = BackendType.TODOIST; + backend_type = SourceType.TODOIST; } public Label.from_import_json (Json.Node node) { diff --git a/core/Objects/Project.vala b/core/Objects/Project.vala index 5bc4af5e2..8d85966ec 100644 --- a/core/Objects/Project.vala +++ b/core/Objects/Project.vala @@ -26,7 +26,7 @@ public class Objects.Project : Objects.BaseObject { public string emoji { get; set; default = ""; } public string description { get; set; default = ""; } public ProjectIconStyle icon_style { get; set; default = ProjectIconStyle.PROGRESS; } - public BackendType backend_type { get; set; default = BackendType.NONE; } + public SourceType backend_type { get; set; default = SourceType.NONE; } public bool inbox_project { get; set; default = false; } public bool team_inbox { get; set; default = false; } public bool is_deleted { get; set; default = false; } @@ -36,7 +36,7 @@ public class Objects.Project : Objects.BaseObject { public bool collapsed { get; set; default = false; } public bool inbox_section_hidded { get; set; default = false; } public string sync_id { get; set; default = ""; } - public string source_id { get; set; default = BackendType.LOCAL.to_string (); } + public string source_id { get; set; default = SourceType.LOCAL.to_string (); } ProjectViewStyle _view_style = ProjectViewStyle.LIST; public ProjectViewStyle view_style { @@ -50,7 +50,7 @@ public class Objects.Project : Objects.BaseObject { } } - public BackendType source_type { + public SourceType source_type { get { return source.source_type; } @@ -318,19 +318,19 @@ public class Objects.Project : Objects.BaseObject { public Project.from_json (Json.Node node) { id = node.get_object ().get_string_member ("id"); update_from_json (node); - backend_type = BackendType.TODOIST; + backend_type = SourceType.TODOIST; } public Project.from_google_tasklist_json (Json.Node node) { id = node.get_object ().get_string_member ("id"); update_from_google_tasklist_json (node); - backend_type = BackendType.GOOGLE_TASKS; + backend_type = SourceType.GOOGLE_TASKS; } public Project.from_caldav_xml (GXml.DomElement element) { id = get_id_from_url (element); update_from_xml (element); - backend_type = BackendType.CALDAV; + backend_type = SourceType.CALDAV; } public void update_from_xml (GXml.DomElement element, bool update_sync_token = true) { @@ -446,9 +446,9 @@ public class Objects.Project : Objects.BaseObject { update_timeout_id = Timeout.add (timeout, () => { update_timeout_id = 0; - if (backend_type == BackendType.LOCAL) { + if (backend_type == SourceType.LOCAL) { Services.Store.instance ().update_project (this); - } else if (backend_type == BackendType.TODOIST) { + } else if (backend_type == SourceType.TODOIST) { if (show_loading) { loading = true; } @@ -458,7 +458,7 @@ public class Objects.Project : Objects.BaseObject { Services.Store.instance ().update_project (this); loading = false; }); - } else if (backend_type == BackendType.CALDAV) { + } else if (backend_type == SourceType.CALDAV) { if (show_loading) { loading = true; } @@ -818,9 +818,9 @@ public class Objects.Project : Objects.BaseObject { dialog.response.connect ((response) => { if (response == "delete") { loading = true; - if (source_type == BackendType.LOCAL) { + if (source_type == SourceType.LOCAL) { Services.Store.instance ().delete_project (this); - } else if (source_type == BackendType.TODOIST) { + } else if (source_type == SourceType.TODOIST) { dialog.set_response_enabled ("cancel", false); dialog.set_response_enabled ("delete", false); @@ -831,7 +831,7 @@ public class Objects.Project : Objects.BaseObject { loading = false; }); - } else if (source_type == BackendType.CALDAV) { + } else if (source_type == SourceType.CALDAV) { dialog.set_response_enabled ("cancel", false); dialog.set_response_enabled ("delete", false); @@ -881,6 +881,7 @@ public class Objects.Project : Objects.BaseObject { new_project.description = description; new_project.icon_style = icon_style; new_project.backend_type = backend_type; + new_project.source_id = source_id; return new_project; } diff --git a/core/Objects/Reminder.vala b/core/Objects/Reminder.vala index fe97a84f1..3d6ce9f22 100644 --- a/core/Objects/Reminder.vala +++ b/core/Objects/Reminder.vala @@ -148,7 +148,7 @@ public class Objects.Reminder : Objects.BaseObject { } public void delete () { - if (item.project.backend_type == BackendType.TODOIST) { + if (item.project.source_type == SourceType.TODOIST) { loading = true; Services.Todoist.get_default ().delete.begin (this, (obj, res) => { if (Services.Todoist.get_default ().delete.end (res).status) { diff --git a/core/Objects/Section.vala b/core/Objects/Section.vala index 593366082..86d30b157 100644 --- a/core/Objects/Section.vala +++ b/core/Objects/Section.vala @@ -192,7 +192,7 @@ public class Objects.Section : Objects.BaseObject { update_timeout_id = 0; Services.Store.instance ().update_section (this); - if (project.backend_type == BackendType.TODOIST && cloud) { + if (project.source_type == SourceType.TODOIST && cloud) { Services.Todoist.get_default ().update.begin (this, (obj, res) => { Services.Todoist.get_default ().update.end (res); }); @@ -345,7 +345,7 @@ public class Objects.Section : Objects.BaseObject { dialog.response.connect ((response) => { if (response == "delete") { loading = true; - if (project.backend_type == BackendType.TODOIST) { + if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().delete.begin (this, (obj, res) => { Services.Todoist.get_default ().delete.end (res); Services.Store.instance ().delete_section (this); diff --git a/core/Objects/Source.vala b/core/Objects/Source.vala index a3f157d9d..80035fb31 100644 --- a/core/Objects/Source.vala +++ b/core/Objects/Source.vala @@ -20,7 +20,7 @@ */ public class Objects.Source : Objects.BaseObject { - public BackendType source_type { get; set; default = BackendType.NONE; } + public SourceType source_type { get; set; default = SourceType.NONE; } public string added_at { get; set; default = new GLib.DateTime.now_local ().to_string (); } public string updated_at { get; set; default = ""; } public bool is_visible { get; set; default = true; } @@ -47,15 +47,15 @@ public class Objects.Source : Objects.BaseObject { public string header_text { get { - if (source_type == BackendType.LOCAL) { + if (source_type == SourceType.LOCAL) { return _("On This Computer"); } - if (source_type == BackendType.TODOIST) { + if (source_type == SourceType.TODOIST) { return todoist_data.user_email; } - if (source_type == BackendType.CALDAV) { + if (source_type == SourceType.CALDAV) { return caldav_data.user_email; } @@ -66,11 +66,11 @@ public class Objects.Source : Objects.BaseObject { string _subheader_text; public string subheader_text { get { - if (source_type == BackendType.TODOIST) { + if (source_type == SourceType.TODOIST) { return _("Todoist"); } - if (source_type == BackendType.CALDAV) { + if (source_type == SourceType.CALDAV) { _subheader_text = _("CalDAV - ") + caldav_data.caldav_type.title (); return _subheader_text; } @@ -85,6 +85,34 @@ public class Objects.Source : Objects.BaseObject { } } + public string user_displayname { + get { + if (source_type == SourceType.TODOIST) { + return todoist_data.user_name; + } + + if (source_type == SourceType.CALDAV) { + return caldav_data.user_displayname; + } + + return ""; + } + } + + public string user_email { + get { + if (source_type == SourceType.TODOIST) { + return todoist_data.user_email; + } + + if (source_type == SourceType.CALDAV) { + return caldav_data.user_email; + } + + return ""; + } + } + private uint server_timeout = 0; public signal void sync_started (); @@ -104,7 +132,11 @@ public class Objects.Source : Objects.BaseObject { server_timeout = Timeout.add_seconds (15 * 60, () => { if (sync_server) { - Services.Todoist.get_default ().sync.begin (this); + if (source_type == SourceType.TODOIST) { + Services.Todoist.get_default ().sync.begin (this); + } else if (source_type == SourceType.CALDAV) { + Services.CalDAV.Core.get_default ().sync.begin (this); + } } return true; diff --git a/core/QuickAdd.vala b/core/QuickAdd.vala index abdd5ee3e..672b8f992 100644 --- a/core/QuickAdd.vala +++ b/core/QuickAdd.vala @@ -365,10 +365,10 @@ public class Layouts.QuickAdd : Adw.Bin { item.content = content_entry.get_text (); item.description = description_textview.get_text (); - if (item.project.source_type == BackendType.LOCAL) { + if (item.project.source_type == SourceType.LOCAL) { item.id = Util.get_default ().generate_id (); _add_item (item); - } else if (item.project.source_type == BackendType.TODOIST) { + } else if (item.project.source_type == SourceType.TODOIST) { is_loading = true; Services.Todoist.get_default ().add.begin (item, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -379,7 +379,7 @@ public class Layouts.QuickAdd : Adw.Bin { _add_item (item); } }); - } else if (item.project.source_type == BackendType.CALDAV) { + } else if (item.project.source_type == SourceType.CALDAV) { is_loading = true; item.id = Util.get_default ().generate_id (); Services.CalDAV.Core.get_default ().add_task.begin (item, false, (obj, res) => { diff --git a/core/Services/CalDAV/Core.vala b/core/Services/CalDAV/Core.vala index 208f99711..12651ddc1 100644 --- a/core/Services/CalDAV/Core.vala +++ b/core/Services/CalDAV/Core.vala @@ -22,7 +22,6 @@ public class Services.CalDAV.Core : GLib.Object { private Soup.Session session; private Json.Parser parser; - private Secret.Schema schema; private static Core? _instance; public static Core get_default () { @@ -36,13 +35,6 @@ public class Services.CalDAV.Core : GLib.Object { public signal void first_sync_started (); public signal void first_sync_finished (); - public signal void sync_started (); - public signal void sync_finished (); - - public signal void log_out (); - public signal void log_in (); - - private uint server_timeout = 0; private Gee.HashMap request_map; // vala-lint=naming-convention @@ -291,37 +283,20 @@ public class Services.CalDAV.Core : GLib.Object { session = new Soup.Session (); parser = new Json.Parser (); - schema = new Secret.Schema ("io.github.alainm23.planify", Secret.SchemaFlags.NONE, - "username", Secret.SchemaAttributeType.STRING, - "server_url", Secret.SchemaAttributeType.STRING - ); - - var network_monitor = GLib.NetworkMonitor.get_default (); - network_monitor.network_changed.connect (() => { - if (GLib.NetworkMonitor.get_default ().network_available && - is_logged_in () && - Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server")) { - sync_async (); - } - }); + // var network_monitor = GLib.NetworkMonitor.get_default (); + // network_monitor.network_changed.connect (() => { + // if (GLib.NetworkMonitor.get_default ().network_available && + // is_logged_in () && + // Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server")) { + // sync_async (); + // } + // }); request_map = new Gee.HashMap (); request_map.set (CalDAVType.NEXTCLOUD.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); request_map.set (CalDAVType.RADICALE.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); } - public void run_server () { - sync_async (); - - server_timeout = Timeout.add_seconds (15 * 60, () => { - if (Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server")) { - sync_async (); - } - - return true; - }); - } - public string get_request_data (CalDAVType caldav_type, string method) { if (request_map.has_key (caldav_type.to_string () + method)) { return request_map[caldav_type.to_string () + method]; @@ -347,7 +322,7 @@ public class Services.CalDAV.Core : GLib.Object { response.error = e.message; return response; } - + string url = Services.CalDAV.Backend.generate_server_url (caldav_type, _server_url, username, GLib.Uri.escape_string (password)); print ("Server URL: %s\n".printf (url)); @@ -367,7 +342,8 @@ public class Services.CalDAV.Core : GLib.Object { if (message.status_code == 207) { var source = new Objects.Source (); source.id = Util.get_default ().generate_id (); - source.source_type = BackendType.CALDAV; + source.source_type = SourceType.CALDAV; + source.last_sync = new GLib.DateTime.now_local ().to_string (); Objects.SourceCalDAVData caldav_data = new Objects.SourceCalDAVData (); caldav_data.server_url = url; @@ -446,9 +422,8 @@ public class Services.CalDAV.Core : GLib.Object { yield get_all_tasks_by_tasklist (project); } } - + first_sync_finished (); - log_in (); } catch (Error e) { debug (e.message); } @@ -485,7 +460,7 @@ public class Services.CalDAV.Core : GLib.Object { label.id = Util.get_default ().generate_id (label); label.name = category; label.color = Util.get_default ().get_random_color (); - label.backend_type = BackendType.CALDAV; + label.backend_type = SourceType.CALDAV; Services.Store.instance ().insert_label (label); } @@ -517,17 +492,13 @@ public class Services.CalDAV.Core : GLib.Object { } public async void update_all_tasks_by_tasklist (Objects.Project project, Gee.HashMap labels_map) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/%s/".printf (server_url, username, project.id); + var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("REPORT", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.request_headers.append ("Depth", "1"); + message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); try { - yield set_credential (message); - message.request_headers.append ("Depth", "1"); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); print_root ("update_all_tasks_by_tasklist", (string) stream.get_data ()); @@ -541,13 +512,13 @@ public class Services.CalDAV.Core : GLib.Object { foreach (string category in labels_map.values) { // TODO: VERIFICAR CALDAV - var label = Services.Store.instance ().get_label_by_name (category, true, BackendType.CALDAV.to_string ()); + var label = Services.Store.instance ().get_label_by_name (category, true, SourceType.CALDAV.to_string ()); if (label == null) { label = new Objects.Label (); label.id = Util.get_default ().generate_id (label); label.name = category; label.color = Util.get_default ().get_random_color (); - label.backend_type = BackendType.CALDAV; + label.backend_type = SourceType.CALDAV; Services.Store.instance ().insert_label (label); } } @@ -616,25 +587,16 @@ public class Services.CalDAV.Core : GLib.Object { return return_value; } - public void sync_async () { - sync.begin ((obj, res) => { - sync.end (res); - }); - } - - private async void sync () { - sync_started (); - - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/".printf (server_url, username); + public async void sync (Objects.Source source) { + var url = "%s/calendars/%s/".printf (source.caldav_data.server_url, source.caldav_data.username); var message = new Soup.Message ("PROPFIND", url); + message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); + message.request_headers.append ("Depth", "1"); + message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); + source.sync_started (); + try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); print_root ("sync", (string) stream.get_data ()); @@ -660,29 +622,25 @@ public class Services.CalDAV.Core : GLib.Object { } } } + + foreach (Objects.Project project in Services.Store.instance ().get_projects_by_source (source.id)) { + yield sync_tasklist (project); + } + + source.sync_finished (); + source.last_sync = new GLib.DateTime.now_local ().to_string (); } catch (Error e) { debug (e.message); } - - foreach (Objects.Project project in Services.Store.instance ().get_all_projects_by_backend_type (BackendType.CALDAV)) { - yield sync_tasklist (project); - } - - Services.Settings.get_default ().settings.set_string ("caldav-last-sync", new GLib.DateTime.now_local ().to_string ()); - sync_finished (); } public async void sync_tasklist (Objects.Project project) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/%s".printf (server_url, username, project.id); + var url = "%s/calendars/%s/%s".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("REPORT", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((SYNC_TOKEN_REQUEST.printf (project.sync_id)).data)); try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((SYNC_TOKEN_REQUEST.printf (project.sync_id)).data)); - if (project.sync_id == "") { return; } @@ -708,7 +666,7 @@ public class Services.CalDAV.Core : GLib.Object { continue; } - string vtodo = yield get_vtodo_by_url (project.id, ics); + string vtodo = yield get_vtodo_by_url (project, ics); ICal.Component ical = new ICal.Component.from_string (vtodo); Objects.Item? item = Services.Store.instance ().get_item (ical.get_uid ()); @@ -761,17 +719,14 @@ public class Services.CalDAV.Core : GLib.Object { } } - private async string? get_vtodo_by_url (string tasklist_id, string task_ics) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/%s/%s".printf (server_url, username, tasklist_id, task_ics); + private async string? get_vtodo_by_url (Objects.Project project, string task_ics) { + var url = "%s/calendars/%s/%s/%s".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id, task_ics); + var message = new Soup.Message ("GET", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); string return_value = null; try { - yield set_credential (message); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); print_root ("get_vtodo_by_url", (string) stream.get_data ()); return_value = (string) stream.get_data (); @@ -845,18 +800,14 @@ public class Services.CalDAV.Core : GLib.Object { */ public async bool add_tasklist (Objects.Project project) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/%s/".printf (server_url, username, project.id); + var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("MKCOL", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((CREATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); + bool status = false; try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((CREATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); - - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); status = true; } catch (Error e) { @@ -866,18 +817,16 @@ public class Services.CalDAV.Core : GLib.Object { return status; } - public async bool update_tasklist (Objects.Project project) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/%s/".printf (server_url, username, project.id); + public async bool update_tasklist (Objects.Project project) { + var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); + var message = new Soup.Message ("PROPPATCH", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((UPDATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); + bool status = false; try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((UPDATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); status = true; } catch (Error e) { @@ -887,17 +836,14 @@ public class Services.CalDAV.Core : GLib.Object { return status; } - public async bool delete_tasklist (Objects.Project project) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); + public async bool delete_tasklist (Objects.Project project) { + var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); - var url = "%s/remote.php/dav/calendars/%s/%s/".printf (server_url, username, project.id); var message = new Soup.Message ("DELETE", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); bool status = false; try { - yield set_credential (message); - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); status = true; } catch (Error e) { @@ -908,18 +854,15 @@ public class Services.CalDAV.Core : GLib.Object { } public async HttpResponse refresh_tasklist (Objects.Project project) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var url = "%s/remote.php/dav/calendars/%s/%s/".printf (server_url, username, project.id); + var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); + var message = new Soup.Message ("PROPFIND", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((TASKLIST_REQUEST).data)); HttpResponse return_value = new HttpResponse (); try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((TASKLIST_REQUEST).data)); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); print_root ("refresh_tasklist", (string) stream.get_data ()); @@ -943,18 +886,15 @@ public class Services.CalDAV.Core : GLib.Object { } public async HttpResponse get_sync_token (Objects.Project project) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); + var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); - var url = "%s/remote.php/dav/calendars/%s/%s/".printf (server_url, username, project.id); var message = new Soup.Message ("PROPFIND", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((GET_SYNC_TOKEN_REQUEST).data)); HttpResponse return_value = new HttpResponse (); try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes ((GET_SYNC_TOKEN_REQUEST).data)); - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); print_root ("get_tasklist", (string) stream.get_data ()); @@ -978,20 +918,17 @@ public class Services.CalDAV.Core : GLib.Object { */ public async HttpResponse add_task (Objects.Item item, bool update = false) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - var ics = update ? item.ics : "%s.ics".printf (item.id); - var url = "%s/remote.php/dav/calendars/%s/%s/%s".printf (server_url, username, item.project.id, ics); + var url = "%s/calendars/%s/%s/%s".printf (item.project.source.caldav_data.server_url, item.project.source.caldav_data.username, item.project.id, ics); + var message = new Soup.Message ("PUT", url); + message.request_headers.append ("Authorization", "Basic %s".printf (item.project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes (item.to_vtodo ().data)); HttpResponse response = new HttpResponse (); try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (item.to_vtodo ().data)); - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); if (update ? message.status_code == 204 : message.status_code == 201) { @@ -1006,16 +943,14 @@ public class Services.CalDAV.Core : GLib.Object { } public async HttpResponse delete_task (Objects.Item item) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); + var url = "%s/calendars/%s/%s/%s".printf (item.project.source.caldav_data.server_url, item.project.source.caldav_data.username, item.project.id, item.ics); - var url = "%s/remote.php/dav/calendars/%s/%s/%s".printf (server_url, username, item.project.id, item.ics); var message = new Soup.Message ("DELETE", url); + message.request_headers.append ("Authorization", "Basic %s".printf (item.project.source.caldav_data.credentials)); HttpResponse response = new HttpResponse (); try { - yield set_credential (message); GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); print_root ("delete_task", (string) stream.get_data ()); @@ -1035,22 +970,19 @@ public class Services.CalDAV.Core : GLib.Object { } public async HttpResponse complete_item (Objects.Item item) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - - var ics = item.ics; var body = item.to_vtodo (); - var url = "%s/remote.php/dav/calendars/%s/%s/%s".printf (server_url, username, item.project.id, ics); + var url = "%s/calendars/%s/%s/%s".printf (item.project.source.caldav_data.server_url, item.project.source.caldav_data.username, item.project.id, ics); + var message = new Soup.Message ("PUT", url); + message.request_headers.append ("Authorization", "Basic %s".printf (item.project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes (body.data)); + HttpResponse response = new HttpResponse (); - try { - yield set_credential (message); - message.set_request_body_from_bytes ("application/xml", new Bytes (body.data)); - + try { yield session.send_and_read_async (message, GLib.Priority.HIGH, null); if (message.status_code == 204) { @@ -1065,19 +997,18 @@ public class Services.CalDAV.Core : GLib.Object { } public async HttpResponse move_task (Objects.Item item, string project_id) { - var server_url = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - var username = Services.Settings.get_default ().settings.get_string ("caldav-username"); + string username = item.project.source.caldav_data.username; - var url = "%s/remote.php/dav/calendars/%s/%s/%s".printf (server_url, username, item.project.id, item.ics); + var url = "%s/calendars/%s/%s/%s".printf (item.project.source.caldav_data.server_url, username, item.project.id, item.ics); var destination = "/remote.php/dav/calendars/%s/%s/%s".printf (username, project_id, item.ics); + var message = new Soup.Message ("MOVE", url); + message.request_headers.append ("Authorization", "Basic %s".printf (item.project.source.caldav_data.credentials)); + message.request_headers.append ("Destination", destination); HttpResponse response = new HttpResponse (); try { - yield set_credential (message); - message.request_headers.append ("Destination", destination); - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); if (message.status_code == 201 || message.status_code == 204) { @@ -1090,29 +1021,6 @@ public class Services.CalDAV.Core : GLib.Object { return response; } - public void remove_items () { - Services.Settings.get_default ().settings.set_string ("caldav-server-url", ""); - Services.Settings.get_default ().settings.set_string ("caldav-username", ""); - Services.Settings.get_default ().settings.set_string ("caldav-user-email", ""); - Services.Settings.get_default ().settings.set_string ("caldav-user-displayname", ""); - - // Delete all projects, sections and items - foreach (var project in Services.Store.instance ().get_all_projects_by_backend_type (BackendType.CALDAV)) { - Services.Store.instance ().delete_project (project); - } - - // Delete all labels; - foreach (var label in Services.Store.instance ().get_labels_by_backend_type (BackendType.CALDAV)) { - Services.Store.instance ().delete_label (label); - } - - // Remove server_timeout - GLib.Source.remove (server_timeout); - server_timeout = 0; - - log_out (); - } - /* * Utils */ @@ -1151,21 +1059,6 @@ public class Services.CalDAV.Core : GLib.Object { return resourcetype.get_elements_by_tag_name ("x2:deleted-calendar").length > 0; } - private GLib.HashTable get_attributes () { - var attributes = new GLib.HashTable (str_hash, str_equal); - attributes["username"] = Services.Settings.get_default ().settings.get_string ("caldav-username"); - attributes["server_url"] = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); - return attributes; - } - - private async void set_credential (Soup.Message message) throws Error { - string username = Services.Settings.get_default ().settings.get_string ("caldav-username"); - string password = yield Secret.password_lookupv (schema, get_attributes (), null); - string credentials = "%s:%s".printf (username, password); - string base64_credentials = Base64.encode (credentials.data); - message.request_headers.append ("Authorization", "Basic %s".printf (base64_credentials)); - } - private void print_root (string fuction, string data) { print (fuction + "\n"); print (data + "\n"); diff --git a/core/Services/Database.vala b/core/Services/Database.vala index 09ca73307..63cd7794d 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -476,7 +476,7 @@ public class Services.Database : GLib.Object { 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 = BackendType.parse (stmt.column_text (1)); + return_value.source_type = SourceType.parse (stmt.column_text (1)); return_value.added_at = stmt.column_text (2); return_value.updated_at = stmt.column_text (3); return_value.is_visible = get_parameter_bool (stmt, 4); @@ -484,9 +484,9 @@ public class Services.Database : GLib.Object { return_value.sync_server = get_parameter_bool (stmt, 6); return_value.last_sync = stmt.column_text (7); - if (return_value.source_type == BackendType.TODOIST) { + if (return_value.source_type == SourceType.TODOIST) { return_value.data = new Objects.SourceTodoistData.from_json (stmt.column_text (8)); - } else if (return_value.source_type == BackendType.CALDAV) { + } else if (return_value.source_type == SourceType.CALDAV) { return_value.data = new Objects.SourceCalDAVData.from_json (stmt.column_text (8)); } @@ -600,7 +600,7 @@ public class Services.Database : GLib.Object { 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 = get_backend_type_by_text (stmt, 3); + 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); @@ -623,20 +623,6 @@ public class Services.Database : GLib.Object { return return_value; } - private BackendType get_backend_type_by_text (Sqlite.Statement stmt, int col) { - if (stmt.column_text (col) == "local") { - return BackendType.LOCAL; - } else if (stmt.column_text (col) == "todoist") { - return BackendType.TODOIST; - } else if (stmt.column_text (col) == "google-tasks") { - return BackendType.GOOGLE_TASKS; - } else if (stmt.column_text (col) == "caldav") { - return BackendType.CALDAV; - } else { - return BackendType.NONE; - } - } - public bool insert_project (Objects.Project project) { Sqlite.Statement stmt; @@ -833,7 +819,7 @@ public class Services.Database : GLib.Object { 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 = get_backend_type_by_text (stmt, 6); + return_value.backend_type = SourceType.parse (stmt.column_text (6)); return_value.source_id = stmt.column_text (7); return return_value; } @@ -1122,7 +1108,7 @@ public class Services.Database : GLib.Object { set_parameter_int (stmt, "$day_order", item.day_order); set_parameter_bool (stmt, "$collapsed", item.collapsed); set_parameter_bool (stmt, "$pinned", item.pinned); - // TODO: set_parameter_str (stmt, "$labels", get_labels_ids (item.labels)); + 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 ()); @@ -1134,6 +1120,20 @@ public class Services.Database : GLib.Object { return stmt.step () == Sqlite.DONE; } + 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 Gee.ArrayList get_items_collection () { Gee.ArrayList return_value = new Gee.ArrayList (); Sqlite.Statement stmt; @@ -1185,7 +1185,7 @@ public class Services.Database : GLib.Object { return_value.day_order = stmt.column_int (14); return_value.collapsed = get_parameter_bool (stmt, 15); return_value.pinned = get_parameter_bool (stmt, 16); - // TODO: return_value.labels = get_labels_by_item_labels (stmt.column_text (17)); + 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)); @@ -2005,23 +2005,24 @@ public class Services.Database : GLib.Object { if (Services.Todoist.get_default ().is_logged_in ()) { var todoist_source = new Objects.Source (); - todoist_source.id = BackendType.TODOIST.to_string (); - todoist_source.source_type = BackendType.TODOIST; + todoist_source.id = SourceType.TODOIST.to_string (); + todoist_source.source_type = SourceType.TODOIST; 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"); - insert_source (todoist_source); + 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 = BackendType.CALDAV.to_string (); - caldav_source.source_type = BackendType.CALDAV; + 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"); - insert_source (caldav_source); + Services.Store.instance ().insert_source (caldav_source); } } } diff --git a/core/Services/EventBus.vala b/core/Services/EventBus.vala index 6566c2ab6..a50adc1d1 100644 --- a/core/Services/EventBus.vala +++ b/core/Services/EventBus.vala @@ -62,6 +62,7 @@ public class Services.EventBus : Object { public signal void request_escape (); public signal void drag_n_drop_active (string project_id, bool active); public signal void expand_all (string project_id, bool active); + public signal void drag_end (string source_id); public bool _mobile_mode = Services.Settings.get_default ().settings.get_boolean ("mobile-mode"); public bool mobile_mode { diff --git a/core/Services/Store.vala b/core/Services/Store.vala index 4f5cf4897..d318f29dd 100644 --- a/core/Services/Store.vala +++ b/core/Services/Store.vala @@ -384,19 +384,6 @@ public class Services.Store : GLib.Object { return return_value; } - public Gee.ArrayList get_projects_by_backend_type (BackendType backend_type) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.backend_type == backend_type && !project.is_inbox_project) { - return_value.add (project); - } - } - - return return_value; - } - } - public int next_project_child_order (Objects.Source source) { int child_order = 0; @@ -999,20 +986,6 @@ public class Services.Store : GLib.Object { return return_value; } - 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 Gee.ArrayList get_items_has_labels () { Gee.ArrayList return_value = new Gee.ArrayList (); lock (_items) { @@ -1069,19 +1042,6 @@ public class Services.Store : GLib.Object { } } - public Gee.ArrayList get_labels_by_backend_type (BackendType backend_type) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_labels) { - foreach (var label in labels) { - if (backend_type == BackendType.ALL ? true : label.backend_type == backend_type) { - return_value.add (label); - } - } - - return return_value; - } - } - public Gee.ArrayList get_labels_by_source (string source_id) { Gee.ArrayList return_value = new Gee.ArrayList (); lock (_labels) { @@ -1138,32 +1098,6 @@ public class Services.Store : GLib.Object { } } - public Gee.ArrayList get_all_projects_by_todoist () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.backend_type == BackendType.TODOIST) { - return_value.add (project); - } - } - - return return_value; - } - } - - public Gee.ArrayList get_all_projects_by_backend_type (BackendType backend_type) { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_projects) { - foreach (var project in projects) { - if (project.backend_type == backend_type) { - return_value.add (project); - } - } - - return return_value; - } - } - public Gee.ArrayList get_all_projects_archived () { Gee.ArrayList return_value = new Gee.ArrayList (); lock (_projects) { @@ -1177,19 +1111,6 @@ public class Services.Store : GLib.Object { } } - public Gee.ArrayList get_all_labels_by_todoist () { - Gee.ArrayList return_value = new Gee.ArrayList (); - lock (_labels) { - foreach (var label in labels) { - if (label.backend_type == BackendType.TODOIST) { - return_value.add (label); - } - } - - return return_value; - } - } - public Gee.ArrayList get_all_items_by_search (string search_text) { Gee.ArrayList return_value = new Gee.ArrayList (); lock (_items) { diff --git a/core/Services/Todoist.vala b/core/Services/Todoist.vala index 4c614bf3c..29070bb7e 100644 --- a/core/Services/Todoist.vala +++ b/core/Services/Todoist.vala @@ -110,7 +110,7 @@ public class Services.Todoist : GLib.Object { var source = new Objects.Source (); source.id = Util.get_default ().generate_id (); - source.source_type = BackendType.TODOIST; + source.source_type = SourceType.TODOIST; Objects.SourceTodoistData todoist_data = new Objects.SourceTodoistData (); todoist_data.sync_token = parser.get_root ().get_object ().get_string_member ("sync_token"); @@ -136,7 +136,10 @@ public class Services.Todoist : GLib.Object { // Create Labels unowned Json.Array labels = parser.get_root ().get_object ().get_array_member (LABELS_COLLECTION); foreach (unowned Json.Node _node in labels.get_elements ()) { - Services.Store.instance ().insert_label (new Objects.Label.from_json (_node)); + Objects.Label _label = new Objects.Label.from_json (_node); + _label.source_id = source.id; + + Services.Store.instance ().insert_label (_label); } // Create Projects @@ -247,7 +250,10 @@ public class Services.Todoist : GLib.Object { Services.Store.instance ().update_label (label); } } else { - Services.Store.instance ().insert_label (new Objects.Label.from_json (_node)); + Objects.Label _label = new Objects.Label.from_json (_node); + _label.source_id = source.id; + + Services.Store.instance ().insert_label (_label); } } diff --git a/core/Util/Migrate.vala b/core/Util/Migrate.vala index 14902181d..a3b37d15f 100644 --- a/core/Util/Migrate.vala +++ b/core/Util/Migrate.vala @@ -33,4 +33,40 @@ public class Utils.AccountMigrate { return return_value; } + + public static Objects.SourceCalDAVData get_data_from_caldav () { + Objects.SourceCalDAVData return_value = new Objects.SourceCalDAVData (); + + string _server_url = ""; + var uri = GLib.Uri.parse (Services.Settings.get_default ().settings.get_string ("caldav-server-url"), GLib.UriFlags.NONE); + _server_url = "%s://%s".printf (uri.get_scheme (), uri.get_host ()); + + return_value.server_url = "%s/remote.php/dav".printf (_server_url); + return_value.username = Services.Settings.get_default ().settings.get_string ("caldav-username"); + return_value.credentials = get_credential (); + return_value.user_displayname = Services.Settings.get_default ().settings.get_string ("caldav-user-displayname"); + return_value.user_email = Services.Settings.get_default ().settings.get_string ("caldav-user-email"); + return_value.caldav_type = CalDAVType.NEXTCLOUD; + + return return_value; + } + + private static string get_credential () throws Error { + Secret.Schema schema = new Secret.Schema ("io.github.alainm23.planify", Secret.SchemaFlags.NONE, + "username", Secret.SchemaAttributeType.STRING, + "server_url", Secret.SchemaAttributeType.STRING + ); + + string username = Services.Settings.get_default ().settings.get_string ("caldav-username"); + + GLib.HashTable attributes = new GLib.HashTable (str_hash, str_equal); + attributes["username"] = username; + attributes["server_url"] = Services.Settings.get_default ().settings.get_string ("caldav-server-url"); + + string password = Secret.password_lookupv_sync (schema, attributes, null); + string credentials = "%s:%s".printf (username, password); + string base64_credentials = Base64.encode (credentials.data); + + return base64_credentials; + } } \ No newline at end of file diff --git a/core/Util/Util.vala b/core/Util/Util.vala index 55f4e2614..4473065c7 100644 --- a/core/Util/Util.vala +++ b/core/Util/Util.vala @@ -569,17 +569,16 @@ public class Util : GLib.Object { public Objects.Source create_local_source () { Objects.Source local_source = new Objects.Source (); - local_source.id = BackendType.LOCAL.to_string (); - local_source.source_type = BackendType.LOCAL; + local_source.id = SourceType.LOCAL.to_string (); + local_source.source_type = SourceType.LOCAL; Services.Store.instance ().insert_source (local_source); return local_source; } public Objects.Project create_inbox_project () { Objects.Project inbox_project = new Objects.Project (); - inbox_project.source_id = BackendType.LOCAL.to_string (); + inbox_project.source_id = SourceType.LOCAL.to_string (); inbox_project.id = Util.get_default ().generate_id (inbox_project); - inbox_project.backend_type = BackendType.LOCAL; inbox_project.name = _("Inbox"); inbox_project.inbox_project = true; inbox_project.color = "blue"; @@ -593,8 +592,7 @@ public class Util : GLib.Object { public void create_tutorial_project () { Objects.Project project = new Objects.Project (); project.id = Util.get_default ().generate_id (project); - project.source_id = BackendType.LOCAL.to_string (); - project.backend_type = BackendType.LOCAL; + project.source_id = SourceType.LOCAL.to_string (); project.icon_style = ProjectIconStyle.EMOJI; project.emoji = "🚀️"; project.name = _("Meet Planify"); @@ -709,31 +707,31 @@ We hope you’ll enjoy using Planify!"""); public void create_default_labels () { var label_01 = new Objects.Label (); label_01.id = Util.get_default ().generate_id (label_01); - label_01.backend_type = BackendType.LOCAL; + label_01.source_id = SourceType.LOCAL.to_string (); label_01.name = _("💼️Work"); label_01.color = "taupe"; var label_02 = new Objects.Label (); label_02.id = Util.get_default ().generate_id (label_02); - label_02.backend_type = BackendType.LOCAL; + label_02.source_id = SourceType.LOCAL.to_string (); label_02.name = _("🎒️School"); label_02.color = "berry_red"; var label_03 = new Objects.Label (); label_03.id = Util.get_default ().generate_id (label_03); - label_03.backend_type = BackendType.LOCAL; + label_03.source_id = SourceType.LOCAL.to_string (); label_03.name = _("👉️Delegated"); label_03.color = "yellow"; var label_04 = new Objects.Label (); label_04.id = Util.get_default ().generate_id (label_04); - label_04.backend_type = BackendType.LOCAL; + label_04.source_id = SourceType.LOCAL.to_string (); label_04.name = _("🏡️Home"); label_04.color = "lime_green"; var label_05 = new Objects.Label (); label_05.id = Util.get_default ().generate_id (label_05); - label_05.backend_type = BackendType.LOCAL; + label_05.source_id = SourceType.LOCAL.to_string (); label_05.name = _("🏃‍♀️️Follow Up"); label_05.color = "grey"; @@ -744,17 +742,17 @@ We hope you’ll enjoy using Planify!"""); Services.Store.instance ().insert_label (label_05); } - public BackendType get_backend_type_by_text (string backend_type) { + public SourceType get_backend_type_by_text (string backend_type) { if (backend_type == "local") { - return BackendType.LOCAL; + return SourceType.LOCAL; } else if (backend_type == "todoist") { - return BackendType.TODOIST; + return SourceType.TODOIST; } else if (backend_type == "google-tasks") { - return BackendType.GOOGLE_TASKS; + return SourceType.GOOGLE_TASKS; } else if (backend_type == "caldav") { - return BackendType.CALDAV; + return SourceType.CALDAV; } else { - return BackendType.NONE; + return SourceType.NONE; } } @@ -859,10 +857,10 @@ We hope you’ll enjoy using Planify!"""); item.loading = true; item.sensitive = false; - if (target_project.backend_type == BackendType.LOCAL) { + if (target_project.source_type == SourceType.LOCAL) { new_item.id = Util.get_default ().generate_id (new_item); yield add_final_duplicate_item (new_item, item); - } else if (target_project.backend_type == BackendType.TODOIST) { + } else if (target_project.source_type == SourceType.TODOIST) { HttpResponse response = yield Services.Todoist.get_default ().add (new_item); item.loading = false; @@ -870,7 +868,7 @@ We hope you’ll enjoy using Planify!"""); new_item.id = response.data; yield add_final_duplicate_item (new_item, item); } - } else if (target_project.backend_type == BackendType.CALDAV) { + } else if (target_project.source_type == SourceType.CALDAV) { new_item.id = Util.get_default ().generate_id (new_item); HttpResponse response = yield Services.CalDAV.Core.get_default ().add_task (new_item); item.loading = false; @@ -918,14 +916,14 @@ We hope you’ll enjoy using Planify!"""); item.loading = true; item.sensitive = false; - if (item.project.backend_type == BackendType.LOCAL) { + if (item.project.source_type == SourceType.LOCAL) { new_item.id = Util.get_default ().generate_id (new_item); item.loading = false; item.sensitive = true; yield insert_duplicate_item (new_item, item, notify); - } else if (item.project.backend_type == BackendType.TODOIST) { + } else if (item.project.source_type == SourceType.TODOIST) { HttpResponse response = yield Services.Todoist.get_default ().add (new_item); item.loading = false; @@ -935,7 +933,7 @@ We hope you’ll enjoy using Planify!"""); new_item.id = response.data; yield insert_duplicate_item (new_item, item, notify); } - } else if (item.project.backend_type == BackendType.CALDAV) { + } else if (item.project.source_type == SourceType.CALDAV) { new_item.id = Util.get_default ().generate_id (new_item); HttpResponse response = yield Services.CalDAV.Core.get_default ().add_task (new_item); @@ -993,10 +991,10 @@ We hope you’ll enjoy using Planify!"""); section.loading = true; section.sensitive = false; - if (new_section.project.backend_type == BackendType.LOCAL) { + if (new_section.project.source_type == SourceType.LOCAL) { new_section.id = Util.get_default ().generate_id (new_section); yield insert_duplicate_section (new_section, section, notify); - } else if (new_section.project.backend_type == BackendType.TODOIST) { + } else if (new_section.project.source_type == SourceType.TODOIST) { HttpResponse response = yield Services.Todoist.get_default ().add (new_section); if (response.status) { new_section.id = response.data; @@ -1028,9 +1026,8 @@ We hope you’ll enjoy using Planify!"""); project.loading = true; - if (project.backend_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { new_project.id = Util.get_default ().generate_id (new_project); - new_project.backend_type = BackendType.LOCAL; Services.Store.instance ().insert_project (new_project); foreach (Objects.Item item in project.items) { @@ -1046,7 +1043,7 @@ We hope you’ll enjoy using Planify!"""); Services.EventBus.get_default ().send_notification ( Util.get_default ().create_toast (_("Project duplicated")) ); - } else if (project.backend_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().duplicate_project.begin (project, (obj, res) => { project.loading = false; @@ -1054,10 +1051,9 @@ We hope you’ll enjoy using Planify!"""); Services.Todoist.get_default ().sync.begin (project.source); } }); - } else if (project.backend_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { new_project.id = Util.get_default ().generate_id (new_project); - new_project.backend_type = BackendType.CALDAV; - + bool status = yield Services.CalDAV.Core.get_default ().add_tasklist (new_project); if (status) { diff --git a/core/Widgets/LabelsPickerCore.vala b/core/Widgets/LabelsPickerCore.vala index d4d714567..3f38b5520 100644 --- a/core/Widgets/LabelsPickerCore.vala +++ b/core/Widgets/LabelsPickerCore.vala @@ -174,14 +174,14 @@ public class Widgets.LabelsPickerCore : Adw.Bin { label.name = search_entry.text; label.source_id = source.id; - if (source.source_type == BackendType.LOCAL || source.source_type == BackendType.CALDAV) { + if (source.source_type == SourceType.LOCAL || source.source_type == SourceType.CALDAV) { label.id = Util.get_default ().generate_id (label); Services.Store.instance ().insert_label (label); checked_toggled (label, true); search_entry.text = ""; close (); - } else if (source.source_type == BackendType.TODOIST) { + } else if (source.source_type == SourceType.TODOIST) { is_loading = true; Services.Todoist.get_default ().add.begin (label, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); diff --git a/core/Widgets/ProjectPicker/ProjectPickerButton.vala b/core/Widgets/ProjectPicker/ProjectPickerButton.vala index 244e864b1..237ae27a4 100644 --- a/core/Widgets/ProjectPicker/ProjectPickerButton.vala +++ b/core/Widgets/ProjectPicker/ProjectPickerButton.vala @@ -100,7 +100,7 @@ public class Widgets.ProjectPicker.ProjectPickerButton : Adw.Bin { name_label.label = project.is_inbox_project ? _("Inbox") : project.name; icon_project.project = project; icon_project.update_request (); - section_box_revealer.reveal_child = project.backend_type != BackendType.CALDAV; + section_box_revealer.reveal_child = project.source_type != SourceType.CALDAV; } private Gtk.Popover build_sections_popover () { diff --git a/data/resources/stylesheet/stylesheet.css b/data/resources/stylesheet/stylesheet.css index 37fb85f62..9de723f71 100644 --- a/data/resources/stylesheet/stylesheet.css +++ b/data/resources/stylesheet/stylesheet.css @@ -629,11 +629,17 @@ checkbutton.theme-selector radio:checked { } .no-selectable:hover, +.no-selectable:focus, .no-selectable:selected, +.no-selectable.activatable:hover, +.no-selectable.activatable:active, +.no-selectable.activatable:selected, .no-selectable { + box-shadow: none; + outline: none; background: transparent; } .pinboard-color { color: #ed333b; -} \ No newline at end of file +} diff --git a/src/Dialogs/Label.vala b/src/Dialogs/Label.vala index 4b0459757..31d74b7b8 100644 --- a/src/Dialogs/Label.vala +++ b/src/Dialogs/Label.vala @@ -32,11 +32,11 @@ public class Dialogs.Label : Adw.Dialog { } } - public Label.new (BackendType backend_type = BackendType.LOCAL) { + public Label.new (Objects.Source source) { var label = new Objects.Label (); label.color = "blue"; label.id = ""; - label.backend_type = backend_type; + label.source_id = source.id; Object ( label: label, @@ -121,8 +121,8 @@ public class Dialogs.Label : Adw.Dialog { return GLib.Source.REMOVE; }); - name_entry.entry_activated.connect (add_update_project); - submit_button.clicked.connect (add_update_project); + name_entry.entry_activated.connect (add_update_label); + submit_button.clicked.connect (add_update_label); name_entry.changed.connect (() => { if (is_creating) { @@ -140,7 +140,7 @@ public class Dialogs.Label : Adw.Dialog { return label != null; } - private void add_update_project () { + private void add_update_label () { if (name_entry.text.length <= 0) { hide_destroy (); return; @@ -156,10 +156,10 @@ public class Dialogs.Label : Adw.Dialog { if (!is_creating) { submit_button.is_loading = true; - if (label.backend_type == BackendType.LOCAL || label.backend_type == BackendType.CALDAV) { + if (label.source_type == SourceType.LOCAL || label.source_type == SourceType.CALDAV) { Services.Store.instance ().update_label (label); hide_destroy (); - } else if (label.backend_type == BackendType.TODOIST) { + } else if (label.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().update.begin (label, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Store.instance ().update_label (label); @@ -168,13 +168,13 @@ public class Dialogs.Label : Adw.Dialog { }); } } else { - label.item_order = Services.Store.instance ().get_labels_by_backend_type (label.backend_type).size; + label.item_order = Services.Store.instance ().get_labels_by_source (label.source_id).size; - if (label.backend_type == BackendType.LOCAL || label.backend_type == BackendType.CALDAV) { + if (label.source_type == SourceType.LOCAL || label.source_type == SourceType.CALDAV) { label.id = Util.get_default ().generate_id (label); Services.Store.instance ().insert_label (label); hide_destroy (); - } else if (label.backend_type == BackendType.TODOIST) { + } else if (label.source_type == SourceType.TODOIST) { submit_button.is_loading = true; Services.Todoist.get_default ().add.begin (label, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); diff --git a/src/Dialogs/Preferences/PreferencesWindow.vala b/src/Dialogs/Preferences/PreferencesWindow.vala index 3333633ce..7687cbb87 100644 --- a/src/Dialogs/Preferences/PreferencesWindow.vala +++ b/src/Dialogs/Preferences/PreferencesWindow.vala @@ -880,7 +880,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { sources_hashmap[source.id] = new Widgets.SourceRow (source); sources_hashmap[source.id].view_detail.connect (() => { - push_subpage (get_todoist_view (source)); + push_subpage (get_source_view (source)); }); sources_group.add_child (sources_hashmap[source.id]); @@ -892,7 +892,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { sources_hashmap[source.id] = new Widgets.SourceRow (source); sources_hashmap[source.id].view_detail.connect (() => { - push_subpage (get_todoist_view (source)); + push_subpage (get_source_view (source)); }); sources_group.add_child (sources_hashmap[source.id]); @@ -923,24 +923,27 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return new Adw.NavigationPage (toolbar_view, "account"); } - private Adw.NavigationPage get_todoist_view (Objects.Source source) { + private Adw.NavigationPage get_source_view (Objects.Source source) { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Todoist")); - var avatar = new Adw.Avatar (84, source.todoist_data.user_name, true); + var avatar = new Adw.Avatar (84, source.user_displayname, true); - var file = File.new_for_path (Util.get_default ().get_avatar_path (source.avatar_path)); - if (file.query_exists ()) { - var image = new Gtk.Image.from_file (file.get_path ()); - avatar.custom_image = image.get_paintable (); + if (source.source_type == SourceType.TODOIST) { + var file = File.new_for_path (Util.get_default ().get_avatar_path (source.avatar_path)); + if (file.query_exists ()) { + var image = new Gtk.Image.from_file (file.get_path ()); + avatar.custom_image = image.get_paintable (); + } } - var user_label = new Gtk.Label (source.todoist_data.user_name) { - margin_top = 12 + var user_label = new Gtk.Label (source.user_displayname) { + margin_top = 12, + css_classes = { "title-1" } }; - user_label.add_css_class ("title-1"); - var email_label = new Gtk.Label (source.todoist_data.user_email); - email_label.add_css_class ("dim-label"); + var email_label = new Gtk.Label (source.user_email) { + css_classes = { "dim-label" } + }; var user_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { margin_top = 24 @@ -956,7 +959,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { var sync_server_row = new Adw.ActionRow (); sync_server_row.title = _("Sync Server"); - sync_server_row.subtitle = _("Activate this setting so that Planify automatically synchronizes with your Todoist account every 15 minutes"); + sync_server_row.subtitle = _("Activate this setting so that Planify automatically synchronizes with your account account every 15 minutes"); sync_server_row.set_activatable_widget (sync_server_switch); sync_server_row.add_suffix (sync_server_switch); @@ -999,7 +1002,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { toolbar_view.add_top_bar (settings_header); toolbar_view.content = main_content; - var page = new Adw.NavigationPage (toolbar_view, "todoist"); + var page = new Adw.NavigationPage (toolbar_view, "source_view"); settings_header.back_activated.connect (() => { pop_subpage (); @@ -1013,92 +1016,6 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return page; } - private Adw.NavigationPage get_caldav_view () { - var settings_header = new Dialogs.Preferences.SettingsHeader (_("Nextcloud")); - - var username_label = new Gtk.Label (Services.Settings.get_default ().settings.get_string ("caldav-user-displayname")) { - margin_top = 12, - css_classes = { "title-1" } - }; - - var email_label = new Gtk.Label (Services.Settings.get_default ().settings.get_string ("caldav-user-email")) { - css_classes = { "dim-label" } - }; - - var server_url_label = new Gtk.Label (Services.Settings.get_default ().settings.get_string ("caldav-server-url")) { - css_classes = { "dim-label" } - }; - - var user_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - margin_top = 24 - }; - user_box.append (username_label); - user_box.append (email_label); - user_box.append (server_url_label); - - var sync_server_switch = new Gtk.Switch () { - valign = Gtk.Align.CENTER, - active = Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server") - }; - - var sync_server_row = new Adw.ActionRow (); - sync_server_row.title = _("Sync Server"); - sync_server_row.subtitle = _("Activate this setting so that Planify automatically synchronizes with your CalDAV account every 15 minutes"); - sync_server_row.set_activatable_widget (sync_server_switch); - sync_server_row.add_suffix (sync_server_switch); - - var last_sync_date = new GLib.DateTime.from_iso8601 ( - Services.Settings.get_default ().settings.get_string ("caldav-last-sync"), new GLib.TimeZone.local () - ); - - var last_sync_label = new Gtk.Label ( - Utils.Datetime.get_relative_date_from_date (last_sync_date) - ); - - var last_sync_row = new Adw.ActionRow (); - last_sync_row.activatable = false; - last_sync_row.title = _("Last Sync"); - last_sync_row.add_suffix (last_sync_label); - - var default_group = new Adw.PreferencesGroup () { - margin_top = 24 - }; - - default_group.add (sync_server_row); - default_group.add (last_sync_row); - - var content_clamp = new Adw.Clamp () { - maximum_size = 600, - margin_start = 24, - margin_end = 24, - child = default_group - }; - - var main_content = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { - vexpand = true, - hexpand = true - }; - - main_content.append (user_box); - main_content.append (content_clamp); - - var toolbar_view = new Adw.ToolbarView (); - toolbar_view.add_top_bar (settings_header); - toolbar_view.content = main_content; - - var page = new Adw.NavigationPage (toolbar_view, "caldav"); - - settings_header.back_activated.connect (() => { - pop_subpage (); - }); - - sync_server_row.notify["active"].connect (() => { - Services.Settings.get_default ().settings.set_boolean ("caldav-sync-server", sync_server_switch.active); - }); - - return page; - } - private Adw.NavigationPage get_quick_add_page () { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Quick Add")); diff --git a/src/Dialogs/Project.vala b/src/Dialogs/Project.vala index 7ab15e4b6..588bebb74 100644 --- a/src/Dialogs/Project.vala +++ b/src/Dialogs/Project.vala @@ -212,9 +212,9 @@ public class Dialogs.Project : Adw.Dialog { progress_bar.color = project.color; color_picker_row.color = project.color; - if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.NONE) { + if (project.source_type == SourceType.LOCAL || project.source_type == SourceType.NONE) { backend_row.selected = 0; - } else if (project.source_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { backend_row.selected = 1; } @@ -260,9 +260,9 @@ public class Dialogs.Project : Adw.Dialog { backend_row.notify["selected"].connect (() => { if (backend_row.selected == 0) { - project.backend_type = BackendType.LOCAL; + project.backend_type = SourceType.LOCAL; } else if (backend_row.selected == 1) { - project.backend_type = BackendType.TODOIST; + project.backend_type = SourceType.TODOIST; } }); @@ -293,16 +293,16 @@ public class Dialogs.Project : Adw.Dialog { private void update_project () { - if (project.source_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_project (project); hide_destroy (); - } else if (project.source_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().update.begin (project, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Store.instance ().update_project (project); hide_destroy (); }); - } else if (project.source_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().update_tasklist.begin (project, (obj, res) => { if (Services.CalDAV.Core.get_default ().update_tasklist.end (res)) { Services.Store.instance ().update_project (project); @@ -313,13 +313,13 @@ public class Dialogs.Project : Adw.Dialog { } private void add_project () { - project.child_order = Services.Store.instance ().get_projects_by_backend_type (project.backend_type).size; + project.child_order = Services.Store.instance ().get_projects_by_source (project.source_id).size; - if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.NONE) { + if (project.source_type == SourceType.LOCAL || project.source_type == SourceType.NONE) { project.id = Util.get_default ().generate_id (project); Services.Store.instance ().insert_project (project); go_project (project.id_string); - } else if (project.source_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().add.begin (project, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -329,7 +329,7 @@ public class Dialogs.Project : Adw.Dialog { go_project (project.id_string); } }); - } else if (project.source_type == BackendType.CALDAV) { + } else if (project.source_type == SourceType.CALDAV) { project.id = Util.get_default ().generate_id (project); Services.CalDAV.Core.get_default ().add_tasklist.begin (project, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_tasklist.end (res)) { diff --git a/src/Dialogs/Section.vala b/src/Dialogs/Section.vala index d3089ec58..e606a9588 100644 --- a/src/Dialogs/Section.vala +++ b/src/Dialogs/Section.vala @@ -157,19 +157,19 @@ public class Dialogs.Section : Adw.Dialog { if (!is_creating) { submit_button.is_loading = true; - if (section.project.source_type == BackendType.TODOIST) { + if (section.project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().update.begin (section, (obj, res) => { Services.Todoist.get_default ().update.end (res); Services.Store.instance ().update_section (section); submit_button.is_loading = false; hide_destroy (); }); - } else if (section.project.source_type == BackendType.LOCAL) { + } else if (section.project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_section (section); hide_destroy (); } } else { - if (section.project.source_type == BackendType.TODOIST) { + if (section.project.source_type == SourceType.TODOIST) { submit_button.is_loading = true; Services.Todoist.get_default ().add.begin (section, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -180,7 +180,7 @@ public class Dialogs.Section : Adw.Dialog { hide_destroy (); } }); - } else if (section.project.source_type == BackendType.LOCAL) { + } else if (section.project.source_type == SourceType.LOCAL) { section.id = Util.get_default ().generate_id (section); section.project.add_section_if_not_exists (section); hide_destroy (); diff --git a/src/Layouts/ItemBoard.vala b/src/Layouts/ItemBoard.vala index 46fde5b52..89c85d067 100644 --- a/src/Layouts/ItemBoard.vala +++ b/src/Layouts/ItemBoard.vala @@ -485,9 +485,9 @@ public class Layouts.ItemBoard : Layouts.ItemBase { } private void _complete_item (bool old_checked) { - if (item.project.source_type == BackendType.LOCAL) { + if (item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().checked_toggled (item, old_checked); - } else if (item.project.source_type == BackendType.TODOIST) { + } else if (item.project.source_type == SourceType.TODOIST) { checked_button.sensitive = false; is_loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { @@ -497,7 +497,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { checked_button.sensitive = true; } }); - } else if (item.project.source_type == BackendType.CALDAV) { + } else if (item.project.source_type == SourceType.CALDAV) { checked_button.sensitive = false; is_loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { @@ -831,17 +831,17 @@ public class Layouts.ItemBoard : Layouts.ItemBase { picked_item.section_id = ""; picked_item.parent_id = target_item.id; - if (picked_item.project.source_type == BackendType.LOCAL) { + if (picked_item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (picked_item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); - } else if (picked_item.project.source_type == BackendType.TODOIST) { + } else if (picked_item.project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().move_item.begin (picked_item, "parent_id", picked_item.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { Services.Store.instance ().update_item (picked_widget.item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); - } else if (picked_item.project.source_type == BackendType.CALDAV) { + } else if (picked_item.project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { Services.Store.instance ().update_item (picked_widget.item); @@ -927,7 +927,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { picked_widget.item.parent_id = target_widget.item.parent_id; } - if (picked_widget.item.project.source_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == SourceType.TODOIST) { string move_id = picked_widget.item.project_id; string move_type = "project_id"; @@ -946,7 +946,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { Services.Store.instance ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (picked_widget.item); } } @@ -1047,7 +1047,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { public void update_pinned (bool pinned) { item.pinned = pinned; - if (item.project.source_type == BackendType.CALDAV) { + if (item.project.source_type == SourceType.CALDAV) { item.update_async (""); } else { item.update_local (); diff --git a/src/Layouts/ItemRow.vala b/src/Layouts/ItemRow.vala index 8e3ce6db1..7d7342d04 100644 --- a/src/Layouts/ItemRow.vala +++ b/src/Layouts/ItemRow.vala @@ -653,8 +653,8 @@ public class Layouts.ItemRow : Layouts.ItemBase { if (item.priority != priority) { item.priority = priority; - if (item.project.source_type == BackendType.TODOIST || - item.project.source_type == BackendType.CALDAV) { + if (item.project.source_type == SourceType.TODOIST || + item.project.source_type == SourceType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -960,7 +960,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { public void update_pinned (bool pinned) { item.pinned = pinned; - if (item.project.source_type == BackendType.CALDAV) { + if (item.project.source_type == SourceType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -1376,9 +1376,9 @@ public class Layouts.ItemRow : Layouts.ItemBase { } private void _complete_item (bool old_checked) { - if (item.project.source_type == BackendType.LOCAL) { + if (item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().checked_toggled (item, old_checked); - } else if (item.project.source_type == BackendType.TODOIST) { + } else if (item.project.source_type == SourceType.TODOIST) { checked_button.sensitive = false; is_loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { @@ -1388,7 +1388,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { checked_button.sensitive = true; } }); - } else if (item.project.source_type == BackendType.CALDAV) { + } else if (item.project.source_type == SourceType.CALDAV) { checked_button.sensitive = false; is_loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { @@ -1596,11 +1596,11 @@ public class Layouts.ItemRow : Layouts.ItemBase { picked_item.section_id = ""; picked_item.parent_id = target_item.id; - if (picked_item.project.source_type == BackendType.LOCAL) { + if (picked_item.project.source_type == SourceType.LOCAL) { target_item.collapsed = true; Services.Store.instance ().update_item (picked_item); Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); - } else if (picked_item.project.source_type == BackendType.TODOIST) { + } else if (picked_item.project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().move_item.begin (picked_item, "parent_id", picked_item.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_item.end (res).status) { target_item.collapsed = true; @@ -1608,7 +1608,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { Services.EventBus.get_default ().item_moved (picked_item, old_project_id, old_section_id, old_parent_id); } }); - } else if (picked_item.project.source_type == BackendType.CALDAV) { + } else if (picked_item.project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { target_item.collapsed = true; @@ -1698,9 +1698,9 @@ public class Layouts.ItemRow : Layouts.ItemBase { picked_widget.item.parent_id = target_widget.item.parent_id; } - if (picked_widget.item.project.source_type == BackendType.LOCAL) { + if (picked_widget.item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (picked_widget.item); - } else if (picked_widget.item.project.source_type == BackendType.TODOIST) { + } else if (picked_widget.item.project.source_type == SourceType.TODOIST) { string move_id = picked_widget.item.project_id; string move_type = "project_id"; @@ -1719,7 +1719,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { Services.Store.instance ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.source_type == BackendType.CALDAV) { + } else if (picked_widget.item.project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().add_task.begin (picked_widget.item, true, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_task.end (res).status) { Services.Store.instance ().update_item (picked_widget.item); diff --git a/src/Layouts/ItemSidebarView.vala b/src/Layouts/ItemSidebarView.vala index 5285972fa..1a8f67111 100644 --- a/src/Layouts/ItemSidebarView.vala +++ b/src/Layouts/ItemSidebarView.vala @@ -232,8 +232,8 @@ public class Layouts.ItemSidebarView : Adw.Bin { if (item.priority != priority) { item.priority = priority; - if (item.project.source_type == BackendType.TODOIST || - item.project.source_type == BackendType.CALDAV) { + if (item.project.source_type == SourceType.TODOIST || + item.project.source_type == SourceType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -256,7 +256,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { reminder_button.reminder_added.connect ((reminder) => { reminder.item_id = item.id; - if (item.project.source_type == BackendType.TODOIST) { + 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); @@ -441,7 +441,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { public void update_pinned (bool pinned) { item.pinned = pinned; - if (item.project.source_type == BackendType.CALDAV) { + if (item.project.source_type == SourceType.CALDAV) { item.update_async (""); } else { item.update_local (); @@ -724,9 +724,9 @@ public class Layouts.ItemSidebarView : Adw.Bin { } private void _complete_item (bool old_checked) { - if (item.project.source_type == BackendType.LOCAL) { + if (item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().checked_toggled (item, old_checked); - } else if (item.project.source_type == BackendType.TODOIST) { + } else if (item.project.source_type == SourceType.TODOIST) { item.loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { if (Services.Todoist.get_default ().complete_item.end (res).status) { @@ -735,7 +735,7 @@ public class Layouts.ItemSidebarView : Adw.Bin { item.loading = false; }); - } else if (item.project.source_type == BackendType.CALDAV) { + } else if (item.project.source_type == SourceType.CALDAV) { item.loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { if (Services.CalDAV.Core.get_default ().complete_item.end (res).status) { diff --git a/src/Layouts/LabelRow.vala b/src/Layouts/LabelRow.vala index 28147fbff..2ad12b9b7 100644 --- a/src/Layouts/LabelRow.vala +++ b/src/Layouts/LabelRow.vala @@ -181,12 +181,12 @@ public class Layouts.LabelRow : Gtk.ListBoxRow { dialog.response.connect ((response) => { if (response == "delete") { - if (label.backend_type == BackendType.TODOIST) { + if (label.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().delete.begin (label, (obj, res) => { Services.Todoist.get_default ().delete.end (res); Services.Store.instance ().delete_label (label); }); - } else if (label.backend_type == BackendType.LOCAL) { + } else if (label.source_type == SourceType.LOCAL) { Services.Store.instance ().delete_label (label); } } diff --git a/src/Layouts/ProjectRow.vala b/src/Layouts/ProjectRow.vala index cf57eca37..a179db68b 100644 --- a/src/Layouts/ProjectRow.vala +++ b/src/Layouts/ProjectRow.vala @@ -85,7 +85,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { } construct { - css_classes = { "selectable-item", "transition" }; + css_classes = { "no-selectable", "transition", "no-padding" }; motion_top_grid = new Gtk.Grid () { height_request = 27, @@ -188,7 +188,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { projectrow_box.append (loading_revealer); handle_grid = new Adw.Bin () { - css_classes = { "transition", "drop-target" }, + css_classes = { "transition", "selectable-item", "drop-target" }, child = projectrow_box }; @@ -282,9 +282,9 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { Services.EventBus.get_default ().pane_selected.connect ((pane_type, id) => { if (pane_type == PaneType.PROJECT && project.id_string == id) { - add_css_class ("selected"); + handle_grid.add_css_class ("selected"); } else { - remove_css_class ("selected"); + handle_grid.remove_css_class ("selected"); } }); @@ -332,6 +332,12 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { project.loading_change.connect (() => { is_loading = project.loading; }); + + Services.EventBus.get_default ().drag_end.connect ((source_id) => { + if (project.source_id == source_id) { + motion_top_revealer.reveal_child = false; + } + }); } private void update_count_label (int count) { @@ -363,7 +369,10 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { motion_top_grid.add_controller (drop_order_target); drop_order_target.drop.connect ((value, x, y) => { var picked_widget = (Layouts.ProjectRow) value; - var target_widget = this; + var target_widget = this; + + // fix #1131 + Services.EventBus.get_default ().drag_end (target_widget.project.source_id); var picked_project = picked_widget.project; var target_project = target_widget.project; @@ -388,7 +397,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (picked_project.parent_id != target_project.parent_id) { picked_project.parent_id = target_project.parent_id; - if (picked_project.source_type == BackendType.TODOIST) { + if (picked_project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (picked_project, target_project.parent_id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { Services.Store.instance ().update_project (picked_project); @@ -412,7 +421,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { private void build_drop_motion () { var drop_motion_ctrl = new Gtk.DropControllerMotion (); add_controller (drop_motion_ctrl); - drop_motion_ctrl.motion.connect ((x, y) => { + drop_motion_ctrl.enter.connect ((x, y) => { var drop = drop_motion_ctrl.get_drop (); GLib.Value value = Value (typeof (Gtk.Widget)); @@ -486,6 +495,9 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { var picked_widget = (Layouts.ProjectRow) value; var target_widget = this; + // fix #1131 + Services.EventBus.get_default ().drag_end (target_widget.project.source_id); + var picked_project = picked_widget.project; var target_project = target_widget.project; @@ -496,7 +508,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { string old_parent_id = picked_project.parent_id; picked_project.parent_id = target_project.id; - if (picked_project.source_type == BackendType.TODOIST) { + if (picked_project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (picked_project, target_project.id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { Services.Store.instance ().update_project (picked_project); @@ -650,7 +662,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { menu_box.append (edit_item); } - if (project.source_type == BackendType.CALDAV) { + if (project.source_type == SourceType.CALDAV) { menu_box.append (refresh_item); } diff --git a/src/Layouts/SectionBoard.vala b/src/Layouts/SectionBoard.vala index caa932447..c19ab2494 100644 --- a/src/Layouts/SectionBoard.vala +++ b/src/Layouts/SectionBoard.vala @@ -571,7 +571,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { if (response == "delete") { is_loading = true; - if (section.project.source_type == BackendType.TODOIST) { + if (section.project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().delete.begin (section, (obj, res) => { Services.Todoist.get_default ().delete.end (res); Services.Store.instance ().delete_section (section); @@ -602,7 +602,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { string old_section_id = section.project_id; section.project_id = project_id; - if (section.project.source_type == BackendType.TODOIST) { + if (section.project.source_type == SourceType.TODOIST) { is_loading = true; Services.Todoist.get_default ().move_project_section.begin (section, project_id, (obj, res) => { @@ -611,7 +611,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { is_loading = false; } }); - } else if (section.project.source_type == BackendType.LOCAL) { + } else if (section.project.source_type == SourceType.LOCAL) { Services.Store.instance ().move_section (section, project_id); is_loading = false; } @@ -637,7 +637,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { picked_widget.item.section_id = section.id; picked_widget.item.parent_id = ""; - if (picked_widget.item.project.source_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == SourceType.TODOIST) { string type = "section_id"; string id = section.id; @@ -651,7 +651,7 @@ public class Layouts.SectionBoard : Gtk.FlowBoxChild { Services.Store.instance ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (picked_widget.item); } diff --git a/src/Layouts/SectionRow.vala b/src/Layouts/SectionRow.vala index 03fb0284e..f853ba432 100644 --- a/src/Layouts/SectionRow.vala +++ b/src/Layouts/SectionRow.vala @@ -762,7 +762,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { picked_widget.item.section_id = section.id; picked_widget.item.parent_id = ""; - if (picked_widget.item.project.source_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == SourceType.TODOIST) { string type = "section_id"; string id = section.id; @@ -776,7 +776,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { Services.Store.instance ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (picked_widget.item); } @@ -804,7 +804,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { picked_widget.item.section_id = section.id; picked_widget.item.parent_id = ""; - if (picked_widget.item.project.source_type == BackendType.TODOIST) { + if (picked_widget.item.project.source_type == SourceType.TODOIST) { string type = "section_id"; string id = section.id; @@ -818,7 +818,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { Services.Store.instance ().update_item (picked_widget.item); } }); - } else if (picked_widget.item.project.source_type == BackendType.LOCAL) { + } else if (picked_widget.item.project.source_type == SourceType.LOCAL) { Services.Store.instance ().update_item (picked_widget.item); } @@ -876,7 +876,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { is_loading = true; - if (section.project.source_type == BackendType.TODOIST) { + if (section.project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().move_project_section.begin (section, project_id, (obj, res) => { if (Services.Todoist.get_default ().move_project_section.end (res).status) { Services.Store.instance ().move_section (section, old_section_id); @@ -884,7 +884,7 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { is_loading = false; }); - } else if (section.project.source_type == BackendType.LOCAL) { + } else if (section.project.source_type == SourceType.LOCAL) { Services.Store.instance ().move_section (section, project_id); is_loading = false; } diff --git a/src/Layouts/SidebarSourceRow.vala b/src/Layouts/SidebarSourceRow.vala index 5c187aad5..7bf09e0ab 100644 --- a/src/Layouts/SidebarSourceRow.vala +++ b/src/Layouts/SidebarSourceRow.vala @@ -41,16 +41,20 @@ public class Layouts.SidebarSourceRow : Gtk.ListBoxRow { subheader_title = source.subheader_text }; group.placeholder_message = _("No project available. Create one by clicking on the '+' button"); - group.margin_top = 6; + group.margin_top = 12; - if (source.source_type == BackendType.TODOIST || source.source_type == BackendType.CALDAV) { + if (source.source_type == SourceType.TODOIST || source.source_type == SourceType.CALDAV) { var sync_button = new Widgets.SyncButton () { reveal_child = true }; group.add_widget_end (sync_button); sync_button.clicked.connect (() => { - Services.Todoist.get_default ().sync.begin (source); + if (source.source_type == SourceType.TODOIST) { + Services.Todoist.get_default ().sync.begin (source); + } else if (source.source_type == SourceType.CALDAV) { + Services.CalDAV.Core.get_default ().sync.begin (source); + } }); source.sync_started.connect (() => { diff --git a/src/Services/ActionManager.vala b/src/Services/ActionManager.vala index 90a9e3f79..9ec82ab44 100644 --- a/src/Services/ActionManager.vala +++ b/src/Services/ActionManager.vala @@ -152,7 +152,7 @@ public class Services.ActionManager : Object { } private void action_new_project () { - var dialog = new Dialogs.Project.new (BackendType.LOCAL.to_string (), true); + var dialog = new Dialogs.Project.new (SourceType.LOCAL.to_string (), true); dialog.present (Planify._instance.main_window); } diff --git a/src/Services/Migrate.vala b/src/Services/Migrate.vala index ccd14fed6..86373cde3 100644 --- a/src/Services/Migrate.vala +++ b/src/Services/Migrate.vala @@ -56,7 +56,7 @@ public class Services.Migrate : GLib.Object { label.id = stmt.column_text (0); label.name = "(Planner) %s".printf (stmt.column_text (1)); label.color = stmt.column_text (2); - label.backend_type = BackendType.LOCAL; + label.source_id = SourceType.LOCAL.to_string (); Services.Store.instance ().insert_label (label); } @@ -78,7 +78,7 @@ public class Services.Migrate : GLib.Object { project.id = stmt.column_text (0); project.name = "(Planner) %s".printf (stmt.column_text (1)); project.color = stmt.column_text (2); - project.source_id = BackendType.LOCAL.to_string (); + project.source_id = SourceType.LOCAL.to_string (); Services.Store.instance ().insert_project (project); } diff --git a/src/Views/Label/LabelSourceRow.vala b/src/Views/Label/LabelSourceRow.vala index 365fbbd80..def4d53c7 100644 --- a/src/Views/Label/LabelSourceRow.vala +++ b/src/Views/Label/LabelSourceRow.vala @@ -41,7 +41,7 @@ public class Views.LabelSourceRow : Gtk.ListBoxRow { subheader_title = source.subheader_text }; group.placeholder_message = _("No labels available. Create one by clicking on the '+' button"); - group.margin_top = 6; + group.margin_top = 12; group.show_separator = true; group.set_sort_func (sort_func); @@ -68,7 +68,7 @@ public class Views.LabelSourceRow : Gtk.ListBoxRow { }); add_button.clicked.connect (() => { - var dialog = new Dialogs.Label.new (BackendType.LOCAL); + var dialog = new Dialogs.Label.new (source); dialog.present (Planify._instance.main_window); }); diff --git a/src/Views/Project/Project.vala b/src/Views/Project/Project.vala index 49a8db445..d42235ca7 100644 --- a/src/Views/Project/Project.vala +++ b/src/Views/Project/Project.vala @@ -36,7 +36,7 @@ public class Views.Project : Adw.Bin { public ProjectViewStyle view_style { get { - return project.source_type == BackendType.CALDAV ? ProjectViewStyle.LIST : project.view_style; + return project.source_type == SourceType.CALDAV ? ProjectViewStyle.LIST : project.view_style; } } @@ -295,7 +295,7 @@ public class Views.Project : Adw.Bin { menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); } - if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.TODOIST) { + if (project.source_type == SourceType.LOCAL || project.source_type == SourceType.TODOIST) { menu_box.append (add_section_item); menu_box.append (manage_sections); menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); @@ -516,7 +516,7 @@ public class Views.Project : Adw.Bin { var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); menu_box.margin_top = menu_box.margin_bottom = 3; - if (project.source_type == BackendType.LOCAL || project.source_type == BackendType.TODOIST) { + if (project.source_type == SourceType.LOCAL || project.source_type == SourceType.TODOIST) { menu_box.append (view_box); menu_box.append (new Widgets.ContextMenu.MenuSeparator ()); } @@ -702,7 +702,7 @@ public class Views.Project : Adw.Bin { } public void prepare_new_section () { - if (project.source_type == BackendType.CALDAV) { + if (project.source_type == SourceType.CALDAV) { return; } diff --git a/src/Views/Scheduled/Scheduled.vala b/src/Views/Scheduled/Scheduled.vala index b6af413fa..85915ff9f 100644 --- a/src/Views/Scheduled/Scheduled.vala +++ b/src/Views/Scheduled/Scheduled.vala @@ -270,7 +270,7 @@ public class Views.Scheduled.Scheduled : Adw.Bin { } var dialog = new Dialogs.LabelPicker (); - // TODO: dialog.add_labels (BackendType.ALL); + // TODO: dialog.add_labels (SourceType.ALL); dialog.labels = _labels; dialog.present (Planify._instance.main_window); diff --git a/src/Views/Today.vala b/src/Views/Today.vala index 46b0fbbcd..980dd7db4 100644 --- a/src/Views/Today.vala +++ b/src/Views/Today.vala @@ -635,7 +635,7 @@ public class Views.Today : Adw.Bin { } var dialog = new Dialogs.LabelPicker (); - // TODO: dialog.add_labels (BackendType.ALL); + // TODO: dialog.add_labels (SourceType.ALL); dialog.labels = _labels; dialog.present (Planify._instance.main_window); diff --git a/src/Widgets/MultiSelectToolbar.vala b/src/Widgets/MultiSelectToolbar.vala index 23c7b627b..dbc37b273 100644 --- a/src/Widgets/MultiSelectToolbar.vala +++ b/src/Widgets/MultiSelectToolbar.vala @@ -148,13 +148,13 @@ public class Widgets.MultiSelectToolbar : Adw.Bin { } private void update_items (Gee.ArrayList objects) { - if (project.source_type == BackendType.LOCAL) { + if (project.source_type == SourceType.LOCAL) { foreach (Objects.Item item in objects) { item.update_async (""); } unselect_all (); - } else if (project.source_type == BackendType.TODOIST) { + } else if (project.source_type == SourceType.TODOIST) { done_button.is_loading = true; Services.Todoist.get_default ().update_items.begin (objects, (obj, res) => { Services.Todoist.get_default ().update_items.end (res); diff --git a/src/Widgets/SourceRow.vala b/src/Widgets/SourceRow.vala index 2284b4adc..3930d4a4b 100644 --- a/src/Widgets/SourceRow.vala +++ b/src/Widgets/SourceRow.vala @@ -46,7 +46,7 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { var subheader_label = new Gtk.Label (source.subheader_text) { halign = Gtk.Align.START, css_classes = { "caption" }, - visible = source.source_type != BackendType.LOCAL + visible = source.source_type != SourceType.LOCAL }; var header_label_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { @@ -59,7 +59,7 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { valign = Gtk.Align.CENTER, halign = Gtk.Align.CENTER, css_classes = { "flat" }, - visible = source.source_type != BackendType.LOCAL + visible = source.source_type != SourceType.LOCAL }; var renove_item = new Widgets.ContextMenu.MenuItem (_("Remove"), "user-trash-symbolic"); @@ -81,7 +81,7 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { css_classes = { "flat", "dim-label" }, tooltip_markup = _("Add Source"), popover = popover, - visible = source.source_type != BackendType.LOCAL + visible = source.source_type != SourceType.LOCAL }; var end_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6) { From 5648e4c8231b3f18de7238623241f832a66fe059 Mon Sep 17 00:00:00 2001 From: Alain Date: Sun, 21 Jul 2024 07:38:34 -0500 Subject: [PATCH 07/14] fix #1131 --- core/Layouts/HeaderItem.vala | 2 +- core/Services/EventBus.vala | 3 +- data/resources/stylesheet/stylesheet.css | 2 +- src/Dialogs/Project.vala | 184 +++++++++++++++++------ src/Dialogs/WhatsNew.vala | 2 +- src/Layouts/ItemBoard.vala | 33 ++-- src/Layouts/ItemRow.vala | 12 +- src/Layouts/ProjectRow.vala | 8 +- src/Views/Label/Labels.vala | 12 +- src/Widgets/ReorderChild.vala | 6 +- src/Widgets/SourceRow.vala | 4 +- 11 files changed, 189 insertions(+), 79 deletions(-) diff --git a/core/Layouts/HeaderItem.vala b/core/Layouts/HeaderItem.vala index 8c866eadd..1c164ba6f 100644 --- a/core/Layouts/HeaderItem.vala +++ b/core/Layouts/HeaderItem.vala @@ -167,7 +167,7 @@ public class Layouts.HeaderItem : Adw.Bin { subheader_label = new Gtk.Label (null) { halign = Gtk.Align.START, - css_classes = { "caption" } + css_classes = { "caption", "dim-label" } }; subheader_revealer = new Gtk.Revealer () { diff --git a/core/Services/EventBus.vala b/core/Services/EventBus.vala index a50adc1d1..3de395582 100644 --- a/core/Services/EventBus.vala +++ b/core/Services/EventBus.vala @@ -62,7 +62,8 @@ public class Services.EventBus : Object { public signal void request_escape (); public signal void drag_n_drop_active (string project_id, bool active); public signal void expand_all (string project_id, bool active); - public signal void drag_end (string source_id); + public signal void drag_projects_end (string source_id); + public signal void drag_items_end (string project_id); public bool _mobile_mode = Services.Settings.get_default ().settings.get_boolean ("mobile-mode"); public bool mobile_mode { diff --git a/data/resources/stylesheet/stylesheet.css b/data/resources/stylesheet/stylesheet.css index 9de723f71..504b1fb67 100644 --- a/data/resources/stylesheet/stylesheet.css +++ b/data/resources/stylesheet/stylesheet.css @@ -547,7 +547,7 @@ checkbutton.theme-selector radio:checked { } .header-item-button, -.header-item-button button { +.header-item-button .image-button { padding: 3px; min-height: 16px; min-width: 16px; diff --git a/src/Dialogs/Project.vala b/src/Dialogs/Project.vala index 588bebb74..b462dcafe 100644 --- a/src/Dialogs/Project.vala +++ b/src/Dialogs/Project.vala @@ -22,13 +22,20 @@ public class Dialogs.Project : Adw.Dialog { public Objects.Project project { get; construct; } public bool backend_picker { get; construct; } - + public string header_title { get; construct; } + + private Gtk.Stack emoji_color_stack; + private Widgets.CircularProgressBar progress_bar; private Adw.EntryRow name_entry; private Widgets.ColorPickerRow color_picker_row; private Widgets.LoadingButton submit_button; private Gtk.Switch emoji_switch; private Gtk.Label emoji_label; + private Gtk.Label source_selected_label; + private Adw.NavigationView navigation_view; + private Adw.NavigationPage sources_page; + public bool is_creating { get { return project.id == ""; @@ -46,7 +53,7 @@ public class Dialogs.Project : Adw.Dialog { Object ( project: project, backend_picker: backend_picker, - title: project.parent_id == "" ? _("New Project") : project.parent.name + " → " + _("New Project") + header_title: project.parent_id == "" ? _("New Project") : project.parent.name + " → " + _("New Project") ); } @@ -54,20 +61,48 @@ public class Dialogs.Project : Adw.Dialog { Object ( project: project, backend_picker: false, - title: _("Edit Project") + header_title: _("Edit Project") ); } construct { + Adw.NavigationPage main_page = get_main_page (); + sources_page = get_sources_page (); + + navigation_view = new Adw.NavigationView (); + navigation_view.add (main_page); + + child = navigation_view; + Services.EventBus.get_default ().disconnect_typing_accel (); + + Timeout.add (emoji_color_stack.transition_duration, () => { + if (project.icon_style == ProjectIconStyle.PROGRESS) { + emoji_color_stack.visible_child_name = "color"; + } else { + emoji_color_stack.visible_child_name = "emoji"; + } + + progress_bar.color = project.color; + color_picker_row.color = project.color; + + if (is_creating) { + name_entry.grab_focus (); + } + + return GLib.Source.REMOVE; + }); + } + + private Adw.NavigationPage get_main_page () { var headerbar = new Adw.HeaderBar (); headerbar.add_css_class ("flat"); emoji_label = new Gtk.Label (project.emoji); - var progress_bar = new Widgets.CircularProgressBar (32); + progress_bar = new Widgets.CircularProgressBar (32); progress_bar.percentage = 0.64; - var emoji_color_stack = new Gtk.Stack () { + emoji_color_stack = new Gtk.Stack () { halign = Gtk.Align.CENTER, valign = Gtk.Align.CENTER, transition_type = Gtk.StackTransitionType.CROSSFADE @@ -122,31 +157,40 @@ public class Dialogs.Project : Adw.Dialog { name_group.add (name_entry); name_group.add (emoji_switch_row); - var backend_model = new Gtk.StringList (null); - foreach (Objects.Source source in Services.Store.instance ().sources) { - backend_model.append (source.header_text); - } + source_selected_label = new Gtk.Label (project.source.header_text) { + css_classes = { "dim-label" }, + tooltip_text = project.source.subheader_text + }; + var pan_icon = new Gtk.Image.from_icon_name ("go-next-symbolic") { + pixel_size = 16 + }; - var backend_row = new Adw.ComboRow (); - backend_row.title = _("Source"); - backend_row.model = backend_model; + var source_selected_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); + source_selected_box.append (source_selected_label); + source_selected_box.append (pan_icon); - var backend_group = new Adw.PreferencesGroup () { + var source_row = new Adw.ActionRow () { + activatable = true, + title = _("Source") + }; + + source_row.add_suffix (source_selected_box); + + var source_group = new Adw.PreferencesGroup () { margin_end = 12, margin_start = 12, margin_top = 24, margin_bottom = 1 }; - backend_group.add (backend_row); + source_group.add (source_row); - var backend_revealer = new Gtk.Revealer () { + var source_revealer = new Gtk.Revealer () { transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, - reveal_child = backend_picker + reveal_child = backend_picker, + child = source_group }; - backend_revealer.child = backend_group; - color_picker_row = new Widgets.ColorPickerRow (); var color_group = new Adw.Bin () { @@ -181,7 +225,7 @@ public class Dialogs.Project : Adw.Dialog { var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); content_box.append (emoji_picker_button); content_box.append (name_group); - content_box.append (backend_revealer); + content_box.append (source_revealer); content_box.append (color_box_revealer); content_box.append (submit_button); @@ -199,31 +243,7 @@ public class Dialogs.Project : Adw.Dialog { toolbar_view.add_top_bar (headerbar); toolbar_view.content = content_clamp; - child = toolbar_view; - Services.EventBus.get_default ().disconnect_typing_accel (); - - Timeout.add (emoji_color_stack.transition_duration, () => { - if (project.icon_style == ProjectIconStyle.PROGRESS) { - emoji_color_stack.visible_child_name = "color"; - } else { - emoji_color_stack.visible_child_name = "emoji"; - } - - progress_bar.color = project.color; - color_picker_row.color = project.color; - - if (project.source_type == SourceType.LOCAL || project.source_type == SourceType.NONE) { - backend_row.selected = 0; - } else if (project.source_type == SourceType.TODOIST) { - backend_row.selected = 1; - } - - if (is_creating) { - name_entry.grab_focus (); - } - - return GLib.Source.REMOVE; - }); + var navigation_page = new Adw.NavigationPage (toolbar_view, header_title); name_entry.entry_activated.connect (add_update_project); submit_button.clicked.connect (add_update_project); @@ -258,17 +278,81 @@ public class Dialogs.Project : Adw.Dialog { } }); - backend_row.notify["selected"].connect (() => { - if (backend_row.selected == 0) { - project.backend_type = SourceType.LOCAL; - } else if (backend_row.selected == 1) { - project.backend_type = SourceType.TODOIST; - } + source_row.activated.connect (() => { + navigation_view.push (sources_page); }); closed.connect (() => { Services.EventBus.get_default ().connect_typing_accel (); }); + + return navigation_page; + } + + private Adw.NavigationPage get_sources_page () { + var headerbar = new Adw.HeaderBar (); + headerbar.add_css_class ("flat"); + + var sources_group = new Adw.PreferencesGroup () { + margin_end = 12, + margin_start = 12, + margin_top = 6, + }; + + var none_radio = new Gtk.CheckButton (); + + foreach (Objects.Source source in Services.Store.instance ().sources) { + var radio_button = new Gtk.CheckButton () { + group = none_radio, + active = project.source_id == source.id + }; + + var source_row = new Adw.ActionRow () { + activatable = true, + title = source.header_text, + subtitle = source.subheader_text + }; + + source_row.add_suffix (radio_button); + source_row.set_activatable_widget (radio_button); + + source_row.activated.connect (() => { + project.source_id = source.id; + + source_selected_label.label = source.header_text; + source_selected_label.tooltip_text = source.subheader_text; + + navigation_view.pop (); + }); + + radio_button.toggled.connect (() => { + project.source_id = source.id; + + source_selected_label.label = source.header_text; + source_selected_label.tooltip_text = source.subheader_text; + + navigation_view.pop (); + }); + + sources_group.add (source_row); + } + + var content_clamp = new Adw.Clamp () { + maximum_size = 600, + margin_start = 12, + margin_end = 12, + margin_bottom = 12, + margin_top = 6, + child = sources_group + }; + + var toolbar_view = new Adw.ToolbarView (); + toolbar_view.add_top_bar (headerbar); + toolbar_view.content = content_clamp; + + var navigation_page = new Adw.NavigationPage (toolbar_view, _("Sources")); + + return navigation_page; } private void add_update_project () { diff --git a/src/Dialogs/WhatsNew.vala b/src/Dialogs/WhatsNew.vala index b68ae84d6..5d1073106 100644 --- a/src/Dialogs/WhatsNew.vala +++ b/src/Dialogs/WhatsNew.vala @@ -123,7 +123,7 @@ public class Dialogs.WhatsNew : Adw.Dialog { } if (page != null) { - row.add_suffix (generate_icon ("pan-end-symbolic", 16)); + row.add_suffix (generate_icon ("go-next-symbolic", 16)); row.activatable = true; row.activated.connect (() => { navigation_view.push (page); diff --git a/src/Layouts/ItemBoard.vala b/src/Layouts/ItemBoard.vala index 89c85d067..531760b4a 100644 --- a/src/Layouts/ItemBoard.vala +++ b/src/Layouts/ItemBoard.vala @@ -411,6 +411,12 @@ public class Layouts.ItemBoard : Layouts.ItemBase { item.sensitive_change.connect (() => { sensitive = item.sensitive; }); + + Services.EventBus.get_default ().drag_items_end.connect ((project_id) => { + if (item.project_id == project_id) { + motion_top_revealer.reveal_child = false; + } + }); } private void update_next_recurrency () { @@ -764,19 +770,24 @@ public class Layouts.ItemBoard : Layouts.ItemBase { var drop_motion_ctrl = new Gtk.DropControllerMotion (); add_controller (drop_motion_ctrl); - drop_motion_ctrl.motion.connect ((x, y) => { + drop_motion_ctrl.enter.connect ((x, y) => { var drop = drop_motion_ctrl.get_drop (); GLib.Value value = Value (typeof (Gtk.Widget)); - drop.drag.content.get_value (ref value); - if (value.dup_object () is Layouts.ItemBoard) { - var picked_widget = (Layouts.ItemBoard) value; - motion_top_grid.height_request = picked_widget.handle_grid.get_height (); - } else { - motion_top_grid.height_request = 32; + try { + drop.drag.content.get_value (ref value); + + if (value.dup_object () is Layouts.ItemBoard) { + var picked_widget = (Layouts.ItemBoard) value; + motion_top_grid.height_request = picked_widget.handle_grid.get_height (); + } else { + motion_top_grid.height_request = 32; + } + + motion_top_revealer.reveal_child = drop_motion_ctrl.contains_pointer; + } catch (Error e) { + debug (e.message); } - - motion_top_revealer.reveal_child = drop_motion_ctrl.contains_pointer; }); drop_motion_ctrl.leave.connect (() => { @@ -820,6 +831,8 @@ public class Layouts.ItemBoard : Layouts.ItemBase { var picked_item = picked_widget.item; var target_item = target_widget.item; + Services.EventBus.get_default ().drag_items_end (item.project_id); + if (picked_widget == target_widget || target_widget == null) { return false; } @@ -896,6 +909,8 @@ public class Layouts.ItemBoard : Layouts.ItemBase { picked_widget.drag_end (); target_widget.drag_end (); + Services.EventBus.get_default ().drag_items_end (item.project_id); + if (picked_widget == target_widget || target_widget == null) { return false; } diff --git a/src/Layouts/ItemRow.vala b/src/Layouts/ItemRow.vala index 7d7342d04..81583360a 100644 --- a/src/Layouts/ItemRow.vala +++ b/src/Layouts/ItemRow.vala @@ -539,7 +539,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { box.append (itemrow_box); box.append (subitems); - hide_subtask_button = new Gtk.Button.from_icon_name ("pan-end-symbolic") { + hide_subtask_button = new Gtk.Button.from_icon_name ("go-next-symbolic") { valign = Gtk.Align.START, margin_top = 3, css_classes = { "flat", "dim-label", "no-padding", "hidden-button" } @@ -766,6 +766,12 @@ public class Layouts.ItemRow : Layouts.ItemBase { reminder_button.delete_reminder (reminder, item.reminders); check_reminders (); }); + + Services.EventBus.get_default ().drag_items_end.connect ((project_id) => { + if (item.project_id == project_id) { + motion_top_revealer.reveal_child = false; + } + }); } public void check_hide_subtask_button () { @@ -1585,6 +1591,8 @@ public class Layouts.ItemRow : Layouts.ItemBase { var picked_item = picked_widget.item; var target_item = target_widget.item; + Services.EventBus.get_default ().drag_items_end (item.project_id); + if (picked_widget == target_widget || target_widget == null) { return false; } @@ -1667,6 +1675,8 @@ public class Layouts.ItemRow : Layouts.ItemBase { picked_widget.drag_end (); target_widget.drag_end (); + Services.EventBus.get_default ().drag_items_end (item.project_id); + if (picked_widget == target_widget || target_widget == null) { return false; } diff --git a/src/Layouts/ProjectRow.vala b/src/Layouts/ProjectRow.vala index a179db68b..692fd120d 100644 --- a/src/Layouts/ProjectRow.vala +++ b/src/Layouts/ProjectRow.vala @@ -126,7 +126,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { child = count_label }; - arrow_button = new Gtk.Button.from_icon_name ("pan-end-symbolic") { + arrow_button = new Gtk.Button.from_icon_name ("go-next-symbolic") { valign = Gtk.Align.CENTER, halign = Gtk.Align.CENTER, css_classes = { "flat", "transparent", "hidden-button", "no-padding" }, @@ -333,7 +333,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { is_loading = project.loading; }); - Services.EventBus.get_default ().drag_end.connect ((source_id) => { + Services.EventBus.get_default ().drag_projects_end.connect ((source_id) => { if (project.source_id == source_id) { motion_top_revealer.reveal_child = false; } @@ -372,7 +372,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { var target_widget = this; // fix #1131 - Services.EventBus.get_default ().drag_end (target_widget.project.source_id); + Services.EventBus.get_default ().drag_projects_end (target_widget.project.source_id); var picked_project = picked_widget.project; var target_project = target_widget.project; @@ -496,7 +496,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { var target_widget = this; // fix #1131 - Services.EventBus.get_default ().drag_end (target_widget.project.source_id); + Services.EventBus.get_default ().drag_projects_end (target_widget.project.source_id); var picked_project = picked_widget.project; var target_project = target_widget.project; diff --git a/src/Views/Label/Labels.vala b/src/Views/Label/Labels.vala index 8624387f0..37655e278 100644 --- a/src/Views/Label/Labels.vala +++ b/src/Views/Label/Labels.vala @@ -37,7 +37,9 @@ public class Views.Labels : Adw.Bin { var content = new Gtk.Box (Gtk.Orientation.VERTICAL, 12) { hexpand = true, - vexpand = true + vexpand = true, + margin_start = 12, + margin_end = 12 }; content.append (sources_listbox); @@ -48,18 +50,16 @@ public class Views.Labels : Adw.Bin { margin_start = 12, margin_end = 12, margin_bottom = 64, + child = content }; - content_clamp.child = content; - var scrolled_window = new Gtk.ScrolledWindow () { hscrollbar_policy = Gtk.PolicyType.NEVER, hexpand = true, - vexpand = true + vexpand = true, + child = content_clamp }; - scrolled_window.child = content_clamp; - var toolbar_view = new Adw.ToolbarView (); toolbar_view.add_top_bar (headerbar); toolbar_view.content = scrolled_window; diff --git a/src/Widgets/ReorderChild.vala b/src/Widgets/ReorderChild.vala index 7cbd3a4a5..6e6df7ec4 100644 --- a/src/Widgets/ReorderChild.vala +++ b/src/Widgets/ReorderChild.vala @@ -25,6 +25,7 @@ public class Widgets.ReorderChild : Adw.Bin { private Gtk.DropControllerMotion drop_motion_ctrl; private Gtk.Grid motion_top_grid; + private Gtk.Revealer motion_top_revealer; private Gtk.Grid motion_bottom_grid; private Gtk.Revealer main_revealer; @@ -59,7 +60,7 @@ public class Widgets.ReorderChild : Adw.Bin { css_classes = { "drop-area", "drop-target" } }; - var motion_top_revealer = new Gtk.Revealer () { + motion_top_revealer = new Gtk.Revealer () { transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, child = motion_top_grid }; @@ -94,7 +95,7 @@ public class Widgets.ReorderChild : Adw.Bin { drop_motion_ctrl = new Gtk.DropControllerMotion (); row.add_controller (drop_motion_ctrl); - drop_motion_ctrl.motion .connect ((x, y) => { + drop_motion_ctrl.enter .connect ((x, y) => { motion_top_revealer.reveal_child = true; }); @@ -142,6 +143,7 @@ public class Widgets.ReorderChild : Adw.Bin { picked_widget.drag_end (); target_widget.drag_end (); + target_widget.motion_top_revealer.reveal_child = false; if (picked_widget == target_widget || target_widget == null) { return false; diff --git a/src/Widgets/SourceRow.vala b/src/Widgets/SourceRow.vala index 3930d4a4b..cb34ed290 100644 --- a/src/Widgets/SourceRow.vala +++ b/src/Widgets/SourceRow.vala @@ -35,8 +35,6 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { construct { add_css_class ("no-selectable"); - print ("%s\n".printf (source.to_string ())); - var visible_checkbutton = new Gtk.CheckButton () { active = source.is_visible }; @@ -45,7 +43,7 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { var subheader_label = new Gtk.Label (source.subheader_text) { halign = Gtk.Align.START, - css_classes = { "caption" }, + css_classes = { "caption", "dim-label" }, visible = source.source_type != SourceType.LOCAL }; From 913dac240a91227c13909d23479e2400943e940f Mon Sep 17 00:00:00 2001 From: Iman Hosseinzadeh Date: Tue, 23 Jul 2024 22:39:14 +0330 Subject: [PATCH 08/14] add necessary dependencies The user needs Vala and Meson to compile the project. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bb1329e03..c6e58a9b1 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ You'll need the following dependencies: +* vala +* meson * gtk4 * libadwaita From 2eda623284778763f8cfa4af230a8403571ea606 Mon Sep 17 00:00:00 2001 From: Iman Hosseinzadeh Date: Tue, 23 Jul 2024 22:43:50 +0330 Subject: [PATCH 09/14] enhance readability --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c6e58a9b1..aec26b3a2 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,9 @@ ### ☁️ Support for Todoist: -- Synchronize your Projects, Task and Sections thanks to Todoist. -- Support for Todoist offline: Work without an internet connection and when everything is reconnected it will be synchronized. -- Planify not created by, affiliated with, or supported by Doist +- Synchronize your Projects, Tasks, and Sections thanks to Todoist. +- Support for Todoist offline: Work without an internet connection; when everything is reconnected, it will be synchronized. +- Planify is not created by, affiliated with, or supported by Doist ### 💎️ Other features: @@ -71,17 +71,15 @@ Planify follows the [GNOME Code of Conduct](https://conduct.gnome.org/). - **Be friendly.** Use welcoming and inclusive language. - **Be empathetic.** Be respectful of differing viewpoints and experiences. -- **Be respectful.** When we disagree, we do so in a polite and constructive - manner. -- **Be considerate.** Remember that decisions are often a difficult choice - between competing priorities. +- **Be respectful.** When we disagree, we do so politely and constructively. +- **Be considerate.** Remember that decisions are often difficult when competing priorities are involved. - **Be patient and generous.** If someone asks for help it is because they need it. - **Try to be concise.** Read the discussion before commenting. ## Support -If you like Planify and you want to support its development, consider supporting via [Patreon](https://www.patreon.com/alainm23), [PayPal](https://www.paypal.me/alainm23) or [Liberapay](https://liberapay.com/Alain) +If you like Planify and want to support its development, consider supporting via [Patreon](https://www.patreon.com/alainm23), [PayPal](https://www.paypal.me/alainm23) or [Liberapay](https://liberapay.com/Alain) ### Bitcoin ` From 20376a05d6c6ef3fa519f0c79898729d82e2cec3 Mon Sep 17 00:00:00 2001 From: Alain Date: Wed, 24 Jul 2024 16:29:11 -0500 Subject: [PATCH 10/14] feat: add new services --- core/Enum.vala | 5 + core/Objects/Attachment.vala | 6 - core/Objects/BaseObject.vala | 5 + core/Objects/Item.vala | 19 +- core/Objects/Project.vala | 57 +-- core/Objects/Section.vala | 29 +- core/Objects/Source.vala | 49 +- core/Services/CalDAV/Backend.vala | 32 -- core/Services/CalDAV/Constants.vala | 31 -- core/Services/CalDAV/Core.vala | 460 +++++------------- core/Services/CalDAV/Providers/Nextcloud.vala | 374 ++++++++++++++ .../CalDAV/Providers/ProviderBase.vala | 33 ++ core/Services/CalDAV/Providers/Radicale.vala | 183 +++++++ core/Services/Database.vala | 141 +++--- core/Services/EventBus.vala | 1 + core/Services/Store.vala | 52 +- core/Services/Todoist.vala | 10 +- core/Widgets/LabelPicker/LabelPicker.vala | 2 +- core/Widgets/LabelsPickerCore.vala | 53 +- core/meson.build | 6 +- data/resources/stylesheet/stylesheet.css | 6 +- src/Dialogs/LabelPicker.vala | 6 +- src/Dialogs/Preferences/Pages/Backup.vala | 2 +- .../Preferences/PreferencesWindow.vala | 31 +- src/Dialogs/Project.vala | 21 +- src/Dialogs/QuickFind/QuickFind.vala | 4 +- src/Layouts/FilterPaneRow.vala | 4 +- src/Layouts/ItemRow.vala | 2 - src/Layouts/SectionRow.vala | 5 +- src/Layouts/Sidebar.vala | 15 +- src/MainWindow.vala | 10 +- src/Services/ActionManager.vala | 10 +- .../{Migrate.vala => MigrateFromPlanner.vala} | 8 +- src/Services/NetworkMonitor.vala | 68 +++ src/Views/Today.vala | 61 ++- src/Widgets/SourceRow.vala | 29 +- src/Widgets/SyncButton.vala | 5 +- src/meson.build | 3 +- 38 files changed, 1148 insertions(+), 690 deletions(-) delete mode 100644 core/Services/CalDAV/Backend.vala delete mode 100644 core/Services/CalDAV/Constants.vala create mode 100644 core/Services/CalDAV/Providers/Nextcloud.vala create mode 100644 core/Services/CalDAV/Providers/ProviderBase.vala create mode 100644 core/Services/CalDAV/Providers/Radicale.vala rename src/Services/{Migrate.vala => MigrateFromPlanner.vala} (96%) create mode 100644 src/Services/NetworkMonitor.vala diff --git a/core/Enum.vala b/core/Enum.vala index 068f1b710..d7e9ff831 100644 --- a/core/Enum.vala +++ b/core/Enum.vala @@ -593,4 +593,9 @@ public enum ObjectEventKeyType { assert_not_reached (); } } +} + +public enum LabelPickerType { + SELECT, + FILTER } \ No newline at end of file diff --git a/core/Objects/Attachment.vala b/core/Objects/Attachment.vala index 4151c6d5e..ac0241d3b 100644 --- a/core/Objects/Attachment.vala +++ b/core/Objects/Attachment.vala @@ -40,12 +40,6 @@ public class Objects.Attachment : GLib.Object { _item = value; } } - - construct { - deleted.connect (() => { - Services.Store.instance ().attachment_deleted (this); - }); - } public string to_string () { return """ diff --git a/core/Objects/BaseObject.vala b/core/Objects/BaseObject.vala index 46bb95a2e..92799b270 100644 --- a/core/Objects/BaseObject.vala +++ b/core/Objects/BaseObject.vala @@ -24,6 +24,7 @@ public class Objects.BaseObject : GLib.Object { public string name { get; set; default = ""; } public string keywords { get; set; default = ""; } public string icon_name { get; set; default = ""; } + public signal void deleted (); public signal void updated (string update_id = ""); public signal void archived (); @@ -212,6 +213,10 @@ public class Objects.BaseObject : GLib.Object { return ((Objects.Label) this).source; } + if (this is Objects.Reminder) { + return ((Objects.Reminder) this).item.project.source; + } + return _source; } } diff --git a/core/Objects/Item.vala b/core/Objects/Item.vala index f03d7f15b..73a1513a8 100644 --- a/core/Objects/Item.vala +++ b/core/Objects/Item.vala @@ -289,15 +289,6 @@ public class Objects.Item : Objects.BaseObject { public signal void collapsed_change (); public signal void attachment_added (Objects.Attachment attachment); public signal void attachment_deleted (Objects.Attachment attachment); - - construct { - deleted.connect (() => { - Idle.add (() => { - Services.Store.instance ().item_deleted (this); - return false; - }); - }); - } public Item.from_json (Json.Node node) { id = node.get_object ().get_string_member ("id"); @@ -505,6 +496,10 @@ public class Objects.Item : Objects.BaseObject { string data = prop.get_elements_by_tag_name ("cal:calendar-data").get_element (0).text_content; string etag = prop.get_elements_by_tag_name ("d:getetag").get_element (0).text_content; + print ("---------------------\n"); + print ("%s\n".printf (data)); + print ("---------------------\n"); + ICal.Component ical = new ICal.Component.from_string (data); id = ical.get_uid (); @@ -572,8 +567,7 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { - // TODO: VERIFICAR CALDAV - Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, SourceType.CALDAV.to_string ()); + Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, source.id); if (label != null) { return_value.add (label); } @@ -638,7 +632,8 @@ public class Objects.Item : Objects.BaseObject { string[] categories_list = categories.split (","); foreach (unowned string category in categories_list) { - Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, SourceType.CALDAV.to_string ()); + // TODO + Objects.Label label = Services.Store.instance ().get_label_by_name (category, true, source.id); if (label != null) { return_value [label.id] = label; } else { diff --git a/core/Objects/Project.vala b/core/Objects/Project.vala index 8d85966ec..d8ba99b72 100644 --- a/core/Objects/Project.vala +++ b/core/Objects/Project.vala @@ -157,16 +157,8 @@ public class Objects.Project : Objects.BaseObject { return -1; }); - - return _items; - } - } - Gee.ArrayList _all_items; - public Gee.ArrayList all_items { - get { - _all_items = Services.Store.instance ().get_items_by_project (this); - return _all_items; + return _items; } } @@ -178,6 +170,14 @@ public class Objects.Project : Objects.BaseObject { } } + Gee.ArrayList _all_items; + public Gee.ArrayList all_items { + get { + _all_items = Services.Store.instance ().get_items_by_project (this); + return _all_items; + } + } + Gee.ArrayList _subprojects; public Gee.ArrayList subprojects { get { @@ -197,6 +197,7 @@ public class Objects.Project : Objects.BaseObject { public signal void section_added (Objects.Section section); public signal void subproject_added (Objects.Project project); public signal void item_added (Objects.Item item); + public signal void item_deleted (Objects.Item item); public signal void show_completed_changed (); public signal void sort_order_changed (); public signal void section_sort_order_changed (); @@ -251,13 +252,6 @@ public class Objects.Project : Objects.BaseObject { public signal void show_multi_select_change (); construct { - deleted.connect (() => { - Idle.add (() => { - Services.Store.instance ().project_deleted (this); - return false; - }); - }); - Services.EventBus.get_default ().checked_toggled.connect ((item) => { if (item.project_id == id) { _project_count = update_project_count (); @@ -266,20 +260,18 @@ public class Objects.Project : Objects.BaseObject { } }); - Services.Store.instance ().item_deleted.connect ((item) => { - if (item.project_id == id) { - _project_count = update_project_count (); - _percentage = update_percentage (); - project_count_updated (); - } + item_deleted.connect ((item) => { + _project_count = update_project_count (); + print ("Count: %d\n".printf (_project_count)); + + _percentage = update_percentage (); + project_count_updated (); }); - Services.Store.instance ().item_added.connect ((item) => { - if (item.project_id == id) { - _project_count = update_project_count (); - _percentage = update_percentage (); - project_count_updated (); - } + item_added.connect ((item) => { + _project_count = update_project_count (); + _percentage = update_percentage (); + project_count_updated (); }); Services.EventBus.get_default ().item_moved.connect ((item, old_project_id, section_id) => { @@ -553,6 +545,11 @@ public class Objects.Project : Objects.BaseObject { } } + public void add_item (Objects.Item item) { + _items.add (item); + item_added (item); + } + public Objects.Item? get_item (string id) { Objects.Item? return_value = null; lock (_items) { @@ -566,10 +563,6 @@ public class Objects.Project : Objects.BaseObject { return return_value; } - public void add_item (Objects.Item item) { - this._items.add (item); - } - public override string get_add_json (string temp_id, string uuid) { return get_update_json (uuid, temp_id); } diff --git a/core/Objects/Section.vala b/core/Objects/Section.vala index 86d30b157..10d51f8ea 100644 --- a/core/Objects/Section.vala +++ b/core/Objects/Section.vala @@ -67,8 +67,6 @@ public class Objects.Section : Objects.BaseObject { } } - public signal void item_added (Objects.Item item); - int? _section_count = null; public int section_count { get { @@ -86,15 +84,10 @@ public class Objects.Section : Objects.BaseObject { public signal void section_count_updated (); - construct { - deleted.connect (() => { - Idle.add (() => { - Services.Store.instance ().section_deleted (this); - return false; - }); - }); - + public signal void item_added (Objects.Item item); + public signal void item_deleted (Objects.Item item); + construct { Services.EventBus.get_default ().checked_toggled.connect ((item) => { if (item.section_id == id) { _section_count = update_section_count (); @@ -102,18 +95,14 @@ public class Objects.Section : Objects.BaseObject { } }); - Services.Store.instance ().item_deleted.connect ((item) => { - if (item.section_id == id) { - _section_count = update_section_count (); - section_count_updated (); - } + item_deleted.connect ((item) => { + _section_count = update_section_count (); + section_count_updated (); }); - Services.Store.instance ().item_added.connect ((item) => { - if (item.section_id == id) { - _section_count = update_section_count (); - section_count_updated (); - } + item_added.connect ((item) => { + _section_count = update_section_count (); + section_count_updated (); }); } diff --git a/core/Objects/Source.vala b/core/Objects/Source.vala index 80035fb31..8f6d773b5 100644 --- a/core/Objects/Source.vala +++ b/core/Objects/Source.vala @@ -118,31 +118,30 @@ public class Objects.Source : Objects.BaseObject { public signal void sync_started (); public signal void sync_finished (); - construct { - deleted.connect (() => { - Idle.add (() => { - Services.Store.instance ().source_deleted (this); - return false; - }); - }); - } - public void run_server () { - Services.Todoist.get_default ().sync.begin (this); + _run_server (); server_timeout = Timeout.add_seconds (15 * 60, () => { - if (sync_server) { - if (source_type == SourceType.TODOIST) { - Services.Todoist.get_default ().sync.begin (this); - } else if (source_type == SourceType.CALDAV) { - Services.CalDAV.Core.get_default ().sync.begin (this); - } - } + _run_server (); return true; }); } + private void _run_server () { + if (sync_server && source_type == SourceType.TODOIST) { + Services.Todoist.get_default ().sync.begin (this); + } else if (sync_server && source_type == SourceType.CALDAV) { + Services.CalDAV.Core.get_default ().sync.begin (this); + } + } + + public void remove_sync_server () { + // Remove server_timeout + GLib.Source.remove (server_timeout); + server_timeout = 0; + } + public void save () { updated_at = new GLib.DateTime.now_local ().to_string (); Services.Store.instance ().update_source (this); @@ -161,23 +160,33 @@ public class Objects.Source : Objects.BaseObject { dialog.present (window); dialog.response.connect ((response) => { - if (response == "delete") { - Services.Store.instance ().delete_source (this); + if (response == "delete") { + _delete_source (); } }); } + private void _delete_source () { + // Remove server_timeout + remove_sync_server (); + + // Remove DB + Services.Store.instance ().delete_source (this); + } + public string to_string () { return """ _________________________________ ID: %s DATA: %s TYPE: %s + SYNC_SERVER: %s --------------------------------- """.printf ( id, data.to_json (), - source_type.to_string () + source_type.to_string (), + sync_server.to_string () ); } } diff --git a/core/Services/CalDAV/Backend.vala b/core/Services/CalDAV/Backend.vala deleted file mode 100644 index b876837c0..000000000 --- a/core/Services/CalDAV/Backend.vala +++ /dev/null @@ -1,32 +0,0 @@ -/* -* Copyright © 2024 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.CalDAV.Backend { - public static string generate_server_url (CalDAVType caldav_type, string server_url, string username, string password) { - if (caldav_type == CalDAVType.NEXTCLOUD) { - return "%s/remote.php/dav".printf (server_url); - } else if (caldav_type == CalDAVType.RADICALE) { - return "https://%s:%s@%s".printf (username, password, server_url); - } - - return ""; - } -} diff --git a/core/Services/CalDAV/Constants.vala b/core/Services/CalDAV/Constants.vala deleted file mode 100644 index ccde0071a..000000000 --- a/core/Services/CalDAV/Constants.vala +++ /dev/null @@ -1,31 +0,0 @@ -/* -* Copyright © 2024 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.CalDAV.Constants { - // vala-lint=naming-convention - public const string LOGIN_REQUEST = """ - - - - - - """; -} diff --git a/core/Services/CalDAV/Core.vala b/core/Services/CalDAV/Core.vala index 12651ddc1..9ff1cf713 100644 --- a/core/Services/CalDAV/Core.vala +++ b/core/Services/CalDAV/Core.vala @@ -34,296 +34,28 @@ public class Services.CalDAV.Core : GLib.Object { public signal void first_sync_started (); public signal void first_sync_finished (); - - private Gee.HashMap request_map; - - // vala-lint=naming-convention - public static string USER_PRINCIPAL_REQUEST = """ - - - - - - """; - - // vala-lint=naming-convention - public static string USER_DATA_REQUEST = """ - - - - - - - """; - - // vala-lint=naming-convention - public static string TASKLIST_REQUEST = """ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - """; - - // vala-lint=naming-convention - public static string GET_SYNC_TOKEN_REQUEST = """ - - - - - - """; - - // vala-lint=naming-convention - public static string CREATE_TASKLIST_REQUEST = """ - - - - - - - 0 - %s - %s - 1 - - - - - - - """; - - // vala-lint=naming-convention - public static string UPDATE_TASKLIST_REQUEST = """ - - - - %s - %s - - - - """; - - // vala-lint=naming-convention - public static string SYNC_TOKEN_REQUEST = """ - - %s - 1 - - - - - - """; - // vala-lint=naming-convention - public static string TASKS_REQUEST = """ - - - - - - - - - - - - - - - - - - - - - - - """; + public Gee.HashMap providers_map = new Gee.HashMap (); public Core () { session = new Soup.Session (); parser = new Json.Parser (); - // var network_monitor = GLib.NetworkMonitor.get_default (); - // network_monitor.network_changed.connect (() => { - // if (GLib.NetworkMonitor.get_default ().network_available && - // is_logged_in () && - // Services.Settings.get_default ().settings.get_boolean ("caldav-sync-server")) { - // sync_async (); - // } - // }); - - request_map = new Gee.HashMap (); - request_map.set (CalDAVType.NEXTCLOUD.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); - request_map.set (CalDAVType.RADICALE.to_string () + "login", Services.CalDAV.Constants.LOGIN_REQUEST); + providers_map.set (CalDAVType.NEXTCLOUD.to_string (), new Services.CalDAV.Providers.Nextcloud ()); + providers_map.set (CalDAVType.RADICALE.to_string (), new Services.CalDAV.Providers.Radicale ()); } - public string get_request_data (CalDAVType caldav_type, string method) { - if (request_map.has_key (caldav_type.to_string () + method)) { - return request_map[caldav_type.to_string () + method]; - } - - return ""; - } - public async HttpResponse login (CalDAVType caldav_type, string server_url, string username, string password, GLib.Cancellable cancellable) { HttpResponse response = new HttpResponse (); - string _server_url = ""; - try { - var uri = GLib.Uri.parse (server_url, GLib.UriFlags.NONE); - - if (caldav_type == CalDAVType.NEXTCLOUD) { - _server_url = "%s://%s".printf (uri.get_scheme (), uri.get_host ()); - } else if (caldav_type == CalDAVType.RADICALE) { - _server_url = uri.get_host (); - } - } catch (Error e) { - response.error_code = e.code; - response.error = e.message; + if (!providers_map.has_key (caldav_type.to_string ())) { + response.error = _("No Provider Available"); return response; } - string url = Services.CalDAV.Backend.generate_server_url (caldav_type, _server_url, username, GLib.Uri.escape_string (password)); + Services.CalDAV.Providers.Base provider = providers_map.get (caldav_type.to_string ()); + + string url = provider.get_server_url (server_url, username, password); print ("Server URL: %s\n".printf (url)); string credentials = "%s:%s".printf (username, password); @@ -331,13 +63,13 @@ public class Services.CalDAV.Core : GLib.Object { var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (base64_credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes (get_request_data (caldav_type, "login").data)); + message.set_request_body_from_bytes ("application/xml", new Bytes (provider.LOGIN_REQUEST.data)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, cancellable); - // print_root ("login", (string) stream.get_data ()); - // print ("login status_code: %s\n".printf (message.status_code.to_string ())); + print_root ("login", (string) stream.get_data ()); + print ("login status_code: %s\n".printf (message.status_code.to_string ())); if (message.status_code == 207) { var source = new Objects.Source (); @@ -372,28 +104,28 @@ public class Services.CalDAV.Core : GLib.Object { } public async void add_caldav_account (Objects.Source source) { - var url = "%s/principals/users/%s/".printf (source.caldav_data.server_url, source.caldav_data.username); + if (!providers_map.has_key (source.caldav_data.caldav_type.to_string ())) { + return; + } + + Services.CalDAV.Providers.Base provider = providers_map.get (source.caldav_data.caldav_type.to_string ()); + + var url = provider.get_account_url (source.caldav_data.server_url, source.caldav_data.username); var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes (USER_DATA_REQUEST.data)); + message.set_request_body_from_bytes ("application/xml", new Bytes (provider.USER_DATA_REQUEST.data)); first_sync_started (); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - // print_root ("first_sync", (string) stream.get_data ()); + print_root ("first_sync", (string) stream.get_data ()); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomElement d_displayname = doc.get_elements_by_tag_name ("d:displayname").get_element (0); - GXml.DomElement d_email = doc.get_elements_by_tag_name ("s:email-address").get_element (0); + provider.set_user_data (doc, source); - source.caldav_data.user_displayname = d_displayname.text_content; - source.caldav_data.user_email = d_email.text_content; - - print ("Source: %s\n".printf (source.to_string ())); Services.Store.instance ().insert_source (source); - + yield get_all_tasklist (source); } catch (Error e) { debug (e.message); @@ -401,26 +133,36 @@ public class Services.CalDAV.Core : GLib.Object { } public async void get_all_tasklist (Objects.Source source) { - var url = "%s/calendars/%s/".printf (source.caldav_data.server_url, source.caldav_data.username); + if (!providers_map.has_key (source.caldav_data.caldav_type.to_string ())) { + return; + } + + Services.CalDAV.Providers.Base provider = providers_map.get (source.caldav_data.caldav_type.to_string ()); + + var url = provider.get_all_taskslist_url (source.caldav_data.server_url, source.caldav_data.username); + print ("Server URL: %s\n".printf (url)); + var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); + message.request_headers.append ("depth", "1"); + message.request_headers.append ("Host", "radicale.xlumurb.eu"); + message.request_headers.append ("User-Agent", "Planify"); + message.request_headers.append ("Content-Length", "629"); + message.request_headers.append ("Content-Type", "application/xml; charset=utf-8"); + message.set_request_body_from_bytes ("application/xml", new Bytes (provider.TASKLIST_REQUEST.data)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - // print_root ("get_all_tasklist", (string) stream.get_data ()); + print_root ("get_all_tasklist", (string) stream.get_data ()); + print ("login status_code: %s\n".printf (message.status_code.to_string ())); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - foreach (GXml.DomElement element in response) { - if (is_vtodo_calendar (element)) { - var project = new Objects.Project.from_caldav_xml (element); - project.source_id = source.id; - - Services.Store.instance ().insert_project (project); - yield get_all_tasks_by_tasklist (project); - } + Gee.ArrayList projects = provider.get_projects_by_doc (doc, source); + + foreach (Objects.Project project in projects) { + Services.Store.instance ().insert_project (project); + // yield get_all_tasks_by_tasklist (project); } first_sync_finished (); @@ -439,12 +181,12 @@ public class Services.CalDAV.Core : GLib.Object { var message = new Soup.Message ("REPORT", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); message.request_headers.append ("Depth", "1"); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); + message.set_request_body_from_bytes ("application/xml", new Bytes (Services.CalDAV.Providers.Nextcloud.TASKS_REQUEST.data)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - // print_root ("get_all_tasks_by_tasklist", (string) stream.get_data ()); + print_root ("get_all_tasks_by_tasklist", (string) stream.get_data ()); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); @@ -460,7 +202,7 @@ public class Services.CalDAV.Core : GLib.Object { label.id = Util.get_default ().generate_id (label); label.name = category; label.color = Util.get_default ().get_random_color (); - label.backend_type = SourceType.CALDAV; + label.source_id = project.source_id; Services.Store.instance ().insert_label (label); } @@ -496,7 +238,7 @@ public class Services.CalDAV.Core : GLib.Object { var message = new Soup.Message ("REPORT", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); message.request_headers.append ("Depth", "1"); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKS_REQUEST.data)); + message.set_request_body_from_bytes ("application/xml", new Bytes (Services.CalDAV.Providers.Nextcloud.TASKS_REQUEST.data)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); @@ -511,14 +253,13 @@ public class Services.CalDAV.Core : GLib.Object { } foreach (string category in labels_map.values) { - // TODO: VERIFICAR CALDAV - var label = Services.Store.instance ().get_label_by_name (category, true, SourceType.CALDAV.to_string ()); + var label = Services.Store.instance ().get_label_by_name (category, true, project.source_id); if (label == null) { label = new Objects.Label (); label.id = Util.get_default ().generate_id (label); label.name = category; label.color = Util.get_default ().get_random_color (); - label.backend_type = SourceType.CALDAV; + label.source_id = project.source_id; Services.Store.instance ().insert_label (label); } } @@ -534,6 +275,7 @@ public class Services.CalDAV.Core : GLib.Object { string old_project_id = item.project_id; string old_parent_id = item.parent_id; + bool old_checked = item.checked; item.update_from_caldav_xml (element); item.project_id = project.id; @@ -543,7 +285,6 @@ public class Services.CalDAV.Core : GLib.Object { Services.EventBus.get_default ().item_moved (item, old_project_id, "", old_parent_id); } - bool old_checked = item.checked; if (old_checked != item.checked) { Services.Store.instance ().checked_toggled (item, old_checked); } @@ -564,23 +305,18 @@ public class Services.CalDAV.Core : GLib.Object { } private Objects.Item add_item_if_not_exists (GXml.DomElement element, Objects.Project project) { - Objects.Item return_value; + Objects.Item return_value = new Objects.Item.from_caldav_xml (element); + return_value.project_id = project.id;; string parent_id = Util.get_related_to_uid (element); if (parent_id != "") { Objects.Item? parent_item = Services.Store.instance ().get_item (parent_id); if (parent_item != null) { - return_value = new Objects.Item.from_caldav_xml (element); - return_value.project_id = project.id; parent_item.add_item_if_not_exists (return_value); } else { - return_value = new Objects.Item.from_caldav_xml (element); - return_value.project_id = project.id; project.add_item_if_not_exists (return_value); } } else { - return_value = new Objects.Item.from_caldav_xml (element); - return_value.project_id = project.id; project.add_item_if_not_exists (return_value); } @@ -592,7 +328,7 @@ public class Services.CalDAV.Core : GLib.Object { var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); message.request_headers.append ("Depth", "1"); - message.set_request_body_from_bytes ("application/xml", new Bytes (TASKLIST_REQUEST.data)); + // message.set_request_body_from_bytes ("application/xml", new Bytes (Services.CalDAV.Providers.Nextcloud.TASKLIST_REQUEST.data)); source.sync_started (); @@ -609,6 +345,8 @@ public class Services.CalDAV.Core : GLib.Object { Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); if (project == null) { project = new Objects.Project.from_caldav_xml (element); + project.source_id = source.id; + Services.Store.instance ().insert_project (project); yield get_all_tasks_by_tasklist (project); } else { @@ -635,10 +373,12 @@ public class Services.CalDAV.Core : GLib.Object { } public async void sync_tasklist (Objects.Project project) { + yield update_tasklist_detail (project); + var url = "%s/calendars/%s/%s".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("REPORT", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes ((SYNC_TOKEN_REQUEST.printf (project.sync_id)).data)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.SYNC_TOKEN_REQUEST.printf (project.sync_id)).data)); try { if (project.sync_id == "") { @@ -674,7 +414,8 @@ public class Services.CalDAV.Core : GLib.Object { if (item != null) { string old_project_id = item.project_id; string old_parent_id = item.parent_id; - + bool old_checked = item.checked; + item.update_from_vtodo (vtodo, ics); item.project_id = project.id; Services.Store.instance ().update_item (item); @@ -682,8 +423,7 @@ public class Services.CalDAV.Core : GLib.Object { if (old_project_id != item.project_id || old_parent_id != item.parent_id) { Services.EventBus.get_default ().item_moved (item, old_project_id, "", old_parent_id); } - - bool old_checked = item.checked; + if (old_checked != item.checked) { Services.Store.instance ().checked_toggled (item, old_checked); } @@ -737,11 +477,13 @@ public class Services.CalDAV.Core : GLib.Object { return return_value; } + // TODO private async void add_project_if_not_exists (GXml.DomElement element, Gee.HashMap labels_map) { if (is_vtodo_calendar (element)) { Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); if (project == null) { project = new Objects.Project.from_caldav_xml (element); + Services.Store.instance ().insert_project (project); yield get_all_tasks_by_tasklist (project); } else { @@ -803,7 +545,7 @@ public class Services.CalDAV.Core : GLib.Object { var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("MKCOL", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes ((CREATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.CREATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); bool status = false; @@ -822,7 +564,7 @@ public class Services.CalDAV.Core : GLib.Object { var message = new Soup.Message ("PROPPATCH", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes ((UPDATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.UPDATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); bool status = false; @@ -853,64 +595,90 @@ public class Services.CalDAV.Core : GLib.Object { return status; } - public async HttpResponse refresh_tasklist (Objects.Project project) { + public async void refresh_tasklist (Objects.Project project) { var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes ((TASKLIST_REQUEST).data)); - - HttpResponse return_value = new HttpResponse (); + // message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.TASKLIST_REQUEST).data)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); print_root ("refresh_tasklist", (string) stream.get_data ()); + // GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); + // GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); + + // // Categories + // Gee.HashMap labels_map = new Gee.HashMap (); + + // foreach (GXml.DomElement element in response) { + // yield add_project_if_not_exists (element, labels_map); + // } + } catch (Error e) { + debug (e.message); + } + } + + private async void update_tasklist_detail (Objects.Project project) { + var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); + + var message = new Soup.Message ("PROPFIND", url); + message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); + message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.TASKS_REQUEST_DETAIL).data)); + + try { + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + + print_root ("get_tasklist_detail", (string) stream.get_data ()); + GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); + GXml.DomHTMLCollection response_collection = doc.get_elements_by_tag_name ("d:response"); - // Categories - Gee.HashMap labels_map = new Gee.HashMap (); + if (response_collection.length > 0) { + GXml.DomElement d_response = response_collection.get_element (0); + GXml.DomElement d_prop = d_response.get_elements_by_tag_name ("d:prop").get_element (0); - foreach (GXml.DomElement element in response) { - yield add_project_if_not_exists (element, labels_map); - } + GXml.DomHTMLCollection displayname_elements = d_prop.get_elements_by_tag_name ("d:displayname"); + if (displayname_elements.length > 0) { + project.name = displayname_elements.get_element (0).text_content; + } - return_value.status = true; + GXml.DomHTMLCollection color_elements = d_prop.get_elements_by_tag_name ("x1:calendar-color"); + if (color_elements.length > 0) { + project.color = color_elements.get_element (0).text_content; + } + + Services.Store.instance ().update_project (project); + } } catch (Error e) { debug (e.message); } - - return return_value; } - public async HttpResponse get_sync_token (Objects.Project project) { + public async void update_sync_token (Objects.Project project) { var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); - message.set_request_body_from_bytes ("application/xml", new Bytes ((GET_SYNC_TOKEN_REQUEST).data)); - - HttpResponse return_value = new HttpResponse (); + message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.GET_SYNC_TOKEN_REQUEST).data)); try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - print_root ("get_tasklist", (string) stream.get_data ()); + print_root ("update_sync_token", (string) stream.get_data ()); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); GXml.DomHTMLCollection sync_token_collection = doc.get_elements_by_tag_name ("d:sync-token"); if (sync_token_collection.length > 0) { - return_value.status = true; - return_value.data = sync_token_collection.get_element (0).text_content; + project.sync_id = sync_token_collection.get_element (0).text_content; + project.update_local (); } } catch (Error e) { debug (e.message); } - - return return_value; } /* diff --git a/core/Services/CalDAV/Providers/Nextcloud.vala b/core/Services/CalDAV/Providers/Nextcloud.vala new file mode 100644 index 000000000..5a6301890 --- /dev/null +++ b/core/Services/CalDAV/Providers/Nextcloud.vala @@ -0,0 +1,374 @@ +/* +* Copyright © 2024 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.CalDAV.Providers.Nextcloud : Services.CalDAV.Providers.Base { + // vala-lint=naming-convention + public static string GET_SYNC_TOKEN_REQUEST = """ + + + + + + """; + + // vala-lint=naming-convention + public static string CREATE_TASKLIST_REQUEST = """ + + + + + + + 0 + %s + %s + 1 + + + + + + + """; + + // vala-lint=naming-convention + public static string UPDATE_TASKLIST_REQUEST = """ + + + + %s + %s + + + + """; + + // vala-lint=naming-convention + public static string SYNC_TOKEN_REQUEST = """ + + %s + 1 + + + + + + """; + + // vala-lint=naming-convention + public static string TASKS_REQUEST = """ + + + + + + + + + + + + + + + + + + + + + + + """; + + // vala-lint=naming-convention + public static string TASKS_REQUEST_DETAIL = """ + + + + + + + + """; + + public Nextcloud () { + LOGIN_REQUEST = """ + + + + + + """; + + USER_DATA_REQUEST = """ + + + + + + + """; + + TASKLIST_REQUEST = """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """; + } + + public override string get_server_url (string url, string username, string password) { + string server_url = ""; + + try { + var _uri = GLib.Uri.parse (url, GLib.UriFlags.NONE); + server_url = "%s://%s".printf (_uri.get_scheme (), _uri.get_host ()); + } catch (Error e) { + debug (e.message); + } + + return "%s/remote.php/dav".printf (server_url); + } + + public override string get_account_url (string server_url, string username) { + return "%s/principals/users/%s/".printf (server_url, username); + } + + public override void set_user_data (GXml.DomDocument doc, Objects.Source source) { + GXml.DomElement d_displayname = doc.get_elements_by_tag_name ("d:displayname").get_element (0); + GXml.DomElement d_email = doc.get_elements_by_tag_name ("s:email-address").get_element (0); + + source.caldav_data.user_displayname = d_displayname.text_content; + source.caldav_data.user_email = d_email.text_content; + } + + public override string get_all_taskslist_url (string server_url, string username) { + return "%s/calendars/%s/".printf (server_url, username);; + } + + public override Gee.ArrayList get_projects_by_doc (GXml.DomDocument doc, Objects.Source source) { + Gee.ArrayList return_value = new Gee.ArrayList (); + + GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); + foreach (GXml.DomElement element in response) { + if (is_vtodo_calendar (element)) { + var project = new Objects.Project (); + project.id = get_id_from_url (element); + project.name = get_prop_value (element, "d:displayname"); + project.color = get_prop_value (element, "x1:calendar-color"); + project.sync_id = get_prop_value (element, "d:sync-token"); + project.source_id = source.id; + return_value.add (project); + } + } + + return return_value; + } + + public string get_id_from_url (GXml.DomElement element) { + if (element.get_elements_by_tag_name ("d:href").length <= 0) { + return ""; + } + + GXml.DomElement href = element.get_elements_by_tag_name ("d:href").get_element (0); + + string[] parts = href.text_content.split ("/"); + return parts[parts.length - 2]; + } + + public string get_prop_value (GXml.DomElement element, string key) { + if (element.get_elements_by_tag_name ("d:propstat").length <= 0) { + return ""; + } + + GXml.DomElement propstat = element.get_elements_by_tag_name ("d:propstat").get_element (0); + + if (propstat.get_elements_by_tag_name ("d:prop").length <= 0) { + return ""; + } + + GXml.DomElement prop = propstat.get_elements_by_tag_name ("d:prop").get_element (0); + + if (prop.get_elements_by_tag_name (key).length <= 0) { + return ""; + } + + return prop.get_elements_by_tag_name (key).get_element (0).text_content; + } + + public override bool is_vtodo_calendar (GXml.DomElement element) { + GXml.DomElement propstat = element.get_elements_by_tag_name ("d:propstat").get_element (0); + GXml.DomElement prop = propstat.get_elements_by_tag_name ("d:prop").get_element (0); + GXml.DomElement resourcetype = prop.get_elements_by_tag_name ("d:resourcetype").get_element (0); + + bool is_calendar = resourcetype.get_elements_by_tag_name ("cal:calendar").length > 0; + bool is_vtodo = false; + + if (is_calendar) { + GXml.DomElement supported_calendar = prop.get_elements_by_tag_name ("cal:supported-calendar-component-set").get_element (0); + GXml.DomHTMLCollection calendar_comps = supported_calendar.get_elements_by_tag_name ("cal:comp"); + foreach (GXml.DomElement calendar_comp in calendar_comps) { + if (calendar_comp.get_attribute ("name") == "VTODO") { + is_vtodo = true; + } + } + } + + return is_vtodo; + } +} diff --git a/core/Services/CalDAV/Providers/ProviderBase.vala b/core/Services/CalDAV/Providers/ProviderBase.vala new file mode 100644 index 000000000..9f6b3c1fa --- /dev/null +++ b/core/Services/CalDAV/Providers/ProviderBase.vala @@ -0,0 +1,33 @@ +public class Services.CalDAV.Providers.Base { + // vala-lint=naming-convention + public virtual string LOGIN_REQUEST { get; set; default = ""; } + + // vala-lint=naming-convention + public virtual string USER_DATA_REQUEST { get; set; default = ""; } + + public virtual string TASKLIST_REQUEST { get; set; default = ""; } + + public virtual string get_server_url (string server_url, string username, string password) { + return ""; + } + + public virtual string get_account_url (string server_url, string username) { + return ""; + } + + public virtual void set_user_data (GXml.DomDocument doc, Objects.Source source) { + + } + + public virtual string get_all_taskslist_url (string server_url, string username) { + return ""; + } + + public virtual Gee.ArrayList get_projects_by_doc (GXml.DomDocument doc, Objects.Source source) { + return new Gee.ArrayList (); + } + + public virtual bool is_vtodo_calendar (GXml.DomElement element) { + return false; + } +} \ No newline at end of file diff --git a/core/Services/CalDAV/Providers/Radicale.vala b/core/Services/CalDAV/Providers/Radicale.vala new file mode 100644 index 000000000..e3838ce3e --- /dev/null +++ b/core/Services/CalDAV/Providers/Radicale.vala @@ -0,0 +1,183 @@ +/* +* Copyright © 2024 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.CalDAV.Providers.Radicale : Services.CalDAV.Providers.Base { + public Radicale () { + LOGIN_REQUEST = """ + + + + + + """; + + USER_DATA_REQUEST = """ + + + + + + + """; + + TASKLIST_REQUEST = """ + + + + + + + + + + + + + + + + + """; + } + + public override string get_server_url (string url, string username, string password) { + string server_url = ""; + string scheme = ""; + try { + var _uri = GLib.Uri.parse (url, GLib.UriFlags.NONE); + server_url = _uri.get_host (); + scheme = _uri.get_scheme (); + } catch (Error e) { + debug (e.message); + } + + return "%s://%s:%s@%s".printf (scheme, username, Uri.escape_string (password), server_url); + } + + public override string get_account_url (string server_url, string username) { + return "%s/%s/".printf (server_url, username); + } + + public override void set_user_data (GXml.DomDocument doc, Objects.Source source) { + source.caldav_data.user_displayname = source.caldav_data.username; + source.caldav_data.user_email = ""; + } + + public override string get_all_taskslist_url (string server_url, string username) { + return "%s/%s/".printf (server_url, username); + } + + public override Gee.ArrayList get_projects_by_doc (GXml.DomDocument doc, Objects.Source source) { + Gee.ArrayList return_value = new Gee.ArrayList (); + + GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("response"); + foreach (GXml.DomElement element in response) { + if (is_vtodo_calendar (element)) { + var project = new Objects.Project (); + project.id = get_id_from_url (element); + project.name = get_prop_value (element, "RADICALE:displayname"); + project.color = get_prop_value (element, "ICAL:calendar-color"); + project.sync_id = get_prop_value (element, "sync-token"); + + return_value.add (project); + } + } + + return return_value; + } + + public string get_id_from_url (GXml.DomElement element) { + if (element.get_elements_by_tag_name ("href").length <= 0) { + return ""; + } + + GXml.DomElement href = element.get_elements_by_tag_name ("href").get_element (0); + + string[] parts = href.text_content.split ("/"); + return parts[parts.length - 2]; + } + + public string get_prop_value (GXml.DomElement element, string key) { + if (element.get_elements_by_tag_name ("propstat").length <= 0) { + return ""; + } + + GXml.DomElement propstat = element.get_elements_by_tag_name ("propstat").get_element (0); + + if (propstat.get_elements_by_tag_name ("prop").length <= 0) { + return ""; + } + + GXml.DomElement prop = propstat.get_elements_by_tag_name ("prop").get_element (0); + + if (prop.get_elements_by_tag_name (key).length <= 0) { + return ""; + } + + return prop.get_elements_by_tag_name (key).get_element (0).text_content; + } + + public override bool is_vtodo_calendar (GXml.DomElement element) { + if (element.get_elements_by_tag_name ("propstat").length <= 0) { + return false; + } + + GXml.DomElement propstat = element.get_elements_by_tag_name ("propstat").get_element (0); + + if (propstat.get_elements_by_tag_name ("prop").length <= 0) { + return false; + } + + GXml.DomElement prop = propstat.get_elements_by_tag_name ("prop").get_element (0); + + if (prop.get_elements_by_tag_name ("resourcetype").length <= 0) { + return false; + } + + GXml.DomElement resourcetype = prop.get_elements_by_tag_name ("resourcetype").get_element (0); + + bool is_calendar = resourcetype.get_elements_by_tag_name ("C:calendar").length > 0; + bool is_vtodo = false; + + if (is_calendar) { + if (prop.get_elements_by_tag_name ("C:supported-calendar-component-set").length <= 0) { + return false; + } + + GXml.DomElement supported_calendar = prop.get_elements_by_tag_name ("C:supported-calendar-component-set").get_element (0); + GXml.DomHTMLCollection calendar_comps = supported_calendar.get_elements_by_tag_name ("C:comp"); + foreach (GXml.DomElement calendar_comp in calendar_comps) { + if (calendar_comp.get_attribute ("name") == "VTODO") { + is_vtodo = true; + } + } + } + + return is_vtodo; + } +} diff --git a/core/Services/Database.vala b/core/Services/Database.vala index 63cd7794d..e23932ab3 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -469,7 +469,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_source (stmt)); } - stmt.reset (); + return return_value; } @@ -518,7 +518,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -536,7 +535,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -569,7 +567,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -591,7 +588,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_project (stmt)); } - stmt.reset (); + return return_value; } @@ -662,11 +659,10 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$sync_id", project.sync_id); set_parameter_str (stmt, "$source_id", project.source_id); - if (stmt.step () == Sqlite.DONE) { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -684,7 +680,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -704,8 +699,6 @@ public class Services.Database : GLib.Object { if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - - stmt.reset (); } public bool update_project (Objects.Project project) { @@ -767,7 +760,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -786,7 +778,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -807,7 +798,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_label (stmt)); } - stmt.reset (); + return return_value; } @@ -848,7 +839,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -866,7 +856,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -894,7 +883,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -930,7 +918,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -945,7 +932,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_section (stmt)); } - stmt.reset (); + return return_value; } @@ -980,7 +967,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -1013,7 +999,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -1032,7 +1017,6 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); return stmt.step () == Sqlite.DONE; } @@ -1051,7 +1035,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1070,7 +1054,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1112,28 +1096,13 @@ public class Services.Database : GLib.Object { 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) { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - - stmt.reset (); + return stmt.step () == Sqlite.DONE; } - 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 Gee.ArrayList get_items_collection () { Gee.ArrayList return_value = new Gee.ArrayList (); Sqlite.Statement stmt; @@ -1145,7 +1114,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_item (stmt)); } - stmt.reset (); + return return_value; } @@ -1162,7 +1131,7 @@ public class Services.Database : GLib.Object { returned = _fill_item (stmt); } - stmt.reset (); + return returned; } @@ -1206,7 +1175,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1241,7 +1210,7 @@ public class Services.Database : GLib.Object { 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, "$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); @@ -1250,7 +1219,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1272,11 +1241,11 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$parent_id", item.parent_id); set_parameter_str (stmt, "$id", item.id); - if (stmt.step () == Sqlite.DONE) { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1297,7 +1266,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1326,7 +1295,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } // Reminders @@ -1350,7 +1319,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1367,7 +1336,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_reminder (stmt)); } - stmt.reset (); + return return_value; } @@ -1395,7 +1364,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_reminder (stmt)); } - stmt.reset (); + return return_value; } @@ -1413,7 +1382,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1439,7 +1408,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1456,7 +1425,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_attachment (stmt)); } - stmt.reset (); + return return_value; } @@ -1485,7 +1454,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1513,7 +1482,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public Gee.ArrayList get_all_queue () { @@ -1529,7 +1498,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_queue (stmt)); } - stmt.reset (); + return return_value; } @@ -1561,7 +1530,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public bool curTempIds_exists (string id) { // vala-lint=naming-convention @@ -1579,7 +1548,7 @@ public class Services.Database : GLib.Object { returned = stmt.column_int (0) > 0; } - stmt.reset (); + return returned; } @@ -1598,7 +1567,7 @@ public class Services.Database : GLib.Object { returned = stmt.column_text (0); } - stmt.reset (); + return returned; } @@ -1617,7 +1586,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1636,7 +1605,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1655,7 +1624,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1674,7 +1643,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1693,7 +1662,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1708,11 +1677,11 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$new_id", new_id); set_parameter_str (stmt, "$current_id", current_id); - if (stmt.step () == Sqlite.DONE) { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1727,11 +1696,11 @@ public class Services.Database : GLib.Object { set_parameter_str (stmt, "$new_id", new_id); set_parameter_str (stmt, "$current_id", current_id); - if (stmt.step () == Sqlite.DONE) { + if (stmt.step () != Sqlite.DONE) { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + return stmt.step () == Sqlite.DONE; } @@ -1749,7 +1718,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public void remove_queue (string uuid) { @@ -1766,7 +1735,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public void clear_queue () { @@ -1785,7 +1754,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public void clear_cur_temp_ids () { @@ -1804,7 +1773,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } /* @@ -1830,7 +1799,7 @@ public class Services.Database : GLib.Object { while (stmt.step () == Sqlite.ROW) { return_value.add (_fill_object_event (stmt)); } - stmt.reset (); + return return_value; } @@ -1889,6 +1858,20 @@ public class Services.Database : GLib.Object { 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; @@ -1907,7 +1890,7 @@ public class Services.Database : GLib.Object { } } - stmt.reset (); + return returned; } @@ -1928,7 +1911,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public void add_int_column (string table, string column, int default_value) { @@ -1948,7 +1931,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public void add_item_label_column () { @@ -1975,7 +1958,7 @@ public class Services.Database : GLib.Object { warning ("Error: %d: %s", db.errcode (), db.errmsg ()); } - stmt.reset (); + } public void add_project_labels_source_id () { diff --git a/core/Services/EventBus.vala b/core/Services/EventBus.vala index 3de395582..b6823d31f 100644 --- a/core/Services/EventBus.vala +++ b/core/Services/EventBus.vala @@ -64,6 +64,7 @@ public class Services.EventBus : Object { public signal void expand_all (string project_id, bool active); public signal void drag_projects_end (string source_id); public signal void drag_items_end (string project_id); + public signal void update_sources_position (); public bool _mobile_mode = Services.Settings.get_default ().settings.get_boolean ("mobile-mode"); public bool mobile_mode { diff --git a/core/Services/Store.vala b/core/Services/Store.vala index d318f29dd..0308b055b 100644 --- a/core/Services/Store.vala +++ b/core/Services/Store.vala @@ -134,47 +134,35 @@ public class Services.Store : GLib.Object { } construct { - label_deleted.connect ((label) => { - if (_labels.remove (label)) { - debug ("Label Removed: %s", label.name); - } - }); - source_deleted.connect ((source) => { if (_sources.remove (source)) { debug ("Source Removed: %s", source.header_text); } }); - project_deleted.connect ((project) => { - if (_projects.remove (project)) { - debug ("Prodeleteject Removed: %s", project.name); + label_deleted.connect ((label) => { + if (_labels.remove (label)) { + debug ("Label Removed: %s", label.name); } }); - section_deleted.connect ((section) => { - if (_sections.remove (section)) { - debug ("Section Removed: %s", section.name); + project_deleted.connect ((project) => { + if (_projects.remove (project)) { + debug ("Project Removed: %s", project.name); } }); - item_deleted.connect ((item) => { - if (_items.remove (item)) { - debug ("item Removed: %s", item.content); - } - }); + // item_deleted.connect ((item) => { + // if (_items.remove (item)) { + // debug ("item Removed: %s", item.content); + // } + // }); reminder_deleted.connect ((reminder) => { if (_reminders.remove (reminder)) { debug ("Reminder Removed: %s", reminder.id.to_string ()); } }); - - attachment_deleted.connect ((attachment) => { - if (_attachments.remove (attachment)) { - debug ("Attachment Removed: %s", attachment.id.to_string ()); - } - }); } public bool is_database_empty () { @@ -218,6 +206,8 @@ public class Services.Store : GLib.Object { } source.deleted (); + source_deleted (source); + _sources.remove (source); } } @@ -286,6 +276,8 @@ public class Services.Store : GLib.Object { } project.deleted (); + project_deleted (project); + _projects.remove (project); } } @@ -420,8 +412,10 @@ public class Services.Store : GLib.Object { foreach (Objects.Item item in section.items) { delete_item (item); } - + section.deleted (); + section_deleted (section); + _sections.remove (section); } } @@ -554,6 +548,13 @@ public class Services.Store : GLib.Object { } item.deleted (); + item_deleted (item); + _items.remove (item); + + item.project.item_deleted (item); + if (item.has_section) { + item.section.item_deleted (item); + } } } @@ -1179,6 +1180,9 @@ public class Services.Store : GLib.Object { public void delete_attachment (Objects.Attachment attachment) { if (Services.Database.get_default ().delete_attachment (attachment)) { attachment.deleted (); + attachment_deleted (attachment); + _attachments.remove (attachment); + attachment.item.attachment_deleted (attachment); } } diff --git a/core/Services/Todoist.vala b/core/Services/Todoist.vala index 29070bb7e..c39a2cae9 100644 --- a/core/Services/Todoist.vala +++ b/core/Services/Todoist.vala @@ -48,14 +48,6 @@ public class Services.Todoist : GLib.Object { public Todoist () { session = new Soup.Session (); parser = new Json.Parser (); - - // var network_monitor = GLib.NetworkMonitor.get_default (); - // network_monitor.network_changed.connect (() => { - // if (GLib.NetworkMonitor.get_default ().network_available && is_logged_in () && - // Services.Settings.get_default ().settings.get_boolean ("todoist-sync-server")) { - // sync_async (); - // } - // }); } public bool invalid_token () { @@ -314,6 +306,7 @@ public class Services.Todoist : GLib.Object { string old_project_id = item.project_id; string old_section_id = item.section_id; string old_parent_id = item.parent_id; + bool old_checked = item.checked; item.update_from_json (_node); Services.Store.instance ().update_item (item); @@ -323,7 +316,6 @@ public class Services.Todoist : GLib.Object { Services.EventBus.get_default ().item_moved (item, old_project_id, old_section_id, old_parent_id); } - bool old_checked = item.checked; if (old_checked != item.checked) { Services.Store.instance ().checked_toggled (item, old_checked); } diff --git a/core/Widgets/LabelPicker/LabelPicker.vala b/core/Widgets/LabelPicker/LabelPicker.vala index abffc9e52..de7688af2 100644 --- a/core/Widgets/LabelPicker/LabelPicker.vala +++ b/core/Widgets/LabelPicker/LabelPicker.vala @@ -53,7 +53,7 @@ public class Widgets.LabelPicker.LabelPicker : Gtk.Popover { construct { css_classes = { "popover-contents" }; - picker = new Widgets.LabelsPickerCore () { + picker = new Widgets.LabelsPickerCore (LabelPickerType.SELECT) { margin_top = 12 }; diff --git a/core/Widgets/LabelsPickerCore.vala b/core/Widgets/LabelsPickerCore.vala index 3f38b5520..ebf419d7f 100644 --- a/core/Widgets/LabelsPickerCore.vala +++ b/core/Widgets/LabelsPickerCore.vala @@ -20,6 +20,8 @@ */ public class Widgets.LabelsPickerCore : Adw.Bin { + public LabelPickerType picker_type { get; construct; } + private Gtk.SearchEntry search_entry; private Gtk.ListBox listbox; private Gtk.Label placeholder_message_label; @@ -63,11 +65,21 @@ public class Widgets.LabelsPickerCore : Adw.Bin { public signal void close (); + public LabelsPickerCore (LabelPickerType picker_type) { + Object ( + picker_type: picker_type + ); + } + construct { css_classes = { "popover-contents" }; + if (picker_type == LabelPickerType.FILTER) { + PLACEHOLDER_MESSAGE = _("Your list of filters will show up here."); + } + search_entry = new Gtk.SearchEntry () { - placeholder_text = _("Search or Create"), + placeholder_text = picker_type == LabelPickerType.SELECT ? _("Search or Create") : _("Search"), valign = Gtk.Align.CENTER, hexpand = true, margin_start = 12, @@ -91,6 +103,7 @@ public class Widgets.LabelsPickerCore : Adw.Bin { margin_start = 9, margin_end = 9, margin_top = 12, + margin_bottom = 6, child = listbox, valign = Gtk.Align.START }; @@ -109,16 +122,13 @@ public class Widgets.LabelsPickerCore : Adw.Bin { child = toolbar_view; - var controller_key = new Gtk.EventControllerKey (); - toolbar_view.add_controller (controller_key); - - controller_key.key_pressed.connect ((keyval, keycode, state) => { + var listbox_controller_key = new Gtk.EventControllerKey (); + listbox.add_controller (listbox_controller_key); + listbox_controller_key.key_pressed.connect ((keyval, keycode, state) => { var key = Gdk.keyval_name (keyval).replace ("KP_", ""); if (key == "Up" || key == "Down") { - return false; } else if (key == "Enter" || key == "Return" || key == "KP_Enter") { - return false; } else { if (!search_entry.has_focus) { search_entry.grab_focus (); @@ -126,11 +136,9 @@ public class Widgets.LabelsPickerCore : Adw.Bin { search_entry.set_position (search_entry.text.length); } } - - return false; } - return true; + return false; }); search_entry.search_changed.connect (() => { @@ -146,12 +154,14 @@ public class Widgets.LabelsPickerCore : Adw.Bin { return return_value; }); - add_tag_revealer.reveal_child = size <= 0; - placeholder_message_label.label = size <= 0 ? PLACEHOLDER_CREATE_MESSAGE.printf (search_entry.text) : PLACEHOLDER_MESSAGE; + if (picker_type == LabelPickerType.SELECT) { + add_tag_revealer.reveal_child = size <= 0; + placeholder_message_label.label = size <= 0 ? PLACEHOLDER_CREATE_MESSAGE.printf (search_entry.text) : PLACEHOLDER_MESSAGE; + } }); search_entry.activate.connect (() => { - if (search_entry.text.length > 0) { + if (source != null && search_entry.text.length > 0) { Objects.Label label = Services.Store.instance ().get_label_by_name (search_entry.text, true, source.id); if (label != null) { if (labels_widgets_map.has_key (label.id_string)) { @@ -251,8 +261,9 @@ public class Widgets.LabelsPickerCore : Adw.Bin { var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { valign = CENTER, - margin_start = 12, - margin_end = 12 + margin_start = 24, + margin_end = 24, + margin_top = 24 }; box.append (add_tag_revealer); box.append (placeholder_message_label); @@ -280,4 +291,16 @@ public class Widgets.LabelsPickerCore : Adw.Bin { labels_widgets_map.clear (); } + + public void add_labels_list (Gee.ArrayList labels_list) { + labels_widgets_map.clear (); + + foreach (unowned Gtk.Widget child in Util.get_default ().get_children (listbox) ) { + listbox.remove (child); + } + + foreach (Objects.Label label in labels_list) { + add_label (label); + } + } } diff --git a/core/meson.build b/core/meson.build index 1e72ded3b..f9f85a17b 100644 --- a/core/meson.build +++ b/core/meson.build @@ -12,9 +12,11 @@ core_files = files( 'Services/Database.vala', 'Services/Store.vala', 'Services/Todoist.vala', + 'Services/CalDAV/Core.vala', - 'Services/CalDAV/Constants.vala', - 'Services/CalDAV/Backend.vala', + 'Services/CalDAV/Providers/ProviderBase.vala', + 'Services/CalDAV/Providers/Nextcloud.vala', + 'Services/CalDAV/Providers/Radicale.vala', 'Services/Chrono/Chrono.vala', 'Services/Chrono/Enum.vala', diff --git a/data/resources/stylesheet/stylesheet.css b/data/resources/stylesheet/stylesheet.css index 504b1fb67..4c840bb33 100644 --- a/data/resources/stylesheet/stylesheet.css +++ b/data/resources/stylesheet/stylesheet.css @@ -616,7 +616,11 @@ checkbutton.theme-selector radio:checked { .banner { border-radius: 9px; background-color: #8bc6ec; - background-image: linear-gradient(135deg, #8bc6ec 0%, #9599e2 100%); + background: linear-gradient( + 90deg, + hsla(242, 58%, 73%, 1) 0%, + hsla(157, 72%, 82%, 1) 100% + ); } .banner-text { diff --git a/src/Dialogs/LabelPicker.vala b/src/Dialogs/LabelPicker.vala index 2ab6f60c2..cf57a9127 100644 --- a/src/Dialogs/LabelPicker.vala +++ b/src/Dialogs/LabelPicker.vala @@ -42,7 +42,7 @@ public class Dialogs.LabelPicker : Adw.Dialog { var headerbar = new Adw.HeaderBar (); headerbar.add_css_class ("flat"); - picker = new Widgets.LabelsPickerCore (); + picker = new Widgets.LabelsPickerCore (LabelPickerType.FILTER); var button = new Widgets.LoadingButton (LoadingButtonType.LABEL, _("Filter")) { margin_top = 12, @@ -87,6 +87,10 @@ public class Dialogs.LabelPicker : Adw.Dialog { picker.source = source; } + public void add_labels_list (Gee.ArrayList labels_list) { + picker.add_labels_list (labels_list); + } + public void hide_destroy () { close (); } diff --git a/src/Dialogs/Preferences/Pages/Backup.vala b/src/Dialogs/Preferences/Pages/Backup.vala index 7e9c89c6f..b84077008 100644 --- a/src/Dialogs/Preferences/Pages/Backup.vala +++ b/src/Dialogs/Preferences/Pages/Backup.vala @@ -127,7 +127,7 @@ public class Dialogs.Preferences.Pages.Backup : Adw.Bin { GLib.File file = GLib.File.new_for_path (path); if (file.query_exists ()) { - if (Services.Migrate.get_default ().migrate_from_file (file)) { + if (Services.MigrateFromPlanner.get_default ().migrate_from_file (file)) { popup_toast (_("Tasks Migrate Successfully")); pop_subpage (); } diff --git a/src/Dialogs/Preferences/PreferencesWindow.vala b/src/Dialogs/Preferences/PreferencesWindow.vala index 7687cbb87..d184e8b63 100644 --- a/src/Dialogs/Preferences/PreferencesWindow.vala +++ b/src/Dialogs/Preferences/PreferencesWindow.vala @@ -825,13 +825,11 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { private Adw.NavigationPage get_accounts_page () { var settings_header = new Dialogs.Preferences.SettingsHeader (_("Accounts")); - // var local_item = new Widgets.ContextMenu.MenuItem (_("On This Computer")); var todoist_item = new Widgets.ContextMenu.MenuItem (_("Todoist")); - var caldav_item = new Widgets.ContextMenu.MenuItem (_("CalDAV")); + var caldav_item = new Widgets.ContextMenu.MenuItem (_("Nextcloud")); var menu_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); menu_box.margin_top = menu_box.margin_bottom = 3; - // menu_box.append (local_item); menu_box.append (todoist_item); menu_box.append (caldav_item); @@ -858,8 +856,13 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { sources_group.add_widget_end (add_source_button); - var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12); + var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 3); content_box.append (sources_group); + content_box.append (new Gtk.Label (_("You can sort your accounts by dragging and dropping")) { + css_classes = { "caption", "dim-label" }, + halign = START, + margin_start = 12 + }); var content_clamp = new Adw.Clamp () { maximum_size = 600, @@ -952,16 +955,10 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { user_box.append (user_label); user_box.append (email_label); - var sync_server_switch = new Gtk.Switch () { - valign = Gtk.Align.CENTER, - active = source.sync_server - }; - - var sync_server_row = new Adw.ActionRow (); + var sync_server_row = new Adw.SwitchRow (); sync_server_row.title = _("Sync Server"); sync_server_row.subtitle = _("Activate this setting so that Planify automatically synchronizes with your account account every 15 minutes"); - sync_server_row.set_activatable_widget (sync_server_switch); - sync_server_row.add_suffix (sync_server_switch); + sync_server_row.active = source.sync_server; var last_sync_date = new GLib.DateTime.from_iso8601 ( source.last_sync, new GLib.TimeZone.local () @@ -1008,9 +1005,15 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { pop_subpage (); }); - sync_server_row.notify["active"].connect (() => { - source.sync_server = sync_server_switch.active; + sync_server_row.activated.connect (() => { + source.sync_server = !source.sync_server; source.save (); + + if (source.sync_server) { + source.run_server (); + } else { + source.remove_sync_server (); + } }); return page; diff --git a/src/Dialogs/Project.vala b/src/Dialogs/Project.vala index b462dcafe..dfc3fffe7 100644 --- a/src/Dialogs/Project.vala +++ b/src/Dialogs/Project.vala @@ -402,7 +402,7 @@ public class Dialogs.Project : Adw.Dialog { if (project.source_type == SourceType.LOCAL || project.source_type == SourceType.NONE) { project.id = Util.get_default ().generate_id (project); Services.Store.instance ().insert_project (project); - go_project (project.id_string); + go_project (project.id); } else if (project.source_type == SourceType.TODOIST) { Services.Todoist.get_default ().add.begin (project, (obj, res) => { HttpResponse response = Services.Todoist.get_default ().add.end (res); @@ -410,34 +410,27 @@ public class Dialogs.Project : Adw.Dialog { if (response.status) { project.id = response.data; Services.Store.instance ().insert_project (project); - go_project (project.id_string); + go_project (project.id); } }); } else if (project.source_type == SourceType.CALDAV) { project.id = Util.get_default ().generate_id (project); Services.CalDAV.Core.get_default ().add_tasklist.begin (project, (obj, res) => { if (Services.CalDAV.Core.get_default ().add_tasklist.end (res)) { - Services.CalDAV.Core.get_default ().get_sync_token.begin (project, (obj, res) => { - HttpResponse response = Services.CalDAV.Core.get_default ().get_sync_token.end (res); - - if (response.status) { - project.sync_id = response.data; - } - - Services.Store.instance ().insert_project (project); - go_project (project.id_string); - }); + Services.Store.instance ().insert_project (project); + Services.CalDAV.Core.get_default ().update_sync_token.begin (project); + go_project (project.id); } }); } } - public void go_project (string id_string) { + public void go_project (string id) { Timeout.add (250, () => { Services.EventBus.get_default ().send_notification ( Util.get_default ().create_toast (_("Project added successfully!")) ); - Services.EventBus.get_default ().pane_selected (PaneType.PROJECT, id_string); + Services.EventBus.get_default ().pane_selected (PaneType.PROJECT, id); hide_destroy (); return GLib.Source.REMOVE; }); diff --git a/src/Dialogs/QuickFind/QuickFind.vala b/src/Dialogs/QuickFind/QuickFind.vala index f31cb8198..769660470 100644 --- a/src/Dialogs/QuickFind/QuickFind.vala +++ b/src/Dialogs/QuickFind/QuickFind.vala @@ -26,8 +26,8 @@ public class Dialogs.QuickFind.QuickFind : Adw.Dialog { public QuickFind () { Object ( - content_width: 350, - content_height: 325, + content_width: 425, + content_height: 350, presentation_mode: Adw.DialogPresentationMode.FLOATING ); } diff --git a/src/Layouts/FilterPaneRow.vala b/src/Layouts/FilterPaneRow.vala index c2fde13a8..2a6e2a4b2 100644 --- a/src/Layouts/FilterPaneRow.vala +++ b/src/Layouts/FilterPaneRow.vala @@ -171,7 +171,9 @@ public class Layouts.FilterPaneRow : Gtk.FlowBoxChild { } } 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")); + 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 (() => { diff --git a/src/Layouts/ItemRow.vala b/src/Layouts/ItemRow.vala index 81583360a..a099b1370 100644 --- a/src/Layouts/ItemRow.vala +++ b/src/Layouts/ItemRow.vala @@ -190,7 +190,6 @@ public class Layouts.ItemRow : Layouts.ItemBase { public bool drag_enabled { get; set; default = true; } public signal void item_added (); - public signal void widget_destroyed (); public ItemRow (Objects.Item item, bool is_project_view = false) { Object ( @@ -955,7 +954,6 @@ public class Layouts.ItemRow : Layouts.ItemBase { } public override void hide_destroy () { - widget_destroyed (); main_revealer.reveal_child = false; Timeout.add (main_revealer.transition_duration, () => { ((Gtk.ListBox) parent).remove (this); diff --git a/src/Layouts/SectionRow.vala b/src/Layouts/SectionRow.vala index f853ba432..7712f1513 100644 --- a/src/Layouts/SectionRow.vala +++ b/src/Layouts/SectionRow.vala @@ -278,8 +278,9 @@ public class Layouts.SectionRow : Gtk.ListBoxRow { }); Services.EventBus.get_default ().checked_toggled.connect ((item, old_checked) => { - if (item.project_id == section.project_id && item.section_id == section.id && - !item.has_parent) { + if (item.project_id == section.project_id && item.section_id == section.id && !item.has_parent) { + print ("Content: %s - %s\n".printf (item.content, old_checked.to_string ())); + if (!old_checked) { if (items.has_key (item.id)) { items [item.id].hide_destroy (); diff --git a/src/Layouts/Sidebar.vala b/src/Layouts/Sidebar.vala index 202652408..cad869e53 100644 --- a/src/Layouts/Sidebar.vala +++ b/src/Layouts/Sidebar.vala @@ -80,9 +80,10 @@ public class Layouts.Sidebar : Adw.Bin { filters_flow.append (pinboard_filter); filters_flow.append (completed_filter); - favorites_header = new Layouts.HeaderItem (_("Favorites")); + favorites_header = new Layouts.HeaderItem (_("Favorites")) { + margin_top = 12 + }; favorites_header.placeholder_message = _("No favorites available. Create one by clicking on the '+' button"); - favorites_header.margin_top = 6; sources_listbox = new Gtk.ListBox () { hexpand = true, @@ -90,6 +91,12 @@ public class Layouts.Sidebar : Adw.Bin { css_classes = { "listbox-background" } }; + sources_listbox.set_sort_func ((child1, child2) => { + int item1 = ((Layouts.SidebarSourceRow) child1).source.child_order; + int item2 = ((Layouts.SidebarSourceRow) child2).source.child_order; + return item1 - item2; + }); + var whats_new_icon = new Gtk.Image.from_icon_name ("star-outline-thick-symbolic") { css_classes = { "gift-animation" } }; @@ -183,6 +190,10 @@ public class Layouts.Sidebar : Adw.Bin { update_version (); whats_new_revealer.reveal_child = verify_new_version (); }); + + Services.EventBus.get_default ().update_sources_position.connect (() => { + sources_listbox.invalidate_sort (); + }); } public void update_version () { diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 1625e9a1e..caa267ae1 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -286,6 +286,14 @@ public class MainWindow : Adw.ApplicationWindow { Services.Store.instance ().project_archived.connect (check_archived); Services.Store.instance ().project_unarchived.connect (check_archived); + + Services.NetworkMonitor.instance ().network_changed.connect (() => { + if (Services.NetworkMonitor.instance ().network_available) { + foreach (Objects.Source source in Services.Store.instance ().sources) { + source.run_server (); + } + } + }); } public void show_hide_sidebar () { @@ -319,7 +327,7 @@ public class MainWindow : Adw.ApplicationWindow { Timeout.add (Constants.SYNC_TIMEOUT, () => { foreach (Objects.Source source in Services.Store.instance ().sources) { - // source.run_server (); + source.run_server (); } return GLib.Source.REMOVE; diff --git a/src/Services/ActionManager.vala b/src/Services/ActionManager.vala index 9ec82ab44..58e558777 100644 --- a/src/Services/ActionManager.vala +++ b/src/Services/ActionManager.vala @@ -142,13 +142,9 @@ public class Services.ActionManager : Object { } private void action_sync_manually () { - // if (Services.Todoist.get_default ().is_logged_in ()) { - // Services.Todoist.get_default ().sync_async (); - // } - - // if (Services.CalDAV.Core.get_default ().is_logged_in ()) { - // Services.CalDAV.Core.get_default ().sync_async (); - // } + foreach (Objects.Source source in Services.Store.instance ().sources) { + source.run_server (); + } } private void action_new_project () { diff --git a/src/Services/Migrate.vala b/src/Services/MigrateFromPlanner.vala similarity index 96% rename from src/Services/Migrate.vala rename to src/Services/MigrateFromPlanner.vala index 86373cde3..ae7b62096 100644 --- a/src/Services/Migrate.vala +++ b/src/Services/MigrateFromPlanner.vala @@ -19,12 +19,12 @@ * Authored by: Alain M. */ -public class Services.Migrate : GLib.Object { - static GLib.Once _instance; +public class Services.MigrateFromPlanner : GLib.Object { + static GLib.Once _instance; - public static unowned Migrate get_default () { + public static unowned MigrateFromPlanner get_default () { return _instance.once (() => { - return new Migrate (); + return new MigrateFromPlanner (); }); } diff --git a/src/Services/NetworkMonitor.vala b/src/Services/NetworkMonitor.vala new file mode 100644 index 000000000..43b534d2c --- /dev/null +++ b/src/Services/NetworkMonitor.vala @@ -0,0 +1,68 @@ +/* +* Copyright © 2024 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.NetworkMonitor : GLib.Object { + static GLib.Once _instance; + public static unowned Services.NetworkMonitor instance () { + return _instance.once (() => { + return new Services.NetworkMonitor (); + }); + } + + bool? _network_available = null; + public bool network_available { + get { + if (_network_available == null) { + _network_available = !is_disconnected (); + } + + return _network_available; + } + } + + public signal void network_changed (); + + construct { + var network_monitor = GLib.NetworkMonitor.get_default (); + network_monitor.network_changed.connect (() => { + _network_available = !is_disconnected (); + network_changed (); + }); + } + + public bool is_disconnected () { + var host = "www.google.com"; + + try { + var resolver = GLib.Resolver.get_default (); + var addresses = resolver.lookup_by_name (host, null); + var address = addresses.nth_data (0); + if (address == null) { + return false; + } + } catch (Error e) { + debug ("%s\n", e.message); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/src/Views/Today.vala b/src/Views/Today.vala index 980dd7db4..8f3da4e39 100644 --- a/src/Views/Today.vala +++ b/src/Views/Today.vala @@ -159,9 +159,9 @@ public class Views.Today : Adw.Bin { overdue_box.append (overdue_listbox_grid); overdue_revealer = new Gtk.Revealer () { - transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN + transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, + child = overdue_box }; - overdue_revealer.child = overdue_box; var today_label = new Gtk.Label (_("Today")) { halign = Gtk.Align.START, @@ -239,6 +239,50 @@ public class Views.Today : Adw.Bin { content_box.append (filters); content_box.append (listbox_placeholder_stack); + // var factory = new Gtk.SignalListItemFactory (); + // factory.setup.connect ((object) => { + // var list_item = object as Gtk.ListItem; + // if (list_item == null) { + // return; + // } + + // var label = new Layouts.ItemRow (Services.Store.instance ().get_item ("f5668249-cd01-41f2-803b-d0fe5fbe6120")); + // list_item.set_child (label); + // }); + + // factory.bind.connect ((object) => { + // var list_item = object as Gtk.ListItem; + // if (list_item == null) { + // return; + // } + + // var label = list_item.child as Layouts.ItemRow; + // if (label == null) { + // return; + // } + + // string label_value = (string) list_item.item; + // label.set_label (label_value); + // }); + + // int index = 1; + // var string_model = new Gtk.StringList ({ "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3", "Default Item 1", "Default Item 2", "Default Item 3" }); + // var model = new Gtk.NoSelection (string_model); + + // var list_view = new Gtk.ListView (model, factory); + + // var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + + // var add_button = new Gtk.Button.with_label (_("Add")); + + // box.append (add_button); + // box.append (list_view); + + // add_button.clicked.connect (() => { + // string_model.append (@"New Item $index"); + // index++; + // }); + var content_clamp = new Adw.Clamp () { maximum_size = 1024, tightening_threshold = 800, @@ -634,8 +678,19 @@ public class Views.Today : Adw.Bin { } } + Gee.HashMap labels_map = new Gee.HashMap (); + Gee.ArrayList labels_list = new Gee.ArrayList (); + foreach (Layouts.ItemRow item_row in items.values) { + foreach (Objects.Label label in item_row.item.labels) { + if (!labels_map.has_key (label.id)) { + labels_map[label.id] = label; + labels_list.add (labels_map[label.id]); + } + } + } + var dialog = new Dialogs.LabelPicker (); - // TODO: dialog.add_labels (SourceType.ALL); + dialog.add_labels_list (labels_list); dialog.labels = _labels; dialog.present (Planify._instance.main_window); diff --git a/src/Widgets/SourceRow.vala b/src/Widgets/SourceRow.vala index cb34ed290..94e6ecf8c 100644 --- a/src/Widgets/SourceRow.vala +++ b/src/Widgets/SourceRow.vala @@ -108,12 +108,15 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { margin_end = 3 }; + var reorder = new Widgets.ReorderChild (card, this); + main_revealer = new Gtk.Revealer () { transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, - child = card + child = reorder }; - + child = main_revealer; + reorder.build_drag_and_drop (); Timeout.add (main_revealer.transition_duration, () => { main_revealer.reveal_child = true; @@ -133,6 +136,28 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { popover.popdown (); source.delete_source (Planify._instance.main_window); }); + + reorder.on_drop_end.connect ((listbox) => { + update_views_order (listbox); + }); + } + + private void update_views_order (Gtk.ListBox listbox) { + unowned Widgets.SourceRow? row = null; + var row_index = 0; + + do { + row = (Widgets.SourceRow) listbox.get_row_at_index (row_index); + + if (row != null) { + row.source.child_order = row_index; + row.source.save (); + } + + row_index++; + } while (row != null); + + Services.EventBus.get_default ().update_sources_position (); } public void hide_destroy () { diff --git a/src/Widgets/SyncButton.vala b/src/Widgets/SyncButton.vala index fc64d438d..ccc350bdb 100644 --- a/src/Widgets/SyncButton.vala +++ b/src/Widgets/SyncButton.vala @@ -66,14 +66,13 @@ public class Widgets.SyncButton : Adw.Bin { clicked (); }); - var network_monitor = GLib.NetworkMonitor.get_default (); - network_monitor.network_changed.connect (() => { + Services.NetworkMonitor.instance ().network_changed.connect (() => { network_available (); }); } private void network_available () { - if (GLib.NetworkMonitor.get_default ().network_available) { + if (Services.NetworkMonitor.instance ().network_available) { stack.visible_child_name = "sync"; } else { stack.visible_child_name = "error"; diff --git a/src/meson.build b/src/meson.build index d43b1406c..c8ffd6ac1 100644 --- a/src/meson.build +++ b/src/meson.build @@ -19,7 +19,8 @@ sources = files( 'Services/TimeMonitor.vala', 'Services/DBusServer.vala', 'Services/Backups.vala', - 'Services/Migrate.vala', + 'Services/MigrateFromPlanner.vala', + 'Services/NetworkMonitor.vala', 'Services/CalendarEvents/CalendarEvents.vala', 'Services/CalendarEvents/DateIterator.vala', From b710a606c899866d48f2233dcb6ca945afb72684 Mon Sep 17 00:00:00 2001 From: Alain Date: Thu, 25 Jul 2024 19:23:46 -0500 Subject: [PATCH 11/14] feat: add error view --- core/Layouts/HeaderItem.vala | 15 +- core/Objects/Item.vala | 29 +-- core/Objects/Label.vala | 7 - core/Objects/Project.vala | 26 ++- core/Objects/Source.vala | 25 +-- core/Services/CalDAV/Core.vala | 175 ++++++++---------- core/Services/CalDAV/Providers/Nextcloud.vala | 22 ++- core/Services/Database.vala | 34 +++- core/Services/EventBus.vala | 3 +- core/Services/Store.vala | 42 +---- core/Services/Todoist.vala | 1 + core/Util/Util.vala | 15 +- .../ProjectPicker/ProjectPickerPopover.vala | 2 +- data/io.github.alainm23.planify.gresource.xml | 3 + .../cross-large-circle-outline-symbolic.svg | 2 + src/Dialogs/ErrorDialog.vala | 43 +++++ src/Dialogs/Preferences/Pages/Backup.vala | 2 +- .../Preferences/PreferencesWindow.vala | 81 ++++---- src/Dialogs/Project.vala | 24 ++- .../ProjectPicker/ProjectPickerSourceRow.vala | 8 +- src/Layouts/ItemBoard.vala | 6 +- src/Layouts/ItemRow.vala | 28 ++- src/Layouts/ItemSidebarView.vala | 2 +- src/Layouts/ProjectRow.vala | 17 +- src/Layouts/SidebarSourceRow.vala | 3 +- src/MainWindow.vala | 20 +- src/Views/Label/LabelSourceRow.vala | 6 +- src/Widgets/Attachments.vala | 2 +- src/Widgets/ErrorView.vala | 137 ++++++++++++++ src/Widgets/SourceRow.vala | 6 +- src/meson.build | 2 + 31 files changed, 520 insertions(+), 268 deletions(-) create mode 100644 data/resources/icons/cross-large-circle-outline-symbolic.svg create mode 100644 src/Dialogs/ErrorDialog.vala create mode 100644 src/Widgets/ErrorView.vala diff --git a/core/Layouts/HeaderItem.vala b/core/Layouts/HeaderItem.vala index 1c164ba6f..615933d4d 100644 --- a/core/Layouts/HeaderItem.vala +++ b/core/Layouts/HeaderItem.vala @@ -150,6 +150,12 @@ public class Layouts.HeaderItem : Adw.Bin { } } } + + public int listbox_margin_top { + set { + listbox.margin_top = value; + } + } public HeaderItem (string? header_title = null) { Object ( @@ -159,9 +165,10 @@ public class Layouts.HeaderItem : Adw.Bin { construct { header_label = new Gtk.Label (null) { - halign = Gtk.Align.START + halign = Gtk.Align.START, + ellipsize = Pango.EllipsizeMode.END }; - + header_label.add_css_class ("h4"); header_label.add_css_class ("heading"); @@ -175,7 +182,9 @@ public class Layouts.HeaderItem : Adw.Bin { child = subheader_label }; - var header_label_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + var header_label_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { + valign = Gtk.Align.CENTER + }; header_label_box.append (header_label); header_label_box.append (subheader_revealer); diff --git a/core/Objects/Item.vala b/core/Objects/Item.vala index 73a1513a8..ac69feffd 100644 --- a/core/Objects/Item.vala +++ b/core/Objects/Item.vala @@ -1317,7 +1317,7 @@ public class Objects.Item : Objects.BaseObject { public void copy_clipboard () { Gdk.Clipboard clipboard = Gdk.Display.get_default ().get_clipboard (); clipboard.set_text ("[%s]%s%s\n------------------------------------------\n%s".printf (checked ? "x" : " ", get_format_date (this), content, description)); - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Task copied to clipboard")) ); } @@ -1359,22 +1359,25 @@ public class Objects.Item : Objects.BaseObject { } else if (project.source_type == SourceType.TODOIST) { loading = true; Services.Todoist.get_default ().delete.begin (this, (obj, res) => { - if (Services.Todoist.get_default ().delete.end (res).status) { + HttpResponse response = Services.Todoist.get_default ().delete.end (res); + loading = false; + + if (response.status) { Services.Store.instance ().delete_item (this); + } else { + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } - - loading = false; }); } else if (project.source_type == SourceType.CALDAV) { loading = true; Services.CalDAV.Core.get_default ().delete_task.begin (this, (obj, res) => { - if (Services.CalDAV.Core.get_default ().delete_task.end (res).status) { - Services.Store.instance ().delete_item (this); - foreach (Objects.Item subitem in this.items) { - subitem.delete_item (); - } + HttpResponse response = Services.CalDAV.Core.get_default ().delete_task.end (res); + loading = false; - loading = false; + if (response.status) { + Services.Store.instance ().delete_item (this); + } else { + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } }); } @@ -1510,6 +1513,8 @@ public class Objects.Item : Objects.BaseObject { if (response.status) { _move (project.id, _section_id); + } else { + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } }); } else if (project.source_type == SourceType.CALDAV) { @@ -1520,6 +1525,8 @@ public class Objects.Item : Objects.BaseObject { if (response.status) { _move (project.id, _section_id); + } else { + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } }); } @@ -1537,7 +1544,7 @@ public class Objects.Item : Objects.BaseObject { Services.Store.instance ().move_item (this); Services.EventBus.get_default ().item_moved (this, old_project_id, old_section_id, old_parent_id); Services.EventBus.get_default ().drag_n_drop_active (old_project_id, false); - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Task moved to %s".printf (project.name))) ); } diff --git a/core/Objects/Label.vala b/core/Objects/Label.vala index c10d6c86e..e7894f12a 100644 --- a/core/Objects/Label.vala +++ b/core/Objects/Label.vala @@ -67,13 +67,6 @@ public class Objects.Label : Objects.BaseObject { public signal void label_count_updated (); construct { - deleted.connect (() => { - Idle.add (() => { - Services.Store.instance ().label_deleted (this); - return false; - }); - }); - Services.Store.instance ().item_added.connect ((item) => { if (item.get_label (id) != null) { _label_count = update_label_count (); diff --git a/core/Objects/Project.vala b/core/Objects/Project.vala index d8ba99b72..2b561b894 100644 --- a/core/Objects/Project.vala +++ b/core/Objects/Project.vala @@ -761,8 +761,8 @@ public class Objects.Project : Objects.BaseObject { public void share_markdown () { Gdk.Clipboard clipboard = Gdk.Display.get_default ().get_clipboard (); clipboard.set_text (to_markdown ()); - Services.EventBus.get_default ().send_notification ( - Util.get_default ().create_toast (_("The project was copied to the Clipboard.")) + Services.EventBus.get_default ().send_toast ( + Util.get_default ().create_toast (_("The project was copied to the Clipboard."), 0) ); } @@ -808,8 +808,8 @@ public class Objects.Project : Objects.BaseObject { dialog.set_response_appearance ("delete", Adw.ResponseAppearance.DESTRUCTIVE); dialog.present (window); - dialog.response.connect ((response) => { - if (response == "delete") { + dialog.response.connect ((_response) => { + if (_response == "delete") { loading = true; if (source_type == SourceType.LOCAL) { Services.Store.instance ().delete_project (this); @@ -818,22 +818,28 @@ public class Objects.Project : Objects.BaseObject { dialog.set_response_enabled ("delete", false); Services.Todoist.get_default ().delete.begin (this, (obj, res) => { - if (Services.Todoist.get_default ().delete.end (res).status) { + HttpResponse response = Services.Todoist.get_default ().delete.end (res); + loading = false; + + if (response.status) { Services.Store.instance ().delete_project (this); + } else { + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } - - loading = false; }); } else if (source_type == SourceType.CALDAV) { dialog.set_response_enabled ("cancel", false); dialog.set_response_enabled ("delete", false); Services.CalDAV.Core.get_default ().delete_tasklist.begin (this, (obj, res) => { - if (Services.CalDAV.Core.get_default ().delete_tasklist.end (res)) { + HttpResponse response = Services.CalDAV.Core.get_default ().delete_tasklist.end (res); + loading = false; + + if (response.status) { Services.Store.instance ().delete_project (this); + } else { + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } - - loading = false; }); } } diff --git a/core/Objects/Source.vala b/core/Objects/Source.vala index 8f6d773b5..bdd49aa1c 100644 --- a/core/Objects/Source.vala +++ b/core/Objects/Source.vala @@ -28,6 +28,7 @@ public class Objects.Source : Objects.BaseObject { public bool sync_server { get; set; default = false; } public string last_sync { get; set; default = ""; } public Objects.SourceData data { get; set; } + public string display_name { get; set; default = ""; } Objects.SourceTodoistData _todoist_data; public Objects.SourceTodoistData todoist_data { @@ -47,19 +48,7 @@ public class Objects.Source : Objects.BaseObject { public string header_text { get { - if (source_type == SourceType.LOCAL) { - return _("On This Computer"); - } - - if (source_type == SourceType.TODOIST) { - return todoist_data.user_email; - } - - if (source_type == SourceType.CALDAV) { - return caldav_data.user_email; - } - - return ""; + return display_name; } } @@ -122,16 +111,18 @@ public class Objects.Source : Objects.BaseObject { _run_server (); server_timeout = Timeout.add_seconds (15 * 60, () => { - _run_server (); - + if (sync_server) { + _run_server (); + } + return true; }); } private void _run_server () { - if (sync_server && source_type == SourceType.TODOIST) { + if (source_type == SourceType.TODOIST) { Services.Todoist.get_default ().sync.begin (this); - } else if (sync_server && source_type == SourceType.CALDAV) { + } else if (source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().sync.begin (this); } } diff --git a/core/Services/CalDAV/Core.vala b/core/Services/CalDAV/Core.vala index 9ff1cf713..268658e3c 100644 --- a/core/Services/CalDAV/Core.vala +++ b/core/Services/CalDAV/Core.vala @@ -71,7 +71,7 @@ public class Services.CalDAV.Core : GLib.Object { print_root ("login", (string) stream.get_data ()); print ("login status_code: %s\n".printf (message.status_code.to_string ())); - if (message.status_code == 207) { + if (message.get_status () == Soup.Status.MULTI_STATUS) { var source = new Objects.Source (); source.id = Util.get_default ().generate_id (); source.source_type = SourceType.CALDAV; @@ -103,9 +103,12 @@ public class Services.CalDAV.Core : GLib.Object { return response; } - public async void add_caldav_account (Objects.Source source) { + public async HttpResponse add_caldav_account (Objects.Source source, GLib.Cancellable cancellable) { + HttpResponse response = new HttpResponse (); + if (!providers_map.has_key (source.caldav_data.caldav_type.to_string ())) { - return; + response.error = _("No Provider Available"); + return response; } Services.CalDAV.Providers.Base provider = providers_map.get (source.caldav_data.caldav_type.to_string ()); @@ -118,7 +121,7 @@ public class Services.CalDAV.Core : GLib.Object { first_sync_started (); try { - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, cancellable); print_root ("first_sync", (string) stream.get_data ()); GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); @@ -126,13 +129,15 @@ public class Services.CalDAV.Core : GLib.Object { Services.Store.instance ().insert_source (source); - yield get_all_tasklist (source); + yield get_all_tasklist (source, cancellable); } catch (Error e) { debug (e.message); } + + return response; } - public async void get_all_tasklist (Objects.Source source) { + public async void get_all_tasklist (Objects.Source source, GLib.Cancellable cancellable) { if (!providers_map.has_key (source.caldav_data.caldav_type.to_string ())) { return; } @@ -144,15 +149,10 @@ public class Services.CalDAV.Core : GLib.Object { var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); - message.request_headers.append ("depth", "1"); - message.request_headers.append ("Host", "radicale.xlumurb.eu"); - message.request_headers.append ("User-Agent", "Planify"); - message.request_headers.append ("Content-Length", "629"); - message.request_headers.append ("Content-Type", "application/xml; charset=utf-8"); message.set_request_body_from_bytes ("application/xml", new Bytes (provider.TASKLIST_REQUEST.data)); try { - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, cancellable); print_root ("get_all_tasklist", (string) stream.get_data ()); print ("login status_code: %s\n".printf (message.status_code.to_string ())); @@ -162,7 +162,7 @@ public class Services.CalDAV.Core : GLib.Object { foreach (Objects.Project project in projects) { Services.Store.instance ().insert_project (project); - // yield get_all_tasks_by_tasklist (project); + yield get_all_tasks_by_tasklist (project); } first_sync_finished (); @@ -324,11 +324,17 @@ public class Services.CalDAV.Core : GLib.Object { } public async void sync (Objects.Source source) { + if (!providers_map.has_key (source.caldav_data.caldav_type.to_string ())) { + return; + } + + Services.CalDAV.Providers.Base provider = providers_map.get (source.caldav_data.caldav_type.to_string ()); + var url = "%s/calendars/%s/".printf (source.caldav_data.server_url, source.caldav_data.username); var message = new Soup.Message ("PROPFIND", url); message.request_headers.append ("Authorization", "Basic %s".printf (source.caldav_data.credentials)); message.request_headers.append ("Depth", "1"); - // message.set_request_body_from_bytes ("application/xml", new Bytes (Services.CalDAV.Providers.Nextcloud.TASKLIST_REQUEST.data)); + message.set_request_body_from_bytes ("application/xml", new Bytes (provider.TASKLIST_REQUEST.data)); source.sync_started (); @@ -428,21 +434,19 @@ public class Services.CalDAV.Core : GLib.Object { Services.Store.instance ().checked_toggled (item, old_checked); } } else { + var new_item = new Objects.Item.from_vtodo (vtodo, ics); + new_item.project_id = project.id; + string parent_id = Util.find_string_value ("RELATED-TO", vtodo); if (parent_id != "") { Objects.Item? parent_item = Services.Store.instance ().get_item (parent_id); + if (parent_item != null) { - var new_item = new Objects.Item.from_vtodo (vtodo, ics); - new_item.project_id = project.id; parent_item.add_item_if_not_exists (new_item); } else { - var new_item = new Objects.Item.from_vtodo (vtodo, ics); - new_item.project_id = project.id; project.add_item_if_not_exists (new_item); } } else { - var new_item = new Objects.Item.from_vtodo (vtodo, ics); - new_item.project_id = project.id; project.add_item_if_not_exists (new_item); } } @@ -477,28 +481,6 @@ public class Services.CalDAV.Core : GLib.Object { return return_value; } - // TODO - private async void add_project_if_not_exists (GXml.DomElement element, Gee.HashMap labels_map) { - if (is_vtodo_calendar (element)) { - Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); - if (project == null) { - project = new Objects.Project.from_caldav_xml (element); - - Services.Store.instance ().insert_project (project); - yield get_all_tasks_by_tasklist (project); - } else { - project.update_from_xml (element); - Services.Store.instance ().update_project (project); - yield update_all_tasks_by_tasklist (project, labels_map); - } - } else if (is_deleted_calendar (element)) { - Objects.Project? project = Services.Store.instance ().get_project (get_tasklist_id_from_url (element)); - if (project != null) { - Services.Store.instance ().delete_project (project); - } - } - } - public string get_tasklist_id_from_url (GXml.DomElement element) { GXml.DomElement href = element.get_elements_by_tag_name ("d:href").get_element (0); string[] parts = href.text_content.split ("/"); @@ -541,84 +523,83 @@ public class Services.CalDAV.Core : GLib.Object { * Tasklist */ - public async bool add_tasklist (Objects.Project project) { + public async HttpResponse add_tasklist (Objects.Project project) { var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("MKCOL", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.CREATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); - bool status = false; + HttpResponse response = new HttpResponse (); try { - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - status = true; + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + + if (message.get_status () == Soup.Status.CREATED) { + response.status = true; + } else { + response.error_code = (int) message.status_code; + response.error = (string) stream.get_data (); + } } catch (Error e) { + response.error_code = e.code; + response.error = e.message; debug (e.message); } - return status; + return response; } - public async bool update_tasklist (Objects.Project project) { + public async HttpResponse update_tasklist (Objects.Project project) { var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("PROPPATCH", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.UPDATE_TASKLIST_REQUEST.printf (project.name, project.color_hex)).data)); - bool status = false; + HttpResponse response = new HttpResponse (); try { - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - status = true; + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + + if (message.get_status () == Soup.Status.MULTI_STATUS) { + response.status = true; + } else { + response.error_code = (int) message.status_code; + response.error = (string) stream.get_data (); + } } catch (Error e) { + response.error_code = e.code; + response.error = e.message; debug (e.message); } - return status; + return response; } - public async bool delete_tasklist (Objects.Project project) { + public async HttpResponse delete_tasklist (Objects.Project project) { var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); var message = new Soup.Message ("DELETE", url); message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); - bool status = false; - - try { - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - status = true; - } catch (Error e) { - debug (e.message); - } - return status; - } - - public async void refresh_tasklist (Objects.Project project) { - var url = "%s/calendars/%s/%s/".printf (project.source.caldav_data.server_url, project.source.caldav_data.username, project.id); - - var message = new Soup.Message ("PROPFIND", url); - message.request_headers.append ("Authorization", "Basic %s".printf (project.source.caldav_data.credentials)); - // message.set_request_body_from_bytes ("application/xml", new Bytes ((Services.CalDAV.Providers.Nextcloud.TASKLIST_REQUEST).data)); + HttpResponse response = new HttpResponse (); try { - GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - - print_root ("refresh_tasklist", (string) stream.get_data ()); - - // GXml.DomDocument doc = new GXml.Document.from_string ((string) stream.get_data ()); - // GXml.DomHTMLCollection response = doc.get_elements_by_tag_name ("d:response"); - - // // Categories - // Gee.HashMap labels_map = new Gee.HashMap (); + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - // foreach (GXml.DomElement element in response) { - // yield add_project_if_not_exists (element, labels_map); - // } + if (message.get_status () == Soup.Status.NO_CONTENT) { + response.status = true; + } else { + response.error_code = (int) message.status_code; + response.error = (string) stream.get_data (); + } } catch (Error e) { + response.error_code = e.code; + response.error = e.message; debug (e.message); } + + return response; } private async void update_tasklist_detail (Objects.Project project) { @@ -699,7 +680,7 @@ public class Services.CalDAV.Core : GLib.Object { try { yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - if (update ? message.status_code == 204 : message.status_code == 201) { + if (update ? message.get_status () == Soup.Status.NO_CONTENT : message.get_status () == Soup.Status.CREATED) { response.status = true; item.extra_data = Util.generate_extra_data (ics, "", item.to_vtodo ()); } @@ -720,18 +701,17 @@ public class Services.CalDAV.Core : GLib.Object { try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); - print_root ("delete_task", (string) stream.get_data ()); - if (message.status_code == 204) { + if (message.get_status () == Soup.Status.NO_CONTENT) { response.status = true; } else { response.error_code = (int) message.status_code; response.error = (string) stream.get_data (); - print ("Code: %d, Error: %s\n".printf (response.error_code, response.error)); } } catch (Error e) { - debug (e.message); + response.error_code = e.code; + response.error = e.message; } return response; @@ -751,11 +731,15 @@ public class Services.CalDAV.Core : GLib.Object { HttpResponse response = new HttpResponse (); try { - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + print_root ("complete_item", (string) stream.get_data ()); - if (message.status_code == 204) { + if (message.get_status () == Soup.Status.NO_CONTENT) { response.status = true; item.extra_data = Util.generate_extra_data (ics, "", body); + } else { + response.error_code = (int) message.status_code; + response.error = (string) stream.get_data (); } } catch (Error e) { debug (e.message); @@ -777,13 +761,18 @@ public class Services.CalDAV.Core : GLib.Object { HttpResponse response = new HttpResponse (); try { - yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); + print_root ("move_task", (string) stream.get_data ()); - if (message.status_code == 201 || message.status_code == 204) { + if (message.get_status () == Soup.Status.CREATED || message.get_status () == Soup.Status.NO_CONTENT) { response.status = true; + } else { + response.error_code = (int) message.status_code; + response.error = (string) stream.get_data (); } } catch (Error e) { debug (e.message); + response.error = e.message; } return response; @@ -828,7 +817,7 @@ public class Services.CalDAV.Core : GLib.Object { } private void print_root (string fuction, string data) { - print (fuction + "\n"); - print (data + "\n"); + debug (fuction + "\n"); + debug (data + "\n"); } } diff --git a/core/Services/CalDAV/Providers/Nextcloud.vala b/core/Services/CalDAV/Providers/Nextcloud.vala index 5a6301890..c3d1ba140 100644 --- a/core/Services/CalDAV/Providers/Nextcloud.vala +++ b/core/Services/CalDAV/Providers/Nextcloud.vala @@ -290,11 +290,25 @@ public class Services.CalDAV.Providers.Nextcloud : Services.CalDAV.Providers.Bas } public override void set_user_data (GXml.DomDocument doc, Objects.Source source) { - GXml.DomElement d_displayname = doc.get_elements_by_tag_name ("d:displayname").get_element (0); - GXml.DomElement d_email = doc.get_elements_by_tag_name ("s:email-address").get_element (0); + if (doc.get_elements_by_tag_name ("d:displayname").length > 0) { + source.caldav_data.user_displayname = doc.get_elements_by_tag_name ("d:displayname").get_element (0).text_content; + } + + if (doc.get_elements_by_tag_name ("s:email-address").length > 0) { + source.caldav_data.user_email = doc.get_elements_by_tag_name ("s:email-address").get_element (0).text_content; + } + + if (source.caldav_data.user_email != "") { + source.display_name = source.caldav_data.user_email; + return; + } + + if (source.caldav_data.user_displayname != "") { + source.display_name = source.caldav_data.user_displayname; + return; + } - source.caldav_data.user_displayname = d_displayname.text_content; - source.caldav_data.user_email = d_email.text_content; + source.display_name = _("Nextcloud"); } public override string get_all_taskslist_url (string server_url, string username) { diff --git a/core/Services/Database.vala b/core/Services/Database.vala index e23932ab3..a056ae764 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -233,6 +233,7 @@ public class Services.Database : GLib.Object { CREATE TABLE IF NOT EXISTS Sources ( id TEXT PRIMARY KEY, source_type TEXT NOT NULL, + display_name TEXT, added_at TEXT, updated_at TEXT, is_visible INTEGER, @@ -477,17 +478,18 @@ public class Services.Database : GLib.Object { 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.added_at = stmt.column_text (2); - return_value.updated_at = stmt.column_text (3); - return_value.is_visible = get_parameter_bool (stmt, 4); - return_value.child_order = stmt.column_int (5); - return_value.sync_server = get_parameter_bool (stmt, 6); - return_value.last_sync = stmt.column_text (7); + 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 (8)); + 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 (8)); + return_value.data = new Objects.SourceCalDAVData.from_json (stmt.column_text (9)); } return return_value; @@ -497,15 +499,16 @@ public class Services.Database : GLib.Object { Sqlite.Statement stmt; sql = """ - INSERT OR IGNORE INTO Sources (id, source_type, added_at, + 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, $added_at, + 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); @@ -544,6 +547,7 @@ public class Services.Database : GLib.Object { sql = """ UPDATE Sources SET source_type=$source_type, + display_name=$display_name, updated_at=$updated_at, is_visible=$is_visible, child_order=$child_order, @@ -555,6 +559,7 @@ public class Services.Database : GLib.Object { 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); @@ -1990,6 +1995,7 @@ public class Services.Database : GLib.Object { 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"); @@ -2005,6 +2011,14 @@ public class Services.Database : GLib.Object { 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/core/Services/EventBus.vala b/core/Services/EventBus.vala index b6823d31f..a6a4c21de 100644 --- a/core/Services/EventBus.vala +++ b/core/Services/EventBus.vala @@ -81,7 +81,8 @@ public class Services.EventBus : Object { public signal void mobile_mode_change (); // Notifications - public signal void send_notification (Adw.Toast toast); + public signal void send_toast (Adw.Toast toast); + public signal void send_error_toast (int error_code, string error_message); // Multi Select public bool multi_select_enabled = false; diff --git a/core/Services/Store.vala b/core/Services/Store.vala index 0308b055b..e70eb42e6 100644 --- a/core/Services/Store.vala +++ b/core/Services/Store.vala @@ -133,38 +133,6 @@ public class Services.Store : GLib.Object { } } - construct { - source_deleted.connect ((source) => { - if (_sources.remove (source)) { - debug ("Source Removed: %s", source.header_text); - } - }); - - label_deleted.connect ((label) => { - if (_labels.remove (label)) { - debug ("Label Removed: %s", label.name); - } - }); - - project_deleted.connect ((project) => { - if (_projects.remove (project)) { - debug ("Project Removed: %s", project.name); - } - }); - - // item_deleted.connect ((item) => { - // if (_items.remove (item)) { - // debug ("item Removed: %s", item.content); - // } - // }); - - reminder_deleted.connect ((reminder) => { - if (_reminders.remove (reminder)) { - debug ("Reminder Removed: %s", reminder.id.to_string ()); - } - }); - } - public bool is_database_empty () { return projects.size <= 0; } @@ -543,7 +511,7 @@ public class Services.Store : GLib.Object { public void delete_item (Objects.Item item) { if (Services.Database.get_default ().delete_item (item)) { - foreach (Objects.Item subitem in item.items) { + foreach (Objects.Item subitem in get_subitems (item)) { delete_item (subitem); } @@ -964,6 +932,8 @@ public class Services.Store : GLib.Object { public void delete_label (Objects.Label label) { if (Services.Database.get_default ().delete_label (label)) { label.deleted (); + label_deleted (label); + _labels.remove (label); } } @@ -1129,8 +1099,8 @@ public class Services.Store : GLib.Object { // Reminders public void insert_reminder (Objects.Reminder reminder) { if (Services.Database.get_default ().insert_reminder (reminder)) { - reminder_added (reminder); reminders.add (reminder); + reminder_added (reminder); reminder.item.reminder_added (reminder); } } @@ -1138,7 +1108,11 @@ public class Services.Store : GLib.Object { public void delete_reminder (Objects.Reminder reminder) { if (Services.Database.get_default ().delete_reminder (reminder)) { reminder.deleted (); + reminder_deleted (reminder); + _reminders.remove (reminder); + reminder.item.reminder_deleted (reminder); + } } diff --git a/core/Services/Todoist.vala b/core/Services/Todoist.vala index c39a2cae9..a17218fbc 100644 --- a/core/Services/Todoist.vala +++ b/core/Services/Todoist.vala @@ -121,6 +121,7 @@ public class Services.Todoist : GLib.Object { todoist_data.user_email = user_object.get_string_member ("email"); todoist_data.user_is_premium = user_object.get_boolean_member ("is_premium"); + source.display_name = user_object.get_string_member ("email"); source.data = todoist_data; Services.Store.instance ().insert_source (source); diff --git a/core/Util/Util.vala b/core/Util/Util.vala index 4473065c7..efdaa746a 100644 --- a/core/Util/Util.vala +++ b/core/Util/Util.vala @@ -571,6 +571,7 @@ public class Util : GLib.Object { Objects.Source local_source = new Objects.Source (); local_source.id = SourceType.LOCAL.to_string (); local_source.source_type = SourceType.LOCAL; + local_source.display_name = _("On This Computer"); Services.Store.instance ().insert_source (local_source); return local_source; } @@ -900,7 +901,7 @@ We hope you’ll enjoy using Planify!"""); yield move_backend_type_item (subitem, new_item.project, new_item.id); } - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( create_toast (_("Task moved to %s".printf (new_item.project.name))) ); @@ -978,7 +979,7 @@ We hope you’ll enjoy using Planify!"""); } if (notify) { - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Task duplicated")) ); } @@ -1014,7 +1015,7 @@ We hope you’ll enjoy using Planify!"""); section.sensitive = true; if (notify) { - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Section duplicated")) ); } @@ -1040,7 +1041,7 @@ We hope you’ll enjoy using Planify!"""); project.loading = false; - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Project duplicated")) ); } else if (project.source_type == SourceType.TODOIST) { @@ -1054,9 +1055,9 @@ We hope you’ll enjoy using Planify!"""); } else if (project.source_type == SourceType.CALDAV) { new_project.id = Util.get_default ().generate_id (new_project); - bool status = yield Services.CalDAV.Core.get_default ().add_tasklist (new_project); + HttpResponse response = yield Services.CalDAV.Core.get_default ().add_tasklist (new_project); - if (status) { + if (response.status) { Services.Store.instance ().insert_project (new_project); foreach (Objects.Item item in project.items) { @@ -1065,7 +1066,7 @@ We hope you’ll enjoy using Planify!"""); project.loading = false; - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Project duplicated")) ); } diff --git a/core/Widgets/ProjectPicker/ProjectPickerPopover.vala b/core/Widgets/ProjectPicker/ProjectPickerPopover.vala index 54c6b8aac..a8d102d2b 100644 --- a/core/Widgets/ProjectPicker/ProjectPickerPopover.vala +++ b/core/Widgets/ProjectPicker/ProjectPickerPopover.vala @@ -31,7 +31,7 @@ public class Widgets.ProjectPicker.ProjectPickerPopover : Gtk.Popover { foreach (Objects.Source source in Services.Store.instance ().sources) { if (!sources_hashmap.has_key (source.id)) { - sources_hashmap[source.id] = new Layouts.HeaderItem (source.header_text) { + sources_hashmap[source.id] = new Layouts.HeaderItem (source.display_name) { reveal_child = Services.Store.instance ().get_projects_by_source (source.id).size > 0, card = true, show_separator = false diff --git a/data/io.github.alainm23.planify.gresource.xml b/data/io.github.alainm23.planify.gresource.xml index 15a9ebc76..6dcc150d3 100644 --- a/data/io.github.alainm23.planify.gresource.xml +++ b/data/io.github.alainm23.planify.gresource.xml @@ -92,6 +92,7 @@ resources/icons/size-vertically-symbolic.svg resources/icons/info-outline-symbolic.svg resources/icons/rotation-edit-symbolic.svg + resources/icons/cross-large-circle-outline-symbolic.svg @@ -158,6 +159,7 @@ resources/icons/size-vertically-symbolic.svg resources/icons/info-outline-symbolic.svg resources/icons/rotation-edit-symbolic.svg + resources/icons/cross-large-circle-outline-symbolic.svg @@ -224,5 +226,6 @@ resources/icons/size-vertically-symbolic.svg resources/icons/info-outline-symbolic.svg resources/icons/rotation-edit-symbolic.svg + resources/icons/cross-large-circle-outline-symbolic.svg diff --git a/data/resources/icons/cross-large-circle-outline-symbolic.svg b/data/resources/icons/cross-large-circle-outline-symbolic.svg new file mode 100644 index 000000000..1b187b191 --- /dev/null +++ b/data/resources/icons/cross-large-circle-outline-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/src/Dialogs/ErrorDialog.vala b/src/Dialogs/ErrorDialog.vala new file mode 100644 index 000000000..5d05c4b31 --- /dev/null +++ b/src/Dialogs/ErrorDialog.vala @@ -0,0 +1,43 @@ +/* +* 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 Dialogs.ErrorDialog : Adw.Dialog { + public int error_code { get; construct; } + public string error_message { get; construct; } + + public ErrorDialog (int error_code, string error_message) { + Object ( + error_code: error_code, + error_message: error_message, + content_width: 375, + content_height: 450 + ); + } + + construct { + var error_view = new Widgets.ErrorView () { + error_code = error_code, + error_message = error_message, + }; + + child = error_view; + } +} diff --git a/src/Dialogs/Preferences/Pages/Backup.vala b/src/Dialogs/Preferences/Pages/Backup.vala index b84077008..40cf07e79 100644 --- a/src/Dialogs/Preferences/Pages/Backup.vala +++ b/src/Dialogs/Preferences/Pages/Backup.vala @@ -150,7 +150,7 @@ public class Dialogs.Preferences.Pages.Backup : Adw.Bin { private Gtk.Widget get_import_page (Objects.Backup backup) { var title = new Gtk.Label (_("Import Overview")) { halign = CENTER, - css_classes = { "h1" } + css_classes = { "title-1" } }; var subtitle = new Gtk.Label (backup.title) { halign = CENTER, diff --git a/src/Dialogs/Preferences/PreferencesWindow.vala b/src/Dialogs/Preferences/PreferencesWindow.vala index d184e8b63..3f213acf7 100644 --- a/src/Dialogs/Preferences/PreferencesWindow.vala +++ b/src/Dialogs/Preferences/PreferencesWindow.vala @@ -851,7 +851,8 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { var sources_group = new Layouts.HeaderItem (_("Sources")) { card = true, reveal = true, - margin_top = 12 + margin_top = 12, + listbox_margin_top = 6 }; sources_group.add_widget_end (add_source_button); @@ -945,9 +946,11 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { }; var email_label = new Gtk.Label (source.user_email) { - css_classes = { "dim-label" } + css_classes = { "dim-label" }, + margin_top = 6 }; + var user_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0) { margin_top = 24 }; @@ -955,17 +958,30 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { user_box.append (user_label); user_box.append (email_label); + if (source.source_type == SourceType.CALDAV) { + var url_label = new Gtk.Label (source.caldav_data.server_url) { + css_classes = { "dim-label" } + }; + user_box.append (url_label); + } + + var display_entry = new Adw.EntryRow () { + title = _("Display Name"), + text = source.display_name, + show_apply_button = true + }; + var sync_server_row = new Adw.SwitchRow (); sync_server_row.title = _("Sync Server"); sync_server_row.subtitle = _("Activate this setting so that Planify automatically synchronizes with your account account every 15 minutes"); sync_server_row.active = source.sync_server; - var last_sync_date = new GLib.DateTime.from_iso8601 ( - source.last_sync, new GLib.TimeZone.local () - ); - var last_sync_label = new Gtk.Label ( - Utils.Datetime.get_relative_date_from_date (last_sync_date) + Utils.Datetime.get_relative_date_from_date ( + new GLib.DateTime.from_iso8601 ( + source.last_sync, new GLib.TimeZone.local () + ) + ) ); var last_sync_row = new Adw.ActionRow (); @@ -977,6 +993,7 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { margin_top = 24 }; + default_group.add (display_entry); default_group.add (sync_server_row); default_group.add (last_sync_row); @@ -1016,6 +1033,11 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { } }); + display_entry.apply.connect (() => { + source.display_name = display_entry.text; + source.save (); + }); + return page; } @@ -1408,11 +1430,19 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { HttpResponse response = Services.CalDAV.Core.get_default ().login.end (res); if (response.status) { Objects.Source source = (Objects.Source) response.data_object.get_object (); - Services.CalDAV.Core.get_default ().add_caldav_account.begin (source); + Services.CalDAV.Core.get_default ().add_caldav_account.begin (source, cancellable, (obj, res) => { + response = Services.CalDAV.Core.get_default ().add_caldav_account.end (res); + + if (!response.status) { + login_button.is_loading = false; + cancel_button.visible = false; + show_message_error (response.error_code, response.error.strip ()); + } + }); } else { login_button.is_loading = false; cancel_button.visible = false; - show_message_error (_("Failed to login"), response.error.strip ()); + show_message_error (response.error_code, response.error.strip ()); } }); }); @@ -1437,36 +1467,15 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return scheme.has_prefix ("http"); } - private void show_message_error (string title, string error) { - var dialog = new Adw.AlertDialog (title, null); - - var textview = new Gtk.TextView () { - left_margin = 12, - top_margin = 12, - bottom_margin = 12, - right_margin = 12, - wrap_mode = Gtk.WrapMode.WORD - }; - textview.buffer.text = error; - textview.add_css_class ("monospace"); - textview.add_css_class ("error-message"); - - var textview_scrolled_window = new Gtk.ScrolledWindow () { - hscrollbar_policy = Gtk.PolicyType.NEVER, - hexpand = true, - vexpand = true, - child = textview, - width_request = 500, - height_request = 430 + private void show_message_error (int error_code, string error_message) { + var error_view = new Widgets.ErrorView () { + error_code = error_code, + error_message = error_message, }; - var textview_frame = new Gtk.Frame (null) { - child = textview_scrolled_window - }; + var page = new Adw.NavigationPage (error_view, ""); - dialog.add_response ("ok", _("Ok")); - dialog.extra_child = textview_frame; - dialog.present (Planify._instance.main_window); + push_subpage (page); } private Adw.NavigationPage get_backups_page () { diff --git a/src/Dialogs/Project.vala b/src/Dialogs/Project.vala index dfc3fffe7..b91dc227a 100644 --- a/src/Dialogs/Project.vala +++ b/src/Dialogs/Project.vala @@ -157,7 +157,7 @@ public class Dialogs.Project : Adw.Dialog { name_group.add (name_entry); name_group.add (emoji_switch_row); - source_selected_label = new Gtk.Label (project.source.header_text) { + source_selected_label = new Gtk.Label (project.source.display_name) { css_classes = { "dim-label" }, tooltip_text = project.source.subheader_text }; @@ -309,7 +309,7 @@ public class Dialogs.Project : Adw.Dialog { var source_row = new Adw.ActionRow () { activatable = true, - title = source.header_text, + title = source.display_name, subtitle = source.subheader_text }; @@ -319,7 +319,7 @@ public class Dialogs.Project : Adw.Dialog { source_row.activated.connect (() => { project.source_id = source.id; - source_selected_label.label = source.header_text; + source_selected_label.label = source.display_name; source_selected_label.tooltip_text = source.subheader_text; navigation_view.pop (); @@ -328,7 +328,7 @@ public class Dialogs.Project : Adw.Dialog { radio_button.toggled.connect (() => { project.source_id = source.id; - source_selected_label.label = source.header_text; + source_selected_label.label = source.display_name; source_selected_label.tooltip_text = source.subheader_text; navigation_view.pop (); @@ -388,9 +388,13 @@ public class Dialogs.Project : Adw.Dialog { }); } else if (project.source_type == SourceType.CALDAV) { Services.CalDAV.Core.get_default ().update_tasklist.begin (project, (obj, res) => { - if (Services.CalDAV.Core.get_default ().update_tasklist.end (res)) { + HttpResponse response = Services.CalDAV.Core.get_default ().update_tasklist.end (res); + + if (response.status) { Services.Store.instance ().update_project (project); hide_destroy (); + } else { + // Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } }); } @@ -411,15 +415,21 @@ public class Dialogs.Project : Adw.Dialog { project.id = response.data; Services.Store.instance ().insert_project (project); go_project (project.id); + } else { + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } }); } else if (project.source_type == SourceType.CALDAV) { project.id = Util.get_default ().generate_id (project); Services.CalDAV.Core.get_default ().add_tasklist.begin (project, (obj, res) => { - if (Services.CalDAV.Core.get_default ().add_tasklist.end (res)) { + HttpResponse response = Services.CalDAV.Core.get_default ().add_tasklist.end (res); + + if (response.status) { Services.Store.instance ().insert_project (project); Services.CalDAV.Core.get_default ().update_sync_token.begin (project); go_project (project.id); + } else { + // Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); } }); } @@ -427,7 +437,7 @@ public class Dialogs.Project : Adw.Dialog { public void go_project (string id) { Timeout.add (250, () => { - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Project added successfully!")) ); Services.EventBus.get_default ().pane_selected (PaneType.PROJECT, id); diff --git a/src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala b/src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala index 827dca633..9264f7cc7 100644 --- a/src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala +++ b/src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala @@ -33,7 +33,7 @@ public class Dialogs.ProjectPicker.ProjectPickerSourceRow : Gtk.ListBoxRow { construct { css_classes = { "no-selectable", "no-padding" }; - group = new Layouts.HeaderItem (source.header_text) { + group = new Layouts.HeaderItem (source.display_name) { card = true, reveal = true }; @@ -45,9 +45,11 @@ public class Dialogs.ProjectPicker.ProjectPickerSourceRow : Gtk.ListBoxRow { private void add_projects () { foreach (Objects.Project project in Services.Store.instance ().get_projects_by_source (source.id)) { - if (!project.is_inbox_project) { - group.add_child (new Dialogs.ProjectPicker.ProjectPickerRow (project)); + if (project.is_inbox_project || project.is_deck) { + continue ; } + + group.add_child (new Dialogs.ProjectPicker.ProjectPickerRow (project)); } } } \ No newline at end of file diff --git a/src/Layouts/ItemBoard.vala b/src/Layouts/ItemBoard.vala index 531760b4a..a825fbf13 100644 --- a/src/Layouts/ItemBoard.vala +++ b/src/Layouts/ItemBoard.vala @@ -523,7 +523,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { 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_notification (toast); + Services.EventBus.get_default ().send_toast (toast); } public override void update_request () { @@ -917,7 +917,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { if (item.project.sort_order != 0) { item.project.sort_order = 0; - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Order changed to 'Custom sort order'")) ); item.project.update_local (); @@ -1022,7 +1022,7 @@ public class Layouts.ItemBoard : Layouts.ItemBase { toast.priority = Adw.ToastPriority.HIGH; toast.timeout = 3; - Services.EventBus.get_default ().send_notification (toast); + Services.EventBus.get_default ().send_toast (toast); toast.dismissed.connect (() => { if (!main_revealer.reveal_child) { diff --git a/src/Layouts/ItemRow.vala b/src/Layouts/ItemRow.vala index a099b1370..da3052f65 100644 --- a/src/Layouts/ItemRow.vala +++ b/src/Layouts/ItemRow.vala @@ -1386,25 +1386,43 @@ public class Layouts.ItemRow : Layouts.ItemBase { checked_button.sensitive = false; is_loading = true; Services.Todoist.get_default ().complete_item.begin (item, (obj, res) => { - if (Services.Todoist.get_default ().complete_item.end (res).status) { + HttpResponse response = Services.Todoist.get_default ().complete_item.end (res); + if (response.status) { Services.Store.instance ().checked_toggled (item, old_checked); is_loading = false; checked_button.sensitive = true; + } else { + _complete_item_error (response); } }); } else if (item.project.source_type == SourceType.CALDAV) { checked_button.sensitive = false; is_loading = true; Services.CalDAV.Core.get_default ().complete_item.begin (item, (obj, res) => { - if (Services.CalDAV.Core.get_default ().complete_item.end (res).status) { + HttpResponse response = Services.CalDAV.Core.get_default ().complete_item.end (res); + if (response.status) { Services.Store.instance ().checked_toggled (item, old_checked); is_loading = false; checked_button.sensitive = true; + } else { + _complete_item_error (response); } }); } } + private void _complete_item_error (HttpResponse response) { + is_loading = false; + checked_button.sensitive = true; + checked_button.active = false; + + itemrow_box.remove_css_class ("complete-animation"); + content_label.remove_css_class ("dim-label"); + content_label.remove_css_class ("line-through"); + + Services.EventBus.get_default ().send_error_toast (response.error_code, response.error); + } + public void update_content (string content = "") { content_textview.buffer.text = content; } @@ -1439,7 +1457,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { Utils.Datetime.get_default_date_format_from_date (next_recurrency) )); var toast = Util.get_default ().create_toast (title, 3); - Services.EventBus.get_default ().send_notification (toast); + Services.EventBus.get_default ().send_toast (toast); } public void update_labels (Gee.HashMap new_labels) { @@ -1482,7 +1500,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { toast.priority = Adw.ToastPriority.HIGH; toast.timeout = 3; - Services.EventBus.get_default ().send_notification (toast); + Services.EventBus.get_default ().send_toast (toast); toast.dismissed.connect (() => { if (!main_revealer.reveal_child) { @@ -1681,7 +1699,7 @@ public class Layouts.ItemRow : Layouts.ItemBase { if (item.project.sort_order != 0) { item.project.sort_order = 0; - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Order changed to 'Custom sort order'")) ); item.project.update_local (); diff --git a/src/Layouts/ItemSidebarView.vala b/src/Layouts/ItemSidebarView.vala index 1a8f67111..6d8d954b2 100644 --- a/src/Layouts/ItemSidebarView.vala +++ b/src/Layouts/ItemSidebarView.vala @@ -760,6 +760,6 @@ public class Layouts.ItemSidebarView : Adw.Bin { 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_notification (toast); + Services.EventBus.get_default ().send_toast (toast); } } diff --git a/src/Layouts/ProjectRow.vala b/src/Layouts/ProjectRow.vala index 692fd120d..378d372d0 100644 --- a/src/Layouts/ProjectRow.vala +++ b/src/Layouts/ProjectRow.vala @@ -227,7 +227,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { Services.Settings.get_default ().settings.bind ("show-tasks-count", count_revealer, "reveal_child", GLib.SettingsBindFlags.DEFAULT); if (drag_n_drop) { - build_drag_and_drop.begin (); + build_drag_and_drop (); } if (show_subprojects) { @@ -344,7 +344,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { count_label.label = count <= 0 ? "" : count.to_string (); } - private async void build_drag_and_drop () { + private void build_drag_and_drop () { // Motion Drop build_drop_motion (); @@ -384,7 +384,7 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { var projects_sort = Services.Settings.get_default ().settings.get_enum ("projects-sort-by"); if (projects_sort != 0) { Services.Settings.get_default ().settings.set_enum ("projects-sort-by", 0); - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (_("Projects sort changed to 'Custom sort order'")) ); } @@ -527,8 +527,13 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { private void build_drop_item_target () { var drop_row_target = new Gtk.DropTarget (typeof (Layouts.ItemRow), Gdk.DragAction.MOVE); handle_grid.add_controller (drop_row_target); - drop_row_target.accept.connect ((drop) => { + var target_widget = this; + + if (target_widget.project.is_deck) { + return false; + } + GLib.Value value = Value (typeof (Gtk.Widget)); try { @@ -709,10 +714,6 @@ public class Layouts.ProjectRow : Gtk.ListBoxRow { if (project.sync_id == "") { is_loading = true; - Services.CalDAV.Core.get_default ().refresh_tasklist.begin (project, (obj, res) => { - Services.CalDAV.Core.get_default ().refresh_tasklist.end (res); - is_loading = false; - }); } else { sync_project (); } diff --git a/src/Layouts/SidebarSourceRow.vala b/src/Layouts/SidebarSourceRow.vala index 7bf09e0ab..ba459cff0 100644 --- a/src/Layouts/SidebarSourceRow.vala +++ b/src/Layouts/SidebarSourceRow.vala @@ -35,7 +35,7 @@ public class Layouts.SidebarSourceRow : Gtk.ListBoxRow { construct { css_classes = { "no-selectable", "no-padding" }; - group = new Layouts.HeaderItem (source.header_text) { + group = new Layouts.HeaderItem (source.display_name) { reveal = true, show_separator = true, subheader_title = source.subheader_text @@ -89,6 +89,7 @@ public class Layouts.SidebarSourceRow : Gtk.ListBoxRow { update_projects_sort (); source.updated.connect (() => { + group.header_title = source.display_name; main_revealer.reveal_child = source.is_visible; }); diff --git a/src/MainWindow.vala b/src/MainWindow.vala index caa267ae1..740343d05 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -30,6 +30,7 @@ public class MainWindow : Adw.ApplicationWindow { private Gtk.Button fake_button; private Widgets.ContextMenu.MenuItem archive_item; private Widgets.ContextMenu.MenuSeparator archive_separator; + private Adw.ToastOverlay toast_overlay; public Services.ActionManager action_manager; @@ -117,7 +118,7 @@ public class MainWindow : Adw.ApplicationWindow { sidebar = item_sidebar_view }; - var toast_overlay = new Adw.ToastOverlay () { + toast_overlay = new Adw.ToastOverlay () { child = views_split_view }; @@ -227,10 +228,12 @@ public class MainWindow : Adw.ApplicationWindow { } }); - Services.EventBus.get_default ().send_notification.connect ((toast) => { + Services.EventBus.get_default ().send_toast.connect ((toast) => { toast_overlay.add_toast (toast); }); + Services.EventBus.get_default ().send_error_toast.connect (send_toast_error); + search_button.clicked.connect (() => { (new Dialogs.QuickFind.QuickFind ()).present (Planify._instance.main_window); }); @@ -574,6 +577,19 @@ public class MainWindow : Adw.ApplicationWindow { } } + public void send_toast_error (int error_code, string error_message) { + var toast = new Adw.Toast (_("Oops! Something happened")); + toast.timeout = 3; + toast.priority = Adw.ToastPriority.HIGH; + toast.button_label = _("See More"); + + toast.button_clicked.connect (() => { + (new Dialogs.ErrorDialog (error_code, error_message)).present (this); + }); + + toast_overlay.add_toast (toast); + } + private void about_dialog () { Adw.AboutDialog dialog; diff --git a/src/Views/Label/LabelSourceRow.vala b/src/Views/Label/LabelSourceRow.vala index def4d53c7..295d7ea69 100644 --- a/src/Views/Label/LabelSourceRow.vala +++ b/src/Views/Label/LabelSourceRow.vala @@ -35,7 +35,7 @@ public class Views.LabelSourceRow : Gtk.ListBoxRow { construct { css_classes = { "no-selectable", "no-padding" }; - group = new Layouts.HeaderItem (source.header_text) { + group = new Layouts.HeaderItem (source.display_name) { reveal = true, show_separator = true, subheader_title = source.subheader_text @@ -67,6 +67,10 @@ public class Views.LabelSourceRow : Gtk.ListBoxRow { return GLib.Source.REMOVE; }); + source.updated.connect (() => { + group.header_title = source.display_name; + }); + add_button.clicked.connect (() => { var dialog = new Dialogs.Label.new (source); dialog.present (Planify._instance.main_window); diff --git a/src/Widgets/Attachments.vala b/src/Widgets/Attachments.vala index 9f43dca65..a8cfb2f8b 100644 --- a/src/Widgets/Attachments.vala +++ b/src/Widgets/Attachments.vala @@ -325,7 +325,7 @@ public class Widgets.AttachmentRow : Gtk.ListBoxRow { close_button.is_loading = false; } catch (Error e) { close_button.is_loading = false; - Services.EventBus.get_default ().send_notification ( + Services.EventBus.get_default ().send_toast ( Util.get_default ().create_toast (e.message) ); } diff --git a/src/Widgets/ErrorView.vala b/src/Widgets/ErrorView.vala new file mode 100644 index 000000000..fc2d1f3a3 --- /dev/null +++ b/src/Widgets/ErrorView.vala @@ -0,0 +1,137 @@ +/* +* 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 Widgets.ErrorView : Adw.Bin { + private Gtk.Label error_label; + private Gtk.Label error_code_label; + private Gtk.TextView error_textview; + + public int error_code { + set { + error_label.label = get_http_error (value); + error_code_label.label = "HTTP %d".printf (value); + } + } + + public string error_message { + set { + error_textview.buffer.text = value; + } + } + + construct { + var headerbar = new Adw.HeaderBar (); + headerbar.add_css_class ("flat"); + + var error_image = new Gtk.Image.from_icon_name ("cross-large-circle-outline-symbolic") { + hexpand = true, + halign = Gtk.Align.CENTER, + pixel_size = 38, + css_classes = { "error" } + }; + + error_label = new Gtk.Label (null) { + hexpand = true, + halign = Gtk.Align.CENTER, + css_classes = { "font-bold", "title-2" }, + margin_top = 12, + margin_start = 12, + margin_end = 12, + wrap = true, + justify = Gtk.Justification.CENTER + }; + + error_code_label = new Gtk.Label (null) { + hexpand = true, + halign = Gtk.Align.CENTER, + css_classes = { "dim-label", "caption" }, + margin_top = 3 + }; + + error_textview = new Gtk.TextView () { + left_margin = 12, + top_margin = 12, + bottom_margin = 12, + right_margin = 12, + wrap_mode = Gtk.WrapMode.WORD + }; + error_textview.add_css_class ("monospace"); + error_textview.add_css_class ("error-message"); + error_textview.remove_css_class ("view"); + + var textview_scrolled_window = new Gtk.ScrolledWindow () { + hscrollbar_policy = Gtk.PolicyType.NEVER, + hexpand = true, + vexpand = true, + child = error_textview, + height_request = 275 + }; + + var textview_frame = new Gtk.Frame (null) { + child = textview_scrolled_window, + margin_top = 24, + margin_bottom = 12, + margin_start = 12, + margin_end = 12 + }; + + var issue_button = new Gtk.Button.with_label (_("Report Issue")) { + hexpand = true, + margin_top = 12, + margin_bottom = 12, + margin_start = 12, + margin_end = 12, + css_classes = { "suggested-action" } + }; + + var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); + content_box.append (headerbar); + content_box.append (error_image); + content_box.append (error_label); + content_box.append (error_code_label); + content_box.append (textview_frame); + content_box.append (issue_button); + + child = content_box; + + issue_button.clicked.connect (() => { + try { + AppInfo.launch_default_for_uri ("https://github.com/alainm23/planify/issues/new?assignees=&labels=&projects=&template=bug_report.md", null); + } catch (Error e) { + warning ("%s\n", e.message); + } + }); + } + + public string get_http_error (int code) { + var messages = new Gee.HashMap (); + + messages.set (400, _("The request was incorrect.")); + messages.set (401, _("Authentication is required, and has failed, or has not yet been provided.")); + messages.set (403, _("The request was valid, but for something that is forbidden.")); + messages.set (404, _("The requested resource could not be found.")); + messages.set (429, _("The user has sent too many requests in a given amount of time.")); + messages.set (500, _("The request failed due to a server error.")); + messages.set (503, _("The server is currently unable to handle the request.")); + + return messages.has_key (code) ? messages.get (code) : _("Unknown error"); + } +} \ No newline at end of file diff --git a/src/Widgets/SourceRow.vala b/src/Widgets/SourceRow.vala index 94e6ecf8c..0c6dbb81c 100644 --- a/src/Widgets/SourceRow.vala +++ b/src/Widgets/SourceRow.vala @@ -39,7 +39,7 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { active = source.is_visible }; - var header_label = new Gtk.Label (source.header_text); + var header_label = new Gtk.Label (source.display_name); var subheader_label = new Gtk.Label (source.subheader_text) { halign = Gtk.Align.START, @@ -123,6 +123,10 @@ public class Widgets.SourceRow : Gtk.ListBoxRow { return GLib.Source.REMOVE; }); + source.updated.connect (() => { + header_label.label = source.display_name; + }); + visible_checkbutton.toggled.connect (() => { source.is_visible = visible_checkbutton.active; source.save (); diff --git a/src/meson.build b/src/meson.build index c8ffd6ac1..57cc95a35 100644 --- a/src/meson.build +++ b/src/meson.build @@ -58,6 +58,7 @@ sources = files( 'Widgets/Attachments.vala', 'Widgets/ItemChangeHistoryRow.vala', 'Widgets/SourceRow.vala', + 'Widgets/ErrorView.vala', 'Views/Project/Project.vala', 'Views/Project/List.vala', @@ -89,6 +90,7 @@ sources = files( 'Dialogs/LabelPicker.vala', 'Dialogs/RepeatConfig.vala', 'Dialogs/ItemChangeHistory.vala', + 'Dialogs/ErrorDialog.vala', 'Dialogs/QuickFind/QuickFind.vala', 'Dialogs/QuickFind/QuickFindItem.vala', From 5023e2b494c769e0b0002798341de42b573ece60 Mon Sep 17 00:00:00 2001 From: Alain Date: Mon, 29 Jul 2024 08:32:21 -0500 Subject: [PATCH 12/14] Improve backup --- core/Constants.vala | 2 +- core/Objects/Label.vala | 7 +- core/Objects/Project.vala | 9 +- core/Objects/Source.vala | 18 ++++ core/Services/CalDAV/Core.vala | 19 +++- core/Services/Database.vala | 2 +- core/Services/Store.vala | 32 ++++++ core/Services/Todoist.vala | 29 +++-- core/Util/Util.vala | 14 --- ....github.alainm23.planify.appdata.xml.in.in | 8 ++ meson.build | 2 +- src/Dialogs/Preferences/Pages/Backup.vala | 25 ++--- .../Preferences/PreferencesWindow.vala | 36 +++++-- src/MainWindow.vala | 2 +- src/Objects/Backup.vala | 101 +++++++++++------- src/Services/Backups.vala | 98 +++++++++++++---- src/Services/Notification.vala | 4 + src/Widgets/ErrorView.vala | 11 +- 18 files changed, 301 insertions(+), 118 deletions(-) diff --git a/core/Constants.vala b/core/Constants.vala index 53d9477db..ae415c1ba 100644 --- a/core/Constants.vala +++ b/core/Constants.vala @@ -2,7 +2,7 @@ namespace Constants { public const string TODOIST_CLIENT_ID = "b0dd7d3714314b1dbbdab9ee03b6b432"; public const string TODOIST_CLIENT_SECRET = "a86dfeb12139459da3e5e2a8c197c678"; public const string TODOIST_SCOPE = "data:read_write,data:delete,project:delete"; - public const string BACKUP_VERSION = "1.0"; + public const string BACKUP_VERSION = "2.0"; public const int UPDATE_TIMEOUT = 1500; public const int DESTROY_TIMEOUT = 750; public const int SYNC_TIMEOUT = 2500; diff --git a/core/Objects/Label.vala b/core/Objects/Label.vala index e7894f12a..1a20ca657 100644 --- a/core/Objects/Label.vala +++ b/core/Objects/Label.vala @@ -117,9 +117,14 @@ public class Objects.Label : Objects.BaseObject { 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 = Util.get_default ().get_backend_type_by_text (node.get_object ().get_string_member ("backend_type")); + 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) { diff --git a/core/Objects/Project.vala b/core/Objects/Project.vala index 2b561b894..9ade26efd 100644 --- a/core/Objects/Project.vala +++ b/core/Objects/Project.vala @@ -355,7 +355,7 @@ public class Objects.Project : Objects.BaseObject { 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 = Util.get_default ().get_backend_type_by_text (node.get_object ().get_string_member ("backend_type")); + backend_type = SourceType.parse (node.get_object ().get_string_member ("backend_type")); inbox_project = node.get_object ().get_boolean_member ("inbox_project"); team_inbox = node.get_object ().get_boolean_member ("team_inbox"); child_order = (int32) node.get_object ().get_int_member ("child_order"); @@ -372,6 +372,13 @@ public class Objects.Project : Objects.BaseObject { show_completed = node.get_object ().get_boolean_member ("show_completed"); description = node.get_object ().get_string_member ("description"); due_date = node.get_object ().get_string_member ("due_date"); + source_id = node.get_object ().get_string_member ("backend_type"); + + if (node.get_object ().has_member ("source_id")) { + source_id = node.get_object ().get_string_member ("source_id"); + } + + print ("%s\n".printf (to_string ())); } public void update_from_json (Json.Node node) { diff --git a/core/Objects/Source.vala b/core/Objects/Source.vala index bdd49aa1c..f51003e78 100644 --- a/core/Objects/Source.vala +++ b/core/Objects/Source.vala @@ -107,6 +107,24 @@ public class Objects.Source : Objects.BaseObject { public signal void sync_started (); public signal void sync_finished (); + public Source.from_import_json (Json.Node node) { + id = node.get_object ().get_string_member ("id"); + source_type = SourceType.parse (node.get_object ().get_string_member ("source_type")); + added_at = node.get_object ().get_string_member ("added_at"); + updated_at = node.get_object ().get_string_member ("updated_at"); + is_visible = node.get_object ().get_boolean_member ("is_visible"); + child_order = (int32) node.get_object ().get_int_member ("is_visible"); + sync_server = node.get_object ().get_boolean_member ("sync_server"); + last_sync = node.get_object ().get_string_member ("last_sync"); + display_name = node.get_object ().get_string_member ("display_name"); + + if (source_type == SourceType.TODOIST) { + data = new Objects.SourceTodoistData.from_json (node.get_object ().get_string_member ("data")); + } else if (source_type == SourceType.CALDAV) { + data = new Objects.SourceCalDAVData.from_json (node.get_object ().get_string_member ("data")); + } + } + public void run_server () { _run_server (); diff --git a/core/Services/CalDAV/Core.vala b/core/Services/CalDAV/Core.vala index 268658e3c..afd1c3586 100644 --- a/core/Services/CalDAV/Core.vala +++ b/core/Services/CalDAV/Core.vala @@ -49,6 +49,7 @@ public class Services.CalDAV.Core : GLib.Object { HttpResponse response = new HttpResponse (); if (!providers_map.has_key (caldav_type.to_string ())) { + response.error_code = 409; response.error = _("No Provider Available"); return response; } @@ -58,6 +59,12 @@ public class Services.CalDAV.Core : GLib.Object { string url = provider.get_server_url (server_url, username, password); print ("Server URL: %s\n".printf (url)); + if (Services.Store.instance ().source_caldav_exists (url, username)) { + response.error_code = 409; + response.error = "Source already exists"; + return response; + } + string credentials = "%s:%s".printf (username, password); string base64_credentials = Base64.encode (credentials.data); @@ -129,15 +136,19 @@ public class Services.CalDAV.Core : GLib.Object { Services.Store.instance ().insert_source (source); - yield get_all_tasklist (source, cancellable); + yield get_all_tasklist (source, response, cancellable); + + response.status = true; } catch (Error e) { + response.error_code = e.code; + response.error = e.message; debug (e.message); } return response; } - public async void get_all_tasklist (Objects.Source source, GLib.Cancellable cancellable) { + public async void get_all_tasklist (Objects.Source source, HttpResponse response, GLib.Cancellable cancellable) { if (!providers_map.has_key (source.caldav_data.caldav_type.to_string ())) { return; } @@ -167,6 +178,8 @@ public class Services.CalDAV.Core : GLib.Object { first_sync_finished (); } catch (Error e) { + response.error_code = e.code; + response.error = e.message; debug (e.message); } } @@ -306,7 +319,7 @@ public class Services.CalDAV.Core : GLib.Object { private Objects.Item add_item_if_not_exists (GXml.DomElement element, Objects.Project project) { Objects.Item return_value = new Objects.Item.from_caldav_xml (element); - return_value.project_id = project.id;; + return_value.project_id = project.id; string parent_id = Util.get_related_to_uid (element); if (parent_id != "") { diff --git a/core/Services/Database.vala b/core/Services/Database.vala index a056ae764..216924540 100644 --- a/core/Services/Database.vala +++ b/core/Services/Database.vala @@ -1995,7 +1995,7 @@ public class Services.Database : GLib.Object { 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.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"); diff --git a/core/Services/Store.vala b/core/Services/Store.vala index e70eb42e6..029cf1371 100644 --- a/core/Services/Store.vala +++ b/core/Services/Store.vala @@ -200,6 +200,38 @@ public class Services.Store : GLib.Object { } } + public bool source_todoist_exists (string email) { + bool return_value = false; + + lock (_sources) { + foreach (Objects.Source source in sources) { + if (source.source_type == SourceType.TODOIST && source.todoist_data.user_email == email) { + return_value = true; + break; + } + } + + return return_value; + } + } + + public bool source_caldav_exists (string server_url, string username) { + bool return_value = false; + + lock (_sources) { + foreach (Objects.Source source in sources) { + if (source.source_type == SourceType.CALDAV && + source.caldav_data.server_url == server_url && + source.caldav_data.username == username) { + return_value = true; + break; + } + } + + return return_value; + } + } + /* * Projects */ diff --git a/core/Services/Todoist.vala b/core/Services/Todoist.vala index a17218fbc..b0e0573d5 100644 --- a/core/Services/Todoist.vala +++ b/core/Services/Todoist.vala @@ -58,7 +58,7 @@ public class Services.Todoist : GLib.Object { return !invalid_token (); } - public async void get_todoist_token (string _url) { + public async HttpResponse login (string _url) { string code = _url.split ("=") [1]; code = code.split ("&") [0]; @@ -67,6 +67,8 @@ public class Services.Todoist : GLib.Object { var message = new Soup.Message ("POST", url); + HttpResponse response = new HttpResponse (); + try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.HIGH, null); parser.load_from_data ((string) stream.get_data ()); @@ -77,15 +79,17 @@ public class Services.Todoist : GLib.Object { var root = parser.get_root ().get_object (); var token = root.get_string_member ("access_token"); - yield add_todoist_account (token); + yield add_todoist_account (token, response); } catch (Error e) { + response.error_code = e.code; + response.error = e.message; error (e.message); } - } - public async void add_todoist_account (string token) { - first_sync_started (); + return response; + } + public async void add_todoist_account (string token, HttpResponse response) { string url = TODOIST_SYNC_URL; url = url + "?sync_token=" + "*"; url = url + "&resource_types=" + "[\"all\"]"; @@ -124,6 +128,13 @@ public class Services.Todoist : GLib.Object { source.display_name = user_object.get_string_member ("email"); source.data = todoist_data; + if (Services.Store.instance ().source_todoist_exists (todoist_data.user_email)) { + response.error_code = 409; + response.error = "Source already exists"; + response.status = false; + return; + } + Services.Store.instance ().insert_source (source); // Create Labels @@ -183,8 +194,10 @@ public class Services.Todoist : GLib.Object { source.last_sync = new GLib.DateTime.now_local ().to_string (); source.save (); - first_sync_finished (); + response.status = true; } catch (Error e) { + response.error_code = e.code; + response.error = e.message; debug (e.message); } } @@ -204,13 +217,9 @@ public class Services.Todoist : GLib.Object { url = url + "?sync_token=" + source.todoist_data.sync_token; url = url + "&resource_types=" + "[\"all\"]"; - print ("URL: %s\n".printf (url)); - var message = new Soup.Message ("POST", url); message.request_headers.append ("Authorization", "Bearer %s".printf (source.todoist_data.access_token)); - print ("TOKEN: %s\n".printf (source.todoist_data.access_token)); - try { GLib.Bytes stream = yield session.send_and_read_async (message, GLib.Priority.LOW, null); parser.load_from_data ((string) stream.get_data ()); diff --git a/core/Util/Util.vala b/core/Util/Util.vala index efdaa746a..bc218e70c 100644 --- a/core/Util/Util.vala +++ b/core/Util/Util.vala @@ -743,20 +743,6 @@ We hope you’ll enjoy using Planify!"""); Services.Store.instance ().insert_label (label_05); } - public SourceType get_backend_type_by_text (string backend_type) { - if (backend_type == "local") { - return SourceType.LOCAL; - } else if (backend_type == "todoist") { - return SourceType.TODOIST; - } else if (backend_type == "google-tasks") { - return SourceType.GOOGLE_TASKS; - } else if (backend_type == "caldav") { - return SourceType.CALDAV; - } else { - return SourceType.NONE; - } - } - public string markup_accel_tooltip (string description, string accels) { return "%s\n%s".printf (description, """%s""".printf (accels)); } diff --git a/data/io.github.alainm23.planify.appdata.xml.in.in b/data/io.github.alainm23.planify.appdata.xml.in.in index 5a2a85809..1c42bb177 100644 --- a/data/io.github.alainm23.planify.appdata.xml.in.in +++ b/data/io.github.alainm23.planify.appdata.xml.in.in @@ -67,6 +67,14 @@ https://www.patreon.com/alainm23 @appid@.desktop + + +
    +
  • Support for multiple sync sources: Integrate more than two Todoist or Nextcloud accounts
  • +
+
+
+
    diff --git a/meson.build b/meson.build index 17cde2f36..1657363ad 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'io.github.alainm23.planify', 'vala', 'c', - version: '4.9.0' + version: '4.10.0' ) gnome = import('gnome') diff --git a/src/Dialogs/Preferences/Pages/Backup.vala b/src/Dialogs/Preferences/Pages/Backup.vala index bd10677a5..1694162df 100644 --- a/src/Dialogs/Preferences/Pages/Backup.vala +++ b/src/Dialogs/Preferences/Pages/Backup.vala @@ -117,8 +117,8 @@ public class Dialogs.Preferences.Pages.Backup : Adw.Bin { }); import_button.clicked.connect (() => { - Services.Backups.get_default ().import_backup.begin ((obj, res) => { - GLib.File file = Services.Backups.get_default ().import_backup.end (res); + Services.Backups.get_default ().choose_backup_file.begin ((obj, res) => { + GLib.File file = Services.Backups.get_default ().choose_backup_file.end (res); Objects.Backup backup = new Objects.Backup.from_file (file); view_backup (backup); }); @@ -160,14 +160,9 @@ public class Dialogs.Preferences.Pages.Backup : Adw.Bin { margin_top = 3 }; - var todoist_row = new Adw.ActionRow (); - todoist_row.title = _("Todoist"); - todoist_row.add_suffix (generate_icon (backup.todoist_backend ? "check-round-outline-symbolic" : "window-close-symbolic", 16)); - - var general_group = new Adw.PreferencesGroup () { - margin_top = 24 - }; - general_group.add (todoist_row); + var sources_row = new Adw.ActionRow (); + sources_row.title = _("Sources"); + sources_row.add_suffix (new Gtk.Label (backup.sources.size.to_string ())); var projects_row = new Adw.ActionRow (); projects_row.title = _("Projects"); @@ -189,6 +184,7 @@ public class Dialogs.Preferences.Pages.Backup : Adw.Bin { margin_top = 24 }; + collection_group.add (sources_row); collection_group.add (projects_row); collection_group.add (sections_row); collection_group.add (items_row); @@ -221,7 +217,6 @@ public class Dialogs.Preferences.Pages.Backup : Adw.Bin { content_box.append (title); content_box.append (subtitle); - content_box.append (general_group); content_box.append (collection_group); content_box.append (buttons_box); @@ -284,12 +279,6 @@ public class Dialogs.Preferences.Pages.Backup : Adw.Bin { group.insert_child (row, 0); } - private Gtk.Widget generate_icon (string icon_name, int size = 32) { - return new Gtk.Image.from_icon_name (icon_name) { - pixel_size = size - }; - } - private void view_backup (Objects.Backup backup) { if (backup.valid ()) { Gtk.Widget? import_page; @@ -408,7 +397,7 @@ public class Widgets.BackupRow : Gtk.ListBoxRow { delete_item.clicked.connect (() => { menu_popover.popdown (); - backup.delete_backup ((Gtk.Window) Planify.instance.main_window); + Services.Backups.get_default ().delete_backup (backup); }); return menu_popover; diff --git a/src/Dialogs/Preferences/PreferencesWindow.vala b/src/Dialogs/Preferences/PreferencesWindow.vala index 3f213acf7..fc38be633 100644 --- a/src/Dialogs/Preferences/PreferencesWindow.vala +++ b/src/Dialogs/Preferences/PreferencesWindow.vala @@ -1221,8 +1221,24 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { if (("https://github.com/alainm23/planner?code=" in redirect_uri) && ("&state=%s".printf (state) in redirect_uri)) { - settings_header.title = _("Synchronizing..."); // vala-lint=ellipsis - get_todoist_token.begin (redirect_uri); + settings_header.title = _("Synchronizing…"); // vala-lint=ellipsis + + stack.visible_child_name = "loading"; + Services.Todoist.get_default ().login.begin (redirect_uri, (obj, res) => { + HttpResponse response = Services.Todoist.get_default ().login.end (res); + pop_subpage (); + webview.get_network_session ().get_website_data_manager ().clear.begin (WebKit.WebsiteDataTypes.ALL, 0, null); + + if (!response.status) { + if (response.error_code != 409) { + show_message_error (response.error_code, response.error.strip ()); + } else { + var toast = new Adw.Toast (response.error.strip ()); + toast.timeout = 3; + add_toast (toast); + } + } + }); } if ("https://github.com/alainm23/planner?error=access_denied" in redirect_uri) { @@ -1442,7 +1458,14 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { } else { login_button.is_loading = false; cancel_button.visible = false; - show_message_error (response.error_code, response.error.strip ()); + + if (response.error_code == 409) { + var toast = new Adw.Toast (response.error.strip ()); + toast.timeout = 3; + add_toast (toast); + } else { + show_message_error (response.error_code, response.error.strip ()); + } } }); }); @@ -1467,10 +1490,11 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return scheme.has_prefix ("http"); } - private void show_message_error (int error_code, string error_message) { + private void show_message_error (int error_code, string error_message, bool visible_issue_button = true) { var error_view = new Widgets.ErrorView () { error_code = error_code, error_message = error_message, + visible_issue_button = visible_issue_button }; var page = new Adw.NavigationPage (error_view, ""); @@ -1682,10 +1706,6 @@ public class Dialogs.Preferences.PreferencesWindow : Adw.PreferencesDialog { return page; } - private async void get_todoist_token (string redirect_uri) { - yield Services.Todoist.get_default ().get_todoist_token (redirect_uri); - } - public bool is_dark_theme () { var dark_mode = Services.Settings.get_default ().settings.get_boolean ("dark-mode"); diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 740343d05..17b0d3c9b 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -149,7 +149,7 @@ public class MainWindow : Adw.ApplicationWindow { Services.Settings.get_default ().settings.set_boolean ( "dark-mode", granite_settings.prefers_color_scheme == Granite.Settings.ColorScheme.DARK - ); + ); Util.get_default ().update_theme (); } }); diff --git a/src/Objects/Backup.vala b/src/Objects/Backup.vala index b4d45bfd2..072c97ccd 100644 --- a/src/Objects/Backup.vala +++ b/src/Objects/Backup.vala @@ -16,6 +16,7 @@ public class Objects.Backup : Object { public Gee.ArrayList sections { get; set; default = new Gee.ArrayList (); } public Gee.ArrayList items { get; set; default = new Gee.ArrayList (); } public Gee.ArrayList labels { get; set; default = new Gee.ArrayList (); } + public Gee.ArrayList sources { get; set; default = new Gee.ArrayList (); } public string path { get; set; } public string error { get; set; default = ""; } @@ -61,14 +62,61 @@ public class Objects.Backup : Object { // Set Settings var settings = node.get_object_member ("settings"); local_inbox_project_id = settings.get_string_member ("local-inbox-project-id"); - todoist_access_token = settings.get_string_member ("todoist-access-token"); - todoist_sync_token = settings.get_string_member ("todoist-sync-token"); - todoist_user_name = settings.get_string_member ("todoist-user-name"); - todoist_user_email = settings.get_string_member ("todoist-user-email"); - todoist_user_image_id = settings.get_string_member ("todoist-user-image-id"); - todoist_user_avatar = settings.get_string_member ("todoist-user-avatar"); - todoist_user_is_premium = settings.get_boolean_member ("todoist-user-is-premium"); - + + if (settings.has_member ("todoist-access-token")) { + todoist_access_token = settings.get_string_member ("todoist-access-token"); + } + + if (settings.has_member ("todoist-sync-token")) { + todoist_sync_token = settings.get_string_member ("todoist-sync-token"); + } + + if (settings.has_member ("todoist-user-name")) { + todoist_user_name = settings.get_string_member ("todoist-user-name"); + } + + if (settings.has_member ("todoist-user-email")) { + todoist_user_email = settings.get_string_member ("todoist-user-name"); + } + + if (settings.has_member ("todoist-user-image-id")) { + todoist_user_image_id = settings.get_string_member ("todoist-user-image-id"); + } + + if (settings.has_member ("todoist-user-avatar")) { + todoist_user_avatar = settings.get_string_member ("todoist-user-avatar"); + } + + if (settings.has_member ("todoist-user-is-premium")) { + todoist_user_is_premium = settings.get_boolean_member ("todoist-user-is-premium"); + } + + // Sources + sources.clear (); + unowned Json.Array _sources = node.get_array_member ("sources"); + foreach (unowned Json.Node item in _sources.get_elements ()) { + sources.add (new Objects.Source.from_import_json (item)); + } + + if (version == "1.0" && todoist_access_token.strip () != "") { + var todoist_source = new Objects.Source (); + todoist_source.id = SourceType.TODOIST.to_string (); + todoist_source.source_type = SourceType.TODOIST; + todoist_source.display_name = todoist_user_email; + + Objects.SourceTodoistData todoist_data = new Objects.SourceTodoistData (); + todoist_data.sync_token = todoist_sync_token; + todoist_data.access_token = todoist_access_token; + todoist_data.user_email = todoist_user_email; + todoist_data.user_name = todoist_user_email; + todoist_data.user_avatar = todoist_user_avatar; + todoist_data.user_image_id = todoist_user_image_id; + todoist_data.user_is_premium = todoist_user_is_premium; + todoist_source.data = todoist_data; + + sources.add (todoist_source); + } + // Labels labels.clear (); unowned Json.Array _labels = node.get_array_member ("labels"); @@ -80,7 +128,15 @@ public class Objects.Backup : Object { projects.clear (); unowned Json.Array _projects = node.get_array_member ("projects"); foreach (unowned Json.Node item in _projects.get_elements ()) { - projects.add (new Objects.Project.from_import_json (item)); + var _project = new Objects.Project.from_import_json (item); + + if (version == "1.0") { + if (_project.source_id != SourceType.CALDAV.to_string ()) { + projects.add (_project); + } + } else { + projects.add (_project); + } } // Sections @@ -120,31 +176,4 @@ public class Objects.Backup : Object { return true; } - - public void delete_backup (Gtk.Window window) { - var dialog = new Adw.AlertDialog ( - _("Delete Backup"), - _("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") { - File db_file = File.new_for_path (path); - if (db_file.query_exists ()) { - try { - if (db_file.delete ()) { - deleted (); - } - } catch (Error err) { - warning (err.message); - } - } - } - }); - } } diff --git a/src/Services/Backups.vala b/src/Services/Backups.vala index 9bb4592c5..55c6a2536 100644 --- a/src/Services/Backups.vala +++ b/src/Services/Backups.vala @@ -117,35 +117,50 @@ public class Services.Backups : Object { builder.set_member_name ("local-inbox-project-id"); builder.add_string_value (Services.Settings.get_default ().settings.get_string ("local-inbox-project-id")); - // Todoist - builder.set_member_name ("todoist-access-token"); - builder.add_string_value (Services.Settings.get_default ().settings.get_string ("todoist-access-token")); + builder.end_object (); + + // Sources - builder.set_member_name ("todoist-sync-token"); - builder.add_string_value (Services.Settings.get_default ().settings.get_string ("todoist-sync-token")); + builder.set_member_name ("sources"); + builder.begin_array (); - builder.set_member_name ("todoist-user-name"); - builder.add_string_value (Services.Settings.get_default ().settings.get_string ("todoist-user-name")); + foreach (Objects.Source source in Services.Database.get_default ().get_sources_collection ()) { + builder.begin_object (); - builder.set_member_name ("todoist-user-email"); - builder.add_string_value (Services.Settings.get_default ().settings.get_string ("todoist-user-email")); + builder.set_member_name ("id"); + builder.add_string_value (source.id); - builder.set_member_name ("todoist-user-image-id"); - builder.add_string_value (Services.Settings.get_default ().settings.get_string ("todoist-user-image-id")); + builder.set_member_name ("display_name"); + builder.add_string_value (source.display_name); - builder.set_member_name ("todoist-user-avatar"); - builder.add_string_value (Services.Settings.get_default ().settings.get_string ("todoist-user-avatar")); + builder.set_member_name ("source_type"); + builder.add_string_value (source.source_type.to_string ()); - builder.set_member_name ("todoist-user-is-premium"); - builder.add_boolean_value (Services.Settings.get_default ().settings.get_boolean ("todoist-user-is-premium")); + builder.set_member_name ("added_at"); + builder.add_string_value (source.added_at); - builder.end_object (); + builder.set_member_name ("updated_at"); + builder.add_string_value (source.updated_at); + + builder.set_member_name ("is_visible"); + builder.add_boolean_value (source.is_visible); + + builder.set_member_name ("child_order"); + builder.add_int_value (source.child_order); + + builder.set_member_name ("data"); + builder.add_string_value (source.data.to_json ()); + + builder.end_object (); + } + + builder.end_array (); // Labels builder.set_member_name ("labels"); builder.begin_array (); - foreach (Objects.Label label in Services.Store.instance ().labels) { + foreach (Objects.Label label in Services.Database.get_default ().get_labels_collection ()) { builder.begin_object (); builder.set_member_name ("id"); @@ -166,6 +181,9 @@ public class Services.Backups : Object { builder.set_member_name ("is_favorite"); builder.add_boolean_value (label.is_favorite); + builder.set_member_name ("source_id"); + builder.add_string_value (label.source_id); + builder.end_object (); } @@ -174,7 +192,7 @@ public class Services.Backups : Object { // Projects builder.set_member_name ("projects"); builder.begin_array (); - foreach (Objects.Project project in Services.Store.instance ().projects) { + foreach (Objects.Project project in Services.Database.get_default ().get_projects_collection ()) { builder.begin_object (); builder.set_member_name ("id"); @@ -240,6 +258,9 @@ public class Services.Backups : Object { builder.set_member_name ("sync_id"); builder.add_string_value (project.sync_id); + builder.set_member_name ("source_id"); + builder.add_string_value (project.source_id); + builder.end_object (); } builder.end_array (); @@ -247,7 +268,7 @@ public class Services.Backups : Object { // Sections builder.set_member_name ("sections"); builder.begin_array (); - foreach (Objects.Section section in Services.Store.instance ().sections) { + foreach (Objects.Section section in Services.Database.get_default ().get_sections_collection ()) { builder.begin_object (); builder.set_member_name ("id"); @@ -284,7 +305,7 @@ public class Services.Backups : Object { // Items builder.set_member_name ("items"); builder.begin_array (); - foreach (Objects.Item item in Services.Store.instance ().items) { + foreach (Objects.Item item in Services.Database.get_default ().get_items_collection ()) { builder.begin_object (); builder.set_member_name ("id"); @@ -378,12 +399,41 @@ public class Services.Backups : Object { if (file_path.query_exists ()) { var backup = new Objects.Backup.from_file (file_path); backup_added (backup); + _backups.add (backup); } } catch (Error e) { debug ("Error: %s\n", e.message); } } + public void delete_backup (Objects.Backup backup) { + var dialog = new Adw.AlertDialog ( + _("Delete Backup"), + _("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 ((Gtk.Window) Planify.instance.main_window); + + dialog.response.connect ((response) => { + if (response == "delete") { + File db_file = File.new_for_path (backup.path); + if (db_file.query_exists ()) { + try { + if (db_file.delete ()) { + backup.deleted (); + _backups.remove (backup); + } + } catch (Error err) { + warning (err.message); + } + } + } + }); + } + public void save_file_as (Objects.Backup backup) { var dialog = new Gtk.FileDialog (); dialog.initial_name = "Planify backup %s.json".printf (backup.title); @@ -409,7 +459,7 @@ public class Services.Backups : Object { }); } - public async GLib.File? import_backup () { + public async GLib.File? choose_backup_file () { var dialog = new Gtk.FileDialog (); add_filters (dialog); @@ -443,6 +493,12 @@ public class Services.Backups : Object { // Clear Database Services.Database.get_default ().clear_database (); Services.Database.get_default ().init_database (); + Util.get_default ().create_local_source (); + + // Create Sources + foreach (Objects.Source source in backup.sources) { + Services.Store.instance ().insert_source (source); + } // Create Labels foreach (Objects.Label item in backup.labels) { diff --git a/src/Services/Notification.vala b/src/Services/Notification.vala index 192c93783..c884277d6 100644 --- a/src/Services/Notification.vala +++ b/src/Services/Notification.vala @@ -95,6 +95,10 @@ public class Services.Notification : GLib.Object { notification.set_icon (new ThemedIcon ("io.github.alainm23.planify")); notification.set_priority (GLib.NotificationPriority.URGENT); notification.set_default_action_and_target_value ("show-item", new Variant.string (reminder.item_id)); + // notification.add_button (_("Complete"), "complete"); + // notification.add_button (_("Snooze for 10 minutes"), "complete"); + // notification.add_button (_("Snooze for 30 minutes"), "complete"); + // notification.add_button (_("Snooze for 1 hour"), "complete"); return notification; } diff --git a/src/Widgets/ErrorView.vala b/src/Widgets/ErrorView.vala index fc2d1f3a3..3f1811a93 100644 --- a/src/Widgets/ErrorView.vala +++ b/src/Widgets/ErrorView.vala @@ -23,6 +23,7 @@ public class Widgets.ErrorView : Adw.Bin { private Gtk.Label error_label; private Gtk.Label error_code_label; private Gtk.TextView error_textview; + private Gtk.Button issue_button; public int error_code { set { @@ -37,6 +38,12 @@ public class Widgets.ErrorView : Adw.Bin { } } + public bool visible_issue_button { + set { + issue_button.visible = value; + } + } + construct { var headerbar = new Adw.HeaderBar (); headerbar.add_css_class ("flat"); @@ -93,7 +100,7 @@ public class Widgets.ErrorView : Adw.Bin { margin_end = 12 }; - var issue_button = new Gtk.Button.with_label (_("Report Issue")) { + issue_button = new Gtk.Button.with_label (_("Report Issue")) { hexpand = true, margin_top = 12, margin_bottom = 12, @@ -134,4 +141,4 @@ public class Widgets.ErrorView : Adw.Bin { return messages.has_key (code) ? messages.get (code) : _("Unknown error"); } -} \ No newline at end of file +} From 50e1c6058733ea8a64f130a0fe4a2f5cce665d65 Mon Sep 17 00:00:00 2001 From: Alain Date: Mon, 29 Jul 2024 08:47:44 -0500 Subject: [PATCH 13/14] Update translate files --- po/POTFILES | 16 +- po/bg.po | 777 ++++++++++++++------------ po/de.po | 789 ++++++++++++++------------ po/es.po | 783 ++++++++++++++------------ po/fr.po | 779 ++++++++++++++------------ po/hi.po | 773 +++++++++++++------------ po/io.github.alainm23.planify.pot | 700 +++++++++++------------ po/ko.po | 774 +++++++++++++------------ po/nl.po | 783 ++++++++++++++------------ po/pt_BR.po | 784 ++++++++++++++------------ po/pt_PT.po | 899 ++++++++++++++++-------------- po/ru.po | 770 +++++++++++++------------ po/tr.po | 777 ++++++++++++++------------ po/zh_CN.po | 766 +++++++++++++------------ 14 files changed, 5406 insertions(+), 4764 deletions(-) diff --git a/po/POTFILES b/po/POTFILES index 2b20089ee..24afc1848 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -10,10 +10,13 @@ core/Util/Datetime.vala core/Services/Settings.vala core/Services/EventBus.vala core/Services/Database.vala +core/Services/Store.vala core/Services/Todoist.vala + core/Services/CalDAV/Core.vala -core/Services/CalDAV/Constants.vala -core/Services/CalDAV/Backend.vala +core/Services/CalDAV/Providers/ProviderBase.vala +core/Services/CalDAV/Providers/Nextcloud.vala +core/Services/CalDAV/Providers/Radicale.vala core/Services/Chrono/Chrono.vala core/Services/Chrono/Enum.vala @@ -84,6 +87,7 @@ core/Objects/Section.vala core/Objects/Promise.vala core/Objects/Attachment.vala core/Objects/ObjectEvent.vala +core/Objects/Source.vala core/Objects/Filters/Pinboard.vala core/Objects/Filters/Scheduled.vala @@ -109,7 +113,8 @@ src/Services/Notification.vala src/Services/TimeMonitor.vala src/Services/DBusServer.vala src/Services/Backups.vala -src/Services/Migrate.vala +src/Services/MigrateFromPlanner.vala +src/Services/NetworkMonitor.vala src/Services/CalendarEvents/CalendarEvents.vala src/Services/CalendarEvents/DateIterator.vala @@ -127,6 +132,7 @@ src/Layouts/LabelRow.vala src/Layouts/ItemSidebarView.vala src/Layouts/SectionBoard.vala src/Layouts/HeaderBar.vala +src/Layouts/SidebarSourceRow.vala src/Widgets/ColorPickerRow.vala src/Widgets/MagicButton.vala @@ -145,6 +151,8 @@ src/Widgets/ReorderChild.vala src/Widgets/FilterFlowBox.vala src/Widgets/Attachments.vala src/Widgets/ItemChangeHistoryRow.vala +src/Widgets/SourceRow.vala +src/Widgets/ErrorView.vala src/Views/Project/Project.vala src/Views/Project/List.vala @@ -152,6 +160,7 @@ src/Views/Project/Board.vala src/Views/Today.vala src/Views/Label/Label.vala src/Views/Label/Labels.vala +src/Views/Label/LabelSourceRow.vala src/Views/Filter.vala src/Views/Scheduled/Scheduled.vala @@ -174,6 +183,7 @@ src/Dialogs/DatePicker.vala src/Dialogs/LabelPicker.vala src/Dialogs/RepeatConfig.vala src/Dialogs/ItemChangeHistory.vala +src/Dialogs/ErrorDialog.vala src/Dialogs/QuickFind/QuickFind.vala src/Dialogs/QuickFind/QuickFindItem.vala diff --git a/po/bg.po b/po/bg.po index e6b649cf3..59d4c63a3 100644 --- a/po/bg.po +++ b/po/bg.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-04-28 17:39+0200\n" "Last-Translator: twlvnn \n" "Language-Team: Bulgarian \n" @@ -23,7 +23,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -32,7 +32,7 @@ msgstr "" msgid "Today" msgstr "Днес" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -42,7 +42,7 @@ msgstr "Днес" msgid "Inbox" msgstr "Входящи" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -56,135 +56,146 @@ msgstr "Насрочени" msgid "Pinboard" msgstr "Закачени" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Проекти" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Раздели" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Задачи" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Етикети" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Филтри" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Списъци" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Не повтаряй" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "Всяка минута" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "Всеки %d минути" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "Всеки час" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "Всеки %d часа" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Всеки ден" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "Всеки %d дни" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Всяка седмица" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "Всеки %d седмици" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Всеки месец" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "Всеки %d месеца" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Всяка година" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "Всеки %d години" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Приоритет" -#: core/Enum.vala:365 +#: core/Enum.vala:419 #, fuzzy msgid "Label" msgstr "Етикети" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "Краен срок" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Дублиране" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Дублиране" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Описание" # This word is being used as a verb but also as an indicator that a task is pinned, they should be two different fields like "Pin" and "Pinned". -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 #, fuzzy msgid "Pin" msgstr "Закачване" @@ -310,8 +321,8 @@ msgstr "Тъмна" msgid "Dark Blue" msgstr "Тъмно синьо" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Без" @@ -320,17 +331,16 @@ msgstr "Без" msgid "Today + Inbox" msgstr "Днес + Входящи" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Отказване" @@ -342,9 +352,8 @@ msgstr "Изтриване на всички файлове" msgid "Process completed, you need to start Planify again." msgstr "Процесът е завършен, трябва да стартирате „Planify“ наново." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "Добре" @@ -380,11 +389,15 @@ msgstr "ниско" msgid "none" msgstr "без" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "На този компютър" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Запознайте се с „Planify“" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -394,11 +407,11 @@ msgstr "" "работа. Не се колебайте да си поиграете с него - винаги може да създадете " "нов проект от настройките." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Натиснете тази задача" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -406,11 +419,11 @@ msgstr "" "Гледате към една задача! Завършете я, като натиснете полето за избор вляво. " "Завършените задачи се събират най-отдоло на вашия проект." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Създайте нова задача" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -418,21 +431,21 @@ msgstr "" "Сега е ваш ред, натиснете бутона „+“ в долната част на проекта, въведете " "всички неизпълнени и докоснете синия бутон „Запазване“." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Планирайте тази задача до днес или по-късно" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Натиснете бутона на календара в долната част, за да решите кога да направите " "тази задача." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Пренаредете вашите задачи" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -440,11 +453,11 @@ msgstr "" "За да пренаредите списъка, натиснете и задръжте дадена задача, след което я " "изтеглете до мястото, където трябва да бъде." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Създайте проект" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -452,11 +465,11 @@ msgstr "" "Организирайте задачите си по-добре! Отидете в левия панел, натиснете бутона " "„+“ в раздела „На този компютър“ и добавете свой проект." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "Готови сте!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 #, fuzzy msgid "" "That’s all you really need to know. Feel free to start adding your own " @@ -473,15 +486,15 @@ msgstr "" "\n" "Надяваме се, че ще ви хареса да използвате „Planify“!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Персонализирайте по свой вкус" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Покажете събитията от календара си" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -490,11 +503,11 @@ msgstr "" "Може да показвате събитията от календара на системата си в „Planify“. " "Отидете в „Настройки“ 🡒 „Календарни събития“, за да го включите." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Активирайте синхронизацията с услуга на трето лице." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -502,15 +515,15 @@ msgstr "" "„Planify“ не само създава задачи локално, но и може да синхронизира профила " "ви в „Todoist“. Отидете в „Настройки“ 🡒 „Профили“." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Увеличете производителността си" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Изтеглете „плюс“ бутона!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -519,11 +532,11 @@ msgstr "" "отколкото изглежда: той е създаден да се движи! Изтеглете го нагоре, за да " "създадете задача, където пожелаете." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "Етикирайте вашите задачи!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -531,11 +544,11 @@ msgstr "" "Етикетите ви позволяват да подобрите работния си процес в „Planify“. За да " "добавите етикет, натиснете върху бутона за етикет в долната част." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Задавайте напомняния!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -544,78 +557,78 @@ msgstr "" "събитие или нещо специално. Натиснете звънец бутона по-долу, за да добавите " "напомняне." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️Работа" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️Училище" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️Делегирано" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️Вкъщи" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️Следващо" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, fuzzy, c-format msgid "Task moved to %s" msgstr "Задачата е копирана в буфера за обмен" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 #, fuzzy msgid "Task duplicated" msgstr "Дублиране" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 #, fuzzy msgid "Section duplicated" msgstr "Име на раздела" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 #, fuzzy msgid "Project duplicated" msgstr "Действия по проекта" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Утре" @@ -671,41 +684,46 @@ msgstr "Сб," msgid "Su," msgstr "Нд," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "Заявката е неправилна." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "" "Упълномощаване е задължително, но е неуспешно или все още не е предоставено." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "Заявката е правилна, но за нещо, което е забранено." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "Заявеният ресурс не може да бъде намерен." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "" "Потребителят е изпратил твърде много заявки за определен период от време." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "Заявката е неуспешна поради грешка на сървъра." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "В момента сървърът не може да обработи заявката." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Непозната грешка" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Не е достъпен" + # This word is being used as a verb but also as an indicator that a task is pinned, they should be two different fields like "Pin" and "Pinned". #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" @@ -751,11 +769,11 @@ msgid "To Do" msgstr "Задача" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Завършено" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -764,15 +782,27 @@ msgstr "" "му и натиснете „Enter“ клавиша." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "Създаване на „%s“" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"Списъкът с напомняния ще се появи тук. Добавете ново, като натиснете върху " +"„+“ бутона." + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Търсене или Създаване" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "Търсене" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -867,8 +897,8 @@ msgstr "Изчистване" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "Назад" @@ -882,36 +912,13 @@ msgstr "Добавяне на етикети" msgid "Select Labels" msgstr "Избиране на етикети" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "На този компютър" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Без раздел" @@ -927,10 +934,6 @@ msgstr "Раздел" msgid "Select Section" msgstr "Избиране на раздел" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "Търсене" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -962,56 +965,71 @@ msgstr "Добавяне на напомняне" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Задачата е копирана в буфера за обмен" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Проектът е копиран в буфера за обмен." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "Да се премахне ли проекта %s?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "Това не може да бъде върнато" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Изтриване" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "" -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "Премахване на раздела %s" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Премахване на раздела" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1126,49 +1144,58 @@ msgstr "" "работи във фонов режим, когато прозорецът му бъде затворен, за да може да " "изпраща известия за задачи." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "Отваряне на „Бързо Търсене“" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Настройки" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Клавишни комбинации" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "Какво ново има" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "Относно „Planify“" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 #, fuzzy msgid "Archived Projects" msgstr "Добавяне на проект" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Създаване на повече" + +#: src/Services/Backups.vala:411 #, fuzzy msgid "Delete Backup" msgstr "Създаване на резервен файл" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Резервата е внесена успешно" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "Процесът е завършен, трябва да стартирате „Planify“ наново" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Резервни „Planify“ файлове" @@ -1176,96 +1203,76 @@ msgstr "Резервни „Planify“ файлове" msgid "On this computer" msgstr "На този компютър" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "Към „Входящи“" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "Към „Днес“" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "Към „Насрочени“" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "Към „Етикети“" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "Към „Закачени“" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Любими" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "Няма налични любими. Създайте такъв, като натиснете върху „+“ бутона." -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "На този компютър" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "Няма наличен проект. Създайте такъв, като натиснете върху „+“ бутона." - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Какво ново има в „Planify“" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Добавяне на проект" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "" -"Няма наличен профил. Синхронизирайте такъв, като натиснете върху „+“ бутона." - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "Сортирането на проектите е променено на „Друг ред на подредба“" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Премахване от „Любими“" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Добавяне в „Любими“" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Редактиране на проекта" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "Дублиране" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "Презареждане" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Премахване на проект" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Ползвам съвместно" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "Изпращане като писмо" @@ -1274,119 +1281,121 @@ msgstr "Изпращане като писмо" msgid "(No Section)" msgstr "(Без раздел)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Добавяне на задача" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Редактиране на раздела" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Преместване на раздела" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Управляване на реда на разделите" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Премахване на раздела" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "Добавяне на подзадачи" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 #, fuzzy msgid "Add Attachments" msgstr "Добавяне на задача" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Без дата" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Преместване" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Добавяне на подзадача" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Редактиране" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Премахване на задачата" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Избиране на дата" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "Копиране в буфера за обмен" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Повтаряне" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Ежедневно" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Ежеседмично" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Ежемесечно" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Годишно" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "По поръчка, Поръчан (заб.: произлиза от израза Custom-made)" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Завършено. Следващо съвпадение: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s е премахнато" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Отмяна" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "Редът е променен на „Друг ред на подредба“" @@ -1419,20 +1428,24 @@ msgstr "Заглавие" msgid "Properties" msgstr "Свойства" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "Сигурни ли сте, че искате да премахнете?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 #, fuzzy msgid "Open/Close Sidebar" msgstr "Превключване на страничната лента" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "Няма наличен проект. Създайте такъв, като натиснете върху „+“ бутона." + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "Режим „Изключен“ е включен" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1493,7 +1506,7 @@ msgid "Attach File" msgstr "Резервни Файлове" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Свалям, Изтеглям, Източвам" @@ -1515,6 +1528,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Източник" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "Действия по проекта" @@ -1562,13 +1589,13 @@ msgstr "Табло" msgid "Custom sort order" msgstr "Друг ред на подредба" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Азбучен ред" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "Дата на добавяне" @@ -1604,27 +1631,27 @@ msgstr "" msgid "Duedate" msgstr "дата" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Търсене по „Етикети“" @@ -1647,7 +1674,7 @@ msgstr "Премахване на всички завършени задачи" msgid "Sort By" msgstr "Подреждане по" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 #, fuzzy msgid "Filter By" @@ -1680,48 +1707,52 @@ msgstr "Просрочено" msgid "Reschedule" msgstr "Изместване" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Подреждане по" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Етикети: на този компютър" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Етикети: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "Няма налични любими. Създайте такъв, като натиснете върху „+“ бутона." -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "Етикети: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Добавяне на проект" #: src/Views/Filter.vala:535 #, fuzzy, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "Това ще премахне %d завършени задачи и техните подзадачи от проект %s" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Нов проект" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Дайте име на проекта си" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Използване на емотикона" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Източник" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Обновяване на проекта" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Източник" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Проектът е добавен успешно!" @@ -1771,8 +1802,8 @@ msgid "Please enter your credentials" msgstr "Въведете данни за идентификация" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "Мрежата не е достъпна" @@ -1831,7 +1862,7 @@ msgstr "" msgid "Archived" msgstr "" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Въведете термин за търсене" @@ -1978,7 +2009,7 @@ msgstr "" "помислете дали да не ни подкрепите." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Подкрепете ни" @@ -2020,7 +2051,7 @@ msgid "Appearance" msgstr "Изглед" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Бързо добавяне" @@ -2050,7 +2081,7 @@ msgid "Reach Us" msgstr "Потърсете ни" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "Свържете се с нас" @@ -2088,7 +2119,7 @@ msgid "Privacy" msgstr "Дискретност" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Настройки за лични данни" @@ -2292,45 +2323,36 @@ msgid "Dark Blue Style" msgstr "Тъмно син стил" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Профили" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Синхронизиране с профила ви в „Todoist“" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Може да сортирате изгледите си чрез изтегляне и пускане" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "Синхронизация според отворени Интернет стандарти" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Сървър за синхронизация" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Активирайте тази настройка, за да може „Planify“ автоматично да се " "синхронизира с профила ви в „Todoist“ на всеки 15 минути." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Последна синхронизация" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Активирайте тази настройка, за да може „Planify“ автоматично да се " -"синхронизира с вашия CalDAV профил на всеки 15 минути." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2339,7 +2361,7 @@ msgstr "" "работния плот само с няколко натискания на клавиши. Дори не е необходимо да " "напускате приложението, в което се намирате в момента." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2347,74 +2369,72 @@ msgstr "" "Отидете в „Стандартни настройки“ → „Клавиатура“ → „Клавишни комбинации“ → " "„Друг“, след което добавете нова комбинация със следното:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Настройки" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Запазване на последно избрания проект" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "" "Ако е премахната отметката, по подразбиране се избира проекта „Входящи“" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "Командата е копирана в буфера за обмен" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Зареждане…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "Planify синхронизира задачите ви, което може да отнеме няколко минути." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Синхронизиране…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Въведете данни за идентификация" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 #, fuzzy msgid "Nextcloud Setup" msgstr "Nextcloud" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "Адрес на сървъра" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "Потребителско име" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "Парола" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "Услуга" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "Вписване" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "Неуспешно вписване" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Лична информация" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2422,7 +2442,7 @@ msgstr "" "Не събираме абсолютно нищо и всички ваши данни се съхраняват в база данни на " "вашия компютър." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2433,11 +2453,11 @@ msgstr "" "ние само ще показваме конфигурираните от вас задачи и ще ги управляваме за " "вас." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "Имате ли въпроси?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2445,7 +2465,7 @@ msgstr "" "Ако имате въпроси относно вашите данните или друг проблем, моля, свържете се " "с нас. Ще се радваме да ви отговорим." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2455,42 +2475,22 @@ msgstr "" "управление на задачи за потребители от цял свят. Вашите дарения подпомагат " "тази дейност. Искате ли да дарите днес?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Сигурни ли сте, че искате да премахнете Todoist синхронизацията? Това " -"действие ще премахне всички ваши задачи и настройки." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Сигурни ли сте, че искате да премахнете CalDAV синхронизацията? Това " -"действие ще премахне всички ваши задачи и настройки." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Изход" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2512,40 +2512,51 @@ msgstr "Внасяне на резервен файл" msgid "Backup Files" msgstr "Резервни Файлове" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "" +"Няма наличен профил. Синхронизирайте такъв, като натиснете върху „+“ бутона." + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "Мигриране" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "Мигриране от „Planner“" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Задачите са мигрирани успешно" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "Задачите са мигрирани успешно" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "Не съществува базата от данни." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "Преглед на внасяне" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 #, fuzzy msgid "To-Dos" msgstr "Добавяне на задача" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Потвърждаване" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Възстановяване от резервно копие" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2553,15 +2564,15 @@ msgstr "" "Сигурни ли сте, че искате да продължите? Тази операция ще премахне текущите " "ви данни и ще ги замести с резервните данни." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Възстановяване от резервно копие" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "Избраният файл е невалиден" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 #, fuzzy msgid "View Backup" msgstr "Създаване на резервен файл" @@ -2681,8 +2692,50 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Отваряне на „Закачени“" -#~ msgid "CalDAV" -#~ msgstr "CalDAV" +#~ msgid "On this Computer" +#~ msgstr "На този компютър" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Етикети: на този компютър" + +#~ msgid "Labels: Todoist" +#~ msgstr "Етикети: Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "Етикети: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Синхронизиране с профила ви в „Todoist“" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "Синхронизация според отворени Интернет стандарти" + +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Активирайте тази настройка, за да може „Planify“ автоматично да се " +#~ "синхронизира с вашия CalDAV профил на всеки 15 минути." + +#~ msgid "Failed to login" +#~ msgstr "Неуспешно вписване" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Сигурни ли сте, че искате да премахнете Todoist синхронизацията? Това " +#~ "действие ще премахне всички ваши задачи и настройки." + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Сигурни ли сте, че искате да премахнете CalDAV синхронизацията? Това " +#~ "действие ще премахне всички ваши задачи и настройки." + +#~ msgid "Sign Off" +#~ msgstr "Изход" #~ msgid "CalDAV Setup" #~ msgstr "Настройване на CalDAV" diff --git a/po/de.po b/po/de.po index a4e97b6a2..48aea8a91 100644 --- a/po/de.po +++ b/po/de.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-06-03 01:28+0200\n" "Last-Translator: alp10711 <93343276+alp10711@users.noreply.github.com>\n" "Language-Team: German\n" @@ -24,7 +24,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -33,7 +33,7 @@ msgstr "" msgid "Today" msgstr "Heute" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -43,7 +43,7 @@ msgstr "Heute" msgid "Inbox" msgstr "Posteingang" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -57,135 +57,146 @@ msgstr "Geplant" msgid "Pinboard" msgstr "Pinnwand" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Projekte" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Abschnitte" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Aufgaben" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Kennzeichnungen" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Filter" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Listen" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Nicht wiederholen" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "Jede Minute" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "Alle %d Minuten" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "Jede Stunde" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "Alle %d Stunden" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Jeden Tag" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "Alle %d Tage" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Jede Woche" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "Alle %d Wochen" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Jeden Monat" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "Alle %d Monate" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Jedes Jahr" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "Alle %d Jahre" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Priorität" -#: core/Enum.vala:365 +#: core/Enum.vala:419 #, fuzzy msgid "Label" msgstr "Kennzeichnungen" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 #, fuzzy msgid "Due Date" msgstr "Fälligkeitsdatum" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Duplizieren" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Duplizieren" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Beschreibung" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 #, fuzzy msgid "Pin" msgstr "Angeheftet" @@ -312,8 +323,8 @@ msgstr "Dunkel" msgid "Dark Blue" msgstr "Dunkelblau" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Keine" @@ -322,17 +333,16 @@ msgstr "Keine" msgid "Today + Inbox" msgstr "Heute + Posteingang" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Abbrechen" @@ -344,9 +354,8 @@ msgstr "Alles löschen" msgid "Process completed, you need to start Planify again." msgstr "Aufgabe abgeschlossen, bitte Planify erneut starten." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "Ok" @@ -382,11 +391,15 @@ msgstr "niedrig" msgid "none" msgstr "keine" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "Auf diesem Computer" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Lerne Planify kennen" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -396,11 +409,11 @@ msgstr "" "können. Zögere nicht, hier herumzuspielen - Du kannst jederzeit ein neues in " "den Einstellungen erstellen." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Klicke auf diese Aufgabe" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -409,11 +422,11 @@ msgstr "" "linken Seite klickst. Erledigte Aufgaben werden am unteren Ende des Projekts " "gesammelt." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Erstelle eine neue Aufgabe" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -422,21 +435,21 @@ msgstr "" "deines Projekts, gib die geforderten Daten ein und tippe auf die blaue " "Schaltfläche \"Speichern\"." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Plane diese Aufgabe für heute oder später" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Tippe auf die Kalender-Schaltfläche unten, um zu entscheiden, wann du diese " "Aufgabe erledigen möchtest." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Ordne deine Aufgaben neu an" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -444,11 +457,11 @@ msgstr "" "Um deine Liste neu anzuordnen, tippe und halte eine Aufgabe gedrückt und " "ziehe sie dann an die gewünschte Stelle." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Erstelle ein Projekt" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -457,11 +470,11 @@ msgstr "" "Schaltfläche '+' im Abschnitt 'Auf diesem Computer' und füge ein eigenes " "Projekt hinzu." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "Du bist fertig!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 #, fuzzy msgid "" "That’s all you really need to know. Feel free to start adding your own " @@ -476,15 +489,15 @@ msgstr "" "Features kennenzulernen..\n" "Viel Spaß beim Nutzen von Planify!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Richte deine Umgebung ein" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Termine aus dem Kalender anzeigen" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -493,11 +506,11 @@ msgstr "" "Du kannst die Termine deines Systemkalenders in Planify anzeigen. Gehe zu " "'Einstellungen' 🡒 Kalenderereignisse, um dies zu aktivieren." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Aktiviere die Synchronisation mit einem Drittanbieterdienst." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -505,15 +518,15 @@ msgstr "" "Planify erstellt nicht nur lokal Aufgaben, sondern kann sich auch mit deinem " "Todoist-Konto synchronisieren. Gehe zu 'Einstellungen' 🡒 'Konten'." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Steigere deine Produktivität" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Ziehe den Plus-Knopf!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -522,11 +535,11 @@ msgstr "" "mächtiger, als er aussieht: Er kann sich zu bewegen! Ziehe ihn nach oben, um " "eine Aufgabe dort zu erstellen, wo du willst." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "Kennzeichne deine Aufgaben!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -535,11 +548,11 @@ msgstr "" "Klicke auf die Kennzeichnen Schaltfläche unten, um eine Kennzeichnung " "hinzuzufügen." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Lege zeitliche Erinnerungen fest!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -548,78 +561,78 @@ msgstr "" "Besonderes erinnert. Tippe auf den Glockenknopf unten, um eine Erinnerung " "hinzuzufügen." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️Arbeit" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️Schule" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️Aufträge" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️Zuhause" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️Nochmal aufgreifen" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, fuzzy, c-format msgid "Task moved to %s" msgstr "Aufgabe in die Zwischenablage kopiert" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 #, fuzzy msgid "Task duplicated" msgstr "Duplizieren" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 #, fuzzy msgid "Section duplicated" msgstr "Abschnittsname" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 #, fuzzy msgid "Project duplicated" msgstr "Projekte" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Morgen" @@ -674,42 +687,47 @@ msgstr "Sa," msgid "Su," msgstr "So," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "Die Anfrage war falsch." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "" "Authentifizierung ist erforderlich und ist fehlgeschlagen oder wurde noch " "nicht übermittelt." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "Die Anfrage war gültig, aber für etwas, das verboten ist." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "Die angeforderte Ressource konnte nicht gefunden werden." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "" "Der Nutzer hat zu viele Anfragen in einer bestimmten Zeitspanne gesendet." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "Die Anfrage ist aufgrund eines Serverfehlers fehlgeschlagen." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "Der Server ist derzeit nicht in der Lage, die Anfrage zu bearbeiten." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Unbekannter Fehler" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Nicht verfügbar" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "Angeheftet" @@ -756,11 +774,11 @@ msgid "To Do" msgstr "Zu tun" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Erledigen" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -769,15 +787,28 @@ msgstr "" "Namen eingibst und die Eingabetaste drückst." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "'%s' erstellen" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"Die Liste deiner Erinnerungen wird hier angezeigt. Füge eine hinzu, indem du " +"auf den '+'-Knopf klickst." + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Suchen oder Erstellen" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +#, fuzzy +msgid "Search" +msgstr "Suchen" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -873,8 +904,8 @@ msgstr "Löschen" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "Zurück" @@ -889,36 +920,13 @@ msgstr "Kennzeichnungen hinzufügen" msgid "Select Labels" msgstr "Kennzeichnung löschen" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "Auf diesem Computer" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Ohne Abschnitt" @@ -937,11 +945,6 @@ msgstr "Abschnitte" msgid "Select Section" msgstr "Abschnitt löschen" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -#, fuzzy -msgid "Search" -msgstr "Suchen" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -973,56 +976,71 @@ msgstr "Erinnerung hinzufügen" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Aufgabe in die Zwischenablage kopiert" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Das Projekt wurde in die Zwischenablage kopiert" -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, fuzzy, c-format msgid "Delete Project %s?" msgstr "Projekt %s löschen?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "Dies kann nicht rückgängig gemacht werden" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Löschen" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "Archivieren?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "Dies wird %s und alle seine Aufgaben archivieren." -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "Archiv" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, fuzzy, c-format msgid "Delete Section %s" msgstr "Abschnitt %s löschen" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Abschnitt löschen" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1145,49 +1163,58 @@ msgstr "" "wird ausgeführt, wenn das Fenster geschlossen wird, so dass es " "Aufgabenbenachrichtigungen senden kann." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "Hauptmenü" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "Schnelle Suche öffnen" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Einstellungen" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Tastenkombinationen" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "Neuigkeiten" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "Über Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 #, fuzzy msgid "Archived Projects" msgstr "Projekt hinzufügen" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Weitere erstellen" + +#: src/Services/Backups.vala:411 #, fuzzy msgid "Delete Backup" msgstr "Sicherung erstellen" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Sicherung erfolgreich importiert" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "Prozess abgeschlossen, bitte starte Planify neu" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Planify Sicherungsdateien" @@ -1195,101 +1222,79 @@ msgstr "Planify Sicherungsdateien" msgid "On this computer" msgstr "Auf diesem Computer" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "Zum Posteingang" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "Nach 'Heute'" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "Nach 'Geplant'" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "Zu 'Kennzeichnungen'" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "Zur 'Pinnwand'" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Favoriten" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "" "Keine Favoriten verfügbar. Erstelle einen, indem du auf den '+' Knopf " "klickst." -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "Auf diesem Computer" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "" -"Kein Projekt vorhanden. Erstelle eins, indem du auf den \"+\" Knopf klickst." - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Neues in Planify" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Projekt hinzufügen" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "" -"Es ist kein Account vorhanden, synchronisiere einen Account, indem du auf " -"den '+'-Knopf klickst" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "" "Projektsortierung wurde in 'Benutzerdefinierte Sortierreihenfolge' geändert." -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Aus Favoriten entfernen" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Zu Favoriten hinzufügen" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Projekt bearbeiten" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "Duplizieren" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "Neu laden" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Projekt löschen" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Teilen" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "Per E-Mail senden" @@ -1298,119 +1303,121 @@ msgstr "Per E-Mail senden" msgid "(No Section)" msgstr "(Ohne Abschnitt)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Aufgabe hinzufügen" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Abschnitt bearbeiten" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Abschnitt verschieben" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Reihenfolge der Abschnitte verändern" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Abschnitt löschen" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "Unteraufgaben hinzufügen" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 #, fuzzy msgid "Add Attachments" msgstr "Aufgabe hinzufügen" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Kein Datum" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Verschieben" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Unteraufgabe hinzufügen" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Bearbeiten" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Aufgabe löschen" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Datum auswählen" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "In die Zwischenablage kopieren" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Wiederholen" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Täglich" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Wöchentlich" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Monatlich" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Jährlich" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Benutzerdefiniert" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Erledigt. Nächstes vorkommen: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s wurde gelöscht" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Rückgängig machen" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "Sortierung wurde in 'Benutzerdefinierte Sortierreihenfolge' geändert." @@ -1444,21 +1451,26 @@ msgstr "Titel" msgid "Properties" msgstr "Eigenschaften" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 #, fuzzy msgid "Are you sure you want to delete?" msgstr "Bist du sicher, dass du %s löschen möchtest?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 #, fuzzy msgid "Open/Close Sidebar" msgstr "Seitenleiste umschalten" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "" +"Kein Projekt vorhanden. Erstelle eins, indem du auf den \"+\" Knopf klickst." + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "Offline-Modus ist aktiviert" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1520,7 +1532,7 @@ msgid "Attach File" msgstr "Sicherungsdateien" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Herunterladen" @@ -1542,6 +1554,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Quelle" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 #, fuzzy msgid "Project Actions" @@ -1590,13 +1616,13 @@ msgstr "Board" msgid "Custom sort order" msgstr "Benutzerdefinierte Sortierreihenfolge" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Alphabetisch" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 #, fuzzy msgid "Date Added" @@ -1633,27 +1659,27 @@ msgstr "Nächste 30 Tage" msgid "Duedate" msgstr "Anwenden" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Nach Kennzeichnungen filtern" @@ -1677,7 +1703,7 @@ msgstr "Erledigte Aufgaben unterstreichen" msgid "Sort By" msgstr "Sortieren nach" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 #, fuzzy msgid "Filter By" @@ -1713,48 +1739,54 @@ msgstr "Überfällig" msgid "Reschedule" msgstr "Neu planen" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Sortieren nach" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Kennzeichnungen: Auf diesem Computer" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Kennzeichnungen: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "" +"Keine Favoriten verfügbar. Erstelle einen, indem du auf den '+' Knopf " +"klickst." -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "Kennzeichnungen: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Projekt hinzufügen" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "Dies wird %d vollendete Aufgaben und deren Unteraufgaben löschen" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Neues Projekt" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Gib deinem Projekt einen Namen" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Emoji nutzen" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Quelle" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Projekt aktualisieren" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Quelle" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Projekt erfolgreich hinzugefügt!" @@ -1804,8 +1836,8 @@ msgid "Please enter your credentials" msgstr "Bitte gib deine Anmeldedaten ein" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "Netzwerk ist nicht verfügbar" @@ -1879,7 +1911,7 @@ msgstr "" msgid "Archived" msgstr "Archiviert" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Suche eingeben" @@ -2027,7 +2059,7 @@ msgstr "" "Betracht, uns zu unterstützen." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Uns unterstützen" @@ -2069,7 +2101,7 @@ msgid "Appearance" msgstr "Erscheinungsbild" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Schnell hinzufügen" @@ -2101,7 +2133,7 @@ msgid "Reach Us" msgstr "Kontakt aufnehmen" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "Kontaktiere uns" @@ -2139,7 +2171,7 @@ msgid "Privacy" msgstr "Datenschutz" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Datenschutzerklärung" @@ -2343,47 +2375,37 @@ msgid "Dark Blue Style" msgstr "Dunkelblauer Stil" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Konten" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Mit deinem Todoist Account synchronisieren" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Du kannst diese Kategorien per Drag & Drop sortieren" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "Synchronisierung auf der Grundlage offener Internet-Standards" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Mit Server synchronisieren" # Assumed error "Planner" -> "Planify" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Aktiviere diese Einstellung, damit Planify alle 15 Minuten automatisch mit " "deinem Todoist-Konto synchronisiert wird" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Letzte Synchronisation" -# Assumed error "Planner" -> "Planify" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Aktiviere diese Einstellung, damit Planify alle 15 Minuten automatisch mit " -"deinem CalDAV-Konto synchronisiert wird" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2392,7 +2414,7 @@ msgstr "" "mit nur wenigen Tastenanschlägen zu erstellen. Du musst nicht einmal die App " "verlassen, in der du dich gerade befindest." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2400,77 +2422,75 @@ msgstr "" "Gehe zu Systemeinstellungen → Tastatur → Tastenkombinationen → Eigene " "Tastenkombinationen und füge dann eine neue Kombination mit folgendem hinzu:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Einstellungen" # Assumed task is saved to the last selected project -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Im zuletzt ausgewählten Projekt speichern" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "" "Wenn nicht aktiviert, wird standardmäßig das Posteingangsprojekt ausgewählt" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "Der Befehl wurde in die Zwischenablage kopiert" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Laden…" # Assumed error "Planner" -> "Planify" and "is sync" -> "is syncing" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "" "Planify synchronisiert deine Aufgaben, das kann ein paar Minuten dauern" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Synchronisieren..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Bitte gib deine Anmeldedaten ein" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 #, fuzzy msgid "Nextcloud Setup" msgstr "Nextcloud" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "Server-URL" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "Nutzername" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "Passwort" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "Anbieter" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "Anmelden" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "Anmeldung fehlgeschlagen" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Persönliche Daten" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2478,7 +2498,7 @@ msgstr "" "Wir sammeln absolut nichts und all deine Daten werden in einer Datenbank auf " "deinem Computer gespeichert." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2489,11 +2509,11 @@ msgstr "" "Servern gespeichert. Wir zeigen nur deine konfigurierten Aufgaben an und " "verwalten sie für dich." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "Hast du Fragen?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2501,7 +2521,7 @@ msgstr "" "Wenn du Fragen zu deinen Daten oder ein anderes Problem hast, melde dich " "bitte bei uns. Wir helfen dir gerne weiter." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2511,42 +2531,22 @@ msgstr "" "Menschen rund um den Globus bereitzustellen. Deine Spenden unterstützen " "diese Arbeit. Möchtest du noch heute spenden" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Bist du sicher, dass du die Todoist-Synchronisierung entfernen möchtest? " -"Dadurch werden alle deine Aufgaben und Einstellungen gelöscht." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Bist du sicher, dass du die CalDAV-Synchronisierung entfernen möchtest? " -"Dadurch werden alle deine Aufgaben und Einstellungen gelöscht." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Abmelden" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2568,41 +2568,53 @@ msgstr "Sicherung wiederherstellen" msgid "Backup Files" msgstr "Sicherungsdateien" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "" +"Es ist kein Account vorhanden, synchronisiere einen Account, indem du auf " +"den '+'-Knopf klickst" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "Migrieren" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "Von Planner migrieren" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Aufgaben erfolgreich migriert" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "Aufgaben erfolgreich migriert" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "Die Datenbankdatei ist nicht vorhanden." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "Wiederherstellungsübersicht" # Maybe just "Hinzufügen" because of space issues -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 #, fuzzy msgid "To-Dos" msgstr "Aufgabe hinzufügen" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Bestätigen" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Sicherung wiederherstellen" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2610,15 +2622,15 @@ msgstr "" "Bist du sicher, dass du fortfahren möchtest? Diese Aktion wird deine " "aktuellen Daten löschen und durch die Sicherungsdaten ersetzen." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Sicherung wiederherstellen" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "Ausgewählte Datei ist ungültig" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 #, fuzzy msgid "View Backup" msgstr "Sicherung erstellen" @@ -2738,12 +2750,55 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "'Pinnwand' öffnen" +#~ msgid "On this Computer" +#~ msgstr "Auf diesem Computer" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Kennzeichnungen: Auf diesem Computer" + +#~ msgid "Labels: Todoist" +#~ msgstr "Kennzeichnungen: Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "Kennzeichnungen: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Mit deinem Todoist Account synchronisieren" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "Synchronisierung auf der Grundlage offener Internet-Standards" + +# Assumed error "Planner" -> "Planify" +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Aktiviere diese Einstellung, damit Planify alle 15 Minuten automatisch " +#~ "mit deinem CalDAV-Konto synchronisiert wird" + +#~ msgid "Failed to login" +#~ msgstr "Anmeldung fehlgeschlagen" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Bist du sicher, dass du die Todoist-Synchronisierung entfernen möchtest? " +#~ "Dadurch werden alle deine Aufgaben und Einstellungen gelöscht." + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Bist du sicher, dass du die CalDAV-Synchronisierung entfernen möchtest? " +#~ "Dadurch werden alle deine Aufgaben und Einstellungen gelöscht." + +#~ msgid "Sign Off" +#~ msgstr "Abmelden" + #~ msgid "Add" #~ msgstr "Hinzufügen" -#~ msgid "CalDAV" -#~ msgstr "CalDAV" - #~ msgid "CalDAV Setup" #~ msgstr "CalDAV Einrichtung" diff --git a/po/es.po b/po/es.po index b8e9808d1..5e77c7a08 100644 --- a/po/es.po +++ b/po/es.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-07-12 13:54-0400\n" "Last-Translator: \n" "Language-Team: \n" @@ -21,7 +21,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -30,7 +30,7 @@ msgstr "" msgid "Today" msgstr "Hoy" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -40,7 +40,7 @@ msgstr "Hoy" msgid "Inbox" msgstr "Bandeja de entrada" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -54,131 +54,142 @@ msgstr "Planificado" msgid "Pinboard" msgstr "Importantes" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Projectos" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Secciones" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Tareas" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Etiquetas" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Filtros" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Listas" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "No repetir" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "Cada minuto" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "Cada %d minutos" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "Cada hora" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "Cada %d horas" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Cada día" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "Cada %d días" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Cada semana" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "Cada %d semanas" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Cada mes" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "Cada %d meses" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Cada año" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "Cada %d años" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Prioridad" -#: core/Enum.vala:365 +#: core/Enum.vala:419 msgid "Label" msgstr "Etiqueta" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "Fecha de vencimiento" -#: core/Enum.vala:474 +#: core/Enum.vala:528 msgid "Task Created" msgstr "Tarea creada" -#: core/Enum.vala:477 +#: core/Enum.vala:531 msgid "Task Updated" msgstr "Tarea actualizada" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "Contenido" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Descripción" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 msgid "Pin" msgstr "Fijar" @@ -302,8 +313,8 @@ msgstr "Oscuro" msgid "Dark Blue" msgstr "Azul oscuro" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Ninguno" @@ -312,17 +323,16 @@ msgstr "Ninguno" msgid "Today + Inbox" msgstr "Hoy + Bandeja de entrada" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Cancelar" @@ -334,9 +344,8 @@ msgstr "Borrar todo" msgid "Process completed, you need to start Planify again." msgstr "Proceso completado, necesita iniciar Planify de nuevo." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "Ok" @@ -372,11 +381,15 @@ msgstr "baja" msgid "none" msgstr "ninguna" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "En este ordenador" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Descubra Planify" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -386,11 +399,11 @@ msgstr "" "obra. No dude en jugar con él: siempre puede crear uno nuevo a partir de la " "configuración." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Toque esta tarea" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -399,11 +412,11 @@ msgstr "" "izquierda. Las tareas pendientes completadas se recopilan en la parte " "inferior de su proyecto." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Cree una nueva tarea pendiente" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -411,21 +424,21 @@ msgstr "" "Ahora es su turno, toque el botón \"+\" en la parte inferior de su proyecto, " "introduzca cualquier pendiente y toque el botón azul \"Guardar\"." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Planifique esta tarea para hoy o más tarde" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Pulse el botón del calendario en la parte inferior para decidir cuándo hacer " "esta tarea." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Reordene sus tareas pendientes" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -433,11 +446,11 @@ msgstr "" "Para reordenar su lista, mantenga pulsada una tarea y arrástrela hacia donde " "deba ir." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Cree un proyecto" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -446,11 +459,11 @@ msgstr "" "en el botón '+' en la sección 'En este ordenador' y agregue su propio " "proyecto." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "¡Ha terminado!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 msgid "" "That’s all you really need to know. Feel free to start adding your own " "projects and to-dos.\n" @@ -464,15 +477,15 @@ msgstr "" "avanzadas a continuación..\n" "¡Esperamos que disfrutes usando Planify!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Ajuste su configuración" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Muestre los eventos de su calendario" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 msgid "" "You can display your system's calendar events in Planify. Go to " "'Preferences' 🡒 General 🡒 Calendar Events to turn it on." @@ -480,11 +493,11 @@ msgstr "" "Puedes mostrar los eventos del calendario de tu sistema en Planify. Ve a " "'Preferencias' 🡒 General 🡒 Eventos de calendario para activarlo." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Habilitar sincronización con servicio de terceros." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -492,15 +505,15 @@ msgstr "" "Planify no solo crea tareas localmente, también puede sincronizar su cuenta " "Todoist. Ve a 'Preferencias' 🡒 'Cuentas'." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Aumente su productividad" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "¡Arrastre el botón más!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -509,11 +522,11 @@ msgstr "" "de lo que parece: ¡está hecho para moverse! Arrástrelo hacia arriba para " "crear una tarea donde quiera." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "¡Etiquete sus tareas pendientes!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -522,11 +535,11 @@ msgstr "" "añadir una etiqueta, haga clic en el botón de la etiqueta en la parte " "inferior." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "¡Establezca recordatorios oportunos!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -535,75 +548,75 @@ msgstr "" "importante o algo especial. Toca el botón de la campana de abajo para añadir " "un recordatorio." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️Trabajo" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️Colegio" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️Delegado" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️Casa" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️Dar seguimiento" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, c-format msgid "Task moved to %s" msgstr "Tarea movida a %s" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 msgid "Task duplicated" msgstr "Tarea duplicada" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 msgid "Section duplicated" msgstr "Sección duplicada" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 msgid "Project duplicated" msgstr "Proyecto duplicado" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "A su debido tiempo" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "10 minutos antes" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "30 minutos antes" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "45 minutos antes" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "1 hora antes" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "2 horas antes" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "3 horas antes" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Mañana" @@ -658,39 +671,44 @@ msgstr "Sab," msgid "Su," msgstr "Dom," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "La solicitud no era correcta." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "Se requiere autenticación, y ha fallado, o aún no se ha proporcionado." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "La petición era válida, pero para algo que está prohibido." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "No se ha podido encontrar el recurso solicitado." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "El usuario ha enviado demasiadas solicitudes en un tiempo determinado." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "La solicitud ha fallado debido a un error del servidor." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "El servidor no puede procesar la solicitud." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Error desconocido" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "No disponible" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "Fijado" @@ -735,11 +753,11 @@ msgid "To Do" msgstr "Por hacer" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Completar" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -748,15 +766,27 @@ msgstr "" "pulsando la tecla Intro." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "Crear '%s" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"Aquí aparecerá su lista de recordatorios. Añada uno haciendo clic en el " +"botón \"+\"." + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Buscar o crear" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "Buscar" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -851,8 +881,8 @@ msgstr "Eliminar" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "Atrás" @@ -866,36 +896,13 @@ msgstr "Añadir etiquetas" msgid "Select Labels" msgstr "Seleccionar etiquetas" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "En este ordenador" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Sin secciones" @@ -911,10 +918,6 @@ msgstr "Seccion" msgid "Select Section" msgstr "Seleccionar sección" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "Buscar" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -947,56 +950,71 @@ msgid "Couldn't find an app to handle file URIs" msgstr "" "No se ha podido encontrar una aplicación que gestione los URI de los archivos" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Tarea copiada al portapapeles" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "El proyecto fue copiado al Portapapeles." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "¿Eliminar proyecto %s?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "Esto no se puede deshacer" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Eliminar" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "Archivar?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "Esto archivará %s y todas sus tareas." -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "Archivo" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "Eliminar sección %s" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Eliminar sección" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1108,47 +1126,56 @@ msgstr "" "ejecutará cuando se cierre su ventana para poder enviar notificaciones de " "tareas pendientes." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "Menú principal" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "Abrir Búsqueda rápida" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Preferencias" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Atajos de teclado" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "Novedades" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "Acerca de Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 msgid "Archived Projects" msgstr "Proyectos archivados" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Crear más" + +#: src/Services/Backups.vala:411 msgid "Delete Backup" msgstr "Eliminar copia de seguridad" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Copia de seguridad importada correctamente" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "Proceso completado, necesita iniciar Planify de nuevo" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Archivos de copia de seguridad de Planify" @@ -1156,98 +1183,76 @@ msgstr "Archivos de copia de seguridad de Planify" msgid "On this computer" msgstr "En este ordenador" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "Ir a la bandeja de entrada" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "Ir a Hoy" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "Ir a Planificado" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "Ir a Etiquetas" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "Ir a Importantes" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Favoritos" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "No hay favoritos disponibles. Cree uno haciendo clic en el botón \"+\"" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "En este ordenador" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "" -"No hay ningún proyecto disponible. Cree uno haciendo clic en el botón \"+\"" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Novedades de Planify" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Añadir proyecto" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "" -"No hay ninguna cuenta disponible. Sincronice una haciendo clic en el botón " -"\"+\"" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "Orden de los proyectos cambiada a \"Ordenación personalizada\"" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Eliminar de favoritos" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Agregar a favoritos" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Editar proyecto" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "Duplicada" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "Actualizar" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Eliminar proyecto" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Compartir" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "Enviar por E-Mail" @@ -1256,117 +1261,119 @@ msgstr "Enviar por E-Mail" msgid "(No Section)" msgstr "(Sin sección)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Añadir tarea" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Editar sección" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Mover sección" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Gestionar el orden de las secciones" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Eliminar sección" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "Añadir Subtarea" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 msgid "Add Attachments" msgstr "Agregar archivos adjuntos" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Sin fecha" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Mover" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Añadir subtarea" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Editar" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Eliminar tarea" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 msgid "Use as a Note" msgstr "Utilizar como nota" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "Copiar al Portapapeles" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Repetir" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "Historial de cambios" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "A diario" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Semanalmente" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Mensualmente" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Anualmente" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Personalizado" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Completada. Próxima aparición: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s fue eliminado" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Deshacer" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "Orden cambiado a 'Orden de clasificación personalizado'" @@ -1399,19 +1406,24 @@ msgstr "Título" msgid "Properties" msgstr "Propiedades" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "¿Seguro que quieres borrarlo?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 msgid "Open/Close Sidebar" msgstr "Abrir/Cerrar la barra lateral" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "" +"No hay ningún proyecto disponible. Cree uno haciendo clic en el botón \"+\"" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "El modo offline está activado" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1470,7 +1482,7 @@ msgid "Attach File" msgstr "Adjuntar archivo" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Descargar" @@ -1492,6 +1504,20 @@ msgstr "Pin: Activo" msgid "Pin: Inactive" msgstr "Pin: Inactivo" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Fuerte" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "Acciones del proyecto" @@ -1538,13 +1564,13 @@ msgstr "Tablón" msgid "Custom sort order" msgstr "Orden personalizado" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Alfabéticamente" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "Fecha de adición" @@ -1578,27 +1604,27 @@ msgstr "Próximos 30 días" msgid "Duedate" msgstr "Fecha de vencimiento" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Filtrar por etiquetas" @@ -1620,7 +1646,7 @@ msgstr "Eliminar todas las tareas completadas" msgid "Sort By" msgstr "Ordenar por" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 msgid "Filter By" msgstr "Filtrar por" @@ -1652,48 +1678,52 @@ msgstr "Atrasada" msgid "Reschedule" msgstr "Reprogramar" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Ordenar por" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Etiquetas: En este ordenador" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Etiquetas: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "No hay favoritos disponibles. Cree uno haciendo clic en el botón \"+\"" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "Etiquetas: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Añadir proyecto" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "Esto eliminará %d tareas completadas y sus subtareas" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Nuevo proyecto" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Dele un nombre a su proyecto" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Usar emojis" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Fuerte" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Actualizar proyecto" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Fuerte" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "¡Proyecto añadido con éxito!" @@ -1742,8 +1772,8 @@ msgid "Please enter your credentials" msgstr "Introduzca sus credenciales" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "La red no está disponible" @@ -1813,7 +1843,7 @@ msgstr "" msgid "Archived" msgstr "Archivados" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Escriba una búsqueda" @@ -1962,7 +1992,7 @@ msgstr "" "considera apoyarnos." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Apóyenos" @@ -2003,7 +2033,7 @@ msgid "Appearance" msgstr "Apariencia" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Añadir Rápido" @@ -2033,7 +2063,7 @@ msgid "Reach Us" msgstr "Contacte con nosotros" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "Contáctenos" @@ -2071,7 +2101,7 @@ msgid "Privacy" msgstr "Privacidad" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Política de privacidad" @@ -2274,45 +2304,36 @@ msgid "Dark Blue Style" msgstr "Estilo Azul Oscuro" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Cuentas" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Sincronizar con su cuenta Todoist" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Puede ordenar las vistas arrastrando y soltando" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "Sincronización basada en normas abiertas de Internet" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Sincronizar servidor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Active esta opción para que Planify se sincronice automáticamente con su " "cuenta Todoist cada 15 minutos" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Última sincronización" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Active esta opción para que Planify se sincronice automáticamente con su " -"cuenta CalDAV cada 15 minutos" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2321,7 +2342,7 @@ msgstr "" "su escritorio con sólo pulsar unas teclas. Ni siquiera tiene que salir de la " "aplicación en la que se encuentra." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2329,74 +2350,72 @@ msgstr "" "Vaya a Configuración del sistema → Teclado → Accesos directos → " "Personalizados y añada un nuevo acceso directo con lo siguiente:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Configuraciones" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Guardar el último proyecto seleccionado" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "" "Si no está marcada, el proyecto seleccionado por defecto es Bandeja de " "entrada" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "El comando fue copiado al portapapeles" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Cargando…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "Planify está sincronizando sus tareas, esto puede tardar unos minutos" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Sincronizando..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Por favor, introduzca sus credenciales" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "Configuración de Nextcloud" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "URL del servidor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "Nombre de usuario" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "Contraseña" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "Proveedor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "Iniciar sesión" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "Error al iniciar sesión" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Datos personales" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2404,7 +2423,7 @@ msgstr "" "No recopilamos absolutamente nada y todos sus datos se almacenan en una base " "de datos en su ordenador." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2414,11 +2433,11 @@ msgstr "" "defecto, sus datos se almacenarán en sus servidores privados, nosotros sólo " "mostramos sus tareas configuradas y las gestionamos por usted." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "¿Tiene alguna pregunta?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2426,7 +2445,7 @@ msgstr "" "Si tiene alguna pregunta sobre sus datos o cualquier otra cuestión, póngase " "en contacto con nosotros. Estaremos encantados de responderle." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2436,42 +2455,22 @@ msgstr "" "código abierto para usuarios de todo el mundo. Tus donaciones apoyan este " "trabajo. ¿Quieres donar hoy?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"¿Está seguro de que quiere eliminar la sincronización de Todoist? Esta " -"acción borrará todas sus tareas y configuraciones." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"¿Está seguro de que quiere eliminar la sincronización CalDAV? Esta acción " -"eliminará todas sus tareas y configuraciones." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Cerrar sesión" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2492,39 +2491,51 @@ msgstr "Importar copia de seguridad" msgid "Backup Files" msgstr "Archivos de copia de seguridad" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "" +"No hay ninguna cuenta disponible. Sincronice una haciendo clic en el botón " +"\"+\"" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "Migrar" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "Migrar desde Planner" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Tareas migradas con éxito" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "Tareas migradas con éxito" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "El archivo de base de datos no existe." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "Descripción general de la importación" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 msgid "To-Dos" msgstr "Tareas pendientes" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Confirmar" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Restaurar copia de seguridad" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2532,15 +2543,15 @@ msgstr "" "¿Está seguro de que desea continuar? Esta operación borrará sus datos " "actuales y los sustituirá por los datos de la copia de seguridad." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Restaurar copia de seguridad" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "El archivo seleccionado no es válido" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 msgid "View Backup" msgstr "Ver copia de seguridad" @@ -2659,12 +2670,54 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Abrir Importantes" +#~ msgid "On this Computer" +#~ msgstr "En este ordenador" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Etiquetas: En este ordenador" + +#~ msgid "Labels: Todoist" +#~ msgstr "Etiquetas: Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "Etiquetas: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Sincronizar con su cuenta Todoist" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "Sincronización basada en normas abiertas de Internet" + +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Active esta opción para que Planify se sincronice automáticamente con su " +#~ "cuenta CalDAV cada 15 minutos" + +#~ msgid "Failed to login" +#~ msgstr "Error al iniciar sesión" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "¿Está seguro de que quiere eliminar la sincronización de Todoist? Esta " +#~ "acción borrará todas sus tareas y configuraciones." + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "¿Está seguro de que quiere eliminar la sincronización CalDAV? Esta acción " +#~ "eliminará todas sus tareas y configuraciones." + +#~ msgid "Sign Off" +#~ msgstr "Cerrar sesión" + #~ msgid "Add" #~ msgstr "Agregar" -#~ msgid "CalDAV" -#~ msgstr "CalDAV" - #~ msgid "CalDAV Setup" #~ msgstr "Configuración de CalDAV" diff --git a/po/fr.po b/po/fr.po index 769bd8603..8f7aaf1eb 100644 --- a/po/fr.po +++ b/po/fr.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: com.github.alainm23.planner\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-05-28 19:25+0200\n" "Last-Translator: Irénée Thirion \n" "Language-Team: French \n" @@ -23,7 +23,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -32,7 +32,7 @@ msgstr "" msgid "Today" msgstr "Aujourd’hui" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -42,7 +42,7 @@ msgstr "Aujourd’hui" msgid "Inbox" msgstr "Boîte de réception" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -56,133 +56,144 @@ msgstr "Prévu" msgid "Pinboard" msgstr "Épinglé" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Projets" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Sections" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Tâches" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Étiquettes" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Filtres" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Listes" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Ne pas répéter" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "Chaque minute" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "Toutes les %d minutes" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "Chaque heure" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "Toutes les %d heures" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Chaque jour" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "Tous les %d jours" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Chaque semaine" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "Toutes les %d semaines" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Chaque mois" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "Tous les %d mois" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Chaque année" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "Toutes les %d années" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Priorité" -#: core/Enum.vala:365 +#: core/Enum.vala:419 msgid "Label" msgstr "Étiquette" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "Date d’échéance" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Tâche dupliquée" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Tâche dupliquée" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Description" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 msgid "Pin" msgstr "Épingler" @@ -306,8 +317,8 @@ msgstr "Sombre" msgid "Dark Blue" msgstr "Bleu sombre" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Aucun" @@ -316,17 +327,16 @@ msgstr "Aucun" msgid "Today + Inbox" msgstr "Aujourd’hui + Boîte de réception" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Annuler" @@ -338,9 +348,8 @@ msgstr "Tout supprimer" msgid "Process completed, you need to start Planify again." msgstr "Processus achevé, vous devez redémarrer Planify." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "OK" @@ -376,11 +385,15 @@ msgstr "basse" msgid "none" msgstr "aucune" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "Sur cet ordinateur" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Découvrir Planify" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -390,11 +403,11 @@ msgstr "" "bien commencer. N’hésitez pas à vous amuser avec – vous pouvez toujours en " "créer un nouveau depuis les paramètres." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Cliquez sur cette tâche" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -403,11 +416,11 @@ msgstr "" "cliquant sur la case à cocher sur la gauche. Les tâches accomplies " "apparaîtront en bas de votre projet." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Créer une nouvelle tâche" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -415,21 +428,21 @@ msgstr "" "Maintenant c’est à vous : cliquez sur le bouton '+' en bas de votre projet, " "saisissez un contenu et cliquez sur le bouton bleu « Enregistrer »." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Planifier cette tâche pour aujourd’hui ou plus tard" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Cliquez sur l’icône de calendrier en bas de votre tâche pour décider d’une " "date d’échéance." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Réorganiser vos tâches" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -437,11 +450,11 @@ msgstr "" "Pour réorganiser votre liste, cliquez sur une tâche et maintenez, puis " "faites-la glisser où vous le souhaitez." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Créer un projet" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -450,11 +463,11 @@ msgstr "" "sur le bouton '+' dans la section « Sur cet ordinateur » pour ajouter vos " "propres projets." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "C’est terminé !" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 msgid "" "That’s all you really need to know. Feel free to start adding your own " "projects and to-dos.\n" @@ -468,15 +481,15 @@ msgstr "" "avancées ci-dessous…\n" "Nous espérons que vous aurez plaisir à utiliser Planify !" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Personnaliser votre installation" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Affichez vos événements de calendrier" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -486,11 +499,11 @@ msgstr "" "Planify. Allez dans « Préférences » → « Événements du calendrier » pour " "activer cette option." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Activez la synchronisation avec des services tiers." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -498,15 +511,15 @@ msgstr "" "Planify ne crée pas seulement des tâches localement, il peut aussi " "synchroniser votre compte Todoist. Allez dans « Préférences » → « Comptes »." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Améliorez votre productivité" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Faites glisser le bouton + !" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -515,11 +528,11 @@ msgstr "" "n’y paraît : il est fait pour bouger ! Faites-le glisser vers le haut pour " "créer une tâche là où vous le souhaitez." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "Étiquetez vos tâches" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -528,11 +541,11 @@ msgstr "" "Planify. Pour ajouter une étiquette, cliquez sur le bouton « Étiquette » en " "bas de la page." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Programmez des rappels !" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -541,75 +554,75 @@ msgstr "" "un événement important ou quelque chose de spécial ? Cliquez sur le bouton " "en forme de cloche ci-dessous pour ajouter un rappel." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️ Travail" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️ École" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️ Délégué" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️ Maison" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️ À suivre" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, c-format msgid "Task moved to %s" msgstr "Tâche déplacée vers %s" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 msgid "Task duplicated" msgstr "Tâche dupliquée" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 msgid "Section duplicated" msgstr "Section dupliquée" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 msgid "Project duplicated" msgstr "Projet dupliqué" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Demain" @@ -664,40 +677,45 @@ msgstr "Sa," msgid "Su," msgstr "Di," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "La requête était incorrecte." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "" "L’authentification est requise et a échoué ou n’a pas encore été effectuée." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "La demande était valide, mais pour quelque chose qui est interdit." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "La ressource demandée n’a pas pu être trouvée." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "L’utilisateur a envoyé trop de requêtes dans un certain délai." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "La requête a échoué à cause d’un problème du serveur." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "Le serveur est actuellement incapable de gérer la requête." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Erreur inconnue" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Indisponible" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "Épingler" @@ -742,11 +760,11 @@ msgid "To Do" msgstr "À faire" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Compléter" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -755,15 +773,27 @@ msgstr "" "en pressant la touche Entrée." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "Créer « %s »" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"Votre liste de rappels apparaîtra ici. Ajoutez-en une en cliquant sur le " +"bouton '+'." + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Chercher ou créer" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "Rechercher" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -858,8 +888,8 @@ msgstr "Effacer" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "Retour" @@ -873,36 +903,13 @@ msgstr "Ajouter des étiquettes" msgid "Select Labels" msgstr "Sélectionner des étiquettes" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "Sur cet ordinateur" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Aucune section" @@ -918,10 +925,6 @@ msgstr "Section" msgid "Select Section" msgstr "Sélectionner une section" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "Rechercher" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -953,56 +956,71 @@ msgstr "Ajouter un rappel" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Tâche copiée dans le presse-papiers" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Projet copié vers le presse-papiers." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "Supprimer le projet %s ?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "Cette action est irréversible" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Supprimer" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "Archiver ?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "%s et toutes ses tâches seront archivés." -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "Archiver" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "Supprimer la section %s" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Supprimer la section" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1116,47 +1134,56 @@ msgstr "" "Planify démarrera automatiquement à l’allumage de cet appareil et continuera " "à s’exécuter à la fermeture de sa fenêtre pour envoyer des notifications." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "Menu principal" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "Ouvrir la recherche rapide" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Préférences" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Raccourcis clavier" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "Quoi de neuf" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "À propos de Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 msgid "Archived Projects" msgstr "Projets archivés" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Créer plus" + +#: src/Services/Backups.vala:411 msgid "Delete Backup" msgstr "Supprimer la sauvegarde" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Sauvegarde importée avec succès" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "Processus achevé, vous devez redémarrer Planify" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Fichiers de sauvegarde Planify" @@ -1164,98 +1191,78 @@ msgstr "Fichiers de sauvegarde Planify" msgid "On this computer" msgstr "Sur cet ordinateur" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "Ouvrir la boîte de réception" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "Aller à la vue du jour" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "Voir les éléments prévus" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "Voir les étiquettes" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "Aller aux éléments épinglés" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Favoris" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "" "Aucune tâche favorite disponible. Créez-en une en cliquant sur le bouton " "« + »" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "Sur cet ordinateur" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "Pas de projet disponible. Créez-en un en cliquant sur le bouton ’+’" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Quoi de neuf dans Planify" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Ajouter un projet" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "" -"Pas de compte disponible, synchronisez-en un en cliquant sur le bouton « + »" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "L’ordre des projets a été modifié en ordre de tri personnalisé." -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Retirer des favoris" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Ajouter aux favoris" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Modifier le projet" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "Dupliquer" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "Actualiser" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Supprimer le projet" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Partager" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "Envoyer par courriel" @@ -1264,118 +1271,120 @@ msgstr "Envoyer par courriel" msgid "(No Section)" msgstr "(Pas de section)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Ajouter la tâche" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Modifier la section" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Déplacer la section" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Gérer l’ordre des sections" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Supprimer la section" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "Ajouter des sous-tâches" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 msgid "Add Attachments" msgstr "Ajouter des pièces-jointes" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Pas de date" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Déplacer" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Ajouter une sous-tâche" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Éditer" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Supprimer la tâche" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Choisir une date" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "Copier vers le presse-papiers" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Répéter" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Quotidiennement" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Hebdomadairement" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Mensuellement" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Annuellement" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Personnalisé" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Terminé. Prochaine occurrence : %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s a été supprimé" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Annuler" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "L’ordre a été modifié en ordre de tri personnalisé." @@ -1408,19 +1417,23 @@ msgstr "Titre" msgid "Properties" msgstr "Propriétés" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "Êtes-vous sûr de vouloir supprimer ?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 msgid "Open/Close Sidebar" msgstr "Basculer la barre latérale" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "Pas de projet disponible. Créez-en un en cliquant sur le bouton ’+’" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "Mode hors-ligne activé" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1481,7 +1494,7 @@ msgid "Attach File" msgstr "Fichiers de sauvegarde" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Télécharger" @@ -1503,6 +1516,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Source" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "Actions du projet" @@ -1549,13 +1576,13 @@ msgstr "Tableau" msgid "Custom sort order" msgstr "Ordre de tri personnalisé" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Alphabétiquement" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "Date d’ajout" @@ -1589,27 +1616,27 @@ msgstr "Les 30 prochains jours" msgid "Duedate" msgstr "Échéance" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Filtrer par étiquettes" @@ -1631,7 +1658,7 @@ msgstr "Supprimer les tâches accomplies" msgid "Sort By" msgstr "Trier par" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 msgid "Filter By" msgstr "Filtrer par" @@ -1664,48 +1691,54 @@ msgstr "En retard" msgid "Reschedule" msgstr "Reprogrammer" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Trier par" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Étiquettes : sur cet ordinateur" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Étiquettes : Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "" +"Aucune tâche favorite disponible. Créez-en une en cliquant sur le bouton " +"« + »" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "Étiquettes : Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Ajouter un projet" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "%d tâches accomplies et leurs sous-tâches seront supprimées" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Nouveau projet" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Donnez un nom à votre projet" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Utiliser un Émoji" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Source" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Mettre le projet à jour" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Source" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Projet ajouté avec succès !" @@ -1754,8 +1787,8 @@ msgid "Please enter your credentials" msgstr "Veuillez entrer vos informations d’identification" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "Réseau indisponible" @@ -1825,7 +1858,7 @@ msgstr "" msgid "Archived" msgstr "Archivé" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Tapez une recherche" @@ -1973,7 +2006,7 @@ msgstr "" "n’hésitez pas à nous soutenir." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Nous soutenir" @@ -2014,7 +2047,7 @@ msgid "Appearance" msgstr "Apparence" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Ajout rapide" @@ -2045,7 +2078,7 @@ msgid "Reach Us" msgstr "Nous joindre" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "Contactez-nous" @@ -2083,7 +2116,7 @@ msgid "Privacy" msgstr "Vie privée" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Politique de vie privée" @@ -2286,45 +2319,36 @@ msgid "Dark Blue Style" msgstr "Style bleu sombre" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Comptes" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Synchroniser avec votre compte Todoist" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Vous pouvez trier vos aperçus par glisser-déposer" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "Synchronisation basée sur des standards Internet ouverts" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Serveur de synchronisation" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Activez ce paramètre pour que Planify se synchronise automatiquement avec " "votre compte Todoist toutes les 15 minutes" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Dernière synchronisation" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Activez ce paramètre pour que Planify se synchronise automatiquement avec " -"votre compte CalDAV toutes les 15 minutes" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2333,7 +2357,7 @@ msgstr "" "sur votre bureau, avec une combinaison de touches. Vous n’aurez même pas à " "quitter l’application que vous étiez en train d’utiliser." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2341,75 +2365,73 @@ msgstr "" "Allez dans Paramètres système → Clavier → Raccourcis → Personnalisé, et " "ajoutez un nouveau raccourci avec la commande suivante :" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Paramètres" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Enregistrer le dernier projet sélectionné" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "" "Si rien n’est coché, le projet sélectionné par défaut sera la boîte de " "réception" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "Commande copiée vers le presse-papiers" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Chargement…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "Planify synchronise vos tâches, cela peut prendre quelques minutes" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Synchronisation…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Veuillez entrer vos informations d’identification" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 #, fuzzy msgid "Nextcloud Setup" msgstr "Nextcloud" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "URL du serveur" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "Nom d’utilisateur" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "Mot de passe" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "Fournisseur" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "Se connecter" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "Échec de la connexion" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Données personnelles" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2417,7 +2439,7 @@ msgstr "" "Nous ne collectons absolument rien et toutes vos données sont stockées sur " "votre ordinateur." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2428,11 +2450,11 @@ msgstr "" "privés, nous ne faisons qu’afficher vos tâches configurées et les gérer pour " "vous." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "Avez-vous des questions ?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2440,7 +2462,7 @@ msgstr "" "Si vous avez des questions concernant vos données ou tout autre sujet, " "n’hésitez pas à nous contacter. Nous nous ferons un plaisir de vous répondre." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2450,42 +2472,22 @@ msgstr "" "des tâches aux utilisateurs du monde entier. Vos dons soutiennent ce " "travail. Vous voulez faire un don aujourd’hui ?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Êtes-vous sûr de vouloir supprimer la synchronisation Todoist ? Cette action " -"supprimera toutes vos tâches et paramètres." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Êtes-vous sûr de vouloir supprimer la synchronisation CalDAV ? Cette action " -"supprimera toutes vos tâches et paramètres." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Se déconnecter" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2506,39 +2508,50 @@ msgstr "Importer une sauvegarde" msgid "Backup Files" msgstr "Fichiers de sauvegarde" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "" +"Pas de compte disponible, synchronisez-en un en cliquant sur le bouton « + »" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "Migrer" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "Migrer depuis Planner" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Tâches migrées avec succès" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "Tâches migrées avec succès" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "Le fichier de la base de données n’existe pas." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "Aperçu d’importation" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 msgid "To-Dos" msgstr "Tâches" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Confirmer" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Restaurer la sauvegarde" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2546,15 +2559,15 @@ msgstr "" "Êtes-vous sûr de vouloir continuer ? Cette action supprimera vos données " "actuelles et les remplacera par celles de la sauvegarde." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Restaurer la sauvegarde" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "Fichier sélectionné invalide" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 msgid "View Backup" msgstr "Visualiser la sauvegarde" @@ -2673,8 +2686,50 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Ouvrir la section Épinglé" -#~ msgid "CalDAV" -#~ msgstr "CalDAV" +#~ msgid "On this Computer" +#~ msgstr "Sur cet ordinateur" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Étiquettes : sur cet ordinateur" + +#~ msgid "Labels: Todoist" +#~ msgstr "Étiquettes : Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "Étiquettes : Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Synchroniser avec votre compte Todoist" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "Synchronisation basée sur des standards Internet ouverts" + +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Activez ce paramètre pour que Planify se synchronise automatiquement avec " +#~ "votre compte CalDAV toutes les 15 minutes" + +#~ msgid "Failed to login" +#~ msgstr "Échec de la connexion" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Êtes-vous sûr de vouloir supprimer la synchronisation Todoist ? Cette " +#~ "action supprimera toutes vos tâches et paramètres." + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Êtes-vous sûr de vouloir supprimer la synchronisation CalDAV ? Cette " +#~ "action supprimera toutes vos tâches et paramètres." + +#~ msgid "Sign Off" +#~ msgstr "Se déconnecter" #~ msgid "CalDAV Setup" #~ msgstr "Configuration CalDAV" diff --git a/po/hi.po b/po/hi.po index 587c633ca..b0eedc149 100644 --- a/po/hi.po +++ b/po/hi.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: planify\n" -"Report-Msgid-Bugs-To: https://github.com/alainm23/planify/issues\n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-07-13 22:12+0530\n" "Last-Translator: Scrambled777 \n" "Language-Team: Hindi \n" @@ -22,7 +22,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -31,7 +31,7 @@ msgstr "" msgid "Today" msgstr "आज" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -41,7 +41,7 @@ msgstr "आज" msgid "Inbox" msgstr "इनबॉक्स" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -55,131 +55,142 @@ msgstr "अनुसूचित" msgid "Pinboard" msgstr "पिनबोर्ड" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "परियोजनाएं" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "अनुभाग" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "कार्य" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "लेबल" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "फिल्टर" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "सूचियां" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "दोहराएं नहीं" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "हर मिनट" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "हर %d मिनट" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "हर घंटे" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "हर %d घंटे" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "हर दिन" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "हर %d दिन" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "हर हफ्ते" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "हर %d हफ्ते" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "हर महीने" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "हर %d महीने" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "हर वर्ष" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "हर %d वर्ष" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "वरीयता" -#: core/Enum.vala:365 +#: core/Enum.vala:419 msgid "Label" msgstr "लेबल" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "देय तारीख" -#: core/Enum.vala:474 +#: core/Enum.vala:528 msgid "Task Created" msgstr "कार्य निर्मित" -#: core/Enum.vala:477 +#: core/Enum.vala:531 msgid "Task Updated" msgstr "कार्य अद्यतित" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "सामग्री" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "विवरण" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 msgid "Pin" msgstr "पिन" @@ -303,8 +314,8 @@ msgstr "गहरा" msgid "Dark Blue" msgstr "गहरा नीला" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "कोई नहीं" @@ -313,17 +324,16 @@ msgstr "कोई नहीं" msgid "Today + Inbox" msgstr "आज + इनबॉक्स" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "रद्द करें" @@ -335,9 +345,8 @@ msgstr "सभी मिटाएं" msgid "Process completed, you need to start Planify again." msgstr "प्रक्रिया पूर्ण, प्लॅानिफाई फिर शुरू करें।" -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "ठीक है" @@ -373,11 +382,15 @@ msgstr "निम्न" msgid "none" msgstr "कोई नहीं" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "इस कंप्यूटर पर" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "प्लॅानिफाई से मिलें" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -386,11 +399,11 @@ msgstr "" "यह परियोजना वह सब कुछ दिखती है जो आपको प्लॅानिफाई के उपयोग हेतु जानना आवश्यक है। इसमें " "बेझिझक बदलाव करें - सेटिंग से हमेशा एक नया बना सकते हैं।" -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "इस कार्य को टैप करें" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -398,11 +411,11 @@ msgstr "" "आप एक कार्य को देख रहे हैं! बाईं ओर चेकबॉक्स पर टैप करके इसे पूरा करें। पूर्ण किए गए कार्य " "परियोजना के निचले भाग में एकत्र किए जाते हैं।" -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "नया कार्य बनाएं" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -410,29 +423,29 @@ msgstr "" "अब आपकी बारी है, अपने परियोजना के नीचे '+' बटन पर टैप करें, कोई भी लंबित दर्ज करें और " "नीले 'सहेजें' बटन पर टैप करें।" -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "आज या बाद में यह कार्य करने की योजना बनाएं" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "यह कार्य कब करना है यह तय करने के लिए नीचे दिए गए कैलेंडर बटन को दबाएं।" -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "अपने कार्यों का क्रम बदलें" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." msgstr "सूची का क्रम बदलने हेतु कार्य पर टैप करके नये स्थान तक खीचें।" -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "एक परियोजना बनाएं" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -440,11 +453,11 @@ msgstr "" "अपने कार्यों को बेहतर ढंग से व्यवस्थित करें! बाएं पैनल पर जाएं और 'इस कंप्यूटर पर' अनुभाग में " "'+' बटन पर क्लिक करें और खुद की एक परियोजना जोड़ें।" -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "बस, हो गया!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 msgid "" "That’s all you really need to know. Feel free to start adding your own " "projects and to-dos.\n" @@ -456,15 +469,15 @@ msgstr "" "नीचे दी गई उन्नत खासियतों को जानने के लिए आप बाद में इस परियोजना पर वापस आ सकते हैं।\n" "हमें आशा है कि आपको प्लॅानिफाई के उपयोग में मज़ा आएगा!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "सेटअप बेहतर बनाएं" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "कैलेंडर कार्यक्रम दिखाएं" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 msgid "" "You can display your system's calendar events in Planify. Go to " "'Preferences' 🡒 General 🡒 Calendar Events to turn it on." @@ -472,11 +485,11 @@ msgstr "" "सिस्टम के कैलेंडर कार्यक्रमों को प्लॅानिफाई में दिखाया जा सकता है। इसे चालू करने के लिए " "'प्राथमिकताएं' 🡒 सामान्य 🡒 कैलेंडर कार्यक्रम पर जाएं।" -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "तृतीय-पक्ष सेवा के साथ समन्वयन सक्षम करें।" -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -484,15 +497,15 @@ msgstr "" "प्लॅानिफाई स्थानीय कार्यों को बनाने के साथ ही Todoist खाते को भी समन्वयन कर सकता है। " "'प्राथमिकताएं' 🡒 'खाते' पर जाएं।" -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "अपनी उत्पादकता बढ़ाएं" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "प्लस बटन खींचें!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -500,11 +513,11 @@ msgstr "" "स्क्रीन के नीचे की और दिखाई देने वाला नीला बटन शक्तिशाली है: इसे खिंचा जा सकता है! जहां " "कार्य बनाना चाहते हैं वहां इसे खींच कर ले जाएं।" -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "कार्यों को टैग करें!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -512,11 +525,11 @@ msgstr "" "टैग प्लॅानिफाई में कार्यप्रवाह को बेहतर बनता है। टैग जोड़ने के लिए नीचे दिए गए टैग बटन पर " "क्लिक करें।" -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "समयानुकूल रिमाइंडर लगाएं!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -524,75 +537,75 @@ msgstr "" "चाहते हैं कि प्लॅानिफाई आपको किसी महत्वपूर्ण कार्यक्रम या किसी विशेष चीज़ की याद दिलाने के " "लिए अधिसूचना भेजे। रिमाइंडर जोड़ने के लिए नीचे घंटी का बटन दबाएं।" -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️दफ्तर" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️स्कूल" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️प्रत्यायोजित" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️घर" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️अनुसरण" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, c-format msgid "Task moved to %s" msgstr "कार्य को %s पर भेजा गया" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 msgid "Task duplicated" msgstr "कार्य प्रतिरूपित" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 msgid "Section duplicated" msgstr "अनुभाग प्रतिरूपित" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 msgid "Project duplicated" msgstr "परियोजना प्रतिरूपित" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "नियत समय पर" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "10 मिनट पहले" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "30 मिनट पहले" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "45 मिनट पहले" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "1 घंटा पहले" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "2 घंटे पहले" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "3 घंटे पहले" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "कल" @@ -647,39 +660,44 @@ msgstr "शनि," msgid "Su," msgstr "रवि," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "अनुरोध गलत था।" -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "प्रमाणीकरण आवश्यक है, या तो विफल हुआ या प्रदान नहीं किया गया।" -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "अनुरोध मान्य था, लेकिन निषिद्ध चीज़ के लिए।" -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "अनुरोधित संसाधन नहीं मिला।" -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "उपयोक्ता ने निश्चित समय में बहुत अधिक अनुरोध भेजे हैं।" -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "सर्वर त्रुटि के कारण अनुरोध विफल हुआ।" -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "सर्वर अनुरोध संभालने में फिलहाल असमर्थ है।" -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "अज्ञात त्रुटि" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "उपलब्ध नहीं" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "पिन किए गए" @@ -724,26 +742,36 @@ msgid "To Do" msgstr "लंबित" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "पूर्ण" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." msgstr "आपकी फिल्टर सूची यहां दिखाई देगी। नाम दर्ज करके और Enter दबा कर एक बनाएं।" #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "'%s' बनाएं" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "आपकी रिमाइंडर सूची यहां दिखाई देगी। '+' बटन पर क्लिक करके एक जोड़ें।" + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "खोजें या बनाएं" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "खोजें" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -838,8 +866,8 @@ msgstr "साफ करें" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "पीछे" @@ -853,36 +881,13 @@ msgstr "लेबल जोड़ें" msgid "Select Labels" msgstr "लेबल चुनें" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "इस कंप्यूटर पर" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "कोई अनुभाग नहीं" @@ -898,10 +903,6 @@ msgstr "अनुभाग" msgid "Select Section" msgstr "अनुभाग चुनें" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "खोजें" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -931,56 +932,70 @@ msgstr "रिमाइंडर जोड़ें" msgid "Couldn't find an app to handle file URIs" msgstr "फाइल URI को संभालने के लिए कोई ऐप नहीं मिला" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "कार्य को क्लिपबोर्ड पर कॉपी किया गया" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "परियोजना को क्लिपबोर्ड पर कॉपी किया गया था।" -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "परियोजना %s मिटाएं?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "इसे पूर्ववत नहीं किया जा सकता" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "मिटाएं" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "संग्रहित करें?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "यह %s और उसके सभी कार्यों को संग्रहीत करेगा।" -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "संग्रहीत करें" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "अनुभाग %s मिटाएं" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +msgid "CalDAV - " +msgstr "" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "अनुभाग मिटाएं" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1091,47 +1106,56 @@ msgstr "" "जब यह उपकरण चालू होगा तो प्लॅानिफाई स्वचालित रूप से प्रारंभ हो जाएगा और विंडो बंद होने " "पर भी चलेगा ताकि यह कार्य संबंधी अधिसूचनाएं भेज सके।" -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "मुख्य मेनू" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "शीघ्र खोज खोलें" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "प्राथमिकताएं" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "कीबोर्ड शॉर्टकट" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "नया क्या है" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "प्लॅानिफाई के बारे में" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 msgid "Archived Projects" msgstr "संग्रहीत परियोजनाएं" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "और बनाएं" + +#: src/Services/Backups.vala:411 msgid "Delete Backup" msgstr "बैकअप मिटाएं" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "बैकअप सफलतापूर्वक आयातित" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "प्रक्रिया पूर्ण, प्लॅानिफाई फिर से शुरू करें" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "प्लॅानिफाई की बैकअप फाइलें" @@ -1139,95 +1163,76 @@ msgstr "प्लॅानिफाई की बैकअप फाइलें msgid "On this computer" msgstr "इस कंप्यूटर पर" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "इनबॉक्स पर जाएं" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "आज पर जाएं" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "अनुसूचित पर जाएं" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "लेबल पर जाएं" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "पिनबोर्ड पर जाएं" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "पसंदीदा" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "कोई पसंदीदा उपलब्ध नहीं है। '+' बटन पर क्लिक करके एक बनाएं" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "इस कंप्यूटर पर" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "कोई परियोजना उपलब्ध नहीं है। '+' बटन पर क्लिक करके एक बनाएं" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "प्लॅानिफाई में नया क्या है" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "परियोजना जोड़ें" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "कोई खाता उपलब्ध नहीं है, '+' बटन पर क्लिक करके किसी एक को समन्वयित करें" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "परियोजना छंटाई को 'तदनुकूल छंटाई क्रम' में बदल दिया गया" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "पसंदीदा से हटाएं" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "पसंदीदा में जोड़े" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "परियोजना संपादन" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "प्रतिरूप" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "ताज़ा करें" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "परियोजना मिटाएं" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "साझा करें" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "ई-मेल द्वारा भेजें" @@ -1236,117 +1241,119 @@ msgstr "ई-मेल द्वारा भेजें" msgid "(No Section)" msgstr "(कोई अनुभाग नहीं)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "कार्य जोड़ें" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "अनुभाग संपादन" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "अनुभाग स्थानांतरण" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "अनुभाग क्रम प्रबंधित करें" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "अनुभाग मिटाएं" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "उपकार्य जोड़ें" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 msgid "Add Attachments" msgstr "अनुलग्नक जोड़ें" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "कोई तारीख नहीं" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "स्थानांतरण" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "उपकार्य जोड़ें" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "संपादन" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "कार्य मिटाएं" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 msgid "Use as a Note" msgstr "नोट के रूप में उपयोग करें" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "क्लिपबोर्ड पर कॉपी करें" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "दोहराएं" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "इतिहास बदलें" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "प्रतिदिन" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "साप्ताहिक" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "मासिक" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "वार्षिक" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "तदनुकूल" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "पूर्ण। अगली बार: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s मिटा दिया गया" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "पूर्ववत करें" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "क्रम को 'तदनुकूल छंटाई क्रम' में बदल दिया गया" @@ -1379,19 +1386,23 @@ msgstr "शीर्षक" msgid "Properties" msgstr "गुण" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "क्या आप वाकई मिटाना चाहते हैं?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 msgid "Open/Close Sidebar" msgstr "पार्श्वपट्टी खोलें/बंद करें" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "कोई परियोजना उपलब्ध नहीं है। '+' बटन पर क्लिक करके एक बनाएं" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "ऑफलाइन मोड चालू है" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1450,7 +1461,7 @@ msgid "Attach File" msgstr "फाइल जोड़ें" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "डाउनलोड" @@ -1472,6 +1483,20 @@ msgstr "पिन: सक्रिय" msgid "Pin: Inactive" msgstr "पिन: निष्क्रिय" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "स्रोत" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "परियोजना कार्रवाई" @@ -1518,13 +1543,13 @@ msgstr "बोर्ड" msgid "Custom sort order" msgstr "तदनुकूल छंटाई क्रम" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "वर्णानुक्रम" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "तारीख जोड़ा गया" @@ -1558,27 +1583,27 @@ msgstr "अगले 30 दिन" msgid "Duedate" msgstr "देयतारीख" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "लेबल द्वारा फिल्टर करें" @@ -1600,7 +1625,7 @@ msgstr "सभी पूर्ण कार्य मिटाएं" msgid "Sort By" msgstr "ऐसे छांटें" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 msgid "Filter By" msgstr "ऐसे फिल्टर करें" @@ -1632,48 +1657,52 @@ msgstr "अतिदेय" msgid "Reschedule" msgstr "पुनर्निर्धारित" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "ऐसे क्रमबद्ध" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "लेबल: इस कंप्यूटर पर" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "लेबल: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "कोई पसंदीदा उपलब्ध नहीं है। '+' बटन पर क्लिक करके एक बनाएं" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "लेबल: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "परियोजना जोड़ें" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "यह %d पूर्ण किए गए कार्यों और उनके उप-कार्यों को हटा देगा" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "नई परियोजना" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "अपने परियोजना को एक नाम दें" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "इमोजी का प्रयोग करें" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "स्रोत" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "परियोजना अद्यतन" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "स्रोत" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "परियोजना सफलतापूर्वक जोड़ी गई!" @@ -1722,8 +1751,8 @@ msgid "Please enter your credentials" msgstr "कृपया अपने प्रत्ययपत्र दर्ज करें" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "नेटवर्क उपलब्ध नहीं है" @@ -1792,7 +1821,7 @@ msgstr "" msgid "Archived" msgstr "संग्रहीत" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "खोज लिखें" @@ -1938,7 +1967,7 @@ msgstr "" "समर्थन देने पर विचार करें।" #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "हमारा समर्थन करें" @@ -1979,7 +2008,7 @@ msgid "Appearance" msgstr "दिखावट" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "शीघ्र जोड़ें" @@ -2009,7 +2038,7 @@ msgid "Reach Us" msgstr "हम तक पहुंचें" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "हमसे संपर्क करें" @@ -2047,7 +2076,7 @@ msgid "Privacy" msgstr "गोपनीयता" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "गोपनीयता नीति" @@ -2247,45 +2276,36 @@ msgid "Dark Blue Style" msgstr "गहरे नीले रंग की शैली" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "खाते" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "अपने Todoist खाते के साथ समन्वयित करें" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "आप अपने विचारों को खींचकर और छोड़ कर छांट सकते हैं" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "खुले इंटरनेट मानकों पर आधारित समन्वयन" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "समन्वयन सर्वर" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "इस सेटिंग को सक्रिय करें ताकि प्लॅानिफाई स्वचालित रूप से हर 15 मिनट में आपके Todoist खाते " "के साथ समन्वयित हो जाए" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "अंतिम समन्वयन" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"इस सेटिंग को सक्रिय करें ताकि प्लॅानिफाई स्वचालित रूप से हर 15 मिनट में आपके CalDAV खाते के " -"साथ समन्वयित हो जाए" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2293,7 +2313,7 @@ msgstr "" "बस कुछ कीस्ट्रोक्स के साथ अपने डेस्कटॉप पर कहीं से भी करने-हेतु कार्य बनाने के लिए शीघ्र जोड़ें " "का उपयोग करें। आपको वह ऐप छोड़ने की भी ज़रूरत नहीं है जिसमें आप वर्तमान में हैं।" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2301,72 +2321,70 @@ msgstr "" "सिस्टम सेटिंग → कीबोर्ड → शॉर्टकट → तदनुकूल पर जाएं, फिर निम्नलिखित के साथ एक नया " "शॉर्टकट जोड़ें:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "सेटिंग" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "अंतिम चयनित परियोजना सहेजें" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "यदि जांचा नहीं गया है, तो चयनित तयशुदा परियोजना इनबॉक्स है" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "कमांड को क्लिपबोर्ड पर कॉपी किया गया था" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "लोड हो रहा है…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "प्लॅानिफाई आपके कार्यों को समन्वयित कर रहा है, इसमें कुछ मिनट लग सकते हैं" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "समन्वयन..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "कृपया अपना प्रत्ययपत्र दर्ज करें" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "Nextcloud सेटअप" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "सर्वर URL" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "उपयोक्ता नाम" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "पासवर्ड" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "प्रदाता" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "लॉगिन" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "लॉगिन करने में विफल" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "व्यक्तिगत डेटा" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2374,7 +2392,7 @@ msgstr "" "हम बिल्कुल कुछ भी एकत्र नहीं करते हैं और आपका सारा डेटा आपके कंप्यूटर पर एक डेटाबेस में " "संग्रहीत होता है।" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2384,11 +2402,11 @@ msgstr "" "तो आपका डेटा उनके निजी सर्वर पर संग्रहीत किया जाएगा, हम केवल आपके विन्यस्त कार्यों को " "प्रदर्शित करते हैं और उन्हें आपके लिए प्रबंधित करते हैं।" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "क्या आपका कोई प्रश्न है?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2396,7 +2414,7 @@ msgstr "" "यदि आपके डेटा या किसी अन्य समस्या के बारे में आपके कोई प्रश्न हैं, तो कृपया हमसे संपर्क करें। " "हमें आपको उत्तर देने में ख़ुशी होगी।" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2405,42 +2423,22 @@ msgstr "" "हमारा मिशन दुनिया भर के उपयोक्ताओं के लिए सर्वोत्तम खुले स्त्रोत की कार्य प्रबंधन अनुप्रयोग " "प्रदान करना है। आपका दान इस कार्य का समर्थन करता है। आज दान करना चाहते हैं?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"क्या आप वाकई Todoist समन्वयन को हटाना चाहते हैं? यह कार्रवाई आपके सभी कार्य और सेटिंग " -"मिटा देगी।" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"क्या आप वाकई CalDAV समन्वयन को हटाना चाहते हैं? यह कार्रवाई आपके सभी कार्य और सेटिंग " -"मिटा देगी।" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "साइन ऑफ़" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2461,39 +2459,49 @@ msgstr "बैकअप आयात करें" msgid "Backup Files" msgstr "बैकअप फाइलें" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "कोई खाता उपलब्ध नहीं है, '+' बटन पर क्लिक करके किसी एक को समन्वयित करें" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "प्रवासन" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "प्लानर से प्रवासन" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "कार्य प्रवासन सफल" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "कार्य प्रवासन सफल" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "डेटाबेस फाइल मौजूद नहीं है।" -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "आयात अवलोकन" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 msgid "To-Dos" msgstr "कार्य" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "पुष्टि करें" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "बैकअप बहाल" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2501,15 +2509,15 @@ msgstr "" "क्या आप वाकई जारी रखना चाहते हैं? यह अभियान आपके वर्तमान डेटा को मिटा देगा और इसे " "बैकअप डेटा से बदल देगा।" -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "बैकअप बहाल" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "चयनित फाइल अमान्य है" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 msgid "View Backup" msgstr "बैकअप देखें" @@ -2627,3 +2635,48 @@ msgstr "लेबल खोलें" msgctxt "shortcut window" msgid "Open Pinboard" msgstr "पिनबोर्ड खोलें" + +#~ msgid "On this Computer" +#~ msgstr "इस कंप्यूटर पर" + +#~ msgid "Labels: On This Computer" +#~ msgstr "लेबल: इस कंप्यूटर पर" + +#~ msgid "Labels: Todoist" +#~ msgstr "लेबल: Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "लेबल: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "अपने Todoist खाते के साथ समन्वयित करें" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "खुले इंटरनेट मानकों पर आधारित समन्वयन" + +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "इस सेटिंग को सक्रिय करें ताकि प्लॅानिफाई स्वचालित रूप से हर 15 मिनट में आपके CalDAV " +#~ "खाते के साथ समन्वयित हो जाए" + +#~ msgid "Failed to login" +#~ msgstr "लॉगिन करने में विफल" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "क्या आप वाकई Todoist समन्वयन को हटाना चाहते हैं? यह कार्रवाई आपके सभी कार्य और " +#~ "सेटिंग मिटा देगी।" + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "क्या आप वाकई CalDAV समन्वयन को हटाना चाहते हैं? यह कार्रवाई आपके सभी कार्य और " +#~ "सेटिंग मिटा देगी।" + +#~ msgid "Sign Off" +#~ msgstr "साइन ऑफ़" diff --git a/po/io.github.alainm23.planify.pot b/po/io.github.alainm23.planify.pot index 1681d9dc3..948f61890 100644 --- a/po/io.github.alainm23.planify.pot +++ b/po/io.github.alainm23.planify.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -21,7 +21,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -30,7 +30,7 @@ msgstr "" msgid "Today" msgstr "" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -40,7 +40,7 @@ msgstr "" msgid "Inbox" msgstr "" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -54,131 +54,142 @@ msgstr "" msgid "Pinboard" msgstr "" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "" -#: core/Enum.vala:365 +#: core/Enum.vala:419 msgid "Label" msgstr "" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "" -#: core/Enum.vala:474 +#: core/Enum.vala:528 msgid "Task Created" msgstr "" -#: core/Enum.vala:477 +#: core/Enum.vala:531 msgid "Task Updated" msgstr "" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 msgid "Pin" msgstr "" @@ -300,8 +311,8 @@ msgstr "" msgid "Dark Blue" msgstr "" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "" @@ -310,17 +321,16 @@ msgstr "" msgid "Today + Inbox" msgstr "" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "" @@ -332,9 +342,8 @@ msgstr "" msgid "Process completed, you need to start Planify again." msgstr "" -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "" @@ -370,70 +379,74 @@ msgstr "" msgid "none" msgstr "" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " "one from settings." msgstr "" -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." msgstr "" -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." msgstr "" -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." msgstr "" -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." msgstr "" -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 msgid "" "That’s all you really need to know. Feel free to start adding your own " "projects and to-dos.\n" @@ -442,133 +455,133 @@ msgid "" "We hope you’ll enjoy using Planify!" msgstr "" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 msgid "" "You can display your system's calendar events in Planify. Go to " "'Preferences' 🡒 General 🡒 Calendar Events to turn it on." msgstr "" -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "" -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." msgstr "" -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." msgstr "" -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." msgstr "" -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." msgstr "" -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, c-format msgid "Task moved to %s" msgstr "" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 msgid "Task duplicated" msgstr "" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 msgid "Section duplicated" msgstr "" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 msgid "Project duplicated" msgstr "" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "" @@ -623,39 +636,43 @@ msgstr "" msgid "Su," msgstr "" -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "" -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "" -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "" -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "" -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "" -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "" -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "" -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +msgid "No Provider Available" +msgstr "" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "" @@ -700,26 +717,35 @@ msgid "To Do" msgstr "" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." msgstr "" #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +msgid "Your list of filters will show up here." +msgstr "" + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -814,8 +840,8 @@ msgstr "" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "" @@ -829,36 +855,13 @@ msgstr "" msgid "Select Labels" msgstr "" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "" @@ -874,10 +877,6 @@ msgstr "" msgid "Select Section" msgstr "" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -907,56 +906,69 @@ msgstr "" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "" -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "" -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "" + +#: core/Objects/Source.vala:63 +msgid "CalDAV - " +msgstr "" + +#: core/Objects/Source.vala:161 +msgid "Delete Source?" +msgstr "" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1065,47 +1077,55 @@ msgid "" "window is closed so that it can send to-do notifications." msgstr "" -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 msgid "Archived Projects" msgstr "" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +msgid "See More" +msgstr "" + +#: src/Services/Backups.vala:411 msgid "Delete Backup" msgstr "" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "" @@ -1113,95 +1133,76 @@ msgstr "" msgid "On this computer" msgstr "" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "" @@ -1210,117 +1211,119 @@ msgstr "" msgid "(No Section)" msgstr "" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 msgid "Add Attachments" msgstr "" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 msgid "Use as a Note" msgstr "" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "" @@ -1353,19 +1356,23 @@ msgstr "" msgid "Properties" msgstr "" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 msgid "Open/Close Sidebar" msgstr "" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1421,7 +1428,7 @@ msgid "Attach File" msgstr "" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "" @@ -1443,6 +1450,19 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +msgid "Add Source" +msgstr "" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "" @@ -1489,13 +1509,13 @@ msgstr "" msgid "Custom sort order" msgstr "" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "" @@ -1529,27 +1549,27 @@ msgstr "" msgid "Duedate" msgstr "" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "" @@ -1571,7 +1591,7 @@ msgstr "" msgid "Sort By" msgstr "" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 msgid "Filter By" msgstr "" @@ -1603,20 +1623,16 @@ msgstr "" msgid "Reschedule" msgstr "" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +msgid "No labels available. Create one by clicking on the '+' button" msgstr "" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" msgstr "" #: src/Views/Filter.vala:535 @@ -1624,27 +1640,33 @@ msgstr "" msgid "This will delete %d completed tasks and their subtasks" msgstr "" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +msgid "Sources" +msgstr "" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "" @@ -1693,8 +1715,8 @@ msgid "Please enter your credentials" msgstr "" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "" @@ -1752,7 +1774,7 @@ msgstr "" msgid "Archived" msgstr "" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "" @@ -1895,7 +1917,7 @@ msgid "" msgstr "" #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "" @@ -1936,7 +1958,7 @@ msgid "Appearance" msgstr "" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "" @@ -1966,7 +1988,7 @@ msgid "Reach Us" msgstr "" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "" @@ -2004,7 +2026,7 @@ msgid "Privacy" msgstr "" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "" @@ -2203,179 +2225,151 @@ msgid "Dark Blue Style" msgstr "" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +msgid "You can sort your accounts by dragging and dropping" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +msgid "Synchronizing…" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " "your configured tasks and manage them for you." msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " "donate today?" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2394,53 +2388,61 @@ msgstr "" msgid "Backup Files" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +msgid "No backups found, create one clicking the button above." +msgstr "" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +msgid "The Backup was created successfully." +msgstr "" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 msgid "To-Dos" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 msgid "View Backup" msgstr "" diff --git a/po/ko.po b/po/ko.po index 70a842bfa..56fee41eb 100644 --- a/po/ko.po +++ b/po/ko.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-06-24 02:42+0900\n" "Last-Translator: Wonje Jung \n" "Language-Team: \n" @@ -22,7 +22,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -31,7 +31,7 @@ msgstr "" msgid "Today" msgstr "오늘" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -41,7 +41,7 @@ msgstr "오늘" msgid "Inbox" msgstr "수신함" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -55,133 +55,144 @@ msgstr "일정" msgid "Pinboard" msgstr "게시판" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "프로젝트" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "섹션" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "할 일" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "라벨" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "필터" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "목록" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "반복 안 함" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "매분" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "%d분마다" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "매시간" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "%d시간마다" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "매일" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "%d일마다" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "매주" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "%d주마다" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "매달" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "%d달마다" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "매년" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "%d년마다" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "우선순위" -#: core/Enum.vala:365 +#: core/Enum.vala:419 msgid "Label" msgstr "라벨" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "기한" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "작업이 복제되었습니다" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "작업이 복제되었습니다" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "설명" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 msgid "Pin" msgstr "고정" @@ -307,8 +318,8 @@ msgstr "어두운색" msgid "Dark Blue" msgstr "남색" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "없음" @@ -317,17 +328,16 @@ msgstr "없음" msgid "Today + Inbox" msgstr "오늘 + 수신함" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "취소" @@ -339,9 +349,8 @@ msgstr "전부 삭제" msgid "Process completed, you need to start Planify again." msgstr "처리 완료, Planify를 재시작해야 합니다." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "확인" @@ -377,11 +386,15 @@ msgstr "낮음" msgid "none" msgstr "없음" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "이 컴퓨터에서" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Planify를 만나보세요" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -390,11 +403,11 @@ msgstr "" "이 프로젝트는 시작하는 데 필요한 모든 것을 보여줍니다. 자유롭게 탐색해 보세" "요 - 설정에서 언제든지 프로젝트를 만들 수 있습니다." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "이 할 일을 탭하세요" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -402,11 +415,11 @@ msgstr "" "지금 할 일을 보고 있어요! 왼쪽의 체크박스를 탭하여 완료하세요. 완료된 할 일" "은 프로젝트 하단에 모입니다." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "새로운 할 일을 생성하세요" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -414,19 +427,19 @@ msgstr "" "이제 당신 차례입니다. 프로젝트 하단의 '+' 버튼을 탭하고, 대기 중인 작업을 입" "력한 후 파란색 '저장' 버튼을 탭하세요." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "이 할 일을 나중에 계획하세요" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "이 할 일을 언제 할지 결정하려면 하단의 캘린더 버튼을 탭하세요." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "할 일의 순서를 변경하세요" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -434,11 +447,11 @@ msgstr "" "리스트를 재정렬하려면, 할 일을 탭하고 길게 누른 후 원하는 위치로 드래그하세" "요." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "새 프로젝트를 생성하세요" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -446,11 +459,11 @@ msgstr "" "할 일을 더 잘 정리하세요! 왼쪽 패널로 이동하여 '이 컴퓨터' 섹션에서 '+' 버튼" "을 클릭하고, 직접 프로젝트를 추가하세요." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "모든 과정이 완료되었습니다. 잘 하셨어요!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 msgid "" "That’s all you really need to know. Feel free to start adding your own " "projects and to-dos.\n" @@ -463,25 +476,25 @@ msgstr "" "나중에 이 프로젝트로 돌아와 아래의 고급 기능을 배울 수 있습니다.\n" "Planify를 즐겁게 사용하시길 바랍니다!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "설정을 조정하세요" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "캘린더 이벤트를 표시하세요" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 msgid "" "You can display your system's calendar events in Planify. Go to " "'Preferences' 🡒 General 🡒 Calendar Events to turn it on." msgstr "Planify에서 시스템의 캘린더 이벤트를 표시할 수 있습니다." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "서드파티 서비스와의 동기화를 활성화하세요." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -489,15 +502,15 @@ msgstr "" "Planify는 로컬에서만 작업을 생성할 수 있을 뿐만 아니라, Todoist 계정과도 동기" "화할 수 있습니다. '설정' 🡒 '계정'으로 이동하세요." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "생산성을 향상하세요" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "플러스 버튼을 드래그하세요!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -505,11 +518,11 @@ msgstr "" "각 화면 하단에 있는 파란 버튼은 보기보다 강력합니다: 이동할 수 있도록 설계되" "었습니다! 위로 드래그하여 원하는 곳에 작업을 생성하세요." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "할 일에 태그를 추가하세요!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -517,11 +530,11 @@ msgstr "" "태그를 사용하면 Planify에서 워크플로우를 개선할 수 있습니다. 태그를 추가하려" "면 하단의 태그 버튼을 클릭하세요." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "시기적절한 리마인더를 설정하세요!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -529,75 +542,75 @@ msgstr "" "중요한 이벤트나 특별한 일을 기억하기 위해 Planify에서 알림을 받고 싶으시다" "면, 아래의 종 버튼을 눌러 알림을 추가하세요." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️업무" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️학교" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️할당됨" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️집" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍️️확인 필요" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, c-format msgid "Task moved to %s" msgstr "작업이 %s(으)로 이동되었습니다" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 msgid "Task duplicated" msgstr "작업이 복제되었습니다" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 msgid "Section duplicated" msgstr "섹션이 복제되었습니다" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 msgid "Project duplicated" msgstr "프로젝트가 복제되었습니다" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "내일" @@ -652,39 +665,44 @@ msgstr "토," msgid "Su," msgstr "일," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "요청이 잘못되었습니다." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "인증이 필요하지만 실패했거나 아직 제공되지 않았습니다." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "요청은 유효하지만 금지된 항목에 대한 것입니다." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "요청한 리소스를 찾을 수 없습니다." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "사용자가 일정 시간 내에 너무 많은 요청을 보냈습니다." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "서버 오류로 인해 요청이 실패했습니다." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "서버가 현재 요청을 처리할 수 없습니다." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "알 수 없는 오류" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "사용할 수 없음" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "고정됨" @@ -729,11 +747,11 @@ msgid "To Do" msgstr "할 일" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "완료" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 #, fuzzy msgid "" "Your list of filters will show up here. Create one by entering the name and " @@ -741,15 +759,25 @@ msgid "" msgstr "여기에 알림 목록이 표시됩니다. '+' 버튼을 클릭하여 알림을 추가하세요." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, fuzzy, c-format msgid "Create '%s'" msgstr "추가 생성" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "여기에 알림 목록이 표시됩니다. '+' 버튼을 클릭하여 알림을 추가하세요." + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "검색" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -844,8 +872,8 @@ msgstr "지우기" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "뒤로" @@ -859,36 +887,13 @@ msgstr "라벨 추가" msgid "Select Labels" msgstr "라벨 선택" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "이 컴퓨터에서" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "섹션 없음" @@ -904,10 +909,6 @@ msgstr "섹션" msgid "Select Section" msgstr "섹션 선택" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "검색" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -937,56 +938,71 @@ msgstr "리마인더 추가" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "작업이 클립보드에 복사되었습니다" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "프로젝트가 클립보드에 복사되었습니다." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "프로젝트 %s을(를) 삭제하시겠습니까?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "이 작업은 취소할 수 없습니다" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "삭제" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "보관하시겠습니까?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "%s 및 모든 작업이 보관됩니다." -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "보관" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "섹션 %s 삭제" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "섹션 삭제" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1099,47 +1115,56 @@ msgstr "" "이 기기가 켜지면 Planify가 자동으로 시작되고 창이 닫힌 상태에서도 할 일 알림" "을 보낼 수 있도록 실행됩니다." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "메인 메뉴" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "빠른 검색 열기" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "설정" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "키보드 단축키" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "새로운 기능" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "Planify 정보" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 msgid "Archived Projects" msgstr "보관된 프로젝트" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "추가 생성" + +#: src/Services/Backups.vala:411 msgid "Delete Backup" msgstr "백업 삭제" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "백업이 성공적으로 가져와졌습니다" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "처리 완료, Planify를 재시작해야 합니다" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Planify 백업 파일" @@ -1147,96 +1172,76 @@ msgstr "Planify 백업 파일" msgid "On this computer" msgstr "이 컴퓨터에서" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "수신함으로 이동" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "오늘로 이동" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "일정으로 이동" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "라벨로 이동" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "게시판으로 이동" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "즐겨찾기" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "즐겨찾기가 없습니다. '+' 버튼을 클릭하여 하나 만들어 보세요" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "이 컴퓨터에서" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "" -"사용 가능한 프로젝트가 없습니다. '+' 버튼을 클릭하여 하나 만들어 보세요" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Planify의 새로운 기능" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "프로젝트 추가" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "사용 가능한 계정이 없습니다. '+' 버튼을 클릭하여 동기화하세요" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "프로젝트 정렬이 '사용자 정의 순서'로 변경되었습니다" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "즐겨찾기에서 제거" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "즐겨찾기에 추가" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "프로젝트 편집" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "복제" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "새로고침" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "프로젝트 삭제" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "공유" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "이메일로 보내기" @@ -1245,118 +1250,120 @@ msgstr "이메일로 보내기" msgid "(No Section)" msgstr "(섹션 없음)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "작업 추가" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "섹션 편집" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "섹션 이동" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "섹션 순서 관리" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "섹션 삭제" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "하위 작업 추가" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 msgid "Add Attachments" msgstr "첨부 팡리 추가" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "날짜 없음" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "이동" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "하위 작업 추가" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "편집" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "작업 삭제" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "날짜 선택" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "클립보드에 복사" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "반복" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "매일" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "매주" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "매월" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "매년" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "사용자 정의" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "완료되었습니다. 다음 발생: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s이(가) 삭제되었습니다" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "되돌리기" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "정렬이 '사용자 정의 순서'로 변경되었습니다" @@ -1389,19 +1396,24 @@ msgstr "제목" msgid "Properties" msgstr "속성" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "삭제하시겠습니까?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 msgid "Open/Close Sidebar" msgstr "사이드바 열기/닫기" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "" +"사용 가능한 프로젝트가 없습니다. '+' 버튼을 클릭하여 하나 만들어 보세요" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "오프라인 모드가 켜져 있습니다" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1462,7 +1474,7 @@ msgid "Attach File" msgstr "백업 파일" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "다운로드" @@ -1484,6 +1496,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "소스" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "프로젝트 작업" @@ -1530,13 +1556,13 @@ msgstr "보드" msgid "Custom sort order" msgstr "사용자 정의 순서" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "알파벳 순" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "추가된 날짜" @@ -1570,27 +1596,27 @@ msgstr "다음 30일" msgid "Duedate" msgstr "기한" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "라벨로 필터링" @@ -1612,7 +1638,7 @@ msgstr "모든 완료된 작업 삭제" msgid "Sort By" msgstr "정렬 기준" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 msgid "Filter By" msgstr "필터 기준" @@ -1644,48 +1670,52 @@ msgstr "기한 초과" msgid "Reschedule" msgstr "일정 변경" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "정렬 순서" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "라벨: 이 컴퓨터에서" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "라벨: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "즐겨찾기가 없습니다. '+' 버튼을 클릭하여 하나 만들어 보세요" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "라벨: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "프로젝트 추가" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "이 작업은 %d개의 완료된 작업 및 하위 작업을 삭제합니다" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "새 프로젝트" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "프로젝트 이름 지정" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "이모지 사용" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "소스" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "프로젝트 업데이트" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "소스" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "프로젝트가 성공적으로 추가되었습니다!" @@ -1734,8 +1764,8 @@ msgid "Please enter your credentials" msgstr "자격 증명을 입력하세요" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "네트워크를 사용할 수 없습니다" @@ -1803,7 +1833,7 @@ msgstr "" msgid "Archived" msgstr "보관됨" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "검색 입력" @@ -1948,7 +1978,7 @@ msgstr "" "아하고 개발을 지원하고 싶다면, 지원을 고려해 주세요." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "지원하기" @@ -1989,7 +2019,7 @@ msgid "Appearance" msgstr "모양" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "빠른 추가" @@ -2019,7 +2049,7 @@ msgid "Reach Us" msgstr "연락처" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "문의하기" @@ -2057,7 +2087,7 @@ msgid "Privacy" msgstr "개인정보 보호" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "개인정보 보호정책" @@ -2257,45 +2287,36 @@ msgid "Dark Blue Style" msgstr "남색 스타일" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "계정" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Todoist 계정과 동기화" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "끌어다 놓기로 보기를 정렬할 수 있습니다" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "오픈 인터넷 표준을 기반으로 한 동기화" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "동기화 서버" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "이 설정을 활성화하여 Planify가 15분마다 Todoist 계정과 자동으로 동기화되도록 " "하세요" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "마지막 동기화" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"이 설정을 활성화하여 Planify가 15분마다 CalDAV 계정과 자동으로 동기화되도록 " -"하세요" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2303,7 +2324,7 @@ msgstr "" "빠른 추가를 사용하여 데스크톱의 어디서나 몇 번의 키 입력으로 할 일을 생성하세" "요. 현재 사용 중인 앱을 떠날 필요도 없습니다." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2311,72 +2332,70 @@ msgstr "" "시스템 설정 → 키보드 → 단축키 → 사용자 정의로 이동한 다음, 다음과 같이 새 단" "축키를 추가하세요:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "설정" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "마지막으로 선택된 프로젝트 저장" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "선택하지 않으면 기본 프로젝트는 수신함으로 설정됩니다" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "명령이 클립보드에 복사되었습니다" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "로딩 중…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "Planify가 작업을 동기화 중입니다. 몇 분 정도 소요될 수 있습니다" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "동기화 중..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "자격 증명을 입력하세요" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "Nextcloud 설정" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "서버 URL" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "사용자 이름" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "비밀번호" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "제공자" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "로그인" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "로그인 실패" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "개인 데이터" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2384,7 +2403,7 @@ msgstr "" "우리는 어떤 데이터도 수집하지 않으며 모든 데이터는 사용자의 컴퓨터에 있는 데" "이터베이스에 저장됩니다." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2394,11 +2413,11 @@ msgstr "" "우 데이터는 그들의 개인 서버에 저장되며, 우리는 사용자가 설정한 작업만 표시하" "고 관리합니다." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "별도의 질문이 있으십니까?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2406,7 +2425,7 @@ msgstr "" "데이터나 기타 문제에 대한 질문이 있으시면 문의해 주세요. 즐거운 마음으로 답변" "해 드리겠습니다." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2416,40 +2435,22 @@ msgstr "" "공하는 것입니다. 여러분의 기부는 이 작업을 지원합니다. 오늘 기부하고 싶으신가" "요?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Todoist 동기화를 제거하시겠습니까? 이 작업은 모든 작업과 설정을 삭제합니다." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"CalDAV 동기화를 제거하시겠습니까? 이 작업은 모든 작업과 설정을 삭제합니다." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "로그아웃" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2470,54 +2471,64 @@ msgstr "백업 가져오기" msgid "Backup Files" msgstr "백업 파일" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "사용 가능한 계정이 없습니다. '+' 버튼을 클릭하여 동기화하세요" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "마이그레이션" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "플래너에서 마이그래이션" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "작업이 성공적으로 마이그레이션되었습니다" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "작업이 성공적으로 마이그레이션되었습니다" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "데이터베이스 파일이 존재하지 않습니다." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "개요 가져오기" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 msgid "To-Dos" msgstr "할 일" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "확인" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "백업 복원" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." msgstr "" "계속하시겠습니까? 이 작업은 현재 데이터를 삭제하고 백업 데이터로 교체합니다." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "백업 복원" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "선택한 파일이 유효하지 않습니다" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 msgid "View Backup" msgstr "백업 보기" @@ -2636,8 +2647,49 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "게시판 열기" +#~ msgid "On this Computer" +#~ msgstr "이 컴퓨터에서" + +#~ msgid "Labels: On This Computer" +#~ msgstr "라벨: 이 컴퓨터에서" + +#~ msgid "Labels: Todoist" +#~ msgstr "라벨: Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "라벨: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Todoist 계정과 동기화" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "오픈 인터넷 표준을 기반으로 한 동기화" + +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "이 설정을 활성화하여 Planify가 15분마다 CalDAV 계정과 자동으로 동기화되도" +#~ "록 하세요" + +#~ msgid "Failed to login" +#~ msgstr "로그인 실패" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Todoist 동기화를 제거하시겠습니까? 이 작업은 모든 작업과 설정을 삭제합니" +#~ "다." + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "CalDAV 동기화를 제거하시겠습니까? 이 작업은 모든 작업과 설정을 삭제합니다." + +#~ msgid "Sign Off" +#~ msgstr "로그아웃" + #~ msgid "Add" #~ msgstr "추가" - -#~ msgid "CalDAV" -#~ msgstr "CalDAV" diff --git a/po/nl.po b/po/nl.po index f9959b523..db561178e 100644 --- a/po/nl.po +++ b/po/nl.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-06-20 17:20+0200\n" "Last-Translator: Gert-dev\n" "Language-Team: Dutch <>\n" @@ -22,7 +22,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -31,7 +31,7 @@ msgstr "" msgid "Today" msgstr "Vandaag" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -41,7 +41,7 @@ msgstr "Vandaag" msgid "Inbox" msgstr "Inbox" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -55,133 +55,144 @@ msgstr "Gepland" msgid "Pinboard" msgstr "Prikbord" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Projecten" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Onderverdelingen" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Taken" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Labels" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Filters" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Lijsten" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Niet herhalen" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "Elke minuut" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "Elke %d minuten" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "Elk uur" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "Elke %d uren" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Elke dag" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "Elke %d dagen" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Elke week" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "Elke %d weken" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Elke maand" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "Elke %d maanden" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Elk jaar" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "Elke %d jaren" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Prioriteit" -#: core/Enum.vala:365 +#: core/Enum.vala:419 msgid "Label" msgstr "Label" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "Deadline" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Taak gedupliceerd" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Taak gedupliceerd" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Beschrijving" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 msgid "Pin" msgstr "Vastgeprikt" @@ -307,8 +318,8 @@ msgstr "Donker" msgid "Dark Blue" msgstr "Donkerblauw" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Geen" @@ -317,17 +328,16 @@ msgstr "Geen" msgid "Today + Inbox" msgstr "Vandaag + Inbox" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Annuleren" @@ -339,9 +349,8 @@ msgstr "Alles verwijderen" msgid "Process completed, you need to start Planify again." msgstr "Proces afgerond, gelieve Planify opnieuw op te starten." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "Ok" @@ -377,11 +386,15 @@ msgstr "laag" msgid "none" msgstr "geen" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "Op deze computer" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Planify leren kennen" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -391,11 +404,11 @@ msgstr "" "Experimenteer naar hartenlust – je kan altijd het altijd opnieuw aanmaken " "via de instellingen." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Klik op deze taak" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -403,11 +416,11 @@ msgstr "" "Dit is dus een taak! Rond de taak af door op de checkbox aan de linkerkant " "te klikken. Afgeronde taken worden onderaan je project bijgehouden." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Creëer een nieuwe taak" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -415,21 +428,21 @@ msgstr "" "Nu is het aan jou. Klik op de '+'-knop onderaan je project, geef iets in en " "druk op de blauwe knop om op te slaan." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Plan deze taak voor vandaag of een later moment" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Druk op de kalenderknop onderaan om te bepalen tegen wanneer deze taak klaar " "moet zijn." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Verander je taken van volgorde" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -437,11 +450,11 @@ msgstr "" "Om de lijst van volgorde te veranderen, houd je de muis ingedrukt op een " "taak en sleep je deze naar zijn nieuwe bestemming." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Maak een project aan" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -449,11 +462,11 @@ msgstr "" "Deel je taken beter in! Ga naar het linkerpaneel en klik op de '+'-knop in " "de sectie 'Op deze computer' en voeg een eigen project toe." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "Je bent klaar!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 msgid "" "That’s all you really need to know. Feel free to start adding your own " "projects and to-dos.\n" @@ -469,16 +482,16 @@ msgstr "" "\n" "We hopen dat het gebruik van Planify je blij zal maken!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Stel je omgeving af" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Toon je kalenderevenementen" # Assumed error "turn ir on" -> "turn it on" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -487,11 +500,11 @@ msgstr "" "Je kan de kalenderevenementen uit je systeem ook in Planify weergeven. Ga " "naar 'Voorkeuren' 🡒 Kalenderevenementen om dit aan te zetten." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Activeer synchronisatie met diensten van derde partijen." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -499,15 +512,15 @@ msgstr "" "Planify maakt taken niet enkel lokaal aan, maar kan deze ook synchroniseren " "naar je Todoist-account. Navigeer hiervoor naar 'Voorkeuren' 🡒 'Accounts'." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Wees productiever dan ooit tevoren" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Sleep de plus-knop!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -516,11 +529,11 @@ msgstr "" "ziet: hij kan bewegen! Sleep deze naar een plaats waar je een taak wil " "aanmaken." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "Label je taken!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -528,11 +541,11 @@ msgstr "" "Met labels kan je je workflow in Planify verbeteren. Om een label toe te " "voegen, klik je op de tag-knop onderaan." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Stel herinneringen op tijd in!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -541,75 +554,75 @@ msgstr "" "belangrijke gebeurtenis of iets speciaals? Klik op de bel-knop onderaan om " "een herinnering in te stellen." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️ Werk" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️ School" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️ Gedelegeerd" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️ Thuis" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️ Opvolging" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, c-format msgid "Task moved to %s" msgstr "Taak verplaatst naar %s" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 msgid "Task duplicated" msgstr "Taak gedupliceerd" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 msgid "Section duplicated" msgstr "Onderverdeling gedupliceerd" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 msgid "Project duplicated" msgstr "Project gedupliceerd" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Morgen" @@ -664,39 +677,44 @@ msgstr "Za," msgid "Su," msgstr "Zo," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "De aanvraag was incorrect." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "Aanmelden is vereist en is mislukt of werd nog niet ingesteld." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "De aanvraag was geldig, maar er werd geen toegang gegeven." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "De opgevraagde bron kon niet teruggevonden worden." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "De gebruiker heeft te veel aanvragen verstuurd op korte tijd." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "De aanvraag is mislukt door een fout aan de serverkant." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "De server kan de aanvraag momenteel niet behandelen." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Onbekende fout" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Niet beschikbaar" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "Vastgeprikt" @@ -741,11 +759,11 @@ msgid "To Do" msgstr "Open" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Afgerond" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -754,15 +772,26 @@ msgstr "" "geven en op Enter te drukken." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "'%s' aanmaken" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"Je herinneringen zullen hier getoond worden. Voeg er één toe via de '+'-knop." + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Zoeken of Aanmaken" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "Zoeken" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -857,8 +886,8 @@ msgstr "Wissen" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "Terug" @@ -872,36 +901,13 @@ msgstr "Labels toevoegen" msgid "Select Labels" msgstr "Labels selecteren" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "Op deze computer" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Zonder onderverdeling" @@ -917,10 +923,6 @@ msgstr "Onderverdeling" msgid "Select Section" msgstr "Onderverdeling selecteren" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "Zoeken" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -951,56 +953,71 @@ msgstr "Herinnering toevoegen" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Taak gekopieerd naar klembord" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Het project werd naar het klembord gekopieerd." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "Project %s verwijderen?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "Dit kan niet ongedaan gemaakt worden" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Verwijderen" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "Archiveren?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "Dit zal %s en alle bijhorende taken archiveren." -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "Archiveren" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "Onderverdeling %s verwijderen" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Onderverdeling verwijderen" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1113,47 +1130,56 @@ msgstr "" "Planify zal automatisch mee opstarten met uw computer en blijven draaien bij " "het sluiten van het venster zodat meldingen verstuurd kunnen worden." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "Hoofdmenu" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "Snel zoeken openen" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Voorkeuren" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Sneltoetsen" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "Wat is er nieuw" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "Over Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 msgid "Archived Projects" msgstr "Gearchiveerde projecten" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Nog één aanmaken" + +#: src/Services/Backups.vala:411 msgid "Delete Backup" msgstr "Back-up verwijderen" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Back-up met succes geïmporteerd" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "Proces afgerond, gelieve Planify opnieuw op te starten" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Back-up-bestanden van Planify" @@ -1161,98 +1187,77 @@ msgstr "Back-up-bestanden van Planify" msgid "On this computer" msgstr "Op deze computer" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "Naar Inbox navigeren" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "Naar Vandaag navigeren" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "Naar Gepland navigeren" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "Naar Labels navigeren" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "Naar Prikbord navigeren" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Favorieten" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "" "Geen favorieten beschikbaar. Maak er één aan door op de '+'-knop te drukken" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "Op deze computer" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "" -"Geen project beschikbaar. Maak er één aan door op de '+'-knop te klikken" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Wat is er nieuw in Planify" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Project toevoegen" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "" -"Geen account beschikbaar, synchroniseer er één door op de '+'-knop te klikken" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "Sortering van projecten aangepast naar 'Aangepaste volgorde'" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Uit favorieten verwijderen" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Aan favorieten toevoegen" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Project bewerken" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "Dupliceren" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "Herladen" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Project verwijderen" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Delen" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "Per e-mail verzenden" @@ -1261,118 +1266,120 @@ msgstr "Per e-mail verzenden" msgid "(No Section)" msgstr "(Geen onderverdeling)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Taak toevoegen" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Onderverdeling bewerken" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Onderverdeling verplaatsen" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Volgorde onderverdelingen beheren" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Onderverdeling verwijderen" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "Subtaken toevoegen" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 msgid "Add Attachments" msgstr "Bijlagen toevoegen" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Geen datum" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Verplaatsen" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Subtaak toevoegen" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Bewerken" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Taak verwijderen" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Datum kiezen" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "Naar klembord kopiëren" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Herhalen" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Dagelijks" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Wekelijks" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Maandelijks" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Jaarlijks" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Aangepast" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Afgewerkt. Volgende datum: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s werd verwijderd" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Ongedaan maken" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "Volgorde aangepast naar 'Aangepaste volgorde'" @@ -1405,19 +1412,24 @@ msgstr "Titel" msgid "Properties" msgstr "Eigenschappen" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "Ben je zeker dat je wilt verwijderen?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 msgid "Open/Close Sidebar" msgstr "Zijbalk tonen/verbergen" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "" +"Geen project beschikbaar. Maak er één aan door op de '+'-knop te klikken" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "Offline-modus is ingeschakeld" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1479,7 +1491,7 @@ msgid "Attach File" msgstr "Bestanden back-uppen" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Downloaden" @@ -1501,6 +1513,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Bron" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "Projectacties" @@ -1547,13 +1573,13 @@ msgstr "Bord" msgid "Custom sort order" msgstr "Aangepaste volgorde" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Alfabetisch" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "Datum ingesteld" @@ -1587,27 +1613,27 @@ msgstr "Volgende 30 dagen" msgid "Duedate" msgstr "Deadline" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Op label filteren" @@ -1629,7 +1655,7 @@ msgstr "Alle afgeronde taken verwijderen" msgid "Sort By" msgstr "Sorteren op" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 msgid "Filter By" msgstr "Filteren op" @@ -1663,48 +1689,53 @@ msgstr "Over tijd" msgid "Reschedule" msgstr "Uitstellen" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Sorteren op" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Labels: Op deze computer" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Labels: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "" +"Geen favorieten beschikbaar. Maak er één aan door op de '+'-knop te drukken" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "Labels: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Project toevoegen" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "Dit zal %d afgeronde taken en alle bijhorende subtaken verwijderen" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Project aanmaken" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Geef je project een naam" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Emoji gebruiken" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Bron" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Project bewerken" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Bron" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Project met succes toegevoegd!" @@ -1754,8 +1785,8 @@ msgid "Please enter your credentials" msgstr "Gelieve je aanmeldgegevens in te geven" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "Netwerk is niet beschikbaar" @@ -1825,7 +1856,7 @@ msgstr "" msgid "Archived" msgstr "Gearchiveerd" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Zoekterm ingeven" @@ -1972,7 +2003,7 @@ msgstr "" "de ontwikkeling van Planify graag wil steunen, gelieve ons dan te steunen." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Ons steunen" @@ -2013,7 +2044,7 @@ msgid "Appearance" msgstr "Uiterlijk" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Snel toevoegen" @@ -2043,7 +2074,7 @@ msgid "Reach Us" msgstr "Bereik ons" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "Contacteer ons" @@ -2081,7 +2112,7 @@ msgid "Privacy" msgstr "Privacy" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Privacy-verklaring" @@ -2283,47 +2314,37 @@ msgid "Dark Blue Style" msgstr "Donkerblauwe stijl" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Accounts" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Synchroniseer met je Todoist-account" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Je kan je weergaves sorteren door drag-'n-drop" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "Synchronisatie gebaseerd op open internetstandaarden" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Met server synchroniseren" # Assumed error "Planner" -> "Planify" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Activeer deze instelling om Planify elke 15 minuten automatisch te laten " "synchroniseren met je Todoist-account" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Laatste synchronisatie" -# Assumed error "Planner" -> "Planify" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Activeer deze instelling om Planify elke 15 minuten automatisch te laten " -"synchroniseren met je CalDAV-account" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2331,7 +2352,7 @@ msgstr "" "Gebruik snel toevoegen om taken van eender waar aan te maken met een paar " "toetsaanslagen. Je hoeft niet eens van applicatie te wisselen." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2339,76 +2360,74 @@ msgstr "" "Ga naar Instellingen → Toetsenbord → Sneltoetsen bekijken en aanpassen → " "Aangepaste sneltoets, en voeg een sneltoets toe met onderstaande inhoud:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Instellingen" # Assumed task is saved to the last selected project -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Laatst geselecteerde project onthouden" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "Wanneer uitgeschakeld zal het standaardproject de Inbox zijn" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "Het commando werd naar het klembord gekopieerd" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Aan het laden…" # Assumed error "Planner" -> "Planify" and "is sync" -> "is syncing" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "" "Planify synchroniseert momenteel je taken, dit kan enkele minuten in beslag " "nemen" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Synchroniseren..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Gelieve je aanmeldgegevens in te geven" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "Nextcloud-configuratie" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "Server-URL" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "Gebruikersnaam" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "Wachtwoord" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "Provider" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "Aanmelden" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "Aanmelden mislukt" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Persoonlijke gegevens" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2416,7 +2435,7 @@ msgstr "" "We verzamelen helemaal niets en al je data wordt lokaal op je computer " "bewaard in een database." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2426,11 +2445,11 @@ msgstr "" "het geval is, zal je data op hun privé-servers bewaard worden; we tonen en " "beheren je taken in dat geval enkel." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "Heb je nog vragen?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2438,7 +2457,7 @@ msgstr "" "Als je nog vragen hebt over je data of een ander probleem, gelieve ons te " "contacteren. We helpen je graag verder." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2448,42 +2467,22 @@ msgstr "" "overal ter wereld te bieden. Jouw donaties helpen ons hiermee. Wil je " "vandaag al doneren?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Weet je zeker dat je de Todoist-synchronisatie wil uitschakelen? Dit zal al " -"je taken en instellingen verwijderen." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Weet je zeker dat je de CalDAV-synchronisatie wil uitschakelen? Dit zal al " -"je taken en instellingen verwijderen." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Afmelden" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2504,40 +2503,51 @@ msgstr "Back-up terugzetten" msgid "Backup Files" msgstr "Bestanden back-uppen" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "" +"Geen account beschikbaar, synchroniseer er één door op de '+'-knop te klikken" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "Migreren" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "Migreren van Planner" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Taken succesvol gemigreerd" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "Taken succesvol gemigreerd" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "Het database-bestand bestaat niet." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "Import-overzicht" # Maybe just "Hinzufügen" because of space issues -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 msgid "To-Dos" msgstr "To-do's" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Bevestigen" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Back-up terugzetten" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2545,15 +2555,15 @@ msgstr "" "Weet je zeker dat je verder wil gaan? Dit zal alle huidige data verwijderen " "en vervangen met die uit de back-up." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Back-up terugzetten" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "Geselecteerd bestand is ongeldig" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 msgid "View Backup" msgstr "Back-up bekijken" @@ -2672,12 +2682,55 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Prikbord weergeven" +#~ msgid "On this Computer" +#~ msgstr "Op deze computer" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Labels: Op deze computer" + +#~ msgid "Labels: Todoist" +#~ msgstr "Labels: Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "Labels: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Synchroniseer met je Todoist-account" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "Synchronisatie gebaseerd op open internetstandaarden" + +# Assumed error "Planner" -> "Planify" +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Activeer deze instelling om Planify elke 15 minuten automatisch te laten " +#~ "synchroniseren met je CalDAV-account" + +#~ msgid "Failed to login" +#~ msgstr "Aanmelden mislukt" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Weet je zeker dat je de Todoist-synchronisatie wil uitschakelen? Dit zal " +#~ "al je taken en instellingen verwijderen." + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Weet je zeker dat je de CalDAV-synchronisatie wil uitschakelen? Dit zal " +#~ "al je taken en instellingen verwijderen." + +#~ msgid "Sign Off" +#~ msgstr "Afmelden" + #~ msgid "Add" #~ msgstr "Toevoegen" -#~ msgid "CalDAV" -#~ msgstr "CalDAV" - #~ msgid "CalDAV Setup" #~ msgstr "CalDAV-setup" diff --git a/po/pt_BR.po b/po/pt_BR.po index 1be2ae610..4892b8db1 100644 --- a/po/pt_BR.po +++ b/po/pt_BR.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-04-01 23:34-0300\n" "Last-Translator: Tiago Lucas Flach \n" "Language-Team: \n" @@ -23,7 +23,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -32,7 +32,7 @@ msgstr "" msgid "Today" msgstr "Hoje" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -42,7 +42,7 @@ msgstr "Hoje" msgid "Inbox" msgstr "Caixa de Entrada" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -56,135 +56,146 @@ msgstr "Agendado" msgid "Pinboard" msgstr "Quadro de anúncios" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Projetos" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Seções" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Tarefas" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Rótulos" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Filtros" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Listas" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Não Repetir" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "Todo minuto" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "A cada %d minutos" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "Toda hora" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "A cada %d horas" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Todo dia" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "A cada %d dias" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Toda semana" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "A cada %d semanas" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Todo mês" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "A cada %d meses" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Todo ano" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "A cada %d anos" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Prioridade" -#: core/Enum.vala:365 +#: core/Enum.vala:419 #, fuzzy msgid "Label" msgstr "Rótulos" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 #, fuzzy msgid "Due Date" msgstr "Data de vencimento" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Duplicar" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Duplicar" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Descrição" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 #, fuzzy msgid "Pin" msgstr "Fixado" @@ -310,8 +321,8 @@ msgstr "Escuro" msgid "Dark Blue" msgstr "Azul Escuro" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Nenhum" @@ -320,17 +331,16 @@ msgstr "Nenhum" msgid "Today + Inbox" msgstr "Hoje + Caixa de Entrada" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Cancelar" @@ -343,9 +353,8 @@ msgstr "Deletar todos" msgid "Process completed, you need to start Planify again." msgstr "Processo concluído, você precisa iniciar o Planify novamente." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "Ok" @@ -381,11 +390,15 @@ msgstr "baixo" msgid "none" msgstr "nenhum" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "Neste Computador" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Conheça o Planify" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -395,11 +408,11 @@ msgstr "" "Não hesite em brincar com ele – você sempre pode criar um novo nas " "configurações." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Toque nesta tarefa" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -408,11 +421,11 @@ msgstr "" "esquerda. As tarefas concluídas são coletadas na parte inferior do seu " "projeto." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Crie uma nova tarefa" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -420,21 +433,21 @@ msgstr "" "Agora é a sua vez, toque no botão ‘+’ na parte inferior do seu projeto, " "insira alguma pendência e toque no botão azul ‘Salvar’." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Planeje esta tarefa hoje ou mais tarde" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Toque no botão de calendário na parte inferior para decidir quando fazer " "esta tarefa." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Reordene suas tarefas" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -442,11 +455,11 @@ msgstr "" "Para reordenar sua lista, toque e segure uma tarefa e arraste-a para onde " "ela deveria ir." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Crie um projeto" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -454,11 +467,11 @@ msgstr "" "Organize melhor suas tarefas! Vá para o painel esquerdo e clique no botão " "'+' na seção ‘Neste computador’ e adicione seu próprio projeto." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "Você Terminou!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 #, fuzzy msgid "" "That’s all you really need to know. Feel free to start adding your own " @@ -475,15 +488,15 @@ msgstr "" "\n" "Esperamos que você goste de usar o Planify!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Ajuste sua configuração" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Mostre os eventos do seu calendário" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -492,11 +505,11 @@ msgstr "" "Você pode exibir os eventos do calendário do seu sistema no Planify. Vá para " "'Preferências' 🡒 Eventos do calendário para ativá-lo." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Habilite a sincronização com serviço de terceiros." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -504,15 +517,15 @@ msgstr "" "O Planify não apenas cria tarefas localmente, mas também pode sincronizar " "sua conta Todoist. Vá para 'Preferências' 🡒 'Contas'." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Aumente sua produtividade" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Arraste o botão de adição!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -521,11 +534,11 @@ msgstr "" "do que parece: foi feito para se mover! Arraste-o para criar uma tarefa onde " "quiser." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "Marque suas tarefas!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -533,11 +546,11 @@ msgstr "" "As tags permitem que você melhore seu fluxo de trabalho no Planify. Para " "adicionar uma tag, clique no botão tag na parte inferior." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Defina lembretes oportunos!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -546,78 +559,78 @@ msgstr "" "importante ou algo especial. Toque no botão do sino abaixo para adicionar um " "lembrete." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️Trabalho" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️Escola" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️Delegado" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️Casa" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️Acompanhamento" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, fuzzy, c-format msgid "Task moved to %s" msgstr "Tarefas adicionadas a %s" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 #, fuzzy msgid "Task duplicated" msgstr "Duplicar" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 #, fuzzy msgid "Section duplicated" msgstr "Nome da Seção" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 #, fuzzy msgid "Project duplicated" msgstr "Projeto duplicado" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Amanhã" @@ -673,39 +686,44 @@ msgstr "Sáb," msgid "Su," msgstr "Dom," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "A requisição foi incorreta." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "Autenticação é requerida, mas falhou ou não foi provida ainda." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "A requisição foi válida, mas por algum motivo é proibida." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "O recurso requerido não pôde ser encontrado." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "O usuário mandou muitas requisições em um dado período de tempo." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "A requisição falhou devido a um erro de servidor." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "O servidor não pode processar a requisição no momento." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Erro desconhecido" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Não disponível" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "Fixado" @@ -752,11 +770,11 @@ msgid "To Do" msgstr "" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Completar" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -765,15 +783,28 @@ msgstr "" "a tecla Enter." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, c-format msgid "Create '%s'" msgstr "Criar '%s'" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"Sua lista de filtros irá aparecer aqui. Crie uma clicando clicando no botão " +"'+'" + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Procure ou Crie" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +#, fuzzy +msgid "Search" +msgstr "Search" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -870,8 +901,8 @@ msgstr "Limpar" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "Voltar" @@ -886,36 +917,13 @@ msgstr "Adicionar Rótulos" msgid "Select Labels" msgstr "Deletar Rótulo" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "Neste computador" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Nenhuma Seção" @@ -934,11 +942,6 @@ msgstr "Seções" msgid "Select Section" msgstr "Deletar Seção" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -#, fuzzy -msgid "Search" -msgstr "Search" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -969,56 +972,71 @@ msgstr "Adicionar Lembrete" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Tarefa copiada para a área de transferência" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Este projeto foi copiado para a Área de Transferência." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, fuzzy, c-format msgid "Delete Project %s?" msgstr "Deletar Projeto" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Deletar" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "Arquivar?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "Isto irá arquivar %s e todas suas tarefas." -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "Arquivar" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, fuzzy, c-format msgid "Delete Section %s" msgstr "Deletar Seção %s" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Deletar Seção" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1141,49 +1159,58 @@ msgstr "" "executado quando sua janela for fechada para que possa enviar notificações " "de tarefas." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "Abra a Busca Rápida" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Preferências" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Atalhos do Teclado" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "O que há de Novo" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "Sobre o Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 #, fuzzy msgid "Archived Projects" msgstr "Adicionar Projeto" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Crie mais" + +#: src/Services/Backups.vala:411 #, fuzzy msgid "Delete Backup" msgstr "Criar Backup" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Backup importado com sucesso" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "Processo concluído, você precisa iniciar o Planify novamente" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Planeje Arquivos de Backup" @@ -1191,98 +1218,79 @@ msgstr "Planeje Arquivos de Backup" msgid "On this computer" msgstr "Neste computador" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "Ir para a Caixa de Entrada" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "Ir para Hoje" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "Ir para Agendado" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "Ir para Rótulos" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "Ir para o Quadro de Anúncios" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Favoritos" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "Nenhum favorito disponível. Crie um clicando no botão '+'" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "Neste Computador" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "Nenhum projeto disponível. Crie um clicando no botão '+'" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "O que há de novo no Planify" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Adicionar Projeto" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "Nenhuma conta disponível. Sincronize uma clicando no botão '+'" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "" "Classificação de projetos alterada para 'Ordem de classificação " "personalizada'" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Remover dos Favoritos" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Adicionar aos Favoritos" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Editar Projeto" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 #, fuzzy msgid "Duplicate" msgstr "Duplicar" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "Atualizar" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Deletar Projeto" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Compartilhar" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "Enviar por E-Mail" @@ -1291,119 +1299,121 @@ msgstr "Enviar por E-Mail" msgid "(No Section)" msgstr "(Sem seção)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Adicionar Tarefa" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Editar Seção" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Mover Seção" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Gerenciar Ordem de Seção" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Deletar Seção" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "Adicionar Subtarefa" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 #, fuzzy msgid "Add Attachments" msgstr "Adicionar tarefa" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Sem Data" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Mover" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Adicionar Subtarefa" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Editar" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Deletar Tarefa" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Escolha uma data" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "Copiar para Área de Transferência" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Repetir" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Diariamente" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Semanalmente" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Mensalmente" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Yearly" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Personalizado" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Concluído. Próxima ocorrência: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s foi deletado" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Desfazer" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "Ordem alterada para 'Ordem de classificação personalizada'" @@ -1437,21 +1447,25 @@ msgstr "Título" msgid "Properties" msgstr "Propriedades" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 #, fuzzy msgid "Are you sure you want to delete?" msgstr "Tem certeza de que deseja excluir %s?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 #, fuzzy msgid "Open/Close Sidebar" msgstr "Alternar Barra Lateral" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "Nenhum projeto disponível. Crie um clicando no botão '+'" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "O modo Offline está Ativado" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1512,7 +1526,7 @@ msgid "Attach File" msgstr "Arquivos de Backup" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Download" @@ -1534,6 +1548,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Fonte" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 #, fuzzy msgid "Project Actions" @@ -1582,13 +1610,13 @@ msgstr "Quadro" msgid "Custom sort order" msgstr "Ordem de classificação personalizada" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Alfabeticamente" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 #, fuzzy msgid "Date Added" @@ -1625,27 +1653,27 @@ msgstr "Próximos 30 dias" msgid "Duedate" msgstr "Data de vencimento" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Filtrar por Rótulos" @@ -1669,7 +1697,7 @@ msgstr "Deletar Todas Tarefas Concluídas" msgid "Sort By" msgstr "Ordenar por" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 #, fuzzy msgid "Filter By" @@ -1703,48 +1731,52 @@ msgstr "Atrasado" msgid "Reschedule" msgstr "Reagendar" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Order by" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Rótulos: Neste Computador" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Rótulos: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "Nenhum favorito disponível. Crie um clicando no botão '+'" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "Marcadores: Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Adicionar Projeto" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "Isto irá deletar %d tarefas completadas e suas subtarefas" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Novo Projeto" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Dê um nome ao seu projeto" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Use Emoji" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Fonte" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Atualizar Projeto" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Fonte" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Projeto adicionado com sucesso!" @@ -1793,8 +1825,8 @@ msgid "Please enter your credentials" msgstr "Insira suas credenciais" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "A Internet Não Está Disponível" @@ -1854,7 +1886,7 @@ msgstr "" msgid "Archived" msgstr "" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Digite uma busca" @@ -2002,7 +2034,7 @@ msgstr "" "considere nos apoiar." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Nos Apoiando" @@ -2044,7 +2076,7 @@ msgid "Appearance" msgstr "Aparência" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Adição Rápida" @@ -2075,7 +2107,7 @@ msgid "Reach Us" msgstr "Chegue Até Nós" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "Contate-nos" @@ -2113,7 +2145,7 @@ msgid "Privacy" msgstr "Privacidade" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Política de Privacidade" @@ -2318,45 +2350,36 @@ msgid "Dark Blue Style" msgstr "Tema Azul-Escuro" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Contas" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Sincronize com sua Conta Todoist" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Você pode classificar suas visualizações arrastando e soltando" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "Sincronização baseada em padrões abertos da Internet" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Sincronizar Servidor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Ative esta configuração para que o Planify sincronize automaticamente com " "sua conta Todoist a cada 15 minutos" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Última Sincronização" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Ative esta configuração para que o Planify sincronize automaticamente com " -"sua conta CalDAV a cada 15 minutos" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2365,7 +2388,7 @@ msgstr "" "trabalho com apenas alguns toques no teclado. Você nem precisa sair do " "aplicativo em que está." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2373,74 +2396,72 @@ msgstr "" "Vá para Configurações do sistema → Teclado → Atalhos → Personalizado e " "adicione um novo atalho com o seguinte:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Configurações" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Salvar Último Projeto Selecionado" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "Se desmarcado, o projeto padrão selecionado será Caixa de Entrada" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "O comando foi copiado para a área de transferência" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Carregando…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "" "Planify está sincronizando suas tarefas, isso pode levar alguns minutos" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Sincronizando..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Por Favor, Insira suas Credenciais" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 #, fuzzy msgid "Nextcloud Setup" msgstr "Nextcloud" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "URL do servidor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "Nome de Usuário" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "Senha" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "Provedor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "Login" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "Falha ao fazer login" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Dados Pessoais" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2448,7 +2469,7 @@ msgstr "" "Não coletamos absolutamente nada e todos os seus dados são armazenados em um " "banco de dados no seu computador." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2458,11 +2479,11 @@ msgstr "" "padrão, seus dados serão armazenados em seus servidores privados, apenas " "exibimos suas tarefas configuradas e as gerenciamos para você." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "Você tem alguma pergunta?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2470,7 +2491,7 @@ msgstr "" "Se você tiver alguma dúvida sobre seus dados ou qualquer outro assunto, " "entre em contato conosco. Teremos o maior prazer em responder-lhe." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2480,42 +2501,22 @@ msgstr "" "código aberto para usuários em todo o mundo. Suas doações apoiam este " "trabalho. Quer doar hoje?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Tem certeza de que deseja remover a sincronização do Todoist? Esta ação " -"excluirá todas as suas tarefas e configurações." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Tem certeza de que deseja remover a sincronização do CalDAV? Esta ação " -"excluirá todas as suas tarefas e configurações." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Sair" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2536,40 +2537,50 @@ msgstr "Importar Backup" msgid "Backup Files" msgstr "Arquivos de Backup" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "Nenhuma conta disponível. Sincronize uma clicando no botão '+'" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "Migrar" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "Migrar do Planner" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Tarefas Migradas com Sucesso" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "Tarefas Migradas com Sucesso" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "O arquivo de banco de dados não existe." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr " Importar Visão Geral" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 #, fuzzy msgid "To-Dos" msgstr "Adicionar tarefa" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Confirmar" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Restaurar Backup" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2577,15 +2588,15 @@ msgstr "" "Você tem certeza que quer continuar? Esta operação excluirá seus dados " "atuais e os substituirá pelos dados de backup." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Restaurar Backup" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "O arquivo selecionado é inválido" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 #, fuzzy msgid "View Backup" msgstr "Criar Backup" @@ -2705,8 +2716,50 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Abrir Quadro de Anúncios" -#~ msgid "CalDAV" -#~ msgstr "CalDAV" +#~ msgid "On this Computer" +#~ msgstr "Neste computador" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Rótulos: Neste Computador" + +#~ msgid "Labels: Todoist" +#~ msgstr "Rótulos: Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "Marcadores: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Sincronize com sua Conta Todoist" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "Sincronização baseada em padrões abertos da Internet" + +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Ative esta configuração para que o Planify sincronize automaticamente com " +#~ "sua conta CalDAV a cada 15 minutos" + +#~ msgid "Failed to login" +#~ msgstr "Falha ao fazer login" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Tem certeza de que deseja remover a sincronização do Todoist? Esta ação " +#~ "excluirá todas as suas tarefas e configurações." + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Tem certeza de que deseja remover a sincronização do CalDAV? Esta ação " +#~ "excluirá todas as suas tarefas e configurações." + +#~ msgid "Sign Off" +#~ msgstr "Sair" #~ msgid "CalDAV Setup" #~ msgstr "Configuração do CalDAV" @@ -2886,13 +2939,6 @@ msgstr "Abrir Quadro de Anúncios" #~ msgid "No label available, click to add one" #~ msgstr "Nenhum rótulo disponível, clique para adicionar um" -#~ msgid "" -#~ "Your list of filters will show up here. Create one by clicking on the '+' " -#~ "button" -#~ msgstr "" -#~ "Sua lista de filtros irá aparecer aqui. Crie uma clicando clicando no " -#~ "botão '+'" - #~ msgid "Sync" #~ msgstr "Sincronizar" diff --git a/po/pt_PT.po b/po/pt_PT.po index ad8adaa95..66b7dbea4 100644 --- a/po/pt_PT.po +++ b/po/pt_PT.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-07-15 10:40-0300\n" "Last-Translator: Ana Godinho \n" "Language: pt_PT\n" @@ -21,7 +21,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -30,7 +30,7 @@ msgstr "" msgid "Today" msgstr "Hoje" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -40,7 +40,7 @@ msgstr "Hoje" msgid "Inbox" msgstr "Caixa de Entrada" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -54,137 +54,148 @@ msgstr "Agendado" msgid "Pinboard" msgstr "Quadro de anúncios" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Projetos" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Secções" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Tarefas" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Etiquetas" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Filtros" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Listas" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Não Repetir" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 #, fuzzy msgid "Every minute" msgstr "A cada minuto" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, fuzzy, c-format msgid "Every %d minutes" msgstr "A cada %d minutos" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 #, fuzzy msgid "Every hour" msgstr "A cada hora" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, fuzzy, c-format msgid "Every %d hours" msgstr "A cada %d horas" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Todos os dias" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "A cada %d dias" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "A cada semana" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "A cada %d semanas" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "A cada mês" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "A cada %d meses" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "A cada ano" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "A cada %d anos" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Prioridade" -#: core/Enum.vala:365 +#: core/Enum.vala:419 #, fuzzy msgid "Label" msgstr "Etiqueta" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 #, fuzzy msgid "Due Date" msgstr "Data limite" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Tarefa Criada" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Tarefa Atualizada" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "Conteúdo" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Descrição" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 #, fuzzy msgid "Pin" msgstr "Fixar" @@ -312,8 +323,8 @@ msgstr "Escuro" msgid "Dark Blue" msgstr "Azul Escuro" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Nenhum" @@ -322,17 +333,16 @@ msgstr "Nenhum" msgid "Today + Inbox" msgstr "Hoje + Caixa de Entrada" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Cancelar" @@ -345,9 +355,8 @@ msgstr "Eliminar Todos" msgid "Process completed, you need to start Planify again." msgstr "Processo completo, é necessário reiniciar o Planify." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "Ok" @@ -383,24 +392,28 @@ msgstr "baixa" msgid "none" msgstr "nenhuma" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "Neste Computador" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Conheça o Planify" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " "one from settings." msgstr "" -"Este projeto mostra tudo o que precisa de saber para começar. Não hesite a explorá-lo " -"- pode sempre criar um novo projeto nas definições." +"Este projeto mostra tudo o que precisa de saber para começar. Não hesite a " +"explorá-lo - pode sempre criar um novo projeto nas definições." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Clique nesta tarefa" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -408,11 +421,11 @@ msgstr "" "Está a olhar para uma tarefa! Conclua a tarefa ao clicar na caixa à esquerda." "As tarefas completas ficarão guardadas na parte inferior do seu projeto." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Criar uma nova tarefa" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 #, fuzzy msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " @@ -421,21 +434,21 @@ msgstr "" "Agora é a sua vez, clique no botão '+' no topo do seu projeto, adicione " "qualquer tarefa em curso e clique no botão azul 'guardar'." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Planeie esta tarefa hoje ou mais tarde" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Clique no botão do calendário em baixo para decidir quando realizar esta " "tarefa" -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Reorganize as suas tarefas" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -443,12 +456,12 @@ msgstr "" "Para reorganizar a sua lista, clique e pressione numa tarefa, e arraste-a " "para onde deve ir." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 #, fuzzy msgid "Create a project" msgstr "Criar um projeto" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -456,11 +469,11 @@ msgstr "" "Organize melhor as suas tarefas! Vá ao painel da esquerda e clique no botão " "'+'na secção 'Neste computador' e adicione o seu próprio projeto." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "Já está!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 #, fuzzy msgid "" "That’s all you really need to know. Feel free to start adding your own " @@ -470,34 +483,33 @@ msgid "" "We hope you’ll enjoy using Planify!" msgstr "" "Isto é tudo que precisa de saber. Esteja à vontade para adicionar os seus " -"próprios projetos e tarefas." -"Pode regressar a este projeto mais tarde para " -"aprender as funcionalidades avançadas em baixo.." -"Esperamos que goste de utilizar o Planify!" +"próprios projetos e tarefas.Pode regressar a este projeto mais tarde para " +"aprender as funcionalidades avançadas em baixo..Esperamos que goste de " +"utilizar o Planify!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Ajustar a configuração" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 #, fuzzy msgid "Show your calendar events" msgstr "Mostrar eventos do Calendário" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " "'Preferences' 🡒 General 🡒 Calendar Events to turn it on." msgstr "" -"Pode mostrar os eventos do calendário do sistema no Planify, Vá " -"às 'Preferências' 🡒 Geral 🡒 Eventos de calendário para ligar." +"Pode mostrar os eventos do calendário do sistema no Planify, Vá às " +"'Preferências' 🡒 Geral 🡒 Eventos de calendário para ligar." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Ativar sincronização com serviços de terceiros." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -505,116 +517,121 @@ msgstr "" "O Planify não só cria tarefas localmente, como também sincroniza com a sua " "conta do Todoist. Vá às 'Preferências' 🡒 'Contas'." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Aumente a sua produtividade" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Arraste o botão mais!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." -msgstr "O botão azul que vê na parte inferior de cada ecrã é mais poderoso que " -"parece: foi feito para se mexer! Arraste-o para cima para criar uma tarefa quando quiser." +msgstr "" +"O botão azul que vê na parte inferior de cada ecrã é mais poderoso que " +"parece: foi feito para se mexer! Arraste-o para cima para criar uma tarefa " +"quando quiser." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 #, fuzzy msgid "Tag your to-dos!" msgstr "Adicione etiquetas às suas tarefas" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." -msgstr "As etiquetas permitem melhorar o seu fluxo de trabalho no Planify. Para adicionar uma Etiqueta, clique no" -"botão de etiqueta em baixo." +msgstr "" +"As etiquetas permitem melhorar o seu fluxo de trabalho no Planify. Para " +"adicionar uma Etiqueta, clique nobotão de etiqueta em baixo." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Define lembretes oportunos!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." -msgstr "Se quiser que o Planify envie uma notificação para lhe lembrar de um evento" -"importante ou algo especial. Toque no botão de sino abaixo para adicionar um lembrete." +msgstr "" +"Se quiser que o Planify envie uma notificação para lhe lembrar de um " +"eventoimportante ou algo especial. Toque no botão de sino abaixo para " +"adicionar um lembrete." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️Trabalho" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️Escola" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️Delegada" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️Casa" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, fuzzy, c-format msgid "Task moved to %s" msgstr "Tarefa movida para %s" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 #, fuzzy msgid "Task duplicated" msgstr "Tarefa duplicada" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 #, fuzzy msgid "Section duplicated" msgstr "Secção duplicada" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 #, fuzzy msgid "Project duplicated" msgstr "Projeto duplicado" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "No momento" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "10 minutos antes" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "30 minutos antes" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "45 minutos antes" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "1 hora antes" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "2 horas antes" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "3 horas antes" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Amanhã" @@ -670,39 +687,44 @@ msgstr "Sáb," msgid "Su," msgstr "Dom," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "O pedido estava incorreto." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "A Autenticação é requerida, e falhou ou ainda não foi fornecida." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "O pedido foi válido, mas por algum motivo é proibido." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "O recurso requerido não pôde ser encontrado." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "O utilizador mandou demasiados pedidos em um dado período de tempo." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "O pedido falhou devido a um erro de servidor." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "O servidor não pode processar o pedido no momento." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Erro desconhecido" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Não disponível" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "Fixado" @@ -754,11 +776,11 @@ msgid "To Do" msgstr "Tarefa" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Completar" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 #, fuzzy msgid "" "Your list of filters will show up here. Create one by entering the name and " @@ -768,15 +790,27 @@ msgstr "" "pressionando a tecla Enter" #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, fuzzy, c-format msgid "Create '%s'" msgstr "Criar '%s'" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"A sua lista de lembretes irá aparecer aqui. Crie uma clicando no botão '+'" + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Procurar ou Criar" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +#, fuzzy +msgid "Search" +msgstr "Procurar" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -872,9 +906,8 @@ msgstr "Apagar" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 -#, fuzzy +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "" @@ -890,36 +923,13 @@ msgstr "Adicionar Etiquetas" msgid "Select Labels" msgstr "Selecionar Etiquetas" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "Neste computador" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Sem Secção" @@ -938,11 +948,6 @@ msgstr "Secção" msgid "Select Section" msgstr "Selecionar Secção" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -#, fuzzy -msgid "Search" -msgstr "Procurar" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -974,58 +979,73 @@ msgstr "Adicionar Lembrete" #: core/Widgets/Markdown/MarkdownEditView.vala:138 #: core/Widgets/Markdown/MarkdownEditView.vala:141 msgid "Couldn't find an app to handle file URIs" -msgstr "Não foi possível encontrar uma aplicação para lidar com o ficheiro URIs " +msgstr "" +"Não foi possível encontrar uma aplicação para lidar com o ficheiro URIs " -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Tarefa copiada para a área de transferência" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Este projeto foi copiado para a Área de Transferência." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, fuzzy, c-format msgid "Delete Project %s?" msgstr "Eliminar Projeto %s?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "Isto não pode ser desfeito" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Eliminar" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "Arquivar?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "Isto irá arquivar %s e todas as suas tarefas." -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "Arquivar" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, fuzzy, c-format msgid "Delete Section %s" msgstr "Eliminar Secção %s" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +msgid "CalDAV - " +msgstr "" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Eliminar Secção" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1150,54 +1170,63 @@ msgstr "" "irá correr quando a janela estiver fechada para que possa enviar " "notificações das tarefas." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "Menu Principal" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 #, fuzzy msgid "Open Quick Find" msgstr "Abrir Busca Rápida" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Preferências" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 #, fuzzy msgid "Keyboard Shortcuts" msgstr "Atalhos de teclado" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "O que há de novo" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 #, fuzzy msgid "About Planify" msgstr "Sobre o Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 #, fuzzy msgid "Archived Projects" msgstr "Projetos Arquivados" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Criar Mais" + +#: src/Services/Backups.vala:411 #, fuzzy msgid "Delete Backup" msgstr "Eliminar cópia de segurança" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 #, fuzzy msgid "Backup Successfully Imported" msgstr "Cópia de segurança importada com sucesso" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 #, fuzzy msgid "Process completed, you need to start Planify again" msgstr "Processo completo, é necessário reiniciar o Planify." -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 #, fuzzy msgid "Planify Backup Files" msgstr "Ficheiros da cópia de segurança do Planify" @@ -1206,106 +1235,87 @@ msgstr "Ficheiros da cópia de segurança do Planify" msgid "On this computer" msgstr "Neste computador" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 #, fuzzy msgid "Go to Inbox" msgstr "Ir para a Caixa de Entrada" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 #, fuzzy msgid "Go to Today" msgstr "Ir para Hoje" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 #, fuzzy msgid "Go to Scheduled" msgstr "Ir para Agendado" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 #, fuzzy msgid "Go to Labels" msgstr "Ir para Etiquetas" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 #, fuzzy msgid "Go to Pinboard" msgstr "Ir para o Quadro de anúncios" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Favoritos" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "Nenhum favorito disponível. Crie um clicando no botão '+'" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "Neste Computador" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "Nenhum projeto disponível. Crie um clicando no botão '+'" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "O que há de novo no Planify" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -#, fuzzy -msgid "Add Project" -msgstr "Adicionar projeto" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "Nenhuma conta disponível. Sincronize uma clicando no botão '+'" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 #, fuzzy msgid "Projects sort changed to 'Custom sort order'" msgstr "" -"Ordem da lista de projetos alterada para 'Ordem de Classificação Personalizada'" +"Ordem da lista de projetos alterada para 'Ordem de Classificação " +"Personalizada'" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 #, fuzzy msgid "Remove From Favorites" msgstr "Remover dos Favoritos" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 #, fuzzy msgid "Add to Favorites" msgstr "Adicionar aos Favoritos" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Editar Projeto" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 #, fuzzy msgid "Duplicate" msgstr "Duplicar" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "Recarregar" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Eliminar Projeto" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Partilhar" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 #, fuzzy msgid "Send by E-Mail" msgstr "Enviar por e-mail" @@ -1315,130 +1325,131 @@ msgstr "Enviar por e-mail" msgid "(No Section)" msgstr "(Sem secção)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Adicionar Tarefa" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Editar Secção" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Mover Secção" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Gerir Ordem de Secção" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Eliminar Secção" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 #, fuzzy msgid "Add Subtasks" msgstr "Adicionar Subtarefas" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 #, fuzzy msgid "Add Attachments" msgstr "Adicionar Anexos" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Sem Data" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Mover" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 #, fuzzy msgid "Add Subtask" msgstr "Adicionar Subtarefa" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Editar" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 #, fuzzy msgid "Delete Task" msgstr "Eliminar Tarefa" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Usar como Nota" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 #, fuzzy msgid "Copy to Clipboard" msgstr "Copiar para a área de transferência" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Repetir" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "Mudar Histórico" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Diária" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 #, fuzzy msgid "Weekly" msgstr "Semanal" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 #, fuzzy msgid "Monthly" msgstr "Mensal" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 #, fuzzy msgid "Yearly" msgstr "Anual" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Personalizado" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Concluído. Próxima ocorrência: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, fuzzy, c-format msgid "%s was deleted" msgstr "%s foi eliminada" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Desfazer" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 #, fuzzy msgid "Order changed to 'Custom sort order'" -msgstr "" -"Ordem alterada para 'Ordem de Classificação Personalizada'" +msgstr "Ordem alterada para 'Ordem de Classificação Personalizada'" #: src/Layouts/ItemBoard.vala:118 msgid "View Details" @@ -1470,22 +1481,26 @@ msgstr "Título" msgid "Properties" msgstr "Propriedades" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 #, fuzzy msgid "Are you sure you want to delete?" msgstr "Tem a certeza que quer eliminar?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 #, fuzzy msgid "Open/Close Sidebar" msgstr "Abrir/Fechar Barra lateral" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "Nenhum projeto disponível. Crie um clicando no botão '+'" + +#: src/Widgets/SyncButton.vala:79 #, fuzzy msgid "Offline Mode Is On" msgstr "O modo offline está ativado" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1548,7 +1563,7 @@ msgid "Attach File" msgstr "Anexar Ficheiro" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Descarregar" @@ -1570,6 +1585,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Fonte" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 #, fuzzy msgid "Project Actions" @@ -1620,13 +1649,13 @@ msgstr "Quadro de anúncios" msgid "Custom sort order" msgstr "Ordem de classificação personalizada" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Alfabeticamente" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 #, fuzzy msgid "Date Added" @@ -1663,27 +1692,27 @@ msgstr "Próximos 30 dias" msgid "Duedate" msgstr "Data" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Filtrar por Etiquetas" @@ -1707,7 +1736,7 @@ msgstr "Eliminar Todas as Tarefas Concluídas" msgid "Sort By" msgstr "Ordenar por" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 #, fuzzy msgid "Filter By" @@ -1716,7 +1745,8 @@ msgstr "Filtrar por" #: src/Views/Project/Project.vala:597 #, c-format msgid "This will delete %d completed tasks and their subtasks from project %s" -msgstr "Isto irá eliminar as %d tarefas concluídas e as suas subtarefas do projeto %s" +msgstr "" +"Isto irá eliminar as %d tarefas concluídas e as suas subtarefas do projeto %s" #: src/Views/Project/List.vala:52 src/Views/Project/Board.vala:42 msgid "Note" @@ -1742,50 +1772,54 @@ msgstr "Atrasado" msgid "Reschedule" msgstr "Reagendar" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Ordenar por" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Etiquetas: Neste Computador" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Etiquetas: Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "Nenhum favorito disponível. Crie um clicando no botão '+'" -#: src/Views/Label/Labels.vala:49 +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 #, fuzzy -msgid "Labels: Nextcloud" -msgstr "Etiquetas: Nextcloud" +msgid "Add Project" +msgstr "Adicionar projeto" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "Isto irá eliminar as %d tarefas concluídas e as suas subtarefas" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Novo Projeto" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Dê um nome ao seu projeto" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Usar Emoji" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Fonte" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 #, fuzzy msgid "Update Project" msgstr "Atualizar projeto" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Fonte" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Projeto adicionado com sucesso!" @@ -1841,8 +1875,8 @@ msgid "Please enter your credentials" msgstr "Insira os seus dados, por favor" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "A Internet Não Está Disponível" @@ -1854,8 +1888,10 @@ msgstr "Caixa de Entrada como Projeto Independente" msgid "" "The Inbox is the default place to add new tasks, allowing you to quickly get " "your ideas out of your head and then plan them when you’re ready." -msgstr "A Caixa de Entrada é o lugar padrão para adicionar novas tarefas, tornando possível" -"tirar rapidamente as suas ideias da cabeça e depois planeá-las quando estiver pronto." +msgstr "" +"A Caixa de Entrada é o lugar padrão para adicionar novas tarefas, tornando " +"possíveltirar rapidamente as suas ideias da cabeça e depois planeá-las " +"quando estiver pronto." #: src/Dialogs/WhatsNew.vala:111 msgid "Enhanced Task Duplication" @@ -1865,8 +1901,10 @@ msgstr "Duplicação de Tarefa Melhorada" msgid "" "When you duplicate a task now, all subtasks and labels are automatically " "duplicated, saving you time and effort in managing your projects." -msgstr "Quando duplica uma tarefa, agora todas as subtarefas e etiquetas são, automaticamente," -"duplicadas, poupando tempo e esforço ao gerir os seus projetos." +msgstr "" +"Quando duplica uma tarefa, agora todas as subtarefas e etiquetas são, " +"automaticamente,duplicadas, poupando tempo e esforço ao gerir os seus " +"projetos." #: src/Dialogs/WhatsNew.vala:112 #, fuzzy @@ -1877,8 +1915,9 @@ msgstr "Duplicação de Secções e Projetos" msgid "" "You can now easily duplicate entire sections and projects, making it easier " "to create new projects based on existing structures." -msgstr "Agora consegue duplicar secções e projetos inteiros facilmente, tornando criar" -"novos projetos baseados em estruturas já existentes mais fáceis." +msgstr "" +"Agora consegue duplicar secções e projetos inteiros facilmente, tornando " +"criarnovos projetos baseados em estruturas já existentes mais fáceis." #: src/Dialogs/WhatsNew.vala:113 msgid "Project Expiry Date" @@ -1888,8 +1927,9 @@ msgstr "Data de validade do Projeto" msgid "" "Your project’s expiry date now clearly shows the remaining days, helping you " "keep track of your deadlines more effectively." -msgstr "A data de validade do projeto agora mostra os dias restantes, ajudando-lhe" -"a acompanhar os seus prazos." +msgstr "" +"A data de validade do projeto agora mostra os dias restantes, ajudando-lhea " +"acompanhar os seus prazos." #: src/Dialogs/WhatsNew.vala:114 #, fuzzy @@ -1900,14 +1940,15 @@ msgstr "Arquivando Projetos e Secções" msgid "" "You can now archive entire projects and sections! This feature helps you " "keep your workspace organized and clutter-free." -msgstr "Agora pode arquivar projetos e secções inteiros! Esta função ajuda a" -"manter o seu espaço de trabalho organizado e livre de desordem." +msgstr "" +"Agora pode arquivar projetos e secções inteiros! Esta função ajuda amanter o " +"seu espaço de trabalho organizado e livre de desordem." #: src/Dialogs/ManageSectionOrder.vala:58 msgid "Archived" msgstr "Arquivado" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Digite uma busca" @@ -2025,7 +2066,8 @@ msgstr "Atualizado às" #: src/Dialogs/ItemChangeHistory.vala:62 msgid "" "Your change history will be displayed here once you start making changes." -msgstr "O histórico de mudanças será exibido aqui quando começar a fazer mudanças." +msgstr "" +"O histórico de mudanças será exibido aqui quando começar a fazer mudanças." #: src/Dialogs/ItemChangeHistory.vala:124 #, c-format @@ -2054,12 +2096,13 @@ msgid "" "Planify is being developed with love and passion for open source. However, " "if you like Planify and want to support its development, please consider " "supporting us." -msgstr "O Planify está a ser desenvolvido com amor e paixão por open source. Contudo," -"se gostar do Planify e quiser apoiar o seu desenvolvimento, por favor considere " -"apoiar-nos." +msgstr "" +"O Planify está a ser desenvolvido com amor e paixão por open source. Contudo," +"se gostar do Planify e quiser apoiar o seu desenvolvimento, por favor " +"considere apoiar-nos." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 #, fuzzy msgid "Supporting Us" msgstr "Apoiar o Planify" @@ -2105,7 +2148,7 @@ msgid "Appearance" msgstr "Aparência" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 #, fuzzy msgid "Quick Add" msgstr "Busca Rápida" @@ -2139,7 +2182,7 @@ msgid "Reach Us" msgstr "Entre em contacto connosco" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 #, fuzzy msgid "Contact Us" msgstr "Contacte-nos" @@ -2182,7 +2225,7 @@ msgid "Privacy" msgstr "Privacidade" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 #, fuzzy msgid "Privacy Policy" msgstr "Política de Privacidade" @@ -2408,56 +2451,44 @@ msgid "Dark Blue Style" msgstr "Estilo Azul Escuro" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Contas" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Sincronize com sua Conta Todoist" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +msgid "You can sort your accounts by dragging and dropping" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "Sincronização baseada nos padrões abertos da Internet" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Sincronizar Servidor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 #, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Ative esta configuração para que o Planner sincronize automaticamente com a " "sua conta Todoist a cada 15 minutos." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Última Sincronização" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -#, fuzzy -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Ative esta configuração para que o Planner sincronize automaticamente com a " -"sua conta CalDAV a cada 15 minutos." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." msgstr "" -"Utilize a Adição Rápida para criar tarefas de qualquer lado do seu computador " -"com apenas alguns cliques. Nem precisa de sair da aplicação em que se " -"encontra." +"Utilize a Adição Rápida para criar tarefas de qualquer lado do seu " +"computador com apenas alguns cliques. Nem precisa de sair da aplicação em " +"que se encontra." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2465,161 +2496,141 @@ msgstr "" "Vá às definições do sistema → Teclado → Atalhos → Personalizar, e depois " "adicione um novo atalho com o seguinte:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 #, fuzzy msgid "Settings" msgstr "Definições" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 #, fuzzy msgid "Save Last Selected Project" msgstr "Eliminar o Último Projeto Selecionado" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 #, fuzzy msgid "If unchecked, the default project selected is Inbox" msgstr "" "Se não estiver selecionado, o projeto padrão selecionado é a Caixa de Entrada" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 #, fuzzy msgid "The command was copied to the clipboard" msgstr "Este comando foi copiado para a Área de Transferência." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 #, fuzzy msgid "Loading…" msgstr "Carregando..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 #, fuzzy msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "" "O Plannify está a sincronizar suas tarefas, isto pode levar alguns minutos." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Sincronizando..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 #, fuzzy msgid "Please Enter Your Credentials" msgstr "Insira os seus dados, por favor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "Configuração Nextcloud" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "URL do Servidor" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "Nome de Utilizador" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "Palavra Passe" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "Iniciar Sessão" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "Falha ao Iniciar Sessão" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Dados Pessoais" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." -msgstr "Nós não recolhemos absolutamente nada e todos os seus dados são guardados na base de dados " -"no seu computador." +msgstr "" +"Nós não recolhemos absolutamente nada e todos os seus dados são guardados na " +"base de dados no seu computador." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " "your configured tasks and manage them for you." -msgstr "Se escolher integrar o Todoist, que é opcional e não está selecionado " -"por padrão, os seus dados serão guardados no servidor privados deles, nós apenas exibimos " -"as suas tarefas configuradas e gerimo-las por si." +msgstr "" +"Se escolher integrar o Todoist, que é opcional e não está selecionado por " +"padrão, os seus dados serão guardados no servidor privados deles, nós apenas " +"exibimos as suas tarefas configuradas e gerimo-las por si." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "Tem alguma questão?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." -msgstr "Se tiver alguma questão em relação ao seus dados ou qualquer outro problema, por favor " -"contacte-nos. Ficaremos felizes em responder-lhe." +msgstr "" +"Se tiver alguma questão em relação ao seus dados ou qualquer outro problema, " +"por favor contacte-nos. Ficaremos felizes em responder-lhe." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " "donate today?" -msgstr "A nossa missão é oferecer a melhor aplicação de gestão de tarefas de código aberto " -"para os utilizador em todo o mundo. As suas doações apoiam este trabalho. Quer " -"doar hoje?" +msgstr "" +"A nossa missão é oferecer a melhor aplicação de gestão de tarefas de código " +"aberto para os utilizador em todo o mundo. As suas doações apoiam este " +"trabalho. Quer doar hoje?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Tem a certeza que deseja remover a sincronização do Todoist? Esta ação irá " -"eliminar todas as suas tarefas e definições." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -#, fuzzy -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Tem a certeza que deseja remover a sincronização do CalDAV? Esta ação irá " -"eliminar todas as suas tarefas e definições." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -#, fuzzy -msgid "Sign Off" -msgstr "Sair" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " "projects, tasks and comments and import them later." msgstr "" -"Não se preocupe em perder os dados. Pode criar cópias de segurança " -"dos seus projetos ativos, tarefas e comentários, e pode importá-los mais tarde." +"Não se preocupe em perder os dados. Pode criar cópias de segurança dos seus " +"projetos ativos, tarefas e comentários, e pode importá-los mais tarde." #: src/Dialogs/Preferences/Pages/Backup.vala:65 #, fuzzy @@ -2636,41 +2647,51 @@ msgstr "Importar Cópia de Segurança" msgid "Backup Files" msgstr "Ficheiros de Cópia de Segurança" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "Nenhuma conta disponível. Sincronize uma clicando no botão '+'" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "Migrar" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "Migrar do Planner" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Tarefas Migradas com Sucesso" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 #, fuzzy msgid "Tasks Migrate Successfully" msgstr "Tarefas Migradas com Sucesso" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "O ficheiro da base de dados não existe." -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "Importar Overview" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 #, fuzzy msgid "To-Dos" msgstr "Tarefas" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Confirmar" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Restaurar cópia de segurança" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 #, fuzzy msgid "" "Are you sure you want to continue? This operation will delete your current " @@ -2679,15 +2700,15 @@ msgstr "" "Tem a certeza que quer continuar? Esta ação irá eliminar todos os seus dados " "atuais e substituí-los com os dados da cópia de segurança." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Restaurar Cópia de Segurança" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "O ficheiro selecionado está inválido" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 #, fuzzy msgid "View Backup" msgstr "Ver Cópia de Segurança" @@ -2825,6 +2846,55 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Abrir Quadro de anúncios" +#~ msgid "On this Computer" +#~ msgstr "Neste computador" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Etiquetas: Neste Computador" + +#~ msgid "Labels: Todoist" +#~ msgstr "Etiquetas: Todoist" + +#, fuzzy +#~ msgid "Labels: Nextcloud" +#~ msgstr "Etiquetas: Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Sincronize com sua Conta Todoist" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "Sincronização baseada nos padrões abertos da Internet" + +#, fuzzy +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Ative esta configuração para que o Planner sincronize automaticamente com " +#~ "a sua conta CalDAV a cada 15 minutos." + +#~ msgid "Failed to login" +#~ msgstr "Falha ao Iniciar Sessão" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Tem a certeza que deseja remover a sincronização do Todoist? Esta ação " +#~ "irá eliminar todas as suas tarefas e definições." + +#, fuzzy +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Tem a certeza que deseja remover a sincronização do CalDAV? Esta ação irá " +#~ "eliminar todas as suas tarefas e definições." + +#, fuzzy +#~ msgid "Sign Off" +#~ msgstr "Sair" + #, fuzzy #~ msgid "Add task" #~ msgstr "Adicionar Tarefa" @@ -2974,8 +3044,7 @@ msgstr "Abrir Quadro de anúncios" #~ msgid "" #~ "Now supports project selection, due date, priority, labels and pinned." #~ msgstr "" -#~ "Agora suporta seleção de projetos, prazo, prioridade, etiquetas, e " -#~ "fixados" +#~ "Agora suporta seleção de projetos, prazo, prioridade, etiquetas, e fixados" #, fuzzy #~ msgid "Sidebar filter settings" diff --git a/po/ru.po b/po/ru.po index d86b23347..3f5b05f40 100644 --- a/po/ru.po +++ b/po/ru.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: com.github.alainm23.planner\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-01-17 08:24+0500\n" "Last-Translator: Hachikoha \n" "Language-Team: \n" @@ -23,7 +23,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -32,7 +32,7 @@ msgstr "" msgid "Today" msgstr "Сегодня" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -42,7 +42,7 @@ msgstr "Сегодня" msgid "Inbox" msgstr "Входящие" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -56,137 +56,148 @@ msgstr "Предстоящее" msgid "Pinboard" msgstr "Закрепленные" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Проекты" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Разделы" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Задачи" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Метки" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Фильтры" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Списки" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Не повторять" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 #, fuzzy msgid "Every minute" msgstr "Каждый месяц" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, fuzzy, c-format msgid "Every %d minutes" msgstr "Каждые %d месяца(ев)" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 #, fuzzy msgid "Every hour" msgstr "Каждый год" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, fuzzy, c-format msgid "Every %d hours" msgstr "Каждые %d года(лет)" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Каждый день" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "Каждые %d дня(ей)" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Каждую неделю" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "Каждые %d недели(ель)" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Каждый месяц" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "Каждые %d месяца(ев)" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Каждый год" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "Каждые %d года(лет)" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "По приоритету" -#: core/Enum.vala:365 +#: core/Enum.vala:419 #, fuzzy msgid "Label" msgstr "Метки" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 #, fuzzy msgid "Due Date" msgstr "По сроку выполнения" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Дублировать" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Дублировать" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Описание" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 #, fuzzy msgid "Pin" msgstr "Закрепить" @@ -313,8 +324,8 @@ msgstr "Темный" msgid "Dark Blue" msgstr "Темно-синий" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Нет" @@ -323,17 +334,16 @@ msgstr "Нет" msgid "Today + Inbox" msgstr "Сегодня + Входящие" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "Отмена" @@ -346,9 +356,8 @@ msgstr "Удалить метку" msgid "Process completed, you need to start Planify again." msgstr "Процесс завершен, вам нужно снова запустить Planify." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "ОК" @@ -384,11 +393,15 @@ msgstr "низкий" msgid "none" msgstr "нет" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "На этом компьютере" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Встречайте Planify" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -398,11 +411,11 @@ msgstr "" "стесняйтесь экспериментировать с ним – вы всегда можете создать новый в " "настройках." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Нажмите на эту задачу" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -410,11 +423,11 @@ msgstr "" "Перед вами задача! Выполните ее, нажав на флажок слева. Выполненные задачи " "собираются в нижней части вашего проекта." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Создайте новую задачу" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -422,20 +435,20 @@ msgstr "" "Теперь ваша очередь, нажмите кнопку «+» в нижней части проекта, введите все " "оставшиеся данные и нажмите синюю кнопку «Сохранить»." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Запланируйте эту задачу на сегодня или позже" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Нажмите кнопку календаря внизу, чтобы решить, когда выполнить это задание." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Измените порядок задач" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -443,11 +456,11 @@ msgstr "" "Чтобы изменить порядок задач, нажмите и удерживайте задачу, а затем " "перетащите ее на нужное место." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Создайте проект" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -455,11 +468,11 @@ msgstr "" "Организуйте свои задачи лучше! Перейдите на боковую панель, нажмите кнопку " "«+» в разделе «На этом компьютере» и добавьте собственный проект." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "Вы готовы!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 #, fuzzy msgid "" "That’s all you really need to know. Feel free to start adding your own " @@ -476,15 +489,15 @@ msgstr "" "\n" "Мы надеемся, что вам понравится использовать Planify!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Настройте параметры приложения" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Отобразите события календаря" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -493,11 +506,11 @@ msgstr "" "Вы можете отображать события календаря вашей системы в Planify. Перейдите в " "«Настройки» 🡒 «Общие» 🡒 «События календаря», чтобы включить их." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Включите синхронизацию со сторонним сервисом." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -505,15 +518,15 @@ msgstr "" "Planify не только создает задачи локально, но и может синхронизировать их с " "вашей учетной записью Todoist. Перейдите в «Настройки» 🡒 «Учетные записи»." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Повысьте свою продуктивность" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Перетащите кнопку плюс!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -522,11 +535,11 @@ msgstr "" "кажется: она создана для перемещения! Перетащите ее вверх, чтобы создать " "задачу там, где вам нужно." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "Помечайте свои задачи!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -534,11 +547,11 @@ msgstr "" "Метки позволяют улучшить рабочий процесс в Planify. Чтобы добавить метку, " "нажмите на кнопку метки внизу." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Устанавливайте своевременные напоминания!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -547,78 +560,78 @@ msgstr "" "событии или чем-то особенном. Нажмите кнопку с изображением колокольчика " "ниже, чтобы добавить напоминание." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️ Работа" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️ Учеба" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️ Делегировано" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️ Дом" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️ Ожидает продолжения" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, fuzzy, c-format msgid "Task moved to %s" msgstr "Задача скопирована в буфер обмена" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 #, fuzzy msgid "Task duplicated" msgstr "Дублировать" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 #, fuzzy msgid "Section duplicated" msgstr "Название раздела" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 #, fuzzy msgid "Project duplicated" msgstr "Проекты" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Завтра" @@ -674,42 +687,47 @@ msgstr "Сб," msgid "Su," msgstr "Вс," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "Запрос был неверным." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "" "Требуется аутентификация, но она завершилась неудачно или еще не была " "выполнена." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "Запрос был корректным, но относился к чему-то, что запрещено." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "Запрошенный ресурс не найден." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "" "Пользователь отправил слишком много запросов за определенный период времени." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "Запрос не был выполнен из-за ошибки сервера." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "В настоящее время сервер не может обработать запрос." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Неизвестная ошибка" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Не доступно" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "Закрепить" @@ -761,11 +779,11 @@ msgid "To Do" msgstr "" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Выполнить" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -774,15 +792,26 @@ msgstr "" "клавишу Enter." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, fuzzy, c-format msgid "Create '%s'" msgstr "Создайте проект" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "Здесь появится список напоминаний. Добавьте его, нажав кнопку «+»." + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Создать или найти" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +#, fuzzy +msgid "Search" +msgstr "Поиск" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -878,8 +907,8 @@ msgstr "" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 #, fuzzy msgid "Back" msgstr "Резервные копии" @@ -896,36 +925,13 @@ msgstr "Добавить метку" msgid "Select Labels" msgstr "Удалить метку" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "На этом компьютере" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Нет раздела" @@ -944,11 +950,6 @@ msgstr "Разделы" msgid "Select Section" msgstr "Удалить раздел" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -#, fuzzy -msgid "Search" -msgstr "Поиск" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -979,56 +980,70 @@ msgstr "Добавить напоминание" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Задача скопирована в буфер обмена" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Проект скопирован в буфер обмена." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, fuzzy, c-format msgid "Delete Project %s?" msgstr "Удалить проект" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Удалить" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "" -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, fuzzy, c-format msgid "Delete Section %s" msgstr "Удалить раздел" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +msgid "CalDAV - " +msgstr "" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Удалить раздел" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1152,50 +1167,59 @@ msgstr "" "Planify будет автоматически запускаться при входе в систему и работать в " "фоновом режиме при закрытии его окна для отправки уведомлений." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 #, fuzzy msgid "Open Quick Find" msgstr "Открыть быстрый поиск" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Настройки" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Комбинации клавиш" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "Что нового" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "О Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 #, fuzzy msgid "Archived Projects" msgstr "Добавить проект" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Создайте проект" + +#: src/Services/Backups.vala:411 #, fuzzy msgid "Delete Backup" msgstr "Создать резервную копию" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Резервная копия успешно восстановлена" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "Процесс завершен, вам нужно снова запустить Planify" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Резервные копии Planify" @@ -1203,100 +1227,81 @@ msgstr "Резервные копии Planify" msgid "On this computer" msgstr "На этом компьютере" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 #, fuzzy msgid "Go to Inbox" msgstr "Сегодня + Входящие" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 #, fuzzy msgid "Go to Today" msgstr "Сегодня" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 #, fuzzy msgid "Go to Scheduled" msgstr "Предстоящее" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 #, fuzzy msgid "Go to Labels" msgstr "Метки" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 #, fuzzy msgid "Go to Pinboard" msgstr "Закрепленные" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Избранное" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "В избранном ничего нет. Создайте, нажав кнопку «+»" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "На этом компьютере" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "Нет доступного проекта. Создайте его, нажав кнопку «+»" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Что нового в Planify" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Добавить проект" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "Нет доступной учетной записи. Синхронизируйте ее, нажав кнопку «+»" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "Сортировка проектов изменена на сортировку «Вручную»" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Удалить из избранного" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Добавить в избранное" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Изменить проект" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "Дублировать" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Удалить проект" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Поделиться" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "Отправить по E-Mail" @@ -1305,120 +1310,122 @@ msgstr "Отправить по E-Mail" msgid "(No Section)" msgstr "(Нет раздела)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Добавить задачу" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Изменить раздел" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Перенести раздел" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Изменить порядок разделов" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Удалить раздел" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 #, fuzzy msgid "Add Subtasks" msgstr "Добавить подзадачу" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 #, fuzzy msgid "Add Attachments" msgstr "Добавить задачу" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Без срока" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Перенести" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Добавить подзадачу" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Изменить" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Удалить задачу" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Выбрать дату" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "Скопировать в буфер обмена" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Повторять" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Ежедневно" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Еженедельно" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Ежемесячно" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Ежегодно" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Установить вручную" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Выполнено. Следующий раз: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s удалено" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Отменить" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "Сортировка изменена на сортировку «Вручную»" @@ -1453,21 +1460,25 @@ msgstr "" msgid "Properties" msgstr "" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 #, fuzzy msgid "Are you sure you want to delete?" msgstr "Вы уверены, что хотите удалить %s?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 #, fuzzy msgid "Open/Close Sidebar" msgstr "Переключить боковую панель" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "Нет доступного проекта. Создайте его, нажав кнопку «+»" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "Автономный режим включен" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1529,7 +1540,7 @@ msgid "Attach File" msgstr "Файлы резервных копии" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "Скачать" @@ -1551,6 +1562,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Источник" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 #, fuzzy msgid "Project Actions" @@ -1599,13 +1624,13 @@ msgstr "Доска" msgid "Custom sort order" msgstr "Вручную" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "По алфавиту" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 #, fuzzy msgid "Date Added" @@ -1642,27 +1667,27 @@ msgstr "" msgid "Duedate" msgstr "Обновить" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Фильтровать по меткам" @@ -1686,7 +1711,7 @@ msgstr "Зачеркивать выполненные задачи" msgid "Sort By" msgstr "Сортировать" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 #, fuzzy msgid "Filter By" @@ -1721,49 +1746,52 @@ msgstr "Просрочено" msgid "Reschedule" msgstr "Перенести" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Сортировать" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Метки : На этом компьютере" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Метки : Todoist" - -#: src/Views/Label/Labels.vala:49 +#: src/Views/Label/LabelSourceRow.vala:43 #, fuzzy -msgid "Labels: Nextcloud" -msgstr "Метки : Todoist" +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "В избранном ничего нет. Создайте, нажав кнопку «+»" + +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Добавить проект" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Новый проект" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Введите название проекта" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Использовать Emoji" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Источник" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Обновить проект" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Источник" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Проект успешно добавлен!" @@ -1812,8 +1840,8 @@ msgid "Please enter your credentials" msgstr "Пожалуйста, введите данные своей учетной записи" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "Сеть недоступна" @@ -1873,7 +1901,7 @@ msgstr "" msgid "Archived" msgstr "" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Введите запрос" @@ -2023,7 +2051,7 @@ msgstr "" "пожалуйста, поддержите нас." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Поддержать нас" @@ -2065,7 +2093,7 @@ msgid "Appearance" msgstr "Оформление" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Быстрое добавление" @@ -2095,7 +2123,7 @@ msgid "Reach Us" msgstr "Связаться с нами" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "Свяжитесь с нами" @@ -2133,7 +2161,7 @@ msgid "Privacy" msgstr "Конфиденциальность" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Политика конфиденциальности" @@ -2343,47 +2371,36 @@ msgid "Dark Blue Style" msgstr "Темно-синий стиль" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Учетные записи" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Синхронизируйте со своей учетной записью Todoist" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Вы можете менять порядок своих списков, перетаскивая их" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Синхронизация с сервером" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 #, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Активируйте эту настройку, чтобы Planify автоматически синхронизировался с " "вашей учетной записью Todoist каждые 15 минут" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Последняя синхронизация" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -#, fuzzy -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Активируйте эту настройку, чтобы Planify автоматически синхронизировался с " -"вашей учетной записью Todoist каждые 15 минут" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2392,7 +2409,7 @@ msgstr "" "места на рабочем столе с помощью всего лишь нескольких нажатий клавиш. Вам " "даже не придется выходить из приложения, в котором вы сейчас находитесь." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2401,74 +2418,72 @@ msgstr "" "«Пользовательская комбинация клавиш», затем добавьте новую комбинацию клавиш " "со следующим текстом:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Настройки" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Сохранить в последний выбранный проект" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "" "Если эта опция не включена, по умолчанию будет выбран проект «Входящие»" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "Команда скопирована в буфер обмена" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Загрузка…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 #, fuzzy msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "Planify синхронизирует ваши задачи, это может занять несколько минут" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Синхронизация..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Пожалуйста, введите данные своей учетной записи" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Личные данные" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2476,7 +2491,7 @@ msgstr "" "Мы не собираем абсолютно ничего, а все ваши данные хранятся в базе данных на " "вашем компьютере." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2486,11 +2501,11 @@ msgstr "" "выбирается по умолчанию, ваши данные будут храниться на их частных серверах, " "а мы лишь отобразим ваши настроенные задачи и будем управлять ими для вас." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "У вас есть вопросы?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2498,7 +2513,7 @@ msgstr "" "Если у вас возникли вопросы по поводу ваших данных или по любому другому " "поводу, пожалуйста, свяжитесь с нами. Мы будем рады ответить вам." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2508,43 +2523,22 @@ msgstr "" "открытым исходным кодом для пользователей во всем мире. Ваши пожертвования " "поддерживают эту работу. Хотите сделать пожертвование сегодня?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Вы уверены, что хотите удалить синхронизацию с Todoist? Это действие " -"приведет к удалению всех ваших задач и настроек." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -#, fuzzy -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Вы уверены, что хотите удалить синхронизацию с Todoist? Это действие " -"приведет к удалению всех ваших задач и настроек." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Выйти" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2565,41 +2559,51 @@ msgstr "Импорт резервной копии" msgid "Backup Files" msgstr "Файлы резервных копии" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "Нет доступной учетной записи. Синхронизируйте ее, нажав кнопку «+»" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Задачи синхронизированы успешно" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 #, fuzzy msgid "Tasks Migrate Successfully" msgstr "Задачи синхронизированы успешно" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "Обзор импорта" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 #, fuzzy msgid "To-Dos" msgstr "Добавить задачу" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Подтвердить" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Восстановление резервной копии" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2607,15 +2611,15 @@ msgstr "" "Вы уверены, что хотите продолжить? Эта операция приведет к удалению текущих " "данных и замене их резервной копией." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Восстановить резервную копию" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "Выбранный файл недействителен" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 #, fuzzy msgid "View Backup" msgstr "Создать резервную копию" @@ -2736,6 +2740,48 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Открыть Закрепленные" +#~ msgid "On this Computer" +#~ msgstr "На этом компьютере" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Метки : На этом компьютере" + +#~ msgid "Labels: Todoist" +#~ msgstr "Метки : Todoist" + +#, fuzzy +#~ msgid "Labels: Nextcloud" +#~ msgstr "Метки : Todoist" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Синхронизируйте со своей учетной записью Todoist" + +#, fuzzy +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Активируйте эту настройку, чтобы Planify автоматически синхронизировался " +#~ "с вашей учетной записью Todoist каждые 15 минут" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Вы уверены, что хотите удалить синхронизацию с Todoist? Это действие " +#~ "приведет к удалению всех ваших задач и настроек." + +#, fuzzy +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Вы уверены, что хотите удалить синхронизацию с Todoist? Это действие " +#~ "приведет к удалению всех ваших задач и настроек." + +#~ msgid "Sign Off" +#~ msgstr "Выйти" + #, fuzzy #~ msgid "Add task" #~ msgstr "Добавить задачу" diff --git a/po/tr.po b/po/tr.po index 45facc5dd..aaf691f6e 100644 --- a/po/tr.po +++ b/po/tr.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: com.github.alainm23.planner\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: \n" "Last-Translator: Sabri Ünal \n" "Language-Team: \n" @@ -27,7 +27,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -36,7 +36,7 @@ msgstr "" msgid "Today" msgstr "Bugün" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -46,7 +46,7 @@ msgstr "Bugün" msgid "Inbox" msgstr "Gelen Kutusu" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -60,137 +60,148 @@ msgstr "Zamanlanmış" msgid "Pinboard" msgstr "Pano" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "Projeler" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "Bölümler" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "Görevler" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "Etiketler" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "Filtreler" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "Listeler" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "Tekrarlama" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 #, fuzzy msgid "Every minute" msgstr "Her ay" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, fuzzy, c-format msgid "Every %d minutes" msgstr "Her %d ayda bir" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 #, fuzzy msgid "Every hour" msgstr "Her yıl" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, fuzzy, c-format msgid "Every %d hours" msgstr "Her %d yılda bir" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "Her gün" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "%d günde bir" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "Her hafta" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "Her %d haftada bir" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "Her ay" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "Her %d ayda bir" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "Her yıl" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "Her %d yılda bir" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "Öncelik" -#: core/Enum.vala:365 +#: core/Enum.vala:419 #, fuzzy msgid "Label" msgstr "Etiketler" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 #, fuzzy msgid "Due Date" msgstr "Bitiş tarihi" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "Çoğalt" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "Çoğalt" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "Açıklama" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 #, fuzzy msgid "Pin" msgstr "İğnelenmiş" @@ -317,8 +328,8 @@ msgstr "Koyu" msgid "Dark Blue" msgstr "Koyu Mavi" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "Hiçbiri" @@ -327,17 +338,16 @@ msgstr "Hiçbiri" msgid "Today + Inbox" msgstr "Bugün + Gelen Kutusu" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "İptal" @@ -350,9 +360,8 @@ msgstr "Etiketi sil" msgid "Process completed, you need to start Planify again." msgstr "İşlem tamamlandı, Planify'ı yeniden başlatmanız gerekiyor." -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "Tamam" @@ -388,11 +397,15 @@ msgstr "düşük" msgid "none" msgstr "yok" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "Bu Bilgisayarda" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "Planify ile tanışın" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -401,11 +414,11 @@ msgstr "" "Bu proje, işe koyulmak için bilmeniz gereken her şeyi size gösterecek. " "Kurcalamaktan çekinmeyin. Ayarlardan her zaman yenisini oluşturabilirsiniz." -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "Bu yapılacaka dokunun" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -413,11 +426,11 @@ msgstr "" "Yapılacak bir işe bakıyorsunuz! Soldaki onay kutusuna dokunarak tamamlayın. " "Tamamlanan yapılacaklar projenizin altında toplanır." -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "Yeni yapılacak oluştur" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -425,21 +438,21 @@ msgstr "" "Şimdi sıra sizde. Projenizin altındaki '+' düğmesine dokunun, bekleyenleri " "girin ve mavi 'Kaydet' düğmesine dokunun." -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "Bu yapılacak işi bugün veya daha sonrasına planlayın" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "" "Bu yapılacak işi ne zaman yapacağınıza karar vermek için alttaki takvim " "düğmesine dokunun." -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "Yapılacaklarınızı yeniden sıralayın" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." @@ -447,11 +460,11 @@ msgstr "" "Listenizi yeniden sıralamak için yapılacak işe dokunup basılı tutun, " "ardından gitmesi gereken yere sürükleyin." -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "Proje oluştur" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -459,11 +472,11 @@ msgstr "" "Yapılacaklarınızı daha iyi organize edin! Sol panele gidip 'Bu Bilgisayarda' " "bölümündeki '+' düğmesine tıklayın ve kendinize ait bir proje ekleyin." -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "Bitti!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 #, fuzzy msgid "" "That’s all you really need to know. Feel free to start adding your own " @@ -480,15 +493,15 @@ msgstr "" "\n" "Planify'ı kullanmaktan keyif alacağınızı umuyoruz!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "Kurulumunuzu ayarlayın" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "Takvim etkinliklerinizi gösterin" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -497,11 +510,11 @@ msgstr "" "Sisteminizin takvim etkinliklerini Planify'da görüntüleyebilirsiniz. Açmak " "için 'Tercihler' 🡒 Takvim Olayları'na gidin." -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "Üçüncü taraf hizmetiyle eşzamanlamayı etkinleştirin." -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -509,15 +522,15 @@ msgstr "" "Planify sadece yerel olarak görevler oluşturmakla kalmaz, aynı zamanda " "Todoist hesabınızı da eşzamanlayabilir. 'Tercihler' 🡒 'Hesaplar'a git." -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "Üretkenliğinizi artırın" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "Artı düğmesini sürükleyin!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -525,11 +538,11 @@ msgstr "" "Her ekranın altındaki mavi düğme göründüğünden daha güçlüdür: hareket " "edebilmektedir! İstediğiniz yerde görev oluşturmak için yukarı sürükleyin." -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "Yapılacaklarınızı etiketleyin!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." @@ -537,11 +550,11 @@ msgstr "" "Etiketler, Planify'daki iş akışınızı geliştirmenizi sağlar. Etiket eklemek " "için alttaki etiket düğmesine tıklayın." -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "Zamanlı hatırlatıcılar ayarlayın!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -550,78 +563,78 @@ msgstr "" "bildirim göndermesini mi istiyorsunuz. Hatırlatıcı eklemek için aşağıdaki " "zil düğmesine dokunun." -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️İş" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️Okul" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️Atanmış" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️Ev" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️Takip Et" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, fuzzy, c-format msgid "Task moved to %s" msgstr "Görev panoya kopyalandı" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 #, fuzzy msgid "Task duplicated" msgstr "Çoğalt" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 #, fuzzy msgid "Section duplicated" msgstr "Bölüm Adı" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 #, fuzzy msgid "Project duplicated" msgstr "Projeler" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "Yarın" @@ -677,39 +690,44 @@ msgstr "Cts," msgid "Su," msgstr "Paz," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "İstek yanlış." -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "Kimlik doğrulama gerekiyor ve başarısız oldu veya henüz sağlanmadı." -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "İstek geçerliydi, ancak yasak olan bir şey için." -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "İstenen kaynak bulunamadı." -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "Kullanıcı belirli bir süre içinde çok fazla istek gönderdi." -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "Sunucu hatası nedeniyle istek başarısız oldu." -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "Sunucu şu anda isteği işleyemiyor." -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "Bilinmeyen hata" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "Kullanılamıyor" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "İğnelenmiş" @@ -761,11 +779,11 @@ msgid "To Do" msgstr "" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "Tamamlandı" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." @@ -774,15 +792,28 @@ msgstr "" "oluşturun." #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, fuzzy, c-format msgid "Create '%s'" msgstr "Proje oluştur" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "" +"Hatırlatıcılar listeniz burada görünecek. '+' düğmesine tıklayarak bir tane " +"ekleyin" + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "Ara veya Oluştur" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +#, fuzzy +msgid "Search" +msgstr "Ara" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -878,8 +909,8 @@ msgstr "" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 #, fuzzy msgid "Back" msgstr "Yedekler" @@ -896,36 +927,13 @@ msgstr "Etiket Ekle" msgid "Select Labels" msgstr "Etiketi sil" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "Bu Bilgisayarda" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "Bölüm Yok" @@ -944,11 +952,6 @@ msgstr "Bölümler" msgid "Select Section" msgstr "Bölümü Sil" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -#, fuzzy -msgid "Search" -msgstr "Ara" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -981,56 +984,70 @@ msgstr "Hatırlatıcı Ekle" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "Görev panoya kopyalandı" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "Proje Panoya kopyalandı." -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, fuzzy, c-format msgid "Delete Project %s?" msgstr "Projeyi Sil" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "Sil" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "" -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, fuzzy, c-format msgid "Delete Section %s" msgstr "Bölümü Sil" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +msgid "CalDAV - " +msgstr "" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "Bölümü Sil" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1154,50 +1171,59 @@ msgstr "" "Planify, bu aygıt açıldığında kendiliğinden başlayacak ve yapılacaklar " "bildirimleri gönderebilmek için penceresi kapatıldığında çalışacak." -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 #, fuzzy msgid "Open Quick Find" msgstr "Hızlı bulu aç" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "Tercihler" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "Klavye Kısayolları" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "Neler Yeni" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "Planify Hakkında" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 #, fuzzy msgid "Archived Projects" msgstr "Proje Ekle" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "Proje oluştur" + +#: src/Services/Backups.vala:411 #, fuzzy msgid "Delete Backup" msgstr "Yedek Oluştur" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "Yedek Başarıyla İçe Aktarıldı" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "İşlem tamamlandı, Planify'ı yeniden başlatmanız gerekiyor" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Planify Yedek Dosyaları" @@ -1205,103 +1231,82 @@ msgstr "Planify Yedek Dosyaları" msgid "On this computer" msgstr "Bu bilgisayarda" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 #, fuzzy msgid "Go to Inbox" msgstr "Bugün + Gelen Kutusu" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 #, fuzzy msgid "Go to Today" msgstr "Bugün" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 #, fuzzy msgid "Go to Scheduled" msgstr "Zamanlanmış" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 #, fuzzy msgid "Go to Labels" msgstr "Etiketler" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 #, fuzzy msgid "Go to Pinboard" msgstr "Pano" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "Gözdeler" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "" "Gözdeler bulunamadı. '+' düğmesine tıklayarak bir tane oluşturabilirsiniz" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "Bu Bilgisayarda" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "Proje bulunamadı. '+' düğmesine tıklayarak bir tane oluşturabilirsiniz" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Planify'daki yenilikler" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "Proje Ekle" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "" -"Hesap bulunamadı. '+' düğmesine tıklayarak bir tane eşzamanlama " -"oluşturabilirsiniz" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "Proje sırası, 'Özel Sıralama Düzeni' olarak değiştirildi" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "Gözdelerden Kaldır" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "Gözdelere Ekle" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "Projeyi Düzenle" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "Çoğalt" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "Projeyi Sil" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "Paylaş" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "E-posta İle Gönder" @@ -1310,120 +1315,122 @@ msgstr "E-posta İle Gönder" msgid "(No Section)" msgstr "(Bölüm Yok)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "Görev Ekle" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "Bölümü Düzenle" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "Bölümü Taşı" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "Bölüm Sıralamasını Yönet" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "Bölümü Sil" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 #, fuzzy msgid "Add Subtasks" msgstr "Alt Görev Ekle" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 #, fuzzy msgid "Add Attachments" msgstr "Görev Ekle" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "Tarih Yok" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "Taşı" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "Alt Görev Ekle" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "Düzenle" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "Görevi Sil" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "Tarih seçiniz" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "Panoya Kopyala" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "Yinele" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "Günlük" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "Haftalık" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "Aylık" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "Yıllık" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "Özel" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "Tamamlandı. Sonraki gerçekleşme: %s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s silindi" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "Geri Al" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "Sıralama 'Özel Sıralama Düzeni' olarak değiştirildi" @@ -1458,21 +1465,25 @@ msgstr "" msgid "Properties" msgstr "" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 #, fuzzy msgid "Are you sure you want to delete?" msgstr "%s ögesini silmek istediğinizden emin misiniz?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 #, fuzzy msgid "Open/Close Sidebar" msgstr "Kenar Çubuğunu Aç/Kapat" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "Proje bulunamadı. '+' düğmesine tıklayarak bir tane oluşturabilirsiniz" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "Çevrim Dışı Kip Açık" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1534,7 +1545,7 @@ msgid "Attach File" msgstr "Yedek Dosyaları" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "İndir" @@ -1556,6 +1567,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "Kaynak" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 #, fuzzy msgid "Project Actions" @@ -1604,13 +1629,13 @@ msgstr "Pano" msgid "Custom sort order" msgstr "Özel sıralama düzeni" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "Alfabetik" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 #, fuzzy msgid "Date Added" @@ -1647,27 +1672,27 @@ msgstr "" msgid "Duedate" msgstr "Güncelle" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "Etiketlere Göre Filtrele" @@ -1691,7 +1716,7 @@ msgstr "Tamamlanan Görevlerin Altını Çiz" msgid "Sort By" msgstr "Sırala" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 #, fuzzy msgid "Filter By" @@ -1726,49 +1751,53 @@ msgstr "Süresi doldu" msgid "Reschedule" msgstr "Yeniden zamanla" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "Sırala" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "Etiketler: Bu Bilgisayarda" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "Etiketler: Todoist" - -#: src/Views/Label/Labels.vala:49 +#: src/Views/Label/LabelSourceRow.vala:43 #, fuzzy -msgid "Labels: Nextcloud" -msgstr "Etiketler: Todoist" +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "" +"Gözdeler bulunamadı. '+' düğmesine tıklayarak bir tane oluşturabilirsiniz" + +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "Proje Ekle" #: src/Views/Filter.vala:535 #, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "Yeni Proje" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "Proje adı" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "Emoji kullan" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "Kaynak" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "Projeyi Güncelle" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "Kaynak" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "Proje eklendi." @@ -1817,8 +1846,8 @@ msgid "Please enter your credentials" msgstr "Lütfen kimlik bilgilerinizi girin" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "Ağ Kullanılamıyor" @@ -1878,7 +1907,7 @@ msgstr "" msgid "Archived" msgstr "" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "Aramak için yazınız" @@ -2028,7 +2057,7 @@ msgstr "" "unutmayın." #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "Bizi Destekleyin" @@ -2070,7 +2099,7 @@ msgid "Appearance" msgstr "Görünüm" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "Hızlı Ekle" @@ -2100,7 +2129,7 @@ msgid "Reach Us" msgstr "Bize Ulaşın" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "İletişime Geç" @@ -2138,7 +2167,7 @@ msgid "Privacy" msgstr "Gizlilik" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "Gizlilik İlkesi" @@ -2345,47 +2374,36 @@ msgid "Dark Blue Style" msgstr "Koyu Mavi Biçem" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "Hesaplar" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "Todoist Hesabınızla Eşzamanlayın" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "Görünümlerinizi sürükleyip bırakarak sıralayabilirsiniz" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "Eşzamanlama Sunucusu" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 #, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "" "Planner'ın 15 dakikada bir Todoist hesabınızla kendiliğinden eşzamanlanması " "için bu ayarı etkinleştirin" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "Son Eşzamanlama" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -#, fuzzy -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "" -"Planner'ın 15 dakikada bir Todoist hesabınızla kendiliğinden eşzamanlanması " -"için bu ayarı etkinleştirin" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2394,7 +2412,7 @@ msgstr "" "oluşturmak için Hızlı Ekle'yi kullanın. Bulunduğunuz uygulamadan çıkmanıza " "bile gerek yok!" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2402,73 +2420,71 @@ msgstr "" "Sistem Ayarları → Klavye → Kısayollar → Özel bölümüne gidin ve aşağıdakileri " "içeren yeni kısayol ekleyin:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "Ayarlar" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "Son Seçilen Projeyi Kaydet" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "İşaretlenmezse, öntanımlı proje Gelen Kutusu olarak seçilir" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "Komut panoya kopyalandı" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "Yükleniyor…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 #, fuzzy msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "Planlayıcı görevlerinizi eşzamanlıyor, bu birkaç dakika sürebilir" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "Eşzamanlanıyor…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "Lütfen Kimlik Bilgilerinizi Girin" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 msgid "Nextcloud Setup" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "Kişisel Veriler" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." @@ -2476,7 +2492,7 @@ msgstr "" "Kesinlikle hiçbir şey toplamıyoruz ve tüm verileriniz bilgisayarınızdaki bir " "veritabanında saklanıyor." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2486,11 +2502,11 @@ msgstr "" "değildir), verileriniz kendi özel sunucularında saklanır, biz sadece " "yapılandırılmış görevlerinizi görüntüler ve sizin için yönetiriz." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "Herhangi bir sorunuz var mı?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." @@ -2498,7 +2514,7 @@ msgstr "" "Verileriniz veya başka bir konu hakkında sorunuz varsa, bizimle iletişime " "geçin. Cevap vermekten mutluluk duyarız." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2508,43 +2524,22 @@ msgstr "" "uygulamasını sağlamaktır. Bağışlarınız bu çalışmayı destekler. Bağış yapmak " "ister misiniz?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "Patreon" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "PayPal" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "Liberapay" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "Ko-fi" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "" -"Todoist eşzamanlamasını kaldırmak istediğinden emin misin? Bu eylem, tüm " -"görevlerinizi ve ayarlarınızı silecek." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -#, fuzzy -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "" -"Todoist eşzamanlamasını kaldırmak istediğinden emin misin? Bu eylem, tüm " -"görevlerinizi ve ayarlarınızı silecek." - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "Oturumu Kapat" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2566,41 +2561,53 @@ msgstr "Yedeği İçe Aktar" msgid "Backup Files" msgstr "Yedek Dosyaları" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "" +"Hesap bulunamadı. '+' düğmesine tıklayarak bir tane eşzamanlama " +"oluşturabilirsiniz" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "Görevler Başarıyla Eşzamanlandı" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 #, fuzzy msgid "Tasks Migrate Successfully" msgstr "Görevler Başarıyla Eşzamanlandı" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "" -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "İçe Aktarmaya Genel Görünümü" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 #, fuzzy msgid "To-Dos" msgstr "Yapılacak Ekle" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "Onayla" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "Yedeği geri yükle" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." @@ -2608,15 +2615,15 @@ msgstr "" "Devam etmek istediğinizden emin misiniz? Bu işlem mevcut verilerinizi " "silecek ve yedek verilerle değiştirecek." -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "Yedeği Geri Yükle" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "Seçilen dosya geçersiz" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 #, fuzzy msgid "View Backup" msgstr "Yedek Oluştur" @@ -2737,6 +2744,48 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "Panoyu aç" +#~ msgid "On this Computer" +#~ msgstr "Bu Bilgisayarda" + +#~ msgid "Labels: On This Computer" +#~ msgstr "Etiketler: Bu Bilgisayarda" + +#~ msgid "Labels: Todoist" +#~ msgstr "Etiketler: Todoist" + +#, fuzzy +#~ msgid "Labels: Nextcloud" +#~ msgstr "Etiketler: Todoist" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "Todoist Hesabınızla Eşzamanlayın" + +#, fuzzy +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "" +#~ "Planner'ın 15 dakikada bir Todoist hesabınızla kendiliğinden " +#~ "eşzamanlanması için bu ayarı etkinleştirin" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Todoist eşzamanlamasını kaldırmak istediğinden emin misin? Bu eylem, tüm " +#~ "görevlerinizi ve ayarlarınızı silecek." + +#, fuzzy +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "" +#~ "Todoist eşzamanlamasını kaldırmak istediğinden emin misin? Bu eylem, tüm " +#~ "görevlerinizi ve ayarlarınızı silecek." + +#~ msgid "Sign Off" +#~ msgstr "Oturumu Kapat" + #, fuzzy #~ msgid "Add task" #~ msgstr "Görev Ekle" diff --git a/po/zh_CN.po b/po/zh_CN.po index 6e7d8ab6c..30600c144 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: io.github.alainm23.planify\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-10 04:40-0500\n" +"POT-Creation-Date: 2024-07-29 08:47-0500\n" "PO-Revision-Date: 2024-05-17 20:46+0800\n" "Last-Translator: Flysoft \n" "Language-Team: \n" @@ -21,7 +21,7 @@ msgstr "" #: core/Util/Datetime.vala:93 #: core/Widgets/DateTimePicker/DateTimePicker.vala:81 #: core/Objects/Filters/Today.vala:66 src/Layouts/FilterPaneRow.vala:113 -#: src/Layouts/ItemRow.vala:983 src/Layouts/ItemBoard.vala:625 +#: src/Layouts/ItemRow.vala:987 src/Layouts/ItemBoard.vala:631 #: src/Views/Project/Project.vala:463 src/Views/Project/Project.vala:630 #: src/Views/Today.vala:53 src/Views/Today.vala:166 #: src/Dialogs/DatePicker.vala:60 @@ -30,7 +30,7 @@ msgstr "" msgid "Today" msgstr "今日" -#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:574 +#: core/Enum.vala:134 core/Util/Util.vala:226 core/Util/Util.vala:583 #: core/Widgets/ProjectPicker/ProjectPickerRow.vala:77 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:100 #: src/Layouts/FilterPaneRow.vala:117 @@ -40,7 +40,7 @@ msgstr "今日" msgid "Inbox" msgstr "待办收件箱" -#: core/Enum.vala:137 core/Enum.vala:527 core/Objects/Filters/Scheduled.vala:50 +#: core/Enum.vala:137 core/Enum.vala:581 core/Objects/Filters/Scheduled.vala:50 #: src/Layouts/FilterPaneRow.vala:121 src/Views/Scheduled/Scheduled.vala:64 #: src/Dialogs/Preferences/PreferencesWindow.vala:349 #: src/Dialogs/Preferences/Pages/Sidebar.vala:38 @@ -54,133 +54,144 @@ msgstr "已计划" msgid "Pinboard" msgstr "置顶" -#: core/Enum.vala:207 src/Dialogs/Preferences/PreferencesWindow.vala:382 -#: src/Dialogs/Preferences/Pages/Backup.vala:171 +#: core/Enum.vala:222 src/Dialogs/Preferences/PreferencesWindow.vala:382 +#: src/Dialogs/Preferences/Pages/Backup.vala:168 msgid "Projects" msgstr "项目" -#: core/Enum.vala:210 src/Dialogs/Preferences/Pages/Backup.vala:175 +#: core/Enum.vala:225 src/Dialogs/Preferences/Pages/Backup.vala:172 msgid "Sections" msgstr "分区" -#: core/Enum.vala:213 core/Enum.vala:222 +#: core/Enum.vala:228 core/Enum.vala:237 msgid "Tasks" msgstr "任务" -#: core/Enum.vala:216 core/Enum.vala:533 +#: core/Enum.vala:231 core/Enum.vala:587 #: core/Widgets/LabelPicker/LabelButton.vala:69 #: core/Objects/Filters/Labels.vala:50 src/Layouts/FilterPaneRow.vala:129 -#: src/Views/Label/Labels.vala:37 src/Dialogs/LabelPicker.vala:35 +#: src/Views/Label/Labels.vala:30 src/Dialogs/LabelPicker.vala:35 #: src/Dialogs/Preferences/PreferencesWindow.vala:350 -#: src/Dialogs/Preferences/Pages/Backup.vala:183 +#: src/Dialogs/Preferences/Pages/Backup.vala:180 #: src/Dialogs/Preferences/Pages/Sidebar.vala:40 msgid "Labels" msgstr "标签" -#: core/Enum.vala:219 +#: core/Enum.vala:234 msgid "Filters" msgstr "过滤器" -#: core/Enum.vala:225 +#: core/Enum.vala:240 msgid "Lists" msgstr "列表" -#: core/Enum.vala:251 +#: core/Enum.vala:266 msgid "Don't Repeat" msgstr "不重复" -#: core/Enum.vala:254 core/Enum.vala:256 +#: core/Enum.vala:269 core/Enum.vala:271 msgid "Every minute" msgstr "每分钟" -#: core/Enum.vala:256 +#: core/Enum.vala:271 #, c-format msgid "Every %d minutes" msgstr "每 %d 分钟" -#: core/Enum.vala:260 core/Enum.vala:262 +#: core/Enum.vala:275 core/Enum.vala:277 msgid "Every hour" msgstr "每小时" -#: core/Enum.vala:262 +#: core/Enum.vala:277 #, c-format msgid "Every %d hours" msgstr "每 %d 年" -#: core/Enum.vala:266 core/Enum.vala:268 +#: core/Enum.vala:281 core/Enum.vala:283 msgid "Every day" msgstr "每天" -#: core/Enum.vala:268 +#: core/Enum.vala:283 #, c-format msgid "Every %d days" msgstr "每 %d 天" -#: core/Enum.vala:272 core/Enum.vala:274 +#: core/Enum.vala:287 core/Enum.vala:289 msgid "Every week" msgstr "每周" -#: core/Enum.vala:274 +#: core/Enum.vala:289 #, c-format msgid "Every %d weeks" msgstr "每 %d 周" -#: core/Enum.vala:279 core/Enum.vala:281 +#: core/Enum.vala:294 core/Enum.vala:296 msgid "Every month" msgstr "每月" -#: core/Enum.vala:281 +#: core/Enum.vala:296 #, c-format msgid "Every %d months" msgstr "每 %d 月" -#: core/Enum.vala:286 core/Enum.vala:288 +#: core/Enum.vala:301 core/Enum.vala:303 msgid "Every year" msgstr "每年" -#: core/Enum.vala:288 +#: core/Enum.vala:303 #, c-format msgid "Every %d years" msgstr "每 %d 年" -#: core/Enum.vala:362 core/Enum.vala:530 core/Widgets/PriorityButton.vala:73 +#: core/Enum.vala:355 core/Services/Database.vala:2019 +#: core/Services/CalDAV/Providers/Nextcloud.vala:311 +#: src/Dialogs/Preferences/PreferencesWindow.vala:829 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1309 +msgid "Nextcloud" +msgstr "Nextcloud" + +#: core/Enum.vala:358 +msgid "Radicale" +msgstr "" + +#: core/Enum.vala:416 core/Enum.vala:584 core/Widgets/PriorityButton.vala:73 #: src/Views/Project/Project.vala:455 src/Views/Project/Project.vala:499 -#: src/Views/Today.vala:554 src/Views/Today.vala:586 +#: src/Views/Today.vala:599 src/Views/Today.vala:631 #: src/Views/Scheduled/Scheduled.vala:190 #: src/Views/Scheduled/Scheduled.vala:222 msgid "Priority" msgstr "优先级" -#: core/Enum.vala:365 +#: core/Enum.vala:419 msgid "Label" msgstr "标签" -#: core/Enum.vala:368 src/Views/Project/Project.vala:453 -#: src/Views/Today.vala:551 src/Views/Scheduled/Scheduled.vala:187 +#: core/Enum.vala:422 src/Views/Project/Project.vala:453 +#: src/Views/Today.vala:596 src/Views/Scheduled/Scheduled.vala:187 msgid "Due Date" msgstr "截止日期" -#: core/Enum.vala:474 +#: core/Enum.vala:528 #, fuzzy msgid "Task Created" msgstr "任务已复制" -#: core/Enum.vala:477 +#: core/Enum.vala:531 #, fuzzy msgid "Task Updated" msgstr "任务已复制" -#: core/Enum.vala:521 +#: core/Enum.vala:575 msgid "Content" msgstr "" -#: core/Enum.vala:524 src/Layouts/ItemSidebarView.vala:181 +#: core/Enum.vala:578 src/Layouts/ItemSidebarView.vala:181 #: src/Dialogs/Section.vala:85 msgid "Description" msgstr "描述" -#: core/Enum.vala:536 src/Layouts/ItemRow.vala:989 -#: src/Layouts/ItemBoard.vala:631 +#: core/Enum.vala:590 src/Layouts/ItemRow.vala:993 +#: src/Layouts/ItemBoard.vala:637 msgid "Pin" msgstr "置顶" @@ -303,8 +314,8 @@ msgstr "深色" msgid "Dark Blue" msgstr "深蓝色" -#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1223 -#: src/Layouts/ItemSidebarView.vala:569 +#: core/Util/Util.vala:223 src/Layouts/ItemRow.vala:1231 +#: src/Layouts/ItemSidebarView.vala:568 #: src/Dialogs/Preferences/PreferencesWindow.vala:546 msgid "None" msgstr "无" @@ -313,17 +324,16 @@ msgstr "无" msgid "Today + Inbox" msgstr "今日任务 + 待办收件夹" -#: core/Util/Util.vala:381 core/Objects/Project.vala:795 -#: core/Objects/Project.vala:837 core/Objects/Section.vala:340 -#: core/Objects/Section.vala:366 src/Objects/Backup.vala:130 -#: src/Layouts/LabelRow.vala:177 src/Layouts/ItemSidebarView.vala:679 -#: src/Layouts/SectionBoard.vala:565 src/Widgets/MultiSelectToolbar.vala:259 -#: src/Views/Project/Project.vala:601 src/Views/Filter.vala:539 -#: src/Dialogs/QuickFind/QuickFind.vala:44 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1458 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1862 -#: src/Dialogs/Preferences/Pages/Backup.vala:195 -#: src/Dialogs/Preferences/Pages/Backup.vala:254 +#: core/Util/Util.vala:381 core/Objects/Project.vala:812 +#: core/Objects/Project.vala:862 core/Objects/Section.vala:329 +#: core/Objects/Section.vala:355 core/Objects/Source.vala:165 +#: src/Services/Backups.vala:415 src/Layouts/LabelRow.vala:177 +#: src/Layouts/ItemSidebarView.vala:678 src/Layouts/SectionBoard.vala:565 +#: src/Widgets/MultiSelectToolbar.vala:259 src/Views/Project/Project.vala:601 +#: src/Views/Filter.vala:539 src/Dialogs/QuickFind/QuickFind.vala:44 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1356 +#: src/Dialogs/Preferences/Pages/Backup.vala:193 +#: src/Dialogs/Preferences/Pages/Backup.vala:251 msgid "Cancel" msgstr "取消" @@ -335,9 +345,8 @@ msgstr "删除所有" msgid "Process completed, you need to start Planify again." msgstr "操作完成,你需要再次启动 Planify。" -#: core/Util/Util.vala:398 src/Services/Backups.vala:509 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1369 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1607 +#: core/Util/Util.vala:398 src/Services/Backups.vala:565 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1271 msgid "Ok" msgstr "好" @@ -373,11 +382,15 @@ msgstr "低" msgid "none" msgstr "无" -#: core/Util/Util.vala:591 +#: core/Util/Util.vala:574 +msgid "On This Computer" +msgstr "此电脑上" + +#: core/Util/Util.vala:599 msgid "Meet Planify" msgstr "认识 Planify" -#: core/Util/Util.vala:594 +#: core/Util/Util.vala:602 msgid "" "This project shows you everything you need to know to hit the ground " "running. Don’t hesitate to play around in it – you can always create a new " @@ -386,11 +399,11 @@ msgstr "" "该项目将为您提供一切入门所需的信息。请随意在其中进行操作,如果需要,您随时可" "以从设置中创建一个新的项目。" -#: core/Util/Util.vala:600 +#: core/Util/Util.vala:609 msgid "Tap this to-do" msgstr "点击此待办事项" -#: core/Util/Util.vala:601 +#: core/Util/Util.vala:610 msgid "" "You're looking at a to-do! Complete it by tapping the checkbox on the left. " "Completed to-dos are collected at the bottom of your project." @@ -398,11 +411,11 @@ msgstr "" "你正在看一个待办事项!点击左边的复选框来完成它。完成的待办事项会被收集在你的" "项目底部。" -#: core/Util/Util.vala:606 +#: core/Util/Util.vala:615 msgid "Create a new to-do" msgstr "创建一个新的待办事项" -#: core/Util/Util.vala:607 +#: core/Util/Util.vala:616 msgid "" "Now it's your turn, tap the '+' button at the bottom of your project, enter " "any pending and tap the blue 'Save' button." @@ -410,29 +423,29 @@ msgstr "" "现在轮到你了,点击你的项目顶部的 ‘+’ 键,输入任何待定,然后点击蓝色的 ‘保存’ " "按钮。" -#: core/Util/Util.vala:612 +#: core/Util/Util.vala:621 msgid "Plan this to-do by today or later" msgstr "将待办事项计划到今天或之后" -#: core/Util/Util.vala:613 +#: core/Util/Util.vala:622 msgid "Tap the calendar button at the bottom to decide when to do this to-do." msgstr "点一下底部的日历按钮,决定何时完成这项待办事项。" -#: core/Util/Util.vala:618 +#: core/Util/Util.vala:627 msgid "Reorder yours to-dos" msgstr "重新排列你的待办事项" -#: core/Util/Util.vala:619 +#: core/Util/Util.vala:628 msgid "" "To reorder your list, tap and hold a to-do, then drag it to where it should " "go." msgstr "要重新排列你的清单,点住一个待办事项,然后把它拖到它应该去的地方。" -#: core/Util/Util.vala:624 +#: core/Util/Util.vala:633 msgid "Create a project" msgstr "创建一个项目" -#: core/Util/Util.vala:625 +#: core/Util/Util.vala:634 msgid "" "Organize your to-dos better! Go to the left panel and click the '+' button " "in the 'On This Computer' section and add a project of your own." @@ -440,11 +453,11 @@ msgstr "" "更好地组织你的待办事项!进入左侧面板,点击 ‘此电脑上’ 部分的 ‘+’ 按钮,添加一" "个你自己的项目。" -#: core/Util/Util.vala:630 +#: core/Util/Util.vala:639 msgid "You’re done!" msgstr "你完成了!" -#: core/Util/Util.vala:631 +#: core/Util/Util.vala:640 #, fuzzy msgid "" "That’s all you really need to know. Feel free to start adding your own " @@ -459,15 +472,15 @@ msgstr "" "\n" "我们希望您会喜欢使用 Planify!" -#: core/Util/Util.vala:645 +#: core/Util/Util.vala:654 msgid "Tune your setup" msgstr "调整你的设置" -#: core/Util/Util.vala:653 +#: core/Util/Util.vala:662 msgid "Show your calendar events" msgstr "显示你的日历事件" -#: core/Util/Util.vala:654 +#: core/Util/Util.vala:663 #, fuzzy msgid "" "You can display your system's calendar events in Planify. Go to " @@ -476,11 +489,11 @@ msgstr "" "您可以在 Planify 中显示您系统的日历事件。进入 ‘偏好设置’ 🡒 ‘日历事件’ 来打" "开。" -#: core/Util/Util.vala:660 +#: core/Util/Util.vala:669 msgid "Enable synchronization with third-party service." msgstr "启用与第三方服务的同步。" -#: core/Util/Util.vala:661 +#: core/Util/Util.vala:670 msgid "" "Planify not only creates tasks locally, it can also synchronize your Todoist " "account. Go to 'Preferences' 🡒 'Accounts'." @@ -488,15 +501,15 @@ msgstr "" "Planify 不仅可以在本地创建任务,它还可以同步你的 Todoist 账户。进入 ‘偏好设" "置’ 🡒 ‘账户’ 。" -#: core/Util/Util.vala:669 +#: core/Util/Util.vala:678 msgid "Boost your productivity" msgstr "提高你的生产力" -#: core/Util/Util.vala:677 +#: core/Util/Util.vala:686 msgid "Drag the plus button!" msgstr "拖拽➕加号按钮!" -#: core/Util/Util.vala:678 +#: core/Util/Util.vala:687 msgid "" "That blue button you see at the bottom of each screen is more powerful than " "it looks: it's made to move! Drag it up to create a task wherever you want." @@ -504,21 +517,21 @@ msgstr "" "你在每个屏幕底部看到的蓝色按钮比看上去更强大:它可以移动!拖动它,就能在任何" "地方创建任务。" -#: core/Util/Util.vala:684 +#: core/Util/Util.vala:693 msgid "Tag your to-dos!" msgstr "为你的待办事项打上标签!" -#: core/Util/Util.vala:685 +#: core/Util/Util.vala:694 msgid "" "Tags allow you to improve your workflow in Planify. To add a Tag click on " "the tag button at the bottom." msgstr "标签可让您改进 Planify 的工作流程。要添加标签,请单击底部的标签按钮。" -#: core/Util/Util.vala:691 +#: core/Util/Util.vala:700 msgid "Set timely reminders!" msgstr "设置及时的提醒!" -#: core/Util/Util.vala:692 +#: core/Util/Util.vala:701 msgid "" "You want Planify to send you a notification to remind you of an important " "event or something special. Tap the bell button below to add a reminder." @@ -526,75 +539,75 @@ msgstr "" "您希望 Planify 向您发送通知,提醒您有重要事件或特别事情。轻按下面的🔔铃铛按钮" "添加提醒。" -#: core/Util/Util.vala:704 +#: core/Util/Util.vala:712 msgid "💼️Work" msgstr "💼️工作" -#: core/Util/Util.vala:710 +#: core/Util/Util.vala:718 msgid "🎒️School" msgstr "🎒️学校" -#: core/Util/Util.vala:716 +#: core/Util/Util.vala:724 msgid "👉️Delegated" msgstr "👉️委托" -#: core/Util/Util.vala:722 +#: core/Util/Util.vala:730 msgid "🏡️Home" msgstr "🏡️家" -#: core/Util/Util.vala:728 +#: core/Util/Util.vala:736 msgid "🏃‍♀️️Follow Up" msgstr "🏃‍♀️️跟进" -#: core/Util/Util.vala:897 core/Objects/Item.vala:1545 +#: core/Util/Util.vala:891 core/Objects/Item.vala:1548 #, c-format msgid "Task moved to %s" msgstr "任务移动至 %s" -#: core/Util/Util.vala:975 +#: core/Util/Util.vala:969 msgid "Task duplicated" msgstr "任务已复制" -#: core/Util/Util.vala:1011 +#: core/Util/Util.vala:1005 msgid "Section duplicated" msgstr "分区已复制" -#: core/Util/Util.vala:1038 core/Util/Util.vala:1064 +#: core/Util/Util.vala:1031 core/Util/Util.vala:1056 msgid "Project duplicated" msgstr "项目已复制" -#: core/Util/Util.vala:1213 src/Dialogs/Preferences/PreferencesWindow.vala:613 +#: core/Util/Util.vala:1205 src/Dialogs/Preferences/PreferencesWindow.vala:613 msgid "At due time" msgstr "" -#: core/Util/Util.vala:1216 src/Dialogs/Preferences/PreferencesWindow.vala:614 +#: core/Util/Util.vala:1208 src/Dialogs/Preferences/PreferencesWindow.vala:614 msgid "10 minutes before" msgstr "" -#: core/Util/Util.vala:1219 src/Dialogs/Preferences/PreferencesWindow.vala:615 +#: core/Util/Util.vala:1211 src/Dialogs/Preferences/PreferencesWindow.vala:615 msgid "30 minutes before" msgstr "" -#: core/Util/Util.vala:1222 src/Dialogs/Preferences/PreferencesWindow.vala:616 +#: core/Util/Util.vala:1214 src/Dialogs/Preferences/PreferencesWindow.vala:616 msgid "45 minutes before" msgstr "" -#: core/Util/Util.vala:1225 src/Dialogs/Preferences/PreferencesWindow.vala:617 +#: core/Util/Util.vala:1217 src/Dialogs/Preferences/PreferencesWindow.vala:617 msgid "1 hour before" msgstr "" -#: core/Util/Util.vala:1228 src/Dialogs/Preferences/PreferencesWindow.vala:618 +#: core/Util/Util.vala:1220 src/Dialogs/Preferences/PreferencesWindow.vala:618 msgid "2 hours before" msgstr "" -#: core/Util/Util.vala:1231 src/Dialogs/Preferences/PreferencesWindow.vala:619 +#: core/Util/Util.vala:1223 src/Dialogs/Preferences/PreferencesWindow.vala:619 msgid "3 hours before" msgstr "" #: core/Util/Datetime.vala:70 #: core/Widgets/DateTimePicker/DateTimePicker.vala:82 -#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:986 -#: src/Layouts/ItemBoard.vala:628 src/Views/Filter.vala:200 +#: core/Objects/Filters/Tomorrow.vala:33 src/Layouts/ItemRow.vala:990 +#: src/Layouts/ItemBoard.vala:634 src/Views/Filter.vala:200 #: src/Dialogs/DatePicker.vala:64 msgid "Tomorrow" msgstr "明天" @@ -649,39 +662,44 @@ msgstr "周六," msgid "Su," msgstr "周日," -#: core/Services/Todoist.vala:1544 +#: core/Services/Todoist.vala:1518 src/Widgets/ErrorView.vala:134 msgid "The request was incorrect." msgstr "请求错误。" -#: core/Services/Todoist.vala:1545 +#: core/Services/Todoist.vala:1519 src/Widgets/ErrorView.vala:135 msgid "" "Authentication is required, and has failed, or has not yet been provided." msgstr "须要身份验证,但已失败或尚未提供。" -#: core/Services/Todoist.vala:1546 +#: core/Services/Todoist.vala:1520 src/Widgets/ErrorView.vala:136 msgid "The request was valid, but for something that is forbidden." msgstr "请求有效,但无权限访问。" -#: core/Services/Todoist.vala:1547 +#: core/Services/Todoist.vala:1521 src/Widgets/ErrorView.vala:137 msgid "The requested resource could not be found." msgstr "找不到请求的资源。" -#: core/Services/Todoist.vala:1548 +#: core/Services/Todoist.vala:1522 src/Widgets/ErrorView.vala:138 msgid "The user has sent too many requests in a given amount of time." msgstr "用户在同一时间发送了太多请求。" -#: core/Services/Todoist.vala:1549 +#: core/Services/Todoist.vala:1523 src/Widgets/ErrorView.vala:139 msgid "The request failed due to a server error." msgstr "由于服务器错误,请求失败。" -#: core/Services/Todoist.vala:1550 +#: core/Services/Todoist.vala:1524 src/Widgets/ErrorView.vala:140 msgid "The server is currently unable to handle the request." msgstr "服务器当前无法处理请求。" -#: core/Services/Todoist.vala:1552 +#: core/Services/Todoist.vala:1526 src/Widgets/ErrorView.vala:142 msgid "Unknown error" msgstr "未知错误" +#: core/Services/CalDAV/Core.vala:53 core/Services/CalDAV/Core.vala:117 +#, fuzzy +msgid "No Provider Available" +msgstr "不可用" + #: core/Widgets/PinButton.vala:31 src/Layouts/ItemBoard.vala:209 msgid "Pinned" msgstr "已置顶" @@ -726,26 +744,36 @@ msgid "To Do" msgstr "待办" #: core/Widgets/StatusButton.vala:85 core/Widgets/StatusButton.vala:119 -#: src/Layouts/ItemRow.vala:997 src/Layouts/ItemBoard.vala:638 +#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemBoard.vala:644 msgid "Complete" msgstr "完成" -#: core/Widgets/LabelsPickerCore.vala:61 +#: core/Widgets/LabelsPickerCore.vala:63 msgid "" "Your list of filters will show up here. Create one by entering the name and " "pressing the Enter key." msgstr "你的过滤器列表将显示在这里,输入名称并按下回车键创建。" #. vala-lint=naming-convention -#: core/Widgets/LabelsPickerCore.vala:62 +#: core/Widgets/LabelsPickerCore.vala:64 #, fuzzy, c-format msgid "Create '%s'" msgstr "创建一个项目" -#: core/Widgets/LabelsPickerCore.vala:70 +#: core/Widgets/LabelsPickerCore.vala:78 +#, fuzzy +msgid "Your list of filters will show up here." +msgstr "你的过滤器列表将显示在这里,点击 ‘+’ 按钮创建" + +#: core/Widgets/LabelsPickerCore.vala:82 msgid "Search or Create" msgstr "搜索或创建" +#: core/Widgets/LabelsPickerCore.vala:82 +#: core/Widgets/SectionPicker/SectionPicker.vala:40 +msgid "Search" +msgstr "搜索" + #: core/Widgets/Calendar/CalendarHeader.vala:35 #: core/Widgets/Calendar/CalendarHeader.vala:49 msgid "%OB" @@ -840,8 +868,8 @@ msgstr "清除" #: core/Widgets/DateTimePicker/DateTimePicker.vala:145 #: core/Widgets/ReminderPicker/ReminderPicker.vala:119 -#: src/Layouts/ItemRow.vala:1113 src/Layouts/ItemSidebarView.vala:452 -#: src/Layouts/HeaderBar.vala:68 src/Dialogs/Preferences/SettingsHeader.vala:47 +#: src/Layouts/ItemRow.vala:1116 src/Layouts/ItemSidebarView.vala:452 +#: src/Layouts/HeaderBar.vala:81 src/Dialogs/Preferences/SettingsHeader.vala:47 msgid "Back" msgstr "返回" @@ -855,36 +883,13 @@ msgstr "添加标签" msgid "Select Labels" msgstr "删除标签" -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:26 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:168 -msgid "On this Computer" -msgstr "此电脑上" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:32 -#: src/Layouts/Sidebar.vala:108 src/Dialogs/Project.vala:127 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:172 -#: src/Dialogs/Preferences/PreferencesWindow.vala:849 -#: src/Dialogs/Preferences/PreferencesWindow.vala:983 -#: src/Dialogs/Preferences/Pages/Backup.vala:162 -msgid "Todoist" -msgstr "Todoist" - -#: core/Widgets/ProjectPicker/ProjectPickerPopover.vala:38 -#: src/Layouts/Sidebar.vala:111 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:176 -#: src/Dialogs/Preferences/PreferencesWindow.vala:877 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1072 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1411 -msgid "Nextcloud" -msgstr "Nextcloud" - #. Section Button #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:59 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:131 #: core/Widgets/ProjectPicker/ProjectPickerButton.vala:142 #: core/Widgets/SectionPicker/SectionButton.vala:85 #: core/Widgets/SectionPicker/SectionPicker.vala:98 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:276 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:247 msgid "No Section" msgstr "无分区" @@ -900,10 +905,6 @@ msgstr "分区" msgid "Select Section" msgstr "选择分区" -#: core/Widgets/SectionPicker/SectionPicker.vala:40 -msgid "Search" -msgstr "搜索" - #: core/Widgets/ReminderPicker/ReminderButton.vala:38 #: core/Widgets/ReminderPicker/ReminderButton.vala:46 #: core/Widgets/ReminderPicker/ReminderButton.vala:59 @@ -933,56 +934,71 @@ msgstr "添加备忘录" msgid "Couldn't find an app to handle file URIs" msgstr "" -#: core/Objects/Item.vala:1325 +#: core/Objects/Item.vala:1321 msgid "Task copied to clipboard" msgstr "任务已复制到剪切板" -#: core/Objects/Project.vala:755 +#: core/Objects/Project.vala:772 msgid "The project was copied to the Clipboard." msgstr "此项目已复制到剪切板。" -#: core/Objects/Project.vala:791 +#: core/Objects/Project.vala:808 #, c-format msgid "Delete Project %s?" msgstr "删除项目 %s 吗?" -#: core/Objects/Project.vala:792 core/Objects/Section.vala:337 -#: src/Objects/Backup.vala:127 src/Layouts/LabelRow.vala:174 -#: src/Layouts/ItemSidebarView.vala:676 src/Layouts/SectionBoard.vala:562 +#: core/Objects/Project.vala:809 core/Objects/Section.vala:326 +#: core/Objects/Source.vala:162 src/Services/Backups.vala:412 +#: src/Layouts/LabelRow.vala:174 src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/SectionBoard.vala:562 msgid "This can not be undone" msgstr "此操作不能被撤销" -#: core/Objects/Project.vala:796 core/Objects/Section.vala:341 -#: src/Objects/Backup.vala:131 src/Layouts/LabelRow.vala:178 -#: src/Layouts/ItemSidebarView.vala:680 src/Layouts/SectionBoard.vala:566 -#: src/Widgets/MultiSelectToolbar.vala:220 +#: core/Objects/Project.vala:813 core/Objects/Section.vala:330 +#: core/Objects/Source.vala:166 src/Services/Backups.vala:416 +#: src/Layouts/LabelRow.vala:178 src/Layouts/ItemSidebarView.vala:679 +#: src/Layouts/SectionBoard.vala:566 src/Widgets/MultiSelectToolbar.vala:220 #: src/Widgets/MultiSelectToolbar.vala:260 src/Views/Project/Project.vala:602 -#: src/Views/Filter.vala:540 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1863 -#: src/Dialogs/Preferences/Pages/Backup.vala:385 +#: src/Views/Filter.vala:540 src/Dialogs/Preferences/Pages/Backup.vala:376 msgid "Delete" msgstr "删除" -#: core/Objects/Project.vala:833 core/Objects/Section.vala:362 +#: core/Objects/Project.vala:858 core/Objects/Section.vala:351 msgid "Archive?" msgstr "存档吗?" -#: core/Objects/Project.vala:834 core/Objects/Section.vala:363 +#: core/Objects/Project.vala:859 core/Objects/Section.vala:352 #, c-format msgid "This will archive %s and all its tasks." msgstr "这将会存档 %s 和它的所有待办项目。" -#: core/Objects/Project.vala:838 core/Objects/Section.vala:367 -#: src/Layouts/ProjectRow.vala:638 src/Layouts/SectionRow.vala:669 +#: core/Objects/Project.vala:863 core/Objects/Section.vala:356 +#: src/Layouts/ProjectRow.vala:655 src/Layouts/SectionRow.vala:670 #: src/Views/Project/Project.vala:281 msgid "Archive" msgstr "存档" -#: core/Objects/Section.vala:336 src/Layouts/SectionBoard.vala:561 +#: core/Objects/Section.vala:325 src/Layouts/SectionBoard.vala:561 #, c-format msgid "Delete Section %s" msgstr "删除分区 %s" +#: core/Objects/Source.vala:59 +#: src/Dialogs/Preferences/PreferencesWindow.vala:828 +#: src/Dialogs/Preferences/PreferencesWindow.vala:931 +msgid "Todoist" +msgstr "Todoist" + +#: core/Objects/Source.vala:63 +#, fuzzy +msgid "CalDAV - " +msgstr "CalDAV 设置" + +#: core/Objects/Source.vala:161 +#, fuzzy +msgid "Delete Source?" +msgstr "删除分区" + #: core/Objects/Filters/Pinboard.vala:51 core/Objects/Filters/Scheduled.vala:51 #: core/Objects/Filters/Today.vala:67 core/Objects/Filters/Priority.vala:59 #: core/Objects/Filters/Completed.vala:51 core/Objects/Filters/Labels.vala:51 @@ -1095,48 +1111,57 @@ msgid "" msgstr "" "Planify 将在设备开机时自动启动并在窗口关闭时保持运行,以便发送待办事项通知。" -#: src/MainWindow.vala:78 +#: src/MainWindow.vala:79 msgid "Main Menu" msgstr "" -#: src/MainWindow.vala:83 +#: src/MainWindow.vala:84 msgid "Open Quick Find" msgstr "打开快速查找" -#: src/MainWindow.vala:494 src/Dialogs/Preferences/PreferencesWindow.vala:49 +#: src/MainWindow.vala:504 src/Dialogs/Preferences/PreferencesWindow.vala:49 msgid "Preferences" msgstr "偏好设置" -#: src/MainWindow.vala:497 +#: src/MainWindow.vala:507 msgid "Keyboard Shortcuts" msgstr "快捷键" -#: src/MainWindow.vala:500 src/Dialogs/WhatsNew.vala:146 +#: src/MainWindow.vala:510 src/Dialogs/WhatsNew.vala:146 msgid "What's New" msgstr "新增内容" -#: src/MainWindow.vala:503 +#: src/MainWindow.vala:513 msgid "About Planify" msgstr "关于 Planify" -#: src/MainWindow.vala:505 src/Dialogs/ManageProjects.vala:28 +#: src/MainWindow.vala:515 src/Dialogs/ManageProjects.vala:28 msgid "Archived Projects" msgstr "已存档项目" -#: src/Objects/Backup.vala:126 +#: src/MainWindow.vala:581 +msgid "Oops! Something happened" +msgstr "" + +#: src/MainWindow.vala:584 +#, fuzzy +msgid "See More" +msgstr "创建一个项目" + +#: src/Services/Backups.vala:411 #, fuzzy msgid "Delete Backup" msgstr "创建备份" -#: src/Services/Backups.vala:505 +#: src/Services/Backups.vala:561 msgid "Backup Successfully Imported" msgstr "备份成功导入" -#: src/Services/Backups.vala:506 +#: src/Services/Backups.vala:562 msgid "Process completed, you need to start Planify again" msgstr "操作完成,你需要重启 Planify" -#: src/Services/Backups.vala:520 +#: src/Services/Backups.vala:576 msgid "Planify Backup Files" msgstr "Planify 备份文件" @@ -1144,95 +1169,76 @@ msgstr "Planify 备份文件" msgid "On this computer" msgstr "此电脑上" -#: src/Layouts/Sidebar.vala:70 +#: src/Layouts/Sidebar.vala:53 msgid "Go to Inbox" msgstr "待办收件夹" -#: src/Layouts/Sidebar.vala:74 +#: src/Layouts/Sidebar.vala:57 msgid "Go to Today" msgstr "今日" -#: src/Layouts/Sidebar.vala:78 +#: src/Layouts/Sidebar.vala:61 msgid "Go to Scheduled" msgstr "已计划" -#: src/Layouts/Sidebar.vala:82 +#: src/Layouts/Sidebar.vala:65 msgid "Go to Labels" msgstr "标签" -#: src/Layouts/Sidebar.vala:86 +#: src/Layouts/Sidebar.vala:69 msgid "Go to Pinboard" msgstr "置顶" -#: src/Layouts/Sidebar.vala:100 +#: src/Layouts/Sidebar.vala:83 msgid "Favorites" msgstr "收藏" -#: src/Layouts/Sidebar.vala:101 +#: src/Layouts/Sidebar.vala:86 msgid "No favorites available. Create one by clicking on the '+' button" msgstr "尚无可用收藏,点击➕加号按钮创建" -#: src/Layouts/Sidebar.vala:104 src/Dialogs/Project.vala:126 -msgid "On This Computer" -msgstr "此电脑上" - -#: src/Layouts/Sidebar.vala:105 src/Layouts/Sidebar.vala:348 -#: src/Layouts/Sidebar.vala:359 src/Layouts/Sidebar.vala:370 -msgid "No project available. Create one by clicking on the '+' button" -msgstr "尚无可用项目,点击➕加号按钮创建" - -#: src/Layouts/Sidebar.vala:121 src/Dialogs/WhatsNew.vala:43 +#: src/Layouts/Sidebar.vala:104 src/Dialogs/WhatsNew.vala:43 msgid "What’s new in Planify" msgstr "Planify 内的新增内容" -#: src/Layouts/Sidebar.vala:177 src/Layouts/Sidebar.vala:193 -#: src/Layouts/Sidebar.vala:213 src/Dialogs/Project.vala:168 -msgid "Add Project" -msgstr "添加项目" - -#: src/Layouts/Sidebar.vala:350 src/Layouts/Sidebar.vala:361 -#: src/Layouts/Sidebar.vala:372 -msgid "No account available, Sync one by clicking the '+' button" -msgstr "尚无可用账户,点击 ‘+’ 按钮以同步" - -#: src/Layouts/ProjectRow.vala:379 +#: src/Layouts/ProjectRow.vala:388 msgid "Projects sort changed to 'Custom sort order'" msgstr "项目列表顺序改变至自定义顺序。" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Remove From Favorites" msgstr "取消收藏" -#: src/Layouts/ProjectRow.vala:627 src/Layouts/ProjectRow.vala:633 +#: src/Layouts/ProjectRow.vala:644 src/Layouts/ProjectRow.vala:650 msgid "Add to Favorites" msgstr "收藏" -#: src/Layouts/ProjectRow.vala:634 src/Views/Project/Project.vala:266 -#: src/Dialogs/Project.vala:57 +#: src/Layouts/ProjectRow.vala:651 src/Views/Project/Project.vala:266 +#: src/Dialogs/Project.vala:64 msgid "Edit Project" msgstr "编辑项目" -#: src/Layouts/ProjectRow.vala:635 src/Layouts/SectionRow.vala:667 -#: src/Layouts/ItemRow.vala:999 src/Layouts/ItemRow.vala:1119 -#: src/Layouts/ItemBoard.vala:640 src/Layouts/ItemSidebarView.vala:458 +#: src/Layouts/ProjectRow.vala:652 src/Layouts/SectionRow.vala:668 +#: src/Layouts/ItemRow.vala:1003 src/Layouts/ItemRow.vala:1122 +#: src/Layouts/ItemBoard.vala:646 src/Layouts/ItemSidebarView.vala:458 #: src/Layouts/SectionBoard.vala:496 src/Views/Project/Project.vala:267 msgid "Duplicate" msgstr "创建副本" -#: src/Layouts/ProjectRow.vala:636 +#: src/Layouts/ProjectRow.vala:653 msgid "Refresh" msgstr "刷新" -#: src/Layouts/ProjectRow.vala:639 src/Views/Project/Project.vala:282 +#: src/Layouts/ProjectRow.vala:656 src/Views/Project/Project.vala:282 #: src/Dialogs/ProjectPicker/ProjectPickerRow.vala:140 msgid "Delete Project" msgstr "删除项目" -#: src/Layouts/ProjectRow.vala:642 +#: src/Layouts/ProjectRow.vala:659 msgid "Share" msgstr "分享" -#: src/Layouts/ProjectRow.vala:643 +#: src/Layouts/ProjectRow.vala:660 msgid "Send by E-Mail" msgstr "通过电子邮件发送" @@ -1241,118 +1247,120 @@ msgstr "通过电子邮件发送" msgid "(No Section)" msgstr "(无分区)" -#: src/Layouts/SectionRow.vala:663 src/Layouts/SectionBoard.vala:492 +#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:492 #: src/Widgets/MagicButton.vala:46 msgid "Add Task" msgstr "添加任务" -#: src/Layouts/SectionRow.vala:664 src/Layouts/SectionBoard.vala:493 +#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:493 #: src/Dialogs/Section.vala:51 msgid "Edit Section" msgstr "编辑分区" -#: src/Layouts/SectionRow.vala:665 src/Layouts/SectionBoard.vala:494 +#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:494 msgid "Move Section" msgstr "移动分区" -#: src/Layouts/SectionRow.vala:666 src/Layouts/SectionBoard.vala:495 +#: src/Layouts/SectionRow.vala:667 src/Layouts/SectionBoard.vala:495 msgid "Manage Section Order" msgstr "管理分区顺序" -#: src/Layouts/SectionRow.vala:670 src/Layouts/SectionBoard.vala:497 +#: src/Layouts/SectionRow.vala:671 src/Layouts/SectionBoard.vala:497 #: src/Dialogs/ProjectPicker/SectionPickerRow.vala:181 msgid "Delete Section" msgstr "删除分区" -#: src/Layouts/ItemRow.vala:424 +#: src/Layouts/ItemRow.vala:423 msgid "Add Subtasks" msgstr "添加子任务" -#: src/Layouts/ItemRow.vala:434 +#: src/Layouts/ItemRow.vala:433 msgid "Add Attachments" msgstr "添加附件" -#: src/Layouts/ItemRow.vala:991 src/Layouts/ItemBoard.vala:633 +#: src/Layouts/ItemRow.vala:995 src/Layouts/ItemBoard.vala:639 #: src/Views/Project/Project.vala:468 src/Views/Project/Project.vala:640 #: src/Dialogs/DatePicker.vala:72 msgid "No Date" msgstr "无日期" -#: src/Layouts/ItemRow.vala:994 src/Layouts/ItemRow.vala:1120 -#: src/Layouts/ItemBoard.vala:635 src/Layouts/ItemSidebarView.vala:459 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:71 -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:102 +#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemRow.vala:1123 +#: src/Layouts/ItemBoard.vala:641 src/Layouts/ItemSidebarView.vala:459 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:68 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:79 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:90 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:119 msgid "Move" msgstr "移动" -#: src/Layouts/ItemRow.vala:996 src/Layouts/ItemBoard.vala:637 +#: src/Layouts/ItemRow.vala:1000 src/Layouts/ItemBoard.vala:643 msgid "Add Subtask" msgstr "添加子任务" -#: src/Layouts/ItemRow.vala:998 src/Layouts/ItemBoard.vala:639 +#: src/Layouts/ItemRow.vala:1002 src/Layouts/ItemBoard.vala:645 msgid "Edit" msgstr "编辑" -#: src/Layouts/ItemRow.vala:1001 src/Layouts/ItemRow.vala:1124 -#: src/Layouts/ItemBoard.vala:642 src/Layouts/ItemSidebarView.vala:463 +#: src/Layouts/ItemRow.vala:1005 src/Layouts/ItemRow.vala:1127 +#: src/Layouts/ItemBoard.vala:648 src/Layouts/ItemSidebarView.vala:463 msgid "Delete Task" msgstr "删除任务" -#: src/Layouts/ItemRow.vala:1115 src/Layouts/ItemSidebarView.vala:454 +#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:454 #, fuzzy msgid "Use as a Note" msgstr "选择一个日期" -#: src/Layouts/ItemRow.vala:1118 src/Layouts/ItemSidebarView.vala:457 +#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:457 msgid "Copy to Clipboard" msgstr "复制到剪切板" -#: src/Layouts/ItemRow.vala:1121 src/Layouts/ItemSidebarView.vala:460 +#: src/Layouts/ItemRow.vala:1124 src/Layouts/ItemSidebarView.vala:460 #: src/Dialogs/RepeatConfig.vala:87 msgid "Repeat" msgstr "重复" -#: src/Layouts/ItemRow.vala:1127 src/Layouts/ItemSidebarView.vala:466 +#: src/Layouts/ItemRow.vala:1130 src/Layouts/ItemSidebarView.vala:466 #: src/Dialogs/ItemChangeHistory.vala:33 msgid "Change History" msgstr "" -#: src/Layouts/ItemRow.vala:1224 src/Layouts/ItemSidebarView.vala:570 +#: src/Layouts/ItemRow.vala:1232 src/Layouts/ItemSidebarView.vala:569 msgid "Daily" msgstr "每天" -#: src/Layouts/ItemRow.vala:1225 src/Layouts/ItemSidebarView.vala:571 +#: src/Layouts/ItemRow.vala:1233 src/Layouts/ItemSidebarView.vala:570 msgid "Weekly" msgstr "每周" -#: src/Layouts/ItemRow.vala:1226 src/Layouts/ItemSidebarView.vala:572 +#: src/Layouts/ItemRow.vala:1234 src/Layouts/ItemSidebarView.vala:571 msgid "Monthly" msgstr "每月" -#: src/Layouts/ItemRow.vala:1227 src/Layouts/ItemSidebarView.vala:573 +#: src/Layouts/ItemRow.vala:1235 src/Layouts/ItemSidebarView.vala:572 msgid "Yearly" msgstr "每年" -#: src/Layouts/ItemRow.vala:1228 src/Layouts/ItemSidebarView.vala:574 +#: src/Layouts/ItemRow.vala:1236 src/Layouts/ItemSidebarView.vala:573 msgid "Custom" msgstr "自定义" -#: src/Layouts/ItemRow.vala:1430 src/Layouts/ItemBoard.vala:517 -#: src/Layouts/ItemSidebarView.vala:762 +#: src/Layouts/ItemRow.vala:1456 src/Layouts/ItemBoard.vala:523 +#: src/Layouts/ItemSidebarView.vala:761 #, c-format msgid "Completed. Next occurrence: %s" msgstr "已完成,下一个事件:%s" -#: src/Layouts/ItemRow.vala:1472 src/Layouts/ItemBoard.vala:1006 +#: src/Layouts/ItemRow.vala:1498 src/Layouts/ItemBoard.vala:1020 #, c-format msgid "%s was deleted" msgstr "%s 已删除" -#: src/Layouts/ItemRow.vala:1473 src/Layouts/ItemBoard.vala:1007 +#: src/Layouts/ItemRow.vala:1499 src/Layouts/ItemBoard.vala:1021 msgid "Undo" msgstr "撤销" -#: src/Layouts/ItemRow.vala:1673 src/Layouts/ItemBoard.vala:907 +#: src/Layouts/ItemRow.vala:1703 src/Layouts/ItemBoard.vala:921 msgid "Order changed to 'Custom sort order'" msgstr "项目列表顺序改变至自定义顺序。" @@ -1385,20 +1393,24 @@ msgstr "标题" msgid "Properties" msgstr "属性" -#: src/Layouts/ItemSidebarView.vala:675 +#: src/Layouts/ItemSidebarView.vala:674 msgid "Are you sure you want to delete?" msgstr "你确定要删除吗?" -#: src/Layouts/HeaderBar.vala:58 +#: src/Layouts/HeaderBar.vala:71 #, fuzzy msgid "Open/Close Sidebar" msgstr "打开或关闭侧边栏" -#: src/Widgets/SyncButton.vala:80 +#: src/Layouts/SidebarSourceRow.vala:43 +msgid "No project available. Create one by clicking on the '+' button" +msgstr "尚无可用项目,点击➕加号按钮创建" + +#: src/Widgets/SyncButton.vala:79 msgid "Offline Mode Is On" msgstr "离线模式已开启" -#: src/Widgets/SyncButton.vala:80 +#: src/Widgets/SyncButton.vala:79 msgid "" "Looks like you'are not connected to the\n" "internet. Changes you make in offline\n" @@ -1459,7 +1471,7 @@ msgid "Attach File" msgstr "备份文件" #: src/Widgets/Attachments.vala:293 -#: src/Dialogs/Preferences/Pages/Backup.vala:384 +#: src/Dialogs/Preferences/Pages/Backup.vala:375 msgid "Download" msgstr "下载" @@ -1481,6 +1493,20 @@ msgstr "" msgid "Pin: Inactive" msgstr "" +#: src/Widgets/SourceRow.vala:63 +msgid "Remove" +msgstr "" + +#: src/Widgets/SourceRow.vala:80 +#: src/Dialogs/Preferences/PreferencesWindow.vala:847 +#, fuzzy +msgid "Add Source" +msgstr "来源" + +#: src/Widgets/ErrorView.vala:103 +msgid "Report Issue" +msgstr "" + #: src/Views/Project/Project.vala:57 msgid "Project Actions" msgstr "项目行为" @@ -1527,13 +1553,13 @@ msgstr "看板视图" msgid "Custom sort order" msgstr "自定义顺序" -#: src/Views/Project/Project.vala:452 src/Views/Today.vala:552 +#: src/Views/Project/Project.vala:452 src/Views/Today.vala:597 #: src/Views/Scheduled/Scheduled.vala:188 #: src/Dialogs/Preferences/PreferencesWindow.vala:364 msgid "Alphabetically" msgstr "字母表顺序" -#: src/Views/Project/Project.vala:454 src/Views/Today.vala:553 +#: src/Views/Project/Project.vala:454 src/Views/Today.vala:598 #: src/Views/Scheduled/Scheduled.vala:189 msgid "Date Added" msgstr "添加日期" @@ -1567,27 +1593,27 @@ msgstr "未来 30 天" msgid "Duedate" msgstr "截止日期" -#: src/Views/Project/Project.vala:477 src/Views/Today.vala:564 +#: src/Views/Project/Project.vala:477 src/Views/Today.vala:609 #: src/Views/Scheduled/Scheduled.vala:200 msgid "P1" msgstr "P1" -#: src/Views/Project/Project.vala:483 src/Views/Today.vala:570 +#: src/Views/Project/Project.vala:483 src/Views/Today.vala:615 #: src/Views/Scheduled/Scheduled.vala:206 msgid "P2" msgstr "P2" -#: src/Views/Project/Project.vala:489 src/Views/Today.vala:576 +#: src/Views/Project/Project.vala:489 src/Views/Today.vala:621 #: src/Views/Scheduled/Scheduled.vala:212 msgid "P3" msgstr "P3" -#: src/Views/Project/Project.vala:495 src/Views/Today.vala:582 +#: src/Views/Project/Project.vala:495 src/Views/Today.vala:627 #: src/Views/Scheduled/Scheduled.vala:218 msgid "P4" msgstr "P4" -#: src/Views/Project/Project.vala:502 src/Views/Today.vala:589 +#: src/Views/Project/Project.vala:502 src/Views/Today.vala:634 #: src/Views/Scheduled/Scheduled.vala:225 msgid "Filter by Labels" msgstr "以标签过滤" @@ -1609,7 +1635,7 @@ msgstr "删除所有完成的人物" msgid "Sort By" msgstr "排序" -#: src/Views/Project/Project.vala:533 src/Views/Today.vala:597 +#: src/Views/Project/Project.vala:533 src/Views/Today.vala:642 #: src/Views/Scheduled/Scheduled.vala:233 msgid "Filter By" msgstr "过滤" @@ -1641,48 +1667,52 @@ msgstr "逾期" msgid "Reschedule" msgstr "重新计划" -#: src/Views/Today.vala:556 src/Views/Scheduled/Scheduled.vala:192 +#: src/Views/Today.vala:601 src/Views/Scheduled/Scheduled.vala:192 msgid "Order by" msgstr "按…排序" -#: src/Views/Label/Labels.vala:39 -msgid "Labels: On This Computer" -msgstr "标签:此电脑上" - -#: src/Views/Label/Labels.vala:44 -msgid "Labels: Todoist" -msgstr "标签:Todoist" +#: src/Views/Label/LabelSourceRow.vala:43 +#, fuzzy +msgid "No labels available. Create one by clicking on the '+' button" +msgstr "尚无可用收藏,点击➕加号按钮创建" -#: src/Views/Label/Labels.vala:49 -msgid "Labels: Nextcloud" -msgstr "标签:Nextcloud" +#: src/Views/Label/LabelSourceRow.vala:51 src/Dialogs/Project.vala:213 +msgid "Add Project" +msgstr "添加项目" #: src/Views/Filter.vala:535 #, fuzzy, c-format msgid "This will delete %d completed tasks and their subtasks" msgstr "这将删除 %d 个已完成的任务及其子任务从项目 %s 中" -#: src/Dialogs/Project.vala:49 +#: src/Dialogs/Project.vala:56 msgid "New Project" msgstr "新项目" -#: src/Dialogs/Project.vala:100 +#: src/Dialogs/Project.vala:135 msgid "Give your project a name" msgstr "给你的项目起个名字" -#: src/Dialogs/Project.vala:111 +#: src/Dialogs/Project.vala:146 msgid "Use Emoji" msgstr "使用 Emoji" -#: src/Dialogs/Project.vala:130 +#: src/Dialogs/Project.vala:174 msgid "Source" msgstr "来源" -#: src/Dialogs/Project.vala:168 +#: src/Dialogs/Project.vala:213 msgid "Update Project" msgstr "更新项目" -#: src/Dialogs/Project.vala:357 +#: src/Dialogs/Project.vala:353 +#: src/Dialogs/Preferences/PreferencesWindow.vala:851 +#: src/Dialogs/Preferences/Pages/Backup.vala:164 +#, fuzzy +msgid "Sources" +msgstr "来源" + +#: src/Dialogs/Project.vala:441 msgid "Project added successfully!" msgstr "成功添加项目!" @@ -1731,8 +1761,8 @@ msgid "Please enter your credentials" msgstr "请输入你的凭证" #: src/Dialogs/GoogleOAuth.vala:157 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1366 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1368 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1268 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1270 msgid "Network Is Not Available" msgstr "网络不可用" @@ -1790,7 +1820,7 @@ msgstr "" msgid "Archived" msgstr "已存档" -#: src/Dialogs/ProjectPicker/ProjectPicker.vala:84 +#: src/Dialogs/ProjectPicker/ProjectPicker.vala:101 msgid "Type a search" msgstr "输入以搜索" @@ -1935,7 +1965,7 @@ msgstr "" "发展,请考虑支持我们。" #: src/Dialogs/Preferences/PreferencesWindow.vala:71 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1712 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1605 msgid "Supporting Us" msgstr "支持" @@ -1976,7 +2006,7 @@ msgid "Appearance" msgstr "外观" #: src/Dialogs/Preferences/PreferencesWindow.vala:183 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1158 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1045 msgid "Quick Add" msgstr "快速添加" @@ -2006,7 +2036,7 @@ msgid "Reach Us" msgstr "找到我们" #: src/Dialogs/Preferences/PreferencesWindow.vala:224 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1662 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 msgid "Contact Us" msgstr "联系我们" @@ -2044,7 +2074,7 @@ msgid "Privacy" msgstr "隐私" #: src/Dialogs/Preferences/PreferencesWindow.vala:307 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1630 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1523 msgid "Privacy Policy" msgstr "隐私政策" @@ -2245,41 +2275,34 @@ msgid "Dark Blue Style" msgstr "深蓝色" #: src/Dialogs/Preferences/PreferencesWindow.vala:826 -#: src/Dialogs/Preferences/PreferencesWindow.vala:886 msgid "Accounts" msgstr "账户" -#: src/Dialogs/Preferences/PreferencesWindow.vala:850 -msgid "Synchronize with your Todoist Account" -msgstr "与你的 Todoist 账户同步" +#: src/Dialogs/Preferences/PreferencesWindow.vala:862 +#, fuzzy +msgid "You can sort your accounts by dragging and dropping" +msgstr "您可以通过拖放对视图进行排序" -#: src/Dialogs/Preferences/PreferencesWindow.vala:878 -msgid "Synchronization based on open Internet standards" -msgstr "基于 CalDAV 的同步" +#: src/Dialogs/Preferences/PreferencesWindow.vala:969 +msgid "Display Name" +msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1014 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 +#: src/Dialogs/Preferences/PreferencesWindow.vala:975 msgid "Sync Server" msgstr "同步服务器" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1015 +#: src/Dialogs/Preferences/PreferencesWindow.vala:976 +#, fuzzy msgid "" "Activate this setting so that Planify automatically synchronizes with your " -"Todoist account every 15 minutes" +"account account every 15 minutes" msgstr "激活此设置后 Planify 将每隔 15 分钟自动通过您的 Todoist 帐号进行同步" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1029 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1115 +#: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync" msgstr "上次同步" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 -msgid "" -"Activate this setting so that Planify automatically synchronizes with your " -"CalDAV account every 15 minutes" -msgstr "激活此设置后 Planify 将每隔 15 分钟自动通过您的 CalDAV 帐号进行同步" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1166 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1053 msgid "" "Use Quick Add to create to-dos from anywhere on your desktop with just a few " "keystrokes. You don’t even have to leave the app you’re currently in." @@ -2287,7 +2310,7 @@ msgstr "" "使用 ‘快速添加’,只需敲击几下键盘,就可以在桌面上的任何地方创建待办事项。你甚" "至不需要离开你目前所在的应用程序。" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1177 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1064 msgid "" "Head to System Settings → Keyboard → Shortcuts → Custom, then add a new " "shortcut with the following:" @@ -2295,79 +2318,77 @@ msgstr "" "前往 ‘系统设置’ → ‘键盘’ → ‘快捷键’ → ‘自定义’,然后一个新的快捷键,内容如" "下:" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1205 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1092 msgid "Settings" msgstr "设置" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1213 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1100 msgid "Save Last Selected Project" msgstr "保存上次选择的项目" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1214 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1101 msgid "If unchecked, the default project selected is Inbox" msgstr "如果未选中,则默认选择收件箱项目" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1248 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1135 msgid "The command was copied to the clipboard" msgstr "命令已复制到剪切板" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1263 -#: src/Dialogs/Preferences/PreferencesWindow.vala:1354 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1150 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1256 msgid "Loading…" msgstr "加载中…" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1290 +#. Loading +#: src/Dialogs/Preferences/PreferencesWindow.vala:1176 msgid "Planify is is syncing your tasks, this may take a few minutes" msgstr "Planify 正在同步你的任务,这可能需要几分钟" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1338 -msgid "Synchronizing..." +#: src/Dialogs/Preferences/PreferencesWindow.vala:1224 +#, fuzzy +msgid "Synchronizing…" msgstr "同步中..." -#: src/Dialogs/Preferences/PreferencesWindow.vala:1349 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1251 msgid "Please Enter Your Credentials" msgstr "输入你的凭证" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1399 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1297 #, fuzzy msgid "Nextcloud Setup" msgstr "Nextcloud" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1402 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1300 msgid "Server URL" msgstr "服务器地址" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1405 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1303 msgid "User Name" msgstr "用户名" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1408 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1306 msgid "Password" msgstr "密码" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1415 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1313 msgid "Provider" msgstr "提供者" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1452 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1350 msgid "Log In" msgstr "登陆" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1555 -msgid "Failed to login" -msgstr "登陆失败" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1637 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1530 msgid "Personal Data" msgstr "个人信息" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1642 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1535 msgid "" "We collect absolutely nothing and all your data is stored in a database on " "your computer." msgstr "我们绝对不收集任何信息,您的所有数据都存储在您计算机上的数据库中。" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1647 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1540 msgid "" "If you choose to integrate Todoist, which is optional and not selected by " "default, your data will be stored on their private servers, we only display " @@ -2376,18 +2397,18 @@ msgstr "" "如果您选择集成 Todoist(可选且默认不选择),您的数据将保存在他们的私人服务器" "上,我们只显示您配置的任务并为您管理这些任务。" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1652 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1545 msgid "Do you have any questions?" msgstr "您有任何问题吗?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1657 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1550 msgid "" "If you have any questions about your data or any other issue, please contact " "us. We will be happy to answer you." msgstr "" "如果您对您的数据有任何疑问或任何其他问题,请联系我们。我们很乐意为您解答。" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1719 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1612 msgid "" "Our mission is to provide the best open source task management application " "for users all over the world. Your donations support this work. Want to " @@ -2396,38 +2417,22 @@ msgstr "" "我们的使命是为世界各地的用户提供最好的开源任务管理应用程序。您的捐款支持这项" "工作。今天想捐款吗?" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1727 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1620 msgid "Patreon" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1740 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1633 msgid "PayPal" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1753 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1646 msgid "Liberapay" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1766 +#: src/Dialogs/Preferences/PreferencesWindow.vala:1659 msgid "Ko-fi" msgstr "" -#: src/Dialogs/Preferences/PreferencesWindow.vala:1854 -msgid "" -"Are you sure you want to remove the Todoist sync? This action will delete " -"all your tasks and settings." -msgstr "你确定要移除 Todoist 同步吗?此操作将会删除你所有的任务和设置。" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1856 -msgid "" -"Are you sure you want to remove the CalDAV sync? This action will delete all " -"your tasks and settings." -msgstr "你确定要移除 CalDAV 同步吗?此操作将会删除你所有的任务和设置。" - -#: src/Dialogs/Preferences/PreferencesWindow.vala:1859 -msgid "Sign Off" -msgstr "登出" - #: src/Dialogs/Preferences/Pages/Backup.vala:55 msgid "" "Never worry about losing your data. You can create backups of your active " @@ -2447,54 +2452,64 @@ msgstr "导入备份" msgid "Backup Files" msgstr "备份文件" -#: src/Dialogs/Preferences/Pages/Backup.vala:79 +#: src/Dialogs/Preferences/Pages/Backup.vala:75 +#, fuzzy +msgid "No backups found, create one clicking the button above." +msgstr "尚无可用账户,点击 ‘+’ 按钮以同步" + +#: src/Dialogs/Preferences/Pages/Backup.vala:80 msgid "Migrate" msgstr "迁移" -#: src/Dialogs/Preferences/Pages/Backup.vala:81 +#: src/Dialogs/Preferences/Pages/Backup.vala:82 msgid "Migrate From Planner" msgstr "从 Planner 迁移" -#: src/Dialogs/Preferences/Pages/Backup.vala:131 +#: src/Dialogs/Preferences/Pages/Backup.vala:116 +#, fuzzy +msgid "The Backup was created successfully." +msgstr "任务迁移成功" + +#: src/Dialogs/Preferences/Pages/Backup.vala:133 msgid "Tasks Migrate Successfully" msgstr "任务迁移成功" -#: src/Dialogs/Preferences/Pages/Backup.vala:135 +#: src/Dialogs/Preferences/Pages/Backup.vala:137 msgid "The database file does not exist." msgstr "数据库文件不存在。" -#: src/Dialogs/Preferences/Pages/Backup.vala:151 +#: src/Dialogs/Preferences/Pages/Backup.vala:153 msgid "Import Overview" msgstr "导入概览" -#: src/Dialogs/Preferences/Pages/Backup.vala:179 +#: src/Dialogs/Preferences/Pages/Backup.vala:176 #, fuzzy msgid "To-Dos" msgstr "添加待办事项" -#: src/Dialogs/Preferences/Pages/Backup.vala:200 +#: src/Dialogs/Preferences/Pages/Backup.vala:198 msgid "Confirm" msgstr "确认" -#: src/Dialogs/Preferences/Pages/Backup.vala:249 +#: src/Dialogs/Preferences/Pages/Backup.vala:246 msgid "Restore backup" msgstr "恢复备份" -#: src/Dialogs/Preferences/Pages/Backup.vala:250 +#: src/Dialogs/Preferences/Pages/Backup.vala:247 msgid "" "Are you sure you want to continue? This operation will delete your current " "data and replace it with the backup data." msgstr "你确定你要继续吗?此操作将删除您当前的数据并用备份数据替换。" -#: src/Dialogs/Preferences/Pages/Backup.vala:255 +#: src/Dialogs/Preferences/Pages/Backup.vala:252 msgid "Restore Backup" msgstr "恢复备份" -#: src/Dialogs/Preferences/Pages/Backup.vala:304 +#: src/Dialogs/Preferences/Pages/Backup.vala:295 msgid "Selected file is invalid" msgstr "选择的文件无效" -#: src/Dialogs/Preferences/Pages/Backup.vala:332 +#: src/Dialogs/Preferences/Pages/Backup.vala:323 #, fuzzy msgid "View Backup" msgstr "创建备份" @@ -2614,8 +2629,44 @@ msgctxt "shortcut window" msgid "Open Pinboard" msgstr "打开标签" -#~ msgid "CalDAV Setup" -#~ msgstr "CalDAV 设置" +#~ msgid "On this Computer" +#~ msgstr "此电脑上" + +#~ msgid "Labels: On This Computer" +#~ msgstr "标签:此电脑上" + +#~ msgid "Labels: Todoist" +#~ msgstr "标签:Todoist" + +#~ msgid "Labels: Nextcloud" +#~ msgstr "标签:Nextcloud" + +#~ msgid "Synchronize with your Todoist Account" +#~ msgstr "与你的 Todoist 账户同步" + +#~ msgid "Synchronization based on open Internet standards" +#~ msgstr "基于 CalDAV 的同步" + +#~ msgid "" +#~ "Activate this setting so that Planify automatically synchronizes with " +#~ "your CalDAV account every 15 minutes" +#~ msgstr "激活此设置后 Planify 将每隔 15 分钟自动通过您的 CalDAV 帐号进行同步" + +#~ msgid "Failed to login" +#~ msgstr "登陆失败" + +#~ msgid "" +#~ "Are you sure you want to remove the Todoist sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "你确定要移除 Todoist 同步吗?此操作将会删除你所有的任务和设置。" + +#~ msgid "" +#~ "Are you sure you want to remove the CalDAV sync? This action will delete " +#~ "all your tasks and settings." +#~ msgstr "你确定要移除 CalDAV 同步吗?此操作将会删除你所有的任务和设置。" + +#~ msgid "Sign Off" +#~ msgstr "登出" #~ msgid "Add task" #~ msgstr "添加任务" @@ -2798,11 +2849,6 @@ msgstr "打开标签" #~ msgid "No label available, click to add one" #~ msgstr "尚无可用标签,点击创建" -#~ msgid "" -#~ "Your list of filters will show up here. Create one by clicking on the '+' " -#~ "button" -#~ msgstr "你的过滤器列表将显示在这里,点击 ‘+’ 按钮创建" - #~ msgid "Sync" #~ msgstr "同步" From 1ea0d351a78a8470c4428edc7a54f7b670fc288d Mon Sep 17 00:00:00 2001 From: Alain Date: Mon, 29 Jul 2024 09:16:44 -0500 Subject: [PATCH 14/14] update releases --- data/io.github.alainm23.planify.appdata.xml.in.in | 6 +++++- po/es.po | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/data/io.github.alainm23.planify.appdata.xml.in.in b/data/io.github.alainm23.planify.appdata.xml.in.in index 1c42bb177..abac18c8c 100644 --- a/data/io.github.alainm23.planify.appdata.xml.in.in +++ b/data/io.github.alainm23.planify.appdata.xml.in.in @@ -70,7 +70,11 @@
      -
    • Support for multiple sync sources: Integrate more than two Todoist or Nextcloud accounts
    • +
    • Support for multiple sync sources: Integrate more than two Todoist or Nextcloud accounts.
    • +
    • Fixed visual bug where dragging an element leaves an empty line.
    • +
    • Portuguese translation update thanks to @godinhoana54.
    • +
    • Hindi translation update thanks to @Scrambled777.
    • +
    • Spanish translation update thanks to @haggen88.
    diff --git a/po/es.po b/po/es.po index 5e77c7a08..6dc128eb9 100644 --- a/po/es.po +++ b/po/es.po @@ -2327,7 +2327,7 @@ msgid "" "account account every 15 minutes" msgstr "" "Active esta opción para que Planify se sincronice automáticamente con su " -"cuenta Todoist cada 15 minutos" +"cuenta cada 15 minutos" #: src/Dialogs/Preferences/PreferencesWindow.vala:989 msgid "Last Sync"