├── .buildconfig ├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ └── build.yml ├── .gitignore ├── .vala-lint.conf ├── .vscode └── settings.json ├── AUTHORS ├── LICENSE ├── README.md ├── build-aux └── io.github.alainm23.planify.Devel.json ├── config.vala.in ├── core ├── Constants.vala ├── Enum.vala ├── Layouts │ └── HeaderItem.vala ├── Objects │ ├── Attachment.vala │ ├── BaseObject.vala │ ├── Color.vala │ ├── DueDate.vala │ ├── Filters │ │ ├── AllItems.vala │ │ ├── Anytime.vala │ │ ├── Completed.vala │ │ ├── FilterItem.vala │ │ ├── Labels.vala │ │ ├── Pinboard.vala │ │ ├── Priority.vala │ │ ├── Repeating.vala │ │ ├── Scheduled.vala │ │ ├── Today.vala │ │ ├── Tomorrow.vala │ │ └── Unlabeled.vala │ ├── Item.vala │ ├── Label.vala │ ├── ObjectEvent.vala │ ├── Project.vala │ ├── Promise.vala │ ├── Queue.vala │ ├── Reminder.vala │ ├── Section.vala │ └── Source.vala ├── QuickAdd.vala ├── Services │ ├── CalDAV │ │ ├── Core.vala │ │ └── Providers │ │ │ ├── Nextcloud.vala │ │ │ ├── ProviderBase.vala │ │ │ └── Radicale.vala │ ├── Chrono │ │ ├── Chrono.vala │ │ ├── Enum.vala │ │ ├── Locales │ │ │ └── En │ │ │ │ ├── Constants.vala │ │ │ │ ├── En.vala │ │ │ │ └── Parsers │ │ │ │ └── ENCasualDateParser.vala │ │ └── Types.vala │ ├── Database.vala │ ├── EventBus.vala │ ├── Settings.vala │ ├── Store.vala │ └── Todoist.vala ├── Util │ ├── Datetime.vala │ ├── Migrate.vala │ └── Util.vala ├── Widgets │ ├── Calendar │ │ ├── Calendar.vala │ │ ├── CalendarDay.vala │ │ ├── CalendarHeader.vala │ │ ├── CalendarView.vala │ │ └── CalendarWeek.vala │ ├── CircularProgressBar.vala │ ├── ContextMenu │ │ ├── MenuCheckPicker.vala │ │ ├── MenuItem.vala │ │ ├── MenuPicker.vala │ │ ├── MenuSeparator.vala │ │ └── MenuSwitch.vala │ ├── DateTimePicker │ │ ├── DateTimePicker.vala │ │ ├── RepeatConfig.vala │ │ ├── ScheduleButton.vala │ │ └── TimePicker.vala │ ├── Entries.vala │ ├── IconColorProject.vala │ ├── ItemLabelChild.vala │ ├── ItemLabels.vala │ ├── LabelPicker │ │ ├── LabelButton.vala │ │ ├── LabelPicker.vala │ │ └── LabelRow.vala │ ├── LabelsPickerCore.vala │ ├── LoadingButton.vala │ ├── Markdown │ │ ├── Color.vala │ │ ├── MarkdownBuffer.vala │ │ ├── MarkdownEditView.vala │ │ └── MarkdownView.vala │ ├── PinButton.vala │ ├── PriorityButton.vala │ ├── ProjectPicker │ │ ├── ProjectPickerButton.vala │ │ ├── ProjectPickerPopover.vala │ │ ├── ProjectPickerRow.vala │ │ └── SectionPickerRow.vala │ ├── ReminderPicker │ │ ├── ReminderButton.vala │ │ ├── ReminderPicker.vala │ │ └── ReminderRow.vala │ ├── SectionPicker │ │ ├── SectionButton.vala │ │ ├── SectionPicker.vala │ │ └── SectionPickerRow.vala │ └── StatusButton.vala ├── meson.build └── planify.deps ├── data ├── icons │ ├── hicolor │ │ ├── scalable │ │ │ └── apps │ │ │ │ ├── io.github.alainm23.planify.Devel.svg │ │ │ │ └── io.github.alainm23.planify.svg │ │ └── symbolic │ │ │ └── apps │ │ │ └── io.github.alainm23.planify-symbolic.svg │ ├── io.github.alainm23.planify.Source.svg │ └── meson.build ├── io.github.alainm23.planify.appdata.xml.in.in ├── io.github.alainm23.planify.desktop.in.in ├── io.github.alainm23.planify.gresource.xml ├── io.github.alainm23.planify.gschema.xml ├── io.github.alainm23.planify.png ├── io.github.alainm23.planify.service.in ├── markdown.xml ├── markdown_dark.xml ├── markdownpp.lang ├── meson.build ├── release.svg └── resources │ ├── icons │ ├── alarm-symbolic.svg │ ├── arrow-circular-top-right-symbolic.svg │ ├── arrow-turn-down-right-symbolic.svg │ ├── arrow3-down-symbolic.svg │ ├── arrow3-right-symbolic.svg │ ├── carousel-symbolic.svg │ ├── chat-bubble-text-symbolic.svg │ ├── check-round-outline-symbolic.svg │ ├── check-round-outline-whole-symbolic.svg │ ├── checkmark-small-symbolic.svg │ ├── clipboard-symbolic.svg │ ├── clock-symbolic.svg │ ├── cloud-outline-thick-symbolic.svg │ ├── cloud.svg │ ├── color-symbolic.svg │ ├── cross-large-circle-filled-symbolic.svg │ ├── cross-large-circle-outline-symbolic.svg │ ├── delay-symbolic.svg │ ├── dock-left-symbolic.svg │ ├── dock-right-symbolic.svg │ ├── edit-find-symbolic.svg │ ├── edit-symbolic.svg │ ├── external-link-symbolic.svg │ ├── eye-open-negative-filled-symbolic.svg │ ├── flag-outline-thick-symbolic.svg │ ├── folder-download-symbolic.svg │ ├── funnel-outline-symbolic.svg │ ├── go-next-symbolic.svg │ ├── go-up-symbolic.svg │ ├── grid-large-symbolic.svg │ ├── heart-outline-thick-symbolic.svg │ ├── info-outline-symbolic.svg │ ├── list-drag-handle-symbolic.svg │ ├── list-large-symbolic.svg │ ├── list-symbolic.svg │ ├── mail-attachment-symbolic.svg │ ├── mail-symbolic.svg │ ├── mailbox-symbolic.svg │ ├── menu-large-symbolic.svg │ ├── month-symbolic.svg │ ├── navigate-symbolic.svg │ ├── paper-symbolic.svg │ ├── permissions-generic-symbolic.svg │ ├── pin-symbolic.svg │ ├── playlist-repeat-symbolic.svg │ ├── plus-large-symbolic.svg │ ├── process-error-symbolic.svg │ ├── reaction-add2-symbolic.svg │ ├── rescue-symbolic.svg │ ├── rotation-edit-symbolic.svg │ ├── settings-symbolic.svg │ ├── share-alt-symbolic.svg │ ├── shield-safe-symbolic.svg │ ├── shoe-box-symbolic.svg │ ├── size-vertically-symbolic.svg │ ├── star-outline-thick-symbolic.svg │ ├── step-out-symbolic.svg │ ├── tabs-stack-symbolic.svg │ ├── tag-outline-add-symbolic.svg │ ├── tag-outline-remove-symbolic.svg │ ├── tag-outline-symbolic.svg │ ├── text-justify-left-symbolic.svg │ ├── today-calendar-symbolic.svg │ ├── todoist.svg │ ├── update-symbolic.svg │ ├── user-trash-symbolic.svg │ ├── vertical-arrows-long-symbolic.svg │ ├── view-columns-symbolic.svg │ ├── view-list-ordered-symbolic.svg │ ├── view-more-symbolic.svg │ ├── view-sort-descending-rtl-symbolic.svg │ └── work-week-symbolic.svg │ ├── screenshot │ ├── screenshot-01.png │ ├── screenshot-02.png │ ├── screenshot-03.png │ └── screenshot-04.png │ ├── sounds │ └── success.ogg │ ├── stylesheet │ ├── animations.css │ ├── calendar.css │ ├── index.css │ ├── sidebar.css │ ├── stylesheet.css │ ├── typography.css │ └── variables.css │ ├── ui │ └── shortcuts.ui │ └── videos │ ├── dnd-order.webm │ ├── magic-button.webm │ └── subprojects.webm ├── meson.build ├── meson_options.txt ├── planify.doap ├── po ├── LINGUAS ├── POTFILES ├── README.md ├── bg.po ├── de.po ├── es.po ├── fr.po ├── hi.po ├── io.github.alainm23.planify.pot ├── ka.po ├── ko.po ├── meson.build ├── nl.po ├── pt_BR.po ├── pt_PT.po ├── ru.po ├── sk_SK.po ├── tr.po └── zh_CN.po ├── quick-add ├── App.vala ├── MainWindow.vala ├── Services │ └── DBusClient.vala └── meson.build ├── search-provider ├── io.github.alainm23.planify.SearchProvider.ini.in ├── io.github.alainm23.planify.SearchProvider.service.in ├── main.vala ├── meson.build └── search-provider.vala ├── snap └── snapcraft.yaml ├── src ├── App.vala ├── Dialogs │ ├── CompletedTasks.vala │ ├── DatePicker.vala │ ├── ErrorDialog.vala │ ├── GoogleOAuth.vala │ ├── ItemChangeHistory.vala │ ├── Label.vala │ ├── LabelPicker.vala │ ├── ManageProjects.vala │ ├── ManageSectionOrder.vala │ ├── Preferences │ │ ├── Pages │ │ │ ├── Backup.vala │ │ │ └── Sidebar.vala │ │ ├── PreferencesWindow.vala │ │ └── SettingsHeader.vala │ ├── Project.vala │ ├── ProjectPicker │ │ ├── ProjectPicker.vala │ │ ├── ProjectPickerRow.vala │ │ ├── ProjectPickerSourceRow.vala │ │ └── SectionPickerRow.vala │ ├── QuickAdd.vala │ ├── QuickFind │ │ ├── QuickFind.vala │ │ ├── QuickFindItem.vala │ │ └── Synapse.vala │ ├── Section.vala │ └── WhatsNew.vala ├── Layouts │ ├── FilterPaneRow.vala │ ├── HeaderBar.vala │ ├── ItemBase.vala │ ├── ItemBoard.vala │ ├── ItemRow.vala │ ├── ItemSidebarView.vala │ ├── LabelRow.vala │ ├── ProjectContainerRow.vala │ ├── ProjectRow.vala │ ├── SectionBoard.vala │ ├── SectionRow.vala │ ├── Sidebar.vala │ └── SidebarSourceRow.vala ├── MainWindow.vala ├── Objects │ └── Backup.vala ├── Services │ ├── ActionManager.vala │ ├── Backups.vala │ ├── CalendarEvents │ │ ├── CalendarEvents.vala │ │ ├── DateIterator.vala │ │ ├── DateRange.vala │ │ └── Util.vala │ ├── DBusServer.vala │ ├── GoogleTasks.vala │ ├── MigrateFromPlanner.vala │ ├── Notification.vala │ ├── TimeMonitor.vala │ └── TodayTaskMonitor.vala ├── Views │ ├── Filter.vala │ ├── Label │ │ ├── Label.vala │ │ ├── LabelSourceRow.vala │ │ └── Labels.vala │ ├── Project │ │ ├── Board.vala │ │ ├── List.vala │ │ └── Project.vala │ ├── Scheduled │ │ ├── Scheduled.vala │ │ ├── ScheduledDay.vala │ │ ├── ScheduledMonth.vala │ │ └── ScheduledRange.vala │ └── Today.vala ├── Widgets │ ├── AttachmentRow.vala │ ├── Attachments.vala │ ├── ColorPickerRow.vala │ ├── CompletedTaskRow.vala │ ├── EditableLabel.vala │ ├── EditableTextView.vala │ ├── ErrorView.vala │ ├── EventRow.vala │ ├── EventsList.vala │ ├── FilterFlowBox.vala │ ├── FilterFlowBoxChild.vala │ ├── ItemChangeHistoryRow.vala │ ├── ItemDetailCompleted.vala │ ├── LabelsSummary.vala │ ├── MagicButton.vala │ ├── MultiSelectToolbar.vala │ ├── PinnedItemsFlowBox.vala │ ├── ReorderChild.vala │ ├── ScrolledWindow.vala │ ├── SectionsOrderPopover.vala │ ├── SourceRow.vala │ ├── SubItems.vala │ └── SyncButton.vala └── meson.build ├── subprojects └── gxml-0.20.wrap └── uncrustify.cfg /.buildconfig: -------------------------------------------------------------------------------- 1 | [default] 2 | name=Default 3 | runtime=host 4 | config-opts= 5 | run-opts= 6 | prefix=/home/alain/.cache/gnome-builder/install/planify/host 7 | app-id= 8 | postbuild= 9 | prebuild= 10 | default=true 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig 2 | root = true 3 | 4 | # elementary defaults 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | indent_size = tab 9 | indent_style = space 10 | insert_final_newline = true 11 | max_line_length = 80 12 | tab_width = 4 13 | 14 | # Markup files 15 | [{*.html,*.xml,*.xml.in,*.yml}] 16 | tab_width = 2 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: alainm23 4 | liberapay: Alain 5 | custom: https://www.paypal.me/alainm23 6 | ko_fi: alainm23 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | 5 | --- 6 | 7 | **Describe the bug** 8 | A clear and concise description of what the bug is. 9 | 10 | **To Reproduce** 11 | Steps to reproduce the behavior: 12 | 1. Go to '...' 13 | 2. Click on '....' 14 | 3. Scroll down to '....' 15 | 4. See error 16 | 17 | **Expected behavior** 18 | A clear and concise description of what you expected to happen. 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Desktop (please complete the following information):** 24 | - OS or DE: [e.g. pantheon, unity, gnome] 25 | - Version [e.g. 0.1.2] 26 | 27 | **Additional context** 28 | Add any other context about the problem here. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [master] 4 | pull_request: 5 | concurrency: 6 | group: ${{ github.workflow }}-${{ github.ref }} 7 | cancel-in-progress: true 8 | name: CI 9 | jobs: 10 | lint: 11 | name: "Vala Lint" 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: elementary/actions/vala-lint@main 16 | with: 17 | dir: . 18 | conf: .vala-lint.conf 19 | flatpak-devel: 20 | name: "Flatpak (Devel)" 21 | runs-on: ubuntu-latest 22 | container: 23 | image: bilelmoussaoui/flatpak-github-actions:gnome-46 24 | options: --privileged 25 | steps: 26 | - uses: actions/checkout@v4 27 | - uses: flatpak/flatpak-github-actions/flatpak-builder@v6 28 | with: 29 | bundle: io.github.alainm23.planify.Devel.flatpak 30 | manifest-path: build-aux/io.github.alainm23.planify.Devel.json 31 | cache-key: flatpak-builder-${{ github.sha }} 32 | # snap: 33 | # name: "Snap" 34 | # runs-on: ubuntu-latest 35 | # steps: 36 | # - name: Checkout Git repository 37 | # uses: actions/checkout@v4 38 | # - name: Build Snap 39 | # uses: snapcore/action-build@v1 40 | # id: snapcraft-build 41 | # with: 42 | # snapcraft-args: "--verbosity debug" 43 | # - uses: actions/upload-artifact@v4 44 | # with: 45 | # name: planify_amd64_snap 46 | # path: ${{ steps.snapcraft-build.outputs.snap }} 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | build/ 3 | builddir/ 4 | build-aux/build-dir 5 | build-aux/flatpak_build 6 | build-aux/.flatpak-builder 7 | build-aux/io.github.alainm23.planify.Devel.flatpak 8 | .flatpak-builder/ 9 | subprojects/gxml**/ 10 | *.snap 11 | planify*txt 12 | -------------------------------------------------------------------------------- /.vala-lint.conf: -------------------------------------------------------------------------------- 1 | [Checks] 2 | block-opening-brace-space-before=error 3 | double-semicolon=error 4 | double-spaces=error 5 | ellipsis=error 6 | line-length=off 7 | naming-convention=off 8 | no-space=error 9 | note=warn 10 | space-before-paren=error 11 | use-of-tabs=off 12 | trailing-newlines=off 13 | trailing-whitespace=off 14 | unnecessary-string-template=error 15 | 16 | [Disabler] 17 | disable-by-inline-comments=true 18 | 19 | [line-length] 20 | max-line-length=120 21 | ignore-comments=true 22 | 23 | [naming-convention] 24 | exceptions=UUID, 25 | 26 | [note] 27 | keywords=TODO,FIXME, 28 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "mesonbuild.configureOnOpen": false 3 | } -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Alain M. -------------------------------------------------------------------------------- /config.vala.in: -------------------------------------------------------------------------------- 1 | namespace Build { 2 | public const string GETTEXT_PACKAGE = @GETTEXT_PACKAGE@; 3 | public const string APPLICATION_ID = @APPLICATION_ID@; 4 | public const string VERSION = @VERSION@; 5 | public const string INSTALL_PREFIX = @PREFIX@; 6 | public const string DATADIR = @DATADIR@; 7 | public const string PROFILE = @PROFILE@; 8 | public const string LOCALEDIR = @LOCALEDIR@; 9 | public const string GNOMELOCALEDIR = @GNOMELOCALEDIR@; 10 | } -------------------------------------------------------------------------------- /core/Constants.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | namespace Constants { 23 | public const string TODOIST_CLIENT_ID = "b0dd7d3714314b1dbbdab9ee03b6b432"; 24 | public const string TODOIST_CLIENT_SECRET = "a86dfeb12139459da3e5e2a8c197c678"; 25 | public const string TODOIST_SCOPE = "data:read_write,data:delete,project:delete"; 26 | public const string BACKUP_VERSION = "2.0"; 27 | public const int UPDATE_TIMEOUT = 1500; 28 | public const int DESTROY_TIMEOUT = 750; 29 | public const int SYNC_TIMEOUT = 2500; 30 | public const int SHORT_NAME_SIZE = 20; 31 | public const int PRIORITY_1 = 4; 32 | public const int PRIORITY_2 = 3; 33 | public const int PRIORITY_3 = 2; 34 | public const int PRIORITY_4 = 1; 35 | public const int SCROLL_STEPS = 6; 36 | public const string TWITTER_URL = "https://twitter.com/useplanify"; 37 | public const string CONTACT_US = "alainmh23@gmail.com"; 38 | public const string TELEGRAM_GROUP = "https://t.me/+cArNTCbdT3xmOTcx"; 39 | public const string PATREON_URL = "https://www.patreon.com/join/alainm23"; 40 | public const string PAYPAL_ME_URL = "https://www.paypal.com/paypalme/alainm23"; 41 | public const string LIBERAPAY_URL = "https://liberapay.com/Alain/"; 42 | public const string KOFI_URL = "https://ko-fi.com/alainm23"; 43 | public const string MATRIX_URL = "https://matrix.to/#/#useplanify:matrix.org"; 44 | public const string MASTODON_URL = "https://mastodon.social/@planifyapp"; 45 | public const bool SHOW_WHATSNEW = false; 46 | public const bool BLOCK_PAST_DAYS = false; 47 | } 48 | -------------------------------------------------------------------------------- /core/Objects/Attachment.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Attachment : GLib.Object { 23 | public string id { get; set; default = ""; } 24 | public string item_id { get; set; default = ""; } 25 | public string file_type { get; set; default = ""; } 26 | public string file_name { get; set; default = ""; } 27 | public int64 file_size { get; set; default = 0; } 28 | public string file_path { get; set; default = ""; } 29 | 30 | public signal void deleted (); 31 | 32 | Objects.Item? _item; 33 | public Objects.Item item { 34 | get { 35 | _item = Services.Store.instance ().get_item (item_id); 36 | return _item; 37 | } 38 | 39 | set { 40 | _item = value; 41 | } 42 | } 43 | 44 | public string to_string () { 45 | return """ 46 | _________________________________ 47 | ID: %s 48 | ITEM ID: %s 49 | FILE TYPE: %s 50 | FILE NAME: %s 51 | FILE SIZE: %s 52 | FILE PATH: %s 53 | --------------------------------- 54 | """.printf ( 55 | id, 56 | item_id, 57 | file_type, 58 | file_name, 59 | file_size.to_string (), 60 | file_path 61 | ); 62 | } 63 | 64 | public void delete () { 65 | Services.Store.instance ().delete_attachment (this); 66 | } 67 | 68 | public Objects.Attachment duplicate () { 69 | var new_attachment = new Objects.Attachment (); 70 | new_attachment.file_type = file_type; 71 | new_attachment.file_name = file_name; 72 | new_attachment.file_size = file_size; 73 | new_attachment.file_path = file_path; 74 | 75 | return new_attachment; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/Objects/Color.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Color : GLib.Object { 23 | public int id { get; construct; } 24 | public string name { get; construct; } 25 | public string hexadecimal { get; construct; } 26 | 27 | public Color (int id, string name, string hexadecimal) { 28 | Object ( 29 | id: id, 30 | name: name, 31 | hexadecimal: hexadecimal 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /core/Objects/Filters/AllItems.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.AllItems : Objects.BaseObject { 23 | private static AllItems? _instance; 24 | public static AllItems get_default () { 25 | if (_instance == null) { 26 | _instance = new AllItems (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | construct { 33 | name = _("All Tasks"); 34 | keywords = "%s;%s".printf (_("all tasks"), _("all")); 35 | icon_name = "check-round-outline-symbolic"; 36 | view_id = "all-items-view"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/Objects/Filters/Anytime.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Anytime : Objects.BaseObject { 23 | private static Anytime? _instance; 24 | public static Anytime get_default () { 25 | if (_instance == null) { 26 | _instance = new Anytime (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | construct { 33 | name = _("Anytime"); 34 | keywords = "%s;%s;%s".printf (_("anytime"), _("filters"), _("no date")); 35 | icon_name = "grid-large-symbolic"; 36 | view_id = "anytime-view"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/Objects/Filters/Completed.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Completed : Objects.BaseObject { 23 | private static Completed? _instance; 24 | public static Completed get_default () { 25 | if (_instance == null) { 26 | _instance = new Completed (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | int? _count = null; 33 | public int count { 34 | get { 35 | if (_count == null) { 36 | _count = Services.Store.instance ().get_items_completed ().size; 37 | } 38 | 39 | return _count; 40 | } 41 | 42 | set { 43 | _count = value; 44 | } 45 | } 46 | 47 | public signal void count_updated (); 48 | 49 | construct { 50 | name = _("Completed"); 51 | keywords = "%s;%s;%s".printf (_("completed"), _("filters"), _("logbook")); 52 | icon_name = "check-round-outline-symbolic"; 53 | view_id = FilterType.COMPLETED.to_string (); 54 | 55 | Services.Store.instance ().item_added.connect (() => { 56 | _count = Services.Store.instance ().get_items_completed ().size; 57 | count_updated (); 58 | }); 59 | 60 | Services.Store.instance ().item_deleted.connect (() => { 61 | _count = Services.Store.instance ().get_items_completed ().size; 62 | count_updated (); 63 | }); 64 | 65 | Services.Store.instance ().item_updated.connect (() => { 66 | _count = Services.Store.instance ().get_items_completed ().size; 67 | count_updated (); 68 | }); 69 | 70 | Services.Store.instance ().item_archived.connect (() => { 71 | _count = Services.Store.instance ().get_items_completed ().size; 72 | count_updated (); 73 | }); 74 | 75 | Services.Store.instance ().item_unarchived.connect (() => { 76 | _count = Services.Store.instance ().get_items_completed ().size; 77 | count_updated (); 78 | }); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /core/Objects/Filters/FilterItem.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.FilterItem : GLib.Object { 23 | public FilterItemType filter_type { get; set; } 24 | public string name { get; set; } 25 | public string value { get; set; } 26 | 27 | private string _id; 28 | public string id { 29 | get { 30 | _id = filter_type.to_string () + "-" + value; 31 | if (filter_type == FilterItemType.DUE_DATE || filter_type == FilterItemType.SECTION) { 32 | _id = filter_type.to_string (); 33 | } 34 | 35 | return _id; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/Objects/Filters/Pinboard.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Pinboard : Objects.BaseObject { 23 | private static Pinboard? _instance; 24 | public static Pinboard get_default () { 25 | if (_instance == null) { 26 | _instance = new Pinboard (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | int? _pinboard_count = null; 33 | public int pinboard_count { 34 | get { 35 | if (_pinboard_count == null) { 36 | _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; 37 | } 38 | 39 | return _pinboard_count; 40 | } 41 | 42 | set { 43 | _pinboard_count = value; 44 | } 45 | } 46 | 47 | public signal void pinboard_count_updated (); 48 | 49 | construct { 50 | name = ("Pinboard"); 51 | keywords = _("Pinboard") + ";" + _("filters"); 52 | icon_name = "pin-symbolic"; 53 | view_id = FilterType.PINBOARD.to_string (); 54 | 55 | Services.Store.instance ().item_added.connect (() => { 56 | _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; 57 | pinboard_count_updated (); 58 | }); 59 | 60 | Services.Store.instance ().item_deleted.connect (() => { 61 | _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; 62 | pinboard_count_updated (); 63 | }); 64 | 65 | Services.Store.instance ().item_updated.connect (() => { 66 | _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; 67 | pinboard_count_updated (); 68 | }); 69 | 70 | Services.Store.instance ().item_archived.connect (() => { 71 | _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; 72 | pinboard_count_updated (); 73 | }); 74 | 75 | Services.Store.instance ().item_unarchived.connect (() => { 76 | _pinboard_count = Services.Store.instance ().get_items_pinned (false).size; 77 | pinboard_count_updated (); 78 | }); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /core/Objects/Filters/Priority.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Priority : Objects.BaseObject { 23 | public int priority { get; construct; } 24 | 25 | private static Priority? _instance; 26 | public static Priority get_default (int priority) { 27 | if (_instance == null) { 28 | _instance = new Priority (priority); 29 | } 30 | 31 | return _instance; 32 | } 33 | 34 | public Priority (int priority) { 35 | Object ( 36 | priority: priority 37 | ); 38 | } 39 | 40 | int? _count = null; 41 | public int count { 42 | get { 43 | if (_count == null) { 44 | _count = Services.Store.instance ().get_items_by_priority (priority, false).size; 45 | } 46 | 47 | return _count; 48 | } 49 | 50 | set { 51 | _count = value; 52 | } 53 | } 54 | 55 | public signal void count_updated (); 56 | 57 | construct { 58 | name = Util.get_default ().get_priority_title (priority); 59 | keywords = Util.get_default ().get_priority_keywords (priority) + ";" + _("filters"); 60 | view_id = "priority-%d".printf (priority); 61 | 62 | Services.Store.instance ().item_added.connect (() => { 63 | _count = Services.Store.instance ().get_items_by_priority (priority, false).size; 64 | count_updated (); 65 | }); 66 | 67 | Services.Store.instance ().item_deleted.connect (() => { 68 | _count = Services.Store.instance ().get_items_by_priority (priority, false).size; 69 | count_updated (); 70 | }); 71 | 72 | Services.Store.instance ().item_updated.connect (() => { 73 | _count = Services.Store.instance ().get_items_by_priority (priority, false).size; 74 | count_updated (); 75 | }); 76 | 77 | Services.Store.instance ().item_archived.connect (() => { 78 | _count = Services.Store.instance ().get_items_by_priority (priority, false).size; 79 | count_updated (); 80 | }); 81 | 82 | Services.Store.instance ().item_unarchived.connect (() => { 83 | _count = Services.Store.instance ().get_items_by_priority (priority, false).size; 84 | count_updated (); 85 | }); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /core/Objects/Filters/Repeating.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Repeating : Objects.BaseObject { 23 | private static Repeating? _instance; 24 | public static Repeating get_default () { 25 | if (_instance == null) { 26 | _instance = new Repeating (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | construct { 33 | name = _("Repeating"); 34 | keywords = "%s;%s".printf (_("repeating"), _("filters")); 35 | icon_name = "arrow-circular-top-right-symbolic"; 36 | view_id = "repeating-view"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/Objects/Filters/Scheduled.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Scheduled : Objects.BaseObject { 23 | private static Scheduled? _instance; 24 | public static Scheduled get_default () { 25 | if (_instance == null) { 26 | _instance = new Scheduled (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | int? _scheduled_count = null; 33 | public int scheduled_count { 34 | get { 35 | if (_scheduled_count == null) { 36 | _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; 37 | } 38 | 39 | return _scheduled_count; 40 | } 41 | 42 | set { 43 | _scheduled_count = value; 44 | } 45 | } 46 | 47 | public signal void scheduled_count_updated (); 48 | 49 | construct { 50 | name = _("Scheduled"); 51 | keywords = "%s;%s;%s".printf (_("scheduled"), _("upcoming"), _("filters")); 52 | icon_name = "month-symbolic"; 53 | view_id = FilterType.SCHEDULED.to_string (); 54 | 55 | Services.Store.instance ().item_added.connect (() => { 56 | _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; 57 | scheduled_count_updated (); 58 | }); 59 | 60 | Services.Store.instance ().item_deleted.connect (() => { 61 | _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; 62 | scheduled_count_updated (); 63 | }); 64 | 65 | Services.Store.instance ().item_updated.connect (() => { 66 | _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; 67 | scheduled_count_updated (); 68 | }); 69 | 70 | Services.Store.instance ().item_archived.connect (() => { 71 | _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; 72 | scheduled_count_updated (); 73 | }); 74 | 75 | Services.Store.instance ().item_unarchived.connect (() => { 76 | _scheduled_count = Services.Store.instance ().get_items_by_scheduled (false).size; 77 | scheduled_count_updated (); 78 | }); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /core/Objects/Filters/Tomorrow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Tomorrow : Objects.BaseObject { 23 | private static Tomorrow? _instance; 24 | public static Tomorrow get_default () { 25 | if (_instance == null) { 26 | _instance = new Tomorrow (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | construct { 33 | name = _("Tomorrow"); 34 | keywords = "%s;%s;%s".printf (_("tomorrow"), _("filters"), _("date")); 35 | icon_name = "today-calendar-symbolic"; 36 | view_id = "tomorrow-view"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/Objects/Filters/Unlabeled.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Filters.Unlabeled : Objects.BaseObject { 23 | private static Unlabeled? _instance; 24 | public static Unlabeled get_default () { 25 | if (_instance == null) { 26 | _instance = new Unlabeled (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | construct { 33 | name = _("Unlabeled"); 34 | keywords = "%s;%s;%s".printf (_("no label"), _("unlabeled"), _("filters")); 35 | icon_name = "tag-outline-remove-symbolic"; 36 | view_id = "unlabeled-view"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core/Objects/Promise.vala: -------------------------------------------------------------------------------- 1 | public class Services.Promise : Object { 2 | public signal void resolved (T value); 3 | public signal void rejected (string error); 4 | 5 | public void resolve (T result) { 6 | resolved (result); 7 | } 8 | 9 | public void reject (string error) { 10 | rejected (error); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core/Objects/Queue.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Objects.Queue : GLib.Object { 23 | public string uuid { get; set; default = ""; } 24 | public string object_id { get; set; default = ""; } 25 | public string temp_id { get; set; default = ""; } 26 | public string query { get; set; default = ""; } 27 | public string args { get; set; default = ""; } 28 | public string date_added { get; set; default = new GLib.DateTime.now_local ().to_string (); } 29 | } 30 | -------------------------------------------------------------------------------- /core/Services/CalDAV/Providers/ProviderBase.vala: -------------------------------------------------------------------------------- 1 | public class Services.CalDAV.Providers.Base { 2 | // vala-lint=naming-convention 3 | public virtual string LOGIN_REQUEST { get; set; default = ""; } 4 | 5 | // vala-lint=naming-convention 6 | public virtual string USER_DATA_REQUEST { get; set; default = ""; } 7 | 8 | public virtual string TASKLIST_REQUEST { get; set; default = ""; } 9 | 10 | public virtual string get_server_url (string server_url, string username, string password) { 11 | return ""; 12 | } 13 | 14 | public virtual string get_account_url (string server_url, string username) { 15 | return ""; 16 | } 17 | 18 | public virtual void set_user_data (GXml.DomDocument doc, Objects.Source source) { 19 | 20 | } 21 | 22 | public virtual string get_all_taskslist_url (string server_url, string username) { 23 | return ""; 24 | } 25 | 26 | public virtual Gee.ArrayList get_projects_by_doc (GXml.DomDocument doc, Objects.Source source) { 27 | return new Gee.ArrayList (); 28 | } 29 | 30 | public virtual bool is_vtodo_calendar (GXml.DomElement element) { 31 | return false; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /core/Services/Chrono/Chrono.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2024 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Chrono.Parse : GLib.Object { 23 | public string lang { get; construct; } 24 | 25 | private Gee.HashMap configurations; 26 | private Chrono.Configuration configuration; 27 | 28 | public Parse (string lang = "en") { 29 | Object ( 30 | lang: lang 31 | ); 32 | } 33 | 34 | construct { 35 | configurations = new Gee.HashMap (); 36 | configurations.set ("en", new Chrono.En.Parse ()); 37 | 38 | if (configurations.has_key (lang)) { 39 | configuration = configurations.get (lang); 40 | } else { 41 | configuration = new Chrono.En.Parse (); 42 | } 43 | } 44 | 45 | public void parse (string text) { 46 | Gee.ArrayList results = new Gee.ArrayList (); 47 | 48 | GLib.MatchInfo match; 49 | foreach (Chrono.AbstractParser parser in configuration.parsers) { 50 | if (parser.inner_pattern ().match_all (text, 0, out match)) { 51 | Chrono.ParsingResult result = parser.inner_extract (match); 52 | results.add (result); 53 | } 54 | } 55 | 56 | foreach (Chrono.ParsingResult result in results) { 57 | print ("Date: %s\n", result.datetime.to_string ()); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /core/Services/Chrono/Enum.vala: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/core/Services/Chrono/Enum.vala -------------------------------------------------------------------------------- /core/Services/Chrono/Locales/En/Constants.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2024 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ -------------------------------------------------------------------------------- /core/Services/Chrono/Locales/En/En.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2024 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Chrono.En.Parse : Chrono.Configuration { 23 | construct { 24 | parsers.add (new Chrono.En.ENCasualDateParser ()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core/Services/Chrono/Locales/En/Parsers/ENCasualDateParser.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2024 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Chrono.En.ENCasualDateParser : GLib.Object, Chrono.AbstractParser { 23 | GLib.Regex PATTERN = /(now|today|tonight|tomorrow|tmr|tmrw|yesterday|last\s*night)(?=\W|$)/; // vala-lint=naming-convention, space-before-paren 24 | 25 | public GLib.Regex inner_pattern () { 26 | return PATTERN; 27 | } 28 | 29 | public Chrono.ParsingResult inner_extract (GLib.MatchInfo match) { 30 | var component = new Chrono.ParsingResult (); 31 | var lowerText = match.fetch_all () [0].down (); // vala-lint=naming-convention 32 | component.text = lowerText; 33 | 34 | switch (lowerText) { 35 | case "now": 36 | component.datetime = new GLib.DateTime.now_local (); 37 | break; 38 | case "today": 39 | component.datetime = new GLib.DateTime.now_local (); 40 | break; 41 | case "tonight": 42 | component.datetime = new GLib.DateTime.now_local (); 43 | break; 44 | case "tomorrow": 45 | case "tmr": 46 | case "tmrw": 47 | component.datetime = new GLib.DateTime.now_local ().add_days (1); 48 | break; 49 | case "yesterday": 50 | component.datetime = new GLib.DateTime.now_local ().add_days (-1); 51 | break; 52 | } 53 | 54 | return component; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/Services/Chrono/Types.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2024 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Chrono.Configuration : GLib.Object { 23 | public Gee.ArrayList parsers { get; set; default = new Gee.ArrayList (); } 24 | } 25 | 26 | public interface Chrono.AbstractParser : GLib.Object { 27 | public abstract GLib.Regex inner_pattern (); 28 | public abstract Chrono.ParsingResult inner_extract (GLib.MatchInfo match); 29 | } 30 | 31 | public class Chrono.ParsingResult : GLib.Object { 32 | public int index { get; set; default = 0; } 33 | public string text { get; set; default = ""; } 34 | public GLib.DateTime? datetime { get; set; default = null; } 35 | } 36 | -------------------------------------------------------------------------------- /core/Services/Settings.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Services.Settings : GLib.Object { 23 | public GLib.Settings settings; 24 | 25 | private static Settings? _instance; 26 | public static Settings get_default () { 27 | if (_instance == null) { 28 | _instance = new Settings (); 29 | } 30 | 31 | return _instance; 32 | } 33 | 34 | public Settings () { 35 | settings = new GLib.Settings ("io.github.alainm23.planify"); 36 | } 37 | 38 | public void reset_settings () { 39 | var schema_source = GLib.SettingsSchemaSource.get_default (); 40 | SettingsSchema schema = schema_source.lookup ("io.github.alainm23.planify", true); 41 | 42 | foreach (string key in schema.list_keys ()) { 43 | Services.Settings.get_default ().settings.reset (key); 44 | } 45 | } 46 | 47 | public NewTaskPosition get_new_task_position () { 48 | var value = Services.Settings.get_default ().settings.get_enum ("new-tasks-position"); 49 | return value == 0 ? NewTaskPosition.TOP : NewTaskPosition.BOTTOM; 50 | } 51 | 52 | public bool get_boolean (string key) { 53 | return settings.get_boolean (key); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /core/Widgets/Calendar/CalendarDay.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.Calendar.CalendarDay : Adw.Bin { 23 | int _day; 24 | public int day { 25 | set { 26 | _day = value; 27 | button.label = _day.to_string (); 28 | } 29 | get { 30 | return _day; 31 | } 32 | } 33 | 34 | private Gtk.Button button; 35 | public signal void day_selected (); 36 | 37 | public CalendarDay () { 38 | Object ( 39 | halign: Gtk.Align.CENTER, 40 | valign: Gtk.Align.CENTER 41 | ); 42 | } 43 | 44 | construct { 45 | button = new Gtk.Button () { 46 | css_classes = { "flat", "calendar-day" } 47 | }; 48 | 49 | child = button; 50 | 51 | button.clicked.connect (() => { 52 | day_selected (); 53 | button.add_css_class ("selected"); 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /core/Widgets/Calendar/CalendarWeek.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.Calendar.CalendarWeek : Gtk.Box { 23 | private Gtk.Label[] day_labels; 24 | 25 | construct { 26 | orientation = Gtk.Orientation.HORIZONTAL; 27 | homogeneous = true; 28 | valign = Gtk.Align.CENTER; 29 | margin_start = 6; 30 | margin_top = 6; 31 | margin_bottom = 6; 32 | margin_end = 6; 33 | 34 | day_labels = new Gtk.Label[] { 35 | new Gtk.Label (_("Su")), 36 | new Gtk.Label (_("Mo")), 37 | new Gtk.Label (_("Tu")), 38 | new Gtk.Label (_("We")), 39 | new Gtk.Label (_("Th")), 40 | new Gtk.Label (_("Fr")), 41 | new Gtk.Label (_("Sa")) 42 | }; 43 | 44 | foreach (var label in day_labels) { 45 | label.add_css_class ("dim-label"); 46 | append (label); 47 | } 48 | 49 | update (); 50 | } 51 | 52 | public void update () { 53 | for (Gtk.Widget? child = get_first_child (); child != null;) { 54 | Gtk.Widget? next = child.get_next_sibling (); 55 | remove (child); 56 | child = next; 57 | } 58 | 59 | var start_week = Services.Settings.get_default ().settings.get_enum ("start-week"); 60 | var rotated_labels = rotate_left (day_labels, start_week); 61 | 62 | foreach (var label in rotated_labels) { 63 | append (label); 64 | } 65 | } 66 | 67 | private Gtk.Label[] rotate_left (Gtk.Label[] array, int positions) { 68 | positions = (positions % array.length + array.length) % array.length; 69 | var rotated = new Gtk.Label[array.length]; 70 | 71 | for (int i = 0; i < array.length; i++) { 72 | rotated[i] = array[(i + positions) % array.length]; 73 | } 74 | 75 | return rotated; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /core/Widgets/ContextMenu/MenuSeparator.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.ContextMenu.MenuSeparator : Adw.Bin { 23 | construct { 24 | child = new Gtk.Separator (Gtk.Orientation.HORIZONTAL) { 25 | margin_top = 6, 26 | margin_bottom = 6, 27 | hexpand = true 28 | }; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core/Widgets/IconColorProject.vala: -------------------------------------------------------------------------------- 1 | public class Widgets.IconColorProject : Adw.Bin { 2 | public Objects.Project project { get; set; } 3 | public int pixel_size { get; construct; } 4 | 5 | private Widgets.CircularProgressBar circular_progress_bar; 6 | private Gtk.Label emoji_label; 7 | private Gtk.Stack color_emoji_stack; 8 | private Gtk.Stack stack; 9 | 10 | public IconColorProject (int pixel_size) { 11 | Object ( 12 | pixel_size: pixel_size 13 | ); 14 | } 15 | 16 | ~IconColorProject () { 17 | print ("Destroying Widgets.IconColorProject\n"); 18 | } 19 | 20 | construct { 21 | circular_progress_bar = new Widgets.CircularProgressBar (pixel_size); 22 | circular_progress_bar.percentage = 100; 23 | 24 | emoji_label = new Gtk.Label (null) { 25 | halign = Gtk.Align.CENTER 26 | }; 27 | 28 | color_emoji_stack = new Gtk.Stack () { 29 | transition_type = Gtk.StackTransitionType.CROSSFADE 30 | }; 31 | 32 | color_emoji_stack.add_named (circular_progress_bar, "color"); 33 | color_emoji_stack.add_named (emoji_label, "emoji"); 34 | 35 | var inbox_icon = new Gtk.Image.from_icon_name ("mailbox-symbolic") { 36 | pixel_size = 16 37 | }; 38 | 39 | stack = new Gtk.Stack () { 40 | transition_type = Gtk.StackTransitionType.CROSSFADE 41 | }; 42 | 43 | stack.add_named (color_emoji_stack, "color-emoji"); 44 | stack.add_named (inbox_icon, "inbox"); 45 | 46 | child = stack; 47 | 48 | ulong signal_id = notify["project"].connect (() => { 49 | update_request (); 50 | }); 51 | 52 | destroy.connect (() => { 53 | disconnect (signal_id); 54 | }); 55 | } 56 | 57 | public void update_request () { 58 | stack.visible_child_name = project.is_inbox_project ? "inbox" : "color-emoji"; 59 | color_emoji_stack.visible_child_name = project.icon_style == ProjectIconStyle.PROGRESS ? "color" : "emoji"; 60 | circular_progress_bar.color = project.color; 61 | circular_progress_bar.percentage = project.percentage; 62 | emoji_label.label = project.emoji; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /core/Widgets/ItemLabelChild.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.ItemLabelChild : Gtk.FlowBoxChild { 23 | public Objects.Label label { get; construct; } 24 | 25 | private Gtk.Label name_label; 26 | private Gtk.Revealer main_revealer; 27 | 28 | public ItemLabelChild (Objects.Label label) { 29 | Object ( 30 | label: label, 31 | halign: Gtk.Align.START 32 | ); 33 | } 34 | 35 | construct { 36 | add_css_class ("item-label-child"); 37 | 38 | name_label = new Gtk.Label (null); 39 | name_label.valign = Gtk.Align.CENTER; 40 | name_label.add_css_class ("caption"); 41 | 42 | var labelrow_grid = new Adw.Bin () { 43 | child = name_label 44 | }; 45 | 46 | main_revealer = new Gtk.Revealer () { 47 | transition_type = Gtk.RevealerTransitionType.SLIDE_RIGHT, 48 | child = labelrow_grid 49 | }; 50 | 51 | child = main_revealer; 52 | update_request (); 53 | 54 | Timeout.add (main_revealer.transition_duration, () => { 55 | main_revealer.reveal_child = true; 56 | return GLib.Source.REMOVE; 57 | }); 58 | 59 | label.deleted.connect (() => { 60 | hide_destroy (); 61 | }); 62 | 63 | label.updated.connect (update_request); 64 | } 65 | 66 | public void update_request () { 67 | name_label.label = label.name; 68 | Util.get_default ().set_widget_color (Util.get_default ().get_color (label.color), this); 69 | } 70 | 71 | public void hide_destroy () { 72 | main_revealer.reveal_child = false; 73 | Timeout.add (main_revealer.transition_duration, () => { 74 | ((Gtk.FlowBox) parent).remove (this); 75 | return GLib.Source.REMOVE; 76 | }); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /core/Widgets/LabelPicker/LabelPicker.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.LabelPicker.LabelPicker : Gtk.Popover { 23 | private Widgets.LabelsPickerCore picker; 24 | 25 | public Gee.ArrayList labels { 26 | set { 27 | picker.labels = value; 28 | } 29 | } 30 | 31 | public Objects.Source source { 32 | set { 33 | picker.source = value; 34 | } 35 | } 36 | 37 | public Gee.HashMap picked { 38 | get { 39 | return picker.picked; 40 | } 41 | } 42 | 43 | 44 | public bool search_visible { 45 | set { 46 | picker.search_visible = value; 47 | } 48 | } 49 | 50 | public LabelPicker () { 51 | Object ( 52 | has_arrow: false, 53 | position: Gtk.PositionType.TOP, 54 | width_request: 275, 55 | height_request: 300 56 | ); 57 | } 58 | 59 | ~LabelPicker () { 60 | print ("Destroying Widgets.LabelPicker.LabelPicker\n"); 61 | } 62 | 63 | construct { 64 | css_classes = { "popover-contents" }; 65 | 66 | picker = new Widgets.LabelsPickerCore (LabelPickerType.FILTER_AND_CREATE) { 67 | margin_top = 12 68 | }; 69 | 70 | child = picker; 71 | 72 | picker.close.connect (() => { 73 | popdown (); 74 | }); 75 | } 76 | 77 | public void reset () { 78 | picker.reset (); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /core/Widgets/LabelPicker/LabelRow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.LabelPicker.LabelRow : Gtk.ListBoxRow { 23 | public Objects.Label label { get; construct; } 24 | 25 | public bool active { 26 | set { 27 | checked_button.active = value; 28 | } 29 | } 30 | 31 | private Gtk.CheckButton checked_button; 32 | public signal void checked_toggled (Objects.Label label, bool active); 33 | 34 | public LabelRow (Objects.Label label) { 35 | Object ( 36 | label: label 37 | ); 38 | } 39 | 40 | ~LabelRow () { 41 | print ("Destroying Widgets.LabelPicker.LabelRow\n"); 42 | } 43 | 44 | construct { 45 | add_css_class ("border-radius-6"); 46 | 47 | checked_button = new Gtk.CheckButton () { 48 | valign = Gtk.Align.CENTER, 49 | css_classes = { "checkbutton-label" } 50 | }; 51 | 52 | var color_grid = new Gtk.Grid () { 53 | width_request = 3, 54 | height_request = 16, 55 | margin_top = 0, 56 | valign = Gtk.Align.CENTER, 57 | css_classes = { "event-bar" } 58 | }; 59 | 60 | Util.get_default ().set_widget_color (Util.get_default ().get_color (label.color), color_grid); 61 | 62 | var content_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); 63 | 64 | content_box.append (checked_button); 65 | content_box.append (color_grid); 66 | content_box.append (new Gtk.Label (label.name) { 67 | valign = Gtk.Align.CENTER, 68 | }); 69 | 70 | child = content_box; 71 | 72 | var checked_button_gesture = new Gtk.GestureClick (); 73 | content_box.add_controller (checked_button_gesture); 74 | ulong signal_id = checked_button_gesture.pressed.connect (() => { 75 | checked_button_gesture.set_state (Gtk.EventSequenceState.CLAIMED); 76 | update_checked_toggled (); 77 | }); 78 | 79 | destroy.connect (() => { 80 | checked_button_gesture.disconnect (signal_id); 81 | }); 82 | 83 | activate.connect (() => { 84 | update_checked_toggled (); 85 | }); 86 | } 87 | 88 | public void update_checked_toggled () { 89 | checked_button.active = !checked_button.active; 90 | checked_toggled (label, checked_button.active); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /core/Widgets/Markdown/Color.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Based on Folio 4 | * https://github.com/toolstack/Folio 5 | */ 6 | 7 | namespace Color { 8 | public struct HSL { 9 | public float h; 10 | public float s; 11 | public float l; 12 | } 13 | 14 | public struct RGB { 15 | public float r; 16 | public float g; 17 | public float b; 18 | 19 | public inline RGB (float r = 0, float g = 0, float b = 0) { 20 | this.r = r; 21 | this.g = g; 22 | this.b = b; 23 | } 24 | 25 | public inline RGB times (RGB rgb) { 26 | return RGB (r * rgb.r, g * rgb.g, b * rgb.b); 27 | } 28 | 29 | public inline RGB multiply (float x) { 30 | return RGB (r * x, g * x, b * x); 31 | } 32 | 33 | public inline RGB plus (RGB rgb) { 34 | return RGB (r + rgb.r, g + rgb.g, b + rgb.b); 35 | } 36 | } 37 | 38 | public inline HSL rgb_to_hsl (RGB rgb, out HSL hsl = null) { 39 | hsl = HSL (); 40 | float s, v; 41 | Gtk.rgb_to_hsv (rgb.r, rgb.g, rgb.b, out hsl.h, out s, out v); 42 | hsl.l = v - v * s / 2; 43 | float m = float.min (hsl.l, 1 - hsl.l); 44 | hsl.s = (m != 0) ? (v - hsl.l) / m : 0; 45 | return hsl; 46 | } 47 | 48 | public inline RGB hsl_to_rgb (HSL hsl, out RGB rgb = null) { 49 | rgb = RGB (); 50 | float v = hsl.s * float.min (hsl.l, 1 - hsl.l) + hsl.l; 51 | float s = (v != 0) ? 2 - 2 * hsl.l / v : 0; 52 | Gtk.hsv_to_rgb (hsl.h, s, v, out rgb.r, out rgb.g, out rgb.b); 53 | return rgb; 54 | } 55 | 56 | public inline RGB RGBA_to_rgb (Gdk.RGBA rgba, out RGB rgb = null) { 57 | rgb = RGB (); 58 | rgb.r = rgba.red; 59 | rgb.g = rgba.green; 60 | rgb.b = rgba.blue; 61 | return rgb; 62 | } 63 | 64 | public inline Gdk.RGBA rgb_to_RGBA (RGB rgb, out Gdk.RGBA rgba = null) { 65 | rgba = Gdk.RGBA (); 66 | rgba.red = rgb.r; 67 | rgba.green = rgb.g; 68 | rgba.blue = rgb.b; 69 | rgba.alpha = 1; 70 | return rgba; 71 | } 72 | 73 | public inline float get_luminance (float r, float g, float b) { 74 | return Math.sqrtf (0.299f * r * r + 0.587f * g * g + 0.114f * b * b); 75 | } 76 | 77 | public inline float get_luminance_photometric (float r, float g, float b) { 78 | return 0.2126f * r + 0.7152f * g + 0.0722f; 79 | } 80 | 81 | public inline float get_luminance_digital (float r, float g, float b) { 82 | return 0.299f * r + 0.587f * g + 0.114f; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /core/Widgets/Markdown/MarkdownBuffer.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Based on Folio 4 | * https://github.com/toolstack/Folio 5 | */ 6 | 7 | public class Widgets.Markdown.Buffer : GtkSource.Buffer { 8 | 9 | public Buffer (string? text = null) { 10 | Object (); 11 | this.text = text; 12 | } 13 | 14 | public string get_all_text () { 15 | Gtk.TextIter start, end; 16 | get_start_iter (out start); 17 | get_end_iter (out end); 18 | return get_text (start, end, true); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core/Widgets/PinButton.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.PinButton : Gtk.Button { 23 | private Gtk.Image pinned_image; 24 | 25 | public signal void changed (); 26 | 27 | public PinButton () { 28 | Object ( 29 | valign: Gtk.Align.CENTER, 30 | halign: Gtk.Align.CENTER, 31 | tooltip_text: _("Pin") 32 | ); 33 | } 34 | 35 | construct { 36 | add_css_class ("flat"); 37 | 38 | pinned_image = new Gtk.Image.from_icon_name ("pin-symbolic"); 39 | child = pinned_image; 40 | 41 | clicked.connect (() => { 42 | changed (); 43 | }); 44 | } 45 | 46 | public void update_from_item (Objects.Item item) { 47 | update_request (item.pinned); 48 | } 49 | 50 | public void update_request (bool pinned) { 51 | if (pinned) { 52 | pinned_image.add_css_class ("pinboard-color"); 53 | } else { 54 | pinned_image.remove_css_class ("pinboard-color"); 55 | } 56 | } 57 | 58 | public void reset () { 59 | pinned_image.css_classes = { }; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /core/Widgets/ProjectPicker/SectionPickerRow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.ProjectPicker.SectionRow : Gtk.ListBoxRow { 23 | public Objects.Section section { get; construct; } 24 | 25 | public SectionRow (Objects.Section section) { 26 | Object ( 27 | section: section 28 | ); 29 | } 30 | 31 | public SectionRow.for_no_section () { 32 | Objects.Section _section = new Objects.Section (); 33 | _section.name = _("No Section"); 34 | 35 | Object ( 36 | section: _section 37 | ); 38 | } 39 | 40 | construct { 41 | css_classes = { "row" }; 42 | 43 | var name_label = new Gtk.Label (section.name) { 44 | halign = Gtk.Align.START, 45 | margin_start = 3 46 | }; 47 | 48 | var container = new Adw.Bin () { 49 | child = name_label, 50 | margin_top = 6, 51 | margin_bottom = 6, 52 | margin_start = 6, 53 | margin_end = 6 54 | }; 55 | 56 | child = container; 57 | } 58 | } -------------------------------------------------------------------------------- /core/planify.deps: -------------------------------------------------------------------------------- 1 | glib-2.0 2 | gio-2.0 3 | gee-0.8 4 | gtk4 5 | sqlite3 6 | libadwaita-1 7 | webkitgtk-6.0 8 | granite-7 9 | json-glib-1.0 10 | libecal-2.0 11 | libedataserver-1.2 12 | libical-glib 13 | gtksourceview-5 14 | gxml-0.20 -------------------------------------------------------------------------------- /data/icons/hicolor/symbolic/apps/io.github.alainm23.planify-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /data/icons/meson.build: -------------------------------------------------------------------------------- 1 | install_subdir( 2 | 'hicolor', 3 | install_dir: get_option('datadir') / 'icons', 4 | ) 5 | -------------------------------------------------------------------------------- /data/io.github.alainm23.planify.desktop.in.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | # Translators: Keep this string as `Planify` 3 | Name=Planify 4 | Comment=Never worry about forgetting things again 5 | Categories=Utility;Office;ProjectManagement;Calendar; 6 | Exec=@exec@ 7 | Icon=@icon@ 8 | Terminal=false 9 | Type=Application 10 | StartupNotify=true 11 | X-GNOME-Gettext-Domain=planify 12 | X-GNOME-UsesNotifications=true 13 | # Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! 14 | Keywords=development;task;tasks;project;todo;event;events;calendar;todoist; 15 | # Translators: Do NOT translate or transliterate this text (these are enum types)! 16 | X-Purism-FormFactor=Workstation;Mobile; 17 | -------------------------------------------------------------------------------- /data/io.github.alainm23.planify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/io.github.alainm23.planify.png -------------------------------------------------------------------------------- /data/io.github.alainm23.planify.service.in: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=@app_id@ 3 | Exec=@bindir@/@app_id@ --gapplication-service 4 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | ########### 2 | # Desktop # 3 | ########### 4 | 5 | desktop_conf = configuration_data() 6 | desktop_conf.set('exec', application_id) 7 | desktop_conf.set('icon', application_id) 8 | desktop_file = i18n.merge_file( 9 | input: configure_file( 10 | input: files('io.github.alainm23.planify.desktop.in.in'), 11 | output: 'io.github.alainm23.planify.desktop.in', 12 | configuration: desktop_conf, 13 | ), 14 | output: '@0@.desktop'.format(application_id), 15 | type: 'desktop', 16 | po_dir: join_paths(meson.source_root(), 'po'), 17 | install: true, 18 | install_dir: get_option('datadir') / 'applications', 19 | ) 20 | 21 | desktop_utils = find_program('desktop-file-validate', required: false) 22 | if desktop_utils.found() 23 | test('Validate desktop file', desktop_utils, args: [desktop_file]) 24 | endif 25 | 26 | 27 | ############# 28 | # AppStream # 29 | ############# 30 | 31 | appdata_conf = configuration_data() 32 | appdata_conf.set('appid', application_id) 33 | appstream_file = i18n.merge_file( 34 | input: configure_file( 35 | input: files('io.github.alainm23.planify.appdata.xml.in.in'), 36 | output: 'io.github.alainm23.planify.appdata.xml.in', 37 | configuration: appdata_conf 38 | ), 39 | output: '@0@.appdata.xml'.format(application_id), 40 | po_dir: join_paths(meson.source_root(), 'po'), 41 | install: true, 42 | install_dir: get_option('datadir') / 'appdata', 43 | ) 44 | 45 | install_data('io.github.alainm23.planify.gschema.xml', 46 | install_dir: get_option('datadir') / 'glib-2.0/schemas', 47 | ) 48 | 49 | compile_schemas = find_program('glib-compile-schemas', required: false) 50 | if compile_schemas.found() 51 | test('Validate schema file', compile_schemas, 52 | args: ['--strict', '--dry-run', meson.current_source_dir()] 53 | ) 54 | endif 55 | 56 | install_data('markdown.xml', 57 | install_dir: get_option('datadir') / 'gtksourceview-5' / 'styles' 58 | ) 59 | install_data('markdown_dark.xml', 60 | install_dir: get_option('datadir') / 'gtksourceview-5' / 'styles' 61 | ) 62 | install_data('markdownpp.lang', 63 | install_dir: get_option('datadir') / 'gtksourceview-5' / 'language-specs' 64 | ) 65 | 66 | # service_conf = configuration_data() 67 | # service_conf.set('appid', application_id) 68 | # service_conf.set('bindir', bindir) 69 | # configure_file( 70 | # input: 'io.github.alainm23.planify.service.in', 71 | # output: '@0@.service'.format(application_id), 72 | # configuration: service_conf, 73 | # install_dir: datadir / 'dbus-1' / 'services' 74 | # ) 75 | 76 | subdir('icons') -------------------------------------------------------------------------------- /data/resources/icons/alarm-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/arrow-circular-top-right-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/arrow-turn-down-right-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/arrow3-down-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/arrow3-right-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/carousel-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 37 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /data/resources/icons/chat-bubble-text-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/check-round-outline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/check-round-outline-whole-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/checkmark-small-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/clipboard-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/clock-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/cloud-outline-thick-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/color-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/cross-large-circle-filled-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/cross-large-circle-outline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/delay-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/resources/icons/dock-left-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/dock-right-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/edit-find-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/edit-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/external-link-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/eye-open-negative-filled-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/flag-outline-thick-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/folder-download-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/funnel-outline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/go-next-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/go-up-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/grid-large-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/heart-outline-thick-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/info-outline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/list-drag-handle-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/list-large-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/list-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/mail-attachment-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/mail-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/mailbox-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/menu-large-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/month-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/navigate-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/paper-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/permissions-generic-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/pin-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/resources/icons/playlist-repeat-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/plus-large-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/process-error-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 36 | 38 | 39 | 41 | image/svg+xml 42 | 44 | 45 | 46 | 47 | 48 | 50 | 55 | 56 | -------------------------------------------------------------------------------- /data/resources/icons/reaction-add2-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/rescue-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/rotation-edit-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 36 | 40 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /data/resources/icons/settings-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/share-alt-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/resources/icons/shield-safe-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/shoe-box-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/size-vertically-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/star-outline-thick-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/step-out-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/tabs-stack-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/tag-outline-add-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/tag-outline-remove-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 36 | 40 | 44 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /data/resources/icons/tag-outline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/text-justify-left-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /data/resources/icons/today-calendar-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/update-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 36 | 38 | 40 | 43 | 46 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /data/resources/icons/user-trash-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/resources/icons/vertical-arrows-long-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/view-columns-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /data/resources/icons/view-list-ordered-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/view-more-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/icons/view-sort-descending-rtl-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /data/resources/icons/work-week-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/resources/screenshot/screenshot-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/screenshot/screenshot-01.png -------------------------------------------------------------------------------- /data/resources/screenshot/screenshot-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/screenshot/screenshot-02.png -------------------------------------------------------------------------------- /data/resources/screenshot/screenshot-03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/screenshot/screenshot-03.png -------------------------------------------------------------------------------- /data/resources/screenshot/screenshot-04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/screenshot/screenshot-04.png -------------------------------------------------------------------------------- /data/resources/sounds/success.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/sounds/success.ogg -------------------------------------------------------------------------------- /data/resources/stylesheet/animations.css: -------------------------------------------------------------------------------- 1 | @keyframes spin-loading { 2 | from {-gtk-icon-transform: rotate(0deg);} 3 | to {-gtk-icon-transform: rotate(360deg);} 4 | } 5 | 6 | @keyframes fancy-turn { 7 | 0% { -gtk-icon-transform: rotate(0deg); } 8 | 25% { -gtk-icon-transform: rotate(-30deg); } 9 | 50% { -gtk-icon-transform: rotate(0deg); } 10 | 75% { -gtk-icon-transform: rotate(30deg); } 11 | 100% { -gtk-icon-transform: rotate(0deg); } 12 | } 13 | 14 | @keyframes add-animation { 15 | 0% { -gtk-icon-transform: rotate(0deg); } 16 | 100% { -gtk-icon-transform: rotate(180deg); } 17 | } 18 | 19 | @keyframes breathing { 20 | 0% { 21 | -gtk-icon-transform: scale(0.9); 22 | } 23 | 24 | 25% { 25 | -gtk-icon-transform: scale(1); 26 | } 27 | 28 | 60% { 29 | -gtk-icon-transform: scale(0.9); 30 | } 31 | 32 | 100% { 33 | -gtk-icon-transform: scale(0.9); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /data/resources/stylesheet/calendar.css: -------------------------------------------------------------------------------- 1 | .calendar-day { 2 | padding: 3px 6px; 3 | border-radius: 9px; 4 | } 5 | 6 | .calendar-day.selected { 7 | background-color: #3584e4; 8 | color: #fafafa; 9 | } 10 | 11 | .calendar-day.today { 12 | color: #33d17a; 13 | font-weight: bold; 14 | } -------------------------------------------------------------------------------- /data/resources/stylesheet/index.css: -------------------------------------------------------------------------------- 1 | @import url("stylesheet/variables.css"); 2 | @import url("stylesheet/animations.css"); 3 | @import url("stylesheet/calendar.css"); 4 | @import url("stylesheet/stylesheet.css"); 5 | @import url("stylesheet/sidebar.css"); 6 | @import url("stylesheet/typography.css"); -------------------------------------------------------------------------------- /data/resources/stylesheet/sidebar.css: -------------------------------------------------------------------------------- 1 | .filter-pane-row { 2 | box-shadow: none; 3 | padding: 6px; 4 | border-radius: 9px; 5 | transition: all 225ms ease-in-out; 6 | background-color: alpha(@colorAccent, 0.15); 7 | color: @colorAccent; 8 | } 9 | 10 | .filter-pane-row.animation image { 11 | animation: fancy-turn 0.7s ease-in-out; 12 | } 13 | 14 | .filter-pane-row:hover, 15 | .filter-pane-row.selected { 16 | box-shadow: 0px 0px 3px 1px @colorAccent; 17 | } 18 | 19 | .sidebar-row { 20 | padding: 0; 21 | transition: all 220ms ease-in-out; 22 | background-color: transparent; 23 | } 24 | 25 | .sidebar-row:selected, 26 | .sidebar-row:hover { 27 | outline: none; 28 | } 29 | 30 | .separator-lines row:not(:first-child) { 31 | border-top: 1px solid @item_border_color; 32 | } 33 | 34 | .selectable-item { 35 | padding: 0; 36 | border-radius: 9px; 37 | transition: all 220ms ease-in-out; 38 | background-color: transparent; 39 | outline: none; 40 | } 41 | 42 | .selectable-item:hover { 43 | background-color: alpha(@shade_color, 0.65); 44 | outline: none; 45 | } 46 | 47 | .selectable-item.selected { 48 | background-color: @shade_color; 49 | border-radius: 9px; 50 | } 51 | 52 | .drop-css { 53 | border-radius: 9px; 54 | transition: all 220ms ease-in-out; 55 | } 56 | 57 | .sidebar { 58 | background: @sidebar_bg_color; 59 | } 60 | 61 | .sidebar-card { 62 | box-shadow: none; 63 | border: 1px solid @item_border_color; 64 | } 65 | 66 | .gift-animation, 67 | .gift-animation image { 68 | animation-name: fancy-turn; 69 | animation-duration: 1s; 70 | animation-timing-function: ease-out; 71 | animation-iteration-count: infinite; 72 | animation-direction: normal; 73 | animation-delay: 0s; 74 | animation-fill-mode: none; 75 | animation-play-state: running; 76 | } 77 | -------------------------------------------------------------------------------- /data/resources/stylesheet/typography.css: -------------------------------------------------------------------------------- 1 | .error-message { 2 | font-size: 12px; 3 | border-radius: 6px; 4 | } 5 | -------------------------------------------------------------------------------- /data/resources/stylesheet/variables.css: -------------------------------------------------------------------------------- 1 | @define-color window_bg_color #fafafa; 2 | @define-color popover_bg_color #ffffff; 3 | @define-color sidebar_bg_color #f2f2f2; 4 | @define-color item_border_color @borders; 5 | @define-color upcoming_bg_color #ededef; 6 | @define-color upcoming_fg_color shade(#ededef, 0); 7 | @define-color selected_color alpha(@shade_color, 0.65); -------------------------------------------------------------------------------- /data/resources/videos/dnd-order.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/videos/dnd-order.webm -------------------------------------------------------------------------------- /data/resources/videos/magic-button.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/videos/magic-button.webm -------------------------------------------------------------------------------- /data/resources/videos/subprojects.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/data/resources/videos/subprojects.webm -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('tracing', type: 'boolean', value: false, description: 'add extra debugging information') 2 | option('profile', type: 'combo', choices: ['default', 'development'], value: 'default') -------------------------------------------------------------------------------- /planify.doap: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | Planify 9 | Forget about forgetting things 10 | 11 | 12 | 13 | Vala 14 | GTK 4 15 | Libadwaita 16 | 17 | 18 | 19 | Alain 20 | 21 | 22 | 23 | 24 | alainm23 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | es 2 | fr 3 | pt_BR 4 | tr 5 | zh_CN 6 | ru 7 | pt_PT 8 | de 9 | nl 10 | hi 11 | bg 12 | ko 13 | sk_SK 14 | ka 15 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext(meson.project_name(), 2 | args: '--directory=' + meson.source_root(), 3 | preset: 'glib' 4 | ) -------------------------------------------------------------------------------- /quick-add/App.vala: -------------------------------------------------------------------------------- 1 | public class QuickAdd : Adw.Application { 2 | public MainWindow main_window; 3 | 4 | public static QuickAdd _instance = null; 5 | public static QuickAdd instance { 6 | get { 7 | if (_instance == null) { 8 | _instance = new QuickAdd (); 9 | } 10 | return _instance; 11 | } 12 | } 13 | 14 | construct { 15 | application_id = "io.github.alainm23.planify.quick-add"; 16 | flags |= ApplicationFlags.FLAGS_NONE; 17 | 18 | Intl.setlocale (LocaleCategory.ALL, ""); 19 | string langpack_dir = Path.build_filename (Build.INSTALL_PREFIX, "share", "locale"); 20 | Intl.bindtextdomain (Build.GETTEXT_PACKAGE, langpack_dir); 21 | Intl.bind_textdomain_codeset (Build.GETTEXT_PACKAGE, "UTF-8"); 22 | Intl.textdomain (Build.GETTEXT_PACKAGE); 23 | } 24 | 25 | protected override void activate () { 26 | main_window = new MainWindow (this); 27 | main_window.show (); 28 | 29 | var quit_action = new SimpleAction ("quit", null); 30 | 31 | add_action (quit_action); 32 | set_accels_for_action ("app.quit", {"Escape"}); 33 | 34 | quit_action.activate.connect (() => { 35 | if (main_window != null && main_window.can_close) { 36 | main_window.hide (); 37 | 38 | Timeout.add (500, () => { 39 | main_window.destroy (); 40 | return GLib.Source.REMOVE; 41 | }); 42 | } 43 | }); 44 | 45 | var provider = new Gtk.CssProvider (); 46 | provider.load_from_resource ("/io/github/alainm23/planify/index.css"); 47 | Gtk.StyleContext.add_provider_for_display ( 48 | Gdk.Display.get_default (), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION 49 | ); 50 | 51 | Util.get_default ().update_theme (); 52 | } 53 | 54 | public static int main (string[] args) { 55 | QuickAdd app = QuickAdd.instance; 56 | return app.run (args); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /quick-add/MainWindow.vala: -------------------------------------------------------------------------------- 1 | public class MainWindow : Adw.ApplicationWindow { 2 | private Layouts.QuickAdd quick_add_widget; 3 | 4 | public bool can_close { get; set; default = true; } 5 | public MainWindow (QuickAdd application) { 6 | Object ( 7 | application: application, 8 | icon_name: "io.github.alainm23.planify", 9 | title: _("Planify - Quick Add"), 10 | resizable: false, 11 | width_request: 600, 12 | halign: Gtk.Align.START 13 | ); 14 | } 15 | 16 | static construct { 17 | weak Gtk.IconTheme default_theme = Gtk.IconTheme.get_for_display (Gdk.Display.get_default ()); 18 | default_theme.add_resource_path ("/io/github/alainm23/planify/"); 19 | } 20 | 21 | construct { 22 | Services.Database.get_default ().init_database (); 23 | 24 | quick_add_widget = new Layouts.QuickAdd (true); 25 | set_content (quick_add_widget); 26 | 27 | quick_add_widget.hide_destroy.connect (hide_destroy); 28 | quick_add_widget.send_interface_id.connect (send_interface_id); 29 | quick_add_widget.add_item_db.connect ((add_item_db)); 30 | quick_add_widget.parent_can_close.connect ((active) => { 31 | Timeout.add (250, () => { 32 | can_close = active; 33 | return GLib.Source.REMOVE; 34 | }); 35 | }); 36 | } 37 | 38 | private void add_item_db (Objects.Item item, Gee.ArrayList reminders) { 39 | Services.Store.instance ().insert_item (item); 40 | 41 | if (reminders.size > 0) { 42 | quick_add_widget.is_loading = true; 43 | 44 | foreach (Objects.Reminder reminder in reminders) { 45 | item.add_reminder (reminder); 46 | } 47 | } 48 | 49 | if (Services.Settings.get_default ().get_boolean ("automatic-reminders-enabled") && item.has_time) { 50 | var reminder = new Objects.Reminder (); 51 | reminder.mm_offset = Util.get_reminders_mm_offset (); 52 | reminder.reminder_type = ReminderType.RELATIVE; 53 | item.add_reminder (reminder); 54 | } 55 | 56 | send_interface_id (item.id); 57 | quick_add_widget.added_successfully (); 58 | } 59 | 60 | private void send_interface_id (string id) { 61 | try { 62 | DBusClient.get_default ().interface.add_item (id); 63 | } catch (Error e) { 64 | debug (e.message); 65 | } 66 | } 67 | 68 | public void hide_destroy () { 69 | if (!can_close) { 70 | return; 71 | } 72 | 73 | hide (); 74 | 75 | Timeout.add (500, () => { 76 | destroy (); 77 | return GLib.Source.REMOVE; 78 | }); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /quick-add/Services/DBusClient.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2019 Alain M. (https://github.com/alainm23/planner) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | [DBus (name = "io.github.alainm23.planify")] 23 | public interface DBusClientInterface : Object { 24 | public abstract void add_item (string id) throws Error; 25 | } 26 | 27 | public class DBusClient : Object { 28 | public DBusClientInterface? interface = null; 29 | 30 | private static GLib.Once instance; 31 | public static unowned DBusClient get_default () { 32 | return instance.once (() => { return new DBusClient (); }); 33 | } 34 | 35 | construct { 36 | try { 37 | interface = Bus.get_proxy_sync ( 38 | BusType.SESSION, 39 | "io.github.alainm23.planify", 40 | "/io/github/alainm23/planify"); 41 | } catch (IOError e) { 42 | error ("Monitor Indicator DBus: %s\n", e.message); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /quick-add/meson.build: -------------------------------------------------------------------------------- 1 | quick_find_sources = files( 2 | 'App.vala', 3 | 'MainWindow.vala', 4 | 'Services/DBusClient.vala', 5 | ) 6 | 7 | executable( 8 | 'io.github.alainm23.planify.quick-add', 9 | quick_find_sources, 10 | asresources, 11 | config_file, 12 | dependencies: deps, 13 | install: true 14 | ) -------------------------------------------------------------------------------- /search-provider/io.github.alainm23.planify.SearchProvider.ini.in: -------------------------------------------------------------------------------- 1 | [Shell Search Provider] 2 | DesktopId=@appid@.desktop 3 | BusName=@appid@.SearchProvider 4 | ObjectPath=@path@/SearchProvider 5 | Version=2 -------------------------------------------------------------------------------- /search-provider/io.github.alainm23.planify.SearchProvider.service.in: -------------------------------------------------------------------------------- 1 | [D-BUS Service] 2 | Name=@appid@.SearchProvider 3 | Exec=@libexecdir@/@appid@-search-provider -------------------------------------------------------------------------------- /search-provider/main.vala: -------------------------------------------------------------------------------- 1 | // This file is part of Highscore. License: GPL-3.0-or-later 2 | 3 | int main (string[] args) { 4 | Intl.bindtextdomain (Build.GETTEXT_PACKAGE, Build.GNOMELOCALEDIR); 5 | Intl.bind_textdomain_codeset (Build.GETTEXT_PACKAGE, "UTF-8"); 6 | Intl.textdomain (Build.GETTEXT_PACKAGE); 7 | 8 | var app = new Planify.SearchProvider (); 9 | 10 | return app.run (args); 11 | } 12 | -------------------------------------------------------------------------------- /search-provider/meson.build: -------------------------------------------------------------------------------- 1 | search_provider_c_args = [ 2 | '-DGETTEXT_PACKAGE="' + meson.project_name () + '"', 3 | '-DG_LOG_DOMAIN="PlanifySearchProvider"', 4 | ] 5 | 6 | search_provider_sources = [ 7 | 'main.vala', 8 | 'search-provider.vala' 9 | ] 10 | 11 | search_provider_deps = [ 12 | gio_dep, 13 | gtk_dep, 14 | sqlite3_dep, 15 | ] 16 | 17 | executable ( 18 | 'io.github.alainmh23.planify-search-provider', 19 | search_provider_sources, 20 | config_file, 21 | dependencies: search_provider_deps, 22 | c_args: search_provider_c_args, 23 | install: true, 24 | install_dir: libexecdir 25 | ) 26 | 27 | search_provider_conf = configuration_data() 28 | search_provider_conf.set('appid', application_id) 29 | search_provider_conf.set('path', application_path) 30 | configure_file( 31 | configuration: search_provider_conf, 32 | input: 'io.github.alainm23.planify.SearchProvider.ini.in', 33 | install_dir: datadir / 'gnome-shell' / 'search-providers', 34 | install: true, 35 | output: '@0@.SearchProvider.ini'.format(application_id) 36 | ) 37 | 38 | search_provider_dbus_conf = configuration_data() 39 | search_provider_dbus_conf.set('appid', application_id) 40 | search_provider_dbus_conf.set('libexecdir', libexecdir) 41 | configure_file ( 42 | input: 'io.github.alainm23.planify.SearchProvider.service.in', 43 | output: '@0@.SearchProvider.service'.format(application_id), 44 | configuration: search_provider_dbus_conf, 45 | install: true, 46 | install_dir: datadir / 'dbus-1' / 'services' 47 | ) 48 | -------------------------------------------------------------------------------- /search-provider/search-provider.vala: -------------------------------------------------------------------------------- 1 | // This file is part of Highscore. License: GPL-3.0+. 2 | 3 | [DBus (name = "org.gnome.Shell.SearchProvider2")] 4 | public class Planify.SearchProvider : Gtk.Application { 5 | internal SearchProvider () { 6 | Object ( 7 | application_id: Build.APPLICATION_ID + ".SearchProvider", 8 | flags: ApplicationFlags.IS_SERVICE, 9 | inactivity_timeout: 10000 10 | ); 11 | } 12 | 13 | construct { 14 | 15 | } 16 | 17 | protected override bool dbus_register (DBusConnection connection, string object_path) { 18 | try { 19 | connection.register_object (object_path, this); 20 | } catch (IOError e) { 21 | warning ("Could not register search provider: %s", e.message); 22 | quit (); 23 | } 24 | 25 | return true; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Dialogs/ErrorDialog.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Dialogs.ErrorDialog : Adw.Dialog { 23 | public int error_code { get; construct; } 24 | public string error_message { get; construct; } 25 | 26 | public ErrorDialog (int error_code, string error_message) { 27 | Object ( 28 | error_code: error_code, 29 | error_message: error_message, 30 | content_width: 375, 31 | content_height: 450 32 | ); 33 | } 34 | 35 | ~ErrorDialog () { 36 | print ("Destroying Dialogs.ErrorDialog\n"); 37 | } 38 | 39 | construct { 40 | var error_view = new Widgets.ErrorView () { 41 | error_code = error_code, 42 | error_message = error_message, 43 | }; 44 | 45 | child = error_view; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Dialogs/LabelPicker.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Dialogs.LabelPicker : Adw.Dialog { 23 | private Widgets.LabelsPickerCore picker; 24 | 25 | public Gee.ArrayList labels { 26 | set { 27 | picker.labels = value; 28 | } 29 | } 30 | 31 | public signal void labels_changed (Gee.HashMap labels); 32 | 33 | public LabelPicker () { 34 | Object ( 35 | title: _("Labels"), 36 | content_width: 320, 37 | content_height: 450 38 | ); 39 | } 40 | 41 | ~LabelPicker () { 42 | print ("Destroying Dialogs.LabelPicker\n"); 43 | } 44 | 45 | construct { 46 | var headerbar = new Adw.HeaderBar (); 47 | headerbar.add_css_class ("flat"); 48 | 49 | picker = new Widgets.LabelsPickerCore (LabelPickerType.FILTER_ONLY); 50 | 51 | var button = new Widgets.LoadingButton (LoadingButtonType.LABEL, _("Filter")) { 52 | margin_top = 12, 53 | margin_start = 12, 54 | margin_end = 12, 55 | margin_bottom = 12, 56 | css_classes = { "suggested-action" } 57 | }; 58 | 59 | var toolbar_view = new Adw.ToolbarView (); 60 | toolbar_view.add_top_bar (headerbar); 61 | toolbar_view.add_bottom_bar (button); 62 | toolbar_view.content = picker; 63 | 64 | child = toolbar_view; 65 | Services.EventBus.get_default ().disconnect_typing_accel (); 66 | 67 | button.clicked.connect (() => { 68 | labels_changed (picker.picked); 69 | hide_destroy (); 70 | }); 71 | 72 | picker.close.connect (() => { 73 | labels_changed (picker.picked); 74 | hide_destroy (); 75 | }); 76 | 77 | var destroy_controller = new Gtk.EventControllerKey (); 78 | add_controller (destroy_controller); 79 | destroy_controller.key_released.connect ((keyval, keycode, state) => { 80 | if (keyval == 65307) { 81 | hide_destroy (); 82 | } 83 | }); 84 | 85 | closed.connect (() => { 86 | Services.EventBus.get_default ().connect_typing_accel (); 87 | }); 88 | } 89 | 90 | public void add_labels (Objects.Source source) { 91 | picker.source = source; 92 | } 93 | 94 | public void add_labels_list (Gee.ArrayList labels_list) { 95 | picker.add_labels_list (labels_list); 96 | } 97 | 98 | public void hide_destroy () { 99 | close (); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Dialogs/ManageProjects.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Dialogs.ManageProjects : Adw.Dialog { 23 | private Gtk.ListBox listbox; 24 | private Widgets.ScrolledWindow scrolled_window; 25 | 26 | public ManageProjects () { 27 | Object ( 28 | title: _("Archived Projects"), 29 | content_width: 320, 30 | content_height: 420 31 | ); 32 | } 33 | 34 | ~ManageProjects () { 35 | print ("Destroying Dialogs.ManageProjects\n"); 36 | } 37 | 38 | construct { 39 | var headerbar = new Adw.HeaderBar (); 40 | headerbar.add_css_class ("flat"); 41 | 42 | listbox = new Gtk.ListBox () { 43 | hexpand = true, 44 | valign = START, 45 | css_classes = { "listbox-background" } 46 | }; 47 | 48 | var listbox_card = new Adw.Bin () { 49 | margin_start = 12, 50 | margin_end = 12, 51 | margin_bottom = 6, 52 | margin_top = 3, 53 | css_classes = { "card" }, 54 | child = listbox, 55 | valign = START 56 | }; 57 | 58 | var content_box = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); 59 | content_box.append (listbox_card); 60 | 61 | scrolled_window = new Widgets.ScrolledWindow (content_box); 62 | 63 | var toolbar_view = new Adw.ToolbarView (); 64 | toolbar_view.add_top_bar (headerbar); 65 | toolbar_view.content = scrolled_window; 66 | 67 | child = toolbar_view; 68 | Services.EventBus.get_default ().disconnect_typing_accel (); 69 | 70 | foreach (Objects.Project project in Services.Store.instance ().get_all_projects_archived ()) { 71 | if (project.is_archived) { 72 | listbox.append (new Dialogs.ProjectPicker.ProjectPickerRow (project, "menu")); 73 | } 74 | } 75 | 76 | Services.Store.instance ().project_unarchived.connect (() => { 77 | if (Services.Store.instance ().get_all_projects_archived ().size <= 0) { 78 | hide_destroy (); 79 | } 80 | }); 81 | 82 | closed.connect (() => { 83 | Services.EventBus.get_default ().connect_typing_accel (); 84 | }); 85 | } 86 | 87 | private void hide_destroy () { 88 | close (); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Dialogs/Preferences/SettingsHeader.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Dialogs.Preferences.SettingsHeader : Adw.Bin { 23 | public bool show_back_button { get; construct; } 24 | 25 | public string title { 26 | set { 27 | title_label.label = value; 28 | } 29 | } 30 | 31 | private Gtk.Label title_label; 32 | 33 | public signal void done_activated (); 34 | public signal void back_activated (); 35 | 36 | public SettingsHeader (string title, bool show_back_button = true) { 37 | Object ( 38 | title: title, 39 | show_back_button: show_back_button, 40 | hexpand: true 41 | ); 42 | } 43 | 44 | ~SettingsHeader () { 45 | print ("Destroying Dialogs.Preferences.SettingsHeader\n"); 46 | } 47 | 48 | construct { 49 | var back_button = new Gtk.Button.from_icon_name ("go-previous-symbolic") { 50 | valign = Gtk.Align.CENTER, 51 | tooltip_text = _("Back"), 52 | css_classes = { "flat" } 53 | }; 54 | 55 | title_label = new Gtk.Label (null); 56 | title_label.add_css_class ("title"); 57 | 58 | var headerbar = new Gtk.HeaderBar () { 59 | title_widget = title_label, 60 | show_title_buttons = true, 61 | hexpand = true 62 | }; 63 | 64 | headerbar.add_css_class ("flat"); 65 | 66 | if (show_back_button) { 67 | headerbar.pack_start (back_button); 68 | } 69 | 70 | child = headerbar; 71 | 72 | back_button.clicked.connect (() => { 73 | back_activated (); 74 | }); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Dialogs/ProjectPicker/ProjectPickerSourceRow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Dialogs.ProjectPicker.ProjectPickerSourceRow : Gtk.ListBoxRow { 23 | public Objects.Source source { get; construct; } 24 | 25 | private Layouts.HeaderItem group; 26 | 27 | public ProjectPickerSourceRow (Objects.Source source) { 28 | Object ( 29 | source: source 30 | ); 31 | } 32 | 33 | ~ProjectPickerSourceRow () { 34 | print ("Destroying Dialogs.ProjectPicker.ProjectPickerSourceRow\n"); 35 | } 36 | 37 | construct { 38 | css_classes = { "no-selectable", "no-padding" }; 39 | 40 | group = new Layouts.HeaderItem (source.display_name) { 41 | card = true, 42 | reveal = true 43 | }; 44 | 45 | child = group; 46 | 47 | add_projects (); 48 | } 49 | 50 | private void add_projects () { 51 | foreach (Objects.Project project in Services.Store.instance ().get_projects_by_source (source.id)) { 52 | if (project.is_archived || project.is_inbox_project || project.is_deck) { 53 | continue ; 54 | } 55 | 56 | group.add_child (new Dialogs.ProjectPicker.ProjectPickerRow (project)); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /src/Layouts/ItemBase.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public abstract class Layouts.ItemBase : Gtk.ListBoxRow { 23 | public Objects.Item item { get; construct; } 24 | 25 | public string update_id { get; set; default = Util.get_default ().generate_id (); } 26 | 27 | public abstract void update_request (); 28 | public abstract void hide_destroy (); 29 | public abstract void delete_request (bool undo = true); 30 | public abstract void select_row (bool active); 31 | public abstract void checked_toggled (bool active, uint? time = null); 32 | } 33 | -------------------------------------------------------------------------------- /src/Layouts/ProjectContainerRow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Layouts.ProjectContainerRow : Gtk.ListBoxRow { 23 | public Objects.Project project { get; construct; } 24 | public bool show_subprojects { get; construct; } 25 | public bool drag_n_drop { get; construct; } 26 | 27 | private Gtk.Revealer main_revealer; 28 | 29 | public ProjectContainerRow (Objects.Project project, bool show_subprojects = true, bool drag_n_drop = true) { 30 | Object ( 31 | project: project, 32 | show_subprojects: show_subprojects, 33 | drag_n_drop: drag_n_drop 34 | ); 35 | } 36 | 37 | ~ProjectContainerRow () { 38 | print ("Destroying Layouts.ProjectContainerRow\n"); 39 | } 40 | 41 | construct { 42 | css_classes = { "no-selectable", "no-padding" }; 43 | 44 | var listbox = new Gtk.ListBox () { 45 | css_classes = { "listbox-background" } 46 | }; 47 | 48 | listbox.append (new Layouts.ProjectRow (project, drag_n_drop)); 49 | 50 | main_revealer = new Gtk.Revealer () { 51 | transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN, 52 | child = listbox 53 | }; 54 | 55 | child = main_revealer; 56 | 57 | Timeout.add (main_revealer.transition_duration, () => { 58 | main_revealer.reveal_child = true; 59 | return GLib.Source.REMOVE; 60 | }); 61 | } 62 | 63 | public void hide_destroy () { 64 | main_revealer.reveal_child = false; 65 | Timeout.add (main_revealer.transition_duration, () => { 66 | ((Gtk.ListBox) parent).remove (this); 67 | return GLib.Source.REMOVE; 68 | }); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Services/CalendarEvents/DateIterator.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2018 elementary, Inc. (https://elementary.io) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA. 18 | * 19 | * Authored by: Corentin Noël 20 | */ 21 | 22 | public class CalendarEventsUtil.DateIterator : Object, Gee.Traversable, Gee.Iterator { 23 | public GLib.DateTime current { get; construct set; } 24 | public CalendarEventsUtil.DateRange range { get; construct; } 25 | 26 | // Required by Gee.Iterator 27 | public bool valid { 28 | get { 29 | return true; 30 | } 31 | } 32 | 33 | // Required by Gee.Iterator 34 | public bool read_only { 35 | get { 36 | return false; 37 | } 38 | } 39 | 40 | public DateIterator (CalendarEventsUtil.DateRange range) { 41 | Object ( 42 | range: range, 43 | current: range.first_dt.add_days (-1) 44 | ); 45 | } 46 | 47 | public bool @foreach (Gee.ForallFunc f) { 48 | var element = range.first_dt; 49 | 50 | while (element.compare (range.last_dt) < 0) { 51 | if (f (element) == false) { 52 | return false; 53 | } 54 | 55 | element = element.add_days (1); 56 | } 57 | 58 | return true; 59 | } 60 | 61 | public bool next () { 62 | if (!has_next ()) { 63 | return false; 64 | } 65 | 66 | current = this.current.add_days (1); 67 | 68 | return true; 69 | } 70 | 71 | public bool has_next () { 72 | return current.compare (range.last_dt) < 0; 73 | } 74 | 75 | public new GLib.DateTime get () { 76 | return current; 77 | } 78 | 79 | public void remove () { 80 | assert_not_reached (); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Services/CalendarEvents/DateRange.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011-2019 elementary, Inc. (https://elementary.io) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 2 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA. 18 | * 19 | * Authored by: Corentin Noël 20 | */ 21 | 22 | /* Represents date range from 'first' to 'last' inclusive */ 23 | public class CalendarEventsUtil.DateRange : Object, Gee.Traversable, Gee.Iterable { 24 | public GLib.DateTime first_dt { get; construct; } 25 | public GLib.DateTime last_dt { get; construct; } 26 | 27 | public bool @foreach (Gee.ForallFunc f) { 28 | foreach (var date in this) { 29 | if (f (date) == false) { 30 | return false; 31 | } 32 | } 33 | 34 | return true; 35 | } 36 | 37 | public DateRange (GLib.DateTime first, GLib.DateTime last) { 38 | Object ( 39 | first_dt: first, 40 | last_dt: last 41 | ); 42 | } 43 | 44 | public bool equals (DateRange other) { 45 | return (first_dt == other.first_dt && last_dt == other.last_dt); 46 | } 47 | 48 | public Gee.Iterator iterator () { 49 | return new DateIterator (this); 50 | } 51 | 52 | public Gee.List to_list () { 53 | var list = new Gee.ArrayList ((Gee.EqualDataFunc? )datetime_equal_func); 54 | 55 | foreach (var date in this) { 56 | list.add (date); 57 | } 58 | 59 | return list; 60 | } 61 | 62 | /* Returns true if 'a' and 'b' are the same GLib.DateTime */ 63 | private bool datetime_equal_func (GLib.DateTime a, GLib.DateTime b) { 64 | return a.equal (b); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Services/DBusServer.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | [DBus (name = "io.github.alainm23.planify")] 23 | public class Services.DBusServer : Object { 24 | private const string DBUS_NAME = "io.github.alainm23.planify"; 25 | private const string DBUS_PATH = "/io/github/alainm23/planify"; 26 | 27 | private static GLib.Once instance; 28 | 29 | public static unowned DBusServer get_default () { 30 | return instance.once (() => { return new DBusServer (); }); 31 | } 32 | 33 | public signal void item_added (string id); 34 | 35 | construct { 36 | Bus.own_name ( 37 | BusType.SESSION, 38 | DBUS_NAME, 39 | BusNameOwnerFlags.NONE, 40 | (connection) => on_bus_aquired (connection), 41 | () => { }, 42 | null 43 | ); 44 | } 45 | 46 | public void add_item (string id) throws IOError, DBusError { 47 | item_added (id); 48 | } 49 | 50 | private void on_bus_aquired (DBusConnection conn) { 51 | try { 52 | conn.register_object (DBUS_PATH, get_default ()); 53 | } catch (Error e) { 54 | error (e.message); 55 | } 56 | } 57 | } 58 | 59 | [DBus (name = "io.github.alainm23.planify")] 60 | public errordomain DBusServerError { 61 | SOME_ERROR 62 | } 63 | -------------------------------------------------------------------------------- /src/Services/TimeMonitor.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Services.TimeMonitor : Object { 23 | private static TimeMonitor? _instance; 24 | public static TimeMonitor get_default () { 25 | if (_instance == null) { 26 | _instance = new TimeMonitor (); 27 | } 28 | 29 | return _instance; 30 | } 31 | 32 | private DateTime last_registered_date; 33 | 34 | public void init_timeout () { 35 | last_registered_date = new DateTime.now_local (); 36 | uint interval = calculate_seconds_until_midnight (); 37 | 38 | Timeout.add_seconds (interval, on_timeout); 39 | } 40 | 41 | private bool on_timeout () { 42 | DateTime now = new DateTime.now_local (); 43 | 44 | if (now.get_day_of_month () != last_registered_date.get_day_of_month () || 45 | now.get_month () != last_registered_date.get_month () || 46 | now.get_year () != last_registered_date.get_year ()) { 47 | 48 | Services.EventBus.get_default ().day_changed (); 49 | Services.Notification.get_default ().regresh (); 50 | 51 | last_registered_date = now; 52 | uint interval = calculate_seconds_until_midnight (); 53 | 54 | Timeout.add_seconds (interval, on_timeout); 55 | } else { 56 | uint interval = calculate_seconds_until_midnight (); 57 | Timeout.add_seconds (interval, on_timeout); 58 | } 59 | 60 | return false; 61 | } 62 | 63 | private uint calculate_seconds_until_midnight () { 64 | DateTime now = new DateTime.now_local (); 65 | 66 | uint value = (24 * 60 * 60) - 67 | (now.get_hour () * 60 * 60 + now.get_minute () * 60 + now.get_second ()); 68 | 69 | return value; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/Services/TodayTaskMonitor.vala: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alainm23/planify/13a167a9c538a94e752595cbe19aee165c27af0f/src/Services/TodayTaskMonitor.vala -------------------------------------------------------------------------------- /src/Views/Label/Labels.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Views.Labels : Adw.Bin { 23 | 24 | private Gtk.ListBox sources_listbox; 25 | public Gee.HashMap sources_hashmap = new Gee.HashMap (); 26 | 27 | 28 | construct { 29 | var headerbar = new Layouts.HeaderBar (); 30 | headerbar.title = _("Labels"); 31 | 32 | sources_listbox = new Gtk.ListBox () { 33 | hexpand = true, 34 | valign = Gtk.Align.START, 35 | css_classes = { "listbox-background" } 36 | }; 37 | 38 | var content = new Gtk.Box (Gtk.Orientation.VERTICAL, 12) { 39 | hexpand = true, 40 | vexpand = true, 41 | margin_start = 12, 42 | margin_end = 12 43 | }; 44 | 45 | content.append (sources_listbox); 46 | 47 | var content_clamp = new Adw.Clamp () { 48 | maximum_size = 1024, 49 | tightening_threshold = 800, 50 | margin_start = 12, 51 | margin_end = 12, 52 | margin_bottom = 64, 53 | child = content 54 | }; 55 | 56 | var scrolled_window = new Gtk.ScrolledWindow () { 57 | hscrollbar_policy = Gtk.PolicyType.NEVER, 58 | hexpand = true, 59 | vexpand = true, 60 | child = content_clamp 61 | }; 62 | 63 | var toolbar_view = new Adw.ToolbarView (); 64 | toolbar_view.add_top_bar (headerbar); 65 | toolbar_view.content = scrolled_window; 66 | 67 | child = toolbar_view; 68 | 69 | foreach (Objects.Source source in Services.Store.instance ().sources) { 70 | add_source_row (source); 71 | } 72 | 73 | Services.Store.instance ().source_deleted.connect ((source) => { 74 | if (sources_hashmap.has_key (source.id)) { 75 | sources_hashmap.get (source.id).hide_destroy (); 76 | } 77 | }); 78 | 79 | Services.Store.instance ().source_added.connect (add_source_row); 80 | } 81 | 82 | private void add_source_row (Objects.Source source) { 83 | if (!sources_hashmap.has_key (source.id)) { 84 | sources_hashmap[source.id] = new Views.LabelSourceRow (source); 85 | sources_listbox.append (sources_hashmap[source.id]); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Widgets/ColorPickerRow.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.ColorPickerRow : Gtk.Grid { 23 | public string color { get; set; } 24 | 25 | public signal void color_changed (string color); 26 | 27 | private Gee.HashMap colors_hashmap; 28 | 29 | public ColorPickerRow () { 30 | Object ( 31 | 32 | ); 33 | } 34 | 35 | construct { 36 | colors_hashmap = new Gee.HashMap (); 37 | 38 | var colors_flowbox = new Gtk.FlowBox () { 39 | column_spacing = 6, 40 | row_spacing = 6, 41 | max_children_per_line = 10, 42 | homogeneous = true, 43 | margin_top = 9, 44 | margin_bottom = 9, 45 | margin_start = 9, 46 | margin_end = 9, 47 | vexpand = true, 48 | hexpand = true, 49 | selection_mode = Gtk.SelectionMode.NONE 50 | }; 51 | 52 | var radio = new Gtk.CheckButton (); 53 | foreach (var entry in Util.get_default ().get_colors ().entries) { 54 | if (entry.key.has_prefix ("#")) { 55 | continue; 56 | } 57 | 58 | Gtk.CheckButton color_radio = new Gtk.CheckButton () { 59 | valign = Gtk.Align.CENTER, 60 | halign = Gtk.Align.CENTER, 61 | tooltip_text = Util.get_default ().get_color_name (entry.key), 62 | name = entry.key, 63 | css_classes = { "color-radio" }, 64 | group = radio 65 | }; 66 | 67 | Util.get_default ().set_widget_color (Util.get_default ().get_color (entry.key), color_radio); 68 | colors_hashmap [entry.key] = color_radio; 69 | colors_flowbox.append (colors_hashmap [entry.key]); 70 | 71 | color_radio.toggled.connect (() => { 72 | color = entry.key; 73 | color_changed (color); 74 | }); 75 | } 76 | 77 | attach (colors_flowbox, 0, 0); 78 | 79 | notify["color"].connect (() => { 80 | if (colors_hashmap.has_key (color)) { 81 | colors_hashmap [color].active = true; 82 | } 83 | }); 84 | 85 | colors_flowbox.child_activated.connect ((child) => { 86 | color = child.child.name; 87 | color_changed (color); 88 | }); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Widgets/SyncButton.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright © 2023 Alain M. (https://github.com/alainm23/planify) 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public 6 | * License as published by the Free Software Foundation; either 7 | * version 3 of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | * General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public 15 | * License along with this program; if not, write to the 16 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 | * Boston, MA 02110-1301 USA 18 | * 19 | * Authored by: Alain M. 20 | */ 21 | 22 | public class Widgets.SyncButton : Adw.Bin { 23 | private Gtk.Revealer main_revealer; 24 | private Gtk.Stack stack; 25 | private Gtk.Button sync_button; 26 | 27 | public signal void clicked (); 28 | 29 | public bool reveal_child { 30 | set { 31 | main_revealer.reveal_child = value; 32 | } 33 | } 34 | 35 | construct { 36 | sync_button = new Gtk.Button.from_icon_name ("update-symbolic") { 37 | valign = Gtk.Align.CENTER, 38 | css_classes = { "flat", "header-item-button", "dim-label" } 39 | }; 40 | 41 | var error_button = new Gtk.Button.from_icon_name ("dialog-warning-symbolic") { 42 | valign = Gtk.Align.CENTER, 43 | css_classes = { "flat", "header-item-button", "dim-label" } 44 | }; 45 | 46 | stack = new Gtk.Stack () { 47 | transition_type = Gtk.StackTransitionType.CROSSFADE 48 | }; 49 | 50 | stack.add_named (sync_button, "sync"); 51 | stack.add_named (error_button, "error"); 52 | 53 | main_revealer = new Gtk.Revealer () { 54 | transition_type = Gtk.RevealerTransitionType.CROSSFADE, 55 | child = stack 56 | }; 57 | 58 | child = main_revealer; 59 | 60 | Timeout.add (main_revealer.transition_duration, () => { 61 | return GLib.Source.REMOVE; 62 | }); 63 | 64 | sync_button.clicked.connect (() => { 65 | clicked (); 66 | }); 67 | 68 | error_button.clicked.connect (() => { 69 | clicked (); 70 | }); 71 | } 72 | 73 | public void sync_started () { 74 | stack.visible_child_name = "sync"; 75 | tooltip_markup = ""; 76 | sync_button.add_css_class ("is_loading"); 77 | } 78 | 79 | public void sync_finished () { 80 | sync_button.remove_css_class ("is_loading"); 81 | } 82 | 83 | public void sync_failed () { 84 | sync_button.remove_css_class ("is_loading"); 85 | stack.visible_child_name = "error"; 86 | tooltip_markup = "%s\n%s".printf (_("Failed to connect to server"), _("It looks like the server is unreachable,\nare you connected to the internet?\nAny changes you make while disconnected\nwill be synchronized when you reconnect.")); // vala-lint=line-length 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /subprojects/gxml-0.20.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory=gxml-0.20 3 | url=https://gitlab.gnome.org/GNOME/gxml.git 4 | revision=gxml-0.20 5 | 6 | [provide] 7 | gxml-0.20 = libgxml_dep 8 | --------------------------------------------------------------------------------