├── .gitignore ├── .gitmodules ├── LICENSE ├── VibratoNotes-Desktop.pro ├── compile.sh ├── devlog.org ├── include ├── fts_fuzzy_match.hpp └── helper-io.hpp ├── readme.md ├── resources ├── dummy-data.qrc ├── dummy │ ├── example-markdown.md │ ├── jsonexample.json │ ├── notebooks.json │ ├── notes-1000.json │ ├── notes.json │ ├── tags.json │ └── test.py ├── fonts.qrc ├── fonts │ ├── Cantarell-Bold.ttf │ ├── Cantarell-BoldOblique.ttf │ ├── Cantarell-Oblique.ttf │ ├── Cantarell-Regular.ttf │ └── SIL Open Font License.txt ├── icons.qrc ├── icons │ ├── vibrato-default-dark │ │ ├── icons │ │ │ ├── dialog-ok-apply.svg │ │ │ ├── document-new.svg │ │ │ ├── draw-star.svg │ │ │ ├── edit-find.svg │ │ │ ├── favorite.svg │ │ │ ├── folder.svg │ │ │ ├── im-user.svg │ │ │ ├── tag.svg │ │ │ └── trash-empty.svg │ │ └── index.theme │ └── vibrato-default │ │ ├── icons │ │ ├── dialog-ok-apply.svg │ │ ├── document-new.svg │ │ ├── document-revert.svg │ │ ├── edit-find.svg │ │ ├── favorite.svg │ │ ├── folder.svg │ │ ├── im-user.svg │ │ ├── tag.svg │ │ ├── trash-empty.svg │ │ ├── trash-empty2.svg │ │ ├── vibrato-draw-star-solid.svg │ │ ├── vibrato-draw-star.svg │ │ └── window-close.svg │ │ └── index.theme ├── qdarkstyle.qrc ├── rc │ ├── Hmovetoolbar.png │ ├── Hsepartoolbar.png │ ├── Vmovetoolbar.png │ ├── Vsepartoolbar.png │ ├── branch_closed-on.png │ ├── branch_closed.png │ ├── branch_open-on.png │ ├── branch_open.png │ ├── checkbox_checked.png │ ├── checkbox_checked_disabled.png │ ├── checkbox_checked_focus.png │ ├── checkbox_indeterminate.png │ ├── checkbox_indeterminate_disabled.png │ ├── checkbox_indeterminate_focus.png │ ├── checkbox_unchecked.png │ ├── checkbox_unchecked_disabled.png │ ├── checkbox_unchecked_focus.png │ ├── close-hover.png │ ├── close-pressed.png │ ├── close.png │ ├── down_arrow.png │ ├── down_arrow_disabled.png │ ├── left_arrow.png │ ├── left_arrow_disabled.png │ ├── radio_checked.png │ ├── radio_checked_disabled.png │ ├── radio_checked_focus.png │ ├── radio_unchecked.png │ ├── radio_unchecked_disabled.png │ ├── radio_unchecked_focus.png │ ├── right_arrow.png │ ├── right_arrow_disabled.png │ ├── sizegrip.png │ ├── stylesheet-branch-end.png │ ├── stylesheet-branch-more.png │ ├── stylesheet-vline.png │ ├── transparent.png │ ├── undock.png │ ├── up_arrow.png │ └── up_arrow_disabled.png ├── resource.qrc ├── sql │ └── create.sql ├── sqlfiles.qrc ├── style │ └── DarkSolarized.qss ├── test.qrc ├── tutorial.qrc └── tutorial │ └── 1-welcome.md ├── src ├── cloud │ ├── cloudmanager.cpp │ └── cloudmanager.h ├── crypto │ ├── vcrypto.cpp │ └── vcrypto.h ├── custom-components │ ├── customlineedit.cpp │ └── customlineedit.h ├── iconutils.cpp ├── iconutils.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── meta │ ├── db │ │ ├── database.cpp │ │ ├── database.h │ │ ├── notebookdatabase.cpp │ │ ├── notebookdatabase.h │ │ ├── notedatabase.cpp │ │ ├── notedatabase.h │ │ ├── tagdatabase.cpp │ │ └── tagdatabase.h │ ├── info │ │ ├── appconfig.cpp │ │ ├── appconfig.h │ │ └── appinfo.h │ ├── note.cpp │ ├── note.h │ ├── notebook.cpp │ ├── notebook.h │ ├── tag.cpp │ └── tag.h ├── models │ ├── delegates │ │ ├── noteitemdelegate.cpp │ │ └── noteitemdelegate.h │ ├── items │ │ ├── basictreeitem.cpp │ │ ├── basictreeitem.h │ │ ├── listitemwithid.cpp │ │ ├── listitemwithid.h │ │ ├── notelistitem.cpp │ │ ├── notelistitem.h │ │ ├── treeitemwithid.cpp │ │ └── treeitemwithid.h │ ├── notelistmodel.cpp │ ├── notelistmodel.h │ ├── sortfilter │ │ ├── notelistproxymodel.cpp │ │ └── notelistproxymodel.h │ ├── treemodel.cpp │ ├── treemodel.h │ └── views │ │ ├── customlistview.cpp │ │ ├── customlistview.h │ │ ├── customtreeview.cpp │ │ └── customtreeview.h ├── scripting-api │ ├── scriptingengine.cpp │ └── scriptingengine.h ├── sql │ ├── sqlmanager.cpp │ └── sqlmanager.h ├── ui-managers │ ├── escribamanager.cpp │ ├── escribamanager.h │ ├── manager.cpp │ ├── manager.h │ ├── notelist-views │ │ ├── genericview.cpp │ │ ├── genericview.h │ │ ├── trashview.cpp │ │ └── trashview.h │ ├── notelistmanager.cpp │ ├── notelistmanager.h │ ├── treemanager.cpp │ └── treemanager.h ├── userwindow.cpp └── userwindow.h ├── tests ├── VibratoNotes-Desktop-Tests.pro ├── resources │ ├── heroes-error.sql │ ├── heroes.sql │ └── testresources.qrc └── unit-tests.cpp └── ui ├── edittags.cpp ├── edittags.h ├── edittags.ui ├── escribaaddons.ui ├── mainwindow.ui ├── note_editnotebook.cpp ├── note_editnotebook.h ├── note_editnotebook.ui ├── note_edittags.cpp ├── note_edittags.h ├── note_edittags.ui ├── notebook_editparent.cpp ├── notebook_editparent.h ├── notebook_editparent.ui ├── notelist_addons.ui ├── notelistitem.ui ├── tagitem.ui ├── trashitem.cpp ├── trashitem.h ├── trashitem.ui └── userwindow.ui /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | .DS_Store 3 | 4 | build/ 5 | 6 | # C++ objects and libs 7 | *.slo 8 | *.lo 9 | *.o 10 | *.a 11 | *.la 12 | *.lai 13 | *.so 14 | *.dll 15 | *.dylib 16 | 17 | compile_commands.json 18 | 19 | # Qt-es 20 | object_script.*.Release 21 | object_script.*.Debug 22 | *_plugin_import.cpp 23 | /.qmake.cache 24 | /.qmake.stash 25 | *.pro.user 26 | *.pro.user.* 27 | *.qbs.user 28 | *.qbs.user.* 29 | *.moc 30 | moc_*.cpp 31 | moc_*.h 32 | qrc_*.cpp 33 | ui_*.h 34 | *.qmlc 35 | *.jsc 36 | Makefile* 37 | *build-* 38 | qmake/ 39 | 40 | # Qt unit tests 41 | target_wrapper.* 42 | 43 | # QtCreator 44 | *.autosave 45 | 46 | # QtCreator Qml 47 | *.qmlproject.user 48 | *.qmlproject.user.* 49 | 50 | # QtCreator CMake 51 | CMakeLists.txt.user* 52 | 53 | *~ 54 | *.core 55 | *.obj 56 | *.orig 57 | *.rej 58 | *.so.* 59 | *_pch.h.cpp 60 | *_resource.rc 61 | *.qm 62 | .#* 63 | *.*# 64 | core 65 | !core/ 66 | tags 67 | .directory 68 | *.debug 69 | *.prl 70 | *.app 71 | Thumbs.db 72 | *.res 73 | *.rc 74 | 75 | # qtcreator generated files 76 | *.pro.user* 77 | 78 | # xemacs temporary files 79 | *.flc 80 | 81 | # Vim temporary files 82 | .*.swp 83 | 84 | # Visual Studio generated files 85 | *.ib_pdb_index 86 | *.idb 87 | *.ilk 88 | *.pdb 89 | *.sln 90 | *.suo 91 | *.vcproj 92 | *vcproj.*.*.user 93 | *.ncb 94 | *.sdf 95 | *.opensdf 96 | *.vcxproj 97 | *vcxproj.* 98 | 99 | # MinGW generated files 100 | *.Release 101 | 102 | # Python byte code 103 | *.pyc 104 | 105 | # Binaries 106 | # -------- 107 | *.exe 108 | 109 | # cquery language server 110 | .cquery_cached_index/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/text-editor"] 2 | path = src/text-editor 3 | url = git@github.com:Open-App-Library/escriba.git 4 | [submodule "src/cloud/api"] 5 | path = src/cloud/api 6 | url = git@github.com:Open-App-Library/Qt-Vibrato-Cloud-API.git 7 | [submodule "src/crypto/vibrato-crypto-utils"] 8 | path = src/crypto/vibrato-crypto-utils 9 | url = git@github.com:Open-App-Library/Vibrato-Crypto-Utils.git 10 | -------------------------------------------------------------------------------- /VibratoNotes-Desktop.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2018-09-19T15:41:41 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui widgets sql 8 | 9 | TARGET = vibrato 10 | TEMPLATE = app 11 | 12 | LIBS += -lsodium 13 | LIBS += -lchicken 14 | 15 | # The following define makes your compiler emit warnings if you use 16 | # any feature of Qt which has been marked as deprecated (the exact warnings 17 | # depend on your compiler). Please consult the documentation of the 18 | # deprecated API in order to know how to port your code away from it. 19 | DEFINES += QT_DEPRECATED_WARNINGS 20 | 21 | # You can also make your code fail to compile if you use deprecated APIs. 22 | # In order to do so, uncomment the following line. 23 | # You can also select to disable deprecated APIs only up to a certain version of Qt. 24 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 25 | 26 | CONFIG += c++11 27 | 28 | VIBRATO_ENTRY_POINT=$$PWD/src/main.cpp 29 | 30 | SOURCES += \ 31 | $$VIBRATO_ENTRY_POINT \ 32 | $$PWD/src/meta/info/appconfig.cpp \ 33 | $$PWD/src/mainwindow.cpp \ 34 | $$PWD/src/userwindow.cpp \ 35 | $$PWD/src/ui-managers/notelistmanager.cpp \ 36 | $$PWD/src/meta/note.cpp \ 37 | $$PWD/src/meta/notebook.cpp \ 38 | $$PWD/src/meta/tag.cpp \ 39 | $$PWD/src/meta/db/notedatabase.cpp \ 40 | $$PWD/src/meta/db/notebookdatabase.cpp \ 41 | $$PWD/src/meta/db/tagdatabase.cpp \ 42 | $$PWD/src/models/treemodel.cpp \ 43 | $$PWD/src/models/items/basictreeitem.cpp \ 44 | $$PWD/src/ui-managers/manager.cpp \ 45 | $$PWD/src/ui-managers/treemanager.cpp \ 46 | $$PWD/src/ui-managers/escribamanager.cpp \ 47 | $$PWD/src/meta/db/database.cpp \ 48 | $$PWD/src/models/items/notelistitem.cpp \ 49 | $$PWD/src/models/notelistmodel.cpp \ 50 | $$PWD/src/models/views/customlistview.cpp \ 51 | $$PWD/ui/note_editnotebook.cpp \ 52 | $$PWD/src/models/items/treeitemwithid.cpp \ 53 | $$PWD/src/iconutils.cpp \ 54 | $$PWD/ui/note_edittags.cpp \ 55 | $$PWD/src/models/items/listitemwithid.cpp \ 56 | $$PWD/src/models/sortfilter/notelistproxymodel.cpp \ 57 | $$PWD/ui/edittags.cpp \ 58 | $$PWD/src/models/views/customtreeview.cpp \ 59 | $$PWD/ui/trashitem.cpp \ 60 | $$PWD/src/ui-managers/notelist-views/trashview.cpp \ 61 | $$PWD/src/ui-managers/notelist-views/genericview.cpp \ 62 | $$PWD/ui/notebook_editparent.cpp \ 63 | $$PWD/src/sql/sqlmanager.cpp \ 64 | $$PWD/src/models/delegates/noteitemdelegate.cpp \ 65 | $$PWD/src/custom-components/customlineedit.cpp \ 66 | $$PWD/src/cloud/cloudmanager.cpp \ 67 | $$PWD/src/crypto/vcrypto.cpp \ 68 | $$PWD/src/crypto/vibrato-crypto-utils/vibrato-crypto.c \ 69 | $$PWD/src/scripting-api/scriptingengine.cpp 70 | 71 | HEADERS += \ 72 | $$PWD/src/meta/info/appconfig.h \ 73 | $$PWD/src/meta/info/appinfo.h \ 74 | $$PWD/src/mainwindow.h \ 75 | $$PWD/src/userwindow.h \ 76 | $$PWD/src/ui-managers/notelistmanager.h \ 77 | $$PWD/src/meta/note.h \ 78 | $$PWD/src/meta/notebook.h \ 79 | $$PWD/src/meta/tag.h \ 80 | $$PWD/src/meta/db/notedatabase.h \ 81 | $$PWD/src/meta/db/notebookdatabase.h \ 82 | $$PWD/src/meta/db/tagdatabase.h \ 83 | $$PWD/include/helper-io.hpp \ 84 | $$PWD/src/models/treemodel.h \ 85 | $$PWD/src/models/items/basictreeitem.h \ 86 | $$PWD/src/ui-managers/manager.h \ 87 | $$PWD/src/ui-managers/treemanager.h \ 88 | $$PWD/src/ui-managers/escribamanager.h \ 89 | $$PWD/src/meta/db/database.h \ 90 | $$PWD/src/models/items/notelistitem.h \ 91 | $$PWD/src/models/notelistmodel.h \ 92 | $$PWD/src/models/views/customlistview.h \ 93 | $$PWD/ui/note_editnotebook.h \ 94 | $$PWD/src/models/items/treeitemwithid.h \ 95 | $$PWD/src/iconutils.h \ 96 | $$PWD/include/helper-io.hpp \ 97 | $$PWD/ui/note_edittags.h \ 98 | $$PWD/src/models/items/listitemwithid.h \ 99 | $$PWD/src/models/sortfilter/notelistproxymodel.h \ 100 | $$PWD/ui/edittags.h \ 101 | $$PWD/src/models/views/customtreeview.h \ 102 | $$PWD/ui/trashitem.h \ 103 | $$PWD/src/ui-managers/notelist-views/trashview.h \ 104 | $$PWD/src/ui-managers/notelist-views/genericview.h \ 105 | $$PWD/ui/notebook_editparent.h \ 106 | $$PWD/src/sql/sqlmanager.h \ 107 | $$PWD/src/models/delegates/noteitemdelegate.h \ 108 | $$PWD/src/custom-components/customlineedit.h \ 109 | $$PWD/src/cloud/cloudmanager.h \ 110 | $$PWD/src/crypto/vcrypto.h \ 111 | $$PWD/src/crypto/vibrato-crypto-utils/vibrato-crypto.h \ 112 | $$PWD/src/scripting-api/scriptingengine.h 113 | 114 | INCLUDEPATH += $$PWD/include 115 | INCLUDEPATH += $$PWD/src/models/views # Location of customlistview 116 | 117 | FORMS += \ 118 | $$PWD/ui/mainwindow.ui \ 119 | $$PWD/ui/userwindow.ui \ 120 | $$PWD/ui/notelistitem.ui \ 121 | $$PWD/ui/escribaaddons.ui \ 122 | $$PWD/ui/tagitem.ui \ 123 | $$PWD/ui/note_editnotebook.ui \ 124 | $$PWD/ui/note_edittags.ui \ 125 | $$PWD/ui/notelist_addons.ui \ 126 | $$PWD/ui/edittags.ui \ 127 | $$PWD/ui/trashitem.ui \ 128 | $$PWD/ui/notebook_editparent.ui 129 | 130 | include($$PWD/src/text-editor/Escriba.pro) 131 | include($$PWD/src/cloud/api/Qt-Vibrato-Cloud-API-Library.pro) 132 | 133 | 134 | RESOURCES += \ 135 | $$PWD/resources/dummy-data.qrc \ 136 | $$PWD/resources/icons.qrc \ 137 | $$PWD/resources/fonts.qrc \ 138 | $$PWD/resources/qdarkstyle.qrc \ 139 | $$PWD/resources/sqlfiles.qrc \ 140 | $$PWD/resources/tutorial.qrc 141 | 142 | # Default rules for deployment. 143 | qnx: target.path = /tmp/$${TARGET}/bin 144 | else: unix:!android: target.path = /opt/$${TARGET}/bin 145 | !isEmpty(target.path): INSTALLS += target 146 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This script will compile your project and generate a compile_commands.json. 4 | # How friggin awesome is that?? 5 | 6 | # Let's start off our journey by creaing a build directory. 7 | if ! [[ -n $BUILD_DIR ]]; then 8 | BUILD_DIR="build/" 9 | fi 10 | mkdir -p $BUILD_DIR 11 | cd $BUILD_DIR 12 | 13 | # Handy-dandy ASCII color variables 14 | normal=\\e[0m 15 | red=\\e[31m 16 | yellow=\\e[33m 17 | cyan=\\e[36m 18 | green=\\e[32m 19 | blue=\\e[34m 20 | 21 | ################################ 22 | # Process command-line options # 23 | ################################ 24 | if [[ $# < 1 ]]; then 25 | echo "" 26 | elif [[ "$1" == "help" ]] || [[ "$1" == "h" ]] || [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then 27 | echo "compile.sh" 28 | printf "$yellow" 29 | echo "A tool for compiling your project and generating a compile_commands.json." 30 | echo "" 31 | printf "$cyan" 32 | echo "Usage:" 33 | printf "$normal" 34 | echo " * View the help screen:" 35 | echo " ./compile.sh --help" 36 | echo "" 37 | echo " * General Usage:" 38 | echo " ./compile.sh" 39 | echo "" 40 | echo " * Clean your build:" 41 | echo " ./compile.sh clean" 42 | echo "" 43 | printf "$cyan" 44 | echo "Environmental Variables:" 45 | printf "$normal" 46 | echo " * \$BUILD_DIR" 47 | echo " Directory for project to be created" 48 | echo " --Defaults to \"build/\"" 49 | echo "" 50 | echo " Keep in mind that build/ is recommended because it" 51 | echo " is also gitignored. Also note that if your specified" 52 | echo " path does not exist, it will be recursively created." 53 | echo "" 54 | echo " * \$QMAKE_CMD" 55 | echo " Custom qmake command. (ex: \"qmake-qt5\")" 56 | echo " --Defaults to \"qmake\"" 57 | echo "" 58 | exit 59 | elif [[ $1 == "clean" ]]; then 60 | make clean 61 | rm -f ../compile_commands.json 62 | exit 63 | elif [[ $1 == "only_hope" ]]; then 64 | printf $blue 65 | printf " .==.\n ()''()-.\n .---. ;--; /\n .'_:___\". _..'. __'.\n |__ --==|'-''' \'...;\n [ ] :[| |---\\n |__| I=[| .' '.\n / / ____| : '._\n |-/.____.' | : :\n /___\ /___\ '-'._----'\n $normal art by Shanaka Dias\n\n" 66 | exit 67 | else 68 | echo "Unknown option \"$1\" :-(" 69 | exit 70 | fi 71 | 72 | 73 | #################################### 74 | # Do a very basic dependency check # 75 | #################################### 76 | 77 | # We are going to test if bear, qmake, and make are availible. 78 | export HAS_BEAR=0 HAS_QMAKE=0 HAS_MAKE=0 79 | 80 | # If user did not specify the QMAKE_CMD variable, default to "qmake" 81 | if ! [[ -n $QMAKE_CMD ]]; then 82 | QMAKE_CMD="qmake" 83 | fi 84 | 85 | # Compile tool dependency checking function 86 | 87 | function dep_check { 88 | program_name=$1 89 | missing_message=$2 90 | var_name=$3 91 | if ! which $program_name>/dev/null 2>&1; then 92 | printf "\n$missing_message" 93 | else 94 | eval $var_name=true 95 | fi 96 | } 97 | 98 | # Check for bear, qmake, and make 99 | dep_check "bear" \ 100 | "$yellow[WARNING]$normal 'bear' not found. compile_commands.json will not be generated.\n\tNeed to install bear? Get it here: https://github.com/rizsotto/Bear\n" \ 101 | "HAS_BEAR" 102 | dep_check $QMAKE_CMD \ 103 | "$red[FATAL]$normal 'qmake' not found.\n If you would like to specify a custom qmake command, you may set the QMAKE_CMD environmental variable\n $cyan ex. QMAKE_CMD=\"qmake-qt5\" ./compile.sh$normal\n" \ 104 | "HAS_QMAKE" 105 | dep_check "make" \ 106 | "$red[FATAL]$normal 'make' not found. Please ensure GNU make is installed\n" \ 107 | "HAS_MAKE" 108 | 109 | # Display error/warning messages if needed 110 | if [[ $HAS_QMAKE != true || $HAS_MAKE != true ]]; then 111 | printf "$red\n========== Failed dependency check :( ==========$normal\n\n" 112 | exit 113 | elif [[ $HAS_BEAR != true ]]; then 114 | printf "$yellow\n========== You've got 1 warning ¯\_(ツ)_/¯ ==========$normal\n\n" 115 | fi 116 | 117 | # Inform user that we are now compiling their project 118 | printf "$yellow" 119 | printf "Compiling your project...\n\n" 120 | printf "$normal" 121 | 122 | 123 | #################################### 124 | # Compiling the project # 125 | #################################### 126 | 127 | echo "QT += testlib" > VibratoNotes.pro 128 | echo "include(../VibratoNotes-Desktop.pro)" >> VibratoNotes.pro 129 | 130 | qmake VibratoNotes.pro 131 | 132 | if [[ $HAS_BEAR == true ]]; then 133 | bear -a -o ../compile_commands.json make -j$(nproc) 134 | else 135 | make -j$(nproc) 136 | fi 137 | -------------------------------------------------------------------------------- /devlog.org: -------------------------------------------------------------------------------- 1 | #+title: Devlog: Vibrato Weekly Accomplishments 2 | 3 | This file tracks the weekly development progress on Vibrato Notes - new features, bug fixes, and more. 4 | 5 | * 2018 6 | ** December 9 - December 15 7 | *** Added various tag operations (add tag, delete tag, rename tag) 8 | *** Created a 'Manager' class to hold all of the UI Managers. This makes it easy to access each of the UI Manager instances in all of the UI Manager classes. 9 | *** Improved the ux of the 'New Note' feature. 10 | *** Made the notelist sidebar properly refresh when a notebook is renamed. 11 | *** Fixed bug where imported notebooks in 'Default Notebook' weren't properly set. 12 | ** December 16 - December 22 13 | *** Added a 'trash note' functionality! 14 | *** Created a new UI for trashing notes - with bulk-trash/restore! 15 | *** Polished tagging functions 16 | *** Added "favorite note" functionality! 17 | *** Added solid yellow star icon to indicate favorited notes (resources/icons/vibrato-default/icons/vibrato-draw-star-solid.svg) 18 | *** Added "favorite note" icon to the Escriba text editor toolbar 19 | *** Made favorites view update when you un-favorite a note 20 | *** Added "trashed" property to Note class 21 | *** Updated the Note class to utilize the updateModifiedDate boolean 22 | ** December 23 - December 29 23 | *** Fuzzy searching capabilities! 24 | *** Added auto-completion when tagging notes 25 | *** Added API for search results 26 | *** Added note-searching UI 27 | *** Made notebook and tags labels not selectable. 28 | *** Fixed a segfault bug when user is deleting a tag/notebook they are viewing. 29 | *** Fixed bug where title in note list wouldn't update properly. 30 | *** Fixed bugs while renaming tags 31 | * 2019 32 | ** January 1 - 5 33 | *** You can now save notes! 34 | *** Notes load & sync locally using SQLite3 35 | *** Created SQLManager and unit-tests for it. 36 | *** You can change the hierarchy of notebook 37 | *** File>>New - a new way to create notes, notebooks and tags 38 | *** Creation shortcut keys - New Note (Ctrl+n), New Notebook (Ctrl+Shift+n), New Tag (Ctrl+Alt+n). 39 | -------------------------------------------------------------------------------- /include/helper-io.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * helper-io.h 3 | * ----------------------------------------------------------------------- 4 | * This file is to provide quick little helper functions for this project. 5 | * It is essentially a header-only library. 6 | */ 7 | 8 | #pragma once 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | class HelperIO { 17 | public: 18 | 19 | // File/directory functions 20 | static QDir dataDir() 21 | { 22 | QDir data_dir = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); 23 | if ( !data_dir.exists() ) 24 | data_dir.mkpath("."); 25 | return data_dir; 26 | } 27 | 28 | // Warning: Returns a char* that must be deleted. 29 | static char *QString2CString(QString str) 30 | { 31 | int len = str.length()+1; 32 | char *new_string = static_cast(malloc(len)); 33 | 34 | std::string std_str = str.toStdString(); 35 | 36 | for (int i=0; i 2 | 3 | dummy/notes.json 4 | dummy/notebooks.json 5 | dummy/tags.json 6 | dummy/jsonexample.json 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/dummy/example-markdown.md: -------------------------------------------------------------------------------- 1 | An h1 header 2 | ============ 3 | 4 | Paragraphs are separated by a blank line. 5 | 6 | 2nd paragraph. *Italic*, **bold**, and `monospace`. Itemized lists 7 | look like: 8 | 9 | * this one 10 | * that one 11 | * the other one 12 | 13 | Note that --- not considering the asterisk --- the actual text 14 | content starts at 4-columns in. 15 | 16 | > Block quotes are 17 | > written like so. 18 | > 19 | > They can span multiple paragraphs, 20 | > if you like. 21 | 22 | Use 3 dashes for an em-dash. Use 2 dashes for ranges (ex., "it's all 23 | in chapters 12--14"). Three dots ... will be converted to an ellipsis. 24 | Unicode is supported. ☺ 25 | 26 | 27 | 28 | An h2 header 29 | ------------ 30 | 31 | Here's a numbered list: 32 | 33 | 1. first item 34 | 2. second item 35 | 3. third item 36 | 37 | Note again how the actual text starts at 4 columns in (4 characters 38 | from the left side). Here's a code sample: 39 | 40 | # Let me re-iterate ... 41 | for i in 1 .. 10 { do-something(i) } 42 | 43 | As you probably guessed, indented 4 spaces. By the way, instead of 44 | indenting the block, you can use delimited blocks, if you like: 45 | 46 | ~~~ 47 | define foobar() { 48 | print "Welcome to flavor country!"; 49 | } 50 | ~~~ 51 | 52 | (which makes copying & pasting easier). You can optionally mark the 53 | delimited block for Pandoc to syntax highlight it: 54 | 55 | ~~~python 56 | import time 57 | # Quick, count to ten! 58 | for i in range(10): 59 | # (but not *too* quick) 60 | time.sleep(0.5) 61 | print i 62 | ~~~ 63 | 64 | 65 | 66 | ### An h3 header ### 67 | 68 | Now a nested list: 69 | 70 | 1. First, get these ingredients: 71 | 72 | * carrots 73 | * celery 74 | * lentils 75 | 76 | 2. Boil some water. 77 | 78 | 3. Dump everything in the pot and follow 79 | this algorithm: 80 | 81 | find wooden spoon 82 | uncover pot 83 | stir 84 | cover pot 85 | balance wooden spoon precariously on pot handle 86 | wait 10 minutes 87 | goto first step (or shut off burner when done) 88 | 89 | Do not bump wooden spoon or it will fall. 90 | 91 | Notice again how text always lines up on 4-space indents (including 92 | that last line which continues item 3 above). 93 | 94 | Here's a link to [a website](http://foo.bar), to a [local 95 | doc](local-doc.html), and to a [section heading in the current 96 | doc](#an-h2-header). Here's a footnote [^1]. 97 | 98 | [^1]: Footnote text goes here. 99 | 100 | Tables can look like this: 101 | 102 | size material color 103 | ---- ------------ ------------ 104 | 9 leather brown 105 | 10 hemp canvas natural 106 | 11 glass transparent 107 | 108 | Table: Shoes, their sizes, and what they're made of 109 | 110 | (The above is the caption for the table.) Pandoc also supports 111 | multi-line tables: 112 | 113 | -------- ----------------------- 114 | keyword text 115 | -------- ----------------------- 116 | red Sunsets, apples, and 117 | other red or reddish 118 | things. 119 | 120 | green Leaves, grass, frogs 121 | and other things it's 122 | not easy being. 123 | -------- ----------------------- 124 | 125 | A horizontal rule follows. 126 | 127 | *** 128 | 129 | Here's a definition list: 130 | 131 | apples 132 | : Good for making applesauce. 133 | oranges 134 | : Citrus! 135 | tomatoes 136 | : There's no "e" in tomatoe. 137 | 138 | # Another H1 139 | 140 | Again, text is indented 4 spaces. (Put a blank line between each 141 | term/definition pair to spread things out more.) 142 | 143 | Here's a "line block": 144 | 145 | | Line one 146 | | Line too 147 | | Line tree 148 | 149 | and images can be specified like so: 150 | 151 | ![example image](example-image.jpg "An exemplary image") 152 | 153 | Inline math equations go in like so: $\omega = d\phi / dt$. Display 154 | math should get its own line and be put in in double-dollarsigns: 155 | 156 | $$I = \int \rho R^{2} dV$$ 157 | 158 | And note that you can backslash-escape any punctuation characters 159 | which you wish to be displayed literally, ex.: \`foo\`, \*bar\*, etc. 160 | -------------------------------------------------------------------------------- /resources/dummy/jsonexample.json: -------------------------------------------------------------------------------- 1 | { 2 | "appDesc": { 3 | "description": "SomeDescription", 4 | "message": "SomeMessage" 5 | }, 6 | "appName": { 7 | "description": "Home", 8 | "message": "Welcome", 9 | "imp":["awesome","best","good"] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /resources/dummy/notebooks.json: -------------------------------------------------------------------------------- 1 | [ 2 | {"title": "Million-Dollar Business Ideas", "is_public": false, "id": 10, "parent": null}, 3 | {"title": "Drawings", "is_public": true, "id": 1, "parent": null}, 4 | {"title": "Book Notes", "is_public": false, "id": 2, "parent": null}, 5 | { 6 | "title": "Recipes", "is_public": true, "id": 3, "parent": null, 7 | "children": [ 8 | {"title": "Summer Recipes", "is_public": false, "id": 4, "parent": 3}, 9 | {"title": "Winter Recipes", "is_public": false, "id": 5, "parent": 3}, 10 | { 11 | "title": "Easy Recipes", "is_public": false, "id": 6, "parent": 3, 12 | "children": [ 13 | {"title": "Breakfast", "is_public": false, "id": 7, "parent": 6}, 14 | {"title": "Lunch", "is_public": false, "id": 8, "parent": 6}, 15 | {"title": "Dinner", "is_public": false, "id": 9, "parent": 6} 16 | ] 17 | } 18 | ] 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /resources/dummy/tags.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "title": "2018", "id": 1 }, 3 | { "title": "1995", "id": 2 }, 4 | { "title": "finance", "id": 3 }, 5 | { "title": "work", "id": 4 }, 6 | { "title": "linux", "id": 5 } 7 | ] 8 | -------------------------------------------------------------------------------- /resources/dummy/test.py: -------------------------------------------------------------------------------- 1 | import json 2 | file = open("notes.json", "r").read() 3 | 4 | notes = json.loads(file) 5 | 6 | count = 0; 7 | 8 | for note in notes: 9 | if note['notebook'] == None: 10 | count += 1 11 | 12 | print(count) 13 | -------------------------------------------------------------------------------- /resources/fonts.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | fonts/Cantarell-Bold.ttf 4 | fonts/Cantarell-Oblique.ttf 5 | fonts/Cantarell-BoldOblique.ttf 6 | fonts/Cantarell-Regular.ttf 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/fonts/Cantarell-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/fonts/Cantarell-Bold.ttf -------------------------------------------------------------------------------- /resources/fonts/Cantarell-BoldOblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/fonts/Cantarell-BoldOblique.ttf -------------------------------------------------------------------------------- /resources/fonts/Cantarell-Oblique.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/fonts/Cantarell-Oblique.ttf -------------------------------------------------------------------------------- /resources/fonts/Cantarell-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/fonts/Cantarell-Regular.ttf -------------------------------------------------------------------------------- /resources/fonts/SIL Open Font License.txt: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 2 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL 3 | 4 | ----------------------------------------------------------- 5 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 6 | ----------------------------------------------------------- 7 | 8 | PREAMBLE 9 | The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others. 10 | 11 | The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives. 12 | 13 | DEFINITIONS 14 | "Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation. 15 | 16 | "Reserved Font Name" refers to any names specified as such after the copyright statement(s). 17 | 18 | "Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s). 19 | 20 | "Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment. 21 | 22 | "Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software. 23 | 24 | PERMISSION & CONDITIONS 25 | Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions: 26 | 27 | 1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself. 28 | 29 | 2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user. 30 | 31 | 3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users. 32 | 33 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission. 34 | 35 | 5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software. 36 | 37 | TERMINATION 38 | This license becomes null and void if any of the above conditions are not met. 39 | 40 | DISCLAIMER 41 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. -------------------------------------------------------------------------------- /resources/icons.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | icons/vibrato-default/index.theme 4 | icons/vibrato-default/icons/tag.svg 5 | icons/vibrato-default/icons/folder.svg 6 | icons/vibrato-default/icons/document-new.svg 7 | icons/vibrato-default/icons/im-user.svg 8 | icons/vibrato-default/icons/trash-empty.svg 9 | icons/vibrato-default/icons/trash-empty2.svg 10 | icons/vibrato-default/icons/edit-find.svg 11 | icons/vibrato-default/icons/vibrato-draw-star.svg 12 | icons/vibrato-default/icons/vibrato-draw-star-solid.svg 13 | icons/vibrato-default/icons/favorite.svg 14 | icons/vibrato-default/icons/dialog-ok-apply.svg 15 | icons/vibrato-default/icons/document-revert.svg 16 | icons/vibrato-default/icons/window-close.svg 17 | 18 | icons/vibrato-default-dark/icons/document-new.svg 19 | icons/vibrato-default-dark/icons/draw-star.svg 20 | icons/vibrato-default-dark/icons/edit-find.svg 21 | icons/vibrato-default-dark/icons/favorite.svg 22 | icons/vibrato-default-dark/icons/folder.svg 23 | icons/vibrato-default-dark/icons/im-user.svg 24 | icons/vibrato-default-dark/icons/tag.svg 25 | icons/vibrato-default-dark/icons/trash-empty.svg 26 | icons/vibrato-default-dark/index.theme 27 | icons/vibrato-default-dark/icons/dialog-ok-apply.svg 28 | 29 | 30 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/dialog-ok-apply.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/document-new.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 48 | 51 | 52 | 54 | 61 | 62 | 66 | 67 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/draw-star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/edit-find.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/favorite.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/im-user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/icons/trash-empty.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default-dark/index.theme: -------------------------------------------------------------------------------- 1 | [Icon Theme] 2 | Name=Vibrato Default (Dark) 3 | Comment=Default dark icon set for Vibrato Notes. Uses Breeze icons mostly. 4 | 5 | [icons] 6 | Size=16 7 | Context=Actions 8 | Type=Scalable 9 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/dialog-ok-apply.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/document-new.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 42 | 46 | 50 | 54 | 58 | 62 | 66 | 70 | 74 | 77 | 81 | 85 | 89 | 93 | 97 | 101 | 105 | 109 | 110 | 112 | 113 | 115 | image/svg+xml 116 | 118 | 119 | 120 | 121 | 122 | 127 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/document-revert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/edit-find.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/favorite.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/im-user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/tag.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 20 | 22 | 26 | 30 | 31 | 38 | 45 | 52 | 59 | 62 | 65 | 66 | 69 | 72 | 73 | 74 | 99 | 102 | 106 | 110 | 114 | 118 | 122 | 126 | 130 | 134 | 135 | 137 | 138 | 140 | image/svg+xml 141 | 143 | 144 | 145 | 146 | 147 | 152 | 156 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/trash-empty.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/trash-empty2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/vibrato-draw-star-solid.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 20 | image/svg+xml 21 | 23 | 24 | 25 | 26 | 46 | 48 | 55 | 56 | 60 | 67 | 68 | 73 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/vibrato-draw-star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/icons/window-close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 17 | 18 | -------------------------------------------------------------------------------- /resources/icons/vibrato-default/index.theme: -------------------------------------------------------------------------------- 1 | [Icon Theme] 2 | Name=Vibrato Default 3 | Comment=Default icon set for Vibrato Notes. Uses Breeze icons mostly. 4 | 5 | [icons] 6 | Size=16 7 | Context=Actions 8 | Type=Scalable 9 | -------------------------------------------------------------------------------- /resources/qdarkstyle.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | style/DarkSolarized.qss 4 | 5 | 6 | rc/branch_closed.png 7 | rc/branch_closed-on.png 8 | rc/branch_open.png 9 | rc/branch_open-on.png 10 | rc/checkbox_checked.png 11 | rc/checkbox_checked_disabled.png 12 | rc/checkbox_checked_focus.png 13 | rc/checkbox_indeterminate.png 14 | rc/checkbox_indeterminate_disabled.png 15 | rc/checkbox_indeterminate_focus.png 16 | rc/checkbox_unchecked.png 17 | rc/checkbox_unchecked_disabled.png 18 | rc/checkbox_unchecked_focus.png 19 | rc/close.png 20 | rc/close-hover.png 21 | rc/close-pressed.png 22 | rc/down_arrow.png 23 | rc/down_arrow_disabled.png 24 | rc/Hmovetoolbar.png 25 | rc/Hsepartoolbar.png 26 | rc/left_arrow.png 27 | rc/left_arrow_disabled.png 28 | rc/radio_checked.png 29 | rc/radio_checked_disabled.png 30 | rc/radio_checked_focus.png 31 | rc/radio_unchecked.png 32 | rc/radio_unchecked_disabled.png 33 | rc/radio_unchecked_focus.png 34 | rc/right_arrow.png 35 | rc/right_arrow_disabled.png 36 | rc/sizegrip.png 37 | rc/stylesheet-branch-end.png 38 | rc/stylesheet-branch-more.png 39 | rc/stylesheet-vline.png 40 | rc/transparent.png 41 | rc/undock.png 42 | rc/up_arrow.png 43 | rc/up_arrow_disabled.png 44 | rc/Vmovetoolbar.png 45 | rc/Vsepartoolbar.png 46 | 47 | 48 | -------------------------------------------------------------------------------- /resources/rc/Hmovetoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/Hmovetoolbar.png -------------------------------------------------------------------------------- /resources/rc/Hsepartoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/Hsepartoolbar.png -------------------------------------------------------------------------------- /resources/rc/Vmovetoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/Vmovetoolbar.png -------------------------------------------------------------------------------- /resources/rc/Vsepartoolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/Vsepartoolbar.png -------------------------------------------------------------------------------- /resources/rc/branch_closed-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/branch_closed-on.png -------------------------------------------------------------------------------- /resources/rc/branch_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/branch_closed.png -------------------------------------------------------------------------------- /resources/rc/branch_open-on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/branch_open-on.png -------------------------------------------------------------------------------- /resources/rc/branch_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/branch_open.png -------------------------------------------------------------------------------- /resources/rc/checkbox_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_checked.png -------------------------------------------------------------------------------- /resources/rc/checkbox_checked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_checked_disabled.png -------------------------------------------------------------------------------- /resources/rc/checkbox_checked_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_checked_focus.png -------------------------------------------------------------------------------- /resources/rc/checkbox_indeterminate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_indeterminate.png -------------------------------------------------------------------------------- /resources/rc/checkbox_indeterminate_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_indeterminate_disabled.png -------------------------------------------------------------------------------- /resources/rc/checkbox_indeterminate_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_indeterminate_focus.png -------------------------------------------------------------------------------- /resources/rc/checkbox_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_unchecked.png -------------------------------------------------------------------------------- /resources/rc/checkbox_unchecked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_unchecked_disabled.png -------------------------------------------------------------------------------- /resources/rc/checkbox_unchecked_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/checkbox_unchecked_focus.png -------------------------------------------------------------------------------- /resources/rc/close-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/close-hover.png -------------------------------------------------------------------------------- /resources/rc/close-pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/close-pressed.png -------------------------------------------------------------------------------- /resources/rc/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/close.png -------------------------------------------------------------------------------- /resources/rc/down_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/down_arrow.png -------------------------------------------------------------------------------- /resources/rc/down_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/down_arrow_disabled.png -------------------------------------------------------------------------------- /resources/rc/left_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/left_arrow.png -------------------------------------------------------------------------------- /resources/rc/left_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/left_arrow_disabled.png -------------------------------------------------------------------------------- /resources/rc/radio_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/radio_checked.png -------------------------------------------------------------------------------- /resources/rc/radio_checked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/radio_checked_disabled.png -------------------------------------------------------------------------------- /resources/rc/radio_checked_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/radio_checked_focus.png -------------------------------------------------------------------------------- /resources/rc/radio_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/radio_unchecked.png -------------------------------------------------------------------------------- /resources/rc/radio_unchecked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/radio_unchecked_disabled.png -------------------------------------------------------------------------------- /resources/rc/radio_unchecked_focus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/radio_unchecked_focus.png -------------------------------------------------------------------------------- /resources/rc/right_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/right_arrow.png -------------------------------------------------------------------------------- /resources/rc/right_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/right_arrow_disabled.png -------------------------------------------------------------------------------- /resources/rc/sizegrip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/sizegrip.png -------------------------------------------------------------------------------- /resources/rc/stylesheet-branch-end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/stylesheet-branch-end.png -------------------------------------------------------------------------------- /resources/rc/stylesheet-branch-more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/stylesheet-branch-more.png -------------------------------------------------------------------------------- /resources/rc/stylesheet-vline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/stylesheet-vline.png -------------------------------------------------------------------------------- /resources/rc/transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/transparent.png -------------------------------------------------------------------------------- /resources/rc/undock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/undock.png -------------------------------------------------------------------------------- /resources/rc/up_arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/up_arrow.png -------------------------------------------------------------------------------- /resources/rc/up_arrow_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Open-App-Library/Vibrato-Notes-Desktop/eee48e05a224ea83987f8e269192afad845fc947/resources/rc/up_arrow_disabled.png -------------------------------------------------------------------------------- /resources/resource.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | dummy-content.txt 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/sql/create.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS notes ( 2 | sync_hash STRING UNIQUE, 3 | title TEXT, 4 | text TEXT, 5 | date_created DATETIME, 6 | date_modified DATETIME, 7 | notebook STRING REFERENCES notebooks(sync_hash), 8 | favorited BOOLEAN, 9 | encrypted BOOLEAN, 10 | trashed BOOLEAN 11 | ); 12 | 13 | CREATE TABLE if NOT EXISTS notebooks ( 14 | sync_hash INTEGER unique, 15 | title TEXT, 16 | date_modified DATETIME, 17 | parent STRING REFERENCES notebooks(sync_hash), 18 | row INTEGER, 19 | encrypted BOOLEAN 20 | ); 21 | 22 | CREATE TABLE IF NOT EXISTS tags ( 23 | sync_hash INTEGER UNIQUE, 24 | title TEXT, 25 | date_modified DATETIME, 26 | row INTEGER, 27 | encrypted BOOLEAN 28 | ); 29 | 30 | -- Many-to-many relationship between notes and tags 31 | CREATE TABLE IF NOT EXISTS notes_tags ( 32 | note STRING REFERENCES notes(sync_hash), 33 | tag INTEGER REFERENCES tags(sync_hash) 34 | ); 35 | -------------------------------------------------------------------------------- /resources/sqlfiles.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | sql/create.sql 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/tutorial.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | tutorial/1-welcome.md 4 | 5 | 6 | -------------------------------------------------------------------------------- /resources/tutorial/1-welcome.md: -------------------------------------------------------------------------------- 1 | **Welcome to Vibrato-Notes!** 2 | 3 | This is a test. 4 | -------------------------------------------------------------------------------- /src/cloud/cloudmanager.cpp: -------------------------------------------------------------------------------- 1 | #include "cloudmanager.h" 2 | 3 | CloudManager::CloudManager() 4 | { 5 | 6 | } 7 | 8 | QDateTime CloudManager::lastSync() const { 9 | return m_lastSync; 10 | } 11 | 12 | QDateTime CloudManager::lastRefresh() const { 13 | return m_lastRefresh; 14 | } 15 | 16 | bool CloudManager::noteExists(QUuid syncHash, bool refresh) 17 | { 18 | if (refresh) 19 | refreshNotes(); 20 | return m_noteList.contains(syncHash); 21 | } 22 | 23 | bool CloudManager::notebookExists(QUuid syncHash, bool refresh) 24 | { 25 | if (refresh) 26 | refreshNotebooks(); 27 | return m_notebookList.contains(syncHash); 28 | } 29 | 30 | bool CloudManager::tagExists(QUuid syncHash, bool refresh) 31 | { 32 | if (refresh) 33 | refreshTags(); 34 | return m_tagList.contains(syncHash); 35 | } 36 | 37 | void CloudManager::refresh() 38 | { 39 | refreshNotes(); 40 | refreshNotebooks(); 41 | refreshTags(); 42 | } 43 | 44 | void CloudManager::refreshNotes() 45 | { 46 | 47 | } 48 | 49 | void CloudManager::refreshNotebooks() 50 | { 51 | 52 | } 53 | 54 | void CloudManager::refreshTags() 55 | { 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/cloud/cloudmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef CLOUDMANAGER_H 2 | #define CLOUDMANAGER_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "api/vibrato-cloud-api.h" 8 | 9 | class CloudManager : public QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | CloudManager(); 14 | 15 | QDateTime lastSync() const; 16 | QDateTime lastRefresh() const; 17 | 18 | bool noteExists(QUuid syncHash, bool refresh=false); 19 | bool notebookExists(QUuid syncHash, bool refresh=false); 20 | bool tagExists(QUuid syncHash, bool refresh=false); 21 | 22 | void refresh(); 23 | void refreshNotes(); 24 | void refreshNotebooks(); 25 | void refreshTags(); 26 | 27 | private: 28 | QDateTime m_lastSync; 29 | QDateTime m_lastRefresh; 30 | 31 | QVector m_noteList; 32 | QVector m_notebookList; 33 | QVector m_tagList; 34 | }; 35 | 36 | #endif // CLOUDMANAGER_H 37 | -------------------------------------------------------------------------------- /src/crypto/vcrypto.cpp: -------------------------------------------------------------------------------- 1 | #include "vcrypto.h" 2 | #include "vibrato-crypto-utils/vibrato-crypto.h" 3 | #include 4 | 5 | VCrypto::VCrypto(QObject *parent) : QObject(parent) 6 | { 7 | if (vcrypto_init() < 0) { 8 | puts("vcrypto cannot init!"); 9 | } 10 | } 11 | 12 | bool VCrypto::login(QString email, QString password) { 13 | 14 | unsigned char key[crypto_secretbox_KEYBYTES]; 15 | unsigned char pubkey[crypto_box_PUBLICKEYBYTES]; 16 | 17 | if (vcrypto_get_privatekey(key, (unsigned char*) email.toLatin1().data(), password.toLatin1().data()) != 0) { 18 | puts("FAILED! privkey"); 19 | free(key); 20 | return false; 21 | } 22 | if (vcrypto_get_publickey(pubkey, key) != 0) { 23 | puts("FAILED! pubkey"); 24 | free(key); 25 | free(pubkey); 26 | return false; 27 | } 28 | 29 | m_private_key = ""; 30 | m_public_key = ""; 31 | 32 | for (int i=0; i < (int) crypto_secretbox_KEYBYTES; i++) 33 | m_private_key.append(key[i]); 34 | 35 | for (int i=0; i < (int) crypto_box_PUBLICKEYBYTES; i++) 36 | m_public_key.append(pubkey[i]); 37 | 38 | return true; 39 | } 40 | 41 | QString VCrypto::encrypt(QString message) { 42 | QString b; 43 | 44 | return b; 45 | } 46 | 47 | QString VCrypto::decrypt(QString enc_message) { 48 | QString b; 49 | 50 | return b; 51 | } 52 | -------------------------------------------------------------------------------- /src/crypto/vcrypto.h: -------------------------------------------------------------------------------- 1 | #ifndef VCRYPTO_H 2 | #define VCRYPTO_H 3 | 4 | #include 5 | 6 | class VCrypto : public QObject 7 | { 8 | Q_OBJECT 9 | public: 10 | explicit VCrypto(QObject *parent = nullptr); 11 | 12 | bool login(QString email, QString password); 13 | QString encrypt(QString message); 14 | QString decrypt(QString enc_message); 15 | 16 | signals: 17 | 18 | public slots: 19 | 20 | private: 21 | QString m_private_key; 22 | QString m_public_key; 23 | }; 24 | 25 | #endif // VCRYPTO_H 26 | -------------------------------------------------------------------------------- /src/custom-components/customlineedit.cpp: -------------------------------------------------------------------------------- 1 | #include "customlineedit.h" 2 | #include 3 | 4 | CustomLineEdit::CustomLineEdit(QWidget *parent) : QLineEdit(parent) 5 | { 6 | 7 | } 8 | 9 | void CustomLineEdit::setDisableTypicalTabKeyBehavior(bool disableTypicalTabKeyBehavior) { 10 | m_disableTypicalTabKeyBehavior = disableTypicalTabKeyBehavior; 11 | } 12 | 13 | bool CustomLineEdit::event(QEvent *event) 14 | { 15 | if (event->type() == QEvent::KeyPress) { 16 | QKeyEvent *keyEvent = static_cast(event); 17 | if (keyEvent->key() == Qt::Key_Tab) { 18 | emit tabPressed(); 19 | if (m_disableTypicalTabKeyBehavior) 20 | return true; 21 | else 22 | return QLineEdit::event(event); 23 | } 24 | } 25 | return QLineEdit::event(event); 26 | } 27 | -------------------------------------------------------------------------------- /src/custom-components/customlineedit.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMLINEEDIT_H 2 | #define CUSTOMLINEEDIT_H 3 | #include 4 | 5 | class CustomLineEdit : public QLineEdit 6 | { 7 | Q_OBJECT 8 | public: 9 | CustomLineEdit(QWidget *parent=nullptr); 10 | 11 | void setDisableTypicalTabKeyBehavior(bool disableTypicalTabKeyBehavior=true); 12 | 13 | bool event(QEvent *event) override; 14 | 15 | signals: 16 | void tabPressed(); 17 | 18 | private: 19 | bool m_disableTypicalTabKeyBehavior = true; 20 | }; 21 | 22 | #endif // CUSTOMLINEEDIT_H 23 | -------------------------------------------------------------------------------- /src/iconutils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Handy little QIcon-related 3 | * functions 4 | */ 5 | 6 | #include "iconutils.h" 7 | #include 8 | 9 | QIcon IconUtils::requestDarkIcon( QString iconName, int size ) 10 | { 11 | QString curTheme = QIcon::themeName(); 12 | QIcon::setThemeName( curTheme + "-dark" ); 13 | 14 | QIcon rawIcon = QIcon::fromTheme( iconName ); 15 | QPixmap map = rawIcon.pixmap(QSize( size,size )); 16 | QIcon newIconFromPixmap(map); 17 | 18 | QIcon::setThemeName( curTheme ); 19 | 20 | return newIconFromPixmap; 21 | } 22 | -------------------------------------------------------------------------------- /src/iconutils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Handy little QIcon-related 3 | * functions 4 | */ 5 | 6 | #ifndef ICONUTILS_H 7 | #define ICONUTILS_H 8 | #include 9 | 10 | class IconUtils 11 | { 12 | public: 13 | static QIcon requestDarkIcon( QString iconName, int size=16 ); 14 | }; 15 | 16 | #endif // ICONUTILS_H 17 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "mainwindow.h" 7 | #include "meta/info/appinfo.h" 8 | #include "meta/info/appconfig.h" 9 | #include 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 14 | QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 15 | 16 | QApplication a(argc, argv); 17 | QIcon::setThemeName("vibrato-default"); 18 | 19 | // Set Cross Platform Icon settings 20 | QIcon::setFallbackSearchPaths( QIcon::fallbackSearchPaths() << ":/icons/vibrato-default/icons" ); 21 | 22 | #if defined(TARGET_OS_MAC) 23 | #else 24 | QFontDatabase::addApplicationFont(":/fonts/Cantarell-Regular.ttf"); 25 | QFont defaultFont("Cantarell", 10); 26 | QApplication::setFont(defaultFont); 27 | #endif 28 | 29 | MainWindow w; 30 | w.setWindowTitle("Vibrato Notes"); 31 | w.show(); 32 | 33 | qDebug().nospace() << "Welcome to Vibrato Notes! v." << qPrintable( VERSION ); 34 | qDebug() << "User Config Location:" << config()->fileName(); 35 | qDebug() << "Data Location:" << HelperIO::dataDir().absolutePath(); 36 | 37 | return a.exec(); 38 | } 39 | -------------------------------------------------------------------------------- /src/mainwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTES_H 2 | #define NOTES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include "meta/info/appinfo.h" 15 | #include "meta/info/appconfig.h" 16 | #include "meta/db/database.h" 17 | #include "meta/db/notedatabase.h" 18 | #include "meta/db/notebookdatabase.h" 19 | #include "meta/db/tagdatabase.h" 20 | #include "ui-managers/manager.h" 21 | #include "sql/sqlmanager.h" 22 | #include "userwindow.h" 23 | 24 | namespace Ui { 25 | class MainWindow; 26 | } 27 | 28 | class MainWindow : public QMainWindow 29 | { 30 | Q_OBJECT 31 | 32 | public: 33 | explicit MainWindow(QWidget *parent = nullptr); 34 | ~MainWindow(); 35 | void closeEvent (QCloseEvent *event); 36 | 37 | void loadDummyData(); 38 | 39 | void selectedNoteChanged(Note *n); 40 | 41 | public slots: 42 | void addNewNote(); 43 | void addNewNotebook(); 44 | void addNewTag(); 45 | void userButtonClicked(); 46 | void view_default(); 47 | void view_minimal(); 48 | void view_focus(); 49 | void search(); 50 | void focusSearchbar(); 51 | 52 | private: 53 | Ui::MainWindow *ui; 54 | UserWindow m_user_window; 55 | 56 | SQLManager *m_sqlManager; 57 | Manager *m_manager; 58 | EscribaManager *m_escriba_manager; 59 | NoteListManager *m_note_list_manager; 60 | TreeManager *m_tree_manager; 61 | 62 | // Where we store user data 63 | Database *m_db; // Contains all three databases below 64 | NoteDatabase *m_notes; 65 | NotebookDatabase *m_notebooks; 66 | TagDatabase *m_tags; 67 | }; 68 | 69 | #endif // NOTES_H 70 | -------------------------------------------------------------------------------- /src/meta/db/database.cpp: -------------------------------------------------------------------------------- 1 | #include "database.h" 2 | 3 | Database::Database(NoteDatabase *noteDatabase, NotebookDatabase *notebookDatabase, TagDatabase *tagDatabase) : 4 | m_note_database(noteDatabase), 5 | m_notebook_database(notebookDatabase), 6 | m_tag_database(tagDatabase) 7 | { 8 | connect(m_tag_database, &TagDatabase::removed, 9 | m_note_database, &NoteDatabase::removeTagFromNotes); 10 | } 11 | 12 | NoteDatabase *Database::noteDatabase() const 13 | { 14 | return m_note_database; 15 | } 16 | 17 | NotebookDatabase *Database::notebookDatabase() const 18 | { 19 | return m_notebook_database; 20 | } 21 | 22 | TagDatabase *Database::tagDatabase() const 23 | { 24 | return m_tag_database; 25 | } 26 | 27 | void Database::addTagToNote(Note *note, QString tagString) 28 | { 29 | Tag *tag = m_tag_database->addTag(tagString); 30 | if ( tag == nullptr ) return; 31 | if ( note->tags().indexOf(tag->syncHash()) == -1 ) 32 | note->setTags( note->tags() << tag->syncHash()); 33 | } 34 | -------------------------------------------------------------------------------- /src/meta/db/database.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The purpose of this class is to contain all database types 3 | * in a single struct for convenient access. 4 | */ 5 | 6 | #ifndef DATABASE_H 7 | #define DATABASE_H 8 | #include 9 | #include "notedatabase.h" 10 | #include "notebookdatabase.h" 11 | #include "tagdatabase.h" 12 | 13 | typedef struct { 14 | NoteDatabase *noteDatabase; 15 | NotebookDatabase *notebookDatabase; 16 | TagDatabase *tagDatabase; 17 | } DatabaseObject; 18 | 19 | class Database : QObject 20 | { 21 | Q_OBJECT 22 | public: 23 | Database(NoteDatabase *noteDatabase, NotebookDatabase *notebookDatabase, TagDatabase *tagDatabase); 24 | NoteDatabase *noteDatabase() const; 25 | NotebookDatabase *notebookDatabase() const; 26 | TagDatabase *tagDatabase() const; 27 | 28 | // Helper functions 29 | void addTagToNote(Note *note, QString tag); 30 | private: 31 | NoteDatabase *m_note_database; 32 | NotebookDatabase *m_notebook_database; 33 | TagDatabase *m_tag_database; 34 | }; 35 | 36 | #endif // DATABASE_H 37 | -------------------------------------------------------------------------------- /src/meta/db/notebookdatabase.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTEBOOKDATABASE_H 2 | #define NOTEBOOKDATABASE_H 3 | #include 4 | #include "../notebook.h" 5 | #include "notedatabase.h" 6 | #include "../../sql/sqlmanager.h" 7 | 8 | class NotebookDatabase : public QObject 9 | { 10 | Q_OBJECT 11 | public: 12 | NotebookDatabase(SQLManager *sqlManager, NoteDatabase *noteDatabase); 13 | 14 | QVector list() const; 15 | int size() const; 16 | QVector listRecursively() const; 17 | QVector listRecursively(const QVector notebookList) const; 18 | 19 | void addNotebook(Notebook *notebook); 20 | void addNotebook(Notebook *notebook, Notebook *parent); 21 | 22 | void removeNotebook(QUuid syncHash); 23 | void removeNotebook(Notebook *notebook); 24 | void clearNotebooks(); 25 | 26 | Notebook *findNotebookWithSyncHash(QUuid syncHash); 27 | 28 | void loadSQL(); 29 | 30 | void connectNotebook(Notebook *notebook); 31 | void disconnectNotebook(Notebook *notebook); 32 | 33 | private slots: 34 | void changed_slot(Notebook *notebook); 35 | 36 | void syncHashChanged_slot(Notebook *notebook); 37 | void titleChanged_slot(Notebook *notebook); 38 | void parentChanged_slot(Notebook *notebook); 39 | void childrenChanged_slot(Notebook *notebook); 40 | 41 | void handleNotebookParentRequest(Notebook *notebook, QUuid parentSyncHash); 42 | 43 | signals: 44 | void changed(Notebook *notebook); 45 | 46 | void syncHashChanged(Notebook *notebook); 47 | void titleChanged(Notebook *notebook); 48 | void parentChanged(Notebook *notebook); 49 | void childrenChanged(Notebook *notebook); 50 | 51 | void added(Notebook *notebook); 52 | void removed(QVector notebookSyncHashes); 53 | 54 | private: 55 | SQLManager *m_sqlManager; 56 | QVector m_list; 57 | NoteDatabase *m_noteDatabase; 58 | 59 | }; 60 | 61 | #endif // NOTEBOOKDATABASE_H 62 | -------------------------------------------------------------------------------- /src/meta/db/notedatabase.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "notedatabase.h" 8 | 9 | #include 10 | 11 | NoteDatabase::NoteDatabase(SQLManager *sqlManager) : 12 | m_sqlManager(sqlManager) 13 | { 14 | loadSQL(); 15 | } 16 | 17 | QList NoteDatabase::list() const 18 | { 19 | return m_list; 20 | } 21 | 22 | int NoteDatabase::size() const 23 | { 24 | return m_list.size(); 25 | } 26 | 27 | Note *NoteDatabase::addNote(Note *note, bool addToSQL) 28 | { 29 | m_list.prepend(note); 30 | 31 | if (addToSQL) m_sqlManager->addNote(note); 32 | 33 | connect(note, &Note::changed, 34 | this, &NoteDatabase::slot_noteChanged); 35 | connect(note, &Note::favoritedChanged, 36 | this, &NoteDatabase::handleNoteFavoritedChanged); 37 | connect(note, &Note::trashedOrRestored, 38 | this, &NoteDatabase::noteTrashedOrRestored); 39 | 40 | emit noteAdded(note); 41 | return note; 42 | } 43 | 44 | Note *NoteDatabase::addDefaultNote() 45 | { 46 | Note *note = new Note(); 47 | return addNote(note); 48 | } 49 | 50 | void NoteDatabase::removeNote(int index) 51 | { 52 | Note *note = m_list[index]; 53 | QUuid syncHash = note->syncHash(); 54 | m_list.removeAt(index); 55 | m_sqlManager->deleteNote(note); 56 | delete note; 57 | emit noteDeleted(syncHash); 58 | } 59 | 60 | void NoteDatabase::removeNote(Note *note) 61 | { 62 | int index = m_list.indexOf( note ); 63 | if ( index >= 0) 64 | removeNote( index ); 65 | else 66 | qDebug() << "Tried to remove a note with an ID of -1 :" << note->title(); 67 | } 68 | 69 | void NoteDatabase::removeNotes(QVector notes) 70 | { 71 | for (Note *note : notes) 72 | removeNote(note); 73 | } 74 | 75 | void NoteDatabase::clearNotes() 76 | { 77 | for (int i = m_list.size()-1; i >= 0; i--) { 78 | removeNote(i); 79 | } 80 | } 81 | 82 | void NoteDatabase::loadSQL() 83 | { 84 | QVector notes = m_sqlManager->notes(); 85 | for (Note *note : notes) 86 | addNote(note, false); 87 | } 88 | 89 | void NoteDatabase::removeNotesWithNotebookSyncHash(QUuid notebookSyncHash) 90 | { 91 | for (Note *note : m_list) 92 | if (note->notebook() == notebookSyncHash) 93 | removeNote(note); 94 | } 95 | 96 | void NoteDatabase::removeNotesWithNotebookSyncHashes(QVector notebookSyncHashes) 97 | { 98 | for (Note *note : m_list) 99 | if ( notebookSyncHashes.contains(note->notebook()) ) 100 | removeNote(note); 101 | } 102 | 103 | void NoteDatabase::removeTagFromNotes(QUuid tagSyncHash) { 104 | // Loop through each note's list of tags. 105 | // If note contains the deleted tag, 106 | // Remove the tag from the note. 107 | for (Note *note : m_list) { 108 | if ( note->tags().contains(tagSyncHash) ) { 109 | QVector newTagList = note->tags(); 110 | newTagList.removeAll(tagSyncHash); 111 | note->setTags( newTagList ); 112 | } 113 | } 114 | } 115 | 116 | QVector NoteDatabase::findNotesWithNotebookIDs(QVector notebookUUIDs) 117 | { 118 | QVector notes; 119 | for ( Note *note : m_list ) 120 | if ( notebookUUIDs.contains(note->notebook()) ) 121 | notes.append(note); 122 | return notes; 123 | } 124 | 125 | bool NoteDatabase::noteWithSyncHashExists(QUuid syncHash) const 126 | { 127 | for (Note *note : m_list) 128 | if (note->syncHash() == syncHash) 129 | return true; 130 | return false; 131 | } 132 | 133 | void NoteDatabase::slot_noteChanged(Note* note) { 134 | m_sqlManager->updateNoteToDB(note); 135 | emit noteChanged(note); 136 | } 137 | 138 | void NoteDatabase::handleNoteFavoritedChanged(Note* note) { 139 | emit noteFavoritedChanged(note); 140 | } 141 | -------------------------------------------------------------------------------- /src/meta/db/notedatabase.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This 'database' is for holding the notes in memory. 3 | * Do not confuse this with something that would connect 4 | * to an actual real-world database. 5 | */ 6 | 7 | #ifndef NOTELIST_H 8 | #define NOTELIST_H 9 | #include 10 | #include "../note.h" 11 | #include "../../sql/sqlmanager.h" 12 | 13 | #define NULL_INT -1 14 | 15 | class NoteDatabase : public QObject 16 | { 17 | Q_OBJECT 18 | public: 19 | NoteDatabase(SQLManager *sqlManager); 20 | 21 | // Lists out the notes in the in-memory database 22 | QList list() const; 23 | int size() const; 24 | 25 | Note *addNote(Note *note, bool addToSQL=true); 26 | Note *addDefaultNote(); // Takes note, sets certain fields to default values. 27 | //p Note *addNote(Note note); 28 | 29 | void removeNote(int index); 30 | void removeNote(Note *note); 31 | void removeNotes(QVector notes); 32 | void clearNotes(); 33 | 34 | void loadSQL(); 35 | 36 | void removeNotesWithNotebookSyncHash(QUuid notebookSyncHash); 37 | void removeNotesWithNotebookSyncHashes(QVector notebookSyncHashes); 38 | 39 | void removeTagFromNotes(QUuid tagSyncHash); 40 | 41 | QVector findNotesWithNotebookIDs(QVector notebookIDs); 42 | 43 | bool noteWithSyncHashExists(QUuid syncHash) const; 44 | 45 | signals: 46 | // Important: 'Trashed' means the *Note is set as trashed=true. 47 | // 'Deleted' means the *Note was deleted and removed from database. (Permanent) 48 | void noteAdded(Note *note); 49 | void noteChanged(Note *note); 50 | void noteTrashedOrRestored(Note *note, bool trashed); 51 | void noteDeleted(QUuid noteSyncHash); 52 | void noteFavoritedChanged(Note *note); 53 | 54 | private slots: 55 | void slot_noteChanged(Note *note); 56 | void handleNoteFavoritedChanged(Note *note); 57 | 58 | private: 59 | SQLManager *m_sqlManager; 60 | QList m_list; 61 | 62 | }; 63 | 64 | #endif // NOTELIST_H 65 | -------------------------------------------------------------------------------- /src/meta/db/tagdatabase.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "tagdatabase.h" 6 | #include 7 | 8 | TagDatabase::TagDatabase(SQLManager *sqlManager) : 9 | m_sqlManager(sqlManager) 10 | { 11 | loadSQL(); 12 | } 13 | 14 | QVector TagDatabase::list() const 15 | { 16 | return m_list; 17 | } 18 | 19 | int TagDatabase::size() const 20 | { 21 | return m_list.size(); 22 | } 23 | 24 | void TagDatabase::addTag(Tag *tag) 25 | { 26 | // Don't allow duplicate tags in our tag database 27 | for ( Tag *t : m_list ) { 28 | if ( t->title().toLower() == tag->title().toLower() ) 29 | return; 30 | } 31 | 32 | m_list.append(tag); 33 | connect(tag, &Tag::changed, 34 | this, &TagDatabase::changed_slot); 35 | 36 | emit added(tag); 37 | } 38 | 39 | Tag *TagDatabase::addTag(QString title) 40 | { 41 | // Clean tag & make sure not empty string 42 | title = title.trimmed(); 43 | if ( title.isEmpty() ) return nullptr; 44 | 45 | // Check if tag exists. Return if so. 46 | Tag *existingTag = findTagWithName(title); 47 | if ( existingTag ) return existingTag; 48 | 49 | Tag *tag = new Tag(); 50 | tag->setTitle(title); 51 | m_sqlManager->addTag(tag); 52 | addTag(tag); 53 | 54 | return tag; 55 | } 56 | 57 | void TagDatabase::removeTag(int index) 58 | { 59 | Tag *tag = m_list[index]; 60 | QUuid sync_hash = tag->syncHash(); 61 | 62 | m_sqlManager->deleteTag(tag); 63 | delete tag; 64 | 65 | m_list.removeAt(index); 66 | emit removed(sync_hash); 67 | } 68 | 69 | void TagDatabase::removeTag(Tag *tag) 70 | { 71 | for ( int i=m_list.length()-1; i>=0; i--) 72 | if ( m_list.at(i) == tag ) { 73 | removeTag(i); 74 | break; 75 | } 76 | } 77 | 78 | void TagDatabase::clearTags() 79 | { 80 | for (int i = m_list.size()-1; i >= 0; i--) { 81 | removeTag(i); 82 | } 83 | } 84 | 85 | Tag *TagDatabase::findTagWithSyncHash(QUuid syncHash) 86 | { 87 | for (Tag *tag : m_list) { 88 | if (tag->syncHash() == syncHash) 89 | return tag; 90 | } 91 | return nullptr; 92 | } 93 | 94 | Tag *TagDatabase::findTagWithName(QString name) 95 | { 96 | for (Tag *tag : m_list) 97 | if ( QString::compare(tag->title(), name, Qt::CaseInsensitive) == 0 ) 98 | return tag; 99 | return nullptr; 100 | } 101 | 102 | void TagDatabase::loadSQL() 103 | { 104 | QVector tags = m_sqlManager->tags(); 105 | for (Tag *tag : tags) 106 | addTag(tag); 107 | } 108 | 109 | void TagDatabase::changed_slot(Tag *tag) 110 | { 111 | qDebug() << tag->title() << "Changed!" << tag->row(); 112 | m_sqlManager->updateTagToDB(tag); 113 | emit changed(tag); 114 | } 115 | -------------------------------------------------------------------------------- /src/meta/db/tagdatabase.h: -------------------------------------------------------------------------------- 1 | #ifndef TAGDATABASE_H 2 | #define TAGDATABASE_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../tag.h" 8 | #include "../../sql/sqlmanager.h" 9 | 10 | class TagDatabase : public QObject 11 | { 12 | Q_OBJECT 13 | public: 14 | TagDatabase(SQLManager *sqlManager); 15 | QVector list() const; 16 | int size() const; 17 | 18 | void addTag(Tag *tag); 19 | Tag *addTag(QString title); 20 | 21 | void removeTag(int index); 22 | void removeTag(Tag *tag); 23 | void clearTags(); 24 | 25 | Tag *findTagWithSyncHash(QUuid syncHash); 26 | Tag *findTagWithName(QString name); 27 | 28 | void loadSQL(); 29 | 30 | private slots: 31 | void changed_slot(Tag *tag); 32 | 33 | signals: 34 | void added(Tag *tag); 35 | void changed(Tag *tag); 36 | void removed(QUuid tagSyncHash); 37 | 38 | private: 39 | SQLManager *m_sqlManager; 40 | QVector m_list; 41 | }; 42 | 43 | #endif // TAGDATABASE_H 44 | -------------------------------------------------------------------------------- /src/meta/info/appconfig.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "appconfig.h" 3 | #include "appinfo.h" 4 | 5 | static QSettings m_config(NAME_SHORT, CONFIG); 6 | static QSettings m_meta_config(NAME_SHORT, CONFIG_META); 7 | 8 | QSettings *config() { 9 | return &m_config; 10 | } 11 | 12 | QVariant config_value(QString key) 13 | { 14 | return m_config.value(key); 15 | } 16 | 17 | void set_config_value(QString key, QVariant value) 18 | { 19 | m_config.setValue(key, value); 20 | } 21 | 22 | bool config_value_exists(QString key) 23 | { 24 | return m_config.contains(key); 25 | } 26 | 27 | QSettings *meta_config() { 28 | return &m_meta_config; 29 | } 30 | 31 | QVariant meta_config_value(QString key) 32 | { 33 | return m_meta_config.value(key); 34 | } 35 | 36 | void set_meta_config_value(QString key, QVariant value) 37 | { 38 | m_meta_config.setValue(key, value); 39 | } 40 | 41 | bool meta_config_key_exists(QString key) 42 | { 43 | return m_meta_config.contains(key); 44 | } 45 | -------------------------------------------------------------------------------- /src/meta/info/appconfig.h: -------------------------------------------------------------------------------- 1 | #ifndef APPCONFIG_H 2 | #define APPCONFIG_H 3 | #include 4 | 5 | // Defining config strings 6 | // ... 7 | // Defining meta config strings 8 | #define LAST_OPENED_WINDOW_SIZE "last_opened_window_size" 9 | #define MAIN_SCREEN_LAYOUT "main_screen_layout" 10 | 11 | QSettings *config(); 12 | QVariant config_value(QString key); 13 | void set_config_value(QString key, QVariant value); 14 | bool config_key_exists(QString key); 15 | 16 | QSettings *meta_config(); 17 | QVariant meta_config_value(QString key); 18 | void set_meta_config_value(QString key, QVariant value); 19 | bool meta_config_key_exists(QString key); 20 | 21 | #endif // APPCONFIG_H 22 | -------------------------------------------------------------------------------- /src/meta/info/appinfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define NAME "Vibrato Notes" 4 | #define NAME_SHORT "vibrato" 5 | #define COMPANY "OpenAppLibary.org" 6 | #define VERSION "0.0.1" 7 | 8 | #define CONFIG "config" // Config name that users are allowed to edit. 9 | #define CONFIG_META "config_meta" // Config name that users are NOT allowed to edit. 10 | -------------------------------------------------------------------------------- /src/meta/note.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTE_H 2 | #define NOTE_H 3 | #include 4 | #include 5 | #include 6 | #include "notebook.h" 7 | #include "tag.h" 8 | 9 | #define NOTE_DEFAULT_TITLE "Untitled Note" 10 | 11 | class Note : public QObject 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | Note(QUuid sync_hash = QUuid::createUuid(), 17 | QString title = NOTE_DEFAULT_TITLE, 18 | QString text = "", 19 | QDateTime dateCreated = QDateTime::currentDateTime(), 20 | QDateTime dateModified = QDateTime::currentDateTime(), 21 | // TODO: user field 22 | QUuid notebook = QUuid(), 23 | QVector tags = {}, 24 | bool favorited = false, 25 | // TODO: public field 26 | bool encrypted = false, 27 | bool trashed = false); 28 | 29 | // Sync Hash 30 | QUuid syncHash() const; 31 | void setSyncHash(QUuid sync_hash); 32 | 33 | // Title 34 | QString title() const; 35 | void setTitle(const QString title); 36 | 37 | // Text 38 | QString text() const; 39 | void setText(const QString text); 40 | 41 | // Date created 42 | QDateTime dateCreated() const; 43 | QString dateCreatedStr() const; // ex. January 26, 1965 44 | QString dateCreatedStrInformative() const; // ex. January 26, 1965 at 12:30pm EST 45 | void setDateCreated(const QDateTime &dateCreated); 46 | 47 | // Date modified 48 | QDateTime dateModified() const; 49 | QString dateModifiedStr(); // ex. 5 minutes ago 50 | QString dateModifiedStrInformative(); // ex. January 26, 1965 at 12:30pm EST 51 | void setDateModified(const QDateTime &dateModified); 52 | 53 | // Notebook 54 | QUuid notebook() const; 55 | void setNotebook(QUuid sync_hash, bool updateDateModified=true); 56 | 57 | // Tags 58 | QVector tags() const; 59 | void setTags(const QVector &value); 60 | 61 | // Favorited 62 | bool favorited() const; 63 | void setFavorited(bool favorited); 64 | 65 | // Encrypted 66 | bool encrypted() const; 67 | void setEncrypted(bool encrypted); 68 | 69 | // Trashed 70 | bool trashed() const; 71 | void setTrashed(bool trashed); 72 | 73 | // Sorting comparison functions for your convenience. 74 | static bool byDateCreatedAsc(const Note *n1, const Note *n2); 75 | static bool byDateCreatedDesc(const Note *n1, const Note *n2); 76 | static bool byDateModifiedAsc(const Note *n1, const Note *n2); 77 | static bool byDateModifiedDesc(const Note *n1, const Note *n2); 78 | 79 | signals: 80 | // The general signal for whenever something changes 81 | void changed(Note *note, bool updateDateModified=true); 82 | 83 | void syncHashChanged(Note *note); 84 | void titleChanged(Note *note); 85 | void textChanged(Note *note); 86 | void dateCreatedChanged(Note *note); 87 | void dateModifiedChanged(Note *note); 88 | void notebookChanged(Note *note); 89 | void tagsChanged(Note *note); 90 | void favoritedChanged(Note *note); 91 | void encryptedChanged(Note *note); 92 | void trashed(Note *note); 93 | void restored(Note *note); 94 | void trashedOrRestored(Note *note, bool _trashed); 95 | 96 | private slots: 97 | void handleChange(Note *note, bool updateDateModified=true); 98 | 99 | private: 100 | QUuid m_sync_hash; 101 | QString m_title; 102 | QString m_text; 103 | QDateTime m_date_created; 104 | QDateTime m_date_modified; 105 | QUuid m_notebook; 106 | QVector m_tags; 107 | // TODO: Private user variable 108 | bool m_favorited; 109 | // TODO: Private public variable 110 | bool m_encrypted; 111 | bool m_trashed=false; 112 | 113 | QString informativeDate(QDateTime date) const; 114 | }; 115 | 116 | #endif // NOTE_H 117 | -------------------------------------------------------------------------------- /src/meta/notebook.cpp: -------------------------------------------------------------------------------- 1 | #include "notebook.h" 2 | #include 3 | 4 | Notebook::Notebook(QUuid sync_hash, QString title, QDateTime date_modified, Notebook *parent, int row, bool encrypted) : 5 | m_sync_hash(sync_hash), 6 | m_title(title), 7 | m_date_modified(date_modified), 8 | m_parent(parent), 9 | m_row(row), 10 | m_encrypted(encrypted) 11 | { 12 | connect(this, &Notebook::changed, 13 | this, &Notebook::handleChange); 14 | } 15 | 16 | Notebook *Notebook::createBlankNotebook() 17 | { 18 | return new Notebook(QUuid::createUuid(), NOTEBOOK_DEFAULT_TITLE); 19 | } 20 | 21 | QUuid Notebook::syncHash() const 22 | { 23 | return m_sync_hash; 24 | } 25 | 26 | void Notebook::setSyncHash(QUuid syncHash) 27 | { 28 | if ( defaultNotebook() ) 29 | return; 30 | m_sync_hash = syncHash; 31 | emit syncHashChanged(this); 32 | } 33 | 34 | QString Notebook::title() const 35 | { 36 | return m_title; 37 | } 38 | 39 | void Notebook::setTitle(const QString &title) 40 | { 41 | QString cleanedTitle = title.trimmed(); 42 | // If Default Notebook or no change or title is empty, return. 43 | if (defaultNotebook() || 44 | cleanedTitle == m_title || 45 | cleanedTitle.isEmpty()) 46 | return; 47 | m_title = cleanedTitle; 48 | emit titleChanged(this); 49 | emit changed(this); 50 | } 51 | 52 | QDateTime Notebook::dateModified() const 53 | { 54 | return m_date_modified; 55 | } 56 | 57 | void Notebook::setDateModified(QDateTime dateModified) 58 | { 59 | m_date_modified = dateModified; 60 | } 61 | 62 | Notebook *Notebook::parent() const 63 | { 64 | return m_parent; 65 | } 66 | 67 | void Notebook::setParent(Notebook *parent) 68 | { 69 | if ( defaultNotebook() ) return; 70 | 71 | if (m_parent != nullptr) 72 | m_parent->removeChild_primitive(this); 73 | setParent_primitive(parent); 74 | if (m_parent != nullptr) 75 | m_parent->addChild_primitive(this); 76 | 77 | emit childrenChanged(parent); 78 | emit parentChanged(this); 79 | emit changed(this); 80 | } 81 | 82 | QVector Notebook::children() const 83 | { 84 | return m_children; 85 | } 86 | 87 | QVector Notebook::recurseChildren(Notebook* parent) const 88 | { 89 | Notebook *curNotebook = parent; 90 | QVector notebooks; 91 | if (curNotebook == nullptr) 92 | curNotebook = const_cast(this); 93 | 94 | notebooks.append( curNotebook->children() ); 95 | for ( int i = 0; i < curNotebook->children().size(); i++ ) { 96 | notebooks.append( recurseChildren( curNotebook->children()[i] ) ); 97 | } 98 | return notebooks; 99 | } 100 | 101 | void Notebook::setChildren(const QVector &children) 102 | { 103 | if ( defaultNotebook() ) 104 | return; 105 | m_children = children; 106 | emit childrenChanged(this); 107 | emit changed(this); 108 | } 109 | 110 | void Notebook::addChild(Notebook *child) 111 | { 112 | if ( defaultNotebook() ) return; 113 | 114 | child->parent()->removeChild_primitive(child); 115 | child->setParent_primitive(this); 116 | addChild_primitive(child); 117 | 118 | emit parentChanged(child); 119 | emit childrenChanged(this); 120 | emit changed(this); 121 | } 122 | 123 | void Notebook::removeChild(Notebook *child) 124 | { 125 | if ( defaultNotebook() ) 126 | return; 127 | 128 | removeChild_primitive(child); 129 | 130 | emit childrenChanged(this); 131 | emit changed(this); 132 | } 133 | 134 | void Notebook::setParent_primitive(Notebook *parent) 135 | { 136 | m_parent = parent; 137 | } 138 | 139 | void Notebook::addChild_primitive(Notebook *child) 140 | { 141 | m_children.append(child); 142 | } 143 | 144 | void Notebook::removeChild_primitive(Notebook *child) 145 | { 146 | int index = m_children.indexOf(child); 147 | if (index > -1) m_children.removeAt(index); 148 | } 149 | 150 | int Notebook::row() const 151 | { 152 | return m_row; 153 | } 154 | 155 | void Notebook::setRow(int row) 156 | { 157 | if ( row == m_row ) return; 158 | 159 | m_row = row; 160 | emit rowChanged(this); 161 | emit changed(this); 162 | } 163 | 164 | bool Notebook::encrypted() const 165 | { 166 | return m_encrypted; 167 | } 168 | 169 | void Notebook::setEncrypted(bool encrypted) 170 | { 171 | if ( encrypted == m_encrypted ) return; 172 | 173 | m_encrypted = encrypted; 174 | emit encryptedChanged(this); 175 | emit changed(this); 176 | } 177 | 178 | bool Notebook::defaultNotebook() const 179 | { 180 | // Check if a blank UUID 181 | return m_sync_hash == nullptr; 182 | } 183 | 184 | void Notebook::requestParentWithSyncHash(QUuid parentSyncHash) { 185 | emit requestedParentWithSyncHash(this, parentSyncHash); 186 | } 187 | 188 | void Notebook::handleChange(Notebook *notebook) 189 | { 190 | notebook->setDateModified( QDateTime::currentDateTime() ); 191 | } 192 | -------------------------------------------------------------------------------- /src/meta/notebook.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTEBOOK_H 2 | #define NOTEBOOK_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define NOTEBOOK_DEFAULT_TITLE "Untitled Notebook" 10 | 11 | class Notebook : public QObject 12 | { 13 | Q_OBJECT 14 | public: 15 | Notebook(QUuid sync_hash = QUuid::createUuid(), 16 | QString title =NOTEBOOK_DEFAULT_TITLE, 17 | QDateTime date_modified = QDateTime::currentDateTime(), 18 | Notebook *parent = nullptr, 19 | int row = -255, 20 | bool encrypted = false); 21 | 22 | static Notebook *createBlankNotebook(); 23 | 24 | // Sync Hash 25 | QUuid syncHash() const; 26 | void setSyncHash(QUuid syncHash); 27 | 28 | // Title 29 | QString title() const; 30 | void setTitle(const QString &title); 31 | 32 | // Date Modified 33 | QDateTime dateModified() const; 34 | void setDateModified(QDateTime dateModified); 35 | 36 | // Parent & Child functions 37 | Notebook *parent() const; 38 | void setParent(Notebook *parent); 39 | 40 | QVector children() const; 41 | QVector recurseChildren(Notebook* parent=nullptr) const; 42 | void setChildren(const QVector &children); 43 | 44 | void addChild(Notebook *child); 45 | void removeChild(Notebook *child); 46 | 47 | // These functions should not be used in the majority of cases 48 | // They do not have the safety checks of the other notebook 49 | // manipulation functions. 50 | void setParent_primitive(Notebook *parent); 51 | void addChild_primitive(Notebook *child); 52 | void removeChild_primitive(Notebook *child); 53 | 54 | int row() const; 55 | void setRow(int row); 56 | 57 | bool encrypted() const; 58 | void setEncrypted(bool encrypted); 59 | 60 | // Returns true if default notebook 61 | bool defaultNotebook() const; 62 | 63 | // Requests the notebookDatabase to change the parent of this notebook 64 | void requestParentWithSyncHash(QUuid parentSyncHash); 65 | 66 | signals: 67 | // General change signal - When any property is changed. 68 | void changed(Notebook *notebook); 69 | 70 | // Property signals 71 | void syncHashChanged(Notebook *notebook); 72 | void titleChanged(Notebook *notebook); 73 | void dateModifiedChanged(Notebook *notebook); 74 | void parentChanged(Notebook *notebook); 75 | void childrenChanged(Notebook *notebook); 76 | void rowChanged(Notebook *notebook); 77 | void encryptedChanged(Notebook *notebook); 78 | 79 | void deletingNotebook(); 80 | void requestedParentWithSyncHash(Notebook *notebook, QUuid parentSyncHash); 81 | 82 | private slots: 83 | void handleChange(Notebook *notebook); 84 | 85 | private: 86 | QUuid m_sync_hash; 87 | QString m_title = ""; 88 | QDateTime m_date_modified; 89 | Notebook *m_parent; 90 | QVector m_children; 91 | int m_row; 92 | bool m_encrypted; 93 | }; 94 | 95 | #endif // NOTEBOOK_H 96 | -------------------------------------------------------------------------------- /src/meta/tag.cpp: -------------------------------------------------------------------------------- 1 | #include "tag.h" 2 | 3 | Tag::Tag(QUuid sync_hash, QString title, QDateTime date_modified, int row, bool encrypted) : 4 | m_sync_hash(sync_hash), 5 | m_title(title), 6 | m_date_modified(date_modified), 7 | m_row(row), 8 | m_encrypted(encrypted) 9 | { 10 | connect(this, &Tag::changed, 11 | this, &Tag::handleChange); 12 | } 13 | 14 | QUuid Tag::syncHash() const 15 | { 16 | return m_sync_hash; 17 | } 18 | 19 | void Tag::setSyncHash(QUuid syncHash) 20 | { 21 | if ( syncHash == m_sync_hash ) return; 22 | 23 | m_sync_hash = syncHash; 24 | emit syncHashChanged(this); 25 | emit changed(this); 26 | } 27 | 28 | QString Tag::title() const 29 | { 30 | return m_title; 31 | } 32 | 33 | void Tag::setTitle(const QString title) 34 | { 35 | QString cleanedTitle = title.trimmed(); 36 | if ( cleanedTitle == m_title || 37 | cleanedTitle.isEmpty() ) 38 | return; 39 | m_title = cleanedTitle; 40 | emit titleChanged(this); 41 | emit changed(this); 42 | } 43 | 44 | QDateTime Tag::dateModified() const 45 | { 46 | return m_date_modified; 47 | } 48 | 49 | void Tag::setDateModified(QDateTime dateModified, bool emitChangeSignal) 50 | { 51 | if ( dateModified == m_date_modified ) return; 52 | 53 | m_date_modified = dateModified; 54 | emit dateModifiedChanged(this); 55 | if (emitChangeSignal) 56 | emit changed(this); 57 | } 58 | 59 | int Tag::row() const 60 | { 61 | return m_row; 62 | } 63 | 64 | void Tag::setRow(int row) 65 | { 66 | if ( row == m_row ) return; 67 | 68 | m_row = row; 69 | emit rowChanged(this); 70 | emit changed(this); 71 | } 72 | 73 | bool Tag::encrypted() const 74 | { 75 | return m_encrypted; 76 | } 77 | 78 | void Tag::setEncrypred(bool encrypted) 79 | { 80 | if ( encrypted == m_encrypted ) return; 81 | 82 | m_encrypted = encrypted; 83 | emit encryptedChanged(this); 84 | emit changed(this); 85 | } 86 | 87 | void Tag::handleChange(Tag *tag) 88 | { 89 | tag->setDateModified( QDateTime::currentDateTime(), false ); 90 | } 91 | -------------------------------------------------------------------------------- /src/meta/tag.h: -------------------------------------------------------------------------------- 1 | #ifndef TAG_H 2 | #define TAG_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define TAG_DEFAULT_TITLE "Untitled Tag" 9 | 10 | class Tag : public QObject 11 | { 12 | Q_OBJECT 13 | public: 14 | Tag(QUuid sync_hash = QUuid::createUuid(), 15 | QString title = TAG_DEFAULT_TITLE, 16 | QDateTime date_modified = QDateTime::currentDateTime(), 17 | int row = -255, 18 | bool encrypted = false); 19 | 20 | // Sync Hash 21 | QUuid syncHash() const; 22 | void setSyncHash(QUuid syncHash); 23 | 24 | // Title 25 | QString title() const; 26 | void setTitle(const QString value); 27 | 28 | // Date Modified 29 | QDateTime dateModified() const; 30 | void setDateModified(QDateTime dateModified, bool emitChangeSignal=true); 31 | 32 | // Row 33 | int row() const; 34 | void setRow(int row); 35 | 36 | // Encrypted 37 | bool encrypted() const; 38 | void setEncrypred(bool encrypted); 39 | 40 | signals: 41 | // General change function - whenever any property is changed 42 | void changed(Tag *tag); 43 | 44 | // Property signals 45 | void syncHashChanged(Tag *tag); 46 | void titleChanged(Tag *tag); 47 | void dateModifiedChanged(Tag *tag); 48 | void rowChanged(Tag *tag); 49 | void encryptedChanged(Tag *tag); 50 | 51 | private slots: 52 | void handleChange(Tag *tag); 53 | 54 | private: 55 | QUuid m_sync_hash; 56 | QString m_title; 57 | QDateTime m_date_modified; 58 | int m_row; 59 | bool m_encrypted; 60 | 61 | }; 62 | 63 | #endif // TAG_H 64 | -------------------------------------------------------------------------------- /src/models/delegates/noteitemdelegate.cpp: -------------------------------------------------------------------------------- 1 | #include "noteitemdelegate.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../items/notelistitem.h" 8 | 9 | NoteItemDelegate::NoteItemDelegate(QListView *view, QSortFilterProxyModel *proxyModel) : 10 | m_view(view), 11 | m_proxyModel(proxyModel) 12 | { 13 | 14 | } 15 | 16 | QRect NoteItemDelegate::getStarRect(const QStyleOptionViewItem &option) const 17 | { 18 | return QRect(option.rect.x()+option.rect.width()-35, 19 | option.rect.y()+option.rect.height()/2-12, 20 | 25,25); 21 | } 22 | 23 | 24 | bool NoteItemDelegate::editorEvent(QEvent *event, 25 | QAbstractItemModel *model, 26 | const QStyleOptionViewItem &option, 27 | const QModelIndex &index) 28 | { 29 | if (event->type() == QEvent::MouseButtonRelease) 30 | { 31 | QMouseEvent* mouseEvent = static_cast(event); 32 | if(mouseEvent->button() == Qt::LeftButton) 33 | { 34 | QRect checkboxRect = getStarRect(option); 35 | QPoint mousePoint = mouseEvent->pos(); 36 | if ( checkboxRect.contains(mousePoint) ) { 37 | QModelIndex realIndex = m_proxyModel->mapToSource(index); 38 | NoteListItem *item = static_cast( realIndex.internalPointer() ); 39 | item->note()->setFavorited( !item->note()->favorited() ); 40 | return true; 41 | } 42 | else 43 | m_view->setCurrentIndex(index); 44 | } 45 | } 46 | 47 | return QStyledItemDelegate::editorEvent(event, model, option, index); 48 | } 49 | 50 | void NoteItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 51 | { 52 | if (index.column() == 0 ) { 53 | QModelIndex realIndex = m_proxyModel->mapToSource(index); 54 | NoteListItem *item = static_cast( realIndex.internalPointer() ); 55 | 56 | // Set the background color 57 | QBrush background = 58 | (option.state & QStyle::State_Selected) ? 59 | option.palette.highlight() : 60 | option.palette.base(); 61 | painter->fillRect(option.rect, background); 62 | 63 | if (option.state & QStyle::State_Selected) 64 | painter->setPen(option.palette.highlightedText().color()); 65 | else 66 | painter->setPen(option.palette.text().color()); 67 | 68 | QRect titleRect = option.rect; 69 | titleRect.setX(titleRect.x()+5); 70 | titleRect.setWidth(titleRect.x()-5); 71 | 72 | QFont font=painter->font() ; 73 | font.setPointSize(10); 74 | 75 | // Title 76 | font.setWeight(QFont::Bold); 77 | painter->setFont(font); 78 | painter->drawText(QPoint(option.rect.x()+10, option.rect.y()+23), item->note()->title()); 79 | 80 | // Date 81 | font.setWeight(QFont::Normal); 82 | painter->setFont(font); 83 | painter->drawText(QPoint(option.rect.x()+10, option.rect.y()+43), item->note()->dateCreatedStr()); 84 | 85 | 86 | // The Excerpt 87 | QRect excerptRect = option.rect; 88 | excerptRect.setX( excerptRect.x()+10 ); 89 | excerptRect.setY( excerptRect.y()+50 ); 90 | excerptRect.setWidth( excerptRect.width()-50 ); 91 | 92 | QString excerpt = item->note()->text(); 93 | if (excerpt.length() > 50) { 94 | excerpt = excerpt.mid(0, 50) + "..."; 95 | } 96 | excerpt.replace("\n", " "); 97 | excerpt.replace(QRegExp("\\s\\s+"), " "); // Ensure at most one space 98 | painter->drawText(excerptRect, excerpt); 99 | 100 | painter->fillRect(QRect( 101 | option.rect.x() + option.rect.width() - 60, 102 | option.rect.y(), 103 | 60, 104 | option.rect.height()), background); 105 | 106 | QIcon favoriteIcon; 107 | if (item->note()->favorited()) 108 | favoriteIcon = QIcon::fromTheme("vibrato-draw-star-solid"); 109 | else 110 | favoriteIcon = QIcon::fromTheme("vibrato-draw-star"); 111 | 112 | favoriteIcon.paint(painter, getStarRect(option)); 113 | 114 | } else { 115 | QStyledItemDelegate::paint(painter, option, index); 116 | } 117 | } 118 | 119 | QSize NoteItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const 120 | { 121 | return QSize(200,100); 122 | } 123 | -------------------------------------------------------------------------------- /src/models/delegates/noteitemdelegate.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTEITEMDELEGATE_H 2 | #define NOTEITEMDELEGATE_H 3 | #include 4 | #include 5 | #include 6 | 7 | class NoteItemDelegate : public QStyledItemDelegate 8 | { 9 | public: 10 | NoteItemDelegate(QListView *view, QSortFilterProxyModel *proxyModel); 11 | 12 | QRect getStarRect(const QStyleOptionViewItem &option) const; 13 | 14 | bool editorEvent(QEvent *event, 15 | QAbstractItemModel *model, 16 | const QStyleOptionViewItem &option, 17 | const QModelIndex &index) override; 18 | 19 | void paint(QPainter *painter, const QStyleOptionViewItem &option, 20 | const QModelIndex &index) const override; 21 | 22 | QSize sizeHint(const QStyleOptionViewItem &option, 23 | const QModelIndex &index) const override; 24 | 25 | private: 26 | bool checked = false; 27 | QListView *m_view; 28 | QSortFilterProxyModel *m_proxyModel; 29 | }; 30 | 31 | #endif // MYDELEGATE_H 32 | -------------------------------------------------------------------------------- /src/models/items/basictreeitem.h: -------------------------------------------------------------------------------- 1 | #ifndef BASICTREEITEM_H 2 | #define BASICTREEITEM_H 3 | #include 4 | #include 5 | #include "../../meta/notebook.h" 6 | #include "../../meta/tag.h" 7 | 8 | typedef union 9 | { 10 | Notebook *notebook; 11 | Tag *tag; 12 | } NotebookOrTag; 13 | 14 | class BasicTreeItem : public QObject 15 | { 16 | Q_OBJECT 17 | public: 18 | explicit BasicTreeItem(const QString label, BasicTreeItem *parent = nullptr); 19 | explicit BasicTreeItem(Notebook *notebook, BasicTreeItem *parent = nullptr); 20 | explicit BasicTreeItem(Tag *tag, BasicTreeItem *parent = nullptr); 21 | 22 | ~BasicTreeItem(); 23 | 24 | enum TypeOfItem {Type_Notebook, Type_Tag, Type_SearchQuery, Type_NotebooksLabel, Type_TagsLabel, Type_Other}; 25 | 26 | bool isNotebook() const; 27 | bool isTag() const; 28 | bool isSearchQuery() const; 29 | bool isNotebooksLabel() const; 30 | bool isTagsLabel() const; 31 | bool isOther() const; 32 | 33 | bool selectable() const; 34 | void setSelectable(bool selectable=true); 35 | 36 | QUuid syncHash() const; 37 | 38 | QString label() const; 39 | void setLabel(QString label); 40 | void updateLabel(); 41 | 42 | QIcon icon() const; 43 | void setIcon(QIcon icon); 44 | 45 | NotebookOrTag object() const; 46 | void setObjectNotebook(Notebook *notebook); 47 | void setObjectTag(Tag *tag); 48 | 49 | // For items with a type of Type_SearchQuery 50 | QString searchQuery() const; 51 | void setSearchQuery(QString searchQuery); 52 | 53 | void setIsNotebooksLabel(); 54 | void setIsTagsLabel(); 55 | 56 | BasicTreeItem *getChild(int index) const; 57 | BasicTreeItem *appendChild(BasicTreeItem *child); 58 | void removeChild(int index); 59 | void removeChild(BasicTreeItem *item); 60 | void moveChild(int row, int newRow); 61 | void moveChild(BasicTreeItem *item, int newRow); 62 | QVector children() const; 63 | QVector recurseChildren() const; 64 | int childCount() const; 65 | 66 | BasicTreeItem *parentItem(); 67 | void setParent(BasicTreeItem *parent); 68 | 69 | int row() const; 70 | 71 | private slots: 72 | void notebookTitleChanged(Notebook *notebook); 73 | void notebookSyncHashChanged(Notebook *notebook); 74 | void tagTitleChanged(Tag *tag); 75 | void tagSyncHashChanged(Tag *tag); 76 | 77 | private: 78 | QUuid m_sync_hash; // Grab ID of notebook or tag without accessing object. This is a safety feature. 79 | QString m_label; 80 | QIcon m_icon; 81 | int m_type; // Type_Notebook, Type_Tag, etc. 82 | bool m_selectable=true; 83 | NotebookOrTag m_object; 84 | QVector m_childItems; 85 | BasicTreeItem *m_parentItem; 86 | QString m_searchQuery = ""; 87 | }; 88 | 89 | #endif // BASICTREEITEM_H 90 | -------------------------------------------------------------------------------- /src/models/items/listitemwithid.cpp: -------------------------------------------------------------------------------- 1 | #include "listitemwithid.h" 2 | 3 | ListItemWithID::ListItemWithID(QString label, QUuid syncHash) : 4 | QListWidgetItem(), 5 | m_sync_hash(syncHash) 6 | { 7 | setText(label); 8 | } 9 | 10 | QUuid ListItemWithID::syncHash() const 11 | { 12 | return m_sync_hash; 13 | } 14 | 15 | void ListItemWithID::setLabel(QString label) 16 | { 17 | setText(label); 18 | } 19 | 20 | void ListItemWithID::setSyncHash(QUuid syncHash) 21 | { 22 | m_sync_hash = syncHash; 23 | } 24 | -------------------------------------------------------------------------------- /src/models/items/listitemwithid.h: -------------------------------------------------------------------------------- 1 | #ifndef LISTITEMWITHID_H 2 | #define LISTITEMWITHID_H 3 | #include 4 | #include 5 | 6 | class ListItemWithID : public QObject, public QListWidgetItem 7 | { 8 | Q_OBJECT 9 | public: 10 | ListItemWithID(QString label, QUuid syncHash); 11 | int id() const; 12 | QUuid syncHash() const; 13 | 14 | public slots: 15 | void setLabel(QString label); 16 | void setSyncHash(QUuid syncHash); 17 | 18 | private: 19 | QUuid m_sync_hash = nullptr; 20 | }; 21 | 22 | #endif // LISTITEMWITHID_H 23 | -------------------------------------------------------------------------------- /src/models/items/notelistitem.cpp: -------------------------------------------------------------------------------- 1 | #include "notelistitem.h" 2 | #include "ui_notelistitem.h" 3 | #include 4 | #include 5 | 6 | NoteListItem::NoteListItem(Note *note) : 7 | m_note(note) 8 | { 9 | } 10 | 11 | NoteListItem::~NoteListItem() 12 | { 13 | m_note = nullptr; 14 | } 15 | 16 | Note *NoteListItem::note() const 17 | { 18 | return m_note; 19 | } 20 | 21 | void NoteListItem::setNote(Note *note) 22 | { 23 | m_note = note; 24 | m_sync_hash = note->syncHash(); 25 | } 26 | 27 | QUuid NoteListItem::syncHash() const 28 | { 29 | return m_sync_hash; 30 | } 31 | -------------------------------------------------------------------------------- /src/models/items/notelistitem.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTELISTITEM_H 2 | #define NOTELISTITEM_H 3 | #include 4 | #include 5 | #include 6 | #include "../../meta/note.h" 7 | 8 | #define NOTE_LIST_ITEM_HEIGHT 90 9 | 10 | namespace Ui { 11 | class NoteListItem; 12 | } 13 | 14 | class NoteListItem : public QObject 15 | { 16 | Q_OBJECT 17 | public: 18 | NoteListItem(Note *note); 19 | ~NoteListItem(); 20 | 21 | Note *note() const; 22 | void setNote(Note *note); 23 | 24 | QUuid syncHash() const; 25 | 26 | private: 27 | Note *m_note; 28 | QUuid m_sync_hash; 29 | }; 30 | 31 | #endif // NOTELISTITEM_H 32 | -------------------------------------------------------------------------------- /src/models/items/treeitemwithid.cpp: -------------------------------------------------------------------------------- 1 | #include "treeitemwithid.h" 2 | 3 | TreeItemWithID::TreeItemWithID(QString label, QUuid syncHash) : 4 | QTreeWidgetItem(), 5 | m_sync_hash(syncHash) 6 | { 7 | setText(0, label); 8 | } 9 | 10 | QUuid TreeItemWithID::syncHash() const 11 | { 12 | return m_sync_hash; 13 | } 14 | 15 | void TreeItemWithID::setSyncHash(QUuid syncHash) 16 | { 17 | m_sync_hash = syncHash; 18 | } 19 | -------------------------------------------------------------------------------- /src/models/items/treeitemwithid.h: -------------------------------------------------------------------------------- 1 | #ifndef TREEITEMWITHID_H 2 | #define TREEITEMWITHID_H 3 | #include 4 | #include 5 | 6 | class TreeItemWithID : public QObject, public QTreeWidgetItem 7 | { 8 | Q_OBJECT 9 | public: 10 | TreeItemWithID(QString label, QUuid syncHash); 11 | QUuid syncHash() const; 12 | 13 | public slots: 14 | void setSyncHash(QUuid syncHash); 15 | private: 16 | QUuid m_sync_hash = nullptr; 17 | }; 18 | 19 | #endif // TREEITEMWITHID_H 20 | -------------------------------------------------------------------------------- /src/models/notelistmodel.cpp: -------------------------------------------------------------------------------- 1 | #include "notelistmodel.h" 2 | #include 3 | 4 | NoteListModel::NoteListModel(QListView *view, NoteDatabase *noteDatabase) : QAbstractItemModel() 5 | { 6 | m_view = view; 7 | QString style = QString("QListView:item::active { color: white; } QListView:item { height: %1 }").arg( NOTE_LIST_ITEM_HEIGHT ); 8 | m_view->setStyleSheet(style); 9 | m_noteDatabase = noteDatabase; 10 | 11 | connect(m_noteDatabase, &NoteDatabase::noteDeleted, 12 | this, &NoteListModel::removeNoteItemWithSyncHash); 13 | } 14 | 15 | QVector NoteListModel::noteItems() const 16 | { 17 | return m_noteItems; 18 | } 19 | 20 | void NoteListModel::refresh(int row) 21 | { 22 | QModelIndex topLeft = createIndex(row,0); 23 | emit dataChanged(topLeft, topLeft); 24 | } 25 | 26 | void NoteListModel::clear() 27 | { 28 | if (m_noteItems.length() > 0) 29 | removeRows(0, m_noteItems.length()); 30 | } 31 | 32 | NoteListItem *NoteListModel::prependItem(Note *note) 33 | { 34 | int newIndex = 0; 35 | beginInsertRows(QModelIndex(), newIndex, newIndex); 36 | 37 | m_noteItems.prepend( new NoteListItem(nullptr)); 38 | NoteListItem *i = m_noteItems.at(newIndex); 39 | i->setNote(note); 40 | 41 | endInsertRows(); 42 | return i; 43 | } 44 | 45 | NoteListItem *NoteListModel::appendItem(Note *note) 46 | { 47 | int newIndex = m_noteItems.length(); 48 | beginInsertRows(QModelIndex(), newIndex, newIndex); 49 | 50 | m_noteItems.append( new NoteListItem(nullptr)); 51 | NoteListItem *i = m_noteItems.at(newIndex); 52 | i->setNote(note); 53 | 54 | endInsertRows(); 55 | return i; 56 | } 57 | 58 | void NoteListModel::noteDateChanged(NoteListItem *item) 59 | { 60 | for ( int i=0; i < m_noteItems.length(); i++ ) { 61 | if ( m_noteItems.at(i) == item ) { 62 | refresh( i ); 63 | break; 64 | } 65 | } 66 | } 67 | 68 | bool NoteListModel::insertRows(int position, int rows, const QModelIndex &parent) 69 | { 70 | beginInsertRows(parent, position, position + rows - 1); 71 | 72 | for (int i = 0; i < rows; i++) 73 | m_noteItems.insert(position+i, new NoteListItem(nullptr)); 74 | 75 | endInsertRows(); 76 | 77 | return true; 78 | } 79 | 80 | bool NoteListModel::removeRows(int position, int rows, const QModelIndex &parent) 81 | { 82 | beginRemoveRows(parent, position, position + rows - 1); 83 | 84 | for (int i = 0; i < rows; i++) { 85 | delete m_noteItems[position]; 86 | m_noteItems[position] = nullptr; 87 | m_noteItems.remove(position); 88 | } 89 | 90 | endRemoveRows(); 91 | 92 | return true; 93 | } 94 | 95 | int NoteListModel::columnCount(const QModelIndex &parent) const 96 | { 97 | return 1; 98 | } 99 | 100 | Note* NoteListModel::noteFromIndex(QModelIndex index) { 101 | if (!index.isValid()) 102 | return nullptr; 103 | NoteListItem *item = static_cast(index.internalPointer()); 104 | return item->note(); 105 | } 106 | 107 | QVariant NoteListModel::data(const QModelIndex &index, int role) const 108 | { 109 | if (!index.isValid()) 110 | return QVariant(); 111 | 112 | if (role != Qt::DisplayRole) 113 | return QVariant(); 114 | 115 | return QVariant(); 116 | } 117 | 118 | Qt::ItemFlags NoteListModel::flags(const QModelIndex &index) const 119 | { 120 | if (!index.isValid()) 121 | return nullptr; 122 | 123 | return QAbstractItemModel::flags(index); 124 | } 125 | 126 | QVariant NoteListModel::headerData(int section, Qt::Orientation orientation, 127 | int role) const 128 | { 129 | return QVariant(); 130 | } 131 | 132 | QModelIndex NoteListModel::index(int row, int column, const QModelIndex &parent) 133 | const 134 | { 135 | if (!hasIndex(row, column, parent)) 136 | return QModelIndex(); 137 | 138 | if (row < m_noteItems.length()) { 139 | QModelIndex index = createIndex(row, column, m_noteItems.at(row)); 140 | return index; 141 | } 142 | else 143 | return QModelIndex(); 144 | } 145 | 146 | QModelIndex NoteListModel::parent(const QModelIndex &index) const 147 | { 148 | return QModelIndex(); 149 | } 150 | 151 | int NoteListModel::rowCount(const QModelIndex &parent) const 152 | { 153 | return m_noteItems.length(); 154 | } 155 | 156 | void NoteListModel::removeNoteItemWithSyncHash(QUuid syncHash) 157 | { 158 | for (int i=0; isyncHash() == syncHash) 160 | removeRow(i); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/models/notelistmodel.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTELISTMODEL_H 2 | #define NOTELISTMODEL_H 3 | #include 4 | #include 5 | #include "items/notelistitem.h" 6 | #include "../meta/db/notedatabase.h" 7 | 8 | class NoteListModel : public QAbstractItemModel 9 | { 10 | Q_OBJECT 11 | public: 12 | NoteListModel(QListView *view, NoteDatabase *noteDatabase); 13 | 14 | QVector noteItems() const; 15 | 16 | void refresh(int row); 17 | void clear(); 18 | NoteListItem *prependItem(Note *note); 19 | NoteListItem *appendItem(Note *note); 20 | 21 | void noteDateChanged(NoteListItem *item); 22 | 23 | bool insertRows(int position, int rows, 24 | const QModelIndex &parent = QModelIndex()) override; 25 | bool removeRows(int position, int rows, 26 | const QModelIndex &parent = QModelIndex()) override; 27 | 28 | QVariant data(const QModelIndex &index, int role) const override; 29 | 30 | Qt::ItemFlags flags(const QModelIndex &index) const override; 31 | QVariant headerData(int section, Qt::Orientation orientation, 32 | int role = Qt::DisplayRole) const override; 33 | QModelIndex index(int row, int column, 34 | const QModelIndex &parent = QModelIndex()) const override; 35 | QModelIndex parent(const QModelIndex &index) const override; 36 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 37 | int columnCount(const QModelIndex &parent = QModelIndex()) const override; 38 | 39 | Note *noteFromIndex(QModelIndex index); 40 | 41 | void removeNoteItemWithSyncHash(QUuid syncHash); 42 | 43 | private: 44 | QListView *m_view; 45 | QVector m_noteItems; 46 | NoteDatabase *m_noteDatabase; 47 | }; 48 | 49 | #endif // NOTELISTMODEL_H 50 | -------------------------------------------------------------------------------- /src/models/sortfilter/notelistproxymodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NoteListProxyModel 3 | * Intended for out NoteList. 4 | * It allows us to sort by date, ascending or descending 5 | */ 6 | 7 | #ifndef NOTELISTPROXYMODEL_H 8 | #define NOTELISTPROXYMODEL_H 9 | #include 10 | #include 11 | #include 12 | #include "../items/notelistitem.h" 13 | #include "../../meta/db/database.h" 14 | #include "../delegates/noteitemdelegate.h" 15 | 16 | class NoteListProxyModel : public QSortFilterProxyModel 17 | { 18 | Q_OBJECT 19 | public: 20 | NoteListProxyModel(QListView *view, Database *db); 21 | 22 | QVariant data(const QModelIndex &index, int role) const override; 23 | 24 | enum SortingMethods {DateCreated, DateModified}; 25 | // With this enum, you can choose whether you want the favorites filter disable, 26 | // to display favorites only or exclude favorites. 27 | enum FavoritesMethods {FavoritesFilterDisabled, FavoritesOnly, FavoritesExclude}; 28 | // Either hide trash (default), show only trash, or show both trash and not-trash. 29 | enum TrashMethods {TrashHidden, TrashOnly, TrashBoth}; 30 | enum SearchMethods {SearchOff, SearchOn}; 31 | 32 | void setSortingMethod(int sortingMethod); 33 | 34 | void invalidateFilter(); 35 | 36 | // Filtering functions 37 | bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; 38 | bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; 39 | void clearFilter(bool invalidate=true); 40 | 41 | QVector notebookFilter() const; 42 | QVector tagFilter() const; 43 | int favoritesFilter() const; 44 | int trashedFilter() const; 45 | 46 | void filterOutEverything(bool shouldFilterOutEverything=true); 47 | void addNotebookToFilter(Notebook *notebook); 48 | void addTagToFilter(Tag *tag); 49 | void setFavoritesFilterMode(int filterMode); 50 | void setTrashedFilter(int trashedFilter); 51 | void setSearchQuery(QString searchQuery, int searchFilterMode=SearchOn); 52 | 53 | NoteListItem *item(int row); 54 | 55 | private slots: 56 | void noteChanged(Note *note); 57 | 58 | signals: 59 | void invalidatedFilter(); 60 | 61 | private: 62 | NoteItemDelegate *m_delegate; 63 | 64 | QModelIndex m_selectedRow; 65 | 66 | QListView *m_view; 67 | int m_sortingMethod=DateModified; 68 | Database *m_db; 69 | 70 | bool m_filter_out_everything=false; 71 | QVector m_notebook_filter; 72 | QVector m_tag_filter; 73 | int m_favorites_filter=FavoritesFilterDisabled; 74 | int m_trashed_filter=TrashHidden; 75 | 76 | // Searching notes 77 | int m_search_filter=SearchOff; 78 | QString m_searchQuery; 79 | 80 | }; 81 | 82 | #endif // NOTELISTPROXYMODEL_H 83 | -------------------------------------------------------------------------------- /src/models/treemodel.h: -------------------------------------------------------------------------------- 1 | #ifndef TREEMODEL_H 2 | #define TREEMODEL_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "items/basictreeitem.h" 8 | 9 | 10 | class TreeModel : public QAbstractItemModel 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit TreeModel(QObject *parent = nullptr); 16 | ~TreeModel(); 17 | 18 | BasicTreeItem *root() const; 19 | 20 | QVariant data(const QModelIndex &index, int role) const override; 21 | bool setData(const QModelIndex &index, const QVariant &value, 22 | int role = Qt::EditRole) override; 23 | Qt::ItemFlags flags(const QModelIndex &index) const override; 24 | QVariant headerData(int section, Qt::Orientation orientation, 25 | int role = Qt::DisplayRole) const override; 26 | QModelIndex index(int row, int column, 27 | const QModelIndex &parent = QModelIndex()) const override; 28 | QModelIndex parent(const QModelIndex &index) const override; 29 | QVector recurseChildren(); 30 | 31 | int rowCount(const QModelIndex &parent = QModelIndex()) const override; 32 | int columnCount(const QModelIndex &parent = QModelIndex()) const override; 33 | 34 | QModelIndex getItem(BasicTreeItem *item, QModelIndex parent=QModelIndex()); 35 | 36 | Qt::DropActions supportedDropActions() const override; 37 | Qt::DropActions supportedDragActions() const override; 38 | 39 | QStringList mimeTypes() const override; 40 | QMimeData *mimeData(const QModelIndexList &indexes) const override; 41 | bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex & parent) override; 42 | 43 | void reOrderRowValues(BasicTreeItem *parent); 44 | 45 | signals: 46 | void gaveNotebookNewParent(BasicTreeItem *parent, BasicTreeItem *child); 47 | 48 | private: 49 | BasicTreeItem *m_rootItem; 50 | QVector m_recurseChildren(QModelIndex parent=QModelIndex()); 51 | }; 52 | 53 | #endif // TREEMODEL_H 54 | -------------------------------------------------------------------------------- /src/models/views/customlistview.cpp: -------------------------------------------------------------------------------- 1 | #include "customlistview.h" 2 | 3 | CustomListView::CustomListView(QWidget *parent) : QListView(parent) 4 | { 5 | 6 | } 7 | 8 | void CustomListView::mousePressEvent(QMouseEvent *event) 9 | { 10 | (void) event; 11 | } 12 | 13 | void CustomListView::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) 14 | { 15 | QListView::currentChanged(current, previous); 16 | emit selectedItemChanged(current, previous); 17 | } 18 | -------------------------------------------------------------------------------- /src/models/views/customlistview.h: -------------------------------------------------------------------------------- 1 | /* 2 | * CustomListView provides some very minimal tweaks to QListView 3 | * At the moment, the only tweak it adds is a selectedItemChanged signal. 4 | */ 5 | 6 | #ifndef CUSTOMLISTVIEW_H 7 | #define CUSTOMLISTVIEW_H 8 | #include 9 | 10 | class CustomListView : public QListView 11 | { 12 | Q_OBJECT 13 | public: 14 | CustomListView(QWidget *parent=nullptr); 15 | 16 | // Empty function to prevent mouse press event. 17 | void mousePressEvent(QMouseEvent *event) override; 18 | 19 | public slots: 20 | void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) override; 21 | 22 | signals: 23 | void selectedItemChanged(const QModelIndex ¤t, const QModelIndex &previous); 24 | }; 25 | 26 | #endif // CUSTOMLISTVIEW_H 27 | -------------------------------------------------------------------------------- /src/models/views/customtreeview.cpp: -------------------------------------------------------------------------------- 1 | #include "customtreeview.h" 2 | #include 3 | 4 | CustomTreeView::CustomTreeView(QWidget *parent) : 5 | QTreeView(parent) 6 | { 7 | setEditTriggers(QTreeView::EditKeyPressed); 8 | 9 | setDragEnabled(true); 10 | setAcceptDrops(true); 11 | setDragDropMode(QAbstractItemView::InternalMove); 12 | } 13 | 14 | void CustomTreeView::mousePressEvent(QMouseEvent *event) 15 | { 16 | if ( event->button() == Qt::LeftButton ) 17 | QTreeView::mousePressEvent(event); 18 | else { 19 | QPoint pos = event->pos(); 20 | QPersistentModelIndex index = indexAt(pos); 21 | emit pressed(index); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/models/views/customtreeview.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMTREEVIEW_H 2 | #define CUSTOMTREEVIEW_H 3 | #include 4 | 5 | class CustomTreeView : public QTreeView 6 | { 7 | public: 8 | CustomTreeView(QWidget *parent=nullptr); 9 | 10 | void mousePressEvent(QMouseEvent *event) override; 11 | }; 12 | 13 | #endif // CUSTOMTREEVIEW_H 14 | -------------------------------------------------------------------------------- /src/scripting-api/scriptingengine.cpp: -------------------------------------------------------------------------------- 1 | #include "scriptingengine.h" 2 | 3 | #include 4 | 5 | ScriptingEngine::ScriptingEngine() 6 | { 7 | CHICKEN_run(CHICKEN_default_toplevel); 8 | 9 | C_word res; 10 | CHICKEN_eval_string("(print \"Welcome to Chicken\")", &res); 11 | 12 | char buffer[256]; 13 | CHICKEN_get_error_message(buffer, 255); 14 | 15 | qDebug() << "Ran chicken" << buffer; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/scripting-api/scriptingengine.h: -------------------------------------------------------------------------------- 1 | #ifndef SCRIPTINGENGINE_H 2 | #define SCRIPTINGENGINE_H 3 | 4 | extern "C" { // another way 5 | #include 6 | } 7 | 8 | class ScriptingEngine 9 | { 10 | public: 11 | ScriptingEngine(); 12 | }; 13 | 14 | #endif // SCRIPTINGENGINE_H 15 | -------------------------------------------------------------------------------- /src/sql/sqlmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef SQLMANAGER_H 2 | #define SQLMANAGER_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "../meta/note.h" 10 | 11 | // A 2d array. 12 | typedef QMap Map; 13 | typedef QVector MapVector; 14 | typedef QVector VariantList; 15 | 16 | class SQLManager : public QObject 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit SQLManager(QObject *parent = nullptr); 21 | void close(); 22 | 23 | QString location() const; 24 | 25 | /* 26 | * basicQuery and realBasicQuery are two ways to quickly execute a SQL query. 27 | * basicQuery executes a query, prints a message if error, and returns a QSqlQuery 28 | * object. 29 | * realBasicQuery runs basicQuery but instead of returning an QSqlQuery object, it 30 | * just returns a boolean indicating whether the query ran without error. 31 | */ 32 | QSqlQuery basicQuery(QString query); 33 | bool realBasicQuery(QString query); 34 | 35 | // Returns a list representing a single-column selection 36 | VariantList column(QString query, int column=0); 37 | 38 | // Returns the row/s of a SQL query. 39 | Map row(QSqlQuery query, QStringList tableLabels); 40 | Map row(QString queryString, QStringList tableLabels); 41 | MapVector rows(QSqlQuery query, QStringList tableLabels); 42 | MapVector rows(QString queryString, QStringList tableLabels); 43 | 44 | bool runScript(QString fileName); 45 | bool runScript(QFile *file, QSqlQuery *query); 46 | 47 | // Log SQL error to console. Returns false if error. 48 | bool logSqlError(QSqlError error, bool fatal=false); 49 | 50 | /* 51 | * Vibrato-specific SQL functions 52 | */ 53 | // List of supported note, notebook, and tag columns (in SQL) 54 | QStringList noteColumns() const; 55 | QStringList notebookColumns() const; 56 | QStringList tagColumns() const; 57 | 58 | // Retrieve notes 59 | QVector notes(); 60 | QVector notebooks(); 61 | QVector tags(); 62 | 63 | bool addNote(Note *note); 64 | bool updateNoteToDB(Note *note); 65 | bool updateNoteFromDB(Note *note); 66 | bool deleteNote(Note *note); 67 | 68 | bool addNotebook(Notebook *notebook); 69 | bool updateNotebookToDB(Notebook *notebook); 70 | bool updateNotebookFromDB(Notebook *notebook); 71 | bool deleteNotebook(Notebook *notebook, bool delete_children=true); 72 | 73 | bool addTag(Tag *tag); 74 | bool updateTagToDB(Tag *tag); 75 | bool updateTagFromDB(Tag *tag); 76 | bool deleteTag(Tag *tag); 77 | 78 | bool tagExists(QUuid noteSyncHash, QUuid tagSyncHash); 79 | // If skip_duplicate_check is set to true, it will not check for a duplicate entry 80 | // before adding the tag to note. This will save you from an extra database call. 81 | bool addTagToNote(QUuid noteSyncHash, QUuid tagSyncHash, bool skip_duplicate_check=false); 82 | bool removeTagFromNote(QUuid noteSyncHash, QUuid tagSyncHash); 83 | 84 | void importTutorialNotes(); 85 | 86 | signals: 87 | 88 | public slots: 89 | 90 | private: 91 | QString m_location; 92 | QSqlDatabase m_sqldb; 93 | 94 | bool m_shouldImportTutorialNotes = false; 95 | 96 | QVector m_getNotebooks(Notebook *parent=nullptr); 97 | 98 | QStringList m_noteColumns = 99 | {"sync_hash", 100 | "title", 101 | "text", 102 | "date_created", 103 | "date_modified", 104 | "notebook", 105 | "favorited", 106 | "encrypted", 107 | "trashed" 108 | }; 109 | QStringList m_notebookColumns = 110 | {"sync_hash", 111 | "title", 112 | "date_modified", 113 | "parent", 114 | "row", 115 | "encrypted" 116 | }; 117 | QStringList m_tagColumns = 118 | {"sync_hash", 119 | "title", 120 | "date_modified", 121 | "row", 122 | "encrypted" 123 | }; 124 | }; 125 | 126 | #endif // SQLMANAGER_H 127 | -------------------------------------------------------------------------------- /src/ui-managers/escribamanager.h: -------------------------------------------------------------------------------- 1 | #ifndef ESCRIBAMANAGER_H 2 | #define ESCRIBAMANAGER_H 3 | 4 | #include 5 | #include 6 | #include "../meta/note.h" 7 | #include "../meta/db/database.h" 8 | #include "../../ui/note_editnotebook.h" 9 | #include "../../ui/note_edittags.h" 10 | #include "../ui-managers/manager.h" 11 | #include "../custom-components/customlineedit.h" 12 | #include 13 | 14 | namespace Ui { 15 | class EscribaAddonsWidget; 16 | } 17 | 18 | class EscribaManager : public QObject 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | EscribaManager(Escriba *editor, Database *db, Manager *manager); 24 | 25 | void updateTagsButtonCounter(); 26 | void updateTagsCompletionList(void); 27 | 28 | Note *note(); 29 | void setNote( Note *note ); 30 | 31 | // Clear the note selection. Disable editor. 32 | void deselect(); 33 | 34 | void toggleFavorited(); 35 | void trashNote(); 36 | 37 | signals: 38 | void selectedNewNote(Note *note); 39 | void deselected(); 40 | 41 | public slots: 42 | void contentChangedFromEditor(QString markdown); 43 | void titleChangedFromEditor(QString title); 44 | void addTag(); 45 | 46 | void openNotebookEditor(); 47 | void openTagsEditor(); 48 | 49 | void focusEditor(); 50 | 51 | void noteChanged(); 52 | 53 | void updateNotebookWidget(void); 54 | void updateDateWidgets(void); 55 | void updateFavoriteButton(void); 56 | void updateTrashButton(void); 57 | 58 | private slots: 59 | void aNoteWasRemoved(QUuid noteSyncHash); 60 | void notebooksRemoved(QVector notebookSyncHashes); 61 | void noteSyncHashChanged(Note *note); 62 | void notebookChanged(Notebook *notebook); 63 | void noteNotebookChanged(Note *note); 64 | 65 | private: 66 | Escriba *m_editor; 67 | Database *m_db; 68 | Manager *m_manager; 69 | Ui::EscribaAddonsWidget *m_addons_ui; 70 | Note *m_curNote=nullptr; 71 | Notebook *m_curNotebook=nullptr; 72 | QUuid m_sync_hash=nullptr; 73 | QUuid m_notebook_sync_hash=nullptr; 74 | 75 | CustomLineEdit *m_titleWidget; 76 | QLineEdit *m_tagsInputWidget; 77 | QToolButton *m_tagsViewerWidget; 78 | QToolButton *m_notebookWidget; 79 | QToolButton *m_favoriteButton; 80 | QToolButton *m_moreWidget; 81 | QToolButton *m_trashButton; 82 | QLabel *m_dateCreatedWidget; 83 | QLabel *m_dateModifiedWidget; 84 | 85 | Note_EditNotebook *m_editNotebookDialog = nullptr; 86 | Note_EditTags *m_editTagsDialog = nullptr; 87 | 88 | QCompleter *m_completer; 89 | QStringListModel *m_completionList; 90 | }; 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /src/ui-managers/manager.cpp: -------------------------------------------------------------------------------- 1 | #include "manager.h" 2 | 3 | TreeManager *Manager::treeManager() const 4 | { 5 | return m_treeManager; 6 | } 7 | 8 | NoteListManager *Manager::noteListManager() const 9 | { 10 | return m_noteListManager; 11 | } 12 | 13 | EscribaManager *Manager::escribaManager() const 14 | { 15 | return m_escribaManager; 16 | } 17 | 18 | void Manager::setManagers(TreeManager *treeManager, NoteListManager *noteListManager, EscribaManager *escribaManager) 19 | { 20 | m_treeManager = treeManager; 21 | m_noteListManager = noteListManager; 22 | m_escribaManager = escribaManager; 23 | emit ready(); 24 | } 25 | -------------------------------------------------------------------------------- /src/ui-managers/manager.h: -------------------------------------------------------------------------------- 1 | #ifndef MANAGER_H 2 | #define MANAGER_H 3 | #include 4 | 5 | class TreeManager; 6 | class NoteListManager; 7 | class EscribaManager; 8 | 9 | class Manager: public QObject { 10 | Q_OBJECT 11 | public: 12 | TreeManager *treeManager() const; 13 | NoteListManager *noteListManager() const; 14 | EscribaManager *escribaManager() const; 15 | 16 | void setManagers(TreeManager *treeManager, NoteListManager *noteListManager, EscribaManager *escribaManager); 17 | 18 | signals: 19 | void ready(); 20 | 21 | private: 22 | TreeManager *m_treeManager; 23 | NoteListManager *m_noteListManager; 24 | EscribaManager *m_escribaManager; 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/ui-managers/notelist-views/genericview.cpp: -------------------------------------------------------------------------------- 1 | #include "genericview.h" 2 | #include 3 | #include "../notelistmanager.h" 4 | 5 | GenericView::GenericView(Database *db, Manager *manager, QObject *parent): 6 | QObject(parent), 7 | m_db(db), 8 | m_manager(manager) 9 | { 10 | } 11 | 12 | Database *GenericView::db() const 13 | { 14 | return m_db; 15 | } 16 | 17 | Manager *GenericView::manager() const 18 | { 19 | return m_manager; 20 | } 21 | 22 | NoteListProxyModel *GenericView::proxyModel() const 23 | { 24 | return m_manager->noteListManager()->proxyModel(); 25 | } 26 | 27 | QListView *GenericView::listView() const 28 | { 29 | return m_manager->noteListManager()->view(); 30 | } 31 | 32 | NoteListAddonsWidget *GenericView::addonsWidgetUi() const 33 | { 34 | return m_manager->noteListManager()->addonsWidgetUi(); 35 | } 36 | 37 | void GenericView::activateView() { 38 | qDebug("[GenericView] activateView() function has not yet been overrided."); 39 | } 40 | 41 | void GenericView::deactivateView() { 42 | qDebug("[GenericView] deactivateView() function has not yet been overrided."); 43 | } 44 | -------------------------------------------------------------------------------- /src/ui-managers/notelist-views/genericview.h: -------------------------------------------------------------------------------- 1 | #ifndef GENERICVIEW_H 2 | #define GENERICVIEW_H 3 | #include 4 | #include 5 | #include "../../models/sortfilter/notelistproxymodel.h" 6 | #include "../../meta/db/database.h" 7 | #include "../manager.h" 8 | #include 9 | 10 | namespace Ui { 11 | class NoteListAddonsWidget; 12 | } 13 | 14 | typedef Ui::NoteListAddonsWidget NoteListAddonsWidget; 15 | 16 | class GenericView : public QObject 17 | { 18 | Q_OBJECT 19 | public: 20 | explicit GenericView(Database *db, Manager *manager, QObject *parent=nullptr); 21 | 22 | Database *db() const; 23 | Manager *manager() const; 24 | NoteListProxyModel *proxyModel() const; 25 | QListView *listView() const; 26 | NoteListAddonsWidget *addonsWidgetUi() const; 27 | 28 | virtual void activateView(); 29 | virtual void deactivateView(); 30 | 31 | private: 32 | Database *m_db=nullptr; 33 | Manager *m_manager=nullptr; 34 | }; 35 | 36 | #endif // GENERICVIEW_H 37 | -------------------------------------------------------------------------------- /src/ui-managers/notelist-views/trashview.h: -------------------------------------------------------------------------------- 1 | #ifndef TRASHVIEW_H 2 | #define TRASHVIEW_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "genericview.h" 9 | #include "../../../ui/trashitem.h" 10 | #include "../../meta/note.h" 11 | 12 | class TrashView : public GenericView 13 | { 14 | public: 15 | explicit TrashView(Database *db, Manager *manager, QObject *parent=nullptr); 16 | 17 | void activateView() override; 18 | void deactivateView() override; 19 | 20 | TrashItem *addItem(Note *note); 21 | 22 | void select(TrashItem *item); 23 | void deselect(TrashItem *item); 24 | void selectAll(); 25 | void deselectAll(); 26 | 27 | private slots: 28 | void determineMassActionVisibility(void); 29 | void selectionChanged(QListWidgetItem *current, QListWidgetItem *previous); 30 | 31 | void deleteSelectedNotes(); 32 | void restoreSelectedNotes(); 33 | 34 | void deleteTrashItem(TrashItem *item); 35 | 36 | void deleteNote(Note *note); 37 | void restoreNote(Note *note); 38 | 39 | private: 40 | QListWidget *m_trashListWidget=nullptr; 41 | QWidget *m_massActions=nullptr; 42 | 43 | QVector m_trashItems; 44 | QVector m_selectedTrashItems; 45 | 46 | QCheckBox *m_checkbox=nullptr; 47 | QToolButton *m_massRestore=nullptr; 48 | QToolButton *m_massDelete=nullptr; 49 | 50 | // Private functions 51 | void toggleMassCheckmark(void); 52 | void itemCheckedOrUncheckedOrRemoved(TrashItem *item); 53 | }; 54 | 55 | #endif // TRASHVIEW_H 56 | -------------------------------------------------------------------------------- /src/ui-managers/notelistmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTELISTMANAGER_H 2 | #define NOTELISTMANAGER_H 3 | #include 4 | #include "../sortfilter/notelistproxymodel.h" 5 | #include "../models/views/customlistview.h" 6 | #include "../models/notelistmodel.h" 7 | #include "../models/items/notelistitem.h" 8 | #include "../meta/note.h" 9 | #include "../meta/db/database.h" 10 | #include "manager.h" 11 | #include "notelist-views/trashview.h" 12 | #include 13 | 14 | namespace Ui { 15 | class NoteListAddonsWidget; 16 | } 17 | 18 | typedef Ui::NoteListAddonsWidget NoteListAddonsWidget; 19 | 20 | class NoteListManager : public QObject 21 | { 22 | Q_OBJECT 23 | public: 24 | NoteListManager(CustomListView *view, QWidget *noteListAddons, Database *db, Manager *manager); 25 | ~NoteListManager(); 26 | 27 | enum viewingModes {View_AllNotes, View_Favorites, View_Notebook, View_Tag, View_Trash, View_Search}; 28 | 29 | QListView *view() const; 30 | NoteListModel *model() const; 31 | NoteListProxyModel *proxyModel() const; 32 | NoteListAddonsWidget *addonsWidgetUi() const; 33 | 34 | NoteListItem *add_note(Note *note); 35 | void remove_note(int index); 36 | void clear(); 37 | void filterOutEverything(bool shouldFilterOutEverything=true); 38 | void loadNotesFromNoteDatabase(); 39 | void loadNotesFromNoteDatabase(NoteDatabase *noteDatabase); 40 | 41 | void openIndexInEditor(int index); 42 | 43 | // Filter controls 44 | void clearFilter(bool invalidate=true); 45 | void addNotebookToFilter(Notebook *notebook); 46 | void addTagToFilter(Tag *tag); 47 | 48 | int curViewType() const; 49 | QUuid curViewType_ItemSyncHash() const; 50 | Notebook *curViewType_Notebook() const; 51 | Tag *curViewType_Tag() const; 52 | 53 | void disconnectCurrentView(); 54 | void showAllNotesView(); 55 | void showFavoritesView(); 56 | void showNotebookView(Notebook *notebook); 57 | void showTagView(Tag *tag); 58 | void showTrashView(); 59 | void showSearchQueryView(QString searchQuery); 60 | 61 | void setTitle(QString title); 62 | void setMetrics(int count, QString objectTypeSingular, QString pluralOverride=QString("")); // objectTypeSingular - ex. "note", "notebook" 63 | void hideTitle(); 64 | void hideMetrics(); 65 | void hideAddons(); 66 | 67 | void deselect(); 68 | 69 | public slots: 70 | void noteListItemChanged(const QModelIndex ¤t_proxy, const QModelIndex &previous_proxy); 71 | void ensureCurrentNoteIsSelected(); 72 | 73 | private slots: 74 | void managerIsReady(); 75 | void notebooksDeleted(QVector notebookSyncHashes); 76 | void tagDeleted(QUuid tagSyncHash); 77 | void favoritedChanged(void); 78 | void trashedOrRestored(void); 79 | void escribaDeselected(); 80 | 81 | // When a notebook or tag changes in the notebook/tag database 82 | void aNoteChanged(Note *note); 83 | void aNotebookChanged(Notebook *notebook); 84 | void aTagChanged(Tag *tag); 85 | 86 | void removeSearchQuery(); 87 | 88 | signals: 89 | void selectedNote(Note *note); 90 | 91 | private: 92 | CustomListView *m_view; 93 | NoteListAddonsWidget *m_noteListAddonsUi; 94 | QWidget *m_noteListAddons; 95 | Manager *m_manager; 96 | 97 | // m_model is the global list of notes 98 | // m_proxyModel is the sorted & filtered list of notes, based on m_model. 99 | NoteListModel *m_model; 100 | NoteListProxyModel *m_proxyModel; 101 | 102 | int m_curViewType=View_AllNotes; 103 | QUuid m_curViewType_ItemSyncHash; 104 | Notebook *m_curViewType_Notebook=nullptr; 105 | Tag *m_curViewType_Tag=nullptr; 106 | TrashView *m_trashView=nullptr; 107 | 108 | Database *m_db; 109 | }; 110 | 111 | #endif // NOTELISTMANAGER_H 112 | -------------------------------------------------------------------------------- /src/ui-managers/treemanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * "I speak for the trees" - The Lorax 3 | * 4 | * The purpose of this file is to control the tree view 5 | * and provide a flexible API for managing notebooks 6 | * and tags. 7 | */ 8 | 9 | #ifndef TREEMANAGER_H 10 | #define TREEMANAGER_H 11 | #include 12 | #include 13 | #include 14 | #include "../models/views/customtreeview.h" 15 | #include "../models/items/basictreeitem.h" 16 | #include "../models/treemodel.h" 17 | #include "../meta/db/notebookdatabase.h" 18 | #include "../meta/db/database.h" 19 | #include "manager.h" 20 | #include "notelistmanager.h" 21 | #include "../../ui/notebook_editparent.h" 22 | 23 | class TreeManager : public QObject 24 | { 25 | Q_OBJECT 26 | public: 27 | explicit TreeManager(CustomTreeView *treeView, Database *db, Manager *manager); 28 | ~TreeManager(); 29 | 30 | enum TreeItemTypes {TreeType_AllNotes, TreeType_Notebooks, TreeType_Notebook, TreeType_Tags, TreeType_Tag, TreeType_Other}; 31 | 32 | void update(); // Refreshes GUI 33 | 34 | // Notebook functions 35 | QVector notebooks() const; 36 | 37 | BasicTreeItem *curItem(); 38 | 39 | BasicTreeItem *addNotebook(Notebook *notebook); 40 | BasicTreeItem *addNotebook(Notebook *notebook, BasicTreeItem *parent); 41 | 42 | void removeNotebook(BasicTreeItem *item); 43 | void removeNotebook(BasicTreeItem *item, BasicTreeItem *fosterParent); 44 | 45 | void clearChildren(BasicTreeItem *item); 46 | void clearNotebooks(); 47 | 48 | void loadNotebookObjectAndChildren(Notebook *notebook, BasicTreeItem *parent=nullptr); 49 | void loadNotebooksFromNotebookDatabase(NotebookDatabase *notebookDatabase, bool expandAll=true); 50 | 51 | QModelIndex findIndexFromTreeItem(BasicTreeItem *item); 52 | void selectItem(BasicTreeItem *item, bool triggerItemChangedEvent=true); 53 | void selectItem(QModelIndex index, bool triggerItemChangedEvent=true); 54 | void gotoAllNotesTab(); 55 | 56 | QVector recurseNotebooks(BasicTreeItem *parent=nullptr); 57 | 58 | // Tag functions 59 | QVector tags() const; 60 | BasicTreeItem *addTag(Tag *tag); 61 | void removeTag(BasicTreeItem *item); 62 | void clearTags(); 63 | 64 | void loadTagsFromTagDatabase(TagDatabase *tagDatabase); 65 | 66 | // SearchQuery functions 67 | BasicTreeItem *addSearchQuery(QString searchQuery); 68 | 69 | // Signal Callbacks 70 | void treeItemChanged(const QModelIndex ¤t, const QModelIndex &previous); 71 | 72 | void treeContextMenu(const QPoint &point); 73 | 74 | // Navigation 75 | void openNotebookWithSyncHash(QUuid notebookSyncHash); 76 | 77 | // Removes a treeitem if isSearchQuery(). 78 | // If item == nullptr (default) it will try to delete the selected item. 79 | void removeSearchQuery(BasicTreeItem *item=nullptr); 80 | 81 | private slots: 82 | void tagAdded(Tag *tag); 83 | void tagRemoved(QUuid tagSyncHash); 84 | void tagChanged(Tag *tag); 85 | 86 | void notebookAdded(Notebook *notebook); 87 | void notebooksRemoved(QVector notebookSyncHashes); 88 | void notebookChanged(Notebook *notebook); 89 | 90 | void contextNewNotebook(); 91 | void contextDeleteNotebook(); 92 | void contextRenameNotebook(); 93 | 94 | void contextNewTag(); 95 | void contextDeleteTag(); 96 | void contextRenameTag(); 97 | 98 | void contextRemoveSearchQuery(); 99 | 100 | private: 101 | TreeModel *m_tree_model; 102 | CustomTreeView *m_tree_view; 103 | Manager *m_manager; 104 | Database *m_db; 105 | 106 | BasicTreeItem *m_curItem; 107 | 108 | BasicTreeItem *m_all_notes; 109 | BasicTreeItem *m_favorites; 110 | BasicTreeItem *m_notebooks; 111 | BasicTreeItem *m_tags; 112 | BasicTreeItem *m_trash; 113 | 114 | // Will open newly-created notebook or tag for editing (Renaming) after notebookAdded or tagAdded slot called. 115 | bool m_openNewNotebookForEditing=false; 116 | bool m_openNewTagForEditing=false; 117 | 118 | QMenu *m_notebookContextMenu; 119 | QAction *m_notebookNew; 120 | QAction *m_notebookRename; 121 | QAction *m_notebookDelete; 122 | 123 | QMenu *m_tagContextMenu; 124 | QAction *m_tagNew; 125 | QAction *m_tagRename; 126 | QAction *m_tagDelete; 127 | 128 | QMenu *m_searchQueryContextMenu; 129 | QAction *m_searchQueryRemove; 130 | 131 | // TODO: https://forum.qt.io/topic/45262/disable-certain-rows-in-qtreeview 132 | BasicTreeItem *m_no_notebooks_placedholder = nullptr; 133 | BasicTreeItem *m_no_tags_placedholder = nullptr; 134 | 135 | BasicTreeItem *m_currentContextIndex = nullptr; 136 | QModelIndex m_currentContextModelIndex; 137 | 138 | void add_no_notebooks_placeholder(); 139 | void add_no_tags_placeholder(); 140 | void remove_no_notebooks_placeholder(); 141 | void remove_no_tags_placeholder(); 142 | }; 143 | 144 | #endif // TREEMANAGER_H 145 | -------------------------------------------------------------------------------- /src/userwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "userwindow.h" 2 | #include "ui_userwindow.h" 3 | 4 | UserWindow::UserWindow(QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::UserWindow) 7 | { 8 | ui->setupUi(this); 9 | } 10 | 11 | UserWindow::~UserWindow() 12 | { 13 | delete ui; 14 | } 15 | 16 | void UserWindow::deleteThatShit() 17 | { 18 | this->close(); 19 | } 20 | -------------------------------------------------------------------------------- /src/userwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef USERWINDOW_H 2 | #define USERWINDOW_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class UserWindow; 8 | } 9 | 10 | class UserWindow : public QDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit UserWindow(QWidget *parent = nullptr); 16 | ~UserWindow(); 17 | 18 | void deleteThatShit(); 19 | 20 | private: 21 | Ui::UserWindow *ui; 22 | }; 23 | 24 | #endif // USERWINDOW_H 25 | -------------------------------------------------------------------------------- /tests/VibratoNotes-Desktop-Tests.pro: -------------------------------------------------------------------------------- 1 | QT += testlib 2 | 3 | include(../VibratoNotes-Desktop.pro) 4 | 5 | TARGET = vibrato-unittests 6 | TEMPLATE = app 7 | DEFINES += UNIT_TEST 8 | 9 | # Remove the app's entry file 10 | SOURCES -= $$VIBRATO_ENTRY_POINT 11 | 12 | # Sources 13 | SOURCES += $$PWD/unit-tests.cpp 14 | 15 | RESOURCES += \ 16 | resources/testresources.qrc 17 | -------------------------------------------------------------------------------- /tests/resources/heroes-error.sql: -------------------------------------------------------------------------------- 1 | drop table if exists heroes; 2 | 3 | create table heroes (name, power); 4 | 5 | insert in heroes values 6 | ("Batman", "Money"), 7 | ("Spiderman", "Webs"); 8 | -------------------------------------------------------------------------------- /tests/resources/heroes.sql: -------------------------------------------------------------------------------- 1 | drop table if exists heroes; 2 | drop table if exists vehicles; 3 | 4 | create table heroes (name, power); 5 | create table vehicles (name, color, speed); 6 | 7 | insert into heroes values 8 | ("Batman", "Money"), 9 | ("Spiderman", "Webs"); 10 | 11 | insert into vehicles values 12 | ("Ferrari", "red", 349), 13 | ("Apache Helicopter", "camo", 227), 14 | ("Apache Webserver", "gray", 30000), 15 | ("Skateboard", "brown", 7); 16 | -------------------------------------------------------------------------------- /tests/resources/testresources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | heroes.sql 4 | heroes-error.sql 5 | 6 | 7 | -------------------------------------------------------------------------------- /ui/edittags.cpp: -------------------------------------------------------------------------------- 1 | #include "edittags.h" 2 | #include "ui_edittags.h" 3 | 4 | EditTags::EditTags(Database *db, QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::EditTags), 7 | m_db(db) 8 | { 9 | ui->setupUi(this); 10 | 11 | connect(m_db->tagDatabase(), &TagDatabase::added, 12 | this, &EditTags::tagAdded); 13 | connect(m_db->tagDatabase(), &TagDatabase::changed, 14 | this, &EditTags::tagChanged); 15 | } 16 | 17 | EditTags::~EditTags() 18 | { 19 | delete ui; 20 | } 21 | 22 | void EditTags::addTag(Tag *tag) 23 | { 24 | ListItemWithID *item = new ListItemWithID(tag->title(), tag->syncHash()); 25 | ui->tagList->addItem(item); 26 | t_tagItem tagItem; 27 | tagItem.tag = tag; 28 | tagItem.item = item; 29 | m_tagItems.append(tagItem); 30 | } 31 | 32 | void EditTags::loadTags() 33 | { 34 | ui->tagList->clear(); 35 | for ( Tag *t : m_db->tagDatabase()->list() ) { 36 | addTag(t); 37 | } 38 | } 39 | 40 | void EditTags::tagAdded(Tag *tag) 41 | { 42 | addTag(tag); 43 | } 44 | 45 | void EditTags::tagChanged(Tag *tag) 46 | { 47 | for (int i=0; isetText( tag->title() ); 52 | break; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ui/edittags.h: -------------------------------------------------------------------------------- 1 | #ifndef EDITTAGS_H 2 | #define EDITTAGS_H 3 | #include 4 | #include 5 | #include "../src/meta/db/database.h" 6 | #include "../src/models/items/listitemwithid.h" 7 | 8 | namespace Ui { 9 | class EditTags; 10 | } 11 | 12 | class EditTags : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit EditTags(Database *db, QWidget *parent = nullptr); 18 | ~EditTags(); 19 | void addTag(Tag *tag); 20 | void loadTags(); 21 | 22 | private slots: 23 | void tagAdded(Tag *tag); 24 | void tagChanged(Tag *tag); 25 | 26 | private: 27 | Ui::EditTags *ui; 28 | Database *m_db; 29 | 30 | typedef struct { Tag *tag; ListItemWithID *item;} t_tagItem; 31 | 32 | QVector m_tagItems; 33 | }; 34 | 35 | #endif // EDITTAGS_H 36 | -------------------------------------------------------------------------------- /ui/edittags.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | EditTags 4 | 5 | 6 | 7 | 0 8 | 0 9 | 518 10 | 388 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | QDialogButtonBox::NoButton 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Enter a new tag... 33 | 34 | 35 | 36 | 37 | 38 | 39 | Add tag 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Qt::Horizontal 49 | 50 | 51 | QDialogButtonBox::Close 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | buttonBox 61 | accepted() 62 | EditTags 63 | accept() 64 | 65 | 66 | 248 67 | 254 68 | 69 | 70 | 157 71 | 274 72 | 73 | 74 | 75 | 76 | buttonBox 77 | rejected() 78 | EditTags 79 | reject() 80 | 81 | 82 | 316 83 | 260 84 | 85 | 86 | 286 87 | 274 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /ui/note_editnotebook.cpp: -------------------------------------------------------------------------------- 1 | #include "note_editnotebook.h" 2 | #include "ui_note_editnotebook.h" 3 | #include "../../meta/db/notebookdatabase.h" 4 | #include "../../ui-managers/treemanager.h" 5 | 6 | #include 7 | 8 | Note_EditNotebook::Note_EditNotebook(Database *db, Manager *manager, Note *note, QWidget *parent) : 9 | QDialog(parent), 10 | ui(new Ui::Note_EditNotebook), 11 | m_manager(manager), 12 | m_db(db), 13 | m_note(note) 14 | { 15 | ui->setupUi(this); 16 | 17 | // Tree Widget 18 | m_notebookTree = ui->notebookTree; 19 | 20 | // Button box 21 | m_selectNotebook = new QPushButton("Select Notebook"); 22 | 23 | ui->buttonBox->addButton(m_selectNotebook, QDialogButtonBox::ActionRole); 24 | 25 | updateTitle(); 26 | 27 | loadNotesNotebooks(); 28 | m_notebookTree->expandAll(); 29 | 30 | m_selectNotebook->setEnabled(false); 31 | 32 | setModal(true); // Make dialog a modal 33 | 34 | connect(note, &Note::changed, 35 | this, &Note_EditNotebook::noteChanged); 36 | connect(m_selectNotebook, &QPushButton::clicked, 37 | this, &Note_EditNotebook::selectNotebook); 38 | connect(m_notebookTree, &QTreeWidget::currentItemChanged, 39 | this, &Note_EditNotebook::currentItemChanged); 40 | connect(m_db->notebookDatabase(), &NotebookDatabase::added, 41 | this, &Note_EditNotebook::notebookAddedOrRemoved); 42 | connect(m_db->notebookDatabase(), &NotebookDatabase::removed, 43 | this, &Note_EditNotebook::notebookAddedOrRemoved); 44 | } 45 | 46 | Note_EditNotebook::~Note_EditNotebook() 47 | { 48 | delete m_selectNotebook; 49 | delete ui; 50 | } 51 | 52 | Note *Note_EditNotebook::note() 53 | { 54 | return m_note; 55 | } 56 | 57 | void Note_EditNotebook::noteChanged(void) 58 | { 59 | updateTitle(); 60 | } 61 | 62 | void Note_EditNotebook::selectNotebook() 63 | { 64 | QList selItemsArray = m_notebookTree->selectedItems(); 65 | if ( selItemsArray.length() == 0) 66 | return; 67 | TreeItemWithID *sel = static_cast( selItemsArray.at(0) ); 68 | 69 | // Uncheck all 70 | for ( int i = 0; i < m_treeItems.length(); i++ ) 71 | checkItem(m_treeItems.at(i), false); 72 | // Check selected icon 73 | checkItem(sel, true); 74 | 75 | // Save into note object 76 | QUuid curSyncHash = m_note->notebook(); 77 | QUuid syncHash = sel->syncHash(); 78 | if ( curSyncHash != syncHash ) { 79 | m_manager->noteListManager()->deselect(); 80 | m_note->setNotebook(syncHash); 81 | m_manager->treeManager()->openNotebookWithSyncHash(syncHash); 82 | emit notebookChanged(); 83 | } 84 | } 85 | 86 | void Note_EditNotebook::updateTitle() 87 | { 88 | if ( m_note == nullptr) 89 | return; 90 | 91 | setWindowTitle( QString("Editing notebook for \"%1\"").arg(m_note->title()) ); 92 | } 93 | 94 | void Note_EditNotebook::clearTree() 95 | { 96 | m_notebookTree->clear(); 97 | m_treeItems.clear(); 98 | } 99 | 100 | void Note_EditNotebook::addNotebookToTree(Notebook *notebook, TreeItemWithID *parent) 101 | { 102 | TreeItemWithID *item = new TreeItemWithID(notebook->title(), notebook->syncHash()); 103 | m_treeItems.append(item); 104 | 105 | checkItem( item, m_note->notebook() == notebook->syncHash() ); 106 | 107 | if ( parent == nullptr ) 108 | m_notebookTree->addTopLevelItem(item); 109 | else 110 | parent->addChild( item ); 111 | 112 | for ( int i=0; ichildren().length(); i++ ) { 113 | Notebook *child = notebook->children().at(i); 114 | addNotebookToTree(child, item); 115 | } 116 | } 117 | 118 | void Note_EditNotebook::loadNotesNotebooks() 119 | { 120 | isResettingTree = true; 121 | clearTree(); 122 | // First add the 'Default Notebook' selection 123 | // m_defaultNotebookItem = new TreeItemWithID("Defaultsss Notebook", -1); 124 | // m_notebookTree->addTopLevelItem(m_defaultNotebookItem); 125 | // m_treeItems.append(m_defaultNotebookItem); 126 | 127 | // Now add everything else 128 | QVector notebooks = m_db->notebookDatabase()->list(); 129 | for ( int i=0; isyncHash() == m_note->notebook(); 143 | checkItem( item, condition); 144 | if ( condition ) 145 | break; 146 | } 147 | } 148 | 149 | void Note_EditNotebook::checkItem(TreeItemWithID *item, bool isChecked) 150 | { 151 | if ( isChecked ) { 152 | item->setIcon(0, QIcon::fromTheme("dialog-ok-apply")); 153 | item->setSelected(true); 154 | } 155 | else 156 | item->setIcon(0, QIcon()); 157 | } 158 | 159 | void Note_EditNotebook::currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) 160 | { 161 | if ( isResettingTree ) 162 | return; 163 | (void) previous; // Ignore unused parameter compiler warning 164 | TreeItemWithID *cur = static_cast(current); 165 | if ( cur->syncHash() == m_note->notebook()) { 166 | m_selectNotebook->setEnabled(false); 167 | } else { 168 | m_selectNotebook->setEnabled(true); 169 | } 170 | } 171 | 172 | void Note_EditNotebook::notebookAddedOrRemoved(void) { 173 | loadNotesNotebooks(); 174 | } 175 | -------------------------------------------------------------------------------- /ui/note_editnotebook.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTE_EDITNOTEBOOKS_H 2 | #define NOTE_EDITNOTEBOOKS_H 3 | #include 4 | #include 5 | #include 6 | #include "../../ui-managers/manager.h" 7 | #include "../../meta/note.h" 8 | #include "../../meta/db/database.h" 9 | #include "../../models/items/treeitemwithid.h" 10 | 11 | namespace Ui { 12 | class Note_EditNotebook; 13 | } 14 | 15 | class Note_EditNotebook : public QDialog 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit Note_EditNotebook(Database *db, Manager *manager, Note *note, QWidget *parent = nullptr); 21 | ~Note_EditNotebook(); 22 | 23 | Note *note(); 24 | 25 | private slots: 26 | void noteChanged(void); 27 | void selectNotebook(); 28 | 29 | void currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); 30 | 31 | void notebookAddedOrRemoved(void); 32 | 33 | signals: 34 | void notebookChanged(); 35 | 36 | private: 37 | Ui::Note_EditNotebook *ui; 38 | Manager *m_manager; 39 | 40 | void updateTitle(); 41 | 42 | QTreeWidget *m_notebookTree; 43 | QPushButton *m_selectNotebook; 44 | 45 | Database *m_db=nullptr; 46 | Note *m_note=nullptr; 47 | 48 | TreeItemWithID *m_defaultNotebookItem=nullptr; 49 | QVector m_treeItems; 50 | 51 | // private functions 52 | void clearTree(); 53 | void addNotebookToTree(Notebook *notebook, TreeItemWithID *parent=nullptr); 54 | void loadNotesNotebooks(); 55 | void updateCheckMarks(); 56 | void checkItem(TreeItemWithID *item, bool isChecked); 57 | 58 | bool isResettingTree=false; 59 | }; 60 | 61 | #endif // NOTE_EDITNOTEBOOKS_H 62 | -------------------------------------------------------------------------------- /ui/note_editnotebook.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Note_EditNotebook 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | Notebook 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Qt::Horizontal 30 | 31 | 32 | QDialogButtonBox::Close 33 | 34 | 35 | false 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | buttonBox 45 | accepted() 46 | Note_EditNotebook 47 | accept() 48 | 49 | 50 | 248 51 | 254 52 | 53 | 54 | 157 55 | 274 56 | 57 | 58 | 59 | 60 | buttonBox 61 | rejected() 62 | Note_EditNotebook 63 | reject() 64 | 65 | 66 | 316 67 | 260 68 | 69 | 70 | 286 71 | 274 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /ui/note_edittags.cpp: -------------------------------------------------------------------------------- 1 | #include "note_edittags.h" 2 | #include "ui_note_edittags.h" 3 | #include "../../meta/db/notebookdatabase.h" 4 | 5 | #include 6 | 7 | Note_EditTags::Note_EditTags(Database *db, Note *note, QWidget *parent) : 8 | QDialog(parent), 9 | ui(new Ui::Note_EditTags), 10 | m_db(db), 11 | m_note(note) 12 | { 13 | ui->setupUi(this); 14 | 15 | setModal(true); 16 | 17 | // Tree Widget 18 | m_tagList = ui->tagList; 19 | m_tagList->setSelectionMode( QAbstractItemView::ExtendedSelection ); // allow multiple item selection 20 | 21 | // Button box 22 | m_removeTagButton = new QPushButton("Remove selected tag from note"); 23 | ui->buttonBox->addButton(m_removeTagButton, QDialogButtonBox::ActionRole); 24 | 25 | // Tag input 26 | m_tagInput = ui->tagInput; 27 | 28 | updateTitle(); 29 | 30 | loadNotesTags(); 31 | 32 | connect(note, &Note::changed, 33 | this, &Note_EditTags::noteChanged); 34 | connect(m_removeTagButton, &QPushButton::clicked, 35 | this, &Note_EditTags::removeTagsFromNote); 36 | connect(m_tagInput, &QLineEdit::returnPressed, 37 | this, &Note_EditTags::addTag); 38 | connect(ui->addTagButton, &QPushButton::clicked, 39 | this, &Note_EditTags::addTag); 40 | connect(m_tagList, &QListWidget::currentItemChanged, 41 | this, &Note_EditTags::currentItemChanged); 42 | 43 | connect(m_db->tagDatabase(), &TagDatabase::removed, 44 | this, &Note_EditTags::updateTagsCompletionList); 45 | connect(m_db->tagDatabase(), &TagDatabase::added, 46 | this, &Note_EditTags::updateTagsCompletionList); 47 | connect(m_db->tagDatabase(), &TagDatabase::changed, 48 | this, &Note_EditTags::updateTagsCompletionList); 49 | 50 | // Create a qcompleter 51 | m_completer = new QCompleter({""}, this); 52 | m_completer->setCaseSensitivity( Qt::CaseInsensitive ); 53 | m_tagInput->setCompleter(m_completer); 54 | m_completionList = qobject_cast(m_completer->model()); 55 | updateTagsCompletionList(); 56 | } 57 | 58 | Note_EditTags::~Note_EditTags() 59 | { 60 | delete m_removeTagButton; 61 | delete m_tagInput; 62 | delete ui; 63 | } 64 | 65 | Note *Note_EditTags::note() 66 | { 67 | return m_note; 68 | } 69 | 70 | void Note_EditTags::keyPressEvent(QKeyEvent *event) 71 | { 72 | // Ignore enter key. We must ignore it because we are using it in our tagInput. 73 | if( event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return ) 74 | return; 75 | QDialog::keyPressEvent(event); 76 | } 77 | 78 | void Note_EditTags::noteChanged(void) 79 | { 80 | updateTitle(); 81 | loadNotesTags(); 82 | } 83 | 84 | void Note_EditTags::updateTagsCompletionList(void) 85 | { 86 | // Create a string list of all of the tags 87 | QStringList tags; 88 | for (Tag *tag : m_db->tagDatabase()->list() ) 89 | tags << tag->title(); 90 | 91 | m_completionList->setStringList(tags); 92 | } 93 | 94 | void Note_EditTags::removeTagsFromNote() 95 | { 96 | QList selItemsArray = m_tagList->selectedItems(); 97 | if ( selItemsArray.length() == 0) 98 | return; 99 | 100 | QVector tags = m_note->tags(); 101 | QVector remove_list; 102 | for (int i=0; i < selItemsArray.length(); i++) { 103 | ListItemWithID *sel = static_cast( selItemsArray.at(i) ); 104 | 105 | QUuid sync_hash = sel->syncHash(); 106 | Tag *t = m_db->tagDatabase()->findTagWithSyncHash(sync_hash); 107 | if (t == nullptr) 108 | continue; 109 | 110 | if ( tags.contains(sync_hash) ) 111 | remove_list.append(tags.indexOf(sync_hash)); 112 | 113 | } 114 | 115 | // sort remove list (ascending) 116 | std::sort(remove_list.begin(), remove_list.end()); 117 | 118 | if ( remove_list.size() > 0 ) { 119 | for (int i=remove_list.length()-1; i>=0; i--) 120 | tags.remove(remove_list.at(i)); 121 | m_note->setTags( tags ); 122 | emit tagChanged(); 123 | } 124 | } 125 | 126 | void Note_EditTags::addTag() 127 | { 128 | m_db->addTagToNote(m_note, m_tagInput->text()); 129 | loadNotesTags(); 130 | m_tagInput->clear(); 131 | m_tagInput->setFocus(); 132 | } 133 | 134 | void Note_EditTags::updateTitle() 135 | { 136 | if ( m_note == nullptr) 137 | return; 138 | 139 | setWindowTitle( QString("Editing tags for \"%1\"").arg(m_note->title()) ); 140 | } 141 | 142 | void Note_EditTags::clearList() 143 | { 144 | if (m_listItems.length() == 0) 145 | return; 146 | 147 | for ( int i=m_listItems.length()-1; i>=0; i-- ) { 148 | ListItemWithID *item = m_listItems.at(i); 149 | m_listItems.remove(i); 150 | delete item; 151 | } 152 | } 153 | 154 | void Note_EditTags::addTagToList(Tag *tag) 155 | { 156 | ListItemWithID *item = new ListItemWithID(tag->title(), tag->syncHash()); 157 | m_listItems.append(item); 158 | 159 | m_tagList->addItem(item); 160 | } 161 | 162 | void Note_EditTags::loadNotesTags() 163 | { 164 | clearList(); 165 | // Now add everything else 166 | QVector tags = m_note->tags(); 167 | for ( int i=0; itagDatabase()->findTagWithSyncHash( tags.at(i) ); 169 | if ( t == nullptr) 170 | continue; 171 | addTagToList(t); 172 | } 173 | if ( m_listItems.length() > 0 && m_tagList->selectedItems().length() == 0 ) 174 | m_tagList->setCurrentRow(0); 175 | } 176 | 177 | void Note_EditTags::currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) 178 | { 179 | QList selItemsArray = m_tagList->selectedItems(); 180 | if ( selItemsArray.length() == 0) { 181 | m_removeTagButton->setEnabled(false); 182 | m_removeTagButton->setText( "Remove selected tag from note" ); 183 | return; 184 | } else 185 | m_removeTagButton->setEnabled(true); 186 | 187 | if ( selItemsArray.length() == 1) 188 | m_removeTagButton->setText( "Remove selected tag from note" ); 189 | else 190 | m_removeTagButton->setText( "Remove selected tags from note" ); 191 | } 192 | -------------------------------------------------------------------------------- /ui/note_edittags.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTE_EDITTAGS_H 2 | #define NOTE_EDITTAGS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../../meta/note.h" 9 | #include "../../meta/db/database.h" 10 | #include "../../models/items/listitemwithid.h" 11 | 12 | namespace Ui { 13 | class Note_EditTags; 14 | } 15 | 16 | class Note_EditTags : public QDialog 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit Note_EditTags(Database *db, Note *note, QWidget *parent = nullptr); 22 | ~Note_EditTags(); 23 | 24 | Note *note(); 25 | 26 | virtual void keyPressEvent(QKeyEvent *event) override; 27 | 28 | private slots: 29 | void noteChanged(void); 30 | void updateTagsCompletionList(void); 31 | void removeTagsFromNote(); 32 | void addTag(); 33 | 34 | void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous); 35 | 36 | signals: 37 | void tagChanged(); 38 | 39 | private: 40 | Ui::Note_EditTags *ui; 41 | 42 | void updateTitle(); 43 | 44 | QListWidget *m_tagList; 45 | QPushButton *m_removeTagButton; 46 | QLineEdit *m_tagInput; 47 | 48 | QCompleter *m_completer; 49 | QStringListModel *m_completionList; 50 | 51 | Database *m_db=nullptr; 52 | Note *m_note=nullptr; 53 | 54 | QVector m_listItems; 55 | 56 | // private functions 57 | void clearList(); 58 | void addTagToList(Tag *tag); 59 | void loadNotesTags(); 60 | 61 | }; 62 | 63 | #endif // MANAGENOTENOTEBOOKSDIALOG_H 64 | -------------------------------------------------------------------------------- /ui/note_edittags.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Note_EditTags 4 | 5 | 6 | 7 | 0 8 | 0 9 | 522 10 | 360 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Add a tag... 26 | 27 | 28 | 29 | 30 | 31 | 32 | Add tag 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | Qt::Horizontal 42 | 43 | 44 | QDialogButtonBox::Close 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | buttonBox 54 | accepted() 55 | Note_EditTags 56 | accept() 57 | 58 | 59 | 248 60 | 254 61 | 62 | 63 | 157 64 | 274 65 | 66 | 67 | 68 | 69 | buttonBox 70 | rejected() 71 | Note_EditTags 72 | reject() 73 | 74 | 75 | 316 76 | 260 77 | 78 | 79 | 286 80 | 274 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /ui/notebook_editparent.cpp: -------------------------------------------------------------------------------- 1 | #include "notebook_editparent.h" 2 | #include "ui_notebook_editparent.h" 3 | #include 4 | Notebook_EditParent::Notebook_EditParent(NotebookDatabase *notebookDatabase, QWidget *parent) : 5 | QDialog(parent), 6 | ui(new Ui::Notebook_EditParent), 7 | m_notebookDatabase(notebookDatabase) 8 | { 9 | ui->setupUi(this); 10 | setModal(true); 11 | 12 | treeWidget = ui->treeWidget; 13 | buttonBox = ui->buttonBox; 14 | 15 | connect(buttonBox, &QDialogButtonBox::accepted, 16 | this, &Notebook_EditParent::okButtonClicked); 17 | } 18 | 19 | Notebook_EditParent::~Notebook_EditParent() 20 | { 21 | delete ui; 22 | } 23 | 24 | Notebook *Notebook_EditParent::notebook() const { 25 | return m_curNotebook; 26 | } 27 | 28 | void Notebook_EditParent::setNotebook(Notebook *notebook) 29 | { 30 | m_curNotebook = notebook; 31 | treeWidget->clear(); 32 | addNotebooks(); 33 | treeWidget->expandAll(); 34 | } 35 | 36 | void Notebook_EditParent::addNotebooks(Notebook* parentNotebook, 37 | TreeItemWithID* parentTreeItem, 38 | bool disable_children) 39 | { 40 | QVector notebooks; 41 | if (parentNotebook == nullptr) 42 | notebooks = m_notebookDatabase->list(); 43 | else 44 | notebooks = parentNotebook->children(); 45 | 46 | for ( Notebook *notebook : notebooks ) { 47 | QString title = notebook->syncHash() == nullptr ? "(No parent)" : notebook->title(); 48 | TreeItemWithID *newItem = new TreeItemWithID(title, notebook->syncHash()); 49 | 50 | // Disable the tree item iff disable_children or the notebook is 51 | // the current notebook (You can't be a parent of yourself!) 52 | bool is_disabled = 53 | disable_children || 54 | notebook == m_curNotebook; 55 | 56 | qDebug() << notebook->title() << disable_children << (notebook == m_curNotebook) << (notebook == m_curNotebook->parent()); 57 | 58 | // Disable if is_disabled or if is current notebook's parent 59 | newItem->setDisabled( is_disabled ); 60 | 61 | if (parentTreeItem == nullptr) 62 | treeWidget->addTopLevelItem(newItem); 63 | else 64 | parentTreeItem->addChild(newItem); 65 | 66 | if (notebook->children().count() > 0) 67 | addNotebooks(notebook, newItem, is_disabled); 68 | } 69 | } 70 | 71 | int Notebook_EditParent::exec() 72 | { 73 | return QDialog::exec(); 74 | } 75 | 76 | int Notebook_EditParent::exec(Notebook *notebook) 77 | { 78 | setNotebook(notebook); 79 | return exec(); 80 | } 81 | 82 | void Notebook_EditParent::okButtonClicked() 83 | { 84 | // If no items are selected, exit. 85 | if (treeWidget->selectedItems().length() == 0) return; 86 | 87 | // Get the single selected item. 88 | TreeItemWithID *selectedItem = 89 | static_cast(treeWidget->selectedItems()[0]); 90 | 91 | QUuid newSyncHash = selectedItem->syncHash(); 92 | 93 | // If the parent ID hasn't changed, exit. 94 | QUuid curParentSyncHash = nullptr; 95 | if ( m_curNotebook->parent() != nullptr ) 96 | curParentSyncHash = m_curNotebook->parent()->syncHash(); 97 | if ( curParentSyncHash == newSyncHash ) 98 | return; 99 | Notebook *newParent = nullptr; 100 | if (newSyncHash != nullptr) newParent = m_notebookDatabase->findNotebookWithSyncHash(newSyncHash); 101 | m_curNotebook->setParent(newParent); 102 | 103 | emit changedParent(); 104 | } 105 | -------------------------------------------------------------------------------- /ui/notebook_editparent.h: -------------------------------------------------------------------------------- 1 | #ifndef NOTEBOOK_EDITPARENT_H 2 | #define NOTEBOOK_EDITPARENT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "../src/meta/db/notebookdatabase.h" 8 | #include "../src/models/items/treeitemwithid.h" 9 | 10 | namespace Ui { 11 | class Notebook_EditParent; 12 | } 13 | 14 | class Notebook_EditParent : public QDialog 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit Notebook_EditParent(NotebookDatabase *notebookDatabase, QWidget *parent = nullptr); 20 | ~Notebook_EditParent(); 21 | 22 | Notebook *notebook() const; 23 | void setNotebook(Notebook *notebook); 24 | 25 | void addNotebooks(Notebook *parentNotebook=nullptr, 26 | TreeItemWithID *parentTreeItem=nullptr, 27 | bool disable_children=false); 28 | 29 | virtual int exec() override; 30 | int exec(Notebook *notebook); 31 | 32 | public slots: 33 | void okButtonClicked(); 34 | 35 | signals: 36 | void changedParent(); 37 | 38 | private: 39 | Ui::Notebook_EditParent *ui; 40 | Notebook *m_curNotebook=nullptr; 41 | NotebookDatabase *m_notebookDatabase=nullptr; 42 | 43 | QTreeWidget *treeWidget; 44 | QDialogButtonBox *buttonBox; 45 | }; 46 | 47 | #endif // NOTEBOOK_EDITPARENT_H 48 | -------------------------------------------------------------------------------- /ui/notebook_editparent.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Notebook_EditParent 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | 21 | Notebook Title 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Qt::Horizontal 30 | 31 | 32 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | buttonBox 42 | accepted() 43 | Notebook_EditParent 44 | accept() 45 | 46 | 47 | 248 48 | 254 49 | 50 | 51 | 157 52 | 274 53 | 54 | 55 | 56 | 57 | buttonBox 58 | rejected() 59 | Notebook_EditParent 60 | reject() 61 | 62 | 63 | 316 64 | 260 65 | 66 | 67 | 286 68 | 274 69 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /ui/notelist_addons.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | NoteListAddonsWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 136 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | 21 | 16777215 22 | 16777215 23 | 24 | 25 | 26 | Form 27 | 28 | 29 | 30 | 31 | 32 | 33 | 5 34 | 35 | 36 | 0 37 | 38 | 39 | 5 40 | 41 | 42 | 0 43 | 44 | 45 | 46 | 47 | 0 48 | 49 | 50 | 51 | 52 | 53 | 15 54 | 75 55 | true 56 | 57 | 58 | 59 | Recipes 60 | 61 | 62 | true 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 0 71 | 0 72 | 73 | 74 | 75 | QDialogButtonBox::NoButton 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -1 84 | 12 85 | false 86 | 87 | 88 | 89 | text-transform: uppercase; 90 | font-weight: 100; 91 | font-size: 10px; 92 | 93 | 94 | 5 notes 95 | 96 | 97 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | In this notebook, I document every recipe I try over the years. I neatly type the instructions and give it a rating from 1 to 10. 107 | 108 | 109 | true 110 | 111 | 112 | 113 | 114 | 115 | 116 | true 117 | 118 | 119 | QDialogButtonBox::NoButton 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /ui/notelistitem.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | NoteListItem 4 | 5 | 6 | 7 | 0 8 | 0 9 | 387 10 | 76 11 | 12 | 13 | 14 | 15 | 1000 16 | 100 17 | 18 | 19 | 20 | Form 21 | 22 | 23 | QWidget#NoteListItem { 24 | border-bottom: 1px solid #efefef; 25 | } 26 | QToolButton { 27 | border-radius: 2; 28 | } 29 | 30 | 31 | 32 | 0 33 | 34 | 35 | 5 36 | 37 | 38 | 0 39 | 40 | 41 | 5 42 | 43 | 44 | 0 45 | 46 | 47 | 48 | 49 | 0 50 | 51 | 52 | 53 | 54 | 55 | 0 56 | 0 57 | 58 | 59 | 60 | 61 | 16777215 62 | 16777215 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 3 71 | 72 | 73 | 74 | 75 | 76 | 0 77 | 0 78 | 79 | 80 | 81 | 82 | 75 83 | true 84 | 85 | 86 | 87 | Untitled Note 88 | 89 | 90 | Qt::PlainText 91 | 92 | 93 | true 94 | 95 | 96 | false 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 8 105 | false 106 | 107 | 108 | 109 | January 17, 1706 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 0 118 | 0 119 | 120 | 121 | 122 | 123 | 200 124 | 0 125 | 126 | 127 | 128 | This note is a blank canvas for your mind. 129 | 130 | 131 | Qt::PlainText 132 | 133 | 134 | true 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | border-radius: 1; 145 | border: 0; 146 | background-color: none; 147 | 148 | 149 | Favorite this note 150 | 151 | 152 | 153 | 25 154 | 25 155 | 156 | 157 | 158 | true 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /ui/tagitem.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TagWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 110 10 | 46 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Form 21 | 22 | 23 | 24 | 25 | 26 | QFrame { 27 | background: #8ADCF2; 28 | border-radius: 7px; 29 | } 30 | 31 | 32 | QFrame::StyledPanel 33 | 34 | 35 | QFrame::Raised 36 | 37 | 38 | 39 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 40 | 41 | 42 | Qt::AlignCenter 43 | 44 | 45 | 0 46 | 47 | 48 | 0 49 | 50 | 51 | 0 52 | 53 | 54 | 0 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 0 62 | 63 | 64 | 65 | 66 | 75 67 | true 68 | true 69 | 70 | 71 | 72 | My Tag 73 | 74 | 75 | Qt::AlignCenter 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 0 84 | 0 85 | 86 | 87 | 88 | 89 | 20 90 | 20 91 | 92 | 93 | 94 | background-color: #8ADCF2; 95 | border-color: #8ADCF2; 96 | 97 | 98 | 99 | 100 | 101 | 102 | .. 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /ui/trashitem.cpp: -------------------------------------------------------------------------------- 1 | #include "trashitem.h" 2 | #include "ui_trashitem.h" 3 | #include 4 | 5 | TrashItem::TrashItem(Note *note, QListWidget *parent) : 6 | QListWidgetItem(parent), 7 | ui(new Ui::TrashItem), 8 | m_note(note), 9 | m_noteSyncHash(note->syncHash()) 10 | { 11 | widget = new QWidget(); 12 | ui->setupUi(widget); 13 | 14 | listWidget()->setItemWidget(this, widget); 15 | setSizeHint( QSize(this->sizeHint().width(), 40)); 16 | 17 | ui->checkbox->setSizePolicy( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) ); 18 | 19 | connect(ui->checkbox, &QCheckBox::stateChanged, 20 | this, &TrashItem::handleItemCheckedOrUnchecked); 21 | 22 | connect(ui->deleteButton, &QToolButton::pressed, 23 | this, &TrashItem::emitDeleteNoteSignal); 24 | 25 | connect(ui->restoreButton, &QToolButton::pressed, 26 | this, &TrashItem::emitRestoreNoteSignal); 27 | 28 | connect(note, &Note::restored, 29 | this, &TrashItem::handlePleaseDeleteTrashItem); 30 | 31 | updateLabels(); 32 | } 33 | 34 | TrashItem::~TrashItem() 35 | { 36 | delete ui; 37 | } 38 | 39 | void TrashItem::updateLabels() { 40 | ui->checkbox->setText( m_note->title() ); 41 | } 42 | 43 | QCheckBox *TrashItem::checkbox() const 44 | { 45 | return ui->checkbox; 46 | } 47 | 48 | bool TrashItem::checked() const 49 | { 50 | return ui->checkbox->isChecked(); 51 | } 52 | 53 | Note *TrashItem::note() const 54 | { 55 | return m_note; 56 | } 57 | 58 | QUuid TrashItem::noteSyncHash() const 59 | { 60 | return m_noteSyncHash; 61 | } 62 | 63 | void TrashItem::emitDeleteNoteSignal() { 64 | emit deleteNote(m_note); 65 | emit pleaseDeleteTrashItem(this); 66 | } 67 | 68 | void TrashItem::emitRestoreNoteSignal() { 69 | emit restoreNote(m_note); 70 | } 71 | 72 | void TrashItem::handleItemCheckedOrUnchecked(void) 73 | { 74 | emit itemCheckedOrUnchecked(this); 75 | } 76 | 77 | void TrashItem::handlePleaseDeleteTrashItem(void) { 78 | emit pleaseDeleteTrashItem(this); 79 | } 80 | -------------------------------------------------------------------------------- /ui/trashitem.h: -------------------------------------------------------------------------------- 1 | #ifndef TRASHITEM_H 2 | #define TRASHITEM_H 3 | #include 4 | #include 5 | #include "../src/meta/note.h" 6 | 7 | namespace Ui { 8 | class TrashItem; 9 | } 10 | 11 | class TrashItem : public QObject, public QListWidgetItem 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit TrashItem(Note *note, QListWidget *parent = nullptr); 17 | ~TrashItem(); 18 | 19 | void updateLabels(); 20 | 21 | QCheckBox *checkbox() const; 22 | bool checked() const; 23 | Note *note() const; 24 | QUuid noteSyncHash() const; 25 | 26 | void emitDeleteNoteSignal(); 27 | void emitRestoreNoteSignal(); 28 | 29 | signals: 30 | void deleteNote(Note *note); 31 | void restoreNote(Note *note); 32 | void itemCheckedOrUnchecked(TrashItem *item); 33 | void noteDeleted(TrashItem *item, QUuid noteSyncHash); 34 | void pleaseDeleteTrashItem(TrashItem *item); 35 | 36 | private slots: 37 | void handleItemCheckedOrUnchecked(void); 38 | void handlePleaseDeleteTrashItem(void); 39 | 40 | private: 41 | Ui::TrashItem *ui; 42 | QWidget *widget=nullptr; 43 | Note *m_note=nullptr; 44 | QUuid m_noteSyncHash=nullptr; 45 | }; 46 | 47 | #endif // TRASHITEM_H 48 | -------------------------------------------------------------------------------- /ui/trashitem.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | TrashItem 4 | 5 | 6 | 7 | 0 8 | 0 9 | 442 10 | 49 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Note Title 21 | 22 | 23 | 24 | 25 | 26 | 27 | Restore note 28 | 29 | 30 | 31 | 32 | 33 | Restore 34 | 35 | 36 | 37 | .. 38 | 39 | 40 | 41 | 42 | 43 | 44 | Permanently delete note 45 | 46 | 47 | 48 | 49 | 50 | Delete 51 | 52 | 53 | 54 | .. 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /ui/userwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | UserWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 300 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 30 20 | 240 21 | 341 22 | 32 23 | 24 | 25 | 26 | Qt::Horizontal 27 | 28 | 29 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 30 | 31 | 32 | 33 | 34 | 35 | 120 36 | 70 37 | 201 38 | 151 39 | 40 | 41 | 42 | This window will allow theuser to log in or edit account info. 43 | 44 | 45 | true 46 | 47 | 48 | 49 | 50 | 51 | 52 | buttonBox 53 | accepted() 54 | UserWindow 55 | accept() 56 | 57 | 58 | 248 59 | 254 60 | 61 | 62 | 157 63 | 274 64 | 65 | 66 | 67 | 68 | buttonBox 69 | rejected() 70 | UserWindow 71 | reject() 72 | 73 | 74 | 316 75 | 260 76 | 77 | 78 | 286 79 | 274 80 | 81 | 82 | 83 | 84 | 85 | --------------------------------------------------------------------------------