├── .github ├── FUNDING.yml └── workflows │ └── flatpak.yml ├── .gitignore ├── AUTHORS ├── ISSUE_TEMPLATE.md ├── LICENSE ├── README.md ├── data ├── assets │ └── texture.png ├── icon.png ├── icons │ ├── hicolor │ │ └── scalable │ │ │ └── actions │ │ │ ├── document-edit-symbolic.svg │ │ │ ├── document-send-symbolic.svg │ │ │ ├── font-x-generic-symbolic.svg │ │ │ ├── format-text-bold-symbolic.svg │ │ │ ├── format-text-italic-symbolic.svg │ │ │ ├── format-text-strikethrough-symbolic.svg │ │ │ ├── format-text-underline-symbolic.svg │ │ │ ├── image-round-symbolic.svg │ │ │ ├── list-select-symbolic.svg │ │ │ ├── notebook-add-symbolic.svg │ │ │ ├── notebook-config-symbolic.svg │ │ │ ├── notebook-symbolic.svg │ │ │ ├── text-x-generic-filled-symbolic.svg │ │ │ ├── user-trash-filled-symbolic.svg │ │ │ ├── view-grid-symbolic.svg │ │ │ ├── view-list-bullet-symbolic.svg │ │ │ └── view-pin-symbolic.svg │ ├── io.github.lainsce.Notejot.Devel.svg │ ├── io.github.lainsce.Notejot.svg │ └── meson.build ├── io.github.lainsce.Notejot.Source.svg ├── io.github.lainsce.Notejot.desktop.in ├── io.github.lainsce.Notejot.gresource.xml ├── io.github.lainsce.Notejot.gschema.xml ├── io.github.lainsce.Notejot.metainfo.xml.in ├── meson.build ├── shot-dark.png ├── shot.png ├── style.css └── ui │ ├── edit_notebooks.ui │ ├── main_menu.ui │ ├── main_window.ui │ ├── move_to_dialog.ui │ ├── note_theme.ui │ ├── notebooklistview.ui │ ├── notebookmainlistview.ui │ ├── notebookmainrow.ui │ ├── notebookmainrowcontent.ui │ ├── notebookmovelistview.ui │ ├── notebookmoverow.ui │ ├── notebookrow.ui │ ├── notebookrowcontent.ui │ ├── notecontentview.ui │ ├── notelistview.ui │ ├── noterow.ui │ ├── noterowcontent.ui │ ├── trashcontentview.ui │ ├── trashlistview.ui │ ├── trashrow.ui │ └── trashrowcontent.ui ├── io.github.lainsce.Notejot.Devel.json ├── io.github.lainsce.Notejot.doap ├── meson.build ├── meson_options.txt ├── po ├── LINGUAS ├── POTFILES ├── README.md ├── ca.po ├── cs.po ├── da.po ├── de.po ├── es.po ├── fr.po ├── gl.po ├── hr.po ├── io.github.lainsce.Notejot.pot ├── it.po ├── ja.po ├── lt.po ├── meson.build ├── nl.po ├── oc.po ├── pl.po ├── pt.po ├── pt_BR.po ├── ru.po ├── sv.po └── tr.po ├── src ├── Application.vala ├── Config.vapi ├── MainWindow.vala ├── Models │ ├── Note.vala │ ├── Notebook.vala │ └── Trash.vala ├── Repositories │ ├── NoteRepository.vala │ ├── NotebookRepository.vala │ └── TrashRepository.vala ├── Services │ ├── MigrationManager.vala │ ├── SettingsManager.vala │ └── StyleManager.vala ├── Utils │ ├── FileUtils.vala │ ├── FormatUtils.vala │ ├── MiscUtils.vala │ ├── NoteSorter.vala │ ├── ObservableList.vala │ └── TimeUtils.vala ├── ViewModels │ ├── NoteViewModel.vala │ ├── NotebookViewModel.vala │ └── TrashViewModel.vala ├── Views │ ├── NoteContentView.vala │ ├── NoteListView.vala │ ├── NotebookListView.vala │ ├── NotebookMainListView.vala │ ├── NotebookMoveListView.vala │ ├── TrashContentView.vala │ ├── TrashListView.vala │ └── View.vala └── Widgets │ ├── EditNotebookDialog.vala │ ├── MainMenu.vala │ ├── MoveToDialog.vala │ ├── NoteRowContent.vala │ ├── NoteTheme.vala │ ├── NotebookMainRowContent.vala │ ├── NotebookRowContent.vala │ └── TrashRowContent.vala └── subprojects └── blueprint-compiler.wrap /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | patreon: lainsce 4 | github: lainsce 5 | -------------------------------------------------------------------------------- /.github/workflows/flatpak.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: [main] 4 | pull_request: 5 | name: CI 6 | jobs: 7 | flatpak: 8 | name: Flatpak 9 | runs-on: ubuntu-latest 10 | container: 11 | image: bilelmoussaoui/flatpak-github-actions:gnome-43 12 | options: --privileged 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v4 16 | with: 17 | bundle: io.github.lainsce.Notejot.Devel.flatpak 18 | manifest-path: io.github.lainsce.Notejot.Devel.json 19 | repository-name: catalogue-unstable 20 | repository-url: https://repo.tauos.co/catalogue-unstable.flatpakrepo 21 | run-tests: true 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | _build/ 2 | build/ 3 | ~* 4 | *~ 5 | .flatpak-builder/ 6 | .flatpak/flatpak-builder/* 7 | .flatpak/ 8 | .flatpak/* 9 | .vscode/ 10 | .vscode/* 11 | app-dir/ 12 | debian/com.github.lainsce.notejot.debhelper.log 13 | debian/com.github.lainsce.notejot.substvars 14 | debian/com.github.lainsce.notejot/ 15 | debian/debhelper-build-stamp 16 | debian/files 17 | obj-x86_64-linux-gnu/ 18 | builddir/ 19 | subprojects/blueprint-compiler -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Lains 2 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Hello! If you found an error in this app, follow this template: 2 | 3 | * Use a descriptive title 4 | * Describe the issue 5 | * State what version you're using 6 | * Take a screenshot of the problem, then use the Markdown property for it: 7 | `![any_name_here](url_here)` 8 | * If the problem needs it, show me a video of the problem with Screenkey running in the background. 9 | 10 | 11 | Thanks! 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Notejot 4 | 5 | Stupidly simple notes app. 6 | 7 | ### 8 | 9 | [![Please do not theme this app](https://stopthemingmy.app/badge.svg)](https://stopthemingmy.app) 10 | [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0) 11 | 12 | ![Light screenshot](data/shot.png#gh-light-mode-only) 13 | ![Dark screenshot](data/shot-dark.png#gh-dark-mode-only) 14 | 15 |

Download on Flathub

16 | 17 | ## 💝 Donations 18 | 19 | Would you like to support the development of this app to new heights? 20 | Then become a GitHub Sponsor or check my Patreon, buttons in the sidebar. 21 | 22 | ## 🛠️ Dependencies 23 | 24 | Please make sure you have these dependencies first before building. 25 | 26 | ```bash 27 | gtk4 28 | libjson-glib 29 | libgee-0.8 30 | libadwaita-1 31 | meson 32 | vala 33 | ``` 34 | 35 | ## 🏗️ Building 36 | 37 | Simply clone this repo, then: 38 | 39 | ```bash 40 | meson _build --prefix=/usr && cd _build 41 | sudo ninja install 42 | ``` 43 | 44 | ## 🗂️ Notes Storage 45 | Notes are stored in `~/.var/app/io.github.lainsce.Notejot/` 46 | -------------------------------------------------------------------------------- /data/assets/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lainsce/notejot/c0ee94863077155a6ab0514fa13cbe086a22d076/data/assets/texture.png -------------------------------------------------------------------------------- /data/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lainsce/notejot/c0ee94863077155a6ab0514fa13cbe086a22d076/data/icon.png -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/document-edit-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/document-send-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/font-x-generic-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/format-text-bold-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/format-text-italic-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/format-text-strikethrough-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/format-text-underline-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/image-round-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 35 | 38 | 39 | 42 | 46 | 51 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/list-select-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 45 | 48 | 49 | 51 | 52 | 54 | image/svg+xml 55 | 57 | 58 | 59 | 60 | 62 | 65 | 69 | 73 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/notebook-add-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 40 | 43 | 44 | 46 | 47 | 49 | image/svg+xml 50 | 52 | 53 | 54 | 55 | 59 | 63 | 67 | 71 | 78 | 85 | 92 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/notebook-config-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 43 | 46 | 47 | 49 | 50 | 52 | image/svg+xml 53 | 55 | 56 | 57 | 58 | 62 | 67 | 74 | 81 | 85 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/notebook-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 42 | 45 | 46 | 48 | 49 | 51 | image/svg+xml 52 | 54 | 55 | 56 | 57 | 58 | 62 | 67 | 72 | 79 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/text-x-generic-filled-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 33 | 49 | 50 | 52 | 56 | 57 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/user-trash-filled-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 33 | 49 | 50 | 52 | 56 | 57 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-grid-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-list-bullet-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-pin-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /data/icons/io.github.lainsce.Notejot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /data/icons/meson.build: -------------------------------------------------------------------------------- 1 | icondir = join_paths(get_option('datadir'), 'icons/hicolor') 2 | 3 | install_data( 4 | 'io.github.lainsce.Notejot.svg', 5 | install_dir: join_paths(icondir, 'scalable/apps'), 6 | ) 7 | install_data( 8 | 'io.github.lainsce.Notejot.Devel.svg', 9 | install_dir: join_paths(icondir, 'scalable/apps'), 10 | ) -------------------------------------------------------------------------------- /data/io.github.lainsce.Notejot.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Notejot 3 | Comment=Jot your ideas 4 | Exec=@app_id@ %u 5 | Icon=io.github.lainsce.Notejot 6 | Keywords=text;plain;plaintext;notepad;notes;sticky;post-it; 7 | Terminal=false 8 | Type=Application 9 | StartupNotify=true 10 | Categories=GTK;Utility; 11 | -------------------------------------------------------------------------------- /data/io.github.lainsce.Notejot.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | style.css 5 | 6 | ui/edit_notebooks.ui 7 | ui/move_to_dialog.ui 8 | ui/main_window.ui 9 | ui/main_menu.ui 10 | ui/note_theme.ui 11 | ui/notecontentview.ui 12 | ui/notelistview.ui 13 | ui/noterow.ui 14 | ui/noterowcontent.ui 15 | ui/notebooklistview.ui 16 | ui/notebookrow.ui 17 | ui/notebookmainrow.ui 18 | ui/notebookmainrowcontent.ui 19 | ui/notebookrowcontent.ui 20 | ui/notebookmainlistview.ui 21 | ui/notebookmovelistview.ui 22 | ui/notebookmoverow.ui 23 | ui/trashcontentview.ui 24 | ui/trashlistview.ui 25 | ui/trashrow.ui 26 | ui/trashrowcontent.ui 27 | 28 | assets/texture.png 29 | 30 | 31 | icons/hicolor/scalable/actions/notebook-add-symbolic.svg 32 | icons/hicolor/scalable/actions/notebook-config-symbolic.svg 33 | icons/hicolor/scalable/actions/notebook-symbolic.svg 34 | icons/hicolor/scalable/actions/view-grid-symbolic.svg 35 | icons/hicolor/scalable/actions/document-edit-symbolic.svg 36 | icons/hicolor/scalable/actions/font-x-generic-symbolic.svg 37 | icons/hicolor/scalable/actions/list-select-symbolic.svg 38 | icons/hicolor/scalable/actions/format-text-bold-symbolic.svg 39 | icons/hicolor/scalable/actions/format-text-italic-symbolic.svg 40 | icons/hicolor/scalable/actions/format-text-strikethrough-symbolic.svg 41 | icons/hicolor/scalable/actions/format-text-underline-symbolic.svg 42 | icons/hicolor/scalable/actions/view-list-bullet-symbolic.svg 43 | icons/hicolor/scalable/actions/image-round-symbolic.svg 44 | icons/hicolor/scalable/actions/view-pin-symbolic.svg 45 | icons/hicolor/scalable/actions/document-send-symbolic.svg 46 | icons/hicolor/scalable/actions/text-x-generic-filled-symbolic.svg 47 | icons/hicolor/scalable/actions/user-trash-filled-symbolic.svg 48 | 49 | 50 | -------------------------------------------------------------------------------- /data/io.github.lainsce.Notejot.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 0 5 | Migration Version 6 | The version of migration to use; Do not change. 7 | 8 | 9 | 0 10 | Last Seen View 11 | The last seen view on the sidebar. 12 | 13 | 14 | "grid" 15 | Last View Used 16 | The last view used in the UI 17 | 18 | 19 | "'medium'" 20 | Notes Font Size 21 | The size of the font used in notes. (Small, Medium, Large) 22 | 23 | 24 | false 25 | Saves whether the window is maximized or not 26 | Whether the window is maximized. Used to open window with user's preferred settings 27 | 28 | 29 | 900 30 | Saves window last-used width 31 | The user's last used window width before closing the app 32 | 33 | 34 | 500 35 | Saves window last-used height 36 | The user's last used window height before closing the app 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /data/io.github.lainsce.Notejot.metainfo.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | @app_id@ 4 | CC0-1.0 5 | GPL-3.0+ 6 | Notejot 7 | Jot your ideas 8 | 9 |

A stupidly-simple notes application for any type of short term notes or ideas.

10 |
    11 |
  • 🟡 Color your notes in 8 different colors
  • 12 |
  • 📓 Classify them in notebooks
  • 13 |
  • 🔤 Format text to your liking
  • 14 |
  • 📌 Pin your most important ones
  • 15 |
16 |
17 | 18 | io.github.lainsce.Notejot 19 | 20 | 21 | ModernToolkit 22 | HiDpiIcon 23 | 24 | Lains 25 | https://github.com/lainsce/notejot/ 26 | https://github.com/lainsce/notejot/issues 27 | https://www.ko-fi.com/lainsce/ 28 | https://github.com/lainsce/notejot/blob/main/po/README.md 29 | io.github.lainsce.Notejot.desktop 30 | 31 | 32 | https://raw.githubusercontent.com/lainsce/notejot/main/data/shot.png 33 | 34 | 35 | 36 | 37 | keyboard 38 | pointing 39 | touch 40 | 41 | 42 | 360 43 | 44 | 45 | [(246, 211, 45)] 46 | 47 | @app_id@ 48 | 49 | 50 | 51 |

Release: Stargone

52 |
    53 |
  • Added: An option to give a note a header image.
  • 54 |
  • Changed: UI fixes.
  • 55 |
56 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

57 |
58 |
59 | 60 | 61 |

Release: Silver

62 |
    63 |
  • Changed: UI now follows my own style that complements that of He.Albumaita, called Solo.
  • 64 |
  • Changed: The syntax follows Markdown conventions where possible.
  • 65 |
  • Fixed: The mobile UI has been fixed, back buttons should show up without issue.
  • 66 |
67 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

68 |
69 |
70 | 71 | 72 |

Release: Beautiful Superstar

73 |
    74 |
  • Added: New Notes Grid view, access your notes in a grid.
  • 75 |
  • Changed: UI colors were changed, and some UI parts now look more intuitive.
  • 76 |
  • Fixed: Unordered list formatting.
  • 77 |
  • Fixed: Some UI bugs.
  • 78 |
79 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

80 |
81 |
82 | 83 | 84 |

Release: The Top 100 (3.3.3)

85 |
    86 |
  • Changed: UI now looks better layoutted, is an experiment.
  • 87 |
  • Changed: Backend was changed to be more stable than the old one.
  • 88 |
89 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

90 |
91 |
92 | 93 | 94 |

Release: The Top 100

95 |
    96 |
  • Changed: UI now looks better layoutted, is an experiment.
  • 97 |
  • Changed: Backend was changed to be more stable than the old one.
  • 98 |
99 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

100 |
101 |
102 | 103 | 104 |

Release: Pinned Notes

105 |
    106 |
  • Added: Notes can now be pinned and are shown separately from others.
  • 107 |
  • Added: Note title styling from older versions is back.
  • 108 |
  • Added: Note searchbar is now always visible.
  • 109 |
110 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

111 |
112 |
113 | 114 | 115 |

Release: Usability Independence

116 |
    117 |
  • Fixed: many UI bugs were fixed, last but not least the notebook switcher and trash and also removing singular notes from a notebook.
  • 118 |
119 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

120 |
121 |
122 | 123 | 124 |

Release: Format But Don't Fail

125 |
    126 |
  • Fixed: formatting functions are the best they can be, plus minor fixes all around.
  • 127 |
128 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

129 |
130 |
131 | 132 | 133 |

Release: Ready, Set, Go!

134 |
    135 |
  • Some UI design fixes, such as the notebook switcher being on the bottom instead of in the top.
  • 136 |
137 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

138 |
139 |
140 | 141 | 142 |

Release: GTK4 and Ready!

143 |
    144 |
  • New UI
  • 145 |
  • Using another widget to display note contents
  • 146 |
  • Keyboard shortcuts for formatting
  • 147 |
148 |

Note: Your notes and notebooks are always saved in ~/.var/app/io.github.lainsce.Notejot when using the Flatpak. Happy notetaking!

149 |
150 |
151 |
152 |
153 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | conf = configuration_data() 2 | conf.set('app_id', app_id) 3 | 4 | desktop_conf = configure_file( 5 | input: meson.project_name() + '.desktop.in', 6 | output: '@0@.desktop.in'.format(app_id), 7 | configuration: conf 8 | ) 9 | 10 | desktop_file = i18n.merge_file( 11 | input: desktop_conf, 12 | output: '@0@.desktop'.format(app_id), 13 | type: 'desktop', 14 | po_dir: '../po', 15 | install: true, 16 | install_dir: join_paths(get_option('datadir'), 'applications') 17 | ) 18 | 19 | # Validate Desktop file 20 | desktop_file_validate = find_program('desktop-file-validate', required: false) 21 | if desktop_file_validate.found() 22 | test('validate-desktop', desktop_file_validate, 23 | args: [desktop_file] 24 | ) 25 | endif 26 | 27 | appstream_conf = configure_file( 28 | input: meson.project_name() + '.metainfo.xml.in', 29 | output: '@0@.metainfo.xml.in'.format(app_id), 30 | configuration: conf 31 | ) 32 | 33 | appstream_file = i18n.merge_file( 34 | input: appstream_conf, 35 | output: '@0@.metainfo.xml'.format(app_id), 36 | po_dir: '../po', 37 | install: true, 38 | install_dir: join_paths(get_option('datadir'), 'metainfo') 39 | ) 40 | 41 | #Validate Appstream file 42 | appstream_file_validate = find_program('appstream-util', required: false) 43 | if appstream_file_validate.found() 44 | test('validate-appstream', appstream_file_validate, 45 | args: ['validate', '--nonet', appstream_file] 46 | ) 47 | endif 48 | 49 | gnome.compile_schemas(build_by_default: true) 50 | install_data( 51 | meson.project_name() + '.gschema.xml', 52 | install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') 53 | ) 54 | 55 | subdir('icons') 56 | 57 | 58 | asresources = gnome.compile_resources( 59 | 'as-resources', 60 | 'io.github.lainsce.Notejot.gresource.xml', 61 | source_dir: meson.current_build_dir(), 62 | c_name: 'as', 63 | install_dir: get_option('datadir') / meson.project_name(), 64 | ) -------------------------------------------------------------------------------- /data/shot-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lainsce/notejot/c0ee94863077155a6ab0514fa13cbe086a22d076/data/shot-dark.png -------------------------------------------------------------------------------- /data/shot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lainsce/notejot/c0ee94863077155a6ab0514fa13cbe086a22d076/data/shot.png -------------------------------------------------------------------------------- /data/style.css: -------------------------------------------------------------------------------- 1 | .circular radio { 2 | background: none; 3 | padding: 12px; 4 | border-width: 1px; 5 | border-style: solid; 6 | border-radius: 999px; 7 | border-color: alpha(@window_fg_color, 0.3); 8 | } 9 | .circular radio:hover { 10 | border-color: alpha(@window_fg_color, 0.6); 11 | } 12 | .circular radio:checked { 13 | border-color: alpha(@window_fg_color, 0.3); 14 | } 15 | 16 | .notejot-theme .textual-button { 17 | border-radius: 0; 18 | background: none; 19 | color: @view_fg_color; 20 | box-shadow: none; 21 | } 22 | .notejot-theme .textual-button:hover { 23 | background: alpha(@window_fg_color, 0.05); 24 | color: @view_fg_color; 25 | } 26 | .notejot-theme .textual-button:active { 27 | background: alpha(@window_fg_color, 0.08); 28 | color: @view_fg_color; 29 | } 30 | 31 | .notejot-body text { 32 | background-color: @surface_container_bg_color; 33 | border-radius: 12px; 34 | } 35 | .notejot-body { 36 | margin: 8px; 37 | margin-bottom: 0; 38 | border-radius: 12px; 39 | } 40 | 41 | .scrim { 42 | color: white; 43 | padding: 0; 44 | margin: 0; 45 | } 46 | .scrim .view-subtitle { 47 | color: white; 48 | text-shadow: 0 1px 2px black; 49 | } 50 | .scrim .close image, 51 | .scrim .maximize image, 52 | .scrim .minimize image { 53 | color: white; 54 | -gtk-icon-shadow: 0 1px 2px black; 55 | box-shadow: 0 1px 2px black; 56 | } 57 | .scrim .disclosure-button { 58 | box-shadow: 0 1px 2px black; 59 | } 60 | .scrim .text-field { 61 | box-shadow: 0 0 0 1px alpha(white, 0.38); 62 | background: alpha(white, 0.08); 63 | } 64 | .scrim .text-field * { 65 | opacity: 1; 66 | color: white; 67 | text-shadow: 0 1px 2px black; 68 | caret-color: @view_bg_color; 69 | } 70 | 71 | .color-red radio { 72 | background: alpha(@meson_red, 0.65); 73 | color: alpha(@meson_red, 0); 74 | } 75 | .color-orange radio { 76 | background: alpha(@lepton_orange, 0.65); 77 | color: alpha(@lepton_orange, 0); 78 | } 79 | .color-yellow radio { 80 | background: alpha(@electron_yellow, 0.65); 81 | color: alpha(@electron_yellow, 0); 82 | } 83 | .color-green radio { 84 | background: alpha(@muon_green, 0.65); 85 | color: alpha(@muon_green, 0); 86 | } 87 | .color-blue radio { 88 | background: alpha(@proton_blue, 0.65); 89 | color: alpha(@proton_blue, 0); 90 | } 91 | .color-purple radio { 92 | background: alpha(@tau_purple, 0.65); 93 | color: alpha(@tau_purple, 0); 94 | } 95 | .color-reset radio { 96 | background: alpha(@surface_bg_color, 0.65); 97 | color: alpha(@surface_bg_color, 0); 98 | } 99 | 100 | .big-font { 101 | font-size: 20px; 102 | } 103 | .med-font { 104 | font-size: 16px; 105 | } 106 | .sml-font { 107 | font-size: 12px; 108 | } 109 | 110 | .rounded-pic { 111 | margin: 0; 112 | padding: 0; 113 | border-radius: 8px; 114 | } 115 | .unrounded-pic { 116 | margin: 0; 117 | padding: 0; 118 | border-radius: 0; 119 | } 120 | -------------------------------------------------------------------------------- /data/ui/edit_notebooks.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 125 | 126 | -------------------------------------------------------------------------------- /data/ui/main_menu.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 71 | 72 | -------------------------------------------------------------------------------- /data/ui/move_to_dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 119 | 120 | -------------------------------------------------------------------------------- /data/ui/note_theme.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 147 | 148 | -------------------------------------------------------------------------------- /data/ui/notebooklistview.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 32 | 33 | -------------------------------------------------------------------------------- /data/ui/notebookmainlistview.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 34 | 35 | -------------------------------------------------------------------------------- /data/ui/notebookmainrow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | -------------------------------------------------------------------------------- /data/ui/notebookmainrowcontent.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 29 | 30 | -------------------------------------------------------------------------------- /data/ui/notebookmovelistview.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37 | 38 | -------------------------------------------------------------------------------- /data/ui/notebookmoverow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 23 | 24 | -------------------------------------------------------------------------------- /data/ui/notebookrow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 15 | 16 | -------------------------------------------------------------------------------- /data/ui/notebookrowcontent.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 28 | 29 | -------------------------------------------------------------------------------- /data/ui/notelistview.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 97 | 98 | -------------------------------------------------------------------------------- /data/ui/noterow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | -------------------------------------------------------------------------------- /data/ui/noterowcontent.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 115 | 116 | -------------------------------------------------------------------------------- /data/ui/trashlistview.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 51 | 52 | -------------------------------------------------------------------------------- /data/ui/trashrow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | 13 | -------------------------------------------------------------------------------- /data/ui/trashrowcontent.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 114 | 115 | -------------------------------------------------------------------------------- /io.github.lainsce.Notejot.Devel.json: -------------------------------------------------------------------------------- 1 | { 2 | "app-id" : "io.github.lainsce.Notejot.Devel", 3 | "runtime" : "com.fyralabs.Platform", 4 | "runtime-version" : "daily", 5 | "sdk" : "com.fyralabs.Sdk", 6 | "command" : "io.github.lainsce.Notejot", 7 | "finish-args" : [ 8 | "--filesystem=xdg-run/gvfsd", 9 | "--socket=wayland", 10 | "--socket=fallback-x11", 11 | "--share=ipc", 12 | "--device=dri" 13 | ], 14 | "desktop-file-name-suffix" : " (Development)", 15 | "cleanup" : [ 16 | "/cache", 17 | "/man", 18 | "/share/aclocal", 19 | "/share/devhelp", 20 | "/lib/systemd", 21 | "/include", 22 | "/lib/pkgconfig", 23 | "/lib/libvala*", 24 | "/share/gtk-doc", 25 | "/share/man", 26 | "/share/vala", 27 | "*.a", 28 | "*.la" 29 | ], 30 | "modules" : [ 31 | { 32 | "name" : "notejot", 33 | "builddir" : true, 34 | "buildsystem" : "meson", 35 | "config-opts" : [ 36 | "-Ddevelopment=true" 37 | ], 38 | "sources" : [ 39 | { 40 | "type" : "dir", 41 | "path" : "." 42 | } 43 | ] 44 | } 45 | ] 46 | } 47 | -------------------------------------------------------------------------------- /io.github.lainsce.Notejot.doap: -------------------------------------------------------------------------------- 1 | 2 | 7 | Notejot 8 | 9 | Jot your ideas 10 | 11 | 12 |

A stupidly-simple notes application for any type of short term notes or ideas.

13 |
    14 |
  • Color your notes in 8 different colors
  • 15 |
  • Classify them in notebooks
  • 16 |
  • Format text to your liking
  • 17 |
  • Pin your most important ones
  • 18 |
19 |
20 | 21 | 22 | Vala 23 | 24 | 25 | Lains 26 | 27 | lainsce 28 | 29 | 30 |
31 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project( 2 | 'io.github.lainsce.Notejot', 3 | 'vala', 4 | version: '3.6.0', 5 | meson_version: '>= 0.60.0', 6 | ) 7 | 8 | gnome = import('gnome') 9 | i18n = import('i18n') 10 | 11 | if get_option('development') 12 | app_id = 'io.github.lainsce.Notejot.Devel' 13 | name_suffix = ' (Development)' 14 | else 15 | app_id = 'io.github.lainsce.Notejot' 16 | name_suffix = '' 17 | endif 18 | 19 | conf = configuration_data() 20 | conf.set_quoted('APP_ID', app_id) 21 | conf.set_quoted('NAME_SUFFIX', name_suffix) 22 | conf.set_quoted('VERSION', meson.project_version()) 23 | conf.set_quoted('GETTEXT_PACKAGE', app_id) 24 | conf.set_quoted('LOCALEDIR', join_paths(get_option('prefix'), get_option('localedir'))) 25 | conf.set10('DEVELOPMENT', get_option('development')) 26 | configure_file(output: 'config.h', configuration: conf) 27 | 28 | add_project_arguments( 29 | '-include', 'config.h', 30 | '-DGETTEXT_PACKAGE="@0@"'.format(app_id), 31 | '-w', 32 | language: 'c', 33 | ) 34 | add_project_arguments( 35 | [ 36 | '--target-glib=2.68', 37 | '--gresourcesdir', meson.current_build_dir() / 'data', 38 | ], 39 | language: 'vala', 40 | ) 41 | 42 | sources = [ 43 | 'src/Application.vala', 44 | 'src/MainWindow.vala', 45 | 'src/Models/Note.vala', 46 | 'src/Models/Notebook.vala', 47 | 'src/Models/Trash.vala', 48 | 'src/Repositories/NoteRepository.vala', 49 | 'src/Repositories/NotebookRepository.vala', 50 | 'src/Repositories/TrashRepository.vala', 51 | 'src/Services/MigrationManager.vala', 52 | 'src/Services/SettingsManager.vala', 53 | 'src/Services/StyleManager.vala', 54 | 'src/Utils/FileUtils.vala', 55 | 'src/Utils/FormatUtils.vala', 56 | 'src/Utils/MiscUtils.vala', 57 | 'src/Utils/NoteSorter.vala', 58 | 'src/Utils/ObservableList.vala', 59 | 'src/Utils/TimeUtils.vala', 60 | 'src/ViewModels/NoteViewModel.vala', 61 | 'src/ViewModels/NotebookViewModel.vala', 62 | 'src/ViewModels/TrashViewModel.vala', 63 | 'src/Views/NoteContentView.vala', 64 | 'src/Views/NoteListView.vala', 65 | 'src/Views/NotebookListView.vala', 66 | 'src/Views/NotebookMainListView.vala', 67 | 'src/Views/NotebookMoveListView.vala', 68 | 'src/Views/TrashContentView.vala', 69 | 'src/Views/TrashListView.vala', 70 | 'src/Views/View.vala', 71 | 'src/Widgets/EditNotebookDialog.vala', 72 | 'src/Widgets/MainMenu.vala', 73 | 'src/Widgets/NotebookMainRowContent.vala', 74 | 'src/Widgets/NoteRowContent.vala', 75 | 'src/Widgets/MoveToDialog.vala', 76 | 'src/Widgets/NotebookRowContent.vala', 77 | 'src/Widgets/NoteTheme.vala', 78 | 'src/Widgets/TrashRowContent.vala', 79 | ] 80 | 81 | dependencies = [ 82 | dependency('gio-2.0'), 83 | dependency('gtk4'), 84 | dependency('glib-2.0'), 85 | dependency('gobject-2.0'), 86 | dependency('gee-0.8'), 87 | dependency('libhelium-1'), 88 | dependency('libbismuth-1'), 89 | dependency('gmodule-2.0'), 90 | dependency('json-glib-1.0'), 91 | meson.get_compiler('c').find_library('m', required: true), 92 | ] 93 | 94 | subdir('data') 95 | subdir('po') 96 | 97 | executable( 98 | meson.project_name(), 99 | asresources, 100 | sources: sources, 101 | vala_args: [ 102 | meson.current_source_dir() + '/src/' + '/Config.vapi', 103 | ], 104 | dependencies: dependencies, 105 | install: true, 106 | ) 107 | 108 | gnome.post_install( 109 | glib_compile_schemas: true, 110 | gtk_update_icon_cache: true, 111 | update_desktop_database: true, 112 | ) 113 | -------------------------------------------------------------------------------- /meson_options.txt: -------------------------------------------------------------------------------- 1 | option('development', type: 'boolean', value: false, description: 'If this is a development build') 2 | -------------------------------------------------------------------------------- /po/LINGUAS: -------------------------------------------------------------------------------- 1 | ca 2 | cs 3 | da 4 | de 5 | es 6 | fr 7 | gl 8 | hr 9 | it 10 | ja 11 | lt 12 | nl 13 | oc 14 | pl 15 | pt 16 | pt_BR 17 | ru 18 | sv 19 | tr 20 | -------------------------------------------------------------------------------- /po/POTFILES: -------------------------------------------------------------------------------- 1 | data/io.github.lainsce.Notejot.desktop.in 2 | data/io.github.lainsce.Notejot.metainfo.xml.in 3 | data/io.github.lainsce.Notejot.gschema.xml 4 | 5 | data/ui/edit_notebooks.blp 6 | data/ui/main_menu.blp 7 | data/ui/main_window.ui 8 | data/ui/move_to_dialog.blp 9 | data/ui/note_theme.blp 10 | data/ui/notecontentview.blp 11 | data/ui/trashcontentview.blp 12 | 13 | src/MainWindow.vala 14 | src/Utils/MiscUtils.vala 15 | src/Utils/TimeUtils.vala 16 | src/ViewModels/NoteViewModel.vala 17 | src/ViewModels/TrashViewModel.vala 18 | src/Views/NoteContentView.vala 19 | src/Views/TrashContentView.vala 20 | src/Widgets/MoveToDialog.vala 21 | -------------------------------------------------------------------------------- /po/README.md: -------------------------------------------------------------------------------- 1 | # 🌐 How to Translate Notejot 2 | 3 | ## ✏️ First Things First 4 | 5 | * Fork the repository here on github with the Fork button at the top-right 6 | * Clone this repository by opening the terminal in a folder of your choice and typing `git clone https://github.com//notejot` 7 | * (Optional) Check [Regenerate translations files](https://github.com/lainsce/notejot/tree/main/po#-regenerate-translations-files) section if files haven't been recently updated. 8 | 9 | ## 📃 Basics 10 | 11 | * You'll need to know your language's code (ex. en = English). 12 | * Add that code to the LINGUAS file, in a new line, after the last line. 13 | * Translate the .pot file using the PO editor of your choice (I recommend POEdit). 14 | * Save it as .po in this folder. 15 | 16 | ## 📝 Not so Basics 17 | 18 | * Next, in the folder you've cloned this repo in, open a terminal and type: ```git checkout -b "Translation ``` 19 | * Then, type ```git add *``` 20 | * Finally, ```git commit -m "Translated your app for " && git push```, follow the instructions in the terminal if need be, then type your github username and password. 21 | 22 | And that's it! You've successfully translated Notejot for your language! 23 | 24 | ## 🔁 Regenerate translations files 25 | * Initialize the project build by typing `meson _build` (make sure you have [dependencies](https://github.com/lainsce/notejot#%EF%B8%8F-dependencies) installed!). 26 | * Compile .pot files, type `meson compile -C _build io.github.lainsce.Notejot-pot`. 27 | * (Optional) Compile .po files instead replacing `-pot` with `-update-po` in the previous command. 28 | 29 | Note: install `appstream` package in order to generate release strings. 30 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext(app_id, preset: 'glib') 2 | -------------------------------------------------------------------------------- /src/Application.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017-2022 Lains 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 | */ 20 | public class Notejot.Application : He.Application { 21 | private const GLib.ActionEntry app_entries[] = { 22 | { "quit", quit }, 23 | }; 24 | 25 | public Application () { 26 | Object (application_id: Config.APP_ID); 27 | } 28 | 29 | public static int main (string[] args) { 30 | Intl.bindtextdomain (Config.GETTEXT_PACKAGE, Config.LOCALEDIR); 31 | Intl.textdomain (Config.GETTEXT_PACKAGE); 32 | 33 | var app = new Notejot.Application (); 34 | return app.run (args); 35 | } 36 | 37 | protected override void startup () { 38 | Gdk.RGBA accent_color = { 0 }; 39 | accent_color.parse ("#febc16"); 40 | default_accent_color = He.from_gdk_rgba (accent_color); 41 | 42 | resource_base_path = "/io/github/lainsce/Notejot"; 43 | 44 | base.startup (); 45 | 46 | add_action_entries (app_entries, this); 47 | 48 | typeof (NoteListView).ensure (); 49 | typeof (NoteContentView).ensure (); 50 | 51 | var repo = new NoteRepository (); 52 | var view_model = new NoteViewModel (repo); 53 | 54 | typeof (NotebookListView).ensure (); 55 | typeof (NotebookMainListView).ensure (); 56 | typeof (NotebookMoveListView).ensure (); 57 | 58 | var nbrepo = new NotebookRepository (); 59 | var nbview_model = new NotebookViewModel (nbrepo); 60 | 61 | typeof (TrashListView).ensure (); 62 | typeof (TrashContentView).ensure (); 63 | 64 | var trepo = new TrashRepository (); 65 | var tview_model = new TrashViewModel (trepo); 66 | 67 | // FIX: Wait for migration to complete before setting schema_version 68 | var settings = new Settings (); 69 | if (settings.schema_version == 0) { 70 | debug ("Starting migration..."); 71 | var mm = new MigrationManager (null); // Pass null for now 72 | 73 | // Create a temporary window just for migration 74 | var temp_window = new MainWindow (this, view_model, tview_model, nbview_model); 75 | mm.win = temp_window; 76 | 77 | run_migration.begin (mm, settings, () => { 78 | debug ("Migration completed, creating main window"); 79 | temp_window.destroy (); 80 | new MainWindow (this, view_model, tview_model, nbview_model); 81 | }); 82 | } else { 83 | // No migration needed 84 | new MainWindow (this, view_model, tview_model, nbview_model); 85 | } 86 | } 87 | 88 | private async void run_migration (MigrationManager mm, Settings settings, owned VoidFunc callback) { 89 | yield mm.migrate_from_file_notes (); 90 | 91 | yield mm.migrate_from_file_trash (); 92 | 93 | yield mm.migrate_from_file_nb (); 94 | 95 | // Only set schema version after migration is complete 96 | settings.schema_version = 1; 97 | debug ("Migration completed successfully"); 98 | } 99 | 100 | protected override void activate () { 101 | active_window?.present (); 102 | } 103 | } 104 | 105 | // Helper delegate for callback 106 | public delegate void VoidFunc (); 107 | -------------------------------------------------------------------------------- /src/Config.vapi: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "config.h")] 20 | namespace Config { 21 | public const string APP_ID; 22 | public const string NAME_SUFFIX; 23 | public const string VERSION; 24 | public const string GETTEXT_PACKAGE; 25 | public const string LOCALEDIR; 26 | public const bool DEVELOPMENT; 27 | } 28 | -------------------------------------------------------------------------------- /src/Models/Note.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | namespace Notejot { 20 | public class Note : Object, Json.Serializable { 21 | public string id { get; set; default = Uuid.string_random (); } 22 | public string title { get; set; } 23 | public string subtitle { get; set; } 24 | public string text { get; set; } 25 | public string color { get; set; } 26 | public string notebook { get; set; } 27 | public string picture { get; set; } 28 | public bool pinned { get; set; } 29 | 30 | public static Note from_json (Json.Node node) requires (node.get_node_type () == OBJECT) { 31 | return (Note) Json.gobject_deserialize (typeof (Note), node); 32 | } 33 | 34 | public static List list_from_json (Json.Node node) requires (node.get_node_type () == ARRAY) { 35 | var result = new List (); 36 | 37 | var json_array = node.get_array (); 38 | json_array.foreach_element ((_, __, element_node) => { 39 | result.append (Note.from_json (element_node)); 40 | }); 41 | 42 | return (owned) result; 43 | } 44 | 45 | public Json.Node to_json () { 46 | return Json.gobject_serialize (this); 47 | } 48 | 49 | bool deserialize_property (string property_name, out Value @value, ParamSpec pspec, Json.Node property_node) { 50 | return default_deserialize_property (property_name, out @value, pspec, property_node); 51 | } 52 | 53 | Json.Node serialize_property (string property_name, Value @value, ParamSpec pspec) { 54 | return default_serialize_property (property_name, @value, pspec); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Models/Notebook.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | namespace Notejot { 20 | public class Notebook : Object, Json.Serializable { 21 | public string id { get; set; default = Uuid.string_random (); } 22 | public string title { get; set; } 23 | 24 | public static Notebook from_json (Json.Node node) requires (node.get_node_type () == OBJECT) { 25 | return (Notebook) Json.gobject_deserialize (typeof (Notebook), node); 26 | } 27 | 28 | public static List list_from_json (Json.Node node) requires (node.get_node_type () == ARRAY) { 29 | var result = new List (); 30 | 31 | var json_array = node.get_array (); 32 | json_array.foreach_element ((_, __, element_node) => { 33 | result.append (Notebook.from_json (element_node)); 34 | }); 35 | 36 | return (owned) result; 37 | } 38 | 39 | public Json.Node to_json () { 40 | return Json.gobject_serialize (this); 41 | } 42 | 43 | bool deserialize_property (string property_name, out Value @value, ParamSpec pspec, Json.Node property_node) { 44 | return default_deserialize_property (property_name, out @value, pspec, property_node); 45 | } 46 | 47 | Json.Node serialize_property (string property_name, Value @value, ParamSpec pspec) { 48 | return default_serialize_property (property_name, @value, pspec); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Models/Trash.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | namespace Notejot { 20 | public class Trash : Object, Json.Serializable { 21 | public string id { get; set; default = Uuid.string_random (); } 22 | public string title { get; set; } 23 | public string subtitle { get; set; } 24 | public string text { get; set; } 25 | public string color { get; set; } 26 | public string notebook { get; set; } 27 | public string picture { get; set; } 28 | public bool pinned { get; set; } 29 | 30 | public static Trash from_json (Json.Node node) requires (node.get_node_type () == OBJECT) { 31 | return (Trash) Json.gobject_deserialize (typeof (Trash), node); 32 | } 33 | 34 | public static List list_from_json (Json.Node node) requires (node.get_node_type () == ARRAY) { 35 | var result = new List (); 36 | 37 | var json_array = node.get_array (); 38 | json_array.foreach_element ((_, __, element_node) => { 39 | result.append (Trash.from_json (element_node)); 40 | }); 41 | 42 | return (owned) result; 43 | } 44 | 45 | public Json.Node to_json () { 46 | return Json.gobject_serialize (this); 47 | } 48 | 49 | bool deserialize_property (string property_name, out Value @value, ParamSpec pspec, Json.Node property_node) { 50 | return default_deserialize_property (property_name, out @value, pspec, property_node); 51 | } 52 | 53 | Json.Node serialize_property (string property_name, Value @value, ParamSpec pspec) { 54 | return default_serialize_property (property_name, @value, pspec); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/Repositories/NoteRepository.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | public class Notejot.NoteRepository : Object { 20 | const string FILENAME = "saved_notes.json"; 21 | 22 | Queue insert_queue = new Queue (); 23 | public Queue update_queue = new Queue (); 24 | Queue delete_queue = new Queue (); 25 | 26 | public async List get_notes () { 27 | try { 28 | var settings = new Settings (); 29 | if (settings.schema_version == 1) { 30 | var contents = yield FileUtils.read_text_file (FILENAME); 31 | 32 | if (contents == null) 33 | return new List (); 34 | 35 | var json = Json.from_string (contents); 36 | 37 | if (json.get_node_type () != ARRAY) 38 | return new List (); 39 | 40 | return Note.list_from_json (json); 41 | } 42 | return new List (); 43 | } catch (Error err) { 44 | critical ("Error: %s", err.message); 45 | return new List (); 46 | } 47 | } 48 | 49 | public void insert_note (Note note) { 50 | insert_queue.push_tail (note); 51 | } 52 | 53 | public void update_note (Note note) { 54 | update_queue.push_tail (note); 55 | } 56 | 57 | public async void update_notebook (Note? note, string nb) { 58 | if (note != null) { 59 | note.notebook = nb; 60 | update_queue.push_tail (note); 61 | save.begin (); 62 | } 63 | } 64 | 65 | public void delete_note (string id) { 66 | delete_queue.push_tail (id); 67 | } 68 | 69 | public async bool save () { 70 | var notes = yield get_notes (); 71 | 72 | Note? note = null; 73 | while ((note = update_queue.pop_head ()) != null) { 74 | var current_note = search_note_by_id (notes, note.id); 75 | 76 | if (current_note == null) { 77 | insert_queue.push_tail (note); 78 | continue; 79 | } 80 | current_note.title = note.title; 81 | current_note.subtitle = note.subtitle; 82 | current_note.text = note.text; 83 | current_note.notebook = note.notebook; 84 | current_note.color = note.color; 85 | current_note.picture = note.picture; 86 | current_note.pinned = note.pinned; 87 | } 88 | 89 | string? note_id = null; 90 | while ((note_id = delete_queue.pop_head ()) != null) { 91 | note = search_note_by_id (notes, note_id); 92 | 93 | if (note == null) 94 | continue; 95 | 96 | notes.remove (note); 97 | } 98 | 99 | note = null; 100 | while ((note = insert_queue.pop_head ()) != null) 101 | notes.append (note); 102 | 103 | var json_array = new Json.Array (); 104 | foreach (var item in notes) 105 | json_array.add_element (item.to_json ()); 106 | 107 | var node = new Json.Node (ARRAY); 108 | node.set_array (json_array); 109 | 110 | var str = Json.to_string (node, false); 111 | 112 | try { 113 | return yield FileUtils.create_text_file (FILENAME, str); 114 | } catch (Error err) { 115 | critical ("Error: %s", err.message); 116 | return false; 117 | } 118 | } 119 | 120 | public inline Note? search_note_by_id (List notes, string id) { 121 | unowned var link = notes.search (id, (note, id) => strcmp (note.id, id)); 122 | return link?.data; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/Repositories/NotebookRepository.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | public class Notejot.NotebookRepository : Object { 20 | const string FILENAME = "saved_notebooks.json"; 21 | 22 | Queue insert_queue = new Queue (); 23 | public Queue update_queue = new Queue (); 24 | Queue delete_queue = new Queue (); 25 | 26 | public async List get_notebooks () { 27 | try { 28 | var settings = new Settings (); 29 | if (settings.schema_version == 1) { 30 | var contents = yield FileUtils.read_text_file (FILENAME); 31 | 32 | if (contents == null) 33 | return new List (); 34 | 35 | var json = Json.from_string (contents); 36 | 37 | if (json.get_node_type () != ARRAY) 38 | return new List (); 39 | 40 | return Notebook.list_from_json (json); 41 | } 42 | return new List (); 43 | } catch (Error err) { 44 | critical ("Error: %s", err.message); 45 | return new List (); 46 | } 47 | } 48 | 49 | public void insert_notebook (Notebook notebook) { 50 | insert_queue.push_tail (notebook); 51 | } 52 | 53 | public async void update_notebook (Notebook? notebook, string nb) { 54 | if (notebook != null) { 55 | notebook.title = nb; 56 | update_queue.push_tail (notebook); 57 | save.begin (); 58 | } 59 | } 60 | 61 | public void delete_notebook (string id) { 62 | delete_queue.push_tail (id); 63 | } 64 | 65 | public async bool save () { 66 | var notebooks = yield get_notebooks (); 67 | 68 | Notebook? notebook = null; 69 | while ((notebook = update_queue.pop_head ()) != null) { 70 | var current_notebook = search_notebook_by_id (notebooks, notebook.id); 71 | 72 | if (current_notebook == null) { 73 | insert_queue.push_tail (notebook); 74 | continue; 75 | } 76 | current_notebook.title = notebook.title; 77 | } 78 | 79 | string? notebook_id = null; 80 | while ((notebook_id = delete_queue.pop_head ()) != null) { 81 | notebook = search_notebook_by_id (notebooks, notebook_id); 82 | 83 | if (notebook == null) 84 | continue; 85 | 86 | notebooks.remove (notebook); 87 | } 88 | 89 | notebook = null; 90 | while ((notebook = insert_queue.pop_head ()) != null) 91 | notebooks.append (notebook); 92 | 93 | var json_array = new Json.Array (); 94 | foreach (var item in notebooks) 95 | json_array.add_element (item.to_json ()); 96 | 97 | var node = new Json.Node (ARRAY); 98 | node.set_array (json_array); 99 | 100 | var str = Json.to_string (node, false); 101 | 102 | try { 103 | return yield FileUtils.create_text_file (FILENAME, str); 104 | } catch (Error err) { 105 | critical ("Error: %s", err.message); 106 | return false; 107 | } 108 | } 109 | 110 | public inline Notebook? search_notebook_by_id (List notebooks, string id) { 111 | unowned var link = notebooks.search (id, (notebook, id) => strcmp (notebook.id, id)); 112 | return link?.data; 113 | } 114 | 115 | public inline Notebook? search_notebook_by_title (List notebooks, string title) { 116 | unowned var link = notebooks.search (title, (notebook, title) => strcmp (notebook.title, title)); 117 | return link?.data; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/Repositories/TrashRepository.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | public class Notejot.TrashRepository : Object { 20 | const string FILENAME = "saved_trash.json"; 21 | 22 | Queue insert_queue = new Queue (); 23 | public Queue update_queue = new Queue (); 24 | Queue delete_queue = new Queue (); 25 | 26 | public async List get_trashs () { 27 | try { 28 | var settings = new Settings (); 29 | if (settings.schema_version == 1) { 30 | var contents = yield FileUtils.read_text_file (FILENAME); 31 | 32 | if (contents == null) 33 | return new List (); 34 | 35 | var json = Json.from_string (contents); 36 | 37 | if (json.get_node_type () != ARRAY) 38 | return new List (); 39 | 40 | return Trash.list_from_json (json); 41 | } 42 | return new List (); 43 | } catch (Error err) { 44 | critical ("Error: %s", err.message); 45 | return new List (); 46 | } 47 | } 48 | 49 | public void insert_trash (Trash trash) { 50 | insert_queue.push_tail (trash); 51 | } 52 | 53 | public void update_trash (Trash trash) { 54 | update_queue.push_tail (trash); 55 | } 56 | 57 | public void delete_trash (string id) { 58 | delete_queue.push_tail (id); 59 | } 60 | 61 | public async bool save () { 62 | var trashs = yield get_trashs (); 63 | 64 | Trash? trash = null; 65 | while ((trash = update_queue.pop_head ()) != null) { 66 | var current_trash = search_trash_by_id (trashs, trash.id); 67 | 68 | if (current_trash == null) { 69 | insert_queue.push_tail (trash); 70 | continue; 71 | } 72 | current_trash.title = trash.title; 73 | current_trash.subtitle = trash.subtitle; 74 | current_trash.text = trash.text; 75 | current_trash.notebook = trash.notebook; 76 | current_trash.color = trash.color; 77 | current_trash.pinned = trash.pinned; 78 | current_trash.picture = trash.picture; 79 | } 80 | 81 | string? trash_id = null; 82 | while ((trash_id = delete_queue.pop_head ()) != null) { 83 | trash = search_trash_by_id (trashs, trash_id); 84 | 85 | if (trash == null) 86 | continue; 87 | 88 | trashs.remove (trash); 89 | } 90 | 91 | trash = null; 92 | while ((trash = insert_queue.pop_head ()) != null) 93 | trashs.append (trash); 94 | 95 | var json_array = new Json.Array (); 96 | foreach (var item in trashs) 97 | json_array.add_element (item.to_json ()); 98 | 99 | var node = new Json.Node (ARRAY); 100 | node.set_array (json_array); 101 | 102 | var str = Json.to_string (node, false); 103 | 104 | try { 105 | return yield FileUtils.create_text_file (FILENAME, str); 106 | } catch (Error err) { 107 | critical ("Error: %s", err.message); 108 | return false; 109 | } 110 | } 111 | 112 | public inline Trash? search_trash_by_id (List trashs, string id) { 113 | unowned var link = trashs.search (id, (trash, id) => strcmp (trash.id, id)); 114 | return link?.data; 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/Services/MigrationManager.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | namespace Notejot { 20 | public class MigrationManager { 21 | public MainWindow? win; 22 | public Json.Builder builder; 23 | private string app_dir = Environment.get_user_data_dir () 24 | + "/io.github.lainsce.Notejot"; 25 | private string file_name_n; 26 | private string file_name_p; 27 | private string file_name_nb; 28 | private string file_name_t; 29 | 30 | public MigrationManager (MainWindow? win) { 31 | this.win = win; 32 | file_name_n = this.app_dir + "/saved_notes.json"; 33 | file_name_p = this.app_dir + "/saved_pinned_notes.json"; 34 | file_name_t = this.app_dir + "/saved_trash.json"; 35 | file_name_nb = this.app_dir + "/saved_notebooks.json"; 36 | } 37 | 38 | public async void migrate_from_file_notes () { 39 | debug ("Migrate Notes..."); 40 | try { 41 | var file = File.new_for_path (file_name_n); 42 | var filep = File.new_for_path (file_name_p); 43 | 44 | if (file.query_exists ()) { 45 | debug ("Migrating normal notes..."); 46 | string line; 47 | GLib.FileUtils.get_contents (file.get_path (), out line); 48 | var node = Json.from_string (line); 49 | var array = node.get_array (); 50 | foreach (var tasks in array.get_elements ()) { 51 | var task = tasks.get_array (); 52 | var title = task.get_string_element (0); 53 | var subtitle = task.get_string_element (1); 54 | var text = task.get_string_element (2); 55 | var color = task.get_string_element (3); 56 | var notebook = task.get_string_element (4); 57 | 58 | if (win != null) { 59 | win.make_note (Uuid.string_random (), title, subtitle, text, color, notebook, "0"); 60 | } 61 | } 62 | debug ("Normal notes migration completed"); 63 | } 64 | 65 | if (filep.query_exists ()) { 66 | debug ("Migrating pinned notes..."); 67 | string linep; 68 | GLib.FileUtils.get_contents (filep.get_path (), out linep); 69 | var pnode = Json.from_string (linep); 70 | var parray = pnode.get_array (); 71 | foreach (var ptasks in parray.get_elements ()) { 72 | var ptask = ptasks.get_array (); 73 | var ptitle = ptask.get_string_element (0); 74 | var psubtitle = ptask.get_string_element (1); 75 | var ptext = ptask.get_string_element (2); 76 | var pcolor = ptask.get_string_element (3); 77 | var pnotebook = ptask.get_string_element (4); 78 | 79 | if (win != null) { 80 | win.make_note (Uuid.string_random (), ptitle, psubtitle, ptext, pcolor, pnotebook, "1"); 81 | } 82 | } 83 | debug ("Pinned notes migration completed"); 84 | } 85 | } catch (Error e) { 86 | warning ("Failed to migrate notes: %s", e.message); 87 | } 88 | } 89 | 90 | public async void migrate_from_file_trash () { 91 | debug ("Migrate Trashed Notes..."); 92 | try { 93 | var file = File.new_for_path (file_name_t); 94 | 95 | if (file.query_exists ()) { 96 | string line; 97 | GLib.FileUtils.get_contents (file.get_path (), out line); 98 | var node = Json.from_string (line); 99 | var array = node.get_array (); 100 | foreach (var tasks in array.get_elements ()) { 101 | var task = tasks.get_array (); 102 | var title = task.get_string_element (0); 103 | var subtitle = task.get_string_element (1); 104 | var text = task.get_string_element (2); 105 | var color = task.get_string_element (3); 106 | var notebook = task.get_string_element (4); 107 | 108 | if (win != null) { 109 | win.make_trash_note (Uuid.string_random (), title, subtitle, text, color, notebook, "0"); 110 | } 111 | } 112 | } 113 | } catch (Error e) { 114 | warning ("Failed to migrate trash: %s", e.message); 115 | } 116 | } 117 | 118 | public async void migrate_from_file_nb () { 119 | debug ("Migrate Notebooks..."); 120 | try { 121 | var file = File.new_for_path (file_name_nb); 122 | 123 | if (file.query_exists ()) { 124 | string line; 125 | GLib.FileUtils.get_contents (file.get_path (), out line); 126 | var node = Json.from_string (line); 127 | var array = node.get_array (); 128 | foreach (var tasks in array.get_elements ()) { 129 | var task = tasks.get_array (); 130 | var title = task.get_string_element (0); 131 | 132 | if (win != null) { 133 | win.make_notebook (Uuid.string_random (), title); 134 | } 135 | } 136 | } 137 | } catch (Error e) { 138 | warning ("Failed to migrate notebooks: %s", e.message); 139 | } 140 | } 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/Services/SettingsManager.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [SingleInstance] 20 | public class Notejot.Settings : Object { 21 | private GLib.Settings settings = new GLib.Settings ("io.github.lainsce.Notejot"); 22 | public bool is_maximized { get; set; } 23 | public string last_view { get; set; } 24 | public string font_size { get; set; } 25 | public int window_w { get; set; } 26 | public int window_h { get; set; } 27 | public int schema_version { get; set; } 28 | public int sort_mode { get; set; } 29 | 30 | construct { 31 | settings.bind ("last-view", this, "last-view", DEFAULT); 32 | settings.bind ("font-size", this, "font-size", DEFAULT); 33 | settings.bind ("window-w", this, "window-w", DEFAULT); 34 | settings.bind ("window-h", this, "window-h", DEFAULT); 35 | settings.bind ("schema-version", this, "schema-version", DEFAULT); 36 | settings.bind ("sort-mode", this, "sort-mode", DEFAULT); 37 | } 38 | 39 | public Action create_action (string key) { 40 | return settings.create_action (key); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Services/StyleManager.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains * 3 | * This program is free software; you can redistribute it or 4 | * modify it under the terms of the GNU General Public 5 | * License as published by the Free Software Foundation; either 6 | * version 3 of the License, or (at your option) any later version. 7 | * 8 | * This program is distributed in the hope that it will be useful, 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 | * General Public License for more details. 12 | * 13 | * You should have received a copy of the GNU General Public 14 | * License along with this program; if not, write to the 15 | * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 16 | * Boston, MA 02110-1301 USA 17 | */ 18 | public class Notejot.StyleManager { 19 | public void set_css () { 20 | var css_provider=new Gtk.CssProvider (); 21 | string style = """ 22 | .notejot-sidebar-box { 23 | background: mix(@surface_bg_color, @note_color, 0.5); 24 | border-radius: 99px; 25 | } 26 | .notejot-header { 27 | background: mix(@surface_bg_color, @note_color, 0.05); 28 | } 29 | .notejot-footer { 30 | background-color: mix(@surface_container_bg_color, @note_color, 0.05); 31 | } 32 | .scrim { 33 | background: alpha(mix(@scrim, @note_color, 0.08), 0.2); 34 | } 35 | """; 36 | css_provider.load_from_data (style.data); 37 | Gtk.StyleContext.add_provider_for_display ( 38 | Gdk.Display.get_default (), 39 | css_provider, 40 | Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Utils/FileUtils.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | namespace Notejot.FileUtils { 20 | async bool create_text_file (string filename, string contents, Cancellable? cancellable = null) throws Error { 21 | var dir_path = Path.build_filename (Environment.get_user_data_dir (), "/io.github.lainsce.Notejot/"); 22 | 23 | if (DirUtils.create_with_parents (dir_path, 0755) != 0) { 24 | throw new Error (FileError.quark (), GLib.FileUtils.error_from_errno (errno), "%s", strerror (errno)); 25 | } 26 | 27 | var file_path = Path.build_filename (dir_path, filename); 28 | 29 | // Use synchronous file operations - they're fast for small files 30 | // and avoid the threading complexity that was causing hangs 31 | GLib.FileUtils.set_contents (file_path, contents); 32 | 33 | return true; 34 | } 35 | 36 | async string ? read_text_file (string filename, Cancellable? cancellable = null) throws Error { 37 | var file_path = Path.build_filename (Environment.get_user_data_dir (), "/io.github.lainsce.Notejot/", filename); 38 | 39 | string contents = ""; 40 | 41 | try { 42 | // Use synchronous file operations - they're fast for small files 43 | GLib.FileUtils.get_contents (file_path, out contents); 44 | } catch (Error err) { 45 | if (err is FileError.NOENT) 46 | return null; 47 | 48 | throw err; 49 | } 50 | 51 | return contents; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Utils/FormatUtils.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | namespace Notejot { 20 | public enum Format { 21 | BOLD, 22 | ITALIC, 23 | UNDERLINE, 24 | STRIKETHROUGH, 25 | MONOSPACE 26 | } 27 | 28 | public struct FormatBlock { 29 | public int start; 30 | public int end; 31 | public Format format; 32 | } 33 | 34 | public string format_to_string(Format fmt) { 35 | switch (fmt) { 36 | case Format.BOLD: 37 | return "**"; 38 | case Format.ITALIC: 39 | return "*"; 40 | case Format.UNDERLINE: 41 | return "_"; 42 | case Format.STRIKETHROUGH: 43 | return "~"; 44 | case Format.MONOSPACE: 45 | return "`"; 46 | default: 47 | assert_not_reached(); 48 | } 49 | } 50 | 51 | public Format string_to_format(string wrap) { 52 | switch (wrap) { 53 | case "**": 54 | return Format.BOLD; 55 | case "*": 56 | return Format.ITALIC; 57 | case "_": 58 | return Format.UNDERLINE; 59 | case "~": 60 | return Format.STRIKETHROUGH; 61 | case "`": 62 | return Format.MONOSPACE; 63 | default: 64 | assert_not_reached(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Utils/MiscUtils.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | namespace Notejot.MiscUtils { 20 | public T find_ancestor_of_type (Gtk.Widget? ancestor) { 21 | while ((ancestor = ancestor.get_parent ()) != null) { 22 | if (ancestor.get_type ().is_a (typeof (T))) 23 | return (T) ancestor; 24 | } 25 | 26 | return null; 27 | } 28 | 29 | public async File? display_save_dialog (MainWindow win) { 30 | var chooser = new Gtk.FileChooserNative (null, win, Gtk.FileChooserAction.SAVE, null, null); 31 | chooser.set_transient_for(win); 32 | var filter1 = new Gtk.FileFilter (); 33 | filter1.set_filter_name (_("Markdown files")); 34 | filter1.add_pattern ("*.md"); 35 | chooser.add_filter (filter1); 36 | var filter = new Gtk.FileFilter (); 37 | filter.set_filter_name (_("All files")); 38 | filter.add_pattern ("*"); 39 | chooser.add_filter (filter); 40 | 41 | var response = yield run_dialog_async (chooser); 42 | 43 | if (response == Gtk.ResponseType.ACCEPT) { 44 | return chooser.get_file (); 45 | } 46 | 47 | return null; 48 | } 49 | 50 | public async File? display_open_dialog (MainWindow win) { 51 | var chooser = new Gtk.FileChooserNative (null, win, Gtk.FileChooserAction.OPEN, null, null); 52 | chooser.set_transient_for(win); 53 | var filter1 = new Gtk.FileFilter (); 54 | filter1.set_filter_name (_("Image files")); 55 | filter1.add_pattern ("*.png"); 56 | filter1.add_pattern ("*.gif"); 57 | filter1.add_pattern ("*.jpg"); 58 | filter1.add_pattern ("*.jpeg"); 59 | chooser.add_filter (filter1); 60 | var filter = new Gtk.FileFilter (); 61 | filter.set_filter_name (_("All files")); 62 | filter.add_pattern ("*"); 63 | chooser.add_filter (filter); 64 | 65 | var response = yield run_dialog_async (chooser); 66 | 67 | if (response == Gtk.ResponseType.ACCEPT) { 68 | return chooser.get_file (); 69 | } 70 | 71 | return null; 72 | } 73 | 74 | private async Gtk.ResponseType run_dialog_async (Gtk.FileChooserNative dialog) { 75 | var response = Gtk.ResponseType.CANCEL; 76 | 77 | dialog.response.connect (r => { 78 | response = (Gtk.ResponseType) r; 79 | 80 | run_dialog_async.callback (); 81 | }); 82 | 83 | dialog.show (); 84 | 85 | yield; 86 | return response; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/Utils/NoteSorter.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | class Notejot.NoteSorter : Gtk.Sorter { 20 | protected override Gtk.Ordering compare (Object? item1, Object? item2) { 21 | var note1 = item1 as Note; 22 | var note2 = item2 as Note; 23 | 24 | var comp = (int) note2.pinned - (int) note1.pinned; 25 | if (comp == 0) 26 | comp = Gtk.Ordering.from_cmpfunc (note2.subtitle.collate(note1.subtitle)); 27 | return comp; 28 | } 29 | 30 | protected override Gtk.SorterOrder get_order () { 31 | return TOTAL; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Utils/ObservableList.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | public class Notejot.ObservableList : Object, ListModel { 20 | List data = new List (); 21 | 22 | public void add (T item) { 23 | var position = data.length (); 24 | 25 | data.append (item); 26 | 27 | items_changed (position, 0, 1); 28 | } 29 | 30 | public void add_all (List items) { 31 | var position = data.length (); 32 | 33 | foreach (var item in items) 34 | data.append (item); 35 | 36 | items_changed (position, 0, items.length ()); 37 | } 38 | 39 | public void remove_all () { 40 | var current_size = data.length (); 41 | data = new List (); 42 | items_changed (0, current_size, 0); 43 | } 44 | 45 | public new T @get (uint index) { 46 | return data.nth_data (index); 47 | } 48 | 49 | public bool remove (T item) { 50 | var position = data.index (item); 51 | 52 | if (position == -1) 53 | return false; 54 | 55 | data.remove (item); 56 | items_changed (position, 1, 0); 57 | 58 | return true; 59 | } 60 | 61 | Object? get_item (uint position) { 62 | return this[position] as Object; 63 | } 64 | 65 | Type get_item_type () { 66 | return typeof (T); 67 | } 68 | 69 | uint get_n_items () { 70 | return data.length (); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/ViewModels/NoteViewModel.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2025 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | public class Notejot.NoteViewModel : Object { 20 | uint timeout_id = 0; 21 | 22 | public ObservableList notes { get; default = new ObservableList (); } 23 | public NoteRepository? repository { private get; construct; } 24 | 25 | public NoteViewModel (NoteRepository repository) { 26 | Object (repository : repository); 27 | } 28 | 29 | construct { 30 | populate_notes.begin (); 31 | } 32 | 33 | public void create_new_note (Note? note) { 34 | if (note == null) { 35 | var dt = new GLib.DateTime.now_local (); 36 | var n = new Note () { 37 | title = _("New Note"), 38 | subtitle = "%s".printf (dt.format ("%A, %d/%m %H∶%M")), 39 | text = _("Type text here…"), 40 | notebook = _("No Notebook"), 41 | color = "", 42 | picture = "", 43 | pinned = false 44 | }; 45 | notes.add (n); 46 | repository.insert_note (n); 47 | save_notes (); 48 | } else { 49 | notes.add (note); 50 | repository.insert_note (note); 51 | save_notes (); 52 | } 53 | } 54 | 55 | public void restore_trash (Trash trash) { 56 | var note = new Note () { 57 | title = trash.title, 58 | subtitle = trash.subtitle, 59 | text = trash.text, 60 | notebook = trash.notebook, 61 | color = trash.color, 62 | picture = trash.picture, 63 | pinned = trash.pinned, 64 | }; 65 | notes.add (note); 66 | repository.insert_note (note); 67 | save_notes (); 68 | } 69 | 70 | public void update_note (Note note) { 71 | repository.update_note (note); 72 | save_notes (); 73 | } 74 | 75 | public void update_note_color (Note note, string color) { 76 | note.color = color; 77 | var style_manager = new StyleManager (); 78 | style_manager.set_css (); 79 | repository.update_note (note); 80 | save_notes (); 81 | } 82 | 83 | public void update_notebook (Note note, string nb) { 84 | repository.update_notebook.begin (note, nb); 85 | save_notes (); 86 | } 87 | 88 | public void delete_note (Note note) { 89 | notes.remove (note); 90 | repository.delete_note (note.id); 91 | save_notes (); 92 | } 93 | 94 | async void populate_notes () { 95 | var notes = yield repository.get_notes (); 96 | 97 | this.notes.add_all (notes); 98 | } 99 | 100 | void save_notes () { 101 | if (timeout_id != 0) { 102 | Source.remove (timeout_id); 103 | } 104 | timeout_id = Timeout.add (500, () => { 105 | timeout_id = 0; 106 | repository.save.begin (); 107 | return Source.REMOVE; 108 | }); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/ViewModels/NotebookViewModel.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2025 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | public class Notejot.NotebookViewModel : Object { 20 | uint timeout_id = 0; 21 | 22 | public ObservableList notebooks { get; default = new ObservableList (); } 23 | public NotebookRepository? repository { get; construct; } 24 | 25 | public NotebookViewModel (NotebookRepository repository) { 26 | Object (repository : repository); 27 | } 28 | 29 | construct { 30 | populate_notebooks.begin (); 31 | } 32 | 33 | public void create_new_notebook (Notebook notebook) { 34 | notebooks.add (notebook); 35 | repository.insert_notebook (notebook); 36 | save_notebooks (); 37 | } 38 | 39 | public void update_notebook (Notebook notebook, string nb) { 40 | repository.update_notebook.begin (notebook, nb); 41 | save_notebooks (); 42 | } 43 | 44 | public void delete_notebook (Notebook notebook) { 45 | notebooks.remove (notebook); 46 | repository.delete_notebook (notebook.id); 47 | save_notebooks (); 48 | } 49 | 50 | async void populate_notebooks () { 51 | var notebooks = yield repository.get_notebooks (); 52 | 53 | this.notebooks.add_all (notebooks); 54 | } 55 | 56 | void save_notebooks () { 57 | if (timeout_id != 0) 58 | Source.remove (timeout_id); 59 | 60 | timeout_id = Timeout.add (500, () => { 61 | timeout_id = 0; 62 | repository.save.begin (); 63 | return Source.REMOVE; 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/ViewModels/TrashViewModel.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2025 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | public class Notejot.TrashViewModel : Object { 20 | uint timeout_id = 0; 21 | 22 | public ObservableList trashs { get; default = new ObservableList (); } 23 | public TrashRepository? repository { private get; construct; } 24 | 25 | public TrashViewModel (TrashRepository repository) { 26 | Object (repository : repository); 27 | } 28 | 29 | construct { 30 | populate_trashs.begin (); 31 | } 32 | 33 | public void create_new_trash (Note note) { 34 | var trash = new Trash () { 35 | title = note.title, 36 | subtitle = note.subtitle, 37 | text = note.text, 38 | notebook = note.notebook, 39 | color = note.color, 40 | picture = note.picture, 41 | pinned = note.pinned 42 | }; 43 | trashs.add (trash); 44 | repository.insert_trash (trash); 45 | save_trashs (); 46 | } 47 | 48 | public void update_trash (Trash trash) { 49 | repository.update_trash (trash); 50 | save_trashs (); 51 | } 52 | 53 | public void update_trash_color (Trash trash, string color) { 54 | trash.color = color; 55 | var style_manager = new StyleManager (); 56 | style_manager.set_css (); 57 | repository.update_trash (trash); 58 | save_trashs (); 59 | } 60 | 61 | public void delete_one_trash (Trash trash) { 62 | trashs.remove (trash); 63 | repository.delete_trash (trash.id); 64 | save_trashs (); 65 | } 66 | 67 | public async void delete_trash (MainWindow win) { 68 | var p_button = new He.Button ("Clear", ""); 69 | p_button.is_fill = true; 70 | var dialog = new He.Dialog (true, win, _("Clear Trash?"), _("Empties the Trash"), _("Clearing means the items in Trash will be permanently lost with no recovery."), "dialog-warning-symbolic", p_button, null); 71 | p_button.clicked.connect (() => { 72 | depopulate_trashs.begin (); 73 | dialog.close (); 74 | }); 75 | if (dialog != null) { 76 | dialog.present (); 77 | return; 78 | } else { 79 | dialog.show (); 80 | } 81 | } 82 | 83 | async void populate_trashs () { 84 | var trashs = yield repository.get_trashs (); 85 | 86 | this.trashs.add_all (trashs); 87 | } 88 | 89 | async void depopulate_trashs () { 90 | trashs.remove_all (); 91 | var rtrashs = yield repository.get_trashs (); 92 | 93 | foreach (var t in rtrashs) { 94 | repository.delete_trash (t.id); 95 | } 96 | save_trashs (); 97 | } 98 | 99 | void save_trashs () { 100 | if (timeout_id != 0) 101 | Source.remove (timeout_id); 102 | 103 | timeout_id = Timeout.add (500, () => { 104 | timeout_id = 0; 105 | repository.save.begin (); 106 | return Source.REMOVE; 107 | }); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/Views/NoteListView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/notelistview.ui")] 20 | public class Notejot.NoteListView : He.Bin { 21 | [GtkChild] 22 | public unowned Gtk.ListView lv; 23 | [GtkChild] 24 | public unowned Gtk.SingleSelection ss; 25 | 26 | public ObservableList? notes { get; set; } 27 | public Note? selected_note { get; set; } 28 | public He.TextField? note_search { get; set; } 29 | public NoteViewModel? view_model { get; set; } 30 | public NotebookViewModel? nbview_model { get; set; } 31 | public Bis.Album album { get; construct; } 32 | 33 | public NoteListView () { 34 | Object ( 35 | album : album 36 | ); 37 | } 38 | 39 | construct { 40 | lv.activate.connect ((pos) => { 41 | if ((lv.get_model ().get_item (pos) as Note) != selected_note) { 42 | selected_note = lv.get_model ().get_item (pos) as Note; 43 | } else { 44 | ss.unselect_all (); 45 | } 46 | album.set_visible_child (((MainWindow) MiscUtils.find_ancestor_of_type (this)).grid); 47 | }); 48 | } 49 | 50 | public signal void new_note_requested (); 51 | } 52 | -------------------------------------------------------------------------------- /src/Views/NotebookListView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/notebooklistview.ui")] 20 | public class Notejot.NotebookListView : He.Bin { 21 | public ObservableList? notebooks { get; set; } 22 | public NotebookViewModel? nbview_model { get; set; } 23 | public NoteViewModel? view_model { get; set; } 24 | 25 | public signal void new_notebook_requested (Note note); 26 | public signal void notebook_removal_requested (Notebook notebook); 27 | 28 | [GtkCallback] 29 | public void on_notebook_removal_requested (Notebook notebook) { 30 | nbview_model.delete_notebook (notebook); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Views/NotebookMainListView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/notebookmainlistview.ui")] 20 | public class Notejot.NotebookMainListView : He.Bin { 21 | [GtkChild] 22 | public unowned Gtk.SingleSelection ss; 23 | 24 | public ObservableList? notebooks { get; set; } 25 | public NotebookViewModel? nbview_model { get; set; } 26 | public Notebook? selected_notebook { get; set; } 27 | public string? sntext { get; set; } 28 | 29 | construct { 30 | ss.bind_property ("selected", this, "selected-notebook", DEFAULT, (_, from, ref to) => { 31 | var pos = (uint) from; 32 | 33 | if (pos != Gtk.INVALID_LIST_POSITION) { 34 | to.set_object (ss.model.get_item (pos)); 35 | sntext = ((Notebook)ss.model.get_item (pos)).title; 36 | } 37 | 38 | return true; 39 | }); 40 | 41 | 42 | ss.selection_changed.connect (() => { 43 | if (sntext != "" && selected_notebook.title != "" && sntext == selected_notebook.title) { 44 | ss.unselect_all (); 45 | } 46 | }); 47 | } 48 | 49 | public signal void new_notebook_requested (Notebook notebook); 50 | } 51 | -------------------------------------------------------------------------------- /src/Views/NotebookMoveListView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/notebookmovelistview.ui")] 20 | public class Notejot.NotebookMoveListView : He.Bin { 21 | [GtkChild] 22 | unowned Gtk.SingleSelection selection_model; 23 | 24 | public ObservableList? notebooks { get; set; } 25 | public Notebook? selected_notebook { get; set; } 26 | public NotebookViewModel? nbview_model { get; set; } 27 | 28 | construct { 29 | selection_model.bind_property ("selected", this, "selected-notebook", DEFAULT, (_, from, ref to) => { 30 | var pos = (uint) from; 31 | 32 | if (pos != Gtk.INVALID_LIST_POSITION) 33 | to.set_object (selection_model.model.get_item (pos)); 34 | 35 | return true; 36 | }); 37 | } 38 | 39 | public signal void new_notebook_requested (); 40 | } 41 | -------------------------------------------------------------------------------- /src/Views/TrashListView.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/trashlistview.ui")] 20 | public class Notejot.TrashListView : He.Bin { 21 | [GtkChild] 22 | unowned Gtk.SingleSelection selection_model; 23 | 24 | public ObservableList? trashs { get; set; } 25 | public TrashViewModel? tview_model { get; set; } 26 | public Bis.Album album { get; construct; } 27 | 28 | Trash? _selected_trash; 29 | public Trash? selected_trash { 30 | get { return _selected_trash; } 31 | set { 32 | if (value == _selected_trash) 33 | return; 34 | 35 | _selected_trash = value; 36 | } 37 | } 38 | 39 | public TrashListView () { 40 | Object ( 41 | album: album 42 | ); 43 | } 44 | 45 | construct { 46 | selection_model.bind_property ("selected", this, "selected-trash", DEFAULT, (_, from, ref to) => { 47 | var pos = (uint) from; 48 | 49 | if (pos != Gtk.INVALID_LIST_POSITION) 50 | to.set_object (selection_model.model.get_item (pos)); 51 | ((Bis.Album)MiscUtils.find_ancestor_of_type(this)).set_visible_child (((MainWindow)MiscUtils.find_ancestor_of_type(this)).grid); 52 | 53 | return true; 54 | }); 55 | } 56 | 57 | public signal void new_trash_requested (); 58 | } 59 | -------------------------------------------------------------------------------- /src/Views/View.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | -------------------------------------------------------------------------------- /src/Widgets/EditNotebookDialog.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 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 | namespace Notejot { 20 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/edit_notebooks.ui")] 21 | public class Widgets.EditNotebooksDialog : He.Window { 22 | public unowned MainWindow win = null; 23 | public NotebookViewModel nbview_model { get; set; } 24 | public NoteViewModel view_model { get; set; } 25 | 26 | [GtkChild] 27 | public unowned He.TextField notebook_name_entry; 28 | [GtkChild] 29 | public unowned He.Button notebook_add_button; 30 | 31 | public EditNotebooksDialog (MainWindow win, NotebookViewModel nbview_model, NoteViewModel view_model) { 32 | Object ( 33 | nbview_model: nbview_model, 34 | view_model: view_model 35 | ); 36 | this.win = win; 37 | this.set_modal (true); 38 | this.set_transient_for (win); 39 | 40 | notebook_name_entry.get_internal_entry ().notify["text"].connect (() => { 41 | if (notebook_name_entry.get_internal_entry ().get_text () != "") { 42 | notebook_add_button.sensitive = true; 43 | } else { 44 | notebook_add_button.sensitive = false; 45 | } 46 | }); 47 | 48 | this.add_css_class ("dialog-content"); 49 | } 50 | 51 | [GtkCallback] 52 | void on_new_notebook_requested () { 53 | var notebook = new Notebook (); 54 | notebook.title = notebook_name_entry.get_internal_entry ().text; 55 | nbview_model.create_new_notebook (notebook); 56 | notebook_name_entry.get_internal_entry ().text = ""; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Widgets/MainMenu.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 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 | namespace Notejot { 20 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/main_menu.ui")] 21 | public class Widgets.MainMenu : Gtk.Box { 22 | [GtkChild] 23 | public unowned He.Button about_button; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Widgets/MoveToDialog.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 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 | namespace Notejot { 20 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/move_to_dialog.ui")] 21 | public class Widgets.MoveToDialog : He.Window { 22 | public signal void clicked (); 23 | 24 | public unowned NoteContentView ncv = null; 25 | public NotebookViewModel nbview_model { get; set; } 26 | public NoteViewModel view_model { get; set; } 27 | 28 | [GtkChild] 29 | public unowned He.Button remove_notebook_button; 30 | [GtkChild] 31 | public unowned He.Button move_button; 32 | 33 | Notebook? _notebook; 34 | public Notebook? notebook { 35 | get { return _notebook; } 36 | set { 37 | if (value == _notebook) 38 | return; 39 | 40 | _notebook = value; 41 | 42 | move_button.sensitive = true; 43 | } 44 | } 45 | 46 | public MoveToDialog (NoteContentView ncv, NotebookViewModel nbview_model, NoteViewModel view_model) { 47 | Object ( 48 | nbview_model : nbview_model, 49 | view_model : view_model 50 | ); 51 | this.ncv = ncv; 52 | this.set_modal (true); 53 | this.set_transient_for (MiscUtils.find_ancestor_of_type (ncv)); 54 | 55 | if (ncv.note.notebook == _("No Notebook")) { 56 | remove_notebook_button.sensitive = false; 57 | } else { 58 | remove_notebook_button.sensitive = true; 59 | } 60 | 61 | this.add_css_class ("dialog-content"); 62 | } 63 | 64 | [GtkCallback] 65 | void on_move_notebook_requested () { 66 | string nb = notebook.title; 67 | view_model.update_notebook (ncv.note, nb); 68 | this.close (); 69 | } 70 | 71 | [GtkCallback] 72 | void on_remove_notebook_requested () { 73 | string nb = _("No Notebook"); 74 | view_model.update_notebook (ncv.note, nb); 75 | remove_notebook_button.set_sensitive (false); 76 | this.close (); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/Widgets/NoteRowContent.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/noterowcontent.ui")] 20 | public class Notejot.NoteRowContent : He.Bin { 21 | [GtkChild] 22 | private unowned Gtk.Image pin; 23 | [GtkChild] 24 | private unowned Gtk.Box box; 25 | [GtkChild] 26 | unowned He.ContentBlockImage image; 27 | 28 | private Binding? pinned_binding; 29 | private Binding? color_binding; 30 | private Binding? pix_binding; 31 | 32 | private Gtk.CssProvider provider = new Gtk.CssProvider (); 33 | 34 | private string? _color; 35 | public string? color { 36 | get { return _color; } 37 | set { 38 | if (value == _color) 39 | return; 40 | 41 | _color = value; 42 | 43 | if (_color == "") { 44 | provider.load_from_data ((uint8[]) "@define-color note_color @outline;"); 45 | ((MainWindow) MiscUtils.find_ancestor_of_type 46 | (this)).view_model.update_note_color (_note, _color); 47 | box.get_style_context ().add_provider (provider, 1); 48 | } else if (_color == "red") { 49 | provider.load_from_data ((uint8[]) "@define-color note_color @meson_red;"); 50 | ((MainWindow) MiscUtils.find_ancestor_of_type 51 | (this)).view_model.update_note_color (_note, _color); 52 | box.get_style_context ().add_provider (provider, 1); 53 | } else if (_color == "yellow") { 54 | provider.load_from_data ((uint8[]) "@define-color note_color @electron_yellow;"); 55 | ((MainWindow) MiscUtils.find_ancestor_of_type 56 | (this)).view_model.update_note_color (_note, _color); 57 | box.get_style_context ().add_provider (provider, 1); 58 | } else if (_color == "green") { 59 | provider.load_from_data ((uint8[]) "@define-color note_color @muon_green;"); 60 | ((MainWindow) MiscUtils.find_ancestor_of_type 61 | (this)).view_model.update_note_color (_note, _color); 62 | box.get_style_context ().add_provider (provider, 1); 63 | } else if (_color == "blue") { 64 | provider.load_from_data ((uint8[]) "@define-color note_color @proton_blue;"); 65 | ((MainWindow) MiscUtils.find_ancestor_of_type 66 | (this)).view_model.update_note_color (_note, _color); 67 | box.get_style_context ().add_provider (provider, 1); 68 | } else if (_color == "purple") { 69 | provider.load_from_data ((uint8[]) "@define-color note_color @tau_purple;"); 70 | ((MainWindow) MiscUtils.find_ancestor_of_type 71 | (this)).view_model.update_note_color (_note, _color); 72 | box.get_style_context ().add_provider (provider, 1); 73 | } 74 | } 75 | } 76 | 77 | private Note? _note; 78 | public Note? note { 79 | get { return _note; } 80 | set { 81 | if (value == _note) 82 | return; 83 | 84 | pinned_binding?.unbind (); 85 | 86 | color_binding?.unbind (); 87 | 88 | pix_binding?.unbind (); 89 | 90 | _note = value; 91 | 92 | pinned_binding = _note ? .bind_property ( 93 | "pinned", pin, "visible", SYNC_CREATE | BIDIRECTIONAL); 94 | color_binding = _note ? .bind_property ( 95 | "color", this, "color", SYNC_CREATE | BIDIRECTIONAL); 96 | pix_binding = _note ? .bind_property ( 97 | "picture", image, "file", SYNC_CREATE | BIDIRECTIONAL); 98 | 99 | if (_note != null) { 100 | if (_note.picture != "") { 101 | image.visible = true; 102 | } else { 103 | image.visible = false; 104 | } 105 | } 106 | 107 | image.notify["file"].connect (() => { 108 | if (image.file != "") { 109 | image.visible = true; 110 | } else { 111 | image.visible = false; 112 | } 113 | }); 114 | } 115 | } 116 | 117 | public NoteRowContent (Note note) { 118 | Object ( 119 | note : note 120 | ); 121 | } 122 | 123 | construct { 124 | box.add_css_class ("notejot-sidebar-box"); 125 | box.get_style_context ().add_provider (provider, 1); 126 | } 127 | 128 | [GtkCallback] 129 | string get_text_line () { 130 | var res = sync_text (note.text); 131 | return res; 132 | } 133 | 134 | [GtkCallback] 135 | string get_subtitle_line () { 136 | var res = sync_subtitles (note.subtitle); 137 | return res; 138 | } 139 | 140 | public string sync_subtitles (string subtitle) { 141 | string res = ""; 142 | try { 143 | var reg = new Regex ("""(?m)^.*, (?\d{2})/(?\d{2}) (?\d{2})∶(?\d{2})$"""); 144 | GLib.MatchInfo match; 145 | 146 | if (log != null) { 147 | if (reg.match (subtitle, 0, out match)) { 148 | var e = new GLib.DateTime.now_local (); 149 | var d = new DateTime.local (e.get_year (), 150 | int.parse (match.fetch_named ("month")), 151 | int.parse (match.fetch_named ("day")), 152 | int.parse (match.fetch_named ("hour")), 153 | int.parse (match.fetch_named ("minute")), 154 | e.get_second ()); 155 | 156 | res = "%s".printf (TimeUtils.get_relative_datetime_compact (d)); 157 | } 158 | } 159 | } catch (GLib.RegexError re) { 160 | warning ("%s".printf (re.message)); 161 | } 162 | 163 | return res; 164 | } 165 | 166 | public string sync_text (string text) { 167 | string res = ""; 168 | try { 169 | var reg = new Regex ("""(?m)^(?.*\n*.*)\n*"""); 170 | GLib.MatchInfo match; 171 | 172 | if (log != null) { 173 | if (reg.match (text, 0, out match)) { 174 | res = "%s".printf (match.fetch_named ("s")); 175 | } 176 | } 177 | } catch (GLib.RegexError re) { 178 | warning ("%s".printf (re.message)); 179 | } 180 | 181 | return res; 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/Widgets/NoteTheme.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2022 Lains 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 | namespace Notejot { 20 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/note_theme.ui")] 21 | public class Widgets.NoteTheme : Gtk.Box { 22 | [GtkChild] 23 | public unowned He.Button note_pin_button; 24 | [GtkChild] 25 | public unowned He.Button export_button; 26 | [GtkChild] 27 | public unowned Gtk.CheckButton color_button_red; 28 | [GtkChild] 29 | public unowned Gtk.CheckButton color_button_yellow; 30 | [GtkChild] 31 | public unowned Gtk.CheckButton color_button_green; 32 | [GtkChild] 33 | public unowned Gtk.CheckButton color_button_blue; 34 | [GtkChild] 35 | public unowned Gtk.CheckButton color_button_purple; 36 | [GtkChild] 37 | public unowned Gtk.CheckButton color_button_reset; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Widgets/NotebookMainRowContent.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/notebookmainrowcontent.ui")] 20 | public class Notejot.NotebookMainRowContent : He.Bin { 21 | public signal void clicked (); 22 | public NotebookViewModel? notebooks {get; set;} 23 | 24 | [GtkChild] 25 | public unowned Gtk.Label notebook_entry; 26 | 27 | Binding? text_binding; 28 | 29 | Notebook? _notebook; 30 | public Notebook? notebook { 31 | get { return _notebook; } 32 | set { 33 | if (value == _notebook) 34 | return; 35 | 36 | text_binding?.unbind (); 37 | 38 | _notebook = value; 39 | 40 | text_binding = _notebook?.bind_property ("title", notebook_entry, "label", SYNC_CREATE|BIDIRECTIONAL); 41 | } 42 | } 43 | 44 | construct { 45 | } 46 | } -------------------------------------------------------------------------------- /src/Widgets/NotebookRowContent.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/notebookrowcontent.ui")] 20 | public class Notejot.NotebookRowContent : He.Bin { 21 | public signal void clicked (); 22 | public NotebookViewModel? notebooks {get; set;} 23 | 24 | [GtkChild] 25 | public unowned He.TextField notebook_entry; 26 | 27 | Binding? text_binding; 28 | 29 | Notebook? _notebook; 30 | public Notebook? notebook { 31 | get { return _notebook; } 32 | set { 33 | if (value == _notebook) 34 | return; 35 | 36 | text_binding?.unbind (); 37 | 38 | _notebook = value; 39 | 40 | text_binding = _notebook?.bind_property ("title", notebook_entry, "text", SYNC_CREATE | BIDIRECTIONAL); 41 | } 42 | } 43 | 44 | construct { 45 | } 46 | 47 | [GtkCallback] 48 | async void on_edit_notebook_requested () { 49 | var vm = ((NotebookListView)MiscUtils.find_ancestor_of_type 50 | (this)).view_model; 51 | var notes = vm.notes; 52 | var nvm = ((NotebookListView)MiscUtils.find_ancestor_of_type 53 | (this)).nbview_model; 54 | var nbrepo = nvm.repository; 55 | List nbrepognbs = yield nbrepo.get_notebooks (); 56 | Notebook? target_notebook = nbrepo.search_notebook_by_id (nbrepognbs, notebook.id); 57 | 58 | uint i,n = notes.get_n_items (); 59 | for (i = 0; i < n; i++) { 60 | var item = notes.get_item (i); 61 | 62 | if (target_notebook.title == ((Note) item).notebook) { 63 | if (((Note) item).notebook != notebook_entry.get_internal_entry ().get_text ()) { 64 | vm.update_notebook (((Note) item), notebook_entry.get_internal_entry ().get_text ()); 65 | } 66 | } 67 | } 68 | 69 | ((NotebookListView)MiscUtils.find_ancestor_of_type 70 | (this)).nbview_model.update_notebook (notebook, notebook_entry.get_internal_entry ().get_text ()); 71 | } 72 | 73 | [GtkCallback] 74 | void on_delete_button_clicked () { 75 | var vm = ((NotebookListView)MiscUtils.find_ancestor_of_type 76 | (this)).view_model; 77 | var notes = vm.notes; 78 | 79 | uint i,n = notes.get_n_items (); 80 | for (i = 0; i < n; i++) { 81 | var item = notes.get_item (i); 82 | 83 | if (((Note) item).notebook == notebook_entry.get_internal_entry ().get_text ()) { 84 | vm.update_notebook (((Note) item), "No Notebook"); 85 | } 86 | } 87 | 88 | ((NotebookListView)MiscUtils.find_ancestor_of_type 89 | (this)).notebook_removal_requested (notebook); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Widgets/TrashRowContent.vala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2021 Lains 3 | * 4 | * This program is free software; you can redistribute it &&/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 | [GtkTemplate (ui = "/io/github/lainsce/Notejot/trashrowcontent.ui")] 20 | public class Notejot.TrashRowContent : He.Bin { 21 | [GtkChild] 22 | private unowned Gtk.Image pin; 23 | [GtkChild] 24 | private unowned Gtk.Box box; 25 | [GtkChild] 26 | unowned He.ContentBlockImage image; 27 | 28 | private Binding? pinned_binding; 29 | private Binding? color_binding; 30 | private Binding? pix_binding; 31 | 32 | private Gtk.CssProvider provider = new Gtk.CssProvider (); 33 | 34 | private string? _color; 35 | public string? color { 36 | get { return _color; } 37 | set { 38 | if (value == _color) 39 | return; 40 | 41 | _color = value; 42 | 43 | if (_color == "") { 44 | provider.load_from_data ((uint8[]) "@define-color note_color @outline;"); 45 | ((MainWindow) MiscUtils.find_ancestor_of_type 46 | (this)).tview_model.update_trash_color (_trash, _color); 47 | box.get_style_context ().add_provider (provider, 1); 48 | } else if (_color == "red") { 49 | provider.load_from_data ((uint8[]) "@define-color note_color @meson_red;"); 50 | ((MainWindow) MiscUtils.find_ancestor_of_type 51 | (this)).tview_model.update_trash_color (_trash, _color); 52 | box.get_style_context ().add_provider (provider, 1); 53 | } else if (_color == "yellow") { 54 | provider.load_from_data ((uint8[]) "@define-color note_color @electron_yellow;"); 55 | ((MainWindow) MiscUtils.find_ancestor_of_type 56 | (this)).tview_model.update_trash_color (_trash, _color); 57 | box.get_style_context ().add_provider (provider, 1); 58 | } else if (_color == "green") { 59 | provider.load_from_data ((uint8[]) "@define-color note_color @muon_green;"); 60 | ((MainWindow) MiscUtils.find_ancestor_of_type 61 | (this)).tview_model.update_trash_color (_trash, _color); 62 | box.get_style_context ().add_provider (provider, 1); 63 | } else if (_color == "blue") { 64 | provider.load_from_data ((uint8[]) "@define-color note_color @proton_blue;"); 65 | ((MainWindow) MiscUtils.find_ancestor_of_type 66 | (this)).tview_model.update_trash_color (_trash, _color); 67 | box.get_style_context ().add_provider (provider, 1); 68 | } else if (_color == "purple") { 69 | provider.load_from_data ((uint8[]) "@define-color note_color @tau_purple;"); 70 | ((MainWindow) MiscUtils.find_ancestor_of_type 71 | (this)).tview_model.update_trash_color (_trash, _color); 72 | box.get_style_context ().add_provider (provider, 1); 73 | } 74 | } 75 | } 76 | 77 | private Trash? _trash; 78 | public Trash? trash { 79 | get { return _trash; } 80 | set { 81 | if (value == _trash) 82 | return; 83 | 84 | pinned_binding?.unbind (); 85 | 86 | color_binding?.unbind (); 87 | 88 | pix_binding?.unbind (); 89 | 90 | _trash = value; 91 | 92 | pinned_binding = _trash ? .bind_property ( 93 | "pinned", pin, "visible", SYNC_CREATE | BIDIRECTIONAL); 94 | color_binding = _trash ? .bind_property ( 95 | "color", this, "color", SYNC_CREATE | BIDIRECTIONAL); 96 | pix_binding = _trash ? .bind_property ( 97 | "picture", image, "file", SYNC_CREATE | BIDIRECTIONAL); 98 | 99 | if (_trash != null) { 100 | if (_trash.picture != "") { 101 | image.visible = true; 102 | } else { 103 | image.visible = false; 104 | } 105 | } 106 | 107 | image.notify["file"].connect (() => { 108 | if (image.file != "") { 109 | image.visible = true; 110 | } else { 111 | image.visible = false; 112 | } 113 | }); 114 | } 115 | } 116 | 117 | public TrashRowContent (Trash trash) { 118 | Object ( 119 | trash : trash 120 | ); 121 | } 122 | 123 | construct { 124 | box.add_css_class ("notejot-sidebar-box"); 125 | box.get_style_context ().add_provider (provider, 1); 126 | } 127 | 128 | [GtkCallback] 129 | string get_text_line () { 130 | var res = sync_text (trash.text); 131 | return res; 132 | } 133 | 134 | [GtkCallback] 135 | string get_subtitle_line () { 136 | var res = sync_subtitles (trash.subtitle); 137 | return res; 138 | } 139 | 140 | public string sync_subtitles (string subtitle) { 141 | string res = ""; 142 | try { 143 | var reg = new Regex ("""(?m)^.*, (?\d{2})/(?\d{2}) (?\d{2})∶(?\d{2})$"""); 144 | GLib.MatchInfo match; 145 | 146 | if (log != null) { 147 | if (reg.match (subtitle, 0, out match)) { 148 | var e = new GLib.DateTime.now_local (); 149 | var d = new DateTime.local (e.get_year (), 150 | int.parse (match.fetch_named ("month")), 151 | int.parse (match.fetch_named ("day")), 152 | int.parse (match.fetch_named ("hour")), 153 | int.parse (match.fetch_named ("minute")), 154 | e.get_second ()); 155 | 156 | res = "%s".printf (TimeUtils.get_relative_datetime_compact (d)); 157 | } 158 | } 159 | } catch (GLib.RegexError re) { 160 | warning ("%s".printf (re.message)); 161 | } 162 | 163 | return res; 164 | } 165 | 166 | public string sync_text (string text) { 167 | string res = ""; 168 | try { 169 | var reg = new Regex ("""(?m)^(?.*\n*.*)\n*"""); 170 | GLib.MatchInfo match; 171 | 172 | if (log != null) { 173 | if (reg.match (text, 0, out match)) { 174 | res = "%s".printf (match.fetch_named ("s")); 175 | } 176 | } 177 | } catch (GLib.RegexError re) { 178 | warning ("%s".printf (re.message)); 179 | } 180 | 181 | return res; 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /subprojects/blueprint-compiler.wrap: -------------------------------------------------------------------------------- 1 | [wrap-git] 2 | directory = blueprint-compiler 3 | url = https://gitlab.gnome.org/jwestman/blueprint-compiler.git 4 | revision = main 5 | depth = 1 6 | 7 | [provide] 8 | program_names = blueprint-compiler --------------------------------------------------------------------------------