1. Project Overview & Quickstart (pbek/QOwnNotes)
[QOwnNotes](https://www.qownnotes.org "QOwnNotes Official Site")
Installation |
Changelog |
Issues |
Shortcuts |
Documentation |
Privacy Policy |
Screenshots |
Nextcloud API App |
ownCloud API App |
Matrix room |
Telegram Group |
IRC Chat |
Mastodon |
QOwnNotes Web Companion Firefox extension |
QOwnNotes Web Companion Chrome extension |
QOwnNotes Web App |
QOwnNotes Tor Hidden Service
QOwnNotes is the open source notepad with
Markdown support
and todo list manager for GNU/Linux, macOS and Windows,
that works together with Nextcloud Notes
and ownCloud Notes.
You are able to write down your thoughts with QOwnNotes and
edit or search for them later from your mobile device, like with
Nextcloud Notes for Android
or the Nextcloud / ownCloud web-service.
The notes are stored as plain text markdown files and are
synced with Nextcloud's/ownCloud's file sync functionality.
Of course other software, like Syncthing or
Dropbox can be used too.
If you like the concept of having notes accessible in plain text files, like it
is done in the Nextcloud / ownCloud notes apps to gain a maximum of freedom
then QOwnNotes is for you.
Visit the project page here: QOwnNotes project page
To manage your todo lists in the web and on your mobile devices, you need to
install the Tasks backend on Nextcloud
or ownCloud.
To get more on-line features for your notes, like versioning and trash access,
you might also want to install the QOwnNotesAPI
app on your server.
To access your ownCloud notes from your mobile device you may want to get one of these:
- For Android and OwnCloud: MyOwnNotes
- For Android and Nextcloud: Notes
- For iOS: CloudNotes
On Android you could also use any sync-tool like Synchronize Ultimate or FolderSync
to sync your note files and use software like neutriNotes or
Markor to edit your notes.
On iOS Notebooks
may also work well (syncing notes via WebDAV).
Screenshot
You can visit the QOwnNotes project page for more screenshots.
Features
- written in C++ and optimized for low resource consumption (no CPU and memory-hungry Electron app)
- multiple note folders can be used
- you can use your existing text or markdown files, no need for an import most of the time
- older versions of your notes can be restored from your Nextcloud / ownCloud server
(install QOwnNotesAPI on your server) - trashed notes can be restored from your Nextcloud / ownCloud server
(install QOwnNotesAPI on your server)- there also are local trash and system trash modes
- sub-string searching of notes is possible and search results are highlighted in the notes
- application can be operated with customizable keyboard shortcuts
- supports global keyboard shortcuts on Wayland
- external changes of note files are watched (notes or note list are reloaded)
- differences between current note and externally changed note are shown in a dialog
- markdown highlighting of notes and a markdown preview
- includes inline image previews, heading folding, and optional hiding of Markdown formatting syntax
- optional wiki-style note links like
[[Note]]with auto-completion, heading anchors, aliases, backlinks, and refactoring support - spellchecking and optional LanguageTool grammar and style checking, Harper grammar and style checking, and Markdown LSP support (e.g. Marksman for completions and diagnostics, or Rumdl for linting)
- tabbing support for editing notes
- scripting support and an online script repository
where you can install scripts inside the application - built-in AI support with script integration for providers like OpenAI and Groq
- includes a built-in MCP server so external AI agents can search and fetch notes securely
- QOwnNotes Web Companion browser extension
to add notes from the selected text and other features- visit the Chrome Web Store
page to install the app on Google Chrome - visit the Firefox Add-ons
page to install the app on Mozilla Firefox
- visit the Chrome Web Store
- notes are getting their name from the first line of the note text (just like
in the Nextcloud / ownCloud notes web-application) and the note text files are
automatically renamed, if the first line changes- this feature can also be turned off, and you can use any filename you like
- manage your Nextcloud / ownCloud todo lists (ownCloud tasks or Tasks Plus / Calendar Plus), or use another CalDAV server
- create Nextcloud Deck cards and link to them in your notes
- encryption of notes (AES-256 is built in, or you can use custom encryption methods like
Keybase.io (encryption-keybase.qml) or
PGP (encryption-pgp.qml)) - dark mode theme support, live theme switching, and custom color modes
- all panels can be placed wherever you want, they can even float or stack (fully dockable)
- toolbars are fully customizable
- support for freedesktop theme icons, so you can use QOwnNotes with your
native desktop icons and with your favorite dark desktop theme
QOwnNotes supports Freedesktop icon themes - support for hierarchical note tagging and note subfolders
- linked files and attachments can be managed from the Navigation panel
- support for sharing notes on your Nextcloud / ownCloud server
- portable mode for carrying QOwnNotes around on USB sticks
- Vim mode
- distraction free mode, full-screen mode, typewriter mode
- Evernote (now with large files and optional YAML front matter metadata) and Joplin import
- QOwnNotes is available in over 60 different languages like English, German,
French, Polish, Chinese, Japanese, Russian, Portuguese, Hungarian, Dutch and Spanish
Installation
Please visit Installation for all the ways to install QOwnNotes.
Building QOwnNotes
To get the most current features you can build the application from the source
code. Download the latest source here:
QOwnNotes Source on GitHub as ZIP
Alternatively you can also check out the code directly from the git repository:
git clone https://github.com/pbek/QOwnNotes.git -b release --depth=1
cd QOwnNotes
git submodule update --initThen download Qt Creator, you will also
need the packages qtwebsockets to build QOwnNotes with Qt6
(only qtwebsockets for Qt5). If you build under Windows, you want to stick to
MinGw 64-bit.
Afterward open the project file src/QOwnNotes.pro and click on
Build / Build Project QOwnNotes.
Or you can build it directly in your terminal:
cd src
# build binary translation files if you want another language than English
lrelease QOwnNotes.pro
# prepare build process and build the application
qmake
make -j4Building QOwnNotes For Development
If you are going to work with the code, then you can do the following instead of the above:
cd src
qmake CONFIG+=DEV_MODE CONFIG+=debug ..
make -j4The DEV_MODE variable enabled higher warning levels + precompiled headers.
Please feel free to contribute source code to this project, make suggestions or
report troubles on the QOwnNotes issues page!
You can also visit QOwnNotes on GitHub.
Minimum software requirements
- A desktop operating system, that supports Qt
- Qt 5.5+ / Qt 6.0+
- gcc 4.8+
Disclaimer
This SOFTWARE PRODUCT is provided by THE PROVIDER "as is" and "with all faults."
THE PROVIDER makes no representations or warranties of any kind concerning the
safety, suitability, lack of viruses, inaccuracies, typographical errors, or
other harmful components of this SOFTWARE PRODUCT.
There are inherent dangers in the use of any software, and you are solely
responsible for determining whether this SOFTWARE PRODUCT is compatible with
your equipment and other software installed on your equipment. You are also
solely responsible for the protection of your equipment and backup of your data,
and THE PROVIDER will not be liable for any damages you may suffer in connection
with using, modifying, or distributing this SOFTWARE PRODUCT.
2. Official Technical Reference & Guides (pbek/QOwnNotes-docs)
File: README.md
qownnotes-docs
Moved to https://github.com/pbek/QOwnNotes/tree/develop/webpage.
File: docs/content/editor/spellchecking.md
Spellchecking
Get your spelling errors corrected
{: .subtitle }
!!! important
QOwnNotes has a builtin Dictionary Manager (in the Edit menu)
which you can use to download dictionaries or delete them (if you are
missing your language see below on how to request adding a dictionary).
If you want to download the dictionaries manually, you can follow the
instructions below.
Under Linux you can install the Hunspell dictionaries for your language using your distro's pkg manager
- If you need to add additional language files you can do so
in~/.local/share/hunspellor/usr/share/hunspell. - If you are using the Snap package of QOwnNotes you can also
use~/hunspellfor language files, since the Snap can't
access~/.local
- If you need to add additional language files you can do so
Under Windows you need to copy Hunspell dictionaries for your language to
a folderdictsin your QOwnNotes application folder or inC:\Users\[username]\dicts- You can download dictionaries from LibreOffice dictionaries
- Under macOS you need to copy Hunspell dictionaries for your
language to/Library/Spellingor~/Library/Spelling. If the
directory doesn't exist you need to create it.
Dictionaries can be downloaded from QOwnNotes
dictionaries. Use the table
at the end of this document to find your language and its respective
language code.
If the dictionary for your language is not in the Dictionary Manager
or in the above mentioned link, please look for it on the internet or
create an issue. We'll be sure to include it in the next release of
QOwnNotes if the dictionary is found.
!!! note
If you can't find your language in this table then unfortunately
a dictionary for it doesn't exist in the LibreOffice files - If you want
to create a dictionary, go to the
Documentfoundation.org Dictionaries Development
| Sr | Language Code | Language |
|---|---|---|
| 1 | af_ZA | Afrikaans (South Africa) |
| 2 | an_ES | Aragonese - Spain (ES) |
| 3 | ar | Arabic |
| 4 | be_BY | Belarusian |
| 5 | bg_BG | Bulgarian |
| 6 | bn_BD | Bengali |
| 7 | bo | Tibetan |
| 8 | br_FR | Breton - France |
| 9 | bs_BA | Bosnian |
| 10 | ca | Catalan |
| 11 | cs_CZ | Czech |
| 12 | da_DK | Danish |
| 13 | de | German |
| 14 | el_GR | Greek |
| 15 | en | English |
| 16 | es | Spanish |
| 17 | et_EE | Estonian |
| 18 | gd_GB | Gaelic |
| 19 | gl | Galician |
| 20 | gu_IN | Gujarati |
| 21 | gug | Guarani |
| 22 | he_IL | Hebrew |
| 23 | hi_IN | Hindi |
| 24 | hr_HR | Croatian |
| 25 | id | Indonesian |
| 26 | it_IT | Italian |
| 27 | kmr_Latn | Kurdish (Turkey) |
| 28 | lo_LA | Lao |
| 29 | lt_LT | Lithuanian |
| 30 | lv_LV | Latvian |
| 31 | ne_NP | Nepali |
| 32 | nl_NL | Dutch |
| 33 | no | Norwegian |
| 34 | oc_FR | Occitan |
| 35 | pl_PL | Polish |
| 36 | pt_BR | Brazilian Portuguese |
| 37 | pt_PT | Portuguese |
| 38 | ro | Romanian |
| 39 | ru_RU | Russian |
| 40 | si_LK | Sinhalese |
| 41 | sk_SK | Slovak |
| 42 | sl_Sl | Slovenian |
| 43 | sq_AL | Albanian |
| 44 | sr | Serbian |
| 45 | sv_SE | Swedish |
| 46 | sw_TZ | Swahili |
| 47 | te_IN | Telugu |
| 48 | th_TH | Thai |
| 49 | tr_TR | Turkish |
| 51 | uk_UA | Ukrainian |
| 52 | vi | Vietnamese |
| 53 | zu_ZA | Zulu(spell dict not avail) |
!!! info
Credits Sonnet with
Hunspell is used for spellchecking
File: docs/content/editor/time-formats.md
Time formats
You can use your own time format when inserting the current time into a
note.
Expressions for the date
| Expression | Output |
|---|---|
d |
the day as number without a leading zero (1 to 31) |
dd |
the day as number with a leading zero (01 to 31) |
ddd |
the abbreviated localized day name (e.g. ?Mon? to ?Sun?). |
dddd |
the long localized day name (e.g. ?Monday? to ?Sunday?). |
M |
the month as number without a leading zero (1-12) |
MM |
the month as number with a leading zero (01-12) |
MMM |
the abbreviated localized month name (e.g. ?Jan? to ?Dec?). |
MMMM |
the long localized month name (e.g. ?January? to ?December?). |
yy |
the year as two digit number (00-99) |
yyyy |
the year as four digit number |
Expressions for the time
| Expression | Output |
|---|---|
h |
the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display) |
hh |
the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display) |
H |
the hour without a leading zero (0 to 23, even with AM/PM display) |
HH |
the hour with a leading zero (00 to 23, even with AM/PM display) |
m |
the minute without a leading zero (0 to 59) |
mm |
the minute with a leading zero (00 to 59) |
s |
the second without a leading zero (0 to 59) |
ss |
the second with a leading zero (00 to 59) |
z |
the milliseconds without leading zeroes (0 to 999) |
zzz |
the milliseconds with leading zeroes (000 to 999) |
AP or A |
use AM/PM display. A/AP will be replaced by either AM or PM. |
ap or a |
use am/pm display. a/ap will be replaced by either am or pm. |
t |
the timezone (for example CEST) |
Example format strings
| Format | Result |
|---|---|
dd.MM.yyyy hh:mm |
21.05.2001 14:13 |
dd.MM.yyyy |
21.05.2001 |
ddd MMMM d yy |
Tue May 21 01 |
hh:mm:ss.zzz |
14:13:09.042 |
h:m:s ap |
2:13:9 pm |
Take a look at the Qt documentation for more
information about time formats.
If you need to make more complex operations to output the current time
please consider creating a custom action.
File: docs/content/getting-started/cli-parameters.md
Command line interface parameters
You can use these parameters on the command line interface:
| Parameter | Description |
|---|---|
--help |
Shows the help screen |
--portable |
Runs the application in portable mode |
--clear-settings |
Clears the settings and runs the application |
--dump-settings |
Prints out a dump of the settings and other information about the application and environment in GitHub Markdown and exits the application |
--session <name> |
Runs the application in a different context for settings and internal files |
--allow-multiple-instances |
Allows multiple instances of QOwnNotes to be started even if disallowed in the settings |
!!! tip
If you run into troubles with your installation of QOwnNotes you may want start
the application with fresh settings without loosing your current settings by using
the --session parameter.
```bash
QOwnNotes --session test
```You may run the application on the command line interface differently on
different operating systems:
| Operating system | Output |
|---|---|
| Linux | QOwnNotes (or qownnotes if installed as snap) |
| macOS | /Applications/QOwnNotes.app/Contents/MacOS/QOwnNotes |
| Windows | QOwnNotes.exe |
File: docs/content/getting-started/install-qownnotes.md
Install QOwnNotes
!!! tip
Visit the QOwnNotes installation page for information
about how to install QOwnNotes!
File: docs/content/scripting/classes.md
Exposed classes
Note
!!! help "Properties and methods"
cpp class NoteApi { Q_PROPERTY(int id) Q_PROPERTY(QString name) Q_PROPERTY(QString fileName) Q_PROPERTY(QString fullNoteFilePath) Q_PROPERTY(QString fullNoteFileDirPath) Q_PROPERTY(int noteSubFolderId) Q_PROPERTY(QString noteText) Q_PROPERTY(QString decryptedNoteText) Q_PROPERTY(bool hasDirtyData) Q_PROPERTY(QQmlListProperty<TagApi> tags) Q_PROPERTY(QDateTime fileCreated) Q_PROPERTY(QDateTime fileLastModified) Q_INVOKABLE QStringList tagNames(); Q_INVOKABLE bool addTag(QString tagName); Q_INVOKABLE bool removeTag(QString tagName); Q_INVOKABLE QString toMarkdownHtml(bool forExport = true); Q_INVOKABLE QString getFileURLFromFileName(QString localFileName); };
You can use the methods from
Date
to work with fileCreated or fileLastModified.
!!! example
js script.log(note.fileCreated.toISOString()); script.log(note.fileLastModified.getFullYear());
Tag
!!! help "Properties and methods"
cpp class TagApi { Q_PROPERTY(int id) Q_PROPERTY(QString name) Q_PROPERTY(int parentId) };
MainWindow
!!! help "Properties and methods"
cpp class MainWindow { Q_INVOKABLE void reloadTagTree(); Q_INVOKABLE void reloadNoteSubFolderTree(); Q_INVOKABLE void buildNotesIndexAndLoadNoteDirectoryList( bool forceBuild = false, bool forceLoad = false); Q_INVOKABLE void focusNoteTextEdit(); };
!!! example
js // force a reload of the note list mainWindow.buildNotesIndexAndLoadNoteDirectoryList(true, true);
File: docs/content/scripting/hooks.md
Hooks
onNoteStored
!!! help "Method call and parameters"
js /** * This function is called when a note gets stored to disk * You cannot modify stored notes, that would be a mess since * you are most likely editing them by hand at the same time * * @param {NoteApi} note - the note object of the stored note */ function onNoteStored(note);
You may want to take a look at the example
on-note-opened.qml.
noteOpenedHook
!!! help "Method call and parameters"
js /** * This function is called after a note was opened * * @param {NoteApi} note - the note object that was opened */ function noteOpenedHook(note);
You may want to take a look at the example
on-note-opened.qml.
noteDoubleClickedHook
!!! help "Method call and parameters"
js /** * This function is called after a note was double clicked * * @param {NoteApi} note - the note object that was clicked */ function noteDoubleClickedHook(note);
You may want to take a look at the example
external-note-open.qml.
insertMediaHook
!!! help "Method call and parameters"
js /** * This function is called when media file is inserted into the note * If this function is defined in multiple scripts, then the first script that returns a non-empty string wins * * @param fileName string the file path of the source media file before it was copied to the media folder * @param mediaMarkdownText string the markdown text of the media file, e.g. * @return string the new markdown text of the media file */ function insertMediaHook(fileName, mediaMarkdownText);
You may want to take a look at the example
example.qml.
insertingFromMimeDataHook
!!! help "Method call and parameters"
js /** * This function is called when html or a media file is pasted to a note with `Ctrl + Shift + V` * * @param text text of the QMimeData object * @param html html of the QMimeData object * @returns the string that should be inserted instead of the text from the QMimeData object */ function insertingFromMimeDataHook(text, html);
You may want to take a look at the example
example.qml,
insert-headline-with-link-from-github-url.qml
or
note-text-from-5pm-mail.qml.
handleNoteTextFileNameHook
!!! help "Method call and parameters"
js /** * This function is called when a note gets stored to disk if * "Allow note file name to be different from headline" is enabled * in the settings * * It allows you to modify the name of the note file * Keep in mind that you have to care about duplicate names yourself! * * Return an empty string if the file name of the note should * not be modified * * @param {NoteApi} note - the note object of the stored note * @return {string} the file name of the note */ function handleNoteTextFileNameHook(note);
You may want to take a look at the example
example.qml
or
use-tag-names-in-filename.qml.
handleNoteNameHook
!!! help "Method call and parameters"
js /** * This function is called when the note name is determined for a note * * It allows you to modify the name of the note that is viewed * * Return an empty string if the name of the note should not be modified * * @param {NoteApi} note - the note object of the stored note * @return {string} the name of the note */ function handleNoteNameHook(note);
You may want to take a look at the example
example.qml.
It may not be a good idea to use this hook if the setting to use the
file name as note name is active.
handleNewNoteHeadlineHook
!!! help "Method call and parameters"
js /** * This function is called before a note note is created * * It allows you to modify the headline of the note before it is created * Note that you have to take care about a unique note name, otherwise * the new note will not be created, it will just be found in the note list * * You can use this method for creating note templates * * @param headline text that would be used to create the headline * @return {string} the headline of the note */ function handleNewNoteHeadlineHook(headline);
You may want to take a look at the example
custom-new-note-headline.qml.
preNoteToMarkdownHtmlHook
!!! help "Method call and parameters"
js /** * This function is called before the markdown html of a note is generated * * It allows you to modify what is passed to the markdown to html converter * * The method can for example be used in multiple scripts to render code (like LaTeX math or mermaid) * to its graphical representation for the preview * * The note will not be changed in this process * * @param {NoteApi} note - the note object * @param {string} markdown - the markdown that is about to being converted to html * @return {string} the modified markdown or an empty string if nothing should be modified */ function preNoteToMarkdownHtmlHook(note, markdown);
You may want to take a look at the example
preview-styling.qml.
noteToMarkdownHtmlHook
!!! help "Method call and parameters"
js /** * This function is called when the markdown html of a note is generated * * It allows you to modify this html * This is for example called before by the note preview * * The method can be used in multiple scripts to modify the html of the preview * * @param {NoteApi} note - the note object * @param {string} html - the html that is about to being rendered * @return {string} the modified html or an empty string if nothing should be modified */ function noteToMarkdownHtmlHook(note, html);
You may want to take a look at the example
example.qml
or
preview-styling.qml.
Please refer to the Supported HTML
Subset documentation
for a list of all supported css styles.
encryptionHook
!!! help "Method call and parameters"
js /** * This function is called when text has to be encrypted or decrypted * * @param text string the text to encrypt or decrypt * @param password string the password * @param decrypt bool if false encryption is demanded, if true decryption is demanded * @return the encrypted decrypted text */ function encryptionHook(text, password, decrypt);
You may want to take a look at the example
encryption-keybase.qml,
encryption-pgp.qml
or
encryption-rot13.qml.
noteTaggingHook
You can implement your own note tagging mechanism for example with
special text in your note like @tag1, @tag2, @tag3.
!!! help "Method call and parameters"
js /** * Handles note tagging for a note * * This function is called when tags are added to, removed from or renamed in * a note or the tags of a note should be listed * * @param note * @param action can be "add", "remove", "rename" or "list" * @param tagName tag name to be added, removed or renamed * @param newTagName tag name to be renamed to if action = "rename" * @return string or string-list (if action = "list") */ function noteTaggingHook(note, action, tagName, newTagName);
as soon as a script is activated that implements the new function
noteTaggingHooknote tagging will be handled by that functionfollowing features should work via the QOwnNotes user interface
- initially importing tags like
@tagfrom your notes and
overwriting your current tag assignment- you will not loose your tags tree, just the former assignment
to notes - you can still move tags into other tags
- if more than one tag has the same name in your tag tree the
first hit will be assigned
- you will not loose your tags tree, just the former assignment
- adding a tag to a note will add the tag to the note text
- removing a tag from a note will remove the tag from the note text
- removing of tags in the tag list will remove those tags from your
notes - renaming of tags in the tag list will rename those tags in your
notes - bulk tagging of notes in the note list will add those tags to your
notes - bulk removing of tags from notes in the note list will remove
those tags from your notes
- initially importing tags like
You may want to take a look at the example
note-tagging.qml
to implement your own tagging mechanism.
autocompletionHook
You can return a list of strings to be added to the autocompletion list
when the autocompletion is invoked.
!!! help "Method call and parameters"
js /** * Calls the autocompletionHook function for all script components * This function is called when autocompletion is invoked in a note * * @return QStringList of text for the autocomplete list */ function callAutocompletionHook();
You may want to take a look at the example
autocompletion.qml.
File: docs/content/scripting/index.md
QOwnNotes Scripting
A QOwnNotes script is mostly a JavaScript file with a qml file extension.
!!! example "Example hello-world.qml"
```js
import QtQml 2.0
import QOwnNotesTypes 1.0
Script {
/**
* Will be run when the scripting engine initializes
*/
function init() {
script.log("Hello world!");
}
}
```You can place those QML files anywhere you like and add use them in QOwnNotes
by adding them in the Scripting settings.
!!! tip
Take a look at the example scripts
to get started fast.
In the Scripting settings you can also install scripts directly from the Script repository.
For issues, questions or feature requests for scripts from the Script repository please open
an issue on the QOwnNotes script repository issue page.
!!! info
If you want to propose a script for the Script repository please follow the
instructions at QOwnNotes script repository.
If you need access to a certain functionality in QOwnNotes or have
questions or ideas please open an issue on the QOwnNotes issue page.
!!! help
For logging you can use the script.log() command to log to the log widget.
File: docs/content/scripting/methods-and-objects.md
Methods and objects QOwnNotes provides
Starting an external program in the background
!!! help "Method call and parameters"
cpp /** * QML wrapper to start a detached process * * @param executablePath the path of the executable * @param parameters a list of parameter strings * @return true on success, false otherwise */ bool startDetachedProcess(QString executablePath, QStringList parameters);
!!! example
js script.startDetachedProcess("/path/to/my/program", ["my parameter"]);
You may want to take a look at the example
custom-actions.qml
or
execute-command-after-note-update.qml.
Starting an external program and wait for the output
!!! help "Method call and parameters"
cpp /** * QML wrapper to start a synchronous process * * @param executablePath the path of the executable * @param parameters a list of parameter strings * @param data the data that will be written to the process (optional) * @return the text that was returned by the process QByteArray startSynchronousProcess(QString executablePath, QStringList parameters, QByteArray data);
!!! example
js var result = script.startSynchronousProcess("/path/to/my/program", ["my parameter"], "data");
You may want to take a look at the example
encryption-keybase.qml.
Getting the path of the current note folder
!!! help "Method call and parameters"
cpp /** * QML wrapper to get the current note folder path * * @return the path of the current note folder */ QString currentNoteFolderPath();
!!! example
```js
var path = script.currentNoteFolderPath();
```You may want to take a look at the example
absolute-media-links.qml.
Getting the current note
!!! help "Method call and parameters"
cpp /** * QML wrapper to get the current note * * @returns {NoteApi} the the current note object */ NoteApi currentNote();
!!! example
js var note = script.currentNote();
You may want to take a look at the example
custom-actions.qml.
Logging to the log widget
!!! help "Method call and parameters"
cpp /** * QML wrapper to log to the log widget * * @param text */ void log(QString text);
!!! example
js script.log("my text");
Downloading an url to a string
!!! help "Method call and parameters"
cpp /** * QML wrapper to download an url and returning it as text * * @param url * @return {QString} the content of the downloaded url */ QString downloadUrlToString(QUrl url);
!!! example
js var html = script.downloadUrlToString("https://www.qownnotes.org");
You may want to take a look at the example
insert-headline-with-link-from-github-url.qml.
Downloading an url to the media folder
!!! help "Method call and parameters"
cpp /** * QML wrapper to download an url to the media folder and returning the media * url or the markdown image text of the media relative to the current note * * @param {QString} url * @param {bool} returnUrlOnly if true only the media url will be returned (default false) * @return {QString} the media markdown or url */ QString downloadUrlToMedia(QUrl url, bool returnUrlOnly);
!!! example
js var markdown = script.downloadUrlToMedia("http://latex.codecogs.com/gif.latex?\frac{1}{1+sin(x)}");
You may want to take a look at the example
paste-latex-image.qml.
Inserting a media file into the media folder
!!! help "Method call and parameters"
cpp /** * QML wrapper to insert a media file into the media folder and returning * the media url or the markdown image text of the media relative to the current note * * @param {QString} mediaFilePath * @param {bool} returnUrlOnly if true only the media url will be returned (default false) * @return {QString} the media markdown or url */ QString ScriptingService::insertMediaFile(QString mediaFilePath, bool returnUrlOnly);
!!! example
js var markdown = script.insertMediaFile("/path/to/your/image.png");
You may want to take a look at the example
scribble.qml.
Regenerating the note preview
Refreshes the note preview.
!!! help "Method call and parameters"
cpp /** * Regenerates the note preview */ QString ScriptingService::regenerateNotePreview();
!!! example
js script.regenerateNotePreview();
You may want to take a look at the example
scribble.qml.
Registering a custom action
!!! help "Method call and parameters"
cpp /** * Registers a custom action * * @param identifier the identifier of the action * @param menuText the text shown in the menu * @param buttonText the text shown in the button * (no button will be viewed if empty) * @param icon the icon file path or the name of a freedesktop theme icon * you will find a list of icons here: * https://specifications.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html * @param useInNoteEditContextMenu if true use the action in the note edit * context menu (default: false) * @param hideButtonInToolbar if true the button will not be shown in the * custom action toolbar (default: false) * @param useInNoteListContextMenu if true use the action in the note list * context menu (default: false) */ void ScriptingService::registerCustomAction(QString identifier, QString menuText, QString buttonText, QString icon, bool useInNoteEditContextMenu, bool hideButtonInToolbar, bool useInNoteListContextMenu);
!!! example
```js
// add a custom action without a button
script.registerCustomAction("mycustomaction1", "Menu text");
// add a custom action with a button
script.registerCustomAction("mycustomaction1", "Menu text", "Button text");
// add a custom action with a button and freedesktop theme icon
script.registerCustomAction("mycustomaction1", "Menu text", "Button text", "task-new");
// add a custom action with a button and an icon from a file
script.registerCustomAction("mycustomaction1", "Menu text", "Button text", "/usr/share/icons/breeze/actions/24/view-calendar-tasks.svg");
```You may then want to use the identifier with functioncustomActionInvoked in a script like
custom-actions.qml.
Registering a label
!!! help "Method call and parameters"
cpp /** * Registers a label to write to * * @param identifier the identifier of the label * @param text the text shown in the label (optional) */ void ScriptingService::registerLabel(QString identifier, QString text);
!!! example
```js
script.registerLabel("html-label", "Strong HTML textwith three linesand a link to a website.");
script.registerLabel("long-label", "an other very long text, an other very long text, an other very long text, an other very long text, an other very long text, an other very long text, an other very long text, an other very long text, an other very long text, an other very long text, an other very long text that will wrap");
script.registerLabel("counter-label");
```The labels will be visible in the scripting dock widget.
You can use both plain text or html in the labels. The text will be
selectable and links can be clicked.
You may then want to take a look at the example script
scripting-label-demo.qml.
Setting the text of a registered label
!!! help "Method call and parameters"
cpp /** * Sets the text of a registered label * * @param identifier the identifier of the label * @param text the text shown in the label */ void ScriptingService::setLabelText(QString identifier, QString text);
!!! example
js script.setLabelText("counter-label", "counter text");
You can use both plain text or html in the labels. The text will be
selectable and links can be clicked.
You may then want to take a look at the example script
scripting-label-demo.qml.
Creating a new note
!!! help "Method call and parameters"
cpp /** * Creates a new note * * @param text the note text */ void ScriptingService::createNote(QString text);
!!! example
js script.createNote("My note headline\n===\n\nMy text");
You may want to take a look at the example
custom-actions.qml.
Accessing the clipboard
!!! help "Method call and parameters"
cpp /** * Returns the content of the clipboard as text or html * * @param asHtml returns the clipboard content as html instead of text */ QString ScriptingService::clipboard(bool asHtml);
!!! example
js var clipboardText = script.clipboard(); var clipboardHtml = script.clipboard(true);
You may want to take a look at the example
custom-actions.qml.
Write text to the note text edit
!!! help "Method call and parameters"
cpp /** * Writes text to the current cursor position in the note text edit * * @param text */ void ScriptingService::noteTextEditWrite(QString text);
!!! example
js // write text to the note text edit script.noteTextEditWrite("My custom text");
You might want to look at the custom action transformTextRot13 in the
example
custom-actions.qml.
You can use this together with noteTextEditSelectAll to overwrite the
whole text of the current note.
Read the selected text in the note text edit
!!! help "Method call and parameters"
cpp /** * Reads the selected text in the note text edit * * @return */ QString ScriptingService::noteTextEditSelectedText();
!!! example
js // read the selected text from the note text edit var text = script.noteTextEditSelectedText();
You might want to look at the custom action transformTextRot13 in the
example
custom-actions.qml.
Select all text in the note text edit
!!! help "Method call and parameters"
cpp /** * Selects all text in the note text edit */ void ScriptingService::noteTextEditSelectAll();
!!! example
js script.noteTextEditSelectAll();
You can use this together with noteTextEditWrite to overwrite the
whole text of the current note.
Select the current line in the note text edit
!!! help "Method call and parameters"
cpp /** * Selects the current line in the note text edit */ void ScriptingService::noteTextEditSelectCurrentLine();
!!! example
js script.noteTextEditSelectCurrentLine();
Select the current word in the note text edit
!!! help "Method call and parameters"
cpp /** * Selects the current line in the note text edit */ void ScriptingService::noteTextEditSelectCurrentWord();
!!! example
js script.noteTextEditSelectCurrentWord();
Set the currently selected text in the note text edit
!!! help "Method call and parameters"
cpp /** * Sets the currently selected text in the note text edit * * @param start * @param end */ void ScriptingService::noteTextEditSetSelection(int start, int end);
!!! example
js // expands the current selection by one character script.noteTextEditSetSelection( script.noteTextEditSelectionStart() - 1, script.noteTextEditSelectionEnd() + 1);
Get the start position of the current selection in the note text edit
!!! help "Method call and parameters"
cpp /** * Returns the start position of the current selection in the note text edit */ int ScriptingService::noteTextEditSelectionStart();
!!! example
js script.log(script.noteTextEditSelectionStart());
Get the end position of the current selection in the note text edit
!!! help "Method call and parameters"
cpp /** * Returns the end position of the current selection in the note text edit */ int ScriptingService::noteTextEditSelectionEnd();
!!! example
js script.log(script.noteTextEditSelectionEnd());
Read the current word from the note text edit
!!! help "Method call and parameters"
cpp /** * Reads the current word in the note text edit * * @param withPreviousCharacters also get more characters at the beginning * to get characters like "@" that are not * word-characters * @return */ QString ScriptingService::noteTextEditCurrentWord(bool withPreviousCharacters);
!!! example
js // read the current word in the note text edit var text = script.noteTextEditCurrentWord();
You may want to take a look at the example
autocompletion.qml.
Check whether platform is Linux, OS X or Windows
!!! help "Method call and parameters"
cpp bool ScriptingService::platformIsLinux(); bool ScriptingService::platformIsOSX(); bool ScriptingService::platformIsWindows();
!!! example
js if (script.platformIsLinux()) { // only will be executed if under Linux }
Tag the current note
!!! help "Method call and parameters"
cpp /** * Tags the current note with a tag named tagName * * @param tagName */ void ScriptingService::tagCurrentNote(QString tagName);
!!! example
js // add a "favorite" tag to the current note script.tagCurrentNote("favorite");
You might want to look at the custom action favoriteNote in the
example
favorite-note.qml.
Search for tags by name
!!! help "Method call and parameters"
cpp /** * Fetches all tags by doing a substring search on the name field * * @param name {QString} name to search for * @return {QStringList} list of tag names */ QStringList ScriptingService::searchTagsByName(QString name);
!!! example
js // searches for all tags with the word game in it var tags = script.searchTagsByName("game");
You may want to take a look at the example
autocompletion.qml.
Search for notes by note text
!!! help "Method call and parameters"
cpp /** * Returns a list of note ids of all notes with a certain text in the note text * * Unfortunately there is no easy way to use a QList<NoteApi*> in QML, so we * can only transfer the note ids * * @return {QList} list of note ids */ QList ScriptingService::fetchNoteIdsByNoteTextPart(QString text);
!!! example
```js
var noteIds = script.fetchNoteIdsByNoteTextPart("mytext");
noteIds.forEach(function (noteId){
var note = script.fetchNoteById(noteId);
// do something with the note
});
```You may want to take a look at the example
unique-note-id.qml.
Add a custom stylesheet
!!! help "Method call and parameters"
cpp /** * Adds a custom stylesheet to the application * * @param stylesheet */ void ScriptingService::addStyleSheet(QString stylesheet);
!!! example
js // make the text in the note list bigger script.addStyleSheet("QTreeWidget#noteTreeWidget {font-size: 30px;}");
You may want to take a look at the example
custom-stylesheet.qml.
You can get the object names from the *.ui files, for example
mainwindow.ui.
Take a look at Style Sheet
Reference for a
reference of what styles are available.
If you want to inject styles into html preview to alter the way notes
are previewed please look at
notetomarkdownhtmlhook.
Reloading the scripting engine
!!! help "Method call and parameters"
cpp /** * Reloads the scripting engine */ void ScriptingService::reloadScriptingEngine();
!!! example
js // reload the scripting engine script.reloadScriptingEngine();
Fetching a note by its file name
!!! help "Method call and parameters"
cpp /** * Fetches a note by its file name * * @param fileName string the file name of the note (mandatory) * @param noteSubFolderId integer id of the note subfolder * @return NoteApi* */ NoteApi* ScriptingService::fetchNoteByFileName(QString fileName, int noteSubFolderId);
!!! example
js // fetch note by file name script.fetchNoteByFileName("my note.md");
Fetching a note by its id
!!! help "Method call and parameters"
cpp /** * Fetches a note by its id * * @param id int the id of the note * @return NoteApi* */ NoteApi* ScriptingService::fetchNoteById(int id);
!!! example
js // fetch note by id script.fetchNoteById(243);
You may want to take a look at the example
export-notes-as-one-html.qml.
Checking if a note exists by its file name
!!! help "Method call and parameters"
cpp /** * Checks if a note file exists by its file name * * @param fileName string the file name of the note (mandatory) * @param ignoreNoteId integer id of a note to ignore in the check * @param noteSubFolderId integer id of the note subfolder * @return bool */ bool ScriptingService::noteExistsByFileName(QString fileName, int ignoreNoteId, int noteSubFolderId);
!!! example
js // check if note exists, but ignore the id of "note" script.noteExistsByFileName("my note.md", note.id);
You may want to take a look at the example
use-tag-names-in-filename.qml.
Copying text into the clipboard
!!! help "Method call and parameters"
cpp /** * Copies text into the clipboard as plain text or html mime data * * @param text string text to put into the clipboard * @param asHtml bool if true the text will be set as html mime data */ void ScriptingService::setClipboardText(QString text, bool asHtml);
!!! example
js // copy text to the clipboard script.setClipboardText("text to copy");
You may want to take a look at the example
selected-markdown-to-bbcode.qml.
Jumping to a note
!!! help "Method call and parameters"
cpp /** * Sets the current note if the note is visible in the note list * * @param note NoteApi note to jump to */ void ScriptingService::setCurrentNote(NoteApi *note);
!!! example
js // jump to the note script.setCurrentNote(note);
You may want to take a look at the example
journal-entry.qml.
Jumping to a note subfolder
!!! help "Method call and parameters"
cpp /** * Jumps to a note subfolder * * @param noteSubFolderPath {QString} path of the subfolder, relative to the note folder * @param separator {QString} separator between parts of the path, default "/" * @return true if jump was successful */ bool ScriptingService::jumpToNoteSubFolder(const QString ¬eSubFolderPath, QString separator);
!!! example
```js
// jump to the note subfolder "a sub folder"
script.jumpToNoteSubFolder("a sub folder");
// jump to the note subfolder "sub" inside of "a sub folder"
script.jumpToNoteSubFolder("a sub folder/sub");
```Showing an information message box
!!! help "Method call and parameters"
cpp /** * Shows an information message box * * @param text * @param title (optional) */ void ScriptingService::informationMessageBox(QString text, QString title);
!!! example
js // show a information message box script.informationMessageBox("The text I want to show", "Some optional title");
Showing a question message box
!!! help "Method call and parameters"
cpp /** * Shows a question message box * * For information about buttons see: * https://doc.qt.io/qt-5/qmessagebox.html#StandardButton-enum * * @param text * @param title (optional) * @param buttons buttons that should be shown (optional) * @param defaultButton default button that will be selected (optional) * @return id of pressed button */ int ScriptingService::questionMessageBox( QString text, QString title, int buttons, int defaultButton);
!!! example
js // show a question message box with an apply and a help button // see: https://doc.qt.io/qt-5/qmessagebox.html#StandardButton-enum var result = script.questionMessageBox( "The text I want to show", "Some optional title", 0x01000000|0x02000000, 0x02000000); script.log(result);
For information about buttons see
StandardButton.
You may also want to take a look at the example
input-dialogs.qml.
Showing an open file dialog
!!! help "Method call and parameters"
cpp /** * Shows an open file dialog * * @param caption (optional) * @param dir (optional) * @param filter (optional) * @return QString */ QString ScriptingService::getOpenFileName(QString caption, QString dir, QString filter);
!!! example
js // show an open file dialog var fileName = script.getOpenFileName("Please select an image", "/home/user/images", "Images (*.png *.xpm *.jpg)");
Showing a save file dialog
!!! help "Method call and parameters"
cpp /** * Shows a save file dialog * * @param caption (optional) * @param dir (optional) * @param filter (optional) * @return QString */ QString ScriptingService::getSaveFileName(QString caption, QString dir, QString filter);
!!! example
js // show a save file dialog var fileName = script.getSaveFileName("Please select HTML file to save", "output.html", "HTML (*.html)");
You may want to take a look at the example
export-notes-as-one-html.qml.
Registering script settings variables
You need to define properties in your script and register them in an
further property named settingsVariables.
The user can then set these properties in the script settings.
!!! example
```
/* Detailed source-code truncated for AI context efficiency. */
In addition you can override the `settingsVariables` with a special
function `registerSettingsVariables()` like this:
!!! example
```js
/**
* Registers the settings variables again
*
* Use this method if you want to use code to override your variables, like setting
* default values depended on the operating system.
*/
function registerSettingsVariables() {
if (script.platformIsWindows()) {
// override the myFile default value
settingsVariables[3].default = "pandoc.exe"
}
}
```
You may also want to take a look at the example
[variables.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/variables.qml).
Storing and loading persistent variables
----------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Stores a persistent variable
* These variables are accessible globally over all scripts
* Please use a meaningful prefix in your key like "PersistentVariablesTest/myVar"
*
* @param key {QString}
* @param value {QVariant}
*/
void ScriptingService::setPersistentVariable(const QString &key,
const QVariant &value);
/**
* Loads a persistent variable
* These variables are accessible globally over all scripts
*
* @param key {QString}
* @param defaultValue {QVariant} return value if the setting doesn't exist (optional)
* @return
*/
QVariant ScriptingService::getPersistentVariable(const QString &key,
const QVariant &defaultValue);
```
!!! example
```js
// store persistent variable
script.setPersistentVariable("PersistentVariablesTest/myVar", result);
// load and log persistent variable
script.log(script.getPersistentVariable("PersistentVariablesTest/myVar", "nothing here yet"));
```
Please make sure to use a meaningful prefix in your key like
`PersistentVariablesTest/myVar` because the variables are accessible
from all scripts.
You may also want to take a look at the example
[persistent-variables.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/persistent-variables.qml).
Loading application settings variables
--------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Loads an application settings variable
*
* @param key {QString}
* @param defaultValue {QVariant} return value if the setting doesn't exist (optional)
* @return
*/
QVariant ScriptingService::getApplicationSettingsVariable(const QString &key,
const QVariant &defaultValue);
```
!!! example
```js
// load and log an application settings variable
script.log(script.getApplicationSettingsVariable("gitExecutablePath"));
```
Keep in mind that settings actually can be empty, you have to take care
about that yourself. `defaultValue` is only used if the setting doesn't
exist at all.
Reading the path to the directory of your script
------------------------------------------------
If you need to get the path to the directory where your script is placed
to for example load other files you have to register a
`property string scriptDirPath;`. This property will be set with the
path to the script's directory.
!!! example
```js
import QtQml 2.0
import QOwnNotesTypes 1.0
Script {
// the path to the script's directory will be set here
property string scriptDirPath;
function init() {
script.log(scriptDirPath);
}
}
```
Converting path separators to native ones
-----------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Returns path with the '/' separators converted to separators that are
* appropriate for the underlying operating system.
*
* On Windows, toNativeDirSeparators("c:/winnt/system32") returns
* "c:\winnt\system32".
*
* @param path
* @return
*/
QString ScriptingService::toNativeDirSeparators(QString path);
```
!!! example
```js
// will return "c:\winnt\system32" on Windows
script.log(script.toNativeDirSeparators("c:/winnt/system32"));
```
Converting path separators from native ones
-------------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Returns path using '/' as file separator.
* On Windows, for instance, fromNativeDirSeparators("c:\\winnt\\system32")
* returns "c:/winnt/system32".
*
* @param path
* @return
*/
QString ScriptingService::fromNativeDirSeparators(QString path);
```
!!! example
```js
// will return "c:/winnt/system32" on Windows
script.log(script.fromNativeDirSeparators("c:\\winnt\\system32"));
```
Getting the native directory separator
--------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Returns the native directory separator "/" or "\" on Windows
*
* @return
*/
QString ScriptingService::dirSeparator();
```
!!! example
```js
// will return "\" on Windows
script.log(script.dirSeparator());
```
Getting a list of the paths of all selected notes
-------------------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Returns a list of the paths of all selected notes
*
* @return {QStringList} list of selected note paths
*/
QStringList ScriptingService::selectedNotesPaths();
```
!!! example
```js
// returns a list of the paths of all selected notes
script.log(script.selectedNotesPaths());
```
You may want to take a look at the example
[external-note-diff.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/external-note-diff.qml).
Getting a list of the ids of all selected notes
-----------------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Returns a list of the ids of all selected notes
*
* @return {QList} list of selected note ids
*/
QList ScriptingService::selectedNotesIds();
```
!!! example
```js
// returns a list of the ids of all selected notes
script.log(script.selectedNotesIds());
```
You may want to take a look at the example
[export-notes-as-one-html.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/export-notes-as-one-html.qml).
Triggering a menu action
------------------------
!!! help "Method call and parameters"
```cpp
/**
* Triggers a menu action
*
* @param objectName {QString} object name of the action to trigger
* @param checked {QString} only trigger the action if checked-state is
* different than this parameter (optional, can be 0 or 1)
*/
void ScriptingService::triggerMenuAction(QString objectName, QString checked);
```
!!! example
```js
// toggle the read-only mode
script.triggerMenuAction("actionAllow_note_editing");
// disable the read-only mode
script.triggerMenuAction("actionAllow_note_editing", 1);
```
You may want to take a look at the example
[disable-readonly-mode.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/disable-readonly-mode.qml).
You can get the object names of the menu action from
[mainwindow.ui](https://github.com/pbek/QOwnNotes/blob/develop/src/mainwindow.ui).
Opening an input dialog with a select box
-----------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Opens an input dialog with a select box
*
* @param title {QString} title of the dialog
* @param label {QString} label text of the dialog
* @param items {QStringList} list of items to select
* @param current {int} index of the item that should be selected (default: 0)
* @param editable {bool} if true the text in the dialog can be edited (default: false)
* @return {QString} text of the selected item
*/
QString ScriptingService::inputDialogGetItem(
const QString &title, const QString &label, const QStringList &items,
int current, bool editable);
```
!!! example
```js
var result = script.inputDialogGetItem(
"combo box", "Please select an item", ["Item 1", "Item 2", "Item 3"]);
script.log(result);
```
You may want to take a look at the example
[input-dialogs.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/input-dialogs.qml).
Opening an input dialog with a line edit
----------------------------------------
!!! help "Method call and parameters"
```cpp
/**
* Opens an input dialog with a line edit
*
* @param title {QString} title of the dialog
* @param label {QString} label text of the dialog
* @param text {QString} text in the dialog (optional)
* @return
*/
QString ScriptingService::inputDialogGetText(
const QString &title, const QString &label, const QString &text);
```
!!! example
```js
var result = script.inputDialogGetText(
"line edit", "Please enter a name", "current text");
script.log(result);
```
Writing text to a file
----------------------
!!! help "Method call and parameters"
```cpp
/**
* Writes a text to a file
*
* @param filePath
* @param data
* @return
*/
bool ScriptingService::writeToFile(const QString &filePath, const QString &data);
```
!!! example
```js
var result = script.writeToFile(filePath, html);;
script.log(result);
```
You may want to take a look at the example
[export-notes-as-one-html.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/export-notes-as-one-html.qml).
Working with websockets
-----------------------
You can remote control QOwnNotes by using `WebSocketServer`.
Please take a look at the example
[websocket-server.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/websocket-server.qml).
You can test the socket server by connecting to it on [Websocket
test](https://www.websocket.org/echo.html?location=ws://127.0.0.1:35345).
You can also listen to sockets with `WebSocket`. Please take look at the
example
[websocket-client.qml](https://github.com/pbek/QOwnNotes/blob/develop/doc/scripting/websocket-client.qml).
Keep in mind that you need to have Qt's QML `websocket` library
installed to use this. For example under Ubuntu Linux you can install
`qml-module-qtwebsockets`.
---
## File: docs/content/index.md
# Welcome
[QOwnNotes](https://www.qownnotes.org/) is the **open source** (GPL) plain-text file
**markdown note taking** application for **GNU/Linux**, **Mac OS X** and **Windows**
by [Patrizio Bekerle](https://keybase.io/pbek) (*pbek* on GitHub and IRC), that
(optionally) works together with the [**notes application**](https://github.com/nextcloud/notes)
of [ownCloud](https://owncloud.org/) or [Nextcloud](https://nextcloud.com/).
!!! info
Join our [Telegram Group](https://t.me/QOwnNotes) to discuss, learn, and connect with the QOwnNotes community.