1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-08-24 20:19:10 +02:00

Compare commits

...

400 Commits

Author SHA1 Message Date
Laurent Cozic
c0d679b6c2 Android release v1.0.178 2018-12-16 18:41:51 +01:00
Laurent Cozic
eb789b9b9a Electron release v1.0.119 2018-12-16 18:35:37 +01:00
Laurent Cozic
b1898141c3 Mobile: Fixes #382: Implemented new search engine for mobile and highlight searched words in notes 2018-12-16 18:32:42 +01:00
Laurent Cozic
3231bfaff0 Mobile: Fixes #1045: Display notebooks as a tree in notebook dropdown 2018-12-16 17:18:24 +01:00
Laurent Cozic
6bb09c9c30 Updated FAQ with info about F-Droid and how to fix Nextcloud issues 2018-12-16 14:30:56 +01:00
Laurent Cozic
35d3fe03ab Android: Fixes #321: Changed notification library to Firebase to get more reliable notifications 2018-12-16 14:11:45 +01:00
Laurent Cozic
f05929cd17 All: Fixes #1033: Handle hard break when rendering Markdown to HTML 2018-12-16 11:41:15 +01:00
Laurent Cozic
982c9828da Desktop: Fixes #1039: Always print or export to PDF using light theme 2018-12-16 02:49:06 +01:00
Laurent Cozic
d6eacb2b33 Android release v1.0.177 2018-12-15 01:51:49 +01:00
Laurent Cozic
0abe213fc2 Merge branch 'master' of github.com:laurent22/joplin 2018-12-15 01:46:16 +01:00
Laurent Cozic
a6716d55c5 Doc: Added search engine doc 2018-12-15 01:46:06 +01:00
Laurent Cozic
fa0572de77 Mobile: Many small fixes and improvements to style and layout to make app more usable 2018-12-15 01:45:35 +01:00
Laurent Cozic
6dca4a0d6b Mobile: Optimised loading of large notes that contain many images. 2018-12-15 01:42:19 +01:00
Helmut K. C. Tessarek
eacfe1a9ac add Apache WebDAV Module to WebDAV-compatible services (#1042) 2018-12-14 22:50:50 +00:00
Laurent Cozic
c223cdf10a Electron release v1.0.118 2018-12-14 19:57:32 +01:00
Laurent Cozic
38c42b7a15 Merge branch 'full_text_search' 2018-12-14 19:56:21 +01:00
Mats Estensen
56432dc773 [Documentation] Add example editor config to FAQ (#1036)
* add external editor example config to faq

* add external editor to feature list
2018-12-14 18:04:53 +00:00
Lucas
d3b4379161 Update to make it works in Kubuntu (#1038)
The directory ~/.local/share/applications/ exists in Kubuntu 18.04 so with this change the script also work in Kubuntu.
2018-12-14 18:03:39 +00:00
Laurent Cozic
8a6fcdbcae Should be commented out by default 2018-12-14 00:00:03 +01:00
Laurent Cozic
061ce646d2 Finished search engine integration with desktop app 2018-12-13 23:57:14 +01:00
Laurent Cozic
5ec7c16e3e Fixed logic to update search engine data 2018-12-12 22:40:05 +01:00
Andros Fenollosa
5d629508c1 Fix name in Linux Desktop (#1034) 2018-12-11 21:51:47 +01:00
Laurent Cozic
0a6f8b0cfe Started integrating search engine to desktop app 2018-12-10 19:58:49 +01:00
Laurent Cozic
460f826672 Nearly finished search engine backend 2018-12-10 18:54:46 +00:00
Laurent Cozic
cb16a10121 Updated the way item changes are recorded so that info can be used by more services (including search engine) 2018-12-10 01:39:31 +01:00
Laurent Cozic
3b6131f1ca Started support for FTS search 2018-12-09 21:45:50 +01:00
Laurent Cozic
57225a36b9 Updated translations 2018-12-09 01:22:16 +01:00
Laurent Cozic
3e313399c2 Desktop: Search within current note 2018-12-09 01:18:10 +01:00
Laurent Cozic
7947e14792 Merge branch 'master' of github.com:laurent22/joplin 2018-12-08 00:42:54 +01:00
Laurent Cozic
71098102c5 Electron: Fixes #476 (maybe): Trying to fix notification flood. Added more log statements in case something goes wrong. 2018-12-08 00:42:29 +01:00
Laurent Cozic
8e601e80df All: Prevent sync infinite loop under some rare conditions 2018-12-08 00:41:39 +01:00
Caleb John
3b14cfcc54 add separate editor font size option (#1027) 2018-12-07 22:26:03 +01:00
Laurent Cozic
61a0e43092 Mobile: Fixes #999: Associate new note with default notebook when creating it from Welcome screen 2018-12-07 01:23:36 +01:00
Laurent Cozic
d08aaffe41 Mobile: Resolves #1015: (Re-)added support for selecting image from camera roll 2018-12-07 01:07:10 +01:00
Laurent Cozic
7d0def30f0 Revert "ReactNativeClient: A better NAV_BACK logic to change folder or tag. (#984)" (Was opening up side menu on first app startup)
This reverts commit fc8f53fd0e.
2018-12-07 00:45:53 +01:00
Laurent Cozic
bb45d72a56 Clipper: Fixes #1026: Handle adding tag to clipped content after content has been clipped 2018-12-06 23:50:02 +01:00
Laurent Cozic
3943192c5d All: Fixes #808 (maybe): Added fix for Nginx 404 error issue. 2018-12-06 23:09:54 +01:00
Laurent Cozic
18d76807f6 Fixing Norwegian locale 2018-12-06 22:59:08 +01:00
Laurent Cozic
01a30a7ccf Fixed renaming 'no' locale to 'nb_NO' 2018-12-05 23:30:36 +01:00
Mats Estensen
3fb35d043b Revise and complete Norwegian translation (no) and rename to correct locale: nb_NO (#1013)
* update norwegian translation and correct locale name to nb_NO

* set no to nb_NO in documentation

* Add name, email and completion to README

Norwegian translation
2018-12-05 23:21:40 +01:00
Alex Devero
9b51bd484d Fix failing Windows build (#997)
* Upgrade sqlite3 to 4.0.4

* Remove rebuild, add install-app-deps
2018-12-05 23:11:40 +01:00
Laurent Cozic
879b556845 Update website 2018-11-24 12:05:49 +00:00
Laurent Cozic
0df2a501dd Electron release v1.0.117 2018-11-24 11:44:38 +00:00
Laurent Cozic
6f64fdffcc Desktop: Fixes #995: Added flag to disable tag bar for now 2018-11-24 11:42:50 +00:00
Laurent Cozic
19252af345 Desktop: Fixes #996: Allow editing multiple notes in external editor 2018-11-21 19:50:50 +00:00
Laurent Cozic
897f53b13e All: Resolves #846: Set resource path to correct relative path so that for example images show up in Markdown viewers 2018-11-21 00:36:23 +00:00
Laurent Cozic
45cd8b7e3c Merge branch 'master' of github.com:laurent22/joplin 2018-11-20 23:19:07 +00:00
Laurent Cozic
922bbdd1b6 All: Fixes #968: Export resources specified with a title 2018-11-20 23:18:56 +00:00
rhtenhove
c24135577c Useless and error prone VERSION file removed & warn use of root (#989)
* Don't create unused VERSION file

It will throw an error if the script is run from a non-writable directory

* Warn user if running as root

This will write files as root:root

* Clearer root warning
2018-11-20 21:54:58 +00:00
Laurent Cozic
3240ff40bc Restored string to avoid invalidating all the translations. 2018-11-20 21:54:40 +00:00
Ben Fisher
58b68cab0c fix for #906, 1) windows paths like C:\a\b weren't accepted because b… (#935)
* fix for #906, 1) windows paths like C:\a\b weren't accepted because backslashes were treated as escape sequences, 2) common paths like C:\Program Files\Foo\Foo.exe weren't accepted because of the space in the path

* Using anothing approach,
a) backslashes are no longer treated as escape characters,
b) string change to remind people to add spaces

* Removing joplin.pot from the patch, it will be updated later.

* Removing unused code.
2018-11-20 21:46:18 +00:00
Helmut K. C. Tessarek
0a0afd7245 CLI v1.0.118 2018-11-20 15:38:32 -05:00
Laurent Cozic
de01606bff Update website 2018-11-20 19:09:47 +00:00
Laurent Cozic
046474b484 Android release v1.0.176 2018-11-20 00:49:27 +00:00
Laurent Cozic
277b2b9298 Electron release v1.0.116 2018-11-20 00:44:25 +00:00
Laurent Cozic
0b7296ae95 Update translations 2018-11-20 00:43:35 +00:00
Laurent Cozic
ce87dd55f0 Merge branch 'master' of github.com:laurent22/joplin 2018-11-20 00:42:33 +00:00
Laurent Cozic
07b724d65b All: Fixes #992: Allow non-ASCII chars when exporting MD and handle duplicate filenames 2018-11-20 00:42:21 +00:00
Caleb John
bc1984298f Add dark theme to note properties dialog (#991) 2018-11-19 22:48:10 +00:00
Ein Verne
9ed0bdfed2 Add more Chinese translation (#986) 2018-11-19 22:44:20 +00:00
Caleb John
57628e8986 Add missing syntax file for dark theme (#985) 2018-11-19 22:43:56 +00:00
Joybin Chen
fc8f53fd0e ReactNativeClient: A better NAV_BACK logic to change folder or tag. (#984) 2018-11-19 22:43:21 +00:00
Renato Rosa
efd7cc6a0c update-locale-pt_BR (#981)
Update missing strings and fixed flagged ones.
2018-11-19 22:40:21 +00:00
Abijeet Patro
7bfc3e1256 Fixes #979 (#980)
* Adds functionality to display tags under the open note.

Towards #469

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Ensured tags in the dialog box and under the note appear in the same order.

Few formatting tweaks.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Fixes issues raised during code review.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Refactored code to always display tags in ascending order.

This changes the order of the tags in the dialog box and below the tag title.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Added the new tag height and margin bottom to the bottomRowHeight

Fixes #979

Signed-off-by: Abijeet <abijeetpatro@gmail.com>
2018-11-17 11:21:57 +00:00
FleischKarussel
7f6ca1e527 fixed typo in Aktualsierungsdatum to Aktualisierungsdatum (#974) 2018-11-17 11:17:47 +00:00
Laurent Cozic
71d9b1d441 Electron: Fixes #933: Handle internal links from HTML and from MD 2018-11-16 18:39:11 +00:00
Laurent Cozic
a3d64d0a90 Update website 2018-11-16 16:53:37 +00:00
Laurent Cozic
e7ec2ce6cf Electron release v1.0.115 2018-11-13 23:18:08 +00:00
Laurent Cozic
61dbdd5f7c Update translations 2018-11-13 23:17:56 +00:00
Laurent Cozic
e6888c451d Fixing Katex version number 2018-11-13 22:42:06 +00:00
Laurent Cozic
899219abd2 Merge branch 'master' of github.com:laurent22/joplin 2018-11-13 22:38:32 +00:00
Joybin Chen
7a4c7a13eb Fix image fetching error. For url like http://example.com/favicon.ico?ver=1.0 will be changed to http://example.com/favicon.ico?ver=1.0?ver=1.0 (#970) 2018-11-13 22:37:39 +00:00
Laurent Cozic
e8797f49b9 Mobile: Display number of resources being fetched in side bar 2018-11-13 22:27:58 +00:00
Laurent Cozic
e17f3051f0 Display number of resources being fetched in side bar 2018-11-13 22:25:23 +00:00
Laurent Cozic
06091933e1 All: Moved resource app-specific state to different table 2018-11-13 00:45:08 +00:00
Laurent Cozic
b30c65dd89 Update CONTRIBUTING.md 2018-11-11 20:23:55 +00:00
Ben Fisher
0eb18d206d Patch to implement feature, exporting notes to JSON (#912, issues/912). (#927)
* Patch to implement feature, exporting notes to JSON (#912, issues/912).

* Revising based on feedback

* Directly calling JSON.stringify on the item
2018-11-11 20:17:43 +00:00
Laurent Cozic
3a9948e528 Build doc 2018-11-08 01:21:18 +00:00
Laurent Cozic
2bcddd38b2 Update API doc 2018-11-08 01:17:46 +00:00
Laurent Cozic
5ff8808f69 API: Allow setting the ID of newly created notes. 2018-11-08 01:14:13 +00:00
Laurent Cozic
28b1d8a324 Desktop: Fixes #953 (maybe): Improved the way internal links to notes are loaded to make it more reliable 2018-11-08 00:58:06 +00:00
Laurent Cozic
5c1dd79435 All: Fixes #952: Upgraded Katex lib to fix bug 2018-11-07 23:44:59 +00:00
Laurent Cozic
706d59a6cc Doc 2018-11-07 23:43:48 +00:00
Ben Fisher
251f1bba55 Show note title in pdf export (#890) (#937)
* Show note title in pdf export (#890)

An example of a possible approach, to temporarily change the html in the webview to show the note title. Works, but there may be a more elegant fix.

* Show title in pdf export

Revising based on feedback
Also, a couple changes to tests so that they pass in Windows.
2018-11-07 23:35:14 +00:00
Caleb John
cb1fd85ca4 Add support for custom css across all notes (#925) 2018-11-07 22:52:31 +00:00
Laurent Cozic
11ddc55911 Fixed theme handling for new tag feature 2018-11-07 22:47:34 +00:00
Caleb John
ee106105d8 Joplin desktop Dark Mode (#921)
* Added support for the dark mode on desktop

* Add dark highlighting to the code tags

* Update app/theme.js to be more clear and more easily support additional themes
Update more files to conform to theming
2018-11-07 22:37:13 +00:00
Laurent Cozic
19f5a144e5 Added comment 2018-11-07 22:22:26 +00:00
Abijeet Patro
18717bac79 Adds functionality to display tags under the open note. (#893)
* Adds functionality to display tags under the open note.

Towards #469

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Ensured tags in the dialog box and under the note appear in the same order.

Few formatting tweaks.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Fixes issues raised during code review.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>

* Refactored code to always display tags in ascending order.

This changes the order of the tags in the dialog box and below the tag title.

Signed-off-by: Abijeet <abijeetpatro@gmail.com>
2018-11-07 22:16:05 +00:00
Laurent Cozic
28fa83c406 Merge branch 'master' of github.com:laurent22/joplin 2018-11-02 19:56:18 +00:00
Laurent Cozic
258e514a91 Marked password cache as secure, and only display stars if the value is non-empty 2018-11-02 19:22:49 +00:00
Ben Fisher
f92546d6eb Adding some tips for building and debugging Joplin on Windows (#938) 2018-11-02 01:06:48 +00:00
sensor-freak
693456164b Minor fix for translation of 'Location' (#936) 2018-11-02 00:53:05 +00:00
Helmut K. C. Tessarek
7cd3e6b1f7 mobile: add version info (#930) 2018-11-02 00:43:42 +00:00
FoxMaSk
764e63d869 new French Translations (#923) 2018-11-02 00:24:28 +00:00
Laurent Cozic
2c6f47f277 Update README.md
Removed Hacktoberfest news
2018-11-01 17:45:05 +00:00
Laurent Cozic
e41896d6f3 All: Resolves #918: Skip properties that are on sync target but not handled by local client 2018-10-31 00:35:57 +00:00
Laurent Cozic
990591cc80 Minor improvments 2018-10-30 00:17:50 +00:00
Laurent Cozic
7b85c33213 CLI v1.0.117 2018-10-29 23:24:19 +00:00
Laurent Cozic
4b4d0e8b25 Update website 2018-10-24 21:14:38 +01:00
Laurent Cozic
4fb6af3c62 Android release v1.0.175 2018-10-24 19:59:37 +01:00
Laurent Cozic
d7ffe7e294 Electron release v1.0.114 2018-10-24 19:52:07 +01:00
Laurent Cozic
3ff139d445 Merge branch 'master' of github.com:laurent22/joplin 2018-10-24 19:51:16 +01:00
Laurent Cozic
40443e0134 Android v153 2018-10-24 19:50:26 +01:00
Laurent Cozic
1f927c1285 iOS v26 2018-10-24 19:48:09 +01:00
Andros Fenollosa
5e82e62335 Linux script install: implement previous updates (#905)
Avoid an erroneous update and prevent installation icon only on gnome.
2018-10-24 19:17:18 +01:00
Yannis Mitsos
de954827df Support FreeBSD in terminal (#896) 2018-10-24 19:16:15 +01:00
Laurent Cozic
2cb24bf198 Mobile: Fixes #902: Don't change existing note when sharing with mobile app 2018-10-24 19:10:05 +01:00
Laurent Cozic
739a6a4a9c Documentation 2018-10-24 18:47:04 +01:00
Laurent Cozic
dfcf1193dc Electron: Handle internal anchors 2018-10-17 08:01:18 +01:00
Laurent Cozic
c72f92e22f Additional info 2018-10-15 18:40:11 +01:00
Laurent Cozic
f6d01ce7e1 Android release v1.0.174 2018-10-15 00:01:36 +01:00
Laurent Cozic
fed9700587 Merge branch 'master' of github.com:laurent22/joplin 2018-10-15 00:00:13 +01:00
Laurent Cozic
12a3a9a89e android release 2018-10-14 23:59:42 +01:00
Laurent Cozic
590c62c371 Merge branch 'fixing_android_build' 2018-10-14 23:56:42 +01:00
Laurent Cozic
df41f64b3c Revert "trying to fix android build"
This reverts commit 621d0260f4.
2018-10-14 21:47:12 +01:00
Laurent Cozic
1849355245 Android: Tryinc to fix release builkd 2018-10-14 21:42:34 +01:00
Laurent Cozic
fa1b471ea4 Android: Tryinc to fix release builkd 2018-10-14 21:41:29 +01:00
Laurent Cozic
0a67f8c947 Revert "Android: Updated project to build on macOS"
This reverts commit b547f9aa13.
2018-10-14 20:44:05 +01:00
Laurent Cozic
621d0260f4 trying to fix android build 2018-10-14 19:57:30 +01:00
Laurent Cozic
f93fca7c5b Revert "Android: Updated project to build on macOS"
This reverts commit b547f9aa13.
2018-10-13 11:35:21 +01:00
Laurent Cozic
f4d830c2ef Android release v1.0.151 2018-10-13 11:09:03 +01:00
Laurent Cozic
1aa2844efa Android release v1.0.148 2018-10-13 10:39:55 +01:00
Laurent Cozic
f22b2adaad Mobile: Improved camera attachment 2018-10-13 10:32:44 +01:00
Laurent Cozic
b547f9aa13 Android: Updated project to build on macOS 2018-10-13 00:30:41 +01:00
Laurent Cozic
e4166e9da7 Electron: Fixes #312 (maybe): Removed power saving feature, which wasn\'t doing anything and added a possible fix to the UI freezing issue on Linux 2018-10-12 23:44:00 +01:00
Laurent Cozic
1634fdb421 Merge branch 'master' of github.com:laurent22/joplin 2018-10-12 23:26:11 +01:00
Laurent Cozic
7f51035f91 Mobile: Reload note when resource got downloaded. Also fixed Android build script to make it work in macOS. 2018-10-12 23:25:11 +01:00
ebayer
70e71cbc2a Mobile: Fixes #856: Add option to open source url (#872)
* Mobile: Fixes #856: Add option to open source url

* Mobile: Fixes #856: Change menu wording for opening source url
2018-10-12 19:30:00 +01:00
Laurent Cozic
ffd03bf34c Merge branch 'master' of github.com:laurent22/joplin 2018-10-11 17:53:40 +01:00
Christian Baer
f59a3dee78 Fixed some more inconsistencies in german language file. (#855)
* Fixed some typos and inconsistencies in the german language file and added missing translations.

* Fixed some more inconsistencies in german language file.
2018-10-11 17:21:12 +01:00
Timothy Cyrus
3ba3037242 Update README.md (#874) 2018-10-11 17:20:42 +01:00
Helmut K. C. Tessarek
dbb269fef6 add support for webp images (#858)
fixes #848
2018-10-11 17:18:33 +01:00
Laurent Cozic
e209189faa All: Added resource test units 2018-10-11 17:18:24 +01:00
Laurent Cozic
2d7065cde2 Android release v1.0.143 2018-10-10 20:36:42 +01:00
Laurent Cozic
59f5972c93 Electron release v1.0.113 2018-10-10 20:32:45 +01:00
Laurent Cozic
8bac5275c3 All: Fixed fetch logic - mark resource as fetched by default, unless it comes from sync 2018-10-10 18:53:09 +01:00
Helmut K. C. Tessarek
58d748e235 fix permissions for shell scripts (add executable flag) (#866) 2018-10-09 22:58:18 +01:00
Laurent Cozic
e69ac3e62a Android release v1.0.142 2018-10-09 22:05:29 +01:00
Laurent Cozic
7fc8ac4c0f Electron release v1.0.112 2018-10-09 22:02:47 +01:00
Laurent Cozic
069dce69cd Mobile: Added support for ResourceFetcher service 2018-10-09 22:01:50 +01:00
Laurent Cozic
3bdf621026 Api: Document tags parameter 2018-10-08 19:38:27 +01:00
Laurent Cozic
2f62897fb6 All: Improved resource side loading 2018-10-08 19:11:53 +01:00
Laurent Cozic
dbdd602f50 All: Created ResourceFetcher class to handle resource downloads 2018-10-08 07:36:45 +01:00
Laurent Cozic
d66fa87b2b All: Allow excluding certain keys during sync 2018-10-07 20:18:43 +01:00
Laurent Cozic
124a959c8d All: Simplifying serialisation of base items 2018-10-07 20:11:33 +01:00
Laurent Cozic
127dce1cd6 Fixed typo 2018-10-07 19:28:19 +01:00
Laurent Cozic
44986a35a4 Android: Fix crash when attaching certain files 2018-10-07 18:55:49 +01:00
Laurent Cozic
ea516301fd Udpated German translation 2018-10-05 19:53:54 +01:00
Christian Baer
90b684457a Fixed some typos and inconsistencies in the german language file and added missing translations. (#854) 2018-10-05 19:53:13 +01:00
Laurent Cozic
8517e2aa42 Mobile: Fixes #840: Images were not being displayed right after being attached in view mode 2018-10-05 19:49:36 +01:00
Laurent Cozic
b880be8b7c All: Fixes #853: Replace characters to equivalent US-ASCII ones when exporting files 2018-10-05 17:53:55 +01:00
Laurent Cozic
57fd1a7588 Electron: Prevent URLs added via A tag from being opened inside app 2018-10-05 18:21:23 +00:00
Laurent Cozic
5ed458f634 Electron: Fixed potential crash that can happen if editor is not ready 2018-10-05 18:19:47 +00:00
Laurent Cozic
ac12143d00 All: Fixes #671: Make string translatable 2018-10-05 18:17:49 +00:00
Helmut K. C. Tessarek
b6c36d1961 fix file permissions (#851) 2018-10-04 22:32:19 +01:00
FoxMaSk
3c2de70baa add shared folder (#850)
shared 📁 is needed, so the encryption menu will be translated
2018-10-04 22:30:48 +01:00
Laurent Cozic
f6c5620682 Electron: Resolves #751: Allow switching between todo and note when multiple notes are selected 2018-10-04 18:34:30 +01:00
Laurent Cozic
79b6f64bd0 Merge branch 'master' of github.com:laurent22/joplin 2018-10-04 18:01:23 +01:00
Laurent Cozic
ed89f55bff Electron: Fixes #847: Prevent view from scrolling to top when clicking checkbox and editor not visible 2018-10-04 17:56:39 +01:00
Laurent Cozic
8841a92142 Update README.md 2018-10-04 09:10:46 +01:00
Laurent Cozic
0bd19c97eb Merge branch 'master' of github.com:laurent22/joplin 2018-10-04 08:53:11 +01:00
Laurent Cozic
2fd026d107 Mentioned Hacktoberfest 🎃 in Readme 2018-10-04 08:51:48 +01:00
Laurent Cozic
5e7eb37ca7 Merge branch 'master' of github.com:laurent22/joplin 2018-10-04 08:18:19 +01:00
Laurent Cozic
6b10d5d821 Api: Fixes #843: Fixed regression that was preventing resource metadata from being downloaded 2018-10-04 08:17:53 +01:00
Laurent Cozic
0f4dbfbcbf Merge pull request #841 from shorty2380/patch-1
Joplin_install_and_update.sh
2018-10-04 08:10:51 +01:00
Laurent Cozic
99493174ec API: Fixed handling of PUT method and log errors to file 2018-10-04 08:05:22 +01:00
Patrick Petermann
333253fd4f Joplin_install_and_update.sh
The script was original written for “Ubuntu – Gnome” only. I change it a little bit to support more distributions and desktop enviroments.

This script could be used to install and update Joplin at several Linux distributions. I could test this script with “Fedora 28 – Cinnamon” and “Mint LMDE 3”.   There are a lot of requests how to install / start Joplin at Linux in the FAQ’s. Hopefully this could help the people
2018-10-03 20:48:14 +02:00
Laurent Cozic
01470e8d3b Android release v1.0.141 2018-10-03 08:30:19 +01:00
Laurent Cozic
bda2fe6717 Merge branch 'master' of github.com:laurent22/joplin 2018-10-03 08:19:15 +01:00
Laurent Cozic
d1f4c5be18 Disable non-working ShareExtension on iOS 2018-10-03 08:17:37 +01:00
Laurent Cozic
377adea51d Android release v1.0.140 2018-10-02 18:19:27 +01:00
Laurent Cozic
cda3d20834 Android release v1.0.138 2018-10-02 18:10:37 +01:00
Laurent Cozic
d11870b1eb Trying to get RN 0.57.1 to work 2018-10-02 19:02:38 +00:00
Laurent Cozic
53bda3eea7 Trying RN 0.57.1 upgrade 2018-10-02 18:57:31 +00:00
Laurent Cozic
30165e8d6a Electron: Fixes #798: Enable Select All shortcut in macOS 2018-10-02 17:45:39 +01:00
Laurent Cozic
2202eb6570 Merge branch 'master' of github.com:laurent22/joplin 2018-10-01 20:55:52 +01:00
Laurent Cozic
720927f488 All: Fixes #832: Enex import: Don't add extra line breaks at the beginning of list item when it contains a block element 2018-10-01 20:55:24 +01:00
Helmut K. C. Tessarek
2858c0fce0 CLI v1.0.116 2018-09-30 18:28:54 -04:00
Laurent Cozic
36c3521f40 Update website 2018-09-30 21:15:21 +01:00
Laurent Cozic
98a3b99d17 Electron release v1.0.111 2018-09-30 20:45:03 +01:00
Laurent Cozic
95a06c4531 All: Fixes #818: Use sort options when displayed tagged notes 2018-09-30 20:43:46 +01:00
Laurent Cozic
6ea77b36ce Electron: Resolves #820: Allow dragging and dropping a note in another note to create a link 2018-09-30 20:15:30 +01:00
Laurent Cozic
0cd7ebf9d3 Electron: Fixes resources being incorrectly auto-deleted when inside an IMG tag 2018-09-30 19:24:02 +01:00
Laurent Cozic
a816498fc6 Android release v1.0.135 2018-09-30 10:52:30 +01:00
Laurent Cozic
549c1a6767 Android: Make camera features optional to, maybe, enable Chromebooks 2018-09-30 10:48:10 +01:00
Laurent Cozic
f87d1f11b0 API: Allow downloading a resource data 2018-09-30 10:15:46 +01:00
Laurent Cozic
fb913bc33c Mobile: Fixes #654: Fixed auto-title logic so that set title doesn't get overwritten in some conditions for new notes 2018-09-29 15:57:18 +01:00
Laurent Cozic
53d7a51cb0 Removed API doc from translations and updated FR translation 2018-09-29 13:29:07 +01:00
Laurent Cozic
12da48c756 Electron release v1.0.110 2018-09-29 13:17:48 +01:00
Laurent Cozic
a0a6bdb684 Update website 2018-09-29 13:15:36 +01:00
Laurent Cozic
eb4aa2c026 API: Added more calls 2018-09-29 12:54:44 +01:00
Laurent Cozic
a9e789f845 Clipper: Fixed screenshot text box label colour 2018-09-29 12:53:16 +01:00
Laurent Cozic
89b76918bd Merge branch 'master' of github.com:laurent22/joplin 2018-09-28 21:04:23 +01:00
Laurent Cozic
e98575643c API: Added documentation generator and built documentation 2018-09-28 21:03:28 +01:00
Laurent Cozic
7c9e7743f1 Merge pull request #825 from sensor-freak/patch-2
Fixed some german translations
2018-09-28 20:58:32 +01:00
sensor-freak
435aa4845b Fixed some german translations 2018-09-28 21:43:17 +02:00
Laurent Cozic
9841488ce4 Updated translations 2018-09-28 19:25:56 +01:00
Laurent Cozic
9c907989a5 Merge branch 'master' of github.com:laurent22/joplin 2018-09-28 19:25:18 +01:00
Laurent Cozic
f684d8e59a Merge pull request #824 from sensor-freak/patch-1
Update de_DE.json
2018-09-28 19:25:05 +01:00
Laurent Cozic
a1ad6c9712 API: Added more API calls 2018-09-28 19:24:57 +01:00
Laurent Cozic
b6ca3090df Merge pull request #822 from foxmask/master
Forbidden is 403 - typo :)
2018-09-28 19:23:48 +01:00
Helmut K. C. Tessarek
ff2d793fbb CLI v1.0.115 2018-09-28 14:08:21 -04:00
sensor-freak
fcfb7f1111 Update de_DE.json
Fix and add some german translations
2018-09-28 07:39:13 +02:00
FoxMaSk
6125cde223 Forbidden is 403 - typo :) 2018-09-27 21:38:16 +02:00
Laurent Cozic
c83391e624 Update website 2018-09-27 19:02:01 +01:00
Laurent Cozic
a3a818ea74 Clipper release v1.0.7 2018-09-27 19:00:04 +01:00
Laurent Cozic
54a4965503 Android release v1.0.133 2018-09-27 18:54:14 +01:00
Laurent Cozic
2233d88c01 Electron release v1.0.109 2018-09-27 18:50:38 +01:00
Laurent Cozic
9680ab74a3 All: Allow loading image resources in IMG html tags 2018-09-27 18:42:34 +01:00
Laurent Cozic
ef711af5b5 Api: Added method to get notes 2018-09-27 18:35:10 +00:00
Laurent Cozic
8a619e4b8b All: Refactored REST API to make it testable and to allow further extension 2018-09-27 09:14:05 +01:00
Laurent Cozic
bc09d2c640 Clipper: Fixes #817: Added support for PICTURE tags, which will fix issues with certain pages from which images were not being imported 2018-09-25 21:19:54 +01:00
Laurent Cozic
f82dfde6f4 Clipper: Fixed importing certain images with sources that contain brackets 2018-09-24 20:15:23 +01:00
Laurent Cozic
312c7f2d27 Electron: Fixed regression following security fix - links were being opened inside Joplin instead of in external browser 2018-09-24 20:14:21 +01:00
Laurent Cozic
953cc327c6 Electron: Fixes #805: Fixed app freezing when opening note in external editor and then creating new note 2018-09-24 07:10:00 +01:00
Laurent Cozic
14cff96713 Mobile: Fix potential crash when going back to OneDrive login screen 2018-09-23 20:45:34 +01:00
Laurent Cozic
34b9af2ce0 Electron: Fixes #802: Scale note text correctly when using zoom 2018-09-23 19:48:50 +01:00
Laurent Cozic
6a6ee280c3 All: Fixes #801: Replaced freegeoip which is no longer free with ip-api 2018-09-23 19:45:13 +01:00
Laurent Cozic
861387707a CLI: Fixes #795: Display tree of notebooks correctly 2018-09-23 19:33:44 +01:00
Laurent Cozic
830e665366 Updated translation 2018-09-23 19:15:49 +01:00
Laurent Cozic
f14ae68ea0 Merge pull request #812 from ikunya/update-japo
Update Japanese Translations.
2018-09-23 19:15:16 +01:00
Laurent Cozic
c7084bf27e Updated French translation 2018-09-23 19:15:04 +01:00
Laurent Cozic
fc8ffcbe46 Clipper: Fixes #672: Make sure selected notebook is saved and restored correctly 2018-09-23 18:44:39 +01:00
Laurent Cozic
77f089654e Clipper: Resolves #681: Allow adding tags from Web Clipper 2018-09-23 18:03:11 +01:00
Laurent Cozic
e7a12bb0dd Clipper: Fixes #809: Saves full URL with note, including query parameters 2018-09-22 17:41:09 +01:00
AWASHIRO Ikuya
22fe3a4e44 Update Japanese Translations. 2018-09-22 23:34:07 +09:00
Laurent Cozic
afb8b92528 Clipper: Fixed init sequence 2018-09-22 11:21:39 +01:00
Laurent Cozic
5178f99100 Electron release v1.0.108 2018-09-21 18:20:34 +01:00
Laurent Cozic
72af564382 Electron: Fixed security issue by enabling contextIsolation and proxying IPC messages via preload script 2018-09-21 18:20:06 +01:00
Laurent Cozic
0a2b83998c Merge pull request #811 from mvonmaltitz/master
Fix ubuntu install script
2018-09-21 12:00:54 +01:00
Marcel von Maltitz
73e79213dc Fix ubuntu install script
If no former version is present, the script fails since the rm commands do not succeed.
Added -f to rm in order to ignore non-existent directories to be deleted.
2018-09-21 12:55:01 +02:00
Laurent Cozic
e31ffc9474 Update website 2018-09-16 20:51:28 +01:00
Laurent Cozic
fdb8706a5f Android release v1.0.132 2018-09-16 20:12:56 +01:00
Laurent Cozic
4c0262bd82 Electron release v1.0.107 2018-09-16 20:09:07 +01:00
Laurent Cozic
3b2dcb37a6 CLI: Updated Readme 2018-09-16 20:03:29 +01:00
Laurent Cozic
46a3b020a6 Merge pull request #784 from Kriechi/cli-decrypt
CLI: improve e2ee decrypt command
2018-09-16 20:01:09 +01:00
Laurent Cozic
8373392e99 Merge pull request #793 from tanrax/patch-4
Added comments and information texts
2018-09-16 19:53:33 +01:00
Laurent Cozic
695c2623c2 Added Romanian translation 2018-09-16 19:53:06 +01:00
Laurent Cozic
979e7f2486 Merge pull request #796 from cdorin93/ro-translation-added
Romanian translation added
2018-09-16 19:50:03 +01:00
Laurent Cozic
e7a9f630ec All: Fixes #799: Handle restricted_content error for Dropbox 2018-09-16 19:49:07 +01:00
Laurent Cozic
4e8372174b Electron: Resolves #755: Added note properties dialog box to view and edit created time, updated time, source URL and geolocation 2018-09-16 19:37:31 +01:00
cdorin93
1b8912d7e9 Romanian translation added 2018-09-15 22:49:40 +02:00
Andros Fenollosa
8c3669588b Added comments and information texts
Comments, presentation title, final informative text have been added and temporary variable is deleted.
2018-09-14 19:03:09 +02:00
Laurent Cozic
1b784fe3b0 Merge branch 'master' of github.com:laurent22/joplin 2018-09-13 20:53:39 +01:00
Laurent Cozic
5ab1d8dfd6 All: Resolves #781: Allow creating notebooks with duplicate titles to allow two notebooks with same name to exist under different parents 2018-09-13 20:53:31 +01:00
Laurent Cozic
cda8b95bfa Merge pull request #768 from sebastienjust/master
Notebooks list is sorted alphabetically as default
2018-09-13 19:56:57 +01:00
Laurent Cozic
9664842b1a Update Chinese translation 2018-09-13 19:48:00 +01:00
Laurent Cozic
09836e1d34 Merge branch 'master' of github.com:laurent22/joplin 2018-09-13 19:46:12 +01:00
Laurent Cozic
8974e20c7f Update readme 2018-09-13 19:46:06 +01:00
Laurent Cozic
761a49803e Merge pull request #775 from tanrax/patch-1
Script to install on Ubuntu with Gnome Shell
2018-09-13 19:45:24 +01:00
Laurent Cozic
a40028f0c0 Merge pull request #776 from tanrax/patch-2
Create install_ubuntu.sh
2018-09-13 19:45:14 +01:00
Laurent Cozic
d4fca7e313 Merge pull request #787 from tessus/external-storage
allow the app to be installed on external storage (SD card)
2018-09-13 19:42:34 +01:00
Laurent Cozic
6748d4d825 Merge branch 'master' of github.com:laurent22/joplin 2018-09-13 19:31:18 +01:00
Laurent Cozic
0a5ad1d628 Electron: Fixes #710: Don't unwatch file when it is temporarily deleted 2018-09-13 19:29:48 +01:00
Laurent Cozic
4080958e10 Merge pull request #790 from chaifeng/zh_CN
Update zh_CN.po
2018-09-12 23:15:32 +01:00
Chai Feng
95c4a717e3 Update zh_CN.po 2018-09-12 09:13:10 +08:00
Helmut K. C. Tessarek
c5b9353105 fix whitespace errors (spaces to tabs) 2018-09-10 20:06:38 -04:00
Helmut K. C. Tessarek
17595f7ceb allow the app to be installed on external storage (SD card) 2018-09-10 20:04:54 -04:00
Andros Fenollosa
dcf78e8a06 Prevent the folder from being deleted 2018-09-10 22:57:50 +02:00
Andros Fenollosa
de0c54c3c3 Add set -e 2018-09-10 22:54:01 +02:00
Laurent Cozic
38970e9a52 Merge branch 'master' of github.com:laurent22/joplin 2018-09-10 19:19:42 +01:00
Laurent Cozic
563f43168b All: Fix #764: Fix equation tag positioning 2018-09-10 19:19:33 +01:00
Thomas Kriechbaumer
6e235605ed CLI: improve e2ee decrypt command 2018-09-10 18:39:19 +02:00
Laurent Cozic
0749e0b675 Merge pull request #777 from tanrax/patch-3
Add fastmail WebDAV synchronisation list
2018-09-09 20:54:30 +01:00
Laurent Cozic
756f3e627c All: Fixes #718: Allow recursively importing Markdown folder 2018-09-09 20:32:23 +01:00
Andros Fenollosa
4b39ed42b1 Add fastmail WebDAV synchronisation list 2018-09-09 21:16:42 +02:00
Andros Fenollosa
abe85ca4bd Update README.md 2018-09-09 21:11:42 +02:00
Andros Fenollosa
a559565ace Create install_ubuntu.sh 2018-09-09 21:08:23 +02:00
Laurent Cozic
d35e3163ca Update translations 2018-09-09 20:05:36 +01:00
Laurent Cozic
f22ad85681 Removed incorrectly duplicated translation 2018-09-09 20:02:08 +01:00
Andros Fenollosa
727bdaeea4 Update README.md 2018-09-09 20:58:30 +02:00
Laurent Cozic
42f7764eed Merge pull request #773 from Vistaus/master
Added Dutch (Netherlands) translation
2018-09-09 19:54:20 +01:00
Andros Fenollosa
1fbc1073ca Script to install on Ubuntu with Gnome Shell
Add script to install on Ubuntu or Debian with Gnome Shell Icon
2018-09-09 20:47:57 +02:00
Heimen Stoffels
66b683e5e7 Added Dutch (Netherlands) translation 2018-09-09 18:26:58 +02:00
Laurent Cozic
7d1f61e47b Electron release v1.0.106 2018-09-08 15:47:15 +01:00
Laurent Cozic
643e5a6a2a Electron: Resolves #714: Allow starting application minimised in the tray icon 2018-09-06 18:56:23 +01:00
Laurent Cozic
a1e7e29279 All: Fixes #709: Now that HTML is supported in notes, remove BR tag replacement hack. 2018-09-06 18:40:05 +01:00
Laurent Cozic
abf6c3f3f1 Electron: Fixes #697: Focus search text input after clearing search 2018-09-06 18:37:39 +01:00
Laurent Cozic
32c81ad8c2 All: Fixes #657: Disallow giving name of existing tag to another tag 2018-09-06 18:33:21 +01:00
Sebastien Just
0f461c4caa #206 Notebooks list defaults to alphabetical order 2018-09-06 12:26:35 +02:00
Sebastien Just
57ed718993 #206 Notebooks list defaults to alphabetical order 2018-09-06 12:22:09 +02:00
Laurent Cozic
ef1ae63233 Electron: Fix #759: Add border around code block when exporting to PDF 2018-09-05 14:59:33 +01:00
Laurent Cozic
81ac200cc0 All: Resolves #761: Highlight single tick code segments 2018-09-05 14:51:50 +01:00
Laurent Cozic
3a2d62f6c7 Update website 2018-09-05 12:30:37 +01:00
Laurent Cozic
7f80f67fd6 CLI v1.0.114 2018-09-05 12:30:09 +01:00
Laurent Cozic
cebd8de77a Android release v1.0.131 2018-09-05 12:19:53 +01:00
Laurent Cozic
417218fc34 Electron release v1.0.105 2018-09-05 12:11:56 +01:00
Laurent Cozic
29586437c2 Merge pull request #719 from gufertum/tag-list-long-op
added support for 'tag list -l [tag]' to show long format as for 'not…
2018-09-05 12:11:03 +01:00
Thomas Schädler
f51d0ad914 fixed indention (again, this time for real) 2018-09-05 12:46:49 +02:00
Laurent Cozic
35294b5f97 Electron: Resolves #679: Drag a note on a tag to associate the tag. 2018-09-05 11:43:03 +01:00
Laurent Cozic
758562cff9 Electron: Fixes #113: Upgraded Ace Editor to try to fix Korean input issue (to be confirmed). 2018-09-05 11:35:40 +01:00
Laurent Cozic
da0678c6fe Merge pull request #726 from tfinnberg/enable_file-urls_in_notes_html_view
enable file-URLs in note html view
2018-09-05 11:23:12 +01:00
Laurent Cozic
afe4fd70cc Update FAQ 2018-09-05 11:22:04 +01:00
Laurent Cozic
4cef383fe7 Added warning when changing WebDAV URL 2018-09-05 11:20:26 +01:00
Laurent Cozic
b58c30889e Updated FAQ and contribution guide 2018-09-05 11:17:47 +01:00
Laurent Cozic
1561c0e4d7 Merge pull request #756 from tessus/cli-correct-date-time-ls
show correct date/time for cli command `ls`
2018-09-05 10:56:44 +01:00
Thomas Schädler
32b11c15a4 fixed indention 2018-09-05 08:45:18 +02:00
Helmut K. C. Tessarek
5e06efc1b9 show correct date/time for cli command ls
closes #729
2018-09-04 18:03:21 -04:00
Helmut K. C. Tessarek
43bd88703c fix 'No newline at end of file' and whitespace errors 2018-09-04 18:00:12 -04:00
Laurent Cozic
cdd70230af Electron: Fixes #663: Fixed copy, cut and paste context menu on text editor 2018-09-04 18:20:41 +01:00
Laurent Cozic
eaf3eef2d3 All: Resolves #734: Allow exporting to a hierarchy of Markdown files, and fixed a few issues related to exporting notebooks 2018-09-04 11:59:09 +01:00
Laurent Cozic
81ec8eaf83 Merge pull request #757 from pensierocrea/patch-1
Update it_IT.po
2018-09-04 11:10:17 +01:00
Laurent Cozic
23f7e350c6 Redirect to app logger 2018-09-04 11:08:55 +01:00
Laurent Cozic
cea368cd3f Fix sharing text when no folder exists 2018-09-04 11:08:08 +01:00
Laurent Cozic
50c8f2ae61 Merge pull request #689 from CalebJohn/android-sharing
Add text sharing on android
2018-09-04 11:06:08 +01:00
pensierocrea
ed0ecababb Update it_IT.po
Hi,
i'm new to github... i hope this help and i've not done some mistake
i think that:
"notebook" should be named "taccuini" in italian like evenote does 
"to-do" can be translated in "Cose-da-fare" not in "attività" that means "activity/activities"

now... i've also a feature request to improve the user interaction with the sidebar and to focus more on the "to-do" stuff
where i can send/post my little suggestion?

thank you
2018-09-04 11:12:19 +02:00
Thomas Schädler
72aa4c40a5 added correct time format method (using user properties)
cleanup (spaces -> tabs, consistent line endings)
2018-09-03 22:18:15 +02:00
Laurent Cozic
4f6784e2e5 Upgraded Katex to support tag 2018-09-03 16:08:56 +01:00
Laurent Cozic
01f015a54f Update translations 2018-09-03 15:11:12 +01:00
Laurent Cozic
806acad22a Fix Sweden flag 2018-09-03 12:16:35 +01:00
Laurent Cozic
1d322d8a39 Fix Korean flag 2018-09-03 12:13:59 +01:00
Laurent Cozic
aef94e6950 Updated translations 2018-09-03 12:08:50 +01:00
Laurent Cozic
456fcec334 Merge branch 'master' of github.com:laurent22/joplin 2018-09-03 12:08:02 +01:00
Laurent Cozic
3b6937c2f0 Merge pull request #746 from jony0008/master
Add Swedish translation
2018-09-03 12:01:46 +01:00
Laurent Cozic
7cdd1d41c1 Merge pull request #728 from fmrtn/master
Spanish translation updated
2018-09-03 12:00:33 +01:00
Laurent Cozic
1fc535a740 Merge pull request #706 from tessus/fix-421
use correct date/time format for sync time - fix for #421
2018-09-03 11:56:04 +01:00
Laurent Cozic
033b37077a Merge pull request #705 from tessus/res-icon-j
use the Joplin icon for internal links
2018-09-03 11:55:25 +01:00
Laurent Cozic
07f6a4a08b Merge pull request #676 from RaphaelKimmig/electron_focus_new_notes_only
focus NoteText only when creating new notes
2018-09-03 11:53:03 +01:00
Laurent Cozic
8c1b592a51 Updated translations 2018-09-03 11:49:41 +01:00
Jony
9460f7a17a Add Swedish translation 2018-08-30 19:48:41 +02:00
Fernando
106260ed69 Spanish translation updated 2018-08-20 02:43:18 +02:00
tfinnberg
123162e946 enable file-URLs in note html view 2018-08-18 11:14:34 +02:00
Thomas Schädler
54e81966e5 added support for 'tag list -l [tag]' to show long format as for 'notebook' lists using 'ls -l' 2018-08-13 23:28:19 +02:00
Helmut K. C. Tessarek
9bf6ab60bb use correct date/time format for sync time
fixes #421
2018-08-01 17:22:24 -04:00
Helmut K. C. Tessarek
4f0ff3cdfc fix whitespace errors 2018-08-01 17:05:09 -04:00
Helmut K. C. Tessarek
47cfaaa5ab replace the resource icon (for internal links) with the Joplin icon (from ForkAwesome) 2018-07-31 23:04:33 -04:00
Helmut K. C. Tessarek
1f49788f21 fix 'No newline at end of file' 2018-07-31 23:00:28 -04:00
Laurent Cozic
7e4cf9aeda All: Resolves #678: Added Korean translation 2018-07-25 18:01:56 +02:00
Laurent Cozic
4b6964b683 CLI v1.0.113 2018-07-25 17:59:00 +02:00
Caleb John
3caf398021 refresh notes list on AppState Changes
- remove mistaken console.log calls in root.js
2018-07-20 15:59:55 +02:00
Caleb John
8840631266 Add simple sharing facilities for Android
- react code should be cross platform but support needs to be added
    for ios
  - only shares plain text notes for now
2018-07-20 11:04:25 +02:00
Raphael Kimmig
c4411bb895 focus NoteText only when creating new notes
This changes the behaviour so that loading a note does automatically
focus the note text/title only when a new note is being created.

This reduces accidental edits and is in line with other note taking
applications such as Simplenote, Evernote and Apple Notes.
2018-07-10 08:35:21 +02:00
Laurent Cozic
f63668350b CLI v1.0.110 2018-06-30 19:58:36 +01:00
Laurent Cozic
3fc54d7ffd CLI: Updating SQLite to support Node 10 2018-06-30 19:57:49 +01:00
Laurent Cozic
2c6c20f44f Mobile: Resolves #350: Open non-image resources in external application 2018-06-30 19:45:21 +01:00
Laurent Cozic
08ee939951 Electron: Resolves #594: Enable support for SVG graphics 2018-06-30 19:05:45 +01:00
Laurent Cozic
463b1441d3 Updated DE translation 2018-06-30 16:20:22 +01:00
Laurent Cozic
6754d4ee89 Electron: Fixes #653: Don't detect horizontal rule as bullet list item 2018-06-30 16:15:44 +01:00
Laurent Cozic
d5d0732bf3 Clipper: Upgrade joplin-turndonw to fix import of literal HTML code 2018-06-30 16:12:01 +01:00
Laurent Cozic
d27cbaa663 Electron: Improve speed of loading notes that include many resources, and prevent UI from freezing 2018-06-29 18:51:50 +00:00
Laurent Cozic
70adf10f2e Clipper: Skip noscript elements 2018-06-29 18:45:33 +00:00
Laurent Cozic
e75417d26e Tools: Automate updating Git repo when creating new Clipper release 2018-06-28 22:16:15 +01:00
Laurent Cozic
2ded983828 Clipper: Resolves #641: Allow clipping selected part of the page 2018-06-28 22:01:55 +01:00
Laurent Cozic
0c708f766b All: Resolves #427: Import source-url from Enex files 2018-06-28 21:36:32 +01:00
Laurent Cozic
a801f8d8ed Update website 2018-06-28 21:27:54 +01:00
Laurent Cozic
26fc26c9fe CLI v1.0.109 2018-06-28 20:49:26 +01:00
Laurent Cozic
df4c07d204 CLI: Added way to decrypt string 2018-06-28 20:48:39 +01:00
Laurent Cozic
cf565d1563 Android release v1.0.129 2018-06-27 22:02:15 +01:00
Laurent Cozic
6b425cf543 Electron release v1.0.104 2018-06-27 22:00:38 +01:00
Laurent Cozic
6188e7a0fa Updated translations 2018-06-27 22:00:02 +01:00
Laurent Cozic
310afb0ad6 Electron: Resolves #612: Allow duplicating a note 2018-06-27 21:45:31 +01:00
Laurent Cozic
7d7e1e1637 Electron: Resolves #647: Allow specifying text editor path and arguments in setting 2018-06-27 21:34:41 +01:00
Laurent Cozic
424c8a2723 Clipper: Support 'author' property 2018-06-27 20:14:20 +01:00
Laurent Cozic
187fb1b85d Electron: Resolves #619: Context menu to cut, copy and paste. Also added menu to copy link in web view 2018-06-26 00:52:46 +01:00
Laurent Cozic
595fd7a9aa All: Resolves #644: Added support for .markdown extension when importing files 2018-06-26 00:07:53 +01:00
Laurent Cozic
0027cb9036 All: Fixes #646: Mentioned that TLS settings must be saved before checking sync config 2018-06-25 23:54:28 +01:00
Laurent Cozic
db6878b978 Electron: Fixes #639: Make sure text wraps when printing or exporting as PDF 2018-06-25 23:32:23 +01:00
Laurent Cozic
1c78722573 CLI: Upgraded Turndown plugins 2018-06-25 18:19:27 +01:00
Laurent Cozic
fea83e28c4 All: Optimised encryption and decryption of items so that it doesn't freeze the UI, especially on mobile 2018-06-25 18:14:57 +01:00
Laurent Cozic
84adf64271 Electron: Set PDF default file name 2018-06-22 18:36:15 +00:00
Laurent Cozic
74e2b0d15d Electron: Fixes #634: Press ESC to dismiss dialog in non-English languages 2018-06-22 18:31:55 +00:00
Laurent Cozic
df302206dd Electron: Allow HTML in Markdown documents in a secure way 2018-06-22 18:18:15 +00:00
Laurent Cozic
6d8941c005 Update website 2018-06-21 22:14:47 +01:00
Laurent Cozic
971b20062f Electron release v1.0.103 2018-06-21 19:13:10 +01:00
Laurent Cozic
936f334b61 Electron: Remove 'New notebook' shortcut 2018-06-21 19:12:08 +01:00
Laurent Cozic
7e3a290939 Merge pull request #628 from Abijeet/master
Adds a shortcut to insert the date and time.
2018-06-21 19:09:36 +01:00
Laurent Cozic
c6466a780e Android release v1.0.128 2018-06-21 19:08:59 +01:00
Laurent Cozic
43774ad3fb Electron release v1.0.102 2018-06-21 19:05:58 +01:00
Laurent Cozic
b3ba5b7747 All: Revert #554 to try to fix #624: WebDAV error when syncing with SeaFile 2018-06-21 19:00:20 +01:00
Laurent Cozic
599f4ccef4 Electron: Fixes #626: Auto-completion for indented items 2018-06-21 18:53:42 +01:00
Laurent Cozic
a67600d264 Updated Chinese and French translation 2018-06-21 18:04:10 +01:00
Laurent Cozic
ebf4c89ef0 All: Fixes #343, Fixes #191: Added options to specify custom TLS certificates 2018-06-20 01:18:58 +01:00
Laurent Cozic
aa7da784fc All: Fixes #343, Fixes #191: Added options to ignore TLS cert errors to allow self-signed certificates on desktop and CLI 2018-06-20 00:28:50 +01:00
Laurent Cozic
617ed42d8c Update website 2018-06-18 19:08:13 +01:00
Laurent Cozic
5848e7d90d Doc: Fixed image 2018-06-18 19:08:07 +01:00
Abijeet Patro
01d032261c Merge branch 'master' into master 2018-06-18 23:32:10 +05:30
Laurent Cozic
54d06646aa Update website 2018-06-18 19:01:52 +01:00
Laurent Cozic
81da46035a Doc: Fixed image 2018-06-18 19:01:42 +01:00
Laurent Cozic
74d0f75802 Update website 2018-06-18 19:00:07 +01:00
Laurent Cozic
f25a352dcb Doc: Mentioned Web Clipper 2018-06-18 18:59:54 +01:00
Laurent Cozic
21ef8da45f Clipper: Completed doc and simplified logic to get clipper port to make it easier to use by third-party 2018-06-18 18:54:48 +01:00
Laurent Cozic
1f3a1c49df Electron: Resolves #611: Allow opening and editing note in external editor 2018-06-18 18:56:07 +00:00
Laurent Cozic
a8b58aaec3 All: Fixes #632: Handle restricted_content error in Dropbox 2018-06-18 08:47:51 +01:00
Laurent Cozic
44f9b35d93 Update website 2018-06-17 19:35:25 +01:00
Laurent Cozic
711af9beed Electron release v1.0.101 2018-06-17 19:12:28 +01:00
Laurent Cozic
971339ca9a Electron: Fixes #630: PDF export in context menu 2018-06-17 17:12:28 +01:00
Laurent Cozic
f5a72ffbaf All: Fixes #593: Resource should not be auto-deleted if they've never been linked to any note 2018-06-17 16:59:06 +01:00
Laurent Cozic
cf4331c5af Electron: Fixes #623: Improved handling of text selection and fixed infinite loop 2018-06-17 02:44:37 +01:00
Abijeet
07b85388fc Adds a shortcut to insert the date and time.
Closes #521
2018-06-16 20:46:27 +05:30
Laurent Cozic
553b086ba2 Update website 2018-06-15 19:56:17 +01:00
Laurent Cozic
ff89537899 Update website 2018-06-15 19:28:58 +01:00
Laurent Cozic
f20792889a Removed Twitter and FB share buttons 2018-06-15 19:28:35 +01:00
Laurent Cozic
ee22a7ff73 Update website 2018-06-15 18:23:23 +01:00
Laurent Cozic
4fc4353859 Update translation 2018-06-15 18:23:15 +01:00
Laurent Cozic
f4f9e25e6b Update website 2018-06-15 18:14:55 +01:00
Laurent Cozic
e54f9934b5 Fixed Catalan flag 2018-06-15 18:14:31 +01:00
Laurent Cozic
f599ae065a CLI v1.0.108 2018-06-14 22:42:43 +01:00
Laurent Cozic
5bd9bf6a4e Update dependencies 2018-06-14 22:42:15 +01:00
Laurent Cozic
cb9e8d4f76 Update website 2018-06-14 18:41:57 +01:00
292 changed files with 27469 additions and 6602 deletions

0
.gitignore vendored Executable file → Normal file
View File

View File

@@ -9,8 +9,6 @@
echo 'export PATH="/usr/local/opt/gettext/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
If you get a node-gyp related error you might need to manually install it: `npm install -g node-gyp`
## Linux and Windows (WSL) dependencies
- Install yarn - https://yarnpkg.com/lang/en/docs/install/
@@ -37,6 +35,10 @@ yarn dist
If there's an error `while loading shared libraries: libgconf-2.so.4: cannot open shared object file: No such file or directory`, run `sudo apt-get install libgconf-2-4`
If you get a node-gyp related error you might need to manually install it: `npm install -g node-gyp`.
If you get the error `libtool: unrecognized option '-static'`, follow the instructions [in this post](https://stackoverflow.com/a/38552393/561309) to use the correct libtool version.
That will create the executable file in the `dist` directory.
From `/ElectronClient` you can also run `run.sh` to run the app for testing.
@@ -56,6 +58,8 @@ If node-gyp does not works (MSBUILD: error MSB3428: Could not load the Visual C+
If `yarn dist` fails, it may need administrative rights.
The [building\_win32\_tips on this page](./readme/building_win32_tips.md) might be helpful.
# Building the Mobile application
First you need to setup React Native to build projects with native code. For this, follow the instructions on the [Get Started](https://facebook.github.io/react-native/docs/getting-started.html) tutorial, in the "Building Projects with Native Code" tab.

View File

@@ -17,3 +17,12 @@ Again, please check that it has not already been requested. If it has, simply **
If you want to add a new feature, consider asking about it before implementing it or checking existing discussions to make sure it is within the scope of the project. Of course you are free to create the pull request directly but it is not guaranteed it is going to be accepted.
Building the apps is relatively easy - please [see the build instructions](https://github.com/laurent22/joplin/blob/master/BUILD.md) for more details.
Pull requests that automatically change many files tend to be rejected (for example changes that automatically update the code styling, or to add new lines to many files, or to automatically convert images to a different format) so if you have such a pull request in mind, please discuss it first in the forum.
# Coding style
There are only two rules, but not following them means the pull request will not be accepted (it can be accepted once the issues are fixed):
- **Please use tabs, NOT spaces.**
- **Please do not add or remove optional characters, such as spaces or colons.** Please setup your editor so that it only changes what you are working on and is not making automated changes elsewhere. The reason for this is that small white space changes make diff hard to read and can cause needless conflicts.

View File

@@ -13,6 +13,7 @@ tests/fuzzing.*
tests/fuzzing -*
tests/logs/*
tests/cli-integration/
tests/tmp/
*.mo
*.*~
tests/sync

View File

@@ -21,7 +21,6 @@ const { _, setLocale, defaultLocale, closestSupportedLocale } = require('lib/loc
const os = require('os');
const fs = require('fs-extra');
const { cliUtils } = require('./cli-utils.js');
const EventEmitter = require('events');
const Cache = require('lib/Cache');
class Application extends BaseApplication {

View File

@@ -0,0 +1,289 @@
const { BaseCommand } = require('./base-command.js');
const { _ } = require('lib/locale.js');
const { cliUtils } = require('./cli-utils.js');
const EncryptionService = require('lib/services/EncryptionService');
const DecryptionWorker = require('lib/services/DecryptionWorker');
const MasterKey = require('lib/models/MasterKey');
const BaseItem = require('lib/models/BaseItem');
const BaseModel = require('lib/BaseModel');
const Setting = require('lib/models/Setting.js');
const { toTitleCase } = require('lib/string-utils.js');
const { reg } = require('lib/registry.js');
const markdownUtils = require('lib/markdownUtils');
const { Database } = require('lib/database.js');
class Command extends BaseCommand {
usage() {
return 'apidoc';
}
description() {
return 'Build the API doc';
}
createPropertiesTable(tableFields) {
const headers = [
{ name: 'name', label: 'Name' },
{ name: 'type', label: 'Type', filter: (value) => {
return Database.enumName('fieldType', value);
}},
{ name: 'description', label: 'Description' },
];
return markdownUtils.createMarkdownTable(headers, tableFields);
}
async action(args) {
const models = [
{
type: BaseModel.TYPE_NOTE,
},
{
type: BaseModel.TYPE_FOLDER,
},
{
type: BaseModel.TYPE_RESOURCE,
},
{
type: BaseModel.TYPE_TAG,
},
];
const lines = [];
lines.push('# Joplin API');
lines.push('');
lines.push('When the Web Clipper service is enabled, Joplin exposes a [REST API](https://en.wikipedia.org/wiki/Representational_state_transfer) which allows third-party applications to access Joplin\'s data and to create, modify or delete notes, notebooks, resources or tags.');
lines.push('');
lines.push('In order to use it, you\'ll first need to find on which port the service is running. To do so, open the Web Clipper Options in Joplin and if the service is running it should tell you on which port. Normally it runs on port **41184**. If you want to find it programmatically, you may follow this kind of algorithm:');
lines.push('');
lines.push('```javascript');
lines.push('let port = null;');
lines.push('for (let portToTest = 41184; portToTest <= 41194; portToTest++) {');
lines.push(' const result = pingPort(portToTest); // Call GET /ping');
lines.push(' if (result == \'JoplinClipperServer\') {');
lines.push(' port = portToTest; // Found the port');
lines.push(' break;');
lines.push(' }');
lines.push('}');
lines.push('```');
lines.push('');
lines.push('# Authorisation')
lines.push('');
lines.push('To prevent unauthorised applications from accessing the API, the calls must be authentified. To do so, you must provide a token as a query parameter for each API call. You can get this token from the Joplin desktop application, on the Web Clipper Options screen.');
lines.push('');
lines.push('This would be an example of valid cURL call using a token:');
lines.push('');
lines.push('\tcurl http://localhost:41184/notes?token=ABCD123ABCD123ABCD123ABCD123ABCD123');
lines.push('');
lines.push('In the documentation below, the token will not be specified every time however you will need to include it.');
lines.push('');
lines.push('# Using the API');
lines.push('');
lines.push('All the calls, unless noted otherwise, receives and send **JSON data**. For example to create a new note:');
lines.push('');
lines.push('\tcurl --data \'{ "title": "My note", "body": "Some note in **Markdown**"}\' http://localhost:41184/notes');
lines.push('');
lines.push('In the documentation below, the calls may include special parameters such as :id or :note_id. You would replace this with the item ID or note ID.');
lines.push('');
lines.push('For example, for the endpoint `DELETE /tags/:id/notes/:note_id`, to remove the tag with ID "ABCD1234" from the note with ID "EFGH789", you would run for example:');
lines.push('');
lines.push('\tcurl -X DELETE http://localhost:41184/tags/ABCD1234/notes/EFGH789');
lines.push('');
lines.push('The four verbs supported by the API are the following ones:');
lines.push('');
lines.push('* **GET**: To retrieve items (notes, notebooks, etc.).');
lines.push('* **POST**: To create new items. In general most item properties are optional. If you omit any, a default value will be used.');
lines.push('* **PUT**: To update an item. Note in a REST API, traditionally PUT is used to completely replace an item, however in this API it will only replace the properties that are provided. For example if you PUT {"title": "my new title"}, only the "title" property will be changed. The other properties will be left untouched (they won\'t be cleared nor changed).');
lines.push('* **DELETE**: To delete items.');
lines.push('');
lines.push('# Filtering data');
lines.push('');
lines.push('You can change the fields that will be returned by the API using the `fields=` query parameter, which takes a list of comma separated fields. For example, to get the longitude and latitude of a note, use this:');
lines.push('');
lines.push('\tcurl http://localhost:41184/notes/ABCD123?fields=longitude,latitude');
lines.push('');
lines.push('To get the IDs only of all the tags:');
lines.push('');
lines.push('\tcurl http://localhost:41184/tags?fields=id');
lines.push('');
lines.push('# About the property types');
lines.push('');
lines.push('* Text is UTF-8.');
lines.push('* All date/time are Unix timestamps in milliseconds.');
lines.push('* Booleans are integer values 0 or 1.');
lines.push('');
lines.push('# Testing if the service is available');
lines.push('');
lines.push('Call **GET /ping** to check if the service is available. It should return "JoplinClipperServer" if it works.');
lines.push('');
for (let i = 0; i < models.length; i++) {
const model = models[i];
const ModelClass = BaseItem.getClassByItemType(model.type);
const tableName = ModelClass.tableName();
let tableFields = reg.db().tableFields(tableName, { includeDescription: true });
const singular = tableName.substr(0, tableName.length - 1);
if (model.type === BaseModel.TYPE_NOTE) {
tableFields = tableFields.slice();
tableFields.push({
name: 'body_html',
type: Database.enumId('fieldType', 'text'),
description: 'Note body, in HTML format',
});
tableFields.push({
name: 'base_url',
type: Database.enumId('fieldType', 'text'),
description: 'If `body_html` is provided and contains relative URLs, provide the `base_url` parameter too so that all the URLs can be converted to absolute ones. The base URL is basically where the HTML was fetched from, minus the query (everything after the \'?\'). For example if the original page was `https://stackoverflow.com/search?q=%5Bjava%5D+test`, the base URL is `https://stackoverflow.com/search`.',
});
tableFields.push({
name: 'image_data_url',
type: Database.enumId('fieldType', 'text'),
description: 'An image to attach to the note, in [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format.',
});
tableFields.push({
name: 'crop_rect',
type: Database.enumId('fieldType', 'text'),
description: 'If an image is provided, you can also specify an optional rectangle that will be used to crop the image. In format `{ x: x, y: y, width: width, height: height }`',
});
tableFields.push({
name: 'tags',
type: Database.enumId('fieldType', 'text'),
description: 'Comma-separated list of tags. eg. `tag1,tag2`.',
});
}
lines.push('# ' + toTitleCase(tableName));
lines.push('');
if (model.type === BaseModel.TYPE_FOLDER) {
lines.push('This is actually a notebook. Internally notebooks are called "folders".');
lines.push('');
}
lines.push('## Properties');
lines.push('');
lines.push(this.createPropertiesTable(tableFields));
lines.push('');
lines.push('## GET /' + tableName);
lines.push('');
lines.push('Gets all ' + tableName);
lines.push('');
if (model.type === BaseModel.TYPE_FOLDER) {
lines.push('The folders are returned as a tree. The sub-notebooks of a notebook, if any, are under the `children` key.');
lines.push('');
}
lines.push('## GET /' + tableName + '/:id');
lines.push('');
lines.push('Gets ' + singular + ' with ID :id');
lines.push('');
if (model.type === BaseModel.TYPE_TAG) {
lines.push('## GET /tags/:id/notes');
lines.push('');
lines.push('Gets all the notes with this tag.');
lines.push('');
}
if (model.type === BaseModel.TYPE_NOTE) {
lines.push('## GET /notes/:id/tags');
lines.push('');
lines.push('Gets all the tags attached to this note.');
lines.push('');
}
if (model.type === BaseModel.TYPE_FOLDER) {
lines.push('## GET /folders/:id/notes');
lines.push('');
lines.push('Gets all the notes inside this folder.');
lines.push('');
}
if (model.type === BaseModel.TYPE_RESOURCE) {
lines.push('## GET /resources/:id/file');
lines.push('');
lines.push('Gets the actual file associated with this resource.');
lines.push('');
}
lines.push('## POST /' + tableName);
lines.push('');
lines.push('Creates a new ' + singular);
lines.push('');
if (model.type === BaseModel.TYPE_RESOURCE) {
lines.push('Creating a new resource is special because you also need to upload the file. Unlike other API calls, this one must have the "multipart/form-data" Content-Type. The file data must be passed to the "data" form field, and the other properties to the "props" form field. An example of a valid call with cURL would be:');
lines.push('');
lines.push('\tcurl -F \'data=@/path/to/file.jpg\' -F \'props={"title":"my resource title"}\' http://localhost:41184/resources');
lines.push('');
lines.push('The "data" field is required, while the "props" one is not. If not specified, default values will be used.');
lines.push('');
}
if (model.type === BaseModel.TYPE_TAG) {
lines.push('## POST /tags/:id/notes');
lines.push('');
lines.push('Post a note to this endpoint to add the tag to the note. The note data must at least contain an ID property (all other properties will be ignored).');
lines.push('');
}
if (model.type === BaseModel.TYPE_NOTE) {
lines.push('You can either specify the note body as Markdown by setting the `body` parameter, or in HTML by setting the `body_html`.');
lines.push('');
lines.push('Examples:');
lines.push('');
lines.push('* Create a note from some Markdown text');
lines.push('');
lines.push(' curl --data \'{ "title": "My note", "body": "Some note in **Markdown**"}\' http://127.0.0.1:41184/notes');
lines.push('');
lines.push('* Create a note from some HTML');
lines.push('');
lines.push(' curl --data \'{ "title": "My note", "body_html": "Some note in <b>HTML</b>"}\' http://127.0.0.1:41184/notes');
lines.push('');
lines.push('* Create a note and attach an image to it:');
lines.push('');
lines.push(' curl --data \'{ "title": "Image test", "body": "Here is Joplin icon:", "image_data_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUeNoAyAA3/wFwtO3K6gUB/vz2+Prw9fj/+/r+/wBZKAAExOgF4/MC9ff+MRH6Ui4E+/0Bqc/zutj6AgT+/Pz7+vv7++nu82c4DlMqCvLs8goA/gL8/fz09fb59vXa6vzZ6vjT5fbn6voD/fwC8vX4UiT9Zi//APHyAP8ACgUBAPv5APz7BPj2+DIaC2o3E+3o6ywaC5fT6gD6/QD9/QEVf9kD+/dcLQgJA/7v8vqfwOf18wA1IAIEVycAyt//v9XvAPv7APz8LhoIAPz9Ri4OAgwARgx4W/6fVeEAAAAASUVORK5CYII="}\' http://127.0.0.1:41184/notes');
lines.push('');
lines.push('### Creating a note with a specific ID');
lines.push('');
lines.push('When a new note is created, it is automatically assigned a new unique ID so **normally you do not need to set the ID**. However, if for some reason you want to set it, you can supply it as the `id` property. It needs to be a 32 characters long hexadecimal string. **Make sure it is unique**, for example by generating it using whatever GUID function is available in your programming language.');
lines.push('');
lines.push(' curl --data \'{ "id": "00a87474082744c1a8515da6aa5792d2", "title": "My note with custom ID"}\' http://127.0.0.1:41184/notes');
lines.push('');
}
lines.push('## PUT /' + tableName + '/:id');
lines.push('');
lines.push('Sets the properties of the ' + singular + ' with ID :id');
lines.push('');
lines.push('## DELETE /' + tableName + '/:id');
lines.push('');
lines.push('Deletes the ' + singular + ' with ID :id');
lines.push('');
if (model.type === BaseModel.TYPE_TAG) {
lines.push('## DELETE /tags/:id/notes/:note_id');
lines.push('');
lines.push('Remove the tag from the note.');
lines.push('');
}
}
this.stdout(lines.join('\n'));
}
}
module.exports = Command;

View File

@@ -26,7 +26,7 @@ class Command extends BaseCommand {
const md = Setting.settingMetadata(name);
let value = Setting.value(name);
if (typeof value === 'object' || Array.isArray(value)) value = JSON.stringify(value);
if (md.secure) value = '********';
if (md.secure && value) value = '********';
if (Setting.isEnum(name)) {
return _('%s = %s (%s)', name, value, Setting.enumOptionsDoc(name));

View File

@@ -47,12 +47,48 @@ class Command extends BaseCommand {
}
if (args.command === 'decrypt') {
this.stdout(_('Starting decryption... Please wait as it may take several minutes depending on how much there is to decrypt.'));
while (true) {
try {
await DecryptionWorker.instance().start();
break;
if (args.path) {
const plainText = await EncryptionService.instance().decryptString(args.path);
this.stdout(plainText);
return;
} else {
if (process.stdin.isTTY) {
this.stdout(_('Starting decryption... Please wait as it may take several minutes depending on how much there is to decrypt.'));
await DecryptionWorker.instance().start();
this.stdout(_('Completed decryption.'));
return;
} else {
// var repl = require("repl");
// var r = repl.start("node> ");
const text = await new Promise((accept, reject) => {
var buffer = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(chunk) {
buffer += chunk;
// process.stdout.write(chunk);
});
process.stdin.on('end', function() {
accept(buffer.trim());
});
});
if (text.length > 0) {
var cipherText = text;
try {
var item = await BaseItem.unserialize(text);
cipherText = item.encryption_cipher_text;
} catch (error) {
// we already got the pure cipher text
}
const plainText = await EncryptionService.instance().decryptString(cipherText);
this.stdout(plainText);
}
return;
}
}
} catch (error) {
if (error.code === 'masterKeyNotLoaded') {
const masterKeyId = error.masterKeyId;
@@ -70,8 +106,6 @@ class Command extends BaseCommand {
}
}
this.stdout(_('Completed decryption.'));
return;
}
@@ -181,4 +215,4 @@ class Command extends BaseCommand {
}
module.exports = Command;
module.exports = Command;

View File

@@ -22,7 +22,7 @@ class Command extends BaseCommand {
enabled() {
return false;
}
options() {
return [
['-n, --limit <num>', _('Displays only the first top <num> notes.')],
@@ -93,7 +93,7 @@ class Command extends BaseCommand {
row.push(await Folder.noteCount(item.id));
}
row.push(time.unixMsToLocalDateTime(item.user_updated_time));
row.push(time.formatMsToLocal(item.user_updated_time));
}
let title = item.title;
@@ -123,4 +123,4 @@ class Command extends BaseCommand {
}
module.exports = Command;
module.exports = Command;

View File

@@ -4,6 +4,7 @@ const { _ } = require('lib/locale.js');
const { OneDriveApiNodeUtils } = require('./onedrive-api-node-utils.js');
const Setting = require('lib/models/Setting.js');
const BaseItem = require('lib/models/BaseItem.js');
const ResourceFetcher = require('lib/services/ResourceFetcher');
const { Synchronizer } = require('lib/synchronizer.js');
const { reg } = require('lib/registry.js');
const { cliUtils } = require('./cli-utils.js');
@@ -191,6 +192,15 @@ class Command extends BaseCommand {
}
}
// When using the tool in command line mode, the ResourceFetcher service is
// not going to be running in the background, so the resources need to be
// explicitely downloaded below.
if (!app().hasGui()) {
this.stdout(_('Downloading resources...'));
await ResourceFetcher.instance().fetchAll();
await ResourceFetcher.instance().waitForAllFinished();
}
await app().refreshCurrentFolder();
} catch (error) {
cleanUp();

View File

@@ -3,6 +3,7 @@ const { app } = require('./app.js');
const { _ } = require('lib/locale.js');
const Tag = require('lib/models/Tag.js');
const BaseModel = require('lib/BaseModel.js');
const { time } = require('lib/time-utils.js');
class Command extends BaseCommand {
@@ -11,11 +12,19 @@ class Command extends BaseCommand {
}
description() {
return _('<tag-command> can be "add", "remove" or "list" to assign or remove [tag] from [note], or to list the notes associated with [tag]. The command `tag list` can be used to list all the tags.');
return _('<tag-command> can be "add", "remove" or "list" to assign or remove [tag] from [note], or to list the notes associated with [tag]. The command `tag list` can be used to list all the tags (use -l for long option).');
}
options() {
return [
['-l, --long', _('Use long list format. Format is ID, NOTE_COUNT (for notebook), DATE, TODO_CHECKED (for to-dos), TITLE')],
];
}
async action(args) {
let tag = null;
let options = args.options;
if (args.tag) tag = await app().loadItem(BaseModel.TYPE_TAG, args.tag);
let notes = [];
if (args.note) {
@@ -41,7 +50,28 @@ class Command extends BaseCommand {
} else if (command == 'list') {
if (tag) {
let notes = await Tag.notes(tag.id);
notes.map((note) => { this.stdout(note.title); });
notes.map((note) => {
let line = '';
if (options.long) {
line += BaseModel.shortId(note.id);
line += ' ';
line += time.formatMsToLocal(note.user_updated_time);
line += ' ';
}
if (note.is_todo) {
line += '[';
if (note.todo_completed) {
line += 'X';
} else {
line += ' ';
}
line += '] ';
} else {
line += ' ';
}
line += note.title;
this.stdout(line);
});
} else {
let tags = await Tag.all();
tags.map((tag) => { this.stdout(tag.title); });

View File

@@ -32,8 +32,6 @@ class FolderListWidget extends ListWidget {
output.push(_('Search:'));
output.push(item.title);
}
// if (item && item.id) output.push(item.id.substr(0, 5));
return output.join(' ');
};
@@ -85,7 +83,6 @@ class FolderListWidget extends ListWidget {
}
set notesParentType(v) {
//if (this.notesParentType_ === v) return;
this.notesParentType_ = v;
this.updateIndexFromSelectedItemId()
this.invalidate();
@@ -123,6 +120,14 @@ class FolderListWidget extends ListWidget {
this.updateIndexFromSelectedItemId()
this.invalidate();
}
folderHasChildren_(folders, folderId) {
for (let i = 0; i < folders.length; i++) {
let folder = folders[i];
if (folder.parent_id === folderId) return true;
}
return false;
}
render() {
if (this.updateItems_) {
@@ -130,7 +135,18 @@ class FolderListWidget extends ListWidget {
const wasSelectedItemId = this.selectedJoplinItemId;
const previousParentType = this.notesParentType;
let newItems = this.folders.slice();
let newItems = [];
const orderFolders = (parentId) => {
for (let i = 0; i < this.folders.length; i++) {
const f = this.folders[i];
if (f.parent_id === parentId) {
newItems.push(f);
if (this.folderHasChildren_(this.folders, f.id)) orderFolders(f.id);
}
}
}
orderFolders('');
if (this.tags.length) {
if (newItems.length) newItems.push('-');

View File

@@ -460,13 +460,17 @@ msgstr "No es pot inicialitzar el sincronitzador."
msgid "Starting synchronisation..."
msgstr "Està començant la sincronització..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "S'està cancel·lant... Espereu."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command>pot ser «add», «remove» o «list» per a assignar o suprimir "
"[tag] de la [nota], o per a llistar les notes associades amb [tag]. L'ordre "
@@ -632,15 +636,29 @@ msgstr "Retalla"
msgid "Paste"
msgstr "Enganxa"
#, fuzzy
msgid "Select all"
msgstr "Seleccioneu una data"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Cerca a totes les notes"
#, fuzzy
msgid "Search in current note"
msgstr "Cerca a totes les notes"
msgid "View"
msgstr "Visualització"
@@ -709,6 +727,9 @@ msgstr "Sí"
msgid "No"
msgstr "No"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
"El servei de desa-retalls de webs és actiu i configurat per a iniciar-se "
@@ -759,6 +780,21 @@ msgstr "Pas 2: Instal·leu l'extensió"
msgid "Download and install the relevant extension for your browser:"
msgstr "Baixeu i instal·leu l'extensió adient per al vostre navegador:"
#, fuzzy
msgid "Advanced options"
msgstr "Mostra les opcions avançades"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr "Comprova la configuració de la sincronització"
@@ -766,12 +802,15 @@ msgstr "Comprova la configuració de la sincronització"
msgid "Notes and settings are stored in: %s"
msgstr "Les notes i la configuració es desen a: %s"
msgid "Save"
msgstr "Desa"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr "Tramet"
msgid "Save"
msgstr "Desa"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -910,9 +949,24 @@ msgstr "Establiu la contrasenya"
msgid "Add or remove tags"
msgstr "Afegeix o suprimeix etiquetes"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Copia"
msgid "Switch between note and to-do type"
msgstr "Alterna entre el tipus nota i tasques pendents"
#, fuzzy
msgid "Switch to note type"
msgstr "Alterna entre el tipus nota i tasques pendents"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Alterna entre el tipus nota i tasques pendents"
msgid "Copy Markdown link"
msgstr "Copia l'enllaç Markdown"
@@ -931,6 +985,15 @@ msgstr ""
"Ara mateix no hi ha cap bloc de notes. Creeu-ne un fent clic a «Bloc de "
"notes nou»."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Obre..."
@@ -944,6 +1007,12 @@ msgstr "Anomena i desa..."
msgid "Copy path to clipboard"
msgstr "Copia el camí al porta-retalls"
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Missatge o enllaç no suportat: %s"
@@ -962,6 +1031,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -999,6 +1071,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "S'està cancel·lant..."
msgid "to-do"
msgstr "Tasques pendents"
@@ -1048,6 +1127,14 @@ msgstr "Sincronitza"
msgid "Notebooks"
msgstr "Blocs de notes"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Elements obtinguts: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Recursos: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Seleccioneu on s'hauria d'exportar l'estat de la sincronització"
@@ -1092,6 +1179,9 @@ msgstr ""
"No es pot actualitzar el testimoni: manquen les dades d'autenticació. Si "
"comenceu altre cop la sincronització, potser es corregeixi el problema."
msgid "Untitled"
msgstr "Sense títol"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1139,10 +1229,6 @@ msgstr "Elements remots suprimits: %d."
msgid "Fetched items: %d/%d."
msgstr "Elements obtinguts: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estat: %s"
msgid "Cancelling..."
msgstr "S'està cancel·lant..."
@@ -1176,10 +1262,6 @@ msgstr "Conflictes"
msgid "Cannot move notebook to this location"
msgstr "No es pot moure el bloc de notes a aquesta ubicació"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Ja existeix un bloc de notes amb aquest títol: «%s»"
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr "Els blocs de notes no poden tenir el nom «%s», és un títol reservat."
@@ -1193,9 +1275,6 @@ msgstr "data d'actualització"
msgid "created date"
msgstr "data de creació"
msgid "Untitled"
msgstr "Sense títol"
msgid "This note does not have geolocation information."
msgstr "Aquesta nota no té informació de geolocalització."
@@ -1207,16 +1286,6 @@ msgstr "No es pot copiar la nota al bloc de notes «%s»"
msgid "Cannot move note to \"%s\" notebook"
msgstr "No es pot moure la nota al bloc de notes «%s»"
msgid "Text editor"
msgstr "Editor de text"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"L'editor que s'usarà per a obrir una nota. Si no s'indica cap, intentarà "
"detectar automàticament l'editor predeterminat."
msgid "Language"
msgstr "Llengua"
@@ -1268,9 +1337,22 @@ msgstr "Mostra la icona a la safata"
msgid "Note: Does not work in all desktop environments."
msgstr "Nota: no funciona en tots els entorns d'escriptori."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Percentatge de zoom global"
#, fuzzy
msgid "Editor font size"
msgstr "Tipus de lletra de l'editor"
msgid "Editor font family"
msgstr "Tipus de lletra de l'editor"
@@ -1300,6 +1382,18 @@ msgstr "%d hora"
msgid "%d hours"
msgstr "%d hores"
#, fuzzy
msgid "Text editor command"
msgstr "Editor de text"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"L'editor que s'usarà per a obrir una nota. Si no s'indica cap, intentarà "
"detectar automàticament l'editor predeterminat."
msgid "Show advanced options"
msgstr "Mostra les opcions avançades"
@@ -1326,6 +1420,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "URL del Nextcloud WebDAV"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Nom d'usuari del Nextcloud"
@@ -1341,10 +1442,27 @@ msgstr "Nom d'usuari WebDAV"
msgid "WebDAV password"
msgstr "Contrasenya de WebDAV"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "El valor de l'opció no és vàlid: «%s». Els valors possibles són: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr "Fitxer d'exportació del Joplin"
@@ -1357,6 +1475,10 @@ msgstr "Directori d'exportació del Joplin"
msgid "Evernote Export File"
msgstr "Fitxer d'exportació de l'Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Directori d'exportació del Joplin"
msgid "Directory"
msgstr "Directori"
@@ -1431,6 +1553,12 @@ msgstr "Alarmes programades"
msgid "On %s: %s"
msgstr "A les %s.%s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Ara mateix no hi ha cap nota. Creeu-ne una fent clic en el botó (+)."
@@ -1459,6 +1587,10 @@ msgstr "Voleu moure %d notes al bloc de notes «%s»?"
msgid "Press to set the decryption password."
msgstr "Premeu per a establir la contrasenya de desxifratge."
#, fuzzy
msgid "Clear alarm"
msgstr "Estableix una alarma"
msgid "Save alarm"
msgstr "Desa l'alarma"
@@ -1471,8 +1603,34 @@ msgstr "Confirmació"
msgid "Cancel synchronisation"
msgstr "Cancel·la la sincronització"
#, fuzzy
msgid "Checking... Please wait."
msgstr "S'està cancel·lant... Espereu."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Comprova la configuració de la sincronització"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "L'aplicació s'ha autoritzat correctament."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Elements obtinguts: %d/%d."
msgid "New tags:"
@@ -1562,6 +1720,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Tipus d'imatge no admesa: %s"
#, fuzzy
msgid "Take photo"
msgstr "Adjunta una imatge"
msgid "Attach photo"
msgstr "Adjunta una imatge"
@@ -1586,6 +1748,9 @@ msgstr "Mostra les metadades"
msgid "View on map"
msgstr "Mostra-ho al mapa"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Suprimeix el bloc de notes"
@@ -1608,3 +1773,9 @@ msgstr ""
msgid "Welcome"
msgstr "Benvingut"
#~ msgid "State: %s."
#~ msgstr "Estat: %s"
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Ja existeix un bloc de notes amb aquest títol: «%s»"

View File

@@ -448,13 +448,17 @@ msgstr "Nelze zavézt synchronizátor."
msgid "Starting synchronisation..."
msgstr "Zahajuji synchronizaci..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Zastavuji, chvíli strpení."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> může být \"add\", \"remove\" nebo \"list\" - přidat (add) či "
"odebrat (remove) [tag] k [poznámce], nebo vypsat (list) seznam poznámek "
@@ -614,15 +618,29 @@ msgstr "Vyjmout"
msgid "Paste"
msgstr "Vložit"
#, fuzzy
msgid "Select all"
msgstr "Vybrat datum"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Hledat ve všech poznámkách"
#, fuzzy
msgid "Search in current note"
msgstr "Hledat ve všech poznámkách"
msgid "View"
msgstr "Zobrazit"
@@ -691,6 +709,9 @@ msgstr "Ano"
msgid "No"
msgstr "Ne"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -734,6 +755,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Ukázat pokročilé volby"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr "Zkontrolujte nastavení synchronizace"
@@ -741,12 +777,15 @@ msgstr "Zkontrolujte nastavení synchronizace"
msgid "Notes and settings are stored in: %s"
msgstr "Poznámky a nastavení uloženo v: %s"
msgid "Save"
msgstr "Uložit"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr "Uložit"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -882,9 +921,24 @@ msgstr "Nastavit heslo"
msgid "Add or remove tags"
msgstr "Přidat či odebrat tagy"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Kopírovat"
msgid "Switch between note and to-do type"
msgstr "Přepnout mezi poznámkou a to-do"
#, fuzzy
msgid "Switch to note type"
msgstr "Přepnout mezi poznámkou a to-do"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Přepnout mezi poznámkou a to-do"
#, fuzzy
msgid "Copy Markdown link"
msgstr "Markdown"
@@ -902,6 +956,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "Nemáte žádný zápisník. Vytvořte jeden kliknutím na \"Nový zápisník\"."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Otevřít..."
@@ -915,6 +978,12 @@ msgstr "Uložit jako..."
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nepodporovaný link či zpráva: %s"
@@ -931,6 +1000,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -968,6 +1040,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "Zastavuji..."
msgid "to-do"
msgstr "to-do"
@@ -1018,6 +1097,14 @@ msgstr "Synchronizovat"
msgid "Notebooks"
msgstr "Zápisníky"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Získané položky: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Zdroje: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Prosím vyberte, kam má být stav synchronizace exportován"
@@ -1062,6 +1149,9 @@ msgstr ""
"Nelze obnovit token: chybí autentizační data. Restart synchronizace může "
"tento problém vyřešit. "
msgid "Untitled"
msgstr "Bez názvu"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1109,10 +1199,6 @@ msgstr "Položky smazané na vzdáleném úložišti: %d."
msgid "Fetched items: %d/%d."
msgstr "Získané položky: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Stav: %s."
msgid "Cancelling..."
msgstr "Zastavuji..."
@@ -1147,10 +1233,6 @@ msgstr "Konflikty"
msgid "Cannot move notebook to this location"
msgstr "Poznámku nelze přesunout do zápisníku \"%s\""
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Zápisník s tímto názvem již existuje: \"%s\""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr "Zápisník se nemůže jmenovat \"%s\", tento název je rezervován."
@@ -1167,9 +1249,6 @@ msgstr "Upraveno: %d."
msgid "created date"
msgstr "Vytvořeno: %d."
msgid "Untitled"
msgstr "Bez názvu"
msgid "This note does not have geolocation information."
msgstr "Tato poznámka nemá informace o poloze."
@@ -1181,16 +1260,6 @@ msgstr "Poznámku \"%s\" nelze zkopírovat do zápisníku"
msgid "Cannot move note to \"%s\" notebook"
msgstr "Poznámku nelze přesunout do zápisníku \"%s\""
msgid "Text editor"
msgstr "Textový editor"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Editor ve kterém budou otvírány poznámky. Pokud není specifikováno, aplikace "
"se pokusí o autodetekci defaultního editoru."
msgid "Language"
msgstr "Jazyk"
@@ -1243,9 +1312,22 @@ msgstr "Zobrazovat ikonu v panelu"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Globální zoom"
#, fuzzy
msgid "Editor font size"
msgstr "Rodina písma v editoru"
msgid "Editor font family"
msgstr "Rodina písma v editoru"
@@ -1275,6 +1357,18 @@ msgstr "%d hodina"
msgid "%d hours"
msgstr "%d hodin"
#, fuzzy
msgid "Text editor command"
msgstr "Textový editor"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Editor ve kterém budou otvírány poznámky. Pokud není specifikováno, aplikace "
"se pokusí o autodetekci defaultního editoru."
msgid "Show advanced options"
msgstr "Ukázat pokročilé volby"
@@ -1301,6 +1395,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV URL"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Nextcloud uživatelské jméno"
@@ -1316,10 +1417,27 @@ msgstr "WebDAV uživatelské jméno"
msgid "WebDAV password"
msgstr "WebDAV heslo"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Neplatná hodnota: \"%s\". Přípustné hodnoty jsou: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr "Soubor Joplin Export"
@@ -1332,6 +1450,10 @@ msgstr "Složka pro export"
msgid "Evernote Export File"
msgstr "Soubor Evernote Exportu"
#, fuzzy
msgid "Json Export Directory"
msgstr "Složka pro export"
msgid "Directory"
msgstr "Adresář"
@@ -1406,6 +1528,12 @@ msgstr "Nadcházející alarmy"
msgid "On %s: %s"
msgstr "Na %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Nemáte žádné poznámky. Vytvořte jednu kliknutím na tlačítko (+)."
@@ -1434,6 +1562,10 @@ msgstr "Přesunout poznámky %d do zápisníku \"%s\"?"
msgid "Press to set the decryption password."
msgstr "Stiskněte pro zadání hesla k dešifrování."
#, fuzzy
msgid "Clear alarm"
msgstr "Nastavit alarm"
#, fuzzy
msgid "Save alarm"
msgstr "Nastavit alarm"
@@ -1447,8 +1579,34 @@ msgstr "Potvrdit"
msgid "Cancel synchronisation"
msgstr "Zrušit synchronizaci"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Zastavuji, chvíli strpení."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Zkontrolujte nastavení synchronizace"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "Aplikace byla úspěšně autorizována."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Získané položky: %d/%d."
msgid "New tags:"
@@ -1531,6 +1689,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nepodporovaný formát obrázku: %s"
#, fuzzy
msgid "Take photo"
msgstr "Přiložit obrázek"
msgid "Attach photo"
msgstr "Přiložit obrázek"
@@ -1555,6 +1717,9 @@ msgstr "Zobrazit metadata"
msgid "View on map"
msgstr "Zobrazit na map+"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Smazat zápisník"
@@ -1577,5 +1742,11 @@ msgstr "Nemáte žádný zápisník. Vytvořte jeden kliknutím na tlačítko (+
msgid "Welcome"
msgstr "Vítejte"
#~ msgid "State: %s."
#~ msgstr "Stav: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Zápisník s tímto názvem již existuje: \"%s\""
#~ msgid "Searches"
#~ msgstr "Hledané výrazy"

View File

@@ -452,13 +452,17 @@ msgstr "Kan ikke initialisere synkroniseringen."
msgid "Starting synchronisation..."
msgstr "Starter synkronisering."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Annullerer... Vent venligst."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> (mærke-kommando) kan enten være \"add\" (tilføj), \"remove"
"\" (slet) eller \"list\" (liste) for at tilføje eller fjerne mærke [tag] fra "
@@ -619,15 +623,29 @@ msgstr "Klip"
msgid "Paste"
msgstr "Indsæt"
#, fuzzy
msgid "Select all"
msgstr "Vælg dato"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Søg i alle noter"
#, fuzzy
msgid "Search in current note"
msgstr "Søg i alle noter"
msgid "View"
msgstr "Vis"
@@ -696,6 +714,9 @@ msgstr "Ja"
msgid "No"
msgstr "Nej"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -739,6 +760,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Vis avancerede indstillinger"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr "Check synkroniserings Indstillinger"
@@ -746,12 +782,15 @@ msgstr "Check synkroniserings Indstillinger"
msgid "Notes and settings are stored in: %s"
msgstr "Noter og indstillinger er gemt i: %s"
msgid "Save"
msgstr "Gem"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr "Gem"
msgid "Save"
msgstr "Gem"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -891,9 +930,24 @@ msgstr "Indstil kodeord"
msgid "Add or remove tags"
msgstr "Tilføj eller slet mærker"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Kopier"
msgid "Switch between note and to-do type"
msgstr "Skift mellem note- og opgave type"
#, fuzzy
msgid "Switch to note type"
msgstr "Skift mellem note- og opgave type"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Skift mellem note- og opgave type"
#, fuzzy
msgid "Copy Markdown link"
msgstr "Markdown"
@@ -911,6 +965,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "Der er ingen notesbog. Opret en ved at klikke på \"Ny Notesbog\"."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Åben..."
@@ -924,6 +987,12 @@ msgstr "Gem som..."
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Ugyldigt- eller ulovligt link eller besked: %s"
@@ -940,6 +1009,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -977,6 +1049,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "Annullerer..."
msgid "to-do"
msgstr "opgave"
@@ -1027,6 +1106,14 @@ msgstr "Synkroniser"
msgid "Notebooks"
msgstr "Notesbøger"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Hentede emner: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Ressourcer: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Vælg hvor sync status skal eksporteres til"
@@ -1071,6 +1158,9 @@ msgstr ""
"Kan ikke opdatere token: Godkendelses data mangler. Prøv at starte "
"synkronisering igen, det kan løse problemet."
msgid "Untitled"
msgstr "Samlet"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1118,10 +1208,6 @@ msgstr "Slettede fjern-emner: %d."
msgid "Fetched items: %d/%d."
msgstr "Hentede emner: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Tilstand: %s."
msgid "Cancelling..."
msgstr "Annullerer..."
@@ -1156,10 +1242,6 @@ msgstr "Konflikter"
msgid "Cannot move notebook to this location"
msgstr "Kan ikke flytte note til \"%s\" notesbog"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "En notesbog bruger allerede dette navn: \"%s\""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr "Notesbøger kan ikke få navnet \"%s\", da det er en beskyttet titel."
@@ -1176,9 +1258,6 @@ msgstr "Opdateret %d."
msgid "created date"
msgstr "Oprettet: %d."
msgid "Untitled"
msgstr "Samlet"
msgid "This note does not have geolocation information."
msgstr "Denne note har ingen geolokations oplysninger."
@@ -1190,16 +1269,6 @@ msgstr "Kan ikke kopiere note til \"%s\" notesbog"
msgid "Cannot move note to \"%s\" notebook"
msgstr "Kan ikke flytte note til \"%s\" notesbog"
msgid "Text editor"
msgstr "Tekst editor"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Editor der bruges til at åbne note. Hvis ingen valgt/udfyldt, vil auto-"
"funktion søge efter standard editor."
msgid "Language"
msgstr "Sprog"
@@ -1252,9 +1321,22 @@ msgstr "Vis ikon på bundbjælke"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Global zoom procent"
#, fuzzy
msgid "Editor font size"
msgstr "Rediger skrifttype"
msgid "Editor font family"
msgstr "Rediger skrifttype"
@@ -1284,6 +1366,18 @@ msgstr "%d time"
msgid "%d hours"
msgstr "%d timer"
#, fuzzy
msgid "Text editor command"
msgstr "Tekst editor"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Editor der bruges til at åbne note. Hvis ingen valgt/udfyldt, vil auto-"
"funktion søge efter standard editor."
msgid "Show advanced options"
msgstr "Vis avancerede indstillinger"
@@ -1310,6 +1404,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV URL"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Nextcloud brugernavn"
@@ -1325,10 +1426,27 @@ msgstr "WebDAV brugernavn"
msgid "WebDAV password"
msgstr "WebDAV kodeord"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Ulovlig værdi: \"%s\". Mulige valg er: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr "Joplin eksport fil"
@@ -1341,6 +1459,10 @@ msgstr "Joplin eksport mappe"
msgid "Evernote Export File"
msgstr "Evernote eksport fil"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin eksport mappe"
msgid "Directory"
msgstr "Indeks"
@@ -1415,6 +1537,12 @@ msgstr "Kommende alarmer"
msgid "On %s: %s"
msgstr "På %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Der er ingen noter. Opret note ved at klikke på (+) knappen."
@@ -1443,6 +1571,10 @@ msgstr "Flyt %d noter til notesbogen \"%s\"?"
msgid "Press to set the decryption password."
msgstr "Klik for at gemme dekrypterings kodeord."
#, fuzzy
msgid "Clear alarm"
msgstr "Indstil alarm"
#, fuzzy
msgid "Save alarm"
msgstr "Indstil alarm"
@@ -1456,8 +1588,34 @@ msgstr "Bekræft"
msgid "Cancel synchronisation"
msgstr "Afbryd synkronisering"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Annullerer... Vent venligst."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Check synkroniserings Indstillinger"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "Denne app er succesfuldt godkendt."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Hentede emner: %d/%d."
msgid "New tags:"
@@ -1540,6 +1698,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Ulovlig billedtype: %s"
#, fuzzy
msgid "Take photo"
msgstr "Vedhæft foto"
msgid "Attach photo"
msgstr "Vedhæft foto"
@@ -1564,6 +1726,9 @@ msgstr "Vis metadata"
msgid "View on map"
msgstr "Vis på kort"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Slet notesbog"
@@ -1586,6 +1751,12 @@ msgstr "Du har ingen notesbøger. Opret en ved at klikke på (+) knappen."
msgid "Welcome"
msgstr "Velkommen"
#~ msgid "State: %s."
#~ msgstr "Tilstand: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "En notesbog bruger allerede dette navn: \"%s\""
#~ msgid ""
#~ "For more information about End-To-End Encryption (E2EE) and advices on "
#~ "how to enable it please check the documentation"

View File

@@ -7,19 +7,18 @@ msgid ""
msgstr ""
"Project-Id-Version: Joplin-CLI 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: Philipp Zumstein <zuphilip@gmail.com>\n"
"Last-Translator: Michael Sonntag <ms@editorei.de>\n"
"Language-Team: \n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.7\n"
"X-Generator: Poedit 2.1.1\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "To delete a tag, untag the associated notes."
msgstr ""
"Um eine Markierung zu löschen, entferne diese bei allen damit verbundenen "
"Notizen."
"Um ein Tag zu löschen, entferne es bei allen damit verbundenen Notizen."
msgid "Please select the note or notebook to be deleted first."
msgstr ""
@@ -53,7 +52,7 @@ msgid "y"
msgstr "j"
msgid "Cancelling background synchronisation... Please wait."
msgstr "Breche Hintergrund-Synchronisation ab... Bitte warten."
msgstr "Breche Hintergrundsynchronisation ab Bitte warten."
#, javascript-format
msgid "No such command: %s"
@@ -197,8 +196,8 @@ msgid ""
"Exports Joplin data to the given path. By default, it will export the "
"complete database including notebooks, notes, tags and resources."
msgstr ""
"Exportiert Joplin Dateien in den angegebenen Pfad. Standardmäßig wird die "
"komplette Datenbank inklusive Notizbüchern, Notizen, Markierungen und "
"Exportiert Joplin-Dateien in den angegebenen Pfad. Standardmäßig wird die "
"komplette Datenbank inklusive Notizbüchern, Notizen, Schlagwörtern und "
"Anhängen exportiert."
#, javascript-format
@@ -306,7 +305,7 @@ msgstr "Anhänge: %d."
#, javascript-format
msgid "Tagged: %d."
msgstr "Markiert: %d."
msgstr "Verschlagwortet: %d."
msgid "Importing notes..."
msgstr "Importiere Notizen..."
@@ -472,18 +471,21 @@ msgstr "Kann Synchronisierer nicht initialisieren."
msgid "Starting synchronisation..."
msgstr "Starte Synchronisation..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Abbrechen… Bitte warten."
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> kann \"add\", \"remove\" or \"list\" sein, um eine "
"[Markierung] zu [Notiz] zuzuweisen oder zu entfernen, oder um mit "
"[Markierung] markierte Notizen anzuzeigen. Mit dem Befehl `tag list` können "
"alle Markierungen angezeigt werden."
"<tag-command> kann add“, „remove“ oder „list sein um [tag] zu [note] "
"hinzuzufügen oder zu entfernen, oder um die Notizen aufzulisten die [tag] "
"zugeordnet sind. Der Befehl `tag list` kann benutzt werden, um alle "
"Schlagwörter anzuzeigen (nutze -l für die lange Option)."
#, javascript-format
msgid "Invalid command: \"%s\""
@@ -643,15 +645,28 @@ msgstr "Ausschneiden"
msgid "Paste"
msgstr "Einfügen"
msgid "Select all"
msgstr "Alle auswählen"
msgid "Bold"
msgstr ""
msgstr "Fett"
msgid "Italic"
msgstr ""
msgstr "Kursiv"
msgid "Insert Date Time"
msgstr "Datum / Uhrzeit einfügen"
msgid "Edit in external editor"
msgstr "Im externen Editor bearbeiten"
msgid "Search in all the notes"
msgstr "Alle Notizen durchsuchen"
#, fuzzy
msgid "Search in current note"
msgstr "Alle Notizen durchsuchen"
msgid "View"
msgstr "Ansicht"
@@ -659,7 +674,7 @@ msgid "Toggle sidebar"
msgstr "Seitenleiste ein/aus"
msgid "Toggle editor layout"
msgstr "Editor Layout umschalten"
msgstr "Editor-Layout umschalten"
msgid "Tools"
msgstr "Werkzeuge"
@@ -668,7 +683,7 @@ msgid "Synchronisation status"
msgstr "Status der Synchronisation"
msgid "Web clipper options"
msgstr "Web Clipper Optionen"
msgstr "Web-Clipper Optionen"
msgid "Encryption options"
msgstr "Verschlüsselungsoptionen"
@@ -686,7 +701,7 @@ msgid "Make a donation"
msgstr "Spenden"
msgid "Check for updates..."
msgstr "Überprüfe auf Updates..."
msgstr "Überprüfe auf Updates"
msgid "About Joplin"
msgstr "Über Joplin"
@@ -712,7 +727,7 @@ msgid "Current version is up-to-date."
msgstr "Die aktuelle Version ist up-to-date."
msgid "An update is available, do you want to download it now?"
msgstr "Es ist ein Update verfügbar! Soll dies jetzt heruntergeladen werden?"
msgstr "Es ist ein Update verfügbar. Soll es jetzt heruntergeladen werden?"
msgid "Yes"
msgstr "Ja"
@@ -720,10 +735,12 @@ msgstr "Ja"
msgid "No"
msgstr "Nein"
#, fuzzy
msgid "Token has been copied to the clipboard!"
msgstr "Token wurde in die Zwischenablage kopiert."
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
"Der Web Clipper Service ist bereits aktiviert und auf Autostart eingestellt."
"Der Web-Clipper-Service ist bereits aktiviert und auf Autostart eingestellt."
#, javascript-format
msgid "Status: Started on port %d"
@@ -734,26 +751,26 @@ msgid "Status: %s"
msgstr "Status: %s"
msgid "Disable Web Clipper Service"
msgstr "Web Clipper Service deaktivieren"
msgstr "Web-Clipper-Service deaktivieren"
msgid "The web clipper service is not enabled."
msgstr "Der Web Clipper Service ist nicht aktiviert."
msgstr "Der Web-Clipper-Service ist nicht aktiviert."
msgid "Enable Web Clipper Service"
msgstr "Web Clipper Service aktivieren"
msgstr "Web-Clipper-Service aktivieren"
msgid ""
"Joplin Web Clipper allows saving web pages and screenshots from your browser "
"to Joplin."
msgstr ""
"Joplin Web Clipper erlaubt im Browser das Speichern von Webseiten und "
"Joplin Web-Clipper erlaubt im Browser das Speichern von Webseiten und "
"Screenshots nach Joplin."
msgid "In order to use the web clipper, you need to do the following:"
msgstr "Um den Web Clipper zu benutzen, musst du folgendes machen:"
msgstr "Um den Web-Clipper zu benutzen, musst du folgendes machen:"
msgid "Step 1: Enable the clipper service"
msgstr "Schritt 1: Clipper Service aktivieren"
msgstr "Schritt 1: Clipper-Service aktivieren"
msgid ""
"This service allows the browser extension to communicate with Joplin. When "
@@ -762,7 +779,7 @@ msgid ""
msgstr ""
"Dieser Service erlaubt es der Browser-Erweiterung mit Joplin zu "
"kommunizieren. Beim Aktivieren kann deine Firewall dich nach der Erlaubnis "
"bitten, dass Joplin auf einen bestimmten Port mithört."
"bitten, dass Joplin auf einen bestimmten Port mithören darf."
msgid "Step 2: Install the extension"
msgstr "Schritt 2: Erweiterung installieren"
@@ -772,6 +789,22 @@ msgstr ""
"Lade die entsprechende Erweiterung für deinen Browser herunter und "
"installiere sie:"
msgid "Advanced options"
msgstr "Erweiterte Optionen"
msgid "Authorisation token:"
msgstr "Autorisierung-Token:"
msgid "Copy token"
msgstr "Token kopieren"
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
"Dieses Autorisierung-Token wird nur benötigt, um Drittanbieter-Anwendungen "
"Zugriff auf Joplin zu gewähren."
msgid "Check synchronisation configuration"
msgstr "Überprüfen der Synchronisationseinstellungen"
@@ -779,12 +812,15 @@ msgstr "Überprüfen der Synchronisationseinstellungen"
msgid "Notes and settings are stored in: %s"
msgstr "Notizen und Einstellungen werden gespeichert in: %s"
msgid "Save"
msgstr "Speichern"
msgid "Apply"
msgstr "Anwenden"
msgid "Submit"
msgstr "Absenden"
msgid "Save"
msgstr "Speichern"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -847,13 +883,14 @@ msgstr ""
"Notizbücher ursprünglich verschlüsselt wurden."
msgid "Missing Master Keys"
msgstr "Fehlender Master-Key"
msgstr "Fehlender Hauptschlüssel"
msgid ""
"The master keys with these IDs are used to encrypt some of your items, "
"however the application does not currently have access to them. It is likely "
"they will eventually be downloaded via synchronisation."
msgstr "Die Master-Keas dieser IDs werden für die Verschlüsselung einiger ..."
msgstr ""
"Die Hauptschlüssel dieser IDs werden für die Verschlüsselung einiger ..."
msgid ""
"For more information about End-To-End Encryption (E2EE) and advices on how "
@@ -885,19 +922,19 @@ msgid "Please create a notebook first"
msgstr "Bitte erstelle zuerst ein Notizbuch"
msgid "Notebook title:"
msgstr "Notizbuch Titel:"
msgstr "Notizbuch-Titel:"
msgid "Add or remove tags:"
msgstr "Füge hinzu oder entferne Markierungen:"
msgstr "Schlagwörter hinzufügen oder entfernen:"
msgid "Separate each tag by a comma."
msgstr "Trenne jede Markierung mit einem Komma."
msgstr "Trenne jedes Schlagwort mit einem Komma."
msgid "Rename notebook:"
msgstr "Notizbuch umbenennen:"
msgid "Rename tag:"
msgstr "Markierung umbenennen:"
msgstr "Schlagwort umbenennen:"
msgid "Set alarm:"
msgstr "Alarm erstellen:"
@@ -921,11 +958,24 @@ msgid "Set the password"
msgstr "Setze ein Passwort"
msgid "Add or remove tags"
msgstr "Markierungen hinzufügen oder entfernen"
msgstr "Schlagwörter hinzufügen oder entfernen"
msgid "Duplicate"
msgstr "Duplizieren"
#, javascript-format
msgid "%s - Copy"
msgstr "%s kopieren"
msgid "Switch between note and to-do type"
msgstr "Zwischen Notiz und To-Do Typ wechseln"
msgid "Switch to note type"
msgstr "Zu Notiz-Typ wechseln"
msgid "Switch to to-do type"
msgstr "Zu To-Do-Typ wechseln"
msgid "Copy Markdown link"
msgstr "Markdown-Link kopieren"
@@ -937,8 +987,7 @@ msgstr "Notizen löschen?"
msgid "No notes in here. Create one by clicking on \"New note\"."
msgstr ""
"Hier sind noch keine Notizen. Erstelle eine, indem du auf \"Neue Notiz\" "
"drückst."
"Keine Notizen vorhanden. Erstelle eine, indem du auf \"Neue Notiz\" drückst."
msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
@@ -946,19 +995,35 @@ msgstr ""
"Momentan existieren noch keine Notizbücher. Erstelle eines, indem du auf "
"\"Neues Notizbuch\" drückst."
# Please note: The term 'Location' is assumed to be the geographical location where the note has been created. For this the german word 'Standort' fits better than the previously used 'Ablageort'. The latter one is used for the folder where files are stored.
msgid "Location"
msgstr "Standort"
msgid "URL"
msgstr "URL"
msgid "Note properties"
msgstr "Notiz-Eigenschaften"
msgid "Open..."
msgstr "Öffne..."
#, fuzzy, javascript-format
#, javascript-format
msgid "This file could not be opened: %s"
msgstr "Dieses Notizbuch konnte nicht gespeichert werden: %s"
msgstr "Dieses Notizbuch konnte nicht geöffnet werden: %s"
msgid "Save as..."
msgstr "Sichern unter..."
msgstr "Speichern unter..."
msgid "Copy path to clipboard"
msgstr "Pfad in Zwischenablage kopieren"
msgid "Copy Link Address"
msgstr "Link-Adresse kopieren"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nicht unterstützter Link oder Nachricht: %s"
@@ -972,47 +1037,56 @@ msgstr ""
"und die Notiz zu bearbeiten."
msgid "strong text"
msgstr ""
msgstr "Fetter Text"
msgid "emphasized text"
msgstr ""
msgstr "hervorgehobener Text"
msgid "List item"
msgstr "Listeneintrag"
msgid "Insert Hyperlink"
msgstr ""
msgstr "Weblink einfügen"
msgid "Attach file"
msgstr "Datei anhängen"
msgid "Tags"
msgstr "Markierungen"
msgstr "Schlagwörter"
msgid "Set alarm"
msgstr "Alarm erstellen"
#, fuzzy, javascript-format
#, javascript-format
msgid "In: %s"
msgstr "%s: %s"
msgstr "In: %s"
msgid "Hyperlink"
msgstr ""
msgstr "Weblink"
msgid "Code"
msgstr ""
msgstr "Code"
msgid "Numbered List"
msgstr ""
msgstr "Nummerierte Liste"
msgid "Bulleted List"
msgstr ""
msgstr "Aufzählung"
msgid "Checkbox"
msgstr ""
msgstr "Kontrollkästchen"
msgid "Heading"
msgstr ""
msgstr "Überschrift"
msgid "Horizontal Rule"
msgstr ""
msgstr "Horizontale Linie"
msgid "Click to stop external editing"
msgstr "Klicken Sie hier, um die externe Bearbeitung anzuhalten"
msgid "Watching..."
msgstr "Zuschauend…"
msgid "to-do"
msgstr "To-Do"
@@ -1031,25 +1105,25 @@ msgid "Clear"
msgstr "Leeren"
msgid "OneDrive Login"
msgstr "OneDrive Anmeldung"
msgstr "OneDrive-Anmeldung"
msgid "Dropbox Login"
msgstr "Dropbox Anmeldung"
msgstr "Dropbox-Anmeldung"
msgid "Options"
msgstr "Optionen"
msgid "Synchronisation Status"
msgstr "Synchronisations Status"
msgstr "Synchronisations-Status"
msgid "Encryption Options"
msgstr "Verschlüsselungsoptionen"
msgid "Clipper Options"
msgstr "Clipper Einstellungen"
msgstr "Clipper-Einstellungen"
msgid "Remove this tag from all the notes?"
msgstr "Diese Markierung von allen Notizen entfernen?"
msgstr "Dieses Schlagwort von allen Notizen entfernen?"
msgid "Remove this search from the sidebar?"
msgstr "Diese Suche von der Seitenleiste entfernen?"
@@ -1063,9 +1137,17 @@ msgstr "Synchronisieren"
msgid "Notebooks"
msgstr "Notizbücher"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Entschlüsselte Objekte: %d/%d"
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Anhänge: %d."
msgid "Please select where the sync status should be exported to"
msgstr ""
"Bitte wähle aus, wohin der Synchronisations Status exportiert werden soll"
"Bitte wähle aus, wohin der Synchronisations-Status exportiert werden soll"
#, javascript-format
msgid "Usage: %s"
@@ -1095,11 +1177,11 @@ msgstr "WebDAV"
#, javascript-format
msgid "Unknown log level: %s"
msgstr "Unbekanntes Log Level: %s"
msgstr "Unbekanntes Log-Level: %s"
#, javascript-format
msgid "Unknown level ID: %s"
msgstr "Unbekannte Level ID: %s"
msgstr "Unbekannte Level-ID: %s"
msgid ""
"Cannot refresh token: authentication data is missing. Starting the "
@@ -1108,6 +1190,9 @@ msgstr ""
"Kann Token nicht erneuern: Authentifikationsdaten nicht vorhanden. Ein "
"Neustart der Synchronisation könnte das Problem beheben."
msgid "Untitled"
msgstr "Unbenannt"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1121,7 +1206,7 @@ msgstr ""
"Dieser Fehler kommt oft vor, wenn OneDrive Business benutzt wird, das leider "
"nicht unterstützt wird.\n"
"\n"
"Bitte benutze stattdessen einen normalen OneDrive Account."
"Bitte benutze stattdessen einen normalen OneDrive-Account."
#, javascript-format
msgid "Cannot access %s"
@@ -1137,11 +1222,11 @@ msgstr "Lokale Objekte aktualisiert: %d."
#, javascript-format
msgid "Created remote items: %d."
msgstr "Remote Objekte erstellt: %d."
msgstr "Remote-Objekte erstellt: %d."
#, javascript-format
msgid "Updated remote items: %d."
msgstr "Remote Objekte aktualisiert: %d."
msgstr "Remote-Objekte aktualisiert: %d."
#, javascript-format
msgid "Deleted local items: %d."
@@ -1149,18 +1234,14 @@ msgstr "Lokale Objekte gelöscht: %d."
#, javascript-format
msgid "Deleted remote items: %d."
msgstr "Remote Objekte gelöscht: %d."
msgstr "Remote-Objekte gelöscht: %d."
#, javascript-format
msgid "Fetched items: %d/%d."
msgstr "Geladene Objekte: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Status: %s."
msgid "Cancelling..."
msgstr "Abbrechen..."
msgstr "Breche ab…"
#, javascript-format
msgid "Completed: %s"
@@ -1171,7 +1252,7 @@ msgid "Last error: %s"
msgstr "Letzte Fehlermeldung: %s"
msgid "Idle"
msgstr "wartend"
msgstr "Wartend"
msgid "In progress"
msgstr "In Bearbeitung"
@@ -1192,29 +1273,19 @@ msgstr "Konflikte"
msgid "Cannot move notebook to this location"
msgstr "Kann Notizbuch nicht an diesen Ort verschieben"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Ein Notizbuch mit diesem Titel existiert bereits : \"%s\""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr ""
"Notizbuch kann nicht \"%s\" genannt werden. Dies ist ein reservierter Titel."
"Notizbuch kann nicht \"%s\" genannt werden. Dieser Name ist reserviert.."
#, fuzzy
msgid "title"
msgstr "Unbenannt"
msgstr "Titel"
#, fuzzy
msgid "updated date"
msgstr "Aktualisiert: %d."
msgstr "Aktualisierungsdatum"
#, fuzzy
msgid "created date"
msgstr "Erstellt: %d."
msgid "Untitled"
msgstr "Unbenannt"
msgstr "Erstelldatum"
msgid "This note does not have geolocation information."
msgstr "Diese Notiz hat keine Standort-Informationen."
@@ -1227,17 +1298,6 @@ msgstr "Kann Notiz nicht zu Notizbuch \"%s\" kopieren"
msgid "Cannot move note to \"%s\" notebook"
msgstr "Kann Notiz nicht zu Notizbuch \"%s\" verschieben"
msgid "Text editor"
msgstr "Textverarbeitungsprogramm"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Das Textverarbeitungsprogramm, mit dem Notizen geöffnet werden. Wenn keines "
"ausgewählt wurde, wird Joplin versuchen das standard-"
"Textverarbeitungsprogramm zu erkennen."
msgid "Language"
msgstr "Sprache"
@@ -1260,7 +1320,7 @@ msgid "Uncompleted to-dos on top"
msgstr "Zeige unvollständige To-Dos an oberster Stelle"
msgid "Show completed to-dos"
msgstr "Abgeschlossene ToDos anzeigen"
msgstr "Abgeschlossene To-Dos anzeigen"
msgid "Sort notes by"
msgstr "Sortiere Notizen nach"
@@ -1284,14 +1344,27 @@ msgid "When creating a new note:"
msgstr "Wenn eine neue Notiz erstellt wird:"
msgid "Show tray icon"
msgstr "Zeige Tray Icon"
msgstr "Zeige Tray-Icon"
msgid "Note: Does not work in all desktop environments."
msgstr "Hinweis: Funktioniert nicht in allen Desktopumgebungen."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr "Starte die Anwendung minimiert im Tray"
msgid "Global zoom percentage"
msgstr "Zoomstufe der Benutzeroberfläche"
#, fuzzy
msgid "Editor font size"
msgstr "Editor Schriftenfamilie"
msgid "Editor font family"
msgstr "Editor Schriftenfamilie"
@@ -1321,6 +1394,16 @@ msgstr "%d Stunde"
msgid "%d hours"
msgstr "%d Stunden"
msgid "Text editor command"
msgstr "Editoraufruf"
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Der Editor, mit dem Notizen geöffnet werden. Wenn keiner ausgewählt wurde, "
"wird Joplin versuchen den Standardeditor zu erkennen."
msgid "Show advanced options"
msgstr "Erweiterte Optionen anzeigen"
@@ -1336,7 +1419,7 @@ msgstr ""
"dokumentiert) bezeichnet werden."
msgid "Directory to synchronise with (absolute path)"
msgstr "Verzeichnis zum synchronisieren (absoluter Pfad)"
msgstr "Verzeichnis mit dem synchronisiert werden soll (absoluter Pfad)"
msgid ""
"The path to synchronise with when file system synchronisation is enabled. "
@@ -1346,27 +1429,60 @@ msgstr ""
"Synchronisation aktiviert ist. Siehe `sync.target`."
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV-URL"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
"Achtung: Stelle sicher, dass Du vor der Synchronisation alle Inhalte an den "
"neuen Ablageort kopiert hast, sonst werden alle Dateien gelöscht! Lies auch "
"die FAQs hierzu: %s"
msgid "Nextcloud username"
msgstr "Nextcloud Benutzername"
msgstr "Nextcloud-Benutzername"
msgid "Nextcloud password"
msgstr "Nextcloud Passwort"
msgstr "Nextcloud-Passwort"
msgid "WebDAV URL"
msgstr "WebDAV URL"
msgstr "WebDAV-URL"
msgid "WebDAV username"
msgstr "WebDAV Benutzername"
msgstr "WebDAV-Benutzername"
msgid "WebDAV password"
msgstr "WebDAV Passwort"
msgstr "WebDAV-Passwort"
msgid "Custom TLS certificates"
msgstr "Benutzerdefinierte TLS-Zertifikate"
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
"Kommagetrennte Liste von Pfaden zu Verzeichnissen, aus denen die Zertifikate "
"geladen werden, oder Pfad zu einzelnen Zertifikatsdateien. Zum Beispiel: /my/"
"cert_dir, /other/custom.pem. Wenn Sie Änderungen an den TLS-Einstellungen "
"vornehmen, müssen Sie Ihre Änderungen speichern, bevor Sie auf "
"\"Synchronisierungskonfiguration prüfen\" klicken."
msgid "Ignore TLS certificate errors"
msgstr "Ignoriere TLS-Zertifikatfehler"
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Ungültiger Optionswert: \"%s\". Mögliche Werte sind: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
"Das Schlagwort \"%s\" existiert bereits. Bitte wähle einen anderen Namen."
msgid "Joplin Export File"
msgstr "Joplin Export Datei"
@@ -1379,12 +1495,16 @@ msgstr "Joplin Export Verzeichnis"
msgid "Evernote Export File"
msgstr "Evernote Export Datei"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin Export Verzeichnis"
msgid "Directory"
msgstr "Verzeichnis"
#, javascript-format
msgid "Cannot load \"%s\" module for format \"%s\""
msgstr "Das Modul „%s“ für das Format „%s“ kann nicht geladen werden"
msgstr "Das Modul \"%s\" für das Format \"%s\" kann nicht geladen werden"
#, javascript-format
msgid "Please specify import format for %s"
@@ -1454,6 +1574,12 @@ msgstr "Anstehende Alarme"
msgid "On %s: %s"
msgstr "Auf %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Momentan existieren noch keine Notizen. Erstelle eine, indem du auf den (+) "
@@ -1484,6 +1610,9 @@ msgstr "%d Notizen in das Notizbuch \"%s\" verschieben?"
msgid "Press to set the decryption password."
msgstr "Tippe hier, um das Entschlüsselungspasswort festzulegen."
msgid "Clear alarm"
msgstr "Alarm löschen"
msgid "Save alarm"
msgstr "Alarm speichern"
@@ -1496,15 +1625,46 @@ msgstr "Bestätigen"
msgid "Cancel synchronisation"
msgstr "Synchronisation abbrechen"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Geladene Objekte: %d/%d."
msgid "Checking... Please wait."
msgstr "Überprüfe… Bitte warten."
msgid "Success! Synchronisation configuration appears to be correct."
msgstr ""
"Erfolgreich. Die Synchronisation-Konfiguration scheint korrekt zu sein."
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
"Fehler. Bitte überprüfe, ob die URL, der Benutzername, das Passwort. usw. "
"korrekt sind und das das Synchronisierungsziel erreichbar ist. Fehlermeldung:"
msgid "The application has been authorised!"
msgstr "Das Programm wurde erfolgreich autorisiert."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
"Konnte Applikation nicht autorisieren:\n"
"\n"
"%s\n"
"\n"
"Bitte versuche es erneut."
#, javascript-format
msgid "Decrypted items: %s / %s"
msgstr "Entschlüsselte Objekte: %s / %s"
msgid "New tags:"
msgstr "Neue Markierungen:"
msgstr "Neue Schlagwörter:"
msgid "Type new tags or select from list"
msgstr "Neue Markierungen eingeben oder aus der Liste auswählen"
msgstr "Neues Schlagwort eingeben oder aus der Liste auswählen"
msgid ""
"To work correctly, the app needs the following permissions. Please enable "
@@ -1586,6 +1746,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nicht unterstütztes Fotoformat: %s"
#, fuzzy
msgid "Take photo"
msgstr "Foto anhängen"
msgid "Attach photo"
msgstr "Foto anhängen"
@@ -1610,6 +1774,9 @@ msgstr "Metadaten anzeigen"
msgid "View on map"
msgstr "Auf der Karte anzeigen"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Notizbuch löschen"
@@ -1623,18 +1790,24 @@ msgid ""
"Click on the (+) button to create a new note or notebook. Click on the side "
"menu to access your existing notebooks."
msgstr ""
"Drücke auf den (+) Knopf, um eine neue Notiz oder ein neues Notizbuch zu "
"erstellen. Tippe auf die Seitenleiste, um auf deine existierenden "
"Drücke auf die (+)-Schaltfläche, um eine neue Notiz oder ein neues Notizbuch "
"zu erstellen. Tippe auf die Seitenleiste, um auf deine existierenden "
"Notizbücher zuzugreifen."
msgid "You currently have no notebook. Create one by clicking on (+) button."
msgstr ""
"Du hast noch kein Notizbuch. Erstelle eines, indem du auf den (+) Knopf "
"drückst."
"Du hast noch kein Notizbuch angelegt. Erstelle eines, indem du auf den (+) "
"Knopf drückst."
msgid "Welcome"
msgstr "Willkommen"
#~ msgid "State: %s."
#~ msgstr "Status: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Ein Notizbuch mit diesem Titel existiert bereits : \"%s\""
#~ msgid "Searches"
#~ msgstr "Suchen"

View File

@@ -408,13 +408,16 @@ msgstr ""
msgid "Starting synchronisation..."
msgstr ""
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr ""
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
#, javascript-format
@@ -552,15 +555,27 @@ msgstr ""
msgid "Paste"
msgstr ""
msgid "Select all"
msgstr ""
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr ""
msgid "Search in current note"
msgstr ""
msgid "View"
msgstr ""
@@ -629,6 +644,9 @@ msgstr ""
msgid "No"
msgstr ""
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -672,6 +690,20 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
msgid "Advanced options"
msgstr ""
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr ""
@@ -679,12 +711,15 @@ msgstr ""
msgid "Notes and settings are stored in: %s"
msgstr ""
msgid "Save"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr ""
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -807,9 +842,22 @@ msgstr ""
msgid "Add or remove tags"
msgstr ""
msgid "Duplicate"
msgstr ""
#, javascript-format
msgid "%s - Copy"
msgstr ""
msgid "Switch between note and to-do type"
msgstr ""
msgid "Switch to note type"
msgstr ""
msgid "Switch to to-do type"
msgstr ""
msgid "Copy Markdown link"
msgstr ""
@@ -826,6 +874,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr ""
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -839,6 +896,12 @@ msgstr ""
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr ""
@@ -855,6 +918,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -892,6 +958,12 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
msgid "Watching..."
msgstr ""
msgid "to-do"
msgstr ""
@@ -941,6 +1013,14 @@ msgstr ""
msgid "Notebooks"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr ""
#, javascript-format
msgid "Fetching resources: %d"
msgstr ""
msgid "Please select where the sync status should be exported to"
msgstr ""
@@ -983,6 +1063,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr ""
msgid "Untitled"
msgstr ""
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1024,10 +1107,6 @@ msgstr ""
msgid "Fetched items: %d/%d."
msgstr ""
#, javascript-format
msgid "State: %s."
msgstr ""
msgid "Cancelling..."
msgstr ""
@@ -1061,10 +1140,6 @@ msgstr ""
msgid "Cannot move notebook to this location"
msgstr ""
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr ""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr ""
@@ -1078,9 +1153,6 @@ msgstr ""
msgid "created date"
msgstr ""
msgid "Untitled"
msgstr ""
msgid "This note does not have geolocation information."
msgstr ""
@@ -1092,14 +1164,6 @@ msgstr ""
msgid "Cannot move note to \"%s\" notebook"
msgstr ""
msgid "Text editor"
msgstr ""
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
msgid "Language"
msgstr ""
@@ -1151,9 +1215,21 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
msgid "Editor font size"
msgstr ""
msgid "Editor font family"
msgstr ""
@@ -1180,6 +1256,14 @@ msgstr ""
msgid "%d hours"
msgstr ""
msgid "Text editor command"
msgstr ""
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
msgid "Show advanced options"
msgstr ""
@@ -1202,6 +1286,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr ""
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr ""
@@ -1217,10 +1308,27 @@ msgstr ""
msgid "WebDAV password"
msgstr ""
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr ""
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr ""
@@ -1233,6 +1341,9 @@ msgstr ""
msgid "Evernote Export File"
msgstr ""
msgid "Json Export Directory"
msgstr ""
msgid "Directory"
msgstr ""
@@ -1302,6 +1413,12 @@ msgstr ""
msgid "On %s: %s"
msgstr ""
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
@@ -1330,6 +1447,9 @@ msgstr ""
msgid "Press to set the decryption password."
msgstr ""
msgid "Clear alarm"
msgstr ""
msgid "Save alarm"
msgstr ""
@@ -1342,8 +1462,31 @@ msgstr ""
msgid "Cancel synchronisation"
msgstr ""
msgid "Checking... Please wait."
msgstr ""
msgid "Success! Synchronisation configuration appears to be correct."
msgstr ""
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
msgid "The application has been authorised!"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, javascript-format
msgid "Decrypted items: %s / %s"
msgstr ""
msgid "New tags:"
@@ -1425,6 +1568,9 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr ""
msgid "Take photo"
msgstr ""
msgid "Attach photo"
msgstr ""
@@ -1449,6 +1595,9 @@ msgstr ""
msgid "View on map"
msgstr ""
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr ""

View File

@@ -457,13 +457,17 @@ msgstr "No se puede inicializar sincronizador."
msgid "Starting synchronisation..."
msgstr "Iniciando sincronización..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Cancelando... Por favor espere."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> puede ser \"add\", \"remove\" o \"list\" para asignar o "
"eliminar [tag] de [note], o para listar las notas asociadas con [tag]. El "
@@ -628,15 +632,29 @@ msgstr "Cortar"
msgid "Paste"
msgstr "Pegar"
#, fuzzy
msgid "Select all"
msgstr "Seleccione fecha"
msgid "Bold"
msgstr ""
msgstr "Negrita"
msgid "Italic"
msgstr ""
msgstr "Cursiva"
msgid "Insert Date Time"
msgstr "Introduce fecha"
msgid "Edit in external editor"
msgstr "Editar con un editor externo"
msgid "Search in all the notes"
msgstr "Buscar en todas las notas"
#, fuzzy
msgid "Search in current note"
msgstr "Buscar en todas las notas"
msgid "View"
msgstr "Ver"
@@ -705,11 +723,13 @@ msgstr "Sí"
msgid "No"
msgstr "No"
#, fuzzy
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
"El servicio de recorte web está habilitado y configurado para inicie "
"automaticamente"
"El servicio de recorte web está habilitado y configurado para que inicie "
"automáticamente."
#, javascript-format
msgid "Status: Started on port %d"
@@ -756,6 +776,21 @@ msgstr "Paso 2: Instalar la extensión"
msgid "Download and install the relevant extension for your browser:"
msgstr "Descargar e instalar para su navegador:"
#, fuzzy
msgid "Advanced options"
msgstr "Mostrar opciones avanzadas"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr "Comprobar sincronización"
@@ -763,12 +798,15 @@ msgstr "Comprobar sincronización"
msgid "Notes and settings are stored in: %s"
msgstr "Las notas y los ajustes se guardan en: %s"
msgid "Save"
msgstr "Guardar"
msgid "Apply"
msgstr "Aplicar"
msgid "Submit"
msgstr "Aceptar"
msgid "Save"
msgstr "Guardar"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -906,9 +944,24 @@ msgstr "Establecer la contraseña"
msgid "Add or remove tags"
msgstr "Añadir o borrar etiquetas"
msgid "Duplicate"
msgstr "Duplicado"
#, javascript-format
msgid "%s - Copy"
msgstr "%s - Copiar"
msgid "Switch between note and to-do type"
msgstr "Cambiar entre nota y lista de tareas"
#, fuzzy
msgid "Switch to note type"
msgstr "Cambiar entre nota y lista de tareas"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Cambiar entre nota y lista de tareas"
msgid "Copy Markdown link"
msgstr "Copiar el enlace de Markdown"
@@ -925,12 +978,21 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "No hay ninguna libreta. Cree una pulsando en «Libreta nueva»."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Abrir..."
#, fuzzy, javascript-format
#, javascript-format
msgid "This file could not be opened: %s"
msgstr "No se ha podido guardar esta libreta: %s"
msgstr "No se ha podido abrir este archivo: %s"
msgid "Save as..."
msgstr "Guardar como..."
@@ -938,6 +1000,12 @@ msgstr "Guardar como..."
msgid "Copy path to clipboard"
msgstr "Copiar la ruta en el portapapeles"
msgid "Copy Link Address"
msgstr "Copiar enlace"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Enlace o mensaje no soportado: %s"
@@ -951,13 +1019,16 @@ msgstr ""
"editar la nota."
msgid "strong text"
msgstr ""
msgstr "texto destacado"
msgid "emphasized text"
msgstr ""
msgstr "texto resaltado"
msgid "List item"
msgstr "Listar elementos"
msgid "Insert Hyperlink"
msgstr ""
msgstr "Insertar hipervínculo"
msgid "Attach file"
msgstr "Adjuntar archivo"
@@ -968,30 +1039,36 @@ msgstr "Etiquetas"
msgid "Set alarm"
msgstr "Establecer alarma"
#, fuzzy, javascript-format
#, javascript-format
msgid "In: %s"
msgstr "%s: %s"
msgstr "En: %s"
msgid "Hyperlink"
msgstr ""
msgstr "Hipervínculo"
msgid "Code"
msgstr ""
msgstr "Código"
msgid "Numbered List"
msgstr ""
msgstr "Lista numerada"
msgid "Bulleted List"
msgstr ""
msgstr "Lista con viñetas"
msgid "Checkbox"
msgstr ""
msgstr "Casilla"
msgid "Heading"
msgstr ""
msgstr "Título"
msgid "Horizontal Rule"
msgstr ""
msgstr "Regla horizontal"
msgid "Click to stop external editing"
msgstr "Pulsa para detener la edición externa"
msgid "Watching..."
msgstr "Mirando..."
msgid "to-do"
msgstr "lista de tareas"
@@ -1042,6 +1119,14 @@ msgstr "Sincronizar"
msgid "Notebooks"
msgstr "Libretas"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Descifrando elementos: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Recursos: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Seleccione a dónde se debería exportar el estado de sincronización"
@@ -1086,6 +1171,9 @@ msgstr ""
"No se ha podido actualizar token: faltan datos de autenticación. Reiniciar "
"la sincronización podría solucionar el problema."
msgid "Untitled"
msgstr "Sin título"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1133,10 +1221,6 @@ msgstr "Elementos remotos borrados: %d."
msgid "Fetched items: %d/%d."
msgstr "Elementos obtenidos: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estado: «%s»."
msgid "Cancelling..."
msgstr "Cancelando..."
@@ -1170,29 +1254,19 @@ msgstr "Conflictos"
msgid "Cannot move notebook to this location"
msgstr "No se puede mover la libreta a este lugar"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Ya existe una libreta con este nombre: «%s»"
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr ""
"No se puede usar el nombre «%s» para una libreta; es un título reservado."
#, fuzzy
msgid "title"
msgstr "Sin título"
msgstr "título"
#, fuzzy
msgid "updated date"
msgstr "Actualizado: %d."
msgstr "fecha de actualización"
#, fuzzy
msgid "created date"
msgstr "Creado: %d."
msgid "Untitled"
msgstr "Sin título"
msgstr "fecha de creación"
msgid "This note does not have geolocation information."
msgstr "Esta nota no tiene informacion de geolocalización."
@@ -1205,16 +1279,6 @@ msgstr "No se ha podido copiar la nota a la libreta «%s»"
msgid "Cannot move note to \"%s\" notebook"
msgstr "No se ha podido mover la nota a la libreta «%s»"
msgid "Text editor"
msgstr "Editor de texto"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"El editor que se usará para abrir una nota. Se intentará auto-detectar el "
"editor predeterminado si no se proporciona ninguno."
msgid "Language"
msgstr "Idioma"
@@ -1266,9 +1330,22 @@ msgstr "Mostrar icono en la bandeja"
msgid "Note: Does not work in all desktop environments."
msgstr "Nota: No funciona en todos los entornos de escritorio."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Establecer el porcentaje de aumento de la aplicación"
#, fuzzy
msgid "Editor font size"
msgstr "Fuente del editor"
msgid "Editor font family"
msgstr "Fuente del editor"
@@ -1298,6 +1375,17 @@ msgstr "%d hora"
msgid "%d hours"
msgstr "%d horas"
msgid "Text editor command"
msgstr "Editor de texto"
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"El comando del editor (puede incluir argumentos) que se utilizará para abrir "
"una nota. Si no se provee ninguno se intentará auto detectar el editor por "
"defecto."
msgid "Show advanced options"
msgstr "Mostrar opciones avanzadas"
@@ -1325,6 +1413,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Servidor WebDAV de Nextcloud"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Usuario de Nextcloud"
@@ -1340,10 +1435,32 @@ msgstr "Usuario de WebDAV"
msgid "WebDAV password"
msgstr "Contraseña de WebDAV"
msgid "Custom TLS certificates"
msgstr "Certificados TLS personalizados"
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
"Lista de rutas de los directorios de dónde cargar los certificados separados "
"por comas, o la ruta individual de los certificados. Por ejemplo: /mi/"
"cert_dir, /otro/personalizado.pem. Tenga en cuenta que si realiza cambios en "
"la configuración de los certificados debe guardar los cambios antes de "
"pulsar en \"Comprobar la configuración de sincronización\"."
msgid "Ignore TLS certificate errors"
msgstr "Ignorar errores en certificados TLS"
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Opción inválida: «%s». Los valores posibles son: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr "Archivo de exportación de Joplin"
@@ -1356,6 +1473,10 @@ msgstr "Directorio para exportar de Joplin"
msgid "Evernote Export File"
msgstr "Archivo exportado de Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Directorio para exportar de Joplin"
msgid "Directory"
msgstr "Directorio"
@@ -1430,6 +1551,12 @@ msgstr "Alarmas próximas"
msgid "On %s: %s"
msgstr "En %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "No hay notas. Cree una pulsando en el botón (+)."
@@ -1459,6 +1586,9 @@ msgid "Press to set the decryption password."
msgstr "Presione para establecer la contraseña de descifrado."
#, fuzzy
msgid "Clear alarm"
msgstr "Establecer alarma"
msgid "Save alarm"
msgstr "Establecer alarma"
@@ -1471,9 +1601,35 @@ msgstr "Confirmar"
msgid "Cancel synchronisation"
msgstr "Cancelar sincronización"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Cancelando... Por favor espere."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Comprobar sincronización"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "La aplicacion ha sido autorizada éxitosamente."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Elementos obtenidos: %d/%d."
msgid "Decrypted items: %s / %s"
msgstr "Descifrando elementos: %d/%d."
msgid "New tags:"
msgstr "Nuevas etiquetas:"
@@ -1562,6 +1718,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Tipo de imagen no soportado: %s"
#, fuzzy
msgid "Take photo"
msgstr "Adjuntar foto"
msgid "Attach photo"
msgstr "Adjuntar foto"
@@ -1586,6 +1746,9 @@ msgstr "Mostrar metadatos"
msgid "View on map"
msgstr "Ver en un mapa"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Borrar libreta"
@@ -1609,6 +1772,12 @@ msgstr ""
msgid "Welcome"
msgstr "Bienvenido"
#~ msgid "State: %s."
#~ msgstr "Estado: «%s»."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Ya existe una libreta con este nombre: «%s»"
#~ msgid ""
#~ "For more information about End-To-End Encryption (E2EE) and advices on "
#~ "how to enable it please check the documentation"

View File

@@ -455,13 +455,17 @@ msgstr "Ezin has daiteke sinkronizazio prozesua."
msgid "Starting synchronisation..."
msgstr "Sinkronizazioa hasten..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Bertan behera uzten... itxaron, mesedez."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> izan daiteke \"add\", \"remove\" edo \"list\" [oharra]tik "
"[etiketa] esleitu edo kentzeko, edo [etiketa]rekin elkartutako oharrak "
@@ -627,15 +631,29 @@ msgstr "Moztu"
msgid "Paste"
msgstr "Itsatsi"
#, fuzzy
msgid "Select all"
msgstr "Data aukeratu"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Bilatu ohar guztietan"
#, fuzzy
msgid "Search in current note"
msgstr "Bilatu ohar guztietan"
msgid "View"
msgstr ""
@@ -706,6 +724,9 @@ msgstr ""
msgid "No"
msgstr "E"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -749,6 +770,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Erakutsi aukera aurreratuak"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
#, fuzzy
msgid "Check synchronisation configuration"
msgstr "Sinkronizazioa utzi"
@@ -757,12 +793,15 @@ msgstr "Sinkronizazioa utzi"
msgid "Notes and settings are stored in: %s"
msgstr "Oharrak eta ezarpenak hemen daude gordeta: %s"
msgid "Save"
msgstr "Gorde"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr "Gorde"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -901,9 +940,24 @@ msgstr "Ezarri pasahitza"
msgid "Add or remove tags"
msgstr "Gehitu edo ezabatu etiketak"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Kopiatu"
msgid "Switch between note and to-do type"
msgstr "Aldatu oharra eta zeregin eren artean."
#, fuzzy
msgid "Switch to note type"
msgstr "Aldatu oharra eta zeregin eren artean."
#, fuzzy
msgid "Switch to to-do type"
msgstr "Aldatu oharra eta zeregin eren artean."
msgid "Copy Markdown link"
msgstr ""
@@ -920,6 +974,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "Momentuz ez dago koadernorik. Sortu bat \"Koaderno berria\" sakatuta."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -934,6 +997,12 @@ msgstr "Gorde aldaketak"
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Esteka edo mezu ez dago onartua: %s"
@@ -950,6 +1019,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -987,6 +1059,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "Bertan behera uzten..."
#, fuzzy
msgid "to-do"
msgstr "Zeregin berria"
@@ -1040,6 +1119,14 @@ msgstr "Sinkronizatu"
msgid "Notebooks"
msgstr "Koadernoak"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Itemak eskuratuta: %d%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Baliabideak: %d."
#, fuzzy
msgid "Please select where the sync status should be exported to"
msgstr "Aukeratu nora esportatu sinkronizazioaren egoera, mesedez"
@@ -1087,6 +1174,9 @@ msgstr ""
"Tokena ezin eguneratu daiteke: egiaztatze-datuak desagertuta daude. Agian, "
"berriro sinkronizatzeak arazoa konpon lezake."
msgid "Untitled"
msgstr "Titulu gabekoa"
#, fuzzy
msgid ""
"Could not synchronize with OneDrive.\n"
@@ -1133,10 +1223,6 @@ msgstr "Urruneko itemak ezabatuta: %d."
msgid "Fetched items: %d/%d."
msgstr "Itemak eskuratuta: %d%d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Egoera: \"%s\"."
msgid "Cancelling..."
msgstr "Bertan behera uzten..."
@@ -1171,10 +1257,6 @@ msgstr "Gatazkak"
msgid "Cannot move notebook to this location"
msgstr "Ezin eraman daiteke oharra \"%s\" koadernora"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Dagoeneko bada koaderno bat izen horrekin: \"%s\""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr ""
@@ -1192,9 +1274,6 @@ msgstr "Eguneratuta: %d."
msgid "created date"
msgstr "Sortuta: %d."
msgid "Untitled"
msgstr "Titulu gabekoa"
msgid "This note does not have geolocation information."
msgstr "Ohar honek ez du geokokapen informaziorik."
@@ -1206,16 +1285,6 @@ msgstr "Ezin kopia daiteke oharra \"%s\" koadernora"
msgid "Cannot move note to \"%s\" notebook"
msgstr "Ezin eraman daiteke oharra \"%s\" koadernora"
msgid "Text editor"
msgstr "Testu editorea"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Editorea erabiliko da oharra zabaltzeko. Ez badago zehaztutakorik lehenetsia "
"igartzen ahaleginduko da."
msgid "Language"
msgstr "Hizkuntza"
@@ -1272,10 +1341,23 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
#, fuzzy
msgid "Global zoom percentage"
msgstr "Ezarri aplikazioaren zoomaren ehunekoa"
#, fuzzy
msgid "Editor font size"
msgstr "Oharra editatu."
msgid "Editor font family"
msgstr ""
@@ -1302,6 +1384,18 @@ msgstr "% ordua"
msgid "%d hours"
msgstr "% orduak"
#, fuzzy
msgid "Text editor command"
msgstr "Testu editorea"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Editorea erabiliko da oharra zabaltzeko. Ez badago zehaztutakorik lehenetsia "
"igartzen ahaleginduko da."
msgid "Show advanced options"
msgstr "Erakutsi aukera aurreratuak"
@@ -1328,6 +1422,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV URL"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Nextcloud erabiltzaile-izena"
@@ -1346,10 +1447,27 @@ msgstr "Nextcloud erabiltzaile-izena"
msgid "WebDAV password"
msgstr "Ezarri pasahitza"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Balio aukera baliogabea: \"%s\". Litezkeen balioak: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
#, fuzzy
msgid "Joplin Export File"
msgstr "Evernotetik esportatutako fitxategiak"
@@ -1364,6 +1482,10 @@ msgstr ""
msgid "Evernote Export File"
msgstr "Evernotetik esportatutako fitxategiak"
#, fuzzy
msgid "Json Export Directory"
msgstr "Evernotetik esportatutako fitxategiak"
msgid "Directory"
msgstr ""
@@ -1436,6 +1558,12 @@ msgstr "Hurrengo alarmak"
msgid "On %s: %s"
msgstr "On %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Ez dago oharrik. Sortu bat (+) botoian klik eginaz."
@@ -1464,6 +1592,10 @@ msgstr "Mugitu %d oharrak \"%s\" koadernora?"
msgid "Press to set the decryption password."
msgstr "Sakatu deszifratze pasahitza ezartzeko."
#, fuzzy
msgid "Clear alarm"
msgstr "Ezarri alarma"
#, fuzzy
msgid "Save alarm"
msgstr "Ezarri alarma"
@@ -1477,8 +1609,34 @@ msgstr "Baieztatu"
msgid "Cancel synchronisation"
msgstr "Sinkronizazioa utzi"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Bertan behera uzten... itxaron, mesedez."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Sinkronizazioa utzi"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "Aplikazioak baimena hartu du."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Itemak eskuratuta: %d%d."
msgid "New tags:"
@@ -1561,6 +1719,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Irudi formatua ez onartua: %s"
#, fuzzy
msgid "Take photo"
msgstr "Argazkia erantsi"
msgid "Attach photo"
msgstr "Argazkia erantsi"
@@ -1585,6 +1747,9 @@ msgstr "Erakutsi metadatuak"
msgid "View on map"
msgstr "Ikusi mapan"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Ezabatu koadernoa"
@@ -1607,6 +1772,13 @@ msgstr "Oraindik ez duzu koadernorik. Sortu bat (+) botoian sakatuta."
msgid "Welcome"
msgstr "Ongi etorri!"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Egoera: \"%s\"."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Dagoeneko bada koaderno bat izen horrekin: \"%s\""
#~ msgid "Searches"
#~ msgstr "Bilaketak"

View File

@@ -59,7 +59,7 @@ msgstr ""
"La commande \"%s\" est disponible uniquement en mode d'interface graphique"
msgid "Cannot change encrypted item"
msgstr "Un objet crypté ne peut pas être modifié"
msgstr "Un objet chiffré ne peut pas être modifié"
#, javascript-format
msgid "Missing required argument: %s"
@@ -127,7 +127,7 @@ msgid ""
"Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`, "
"`status` and `target-status`."
msgstr ""
"Gérer la configuration E2EE (Cryptage de bout à bout). Les commandes sont "
"Gérer la configuration E2EE (Chiffrement de bout à bout). Les commandes sont "
"`enable`, `disable`, `decrypt` et `status` et `target-status`."
msgid "Enter master password:"
@@ -140,11 +140,11 @@ msgid ""
"Starting decryption... Please wait as it may take several minutes depending "
"on how much there is to decrypt."
msgstr ""
"Démarrage du décryptage... Veuillez patienter car cela pourrait prendre "
"plusieurs minutes selon le nombre d'objets à décrypter."
"Démarrage du déchiffrement... Veuillez patienter car cela pourrait prendre "
"plusieurs minutes selon le nombre d'objets à déchiffrer."
msgid "Completed decryption."
msgstr "Décryptage complété."
msgstr "Déchiffrement complété."
msgid "Enabled"
msgstr "Activé"
@@ -154,7 +154,7 @@ msgstr "Désactivé"
#, javascript-format
msgid "Encryption is: %s"
msgstr "Le cryptage est : %s"
msgstr "Le chiffrement est : %s"
msgid "Edit note."
msgstr "Éditer la note."
@@ -458,18 +458,21 @@ msgstr "Impossible d'initialiser la synchronisation."
msgid "Starting synchronisation..."
msgstr "Commencement de la synchronisation..."
msgid "Downloading resources..."
msgstr "Téléchargement des ressources..."
msgid "Cancelling... Please wait."
msgstr "Annulation... Veuillez attendre."
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> peut être \"add\", \"remove\" ou \"list\" pour assigner ou "
"enlever l'étiquette [tag] de la [note], our pour lister les notes associées "
"avec l'étiquette [tag]. La commande `tag list` peut être utilisée pour "
"lister les étiquettes."
"lister les étiquettes (utilisez l'option -l pour les options complètes)."
#, javascript-format
msgid "Invalid command: \"%s\""
@@ -571,10 +574,10 @@ msgid ""
"supplied the password, the encrypted items are being decrypted in the "
"background and will be available soon."
msgstr ""
"Au moins un objet est actuellement crypté et il se peut que vous deviez "
"Au moins un objet est actuellement chiffré et il se peut que vous deviez "
"fournir votre mot de passe maître. Pour se faire, veuillez taper `e2ee "
"decrypt`. Si vous avez déjà fourni ce mot de passe, les objets cryptés vont "
"être décrypté en tâche de fond et seront disponible prochainement."
"decrypt`. Si vous avez déjà fourni ce mot de passe, les objets chiffrés vont "
"être déchiffré en tâche de fond et seront disponible prochainement."
#, javascript-format
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
@@ -627,15 +630,27 @@ msgstr "Couper"
msgid "Paste"
msgstr "Coller"
msgid "Select all"
msgstr "Sélectionner tout"
msgid "Bold"
msgstr ""
msgstr "Gras"
msgid "Italic"
msgstr ""
msgstr "Italique"
msgid "Insert Date Time"
msgstr "Insérer la date et l'heure"
msgid "Edit in external editor"
msgstr "Ouvrir dans un éditeur externe"
msgid "Search in all the notes"
msgstr "Chercher dans toutes les notes"
msgid "Search in current note"
msgstr "Chercher dans la note en cours"
msgid "View"
msgstr "Affichage"
@@ -655,7 +670,7 @@ msgid "Web clipper options"
msgstr "Options du Web Clipper"
msgid "Encryption options"
msgstr "Options de cryptage"
msgstr "Options de chiffrement"
msgid "General Options"
msgstr "Options générales"
@@ -705,12 +720,15 @@ msgstr "Oui"
msgid "No"
msgstr "Non"
msgid "Token has been copied to the clipboard!"
msgstr "Le code d'authentification a été copié dans le presse-papiers !"
msgid "The web clipper service is enabled and set to auto-start."
msgstr "Le service du Web Clipper est activé et démarrera automatiquement."
#, javascript-format
msgid "Status: Started on port %d"
msgstr "État : Commencé sur le port %d"
msgstr "État : Démarré sur le port %d"
#, javascript-format
msgid "Status: %s"
@@ -729,8 +747,8 @@ msgid ""
"Joplin Web Clipper allows saving web pages and screenshots from your browser "
"to Joplin."
msgstr ""
"Le Web Clipper permet de sauver des pages web et des captures d'écran depuis "
"votre navigateur vers Joplin."
"Le Web Clipper permet d'enregistrer des pages web et des captures d'écran "
"depuis votre navigateur vers Joplin."
msgid "In order to use the web clipper, you need to do the following:"
msgstr "Pour utiliser le Web Clipper, veuillez suivre ces instructions :"
@@ -755,6 +773,22 @@ msgstr ""
"Téléchargez et installez le module complémentaire correspondant à votre "
"navigateur :"
msgid "Advanced options"
msgstr "Options avancées"
msgid "Authorisation token:"
msgstr "Code d'authentification :"
msgid "Copy token"
msgstr "Copier le code"
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
"Ce code d'authentification est nécessaire uniquement pour permettre aux "
"logiciels tiers d'accéder aux données de Joplin."
msgid "Check synchronisation configuration"
msgstr "Vérifier config synchronisation"
@@ -762,20 +796,23 @@ msgstr "Vérifier config synchronisation"
msgid "Notes and settings are stored in: %s"
msgstr "Les notes et paramètres se trouve dans : %s"
msgid "Save"
msgstr "Enregistrer"
msgid "Apply"
msgstr "Appliquer"
msgid "Submit"
msgstr "Envoyer"
msgid "Save"
msgstr "Enregistrer"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
"continue?"
msgstr ""
"Désactiver le cryptage signifie que *toutes* les notes et fichiers vont être "
"re-synchronisés et envoyés décryptés sur la cible de la synchronisation. "
"Souhaitez vous continuer ?"
"Désactiver le chiffrement signifie que *toutes* les notes et fichiers vont "
"être re-synchronisés et envoyés déchiffrés sur la cible de la "
"synchronisation. Souhaitez vous continuer ?"
msgid ""
"Enabling encryption means *all* your notes and attachments are going to be "
@@ -783,17 +820,17 @@ msgid ""
"password as, for security purposes, this will be the *only* way to decrypt "
"the data! To enable encryption, please enter your password below."
msgstr ""
"Activer le cryptage signifie que *toutes* les notes et fichiers vont être re-"
"synchronisés et envoyés cryptés vers la cible de la synchronisation. Ne "
"Activer le chiffrement signifie que *toutes* les notes et fichiers vont être "
"re-synchronisés et envoyés chiffrés vers la cible de la synchronisation. Ne "
"perdez pas votre mot de passe car, pour des raisons de sécurité, ce sera la "
"*seule* façon de décrypter les données ! Pour activer le cryptage, veuillez "
"entrer votre mot de passe ci-dessous."
"*seule* façon de déchiffrer les données ! Pour activer le chiffrement, "
"veuillez entrer votre mot de passe ci-dessous."
msgid "Disable encryption"
msgstr "Désactiver le cryptage"
msgstr "Désactiver le chiffrement"
msgid "Enable encryption"
msgstr "Activer le cryptage"
msgstr "Activer le chiffrement"
msgid "Master Keys"
msgstr "Clefs maître"
@@ -824,10 +861,10 @@ msgid ""
"as \"active\"). Any of the keys might be used for decryption, depending on "
"how the notes or notebooks were originally encrypted."
msgstr ""
"Note : seule une clef maître va être utilisée pour le cryptage (celle "
"Note : seule une clef maître va être utilisée pour le chiffrement (celle "
"marquée comme \"actif\" ci-dessus). N'importe quelle clef peut être utilisée "
"pour le décryptage, selon la façon dont les notes ou carnets étaient cryptés "
"à l'origine."
"pour le déchiffrement, selon la façon dont les notes ou carnets étaient "
"chiffrés à l'origine."
msgid "Missing Master Keys"
msgstr "Clefs maître manquantes"
@@ -837,7 +874,7 @@ msgid ""
"however the application does not currently have access to them. It is likely "
"they will eventually be downloaded via synchronisation."
msgstr ""
"Les clefs maître avec ces identifiants sont utilisées pour crypter certains "
"Les clefs maître avec ces identifiants sont utilisées pour chiffrer certains "
"de vos objets, cependant le logiciel n'y a pour l'instant pas accès. Il est "
"probable qu'elle vont être prochainement disponible via la synchronisation."
@@ -845,14 +882,14 @@ msgid ""
"For more information about End-To-End Encryption (E2EE) and advices on how "
"to enable it please check the documentation:"
msgstr ""
"Pour plus d'informations sur l'encryption de bout en bout, ainsi que des "
"Pour plus d'informations sur le chiffrement de bout en bout, ainsi que des "
"conseils pour l'activer, veuillez consulter la documentation :"
msgid "Status"
msgstr "État"
msgid "Encryption is:"
msgstr "Le cryptage est :"
msgstr "Le chiffrement est :"
msgid "Back"
msgstr "Retour"
@@ -901,7 +938,7 @@ msgid "View them now"
msgstr "Les voir maintenant"
msgid "Some items cannot be decrypted."
msgstr "Certains objets ne peuvent être décryptés."
msgstr "Certains objets ne peuvent être déchiffrés."
msgid "Set the password"
msgstr "Définir le mot de passe"
@@ -909,9 +946,22 @@ msgstr "Définir le mot de passe"
msgid "Add or remove tags"
msgstr "Gérer les étiquettes"
msgid "Duplicate"
msgstr "Dupliquer"
#, javascript-format
msgid "%s - Copy"
msgstr "%s - Copie"
msgid "Switch between note and to-do type"
msgstr "Alterner entre note et tâche"
msgid "Switch to note type"
msgstr "Convertir en note"
msgid "Switch to to-do type"
msgstr "Convertir en tâche"
msgid "Copy Markdown link"
msgstr "Copier lien Markdown"
@@ -931,12 +981,21 @@ msgstr ""
"Il n'y a pour l'instant aucun carnet. Créez-en un en cliquant sur \"Nouveau "
"carnet\"."
msgid "Location"
msgstr "Lieu"
msgid "URL"
msgstr "URL"
msgid "Note properties"
msgstr "Propriétés de la note"
msgid "Open..."
msgstr "Ouvrir..."
#, fuzzy, javascript-format
#, javascript-format
msgid "This file could not be opened: %s"
msgstr "Ce carnet n'a pas pu être sauvegardé : %s"
msgstr "Ce fichier n'a pas pu être ouvert : %s"
msgid "Save as..."
msgstr "Enregistrer sous..."
@@ -944,6 +1003,12 @@ msgstr "Enregistrer sous..."
msgid "Copy path to clipboard"
msgstr "Copier le chemin"
msgid "Copy Link Address"
msgstr "Copier l'adresse du lien"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr "Cette pièce jointe n'est pas téléchargée ou pas encore déchiffrée"
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Lien ou message non géré : %s"
@@ -957,13 +1022,16 @@ msgstr ""
"l'éditeur et éditer cette note."
msgid "strong text"
msgstr ""
msgstr "texte en gras"
msgid "emphasized text"
msgstr ""
msgstr "texte en italique"
msgid "List item"
msgstr "Élément de liste"
msgid "Insert Hyperlink"
msgstr ""
msgstr "Insérer lien"
msgid "Attach file"
msgstr "Attacher un fichier"
@@ -979,25 +1047,31 @@ msgid "In: %s"
msgstr "Dans : %s"
msgid "Hyperlink"
msgstr ""
msgstr "Lien"
msgid "Code"
msgstr ""
msgstr "Code"
msgid "Numbered List"
msgstr ""
msgstr "Liste numérotée"
msgid "Bulleted List"
msgstr ""
msgstr "Liste à puces"
msgid "Checkbox"
msgstr ""
msgstr "Case à cocher"
msgid "Heading"
msgstr ""
msgstr "Titre"
msgid "Horizontal Rule"
msgstr ""
msgstr "Règle horizontale"
msgid "Click to stop external editing"
msgstr "Cliquez pour arrêter l'édition externe"
msgid "Watching..."
msgstr "En cours..."
msgid "to-do"
msgstr "tâche"
@@ -1028,7 +1102,7 @@ msgid "Synchronisation Status"
msgstr "État de la synchronisation"
msgid "Encryption Options"
msgstr "Options de cryptage"
msgstr "Options de chiffrement"
msgid "Clipper Options"
msgstr "Options du Web Clipper"
@@ -1048,6 +1122,14 @@ msgstr "Synchroniser"
msgid "Notebooks"
msgstr "Carnets"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Déchiffrement des objets : %d/%d"
#, javascript-format
msgid "Fetching resources: %d"
msgstr "Tél. ressources : %d"
msgid "Please select where the sync status should be exported to"
msgstr ""
"Veuillez sélectionner un répertoire ou exporter l'état de la synchronisation"
@@ -1093,6 +1175,9 @@ msgstr ""
"Impossible de rafraîchir la connexion à OneDrive. Démarrez la "
"synchronisation à nouveau pour corriger le problème."
msgid "Untitled"
msgstr "Sans titre"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1140,10 +1225,6 @@ msgstr "Objets distants supprimés : %d."
msgid "Fetched items: %d/%d."
msgstr "Téléchargés : %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "État : %s."
msgid "Cancelling..."
msgstr "Annulation..."
@@ -1166,20 +1247,16 @@ msgid "Synchronisation is already in progress. State: %s"
msgstr "La synchronisation est déjà en cours. État : %s"
msgid "Encrypted"
msgstr "Crypté"
msgstr "Chiffré"
msgid "Encrypted items cannot be modified"
msgstr "Les objets cryptés ne peuvent être modifiés"
msgstr "Les objets chiffrés ne peuvent être modifiés"
msgid "Conflicts"
msgstr "Conflits"
msgid "Cannot move notebook to this location"
msgstr "Impossible de déplacer le carnet vers le carnet \"%s\""
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Un carnet avec ce titre existe déjà : \"%s\""
msgstr "Impossible de déplacer le carnet à cet endroit"
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
@@ -1189,13 +1266,10 @@ msgid "title"
msgstr "titre"
msgid "updated date"
msgstr "Date modification"
msgstr "date de modification"
msgid "created date"
msgstr "Date création"
msgid "Untitled"
msgstr "Sans titre"
msgstr "date de création"
msgid "This note does not have geolocation information."
msgstr "Cette note n'a pas d'information d'emplacement."
@@ -1208,16 +1282,6 @@ msgstr "Impossible de copier la note vers le carnet \"%s\""
msgid "Cannot move note to \"%s\" notebook"
msgstr "Impossible de déplacer la note vers le carnet \"%s\""
msgid "Text editor"
msgstr "Éditeur de texte"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"L'éditeur de texte pour ouvrir et modifier les notes. Si aucun n'est "
"spécifié, il sera détecté automatiquement."
msgid "Language"
msgstr "Langue"
@@ -1264,14 +1328,29 @@ msgid "When creating a new note:"
msgstr "Lors de la création d'une note :"
msgid "Show tray icon"
msgstr "Afficher icône dans la zone de notifications"
msgstr "Afficher l'icône dans la zone de notifications"
msgid "Note: Does not work in all desktop environments."
msgstr "Note : Ne fonctionne pas dans tous les environnements de bureau."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
"Cela permettra à Joplin de s'exécuter en arrière-plan. Il est recommandé "
"d'activer ce réglage pour que vos notes soient constamment synchronisées, "
"donc réduire le nombre de conflits."
msgid "Start application minimised in the tray icon"
msgstr "Démarrer minimisé dans la zone de notification"
msgid "Global zoom percentage"
msgstr "Niveau de zoom"
msgid "Editor font size"
msgstr "Taille police éditeur"
msgid "Editor font family"
msgstr "Police de l'éditeur"
@@ -1301,6 +1380,16 @@ msgstr "%d heure"
msgid "%d hours"
msgstr "%d heures"
msgid "Text editor command"
msgstr "Commande de l'éditeur de texte"
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"La commande de l'éditeur de texte (peut inclure des options) pour ouvrir et "
"modifier les notes. Si non-spécifiée, elle sera détectée automatiquement."
msgid "Show advanced options"
msgstr "Montrer les options avancées"
@@ -1328,6 +1417,16 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud : URL WebDAV"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
"Attention : si vous changez cet emplacement, copiez-y tout le contenu avant "
"de synchroniser, sinon tous les fichiers seront supprimés ! Consulter la FAQ "
"pour plus de détails : %s"
msgid "Nextcloud username"
msgstr "Nextcloud : Nom utilisateur"
@@ -1343,10 +1442,32 @@ msgstr "WebDAV : Nom utilisateur"
msgid "WebDAV password"
msgstr "WebDAV : Mot de passe"
msgid "Custom TLS certificates"
msgstr "Certificats TLS personnalisés"
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
"Liste séparée par des virgules contenant les chemins des répertoires "
"contenants des certificats, ou les chemins de certificats individuels. Par "
"exemple : /my/cert_dir, /other/custom.pem. Remarquez que si vous changez les "
"paramètres TLS, vous devez enregistrer vos changements avant de cliquer sur "
"\"Vérifier config synchronisation\"."
msgid "Ignore TLS certificate errors"
msgstr "Ignorer les erreurs de certificats TLS"
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Option invalide: \"%s\". Les valeurs possibles sont : %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr "L'étiquette \"%s\" existe déjà. Veuillez choisir un autre nom."
msgid "Joplin Export File"
msgstr "Fichier d'export Joplin"
@@ -1359,6 +1480,9 @@ msgstr "Dossier d'export Joplin"
msgid "Evernote Export File"
msgstr "Fichiers d'export Evernote"
msgid "Json Export Directory"
msgstr "Dossier d'export JSON"
msgid "Directory"
msgstr "Dossier"
@@ -1375,7 +1499,7 @@ msgid ""
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
"decrypted and try again."
msgstr ""
"Cet objet est crypté : %s \"%s\". Veuillez attendre que tout soit décrypté "
"Cet objet est chiffré : %s \"%s\". Veuillez attendre que tout soit déchiffré "
"et réessayez."
msgid "There is no data to export."
@@ -1433,6 +1557,12 @@ msgstr "Alarmes à venir"
msgid "On %s: %s"
msgstr "Le %s : %s"
msgid "Permission to use camera"
msgstr "Permission d'utiliser l'appareil photo"
msgid "Your permission to use your camera is required."
msgstr "Votre permission est requise pour utiliser l'appareil photo"
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Ce carnet ne contient aucune note. Créez-en une en appuyant sur le bouton "
@@ -1448,7 +1578,7 @@ msgid "Export Debug Report"
msgstr "Exporter rapport de débogage"
msgid "Encryption Config"
msgstr "Config cryptage"
msgstr "Config chiffrement"
msgid "Configuration"
msgstr "Configuration"
@@ -1463,6 +1593,9 @@ msgstr "Déplacer %d notes vers carnet \"%s\" ?"
msgid "Press to set the decryption password."
msgstr "Définir mot de passe de synchronisation."
msgid "Clear alarm"
msgstr "Enlever l'alarme"
msgid "Save alarm"
msgstr "Enregistrer alarme"
@@ -1475,9 +1608,39 @@ msgstr "Confirmer"
msgid "Cancel synchronisation"
msgstr "Annuler synchronisation"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Téléchargés : %d/%d."
msgid "Checking... Please wait."
msgstr "Vérification... Veuillez attendre."
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "La configuration de la synchronisation semble correcte."
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
"Erreur. Veuillez vérifier que l'URL, le nom, le mot de passe, etc. sont "
"corrects et que la destination est accessible. L'erreur reportée est :"
msgid "The application has been authorised!"
msgstr "Le logiciel a été autorisé !"
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
"Impossible d'autoriser le logiciel :\n"
"\n"
"%s\n"
"\n"
"Veuillez réessayer."
#, javascript-format
msgid "Decrypted items: %s / %s"
msgstr "Déchiffrement : %s / %s"
msgid "New tags:"
msgstr "Nouvelles étiquettes :"
@@ -1565,6 +1728,9 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Type d'image non géré : %s"
msgid "Take photo"
msgstr "Prendre une photo"
msgid "Attach photo"
msgstr "Attacher une photo"
@@ -1589,6 +1755,9 @@ msgstr "Voir métadonnées"
msgid "View on map"
msgstr "Voir sur carte"
msgid "Go to source URL"
msgstr "Aller à l'URL source"
msgid "Delete notebook"
msgstr "Supprimer le carnet"
@@ -1613,12 +1782,18 @@ msgstr ""
msgid "Welcome"
msgstr "Bienvenue"
#~ msgid "State: %s."
#~ msgstr "État : %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Un carnet avec ce titre existe déjà : \"%s\""
#~ msgid ""
#~ "For more information about End-To-End Encryption (E2EE) and advices on "
#~ "how to enable it please check the documentation"
#~ msgstr ""
#~ "Pour plus d'informations sur l'encryption de bout en bout, ainsi que des "
#~ "conseils pour l'activer, veuillez consulter la documentation"
#~ "Pour plus d'informations sur le chiffrement de bout en bout, ainsi que "
#~ "des conseils pour l'activer, veuillez consulter la documentation"
#~ msgid "Searches"
#~ msgstr "Recherches"

View File

@@ -452,13 +452,17 @@ msgstr "Non é posíbel iniciar o sincronizador."
msgid "Starting synchronisation..."
msgstr "Iniciando sincronización..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Cancelando... Agarde."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> pode ser «add», «remove» ou «list» para asignar ou eliminar "
"[tag] da [note] ou para listar as notas asociadas con [tag]. A orde «list» "
@@ -619,15 +623,29 @@ msgstr "Cortar"
msgid "Paste"
msgstr "Pegar"
#, fuzzy
msgid "Select all"
msgstr "Seleccionar data"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Buscar en todas as notas"
#, fuzzy
msgid "Search in current note"
msgstr "Buscar en todas as notas"
msgid "View"
msgstr "Vista"
@@ -696,6 +714,9 @@ msgstr "Si"
msgid "No"
msgstr "Non"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -739,6 +760,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Mostrar opcións avanzadas"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr "Comprobar a configuración da sincronización"
@@ -746,12 +782,15 @@ msgstr "Comprobar a configuración da sincronización"
msgid "Notes and settings are stored in: %s"
msgstr "As notas e axustes gardáronse en: %s"
msgid "Save"
msgstr "Gardar"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr "Gardar"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -888,9 +927,24 @@ msgstr "Estabelecer un contrasinal"
msgid "Add or remove tags"
msgstr "Engadir ou eliminar etiquetas"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Copiar"
msgid "Switch between note and to-do type"
msgstr "Cambiar entre notas e tarefas"
#, fuzzy
msgid "Switch to note type"
msgstr "Cambiar entre notas e tarefas"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Cambiar entre notas e tarefas"
#, fuzzy
msgid "Copy Markdown link"
msgstr "Markdown"
@@ -908,6 +962,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "Este no é un caderno. Cree un, premendo en «Novo caderno»."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Abrir…"
@@ -921,6 +984,12 @@ msgstr "Gardar como…"
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Ligazón ou mensaxe incompatíbeis: %s"
@@ -939,6 +1008,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -976,6 +1048,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "Cancelando..."
msgid "to-do"
msgstr "tarefas pendentes"
@@ -1026,6 +1105,14 @@ msgstr "Sincronizar"
msgid "Notebooks"
msgstr "Cadernos"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Elementos obtidos: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Recursos: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Seleccione onde exportar o estado da sincronización"
@@ -1070,6 +1157,9 @@ msgstr ""
"Non é posíbel actualizar o «token»: faltan datos da autenticación. Iniciar a "
"sincronización de novo pode arranxar o problema."
msgid "Untitled"
msgstr "Sen título"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1117,10 +1207,6 @@ msgstr "Elementos remotos borrados: %d."
msgid "Fetched items: %d/%d."
msgstr "Elementos obtidos: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estado: %s."
msgid "Cancelling..."
msgstr "Cancelando..."
@@ -1155,10 +1241,6 @@ msgstr "Conflitos"
msgid "Cannot move notebook to this location"
msgstr "Non é posíbel mover a nota ao caderno «%s»"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Xa existe un caderno con ese título: «%s»"
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr "Os cadernos non poden levar o nome «%s» porque é un título reservado."
@@ -1175,9 +1257,6 @@ msgstr "Actualizado: %d."
msgid "created date"
msgstr "Creado: %d."
msgid "Untitled"
msgstr "Sen título"
msgid "This note does not have geolocation information."
msgstr "Esta nota non ten información de xeolocalización."
@@ -1189,16 +1268,6 @@ msgstr "Non é posíbel copiar a nota ao caderno «%s»"
msgid "Cannot move note to \"%s\" notebook"
msgstr "Non é posíbel mover a nota ao caderno «%s»"
msgid "Text editor"
msgstr "Editor de texto"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Editor a usar para abrir unha nota. Se non se indica ningún tentará detectar "
"automaticamente o editor predeterminado."
msgid "Language"
msgstr "Idioma"
@@ -1251,9 +1320,22 @@ msgstr "Mostrar a icona na bandexa"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Porcentaxe de ampliación"
#, fuzzy
msgid "Editor font size"
msgstr "Familia de tipos de letra do editor"
msgid "Editor font family"
msgstr "Familia de tipos de letra do editor"
@@ -1283,6 +1365,18 @@ msgstr "%d hora"
msgid "%d hours"
msgstr "%d horas"
#, fuzzy
msgid "Text editor command"
msgstr "Editor de texto"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Editor a usar para abrir unha nota. Se non se indica ningún tentará detectar "
"automaticamente o editor predeterminado."
msgid "Show advanced options"
msgstr "Mostrar opcións avanzadas"
@@ -1309,6 +1403,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "URL de Nextcloud WebDAV"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Usuario de Nextcloud"
@@ -1324,10 +1425,27 @@ msgstr "Usuario de WebDAV"
msgid "WebDAV password"
msgstr "Contrasinal do WebDAV"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Valor incorrecto de opción: «%s». Os valores posíbeis son: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr "Ficheiro de exportación do Joplin"
@@ -1340,6 +1458,10 @@ msgstr "Cartafol de exportación do Joplin"
msgid "Evernote Export File"
msgstr "Ficheiro de exportación de Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Cartafol de exportación do Joplin"
msgid "Directory"
msgstr "Cartafol"
@@ -1414,6 +1536,12 @@ msgstr "Alarmas próximas"
msgid "On %s: %s"
msgstr "En %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Non ten notas actualmente. Cree unha premendo no botón (+)."
@@ -1442,6 +1570,10 @@ msgstr "Mover %d notas para o caderno \"%s\"?"
msgid "Press to set the decryption password."
msgstr "Prema para estabelecer o contrasinal de descifrado."
#, fuzzy
msgid "Clear alarm"
msgstr "Estabelecer alarma"
#, fuzzy
msgid "Save alarm"
msgstr "Estabelecer alarma"
@@ -1455,8 +1587,34 @@ msgstr "Confirmar"
msgid "Cancel synchronisation"
msgstr "Cancelar sincronización"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Cancelando... Agarde."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Comprobar a configuración da sincronización"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "O aplicativo foi autorizado correctamente."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Elementos obtidos: %d/%d."
msgid "New tags:"
@@ -1539,6 +1697,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Tipo de imaxe incompatíbel: %s"
#, fuzzy
msgid "Take photo"
msgstr "Anexar foto"
msgid "Attach photo"
msgstr "Anexar foto"
@@ -1563,6 +1725,9 @@ msgstr "Mostrar metadatos"
msgid "View on map"
msgstr "Ver no mapa"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Eliminar caderno"
@@ -1584,3 +1749,9 @@ msgstr "Non ten cadernos actualmente. Cree un premendo no botón (+)."
msgid "Welcome"
msgstr "Benvido/a"
#~ msgid "State: %s."
#~ msgstr "Estado: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Xa existe un caderno con ese título: «%s»"

View File

@@ -455,6 +455,9 @@ msgstr "Ne mogu započeti sinkronizaciju."
msgid "Starting synchronisation..."
msgstr "Započinjem sinkronizaciju..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Prekidam... Pričekaj."
@@ -462,7 +465,7 @@ msgstr "Prekidam... Pričekaj."
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
@@ -625,15 +628,29 @@ msgstr "Izreži"
msgid "Paste"
msgstr "Zalijepi"
#, fuzzy
msgid "Select all"
msgstr "Odaberi datum"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Pretraži u svim bilješkama"
#, fuzzy
msgid "Search in current note"
msgstr "Pretraži u svim bilješkama"
msgid "View"
msgstr ""
@@ -705,6 +722,9 @@ msgstr ""
msgid "No"
msgstr "N"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -748,6 +768,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Prikaži napredne opcije"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
#, fuzzy
msgid "Check synchronisation configuration"
msgstr "Prekini sinkronizaciju"
@@ -756,12 +791,15 @@ msgstr "Prekini sinkronizaciju"
msgid "Notes and settings are stored in: %s"
msgstr "Bilješke i postavke su pohranjene u: %s"
msgid "Save"
msgstr "Spremi"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr "Spremi"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -889,9 +927,24 @@ msgstr ""
msgid "Add or remove tags"
msgstr "Dodaj ili makni oznake"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Kopiraj"
msgid "Switch between note and to-do type"
msgstr "Zamijeni bilješku i zadatak"
#, fuzzy
msgid "Switch to note type"
msgstr "Zamijeni bilješku i zadatak"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Zamijeni bilješku i zadatak"
msgid "Copy Markdown link"
msgstr ""
@@ -908,6 +961,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "Ovdje nema bilježnica. Stvori novu pritiskom na \"Nova bilježnica\"."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -922,6 +984,12 @@ msgstr "Spremi promjene"
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nepodržana poveznica ili poruka: %s"
@@ -938,6 +1006,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -975,6 +1046,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "Prekidam..."
#, fuzzy
msgid "to-do"
msgstr "Novi zadatak"
@@ -1027,6 +1105,14 @@ msgstr "Sinkroniziraj"
msgid "Notebooks"
msgstr "Bilježnice"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Stvorene lokalne stavke: %d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Resursi: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Odaberi lokaciju za izvoz statusa sinkronizacije"
@@ -1069,6 +1155,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr "Nedostaju podaci za ovjeru. Pokušaj ponovo započeti sinkronizaciju."
msgid "Untitled"
msgstr "Nenaslovljen"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1116,10 +1205,6 @@ msgstr "Obrisane udaljene stavke: %d."
msgid "Fetched items: %d/%d."
msgstr "Stvorene lokalne stavke: %d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Stanje: \"%s\"."
msgid "Cancelling..."
msgstr "Prekidam..."
@@ -1155,10 +1240,6 @@ msgstr "Sukobi"
msgid "Cannot move notebook to this location"
msgstr "Ne mogu premjestiti bilješku u bilježnicu %s"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Bilježnica s ovim naslovom već postoji: \"%s\""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr "Naslov \"%s\" je rezerviran i ne može se koristiti."
@@ -1175,9 +1256,6 @@ msgstr "Ažurirano: %d."
msgid "created date"
msgstr "Stvoreno: %d."
msgid "Untitled"
msgstr "Nenaslovljen"
msgid "This note does not have geolocation information."
msgstr "Ova bilješka nema geolokacijske informacije."
@@ -1189,16 +1267,6 @@ msgstr "Ne mogu kopirati bilješku u bilježnicu %s"
msgid "Cannot move note to \"%s\" notebook"
msgstr "Ne mogu premjestiti bilješku u bilježnicu %s"
msgid "Text editor"
msgstr "Uređivač teksta"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Program za uređivanje koji će biti korišten za uređivanje bilješki. Ako ni "
"jedan nije odabran, pokušati će se sa default programom."
msgid "Language"
msgstr "Jezik"
@@ -1256,9 +1324,22 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
#, fuzzy
msgid "Editor font size"
msgstr "Uredi bilješku."
msgid "Editor font family"
msgstr ""
@@ -1285,6 +1366,18 @@ msgstr "%d sat"
msgid "%d hours"
msgstr "%d sati"
#, fuzzy
msgid "Text editor command"
msgstr "Uređivač teksta"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Program za uređivanje koji će biti korišten za uređivanje bilješki. Ako ni "
"jedan nije odabran, pokušati će se sa default programom."
msgid "Show advanced options"
msgstr "Prikaži napredne opcije"
@@ -1309,6 +1402,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr ""
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr ""
@@ -1324,10 +1424,27 @@ msgstr ""
msgid "WebDAV password"
msgstr ""
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Nevažeća vrijednost: \"%s\". Moguće vrijednosti su: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
#, fuzzy
msgid "Joplin Export File"
msgstr "Evernote izvozne datoteke"
@@ -1342,6 +1459,10 @@ msgstr ""
msgid "Evernote Export File"
msgstr "Evernote izvozne datoteke"
#, fuzzy
msgid "Json Export Directory"
msgstr "Evernote izvozne datoteke"
msgid "Directory"
msgstr ""
@@ -1412,6 +1533,12 @@ msgstr "Nadolazeća upozorenja"
msgid "On %s: %s"
msgstr "On %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Trenutno nema bilješki. Stvori novu klikom na (+) gumb."
@@ -1440,6 +1567,10 @@ msgstr "Premjesti %d bilješke u bilježnicu \"%s\"?"
msgid "Press to set the decryption password."
msgstr ""
#, fuzzy
msgid "Clear alarm"
msgstr "Postavi upozorenje"
#, fuzzy
msgid "Save alarm"
msgstr "Postavi upozorenje"
@@ -1453,8 +1584,34 @@ msgstr "Potvrdi"
msgid "Cancel synchronisation"
msgstr "Prekini sinkronizaciju"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Prekidam... Pričekaj."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Prekini sinkronizaciju"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "Aplikacija je uspješno autorizirana."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Stvorene lokalne stavke: %d."
msgid "New tags:"
@@ -1538,6 +1695,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nepodržana vrsta slike: %s"
#, fuzzy
msgid "Take photo"
msgstr "Priloži sliku"
msgid "Attach photo"
msgstr "Priloži sliku"
@@ -1562,6 +1723,9 @@ msgstr "Prikaži metapodatke"
msgid "View on map"
msgstr "Vidi na karti"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Obriši bilježnicu"
@@ -1584,6 +1748,13 @@ msgstr "Trenutno nemaš nijednu bilježnicu. Stvori novu klikom na (+) gumb."
msgid "Welcome"
msgstr "Dobro došli"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Stanje: \"%s\"."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Bilježnica s ovim naslovom već postoji: \"%s\""
#~ msgid "Searches"
#~ msgstr "Pretraživanja"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -408,13 +408,16 @@ msgstr ""
msgid "Starting synchronisation..."
msgstr ""
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr ""
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
#, javascript-format
@@ -552,15 +555,27 @@ msgstr ""
msgid "Paste"
msgstr ""
msgid "Select all"
msgstr ""
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr ""
msgid "Search in current note"
msgstr ""
msgid "View"
msgstr ""
@@ -629,6 +644,9 @@ msgstr ""
msgid "No"
msgstr ""
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -672,6 +690,20 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
msgid "Advanced options"
msgstr ""
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr ""
@@ -679,12 +711,15 @@ msgstr ""
msgid "Notes and settings are stored in: %s"
msgstr ""
msgid "Save"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr ""
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -807,9 +842,22 @@ msgstr ""
msgid "Add or remove tags"
msgstr ""
msgid "Duplicate"
msgstr ""
#, javascript-format
msgid "%s - Copy"
msgstr ""
msgid "Switch between note and to-do type"
msgstr ""
msgid "Switch to note type"
msgstr ""
msgid "Switch to to-do type"
msgstr ""
msgid "Copy Markdown link"
msgstr ""
@@ -826,6 +874,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr ""
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -839,6 +896,12 @@ msgstr ""
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr ""
@@ -855,6 +918,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -892,6 +958,12 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
msgid "Watching..."
msgstr ""
msgid "to-do"
msgstr ""
@@ -941,6 +1013,14 @@ msgstr ""
msgid "Notebooks"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr ""
#, javascript-format
msgid "Fetching resources: %d"
msgstr ""
msgid "Please select where the sync status should be exported to"
msgstr ""
@@ -983,6 +1063,9 @@ msgid ""
"synchronisation again may fix the problem."
msgstr ""
msgid "Untitled"
msgstr ""
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1024,10 +1107,6 @@ msgstr ""
msgid "Fetched items: %d/%d."
msgstr ""
#, javascript-format
msgid "State: %s."
msgstr ""
msgid "Cancelling..."
msgstr ""
@@ -1061,10 +1140,6 @@ msgstr ""
msgid "Cannot move notebook to this location"
msgstr ""
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr ""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr ""
@@ -1078,9 +1153,6 @@ msgstr ""
msgid "created date"
msgstr ""
msgid "Untitled"
msgstr ""
msgid "This note does not have geolocation information."
msgstr ""
@@ -1092,14 +1164,6 @@ msgstr ""
msgid "Cannot move note to \"%s\" notebook"
msgstr ""
msgid "Text editor"
msgstr ""
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
msgid "Language"
msgstr ""
@@ -1151,9 +1215,21 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
msgid "Editor font size"
msgstr ""
msgid "Editor font family"
msgstr ""
@@ -1180,6 +1256,14 @@ msgstr ""
msgid "%d hours"
msgstr ""
msgid "Text editor command"
msgstr ""
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
msgid "Show advanced options"
msgstr ""
@@ -1202,6 +1286,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr ""
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr ""
@@ -1217,10 +1308,27 @@ msgstr ""
msgid "WebDAV password"
msgstr ""
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr ""
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr ""
@@ -1233,6 +1341,9 @@ msgstr ""
msgid "Evernote Export File"
msgstr ""
msgid "Json Export Directory"
msgstr ""
msgid "Directory"
msgstr ""
@@ -1302,6 +1413,12 @@ msgstr ""
msgid "On %s: %s"
msgstr ""
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
@@ -1330,6 +1447,9 @@ msgstr ""
msgid "Press to set the decryption password."
msgstr ""
msgid "Clear alarm"
msgstr ""
msgid "Save alarm"
msgstr ""
@@ -1342,8 +1462,31 @@ msgstr ""
msgid "Cancel synchronisation"
msgstr ""
msgid "Checking... Please wait."
msgstr ""
msgid "Success! Synchronisation configuration appears to be correct."
msgstr ""
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
msgid "The application has been authorised!"
msgstr ""
#, javascript-format
msgid "Decrypting items: %d/%d"
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, javascript-format
msgid "Decrypted items: %s / %s"
msgstr ""
msgid "New tags:"
@@ -1425,6 +1568,9 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr ""
msgid "Take photo"
msgstr ""
msgid "Attach photo"
msgstr ""
@@ -1449,6 +1595,9 @@ msgstr ""
msgid "View on map"
msgstr ""
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr ""

1748
CliClient/locales/ko.po Normal file

File diff suppressed because it is too large Load Diff

1762
CliClient/locales/nb_NO.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -456,13 +456,17 @@ msgstr "Kan de synchronisatie niet starten."
msgid "Starting synchronisation..."
msgstr "Synchronisatie starten..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Annuleren.. Even geduld."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> kan \"add\", \"remove\" of \"list\" zijn om een [tag] toe te "
"voegen aan een [note] of te verwijderen, of om alle notities geassocieerd "
@@ -629,15 +633,29 @@ msgstr "Knip"
msgid "Paste"
msgstr "Plak"
#, fuzzy
msgid "Select all"
msgstr "Selecteer datum"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Zoek in alle notities"
#, fuzzy
msgid "Search in current note"
msgstr "Zoek in alle notities"
msgid "View"
msgstr ""
@@ -708,6 +726,9 @@ msgstr ""
msgid "No"
msgstr "N"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -751,6 +772,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Toon geavanceerde opties"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
#, fuzzy
msgid "Check synchronisation configuration"
msgstr "Annuleer synchronisatie"
@@ -759,12 +795,15 @@ msgstr "Annuleer synchronisatie"
msgid "Notes and settings are stored in: %s"
msgstr "Notities en instellingen zijn opgeslaan in %s"
msgid "Save"
msgstr "Sla op"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr "Sla op"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -903,9 +942,24 @@ msgstr "Stel wachtwoord in"
msgid "Add or remove tags"
msgstr "Voeg tag toe of verwijder tag"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Kopieer"
msgid "Switch between note and to-do type"
msgstr "Wissel tussen notitie en to-do type"
#, fuzzy
msgid "Switch to note type"
msgstr "Wissel tussen notitie en to-do type"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Wissel tussen notitie en to-do type"
msgid "Copy Markdown link"
msgstr ""
@@ -924,6 +978,15 @@ msgstr ""
"U heeft momenteel geen notitieboek. Maak een notitieboek door op \"Nieuw "
"notitieboek\" te klikken."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr ""
@@ -938,6 +1001,12 @@ msgstr "Sla wijzigingen op"
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Link of bericht \"%s\" wordt niet ondersteund"
@@ -954,6 +1023,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -991,6 +1063,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "Annuleren..."
#, fuzzy
msgid "to-do"
msgstr "Nieuwe to-do"
@@ -1043,6 +1122,14 @@ msgstr "Synchroniseer"
msgid "Notebooks"
msgstr "Notitieboeken"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Opgehaalde items: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Middelen: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Selecteer waar de synchronisatie status naar geëxporteerd moet worden"
@@ -1088,6 +1175,9 @@ msgstr ""
"Kan token niet vernieuwen: authenticatiedata ontbreekt. Herstarten van de "
"synchronisatie kan het probleem eventueel oplossen. "
msgid "Untitled"
msgstr "Untitled"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1135,10 +1225,6 @@ msgstr "Verwijderde remote items: %d."
msgid "Fetched items: %d/%d."
msgstr "Opgehaalde items: %d/%d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Status: \"%s\""
msgid "Cancelling..."
msgstr "Annuleren..."
@@ -1173,10 +1259,6 @@ msgstr "Conflicten"
msgid "Cannot move notebook to this location"
msgstr "Kan notitie niet naar notitieboek \"%s\" verplaatsen."
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Er bestaat al een notitieboek met \"%s\" als titel"
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr ""
@@ -1195,9 +1277,6 @@ msgstr "Bijgewerkt: %d."
msgid "created date"
msgstr "Aangemaakt: %d."
msgid "Untitled"
msgstr "Untitled"
msgid "This note does not have geolocation information."
msgstr "Deze notitie bevat geen geo-locatie informatie."
@@ -1209,17 +1288,6 @@ msgstr "Kan notitie niet naar notitieboek \"%s\" kopiëren."
msgid "Cannot move note to \"%s\" notebook"
msgstr "Kan notitie niet naar notitieboek \"%s\" verplaatsen."
msgid "Text editor"
msgstr "Tekst editor"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"De editor die zal gebruikt worden bij het openen van een notitie. Als er "
"geen meegegeven wordt, zal het programma de standaard editor proberen te "
"detecteren. "
msgid "Language"
msgstr "Taal"
@@ -1276,9 +1344,22 @@ msgstr ""
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr ""
#, fuzzy
msgid "Editor font size"
msgstr "Bewerk notitie."
msgid "Editor font family"
msgstr ""
@@ -1305,6 +1386,19 @@ msgstr "%d uur"
msgid "%d hours"
msgstr "%d uren"
#, fuzzy
msgid "Text editor command"
msgstr "Tekst editor"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"De editor die zal gebruikt worden bij het openen van een notitie. Als er "
"geen meegegeven wordt, zal het programma de standaard editor proberen te "
"detecteren. "
msgid "Show advanced options"
msgstr "Toon geavanceerde opties"
@@ -1329,6 +1423,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr ""
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr ""
@@ -1346,10 +1447,27 @@ msgstr ""
msgid "WebDAV password"
msgstr "Stel wachtwoord in"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Ongeldige optie: \"%s\". Geldige waarden zijn: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
#, fuzzy
msgid "Joplin Export File"
msgstr "Exporteer Evernote bestanden"
@@ -1364,6 +1482,10 @@ msgstr ""
msgid "Evernote Export File"
msgstr "Exporteer Evernote bestanden"
#, fuzzy
msgid "Json Export Directory"
msgstr "Exporteer Evernote bestanden"
msgid "Directory"
msgstr ""
@@ -1437,6 +1559,12 @@ msgstr "Meldingen"
msgid "On %s: %s"
msgstr "Op %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr ""
"Er zijn momenteel geen notities. Maak een notitie door op (+) te klikken."
@@ -1466,6 +1594,10 @@ msgstr "Verplaats %d notities naar notitieboek \"%s\"?"
msgid "Press to set the decryption password."
msgstr "Klik om het decryptie wachtwoord in te stellen"
#, fuzzy
msgid "Clear alarm"
msgstr "Zet melding"
#, fuzzy
msgid "Save alarm"
msgstr "Zet melding"
@@ -1479,8 +1611,34 @@ msgstr "Bevestig"
msgid "Cancel synchronisation"
msgstr "Annuleer synchronisatie"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Annuleren.. Even geduld."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Annuleer synchronisatie"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "De applicatie is succesvol geauthenticeerd."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Opgehaalde items: %d/%d."
msgid "New tags:"
@@ -1563,6 +1721,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Afbeeldingstype %s wordt niet ondersteund"
#, fuzzy
msgid "Take photo"
msgstr "Voeg foto toe"
msgid "Attach photo"
msgstr "Voeg foto toe"
@@ -1587,6 +1749,9 @@ msgstr "Toon metadata"
msgid "View on map"
msgstr "Toon op de kaart"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Verwijder notitieboek"
@@ -1611,6 +1776,13 @@ msgstr ""
msgid "Welcome"
msgstr "Welkom"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Status: \"%s\""
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Er bestaat al een notitieboek met \"%s\" als titel"
#~ msgid "Searches"
#~ msgstr "Zoekopdrachten"

1786
CliClient/locales/nl_NL.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,8 @@
# SOME DESCRIPTIVE TITLE.
# pt_BR locale strings - Joplin.
# Copyright (C) YEAR Laurent Cozic
# This file is distributed under the same license as the Joplin-CLI package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# Updated by Renato Xavier da Silveira Rosa <renatoxsr@gmail.com>, 2018.
#
msgid ""
msgstr ""
@@ -13,7 +14,7 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 2.0.7\n"
"X-Generator: Poedit 2.2\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "To delete a tag, untag the associated notes."
@@ -147,7 +148,7 @@ msgid "Completed decryption."
msgstr "Decriptação completada."
msgid "Enabled"
msgstr "Desabilitado"
msgstr "Habilitado"
msgid "Disabled"
msgstr "Desabilitado"
@@ -246,9 +247,8 @@ msgstr ""
"Use as setas e a Page Up/Page Down para rolar as listas e áreas de texto "
"(incluindo este console)."
#, fuzzy
msgid "To maximise/minimise the console, press \"tc\"."
msgstr "Para maximizar / minimizar o console, pressione \"TC\"."
msgstr "Para maximizar / minimizar o console, pressione \"tc\"."
msgid "To enter command line mode, press \":\""
msgstr "Para entrar no modo de linha de comando, pressione \":\""
@@ -363,12 +363,11 @@ msgstr "Exclui o caderno informado."
msgid "Deletes the notebook without asking for confirmation."
msgstr "Exclui o caderno sem pedir confirmação."
#, fuzzy
msgid ""
"Delete notebook? All notes and sub-notebooks within this notebook will also "
"be deleted."
msgstr ""
"Excluir o caderno? Todas as notas deste caderno notebook também serão "
"Excluir o caderno? Todas as notas e sub-cadernos dentro deste também serão "
"excluídas."
msgid "Deletes the notes matching <note-pattern>."
@@ -456,17 +455,21 @@ msgstr "Não é possível inicializar o sincronizador."
msgid "Starting synchronisation..."
msgstr "Iniciando sincronização..."
msgid "Downloading resources..."
msgstr "Baixando os recursos..."
msgid "Cancelling... Please wait."
msgstr "Cancelando... Aguarde."
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> pode ser \"add\", \"remove\" ou \"list\" para atribuir ou "
"remover [tag] de [nota], ou para listar as notas associadas a [tag]. O "
"comando `taglist` pode ser usado para listar todas as tags."
"comando `tag list` pode ser usado para listar todas as tags (use -l para "
"opção longa)."
#, javascript-format
msgid "Invalid command: \"%s\""
@@ -626,20 +629,33 @@ msgstr "Cortar"
msgid "Paste"
msgstr "Colar"
msgid "Select all"
msgstr "Selecionar tudo"
msgid "Bold"
msgstr ""
msgstr "Negrito"
msgid "Italic"
msgstr ""
msgstr "Itálico"
msgid "Insert Date Time"
msgstr "Inserir Data e Hora"
msgid "Edit in external editor"
msgstr "Editar com editor externo"
msgid "Search in all the notes"
msgstr "Pesquisar em todas as notas"
#, fuzzy
msgid "Search in current note"
msgstr "Pesquisar em todas as notas"
msgid "View"
msgstr "Visualizar"
msgid "Toggle sidebar"
msgstr ""
msgstr "Alternar barra lateral"
msgid "Toggle editor layout"
msgstr "Alternar layout do editor"
@@ -651,7 +667,7 @@ msgid "Synchronisation status"
msgstr "Status de sincronização"
msgid "Web clipper options"
msgstr ""
msgstr "Opções do Web clipper"
msgid "Encryption options"
msgstr "Opções de Encriptação"
@@ -703,48 +719,73 @@ msgstr "Sim"
msgid "No"
msgstr "Não"
msgid "Token has been copied to the clipboard!"
msgstr "Token foi copiado para a \\u00e1rea de transfer\\u00eancia!"
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
"O serviço de web clipper está habilitado e configurado para auto-start."
#, javascript-format
msgid "Status: Started on port %d"
msgstr ""
msgstr "Status: Iniciado, na porta %d"
#, fuzzy, javascript-format
#, javascript-format
msgid "Status: %s"
msgstr "Estado: \"%s\"."
msgstr "Status: %s"
msgid "Disable Web Clipper Service"
msgstr ""
msgstr "Desabilitar serviço Web Clipper"
msgid "The web clipper service is not enabled."
msgstr ""
msgstr "O serviço de web clipper não está habilitado."
msgid "Enable Web Clipper Service"
msgstr ""
msgstr "Habilitar serviço Web Clipper"
msgid ""
"Joplin Web Clipper allows saving web pages and screenshots from your browser "
"to Joplin."
msgstr ""
"O serviço de Web Clipper do Joplin permite salvar páginas da web e "
"screenshots do seu browser, no Joplin."
msgid "In order to use the web clipper, you need to do the following:"
msgstr ""
msgstr "Para usar o web clipper, você precisa fazer o seguinte:"
msgid "Step 1: Enable the clipper service"
msgstr ""
msgstr "Passo 1: Habilitar o serviço do clipper"
msgid ""
"This service allows the browser extension to communicate with Joplin. When "
"enabling it your firewall may ask you to give permission to Joplin to listen "
"to a particular port."
msgstr ""
"Este serviço permite a extensão do browser se comunicat com o Joplin. Quando "
"habilitar, talvez seu firewall peça que você conceda permissão ao Joplin "
"para escutar determinada porta."
msgid "Step 2: Install the extension"
msgstr ""
msgstr "Passo 2: Instalar a extensão"
msgid "Download and install the relevant extension for your browser:"
msgstr "Baixe e instale a extensão relevante para seu browser:"
msgid "Advanced options"
msgstr "Mostrar opções avançadas"
msgid "Authorisation token:"
msgstr "Token de autoriza\\u00e7\\u00e3o:"
msgid "Copy token"
msgstr "Copira token"
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
"Esse token de autoriza\\u00e7\\u00e3o só é necess\\u00e1rio para permitir "
"que aplicativos de terceiros acessem o Joplin."
msgid "Check synchronisation configuration"
msgstr "Verificar a configuração da sincronização"
@@ -753,12 +794,15 @@ msgstr "Verificar a configuração da sincronização"
msgid "Notes and settings are stored in: %s"
msgstr "Notas e configurações estão armazenadas em: %s"
msgid "Save"
msgstr "Salvar"
msgid "Apply"
msgstr "Aplicar"
msgid "Submit"
msgstr "Enviar"
msgid "Save"
msgstr "Salvar"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -870,9 +914,8 @@ msgstr "Separe cada tag por vírgula."
msgid "Rename notebook:"
msgstr "Renomear caderno:"
#, fuzzy
msgid "Rename tag:"
msgstr "Renomear"
msgstr "Renomear tag:"
msgid "Set alarm:"
msgstr "Definir alarme:"
@@ -898,12 +941,24 @@ msgstr "Configurar a senha"
msgid "Add or remove tags"
msgstr "Adicionar ou remover tags"
msgid "Duplicate"
msgstr "Duplicar"
#, javascript-format
msgid "%s - Copy"
msgstr "%s - Copiar"
msgid "Switch between note and to-do type"
msgstr "Alternar entre os tipos Nota e Tarefa"
#, fuzzy
msgid "Switch to note type"
msgstr "Alternar para o tipo Nota"
msgid "Switch to to-do type"
msgstr "Alternar para o tipo Tarefa"
msgid "Copy Markdown link"
msgstr "Markdown"
msgstr "Copiar link de Markdown"
msgid "Delete"
msgstr "Excluir"
@@ -918,18 +973,33 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "Atualmente, não há cadernos. Crie um, clicando em \"Novo caderno\"."
msgid "Location"
msgstr "Localização"
msgid "URL"
msgstr "URL"
msgid "Note properties"
msgstr "Propriedades da nota"
msgid "Open..."
msgstr "Abrir..."
#, fuzzy, javascript-format
#, javascript-format
msgid "This file could not be opened: %s"
msgstr "O caderno não pôde ser salvo: %s"
msgstr "Este arquivo não pôde ser aberto: %s"
msgid "Save as..."
msgstr "Salvar como..."
msgid "Copy path to clipboard"
msgstr ""
msgstr "Copiar caminho para a área de transferência"
msgid "Copy Link Address"
msgstr "Copiar endereço do link"
msgid "This attachment is not downloaded or not decrypted yet."
msgstr "O anexo ainda não foi baixado ou decriptado."
#, javascript-format
msgid "Unsupported link or message: %s"
@@ -944,13 +1014,16 @@ msgstr ""
"e edite a nota."
msgid "strong text"
msgstr ""
msgstr "texto forte"
msgid "emphasized text"
msgstr ""
msgstr "texto enfatizado"
msgid "List item"
msgstr "Listar item"
msgid "Insert Hyperlink"
msgstr ""
msgstr "Inserir Hiperlink"
msgid "Attach file"
msgstr "Anexar arquivo"
@@ -961,30 +1034,36 @@ msgstr "Tags"
msgid "Set alarm"
msgstr "Definir alarme"
#, fuzzy, javascript-format
#, javascript-format
msgid "In: %s"
msgstr "%s: %s"
msgstr "Em: %s"
msgid "Hyperlink"
msgstr ""
msgstr "Hiperlink"
msgid "Code"
msgstr ""
msgstr "Código"
msgid "Numbered List"
msgstr ""
msgstr "Lista numerada"
msgid "Bulleted List"
msgstr ""
msgstr "Lista com bullets"
msgid "Checkbox"
msgstr ""
msgstr "Checkbox"
msgid "Heading"
msgstr ""
msgstr "Cabeçalho"
msgid "Horizontal Rule"
msgstr ""
msgstr "Régua horizontal"
msgid "Click to stop external editing"
msgstr "Clique para encerrar edição externa"
msgid "Watching..."
msgstr "Observando alterações..."
msgid "to-do"
msgstr "tarefa"
@@ -1017,9 +1096,8 @@ msgstr "Status de sincronização"
msgid "Encryption Options"
msgstr "Opções de Encriptação"
#, fuzzy
msgid "Clipper Options"
msgstr "Opções Gerais"
msgstr "Opções do clipper"
msgid "Remove this tag from all the notes?"
msgstr "Remover esta tag de todas as notas?"
@@ -1036,6 +1114,14 @@ msgstr "Sincronizar"
msgid "Notebooks"
msgstr "Cadernos"
#, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Decriptando itens: %d/%d"
#, javascript-format
msgid "Fetching resources: %d"
msgstr "Buscando recursos: %d"
msgid "Please select where the sync status should be exported to"
msgstr ""
"Favor selecionar o local para onde o status de sincronia deveria ser "
@@ -1082,6 +1168,9 @@ msgstr ""
"Não é possível atualizar token: faltam dados de autenticação. Iniciar a "
"sincronização novamente pode corrigir o problema."
msgid "Untitled"
msgstr "Sem título"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1129,10 +1218,6 @@ msgstr "Itens remotos excluídos: %d."
msgid "Fetched items: %d/%d."
msgstr "Itens pesquisados: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Estado: \"%s\"."
msgid "Cancelling..."
msgstr "Cancelando..."
@@ -1163,33 +1248,22 @@ msgstr "Itens encriptados não podem ser modificados"
msgid "Conflicts"
msgstr "Conflitos"
#, fuzzy
msgid "Cannot move notebook to this location"
msgstr "Não é possível mover a nota para o caderno \"%s\""
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Já existe caderno com este título: \"%s\""
msgstr "Não é possível mover a nota para este local"
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr ""
"Os cadernos não podem ser nomeados como\"%s\", que é um título reservado."
#, fuzzy
msgid "title"
msgstr "Sem título"
msgstr "título"
#, fuzzy
msgid "updated date"
msgstr "Atualizado: %d."
msgstr "data de ataualização"
#, fuzzy
msgid "created date"
msgstr "Criado: %d."
msgid "Untitled"
msgstr "Sem título"
msgstr "data de criação"
msgid "This note does not have geolocation information."
msgstr "Esta nota não possui informações de geolocalização."
@@ -1202,16 +1276,6 @@ msgstr "Não é possível copiar a nota para o caderno \"%s\""
msgid "Cannot move note to \"%s\" notebook"
msgstr "Não é possível mover a nota para o caderno \"%s\""
msgid "Text editor"
msgstr "Editor de texto"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"O editor que será usado para abrir uma nota. Se nenhum for indicado, ele "
"tentará detectar automaticamente o editor padrão."
msgid "Language"
msgstr "Idioma"
@@ -1233,15 +1297,14 @@ msgstr "Dark"
msgid "Uncompleted to-dos on top"
msgstr "Mostrar tarefas incompletas no topo"
#, fuzzy
msgid "Show completed to-dos"
msgstr "Mostrar tarefas incompletas no topo"
msgstr "Mostrar tarefas completas"
msgid "Sort notes by"
msgstr "Ordenar notas por"
msgid "Reverse sort order"
msgstr "Inverter ordem de classificação."
msgstr "Inverter ordem de classificação"
msgid "Save geo-location with notes"
msgstr "Salvar geolocalização com notas"
@@ -1262,21 +1325,36 @@ msgid "Show tray icon"
msgstr "Exibir tray icon"
msgid "Note: Does not work in all desktop environments."
msgstr "Nota: não funciona em todos os ambientes de desktop."
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
"Isso irá permitir que o Joplin continue sendo executado em segundo plano. É "
"recomendado que você habilita essa configuração para que suas notas "
"sejamconstantemente sincronizadas, de modo a reduzir as chances de conflitos."
msgid "Start application minimised in the tray icon"
msgstr "Iniciar aplicativo minimizado na barra de tarefas"
msgid "Global zoom percentage"
msgstr "Porcentagem global do zoom"
#, fuzzy
msgid "Editor font size"
msgstr "Família de fontes do editor"
msgid "Editor font family"
msgstr "Família de fontes do editor"
#, fuzzy
msgid ""
"This must be *monospace* font or it will not work properly. If the font is "
"incorrect or empty, it will default to a generic monospace font."
msgstr ""
"O nomes da fonte não será verificado. Se estiver incorreto ou vazio, será "
"usado por default uma fonte genérica monospace."
"Deve ser uma fonte *monospace\" ou não vai funcionar direito. Se a fonte "
"estiver incorreta ou vazia, será usada uma fonte genérica monospace default."
msgid "Automatically update the application"
msgstr "Atualizar automaticamente o aplicativo"
@@ -1296,6 +1374,17 @@ msgstr "%d hora"
msgid "%d hours"
msgstr "%d horas"
msgid "Text editor command"
msgstr "Comando do editor de texto"
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"O comando do editor (pode incluir argumentos) que será usado para abrir uma "
"nota. Se nenhum for indicado, ele tentará detectar automaticamente o editor "
"padrão."
msgid "Show advanced options"
msgstr "Mostrar opções avançadas"
@@ -1322,6 +1411,16 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV URL"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
"Atenção: Se você modificar esse local, tenha certeza de copiar todo o seu "
"conteúdo para lá antes de sincronizar, do contrário todos os seus arquivos "
"serão removidos! Veja o FAQ para mais detalhes: %s"
msgid "Nextcloud username"
msgstr "Usuário da Nextcloud"
@@ -1337,10 +1436,32 @@ msgstr "Usuário do WebDAV"
msgid "WebDAV password"
msgstr "Senha do WebDAV"
msgid "Custom TLS certificates"
msgstr "Certificados TLS customizados"
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
"Lista de caminhos para diretórios, separados por vírgula, de onde carregar "
"os certificados, ou caminhos para arquivos cert. Por exemplo, /my/cert_dir, /"
"other/custom.pem. Note que se você fizer mudanças nas configurações de TLS, "
"você tem que salvar as mudanças antes de clicar em \"Verificar a "
"configuração da sincronização\"."
msgid "Ignore TLS certificate errors"
msgstr "Ignorar erros de certificados TLS"
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Valor da opção inválida: \"%s\". Os valores possíveis são: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr "A tag \"%s\" já existe. Escolha um nome diferente."
msgid "Joplin Export File"
msgstr "Arquivo de Exportação do Joplin"
@@ -1353,8 +1474,11 @@ msgstr "Diretório de Exportação do Joplin"
msgid "Evernote Export File"
msgstr "Arquivo de Exportação do Evernote"
msgid "Json Export Directory"
msgstr "Diretório de Exportação JSON"
msgid "Directory"
msgstr "DIretório"
msgstr "Diretório"
#, javascript-format
msgid "Cannot load \"%s\" module for format \"%s\""
@@ -1428,6 +1552,12 @@ msgstr "Próximos alarmes"
msgid "On %s: %s"
msgstr "Em %s: %s"
msgid "Permission to use camera"
msgstr "Permissão para utilizar sua c\\u00e2mera"
msgid "Your permission to use your camera is required."
msgstr "É necessária a sua permissão para utilizar sua c\\u00e2mera."
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Atualmente, não há notas. Crie uma, clicando no botão (+)."
@@ -1456,9 +1586,11 @@ msgstr "Mover %d notas para o caderno \"%s\"?"
msgid "Press to set the decryption password."
msgstr "Pressione para configurar a senha de decriptação."
#, fuzzy
msgid "Clear alarm"
msgstr "Limpar alarme"
msgid "Save alarm"
msgstr "Definir alarme"
msgstr "Salvar alarme"
msgid "Select date"
msgstr "Selecionar data"
@@ -1469,9 +1601,40 @@ msgstr "Confirmar"
msgid "Cancel synchronisation"
msgstr "Cancelar sincronização"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Itens pesquisados: %d/%d."
msgid "Checking... Please wait."
msgstr "Verificando... Por favor aguarde."
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Sucesso! A configuração da sincronização parece estar correta."
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
"Erro. Verifique se a URL, nome de usuário, senha, etc., estão corretos e "
"tenha certeza que o destino da sincronização está acessível. O erro "
"reportado foi:"
msgid "The application has been authorised!"
msgstr "O aplicativo foi autorizado!"
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
"Não foi possível autorizar o aplicativo:\n"
"\n"
"%s\n"
"\n"
"Por favor tente novamente."
#, javascript-format
msgid "Decrypted items: %s / %s"
msgstr "Itens decriptados: %s / %s"
msgid "New tags:"
msgstr "Novas tags:"
@@ -1483,17 +1646,24 @@ msgid ""
"To work correctly, the app needs the following permissions. Please enable "
"them in your phone settings, in Apps > Joplin > Permissions"
msgstr ""
"Para funcionar corretamente, o app precisa das seguintes permissões. Por "
"favor, habilite-as nas configurações do seu telefone, em Apps >Joplin > "
"Permissões"
msgid ""
"- Storage: to allow attaching files to notes and to enable filesystem "
"synchronisation."
msgstr ""
"- Armazenamento: para permitir anexar arquivos a notas e para permitir a "
"sincronização do sistema de arquivos."
msgid "- Camera: to allow taking a picture and attaching it to a note."
msgstr ""
msgstr "- Câmera: para permitir tirar fotos e anexar a uma nota."
msgid "- Location: to allow attaching geo-location information to a note."
msgstr ""
"- Localização: para permitir anexar informações de geo-localização a uma "
"nota."
msgid "Joplin website"
msgstr "Site do Joplin"
@@ -1542,16 +1712,20 @@ msgstr "Descartar alterações"
#, javascript-format
msgid "No item with ID %s"
msgstr ""
msgstr "Nenhum item com ID %s"
#, javascript-format
msgid "The Joplin mobile app does not currently support this type of link: %s"
msgstr ""
msgstr "O app mobile do Joplin não suporta, atualmente, esse tipo de link: %s"
#, javascript-format
msgid "Unsupported image type: %s"
msgstr "Tipo de imagem não suportada: %s"
#, fuzzy
msgid "Take photo"
msgstr "Anexar foto"
msgid "Attach photo"
msgstr "Anexar foto"
@@ -1559,7 +1733,7 @@ msgid "Attach any file"
msgstr "Anexar qualquer arquivo"
msgid "Share"
msgstr ""
msgstr "Compartilhar"
msgid "Convert to note"
msgstr "Converter para nota"
@@ -1576,6 +1750,9 @@ msgstr "Exibir metadados"
msgid "View on map"
msgstr "Ver no mapa"
msgid "Go to source URL"
msgstr "Ir para a URL de origem"
msgid "Delete notebook"
msgstr "Excluir caderno"
@@ -1598,6 +1775,12 @@ msgstr "Você não possui cadernos. Crie um clicando no botão (+)."
msgid "Welcome"
msgstr "Bem-vindo"
#~ msgid "State: %s."
#~ msgstr "Estado: \"%s\"."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Já existe caderno com este título: \"%s\""
#~ msgid "Searches"
#~ msgstr "Pesquisas"

1650
CliClient/locales/ro.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -456,13 +456,17 @@ msgstr "Не удалось инициировать синхронизацию.
msgid "Starting synchronisation..."
msgstr "Начало синхронизации..."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "Отмена... Пожалуйста, ожидайте."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> может быть «add», «remove» или «list», чтобы назначить или "
"убрать [tag] с [note], или чтобы вывести список заметок, ассоциированых с "
@@ -626,15 +630,29 @@ msgstr "Вырезать"
msgid "Paste"
msgstr "Вставить"
#, fuzzy
msgid "Select all"
msgstr "Выбрать дату"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Поиск во всех заметках"
#, fuzzy
msgid "Search in current note"
msgstr "Поиск во всех заметках"
msgid "View"
msgstr "Вид"
@@ -703,6 +721,9 @@ msgstr "Да"
msgid "No"
msgstr "Нет"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -746,6 +767,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Показывать расширенные настройки"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr "Проверить настройки синхронизации"
@@ -753,12 +789,15 @@ msgstr "Проверить настройки синхронизации"
msgid "Notes and settings are stored in: %s"
msgstr "Заметки и настройки сохранены в: %s"
msgid "Save"
msgstr "Сохранить"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr "Сохранить"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -898,9 +937,24 @@ msgstr "Установить пароль"
msgid "Add or remove tags"
msgstr "Добавить или удалить теги"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Копировать"
msgid "Switch between note and to-do type"
msgstr "Переключить тип между заметкой и задачей"
#, fuzzy
msgid "Switch to note type"
msgstr "Переключить тип между заметкой и задачей"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Переключить тип между заметкой и задачей"
#, fuzzy
msgid "Copy Markdown link"
msgstr "Markdown"
@@ -918,6 +972,15 @@ msgid ""
"There is currently no notebook. Create one by clicking on \"New notebook\"."
msgstr "Сейчас здесь нет блокнотов. Создайте новый нажав «Новый блокнот»."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Открыть..."
@@ -931,6 +994,12 @@ msgstr "Сохранить как..."
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Неподдерживаемая ссыка или сообщение: %s"
@@ -949,6 +1018,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -986,6 +1058,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "Отмена..."
msgid "to-do"
msgstr "задача"
@@ -1036,6 +1115,14 @@ msgstr "Синхронизировать"
msgid "Notebooks"
msgstr "Блокноты"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Получено элементов: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Ресурсов: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Выберите, куда должен быть экспортирован статус синхронизации"
@@ -1080,6 +1167,9 @@ msgstr ""
"Не удалось обновить токен: отсутствуют данные аутентификации. Повторный "
"запуск синхронизации может решить проблему."
msgid "Untitled"
msgstr "Без имени"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1127,10 +1217,6 @@ msgstr "Удалено удалённых элементов: %d."
msgid "Fetched items: %d/%d."
msgstr "Получено элементов: %d/%d."
#, fuzzy, javascript-format
msgid "State: %s."
msgstr "Статус: «%s»."
msgid "Cancelling..."
msgstr "Отмена..."
@@ -1165,10 +1251,6 @@ msgstr "Конфликты"
msgid "Cannot move notebook to this location"
msgstr "Не удалось переместить заметку в блокнот «%s»"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Блокнот с таким названием уже существует: «%s»"
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr "Блокнот не может быть назван «%s», это зарезервированное название."
@@ -1185,9 +1267,6 @@ msgstr "Обновлено: %d."
msgid "created date"
msgstr "Создано: %d."
msgid "Untitled"
msgstr "Без имени"
msgid "This note does not have geolocation information."
msgstr "Эта заметка не содержит информации о геолокации."
@@ -1199,16 +1278,6 @@ msgstr "Не удалось скопировать заметку в блокн
msgid "Cannot move note to \"%s\" notebook"
msgstr "Не удалось переместить заметку в блокнот «%s»"
msgid "Text editor"
msgstr "Текстовый редактор"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Редактор, в котором будут открываться заметки. Если не задан, будет "
"произведена попытка автоматического определения редактора по умолчанию."
msgid "Language"
msgstr "Язык"
@@ -1261,9 +1330,22 @@ msgstr "Показывать иконку в панели задач"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Глобальный масштаб в процентах"
#, fuzzy
msgid "Editor font size"
msgstr "Семейство шрифтов редактора"
msgid "Editor font family"
msgstr "Семейство шрифтов редактора"
@@ -1293,6 +1375,18 @@ msgstr "%d час"
msgid "%d hours"
msgstr "%d часов"
#, fuzzy
msgid "Text editor command"
msgstr "Текстовый редактор"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Редактор, в котором будут открываться заметки. Если не задан, будет "
"произведена попытка автоматического определения редактора по умолчанию."
msgid "Show advanced options"
msgstr "Показывать расширенные настройки"
@@ -1319,6 +1413,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV URL"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Имя пользователя Nextcloud"
@@ -1334,10 +1435,27 @@ msgstr "Имя пользователя WebDAV"
msgid "WebDAV password"
msgstr "Пароль WebDAV"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Неверное значение параметра: «%s». Доступные значения: %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr "Файл экспорта Joplin"
@@ -1350,6 +1468,10 @@ msgstr "Папка экспорта Joplin"
msgid "Evernote Export File"
msgstr "Файл экспорта Evernote"
#, fuzzy
msgid "Json Export Directory"
msgstr "Папка экспорта Joplin"
msgid "Directory"
msgstr "Директория"
@@ -1425,6 +1547,12 @@ msgstr "Грядущие напоминания"
msgid "On %s: %s"
msgstr "В %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Сейчас здесь нет заметок. Создаёте новую, нажав кнопку (+)."
@@ -1453,6 +1581,10 @@ msgstr "Переместить %d заметок в блокнот «%s»?"
msgid "Press to set the decryption password."
msgstr "Нажмите, чтобы установить пароль для расшифровки."
#, fuzzy
msgid "Clear alarm"
msgstr "Установить напоминание"
#, fuzzy
msgid "Save alarm"
msgstr "Установить напоминание"
@@ -1466,8 +1598,34 @@ msgstr "Подтвердить"
msgid "Cancel synchronisation"
msgstr "Отменить синхронизацию"
#, fuzzy
msgid "Checking... Please wait."
msgstr "Отмена... Пожалуйста, ожидайте."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Проверить настройки синхронизации"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "Приложение успешно авторизовано."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Получено элементов: %d/%d."
msgid "New tags:"
@@ -1550,6 +1708,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Неподдерживаемый формат изображения: %s"
#, fuzzy
msgid "Take photo"
msgstr "Прикрепить фото"
msgid "Attach photo"
msgstr "Прикрепить фото"
@@ -1574,6 +1736,9 @@ msgstr "Показать метаданные"
msgid "View on map"
msgstr "Посмотреть на карте"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Удалить блокнот"
@@ -1596,6 +1761,13 @@ msgstr "У вас сейчас нет блокнота. Создайте его
msgid "Welcome"
msgstr "Добро пожаловать"
#, fuzzy
#~ msgid "State: %s."
#~ msgstr "Статус: «%s»."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Блокнот с таким названием уже существует: «%s»"
#~ msgid "Searches"
#~ msgstr "Запросы"

View File

@@ -455,13 +455,17 @@ msgstr "Ni moč zagnati sinhronizatorja."
msgid "Starting synchronisation..."
msgstr "Sinhronizacija se začenja."
msgid "Downloading resources..."
msgstr ""
msgid "Cancelling... Please wait."
msgstr "V preklicu...Prosim počakajte."
#, fuzzy
msgid ""
"<tag-command> can be \"add\", \"remove\" or \"list\" to assign or remove "
"[tag] from [note], or to list the notes associated with [tag]. The command "
"`tag list` can be used to list all the tags."
"`tag list` can be used to list all the tags (use -l for long option)."
msgstr ""
"<tag-command> je lahko \"dodaj\", \"odstrani\" ali \"naštej\", da dodeliš "
"ali odstraniš [tag] from [note] ali našteje zabeležke povezane z oznako "
@@ -625,15 +629,29 @@ msgstr "Izreži"
msgid "Paste"
msgstr "Prilepi"
#, fuzzy
msgid "Select all"
msgstr "Izberi datum"
msgid "Bold"
msgstr ""
msgid "Italic"
msgstr ""
msgid "Insert Date Time"
msgstr ""
msgid "Edit in external editor"
msgstr ""
msgid "Search in all the notes"
msgstr "Išči znotraj vseh zabeležk"
#, fuzzy
msgid "Search in current note"
msgstr "Išči znotraj vseh zabeležk"
msgid "View"
msgstr "Pogled"
@@ -702,6 +720,9 @@ msgstr "Da"
msgid "No"
msgstr "Ne"
msgid "Token has been copied to the clipboard!"
msgstr ""
msgid "The web clipper service is enabled and set to auto-start."
msgstr ""
@@ -745,6 +766,21 @@ msgstr ""
msgid "Download and install the relevant extension for your browser:"
msgstr ""
#, fuzzy
msgid "Advanced options"
msgstr "Pokaži napredne možnosti"
msgid "Authorisation token:"
msgstr ""
msgid "Copy token"
msgstr ""
msgid ""
"This authorisation token is only needed to allow third-party applications to "
"access Joplin."
msgstr ""
msgid "Check synchronisation configuration"
msgstr "Preveri nastavitve sinhronizacije"
@@ -752,12 +788,15 @@ msgstr "Preveri nastavitve sinhronizacije"
msgid "Notes and settings are stored in: %s"
msgstr "Zabeležke in nastavitve so shranjene v: %s"
msgid "Save"
msgstr "Shrani"
msgid "Apply"
msgstr ""
msgid "Submit"
msgstr ""
msgid "Save"
msgstr "Shrani"
msgid ""
"Disabling encryption means *all* your notes and attachments are going to be "
"re-synchronised and sent unencrypted to the sync target. Do you wish to "
@@ -898,9 +937,24 @@ msgstr "Nastavi geslo"
msgid "Add or remove tags"
msgstr "Dodaj ali odstrani oznake"
msgid "Duplicate"
msgstr ""
#, fuzzy, javascript-format
msgid "%s - Copy"
msgstr "Kopiraj"
msgid "Switch between note and to-do type"
msgstr "Menjaj med zabeležko in seznamom opravil"
#, fuzzy
msgid "Switch to note type"
msgstr "Menjaj med zabeležko in seznamom opravil"
#, fuzzy
msgid "Switch to to-do type"
msgstr "Menjaj med zabeležko in seznamom opravil"
#, fuzzy
msgid "Copy Markdown link"
msgstr "Sistem označevanja"
@@ -922,6 +976,15 @@ msgstr ""
"Trenutno ni tukaj nobene beležnice. Ustvarite jo z klikom na \"Nova beležnica"
"\"."
msgid "Location"
msgstr ""
msgid "URL"
msgstr ""
msgid "Note properties"
msgstr ""
msgid "Open..."
msgstr "Odpri..."
@@ -935,6 +998,12 @@ msgstr "Shrani kot..."
msgid "Copy path to clipboard"
msgstr ""
msgid "Copy Link Address"
msgstr ""
msgid "This attachment is not downloaded or not decrypted yet."
msgstr ""
#, javascript-format
msgid "Unsupported link or message: %s"
msgstr "Nepodprta povezava ali sporočilo: %s"
@@ -953,6 +1022,9 @@ msgstr ""
msgid "emphasized text"
msgstr ""
msgid "List item"
msgstr ""
msgid "Insert Hyperlink"
msgstr ""
@@ -990,6 +1062,13 @@ msgstr ""
msgid "Horizontal Rule"
msgstr ""
msgid "Click to stop external editing"
msgstr ""
#, fuzzy
msgid "Watching..."
msgstr "V preklicu..."
msgid "to-do"
msgstr "seznam opravil"
@@ -1040,6 +1119,14 @@ msgstr "Sinhroniziraj"
msgid "Notebooks"
msgstr "Beležnice"
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgstr "Preneseni predmeti: %d/%d."
#, fuzzy, javascript-format
msgid "Fetching resources: %d"
msgstr "Viri: %d."
msgid "Please select where the sync status should be exported to"
msgstr "Prosim izberite, kam želite izvoziti sinhronizacijski status"
@@ -1084,6 +1171,9 @@ msgstr ""
"Ne gre osvežiti tokena: manjkajo podatki o avtentikaciji. Ponovno zaženite "
"sinhronizacijo, da morda popravite težavo."
msgid "Untitled"
msgstr "Neimenovano"
msgid ""
"Could not synchronize with OneDrive.\n"
"\n"
@@ -1131,10 +1221,6 @@ msgstr "Izbrisani oddaljeni predmeti: %d."
msgid "Fetched items: %d/%d."
msgstr "Preneseni predmeti: %d/%d."
#, javascript-format
msgid "State: %s."
msgstr "Stanje: %s."
msgid "Cancelling..."
msgstr "V preklicu..."
@@ -1169,10 +1255,6 @@ msgstr "Konfikti"
msgid "Cannot move notebook to this location"
msgstr "Ni moč premakniti zabeležke v \"%s\" beležnico"
#, javascript-format
msgid "A notebook with this title already exists: \"%s\""
msgstr "Beležnica s tem naslovom že obstaja: \"%s\""
#, javascript-format
msgid "Notebooks cannot be named \"%s\", which is a reserved title."
msgstr "Beležnica ne more biti imenovana \"%s\", ker je to rezerviran naslov."
@@ -1189,9 +1271,6 @@ msgstr "Posodobljeno: %d."
msgid "created date"
msgstr "Ustvarjeno: %d."
msgid "Untitled"
msgstr "Neimenovano"
msgid "This note does not have geolocation information."
msgstr "Ta zabeležke nima geografske lokacije."
@@ -1203,16 +1282,6 @@ msgstr "Ni moč kopirati zabeležke v \"%s\" beležnico"
msgid "Cannot move note to \"%s\" notebook"
msgstr "Ni moč premakniti zabeležke v \"%s\" beležnico"
msgid "Text editor"
msgstr "Urejevalnik besedila"
msgid ""
"The editor that will be used to open a note. If none is provided it will try "
"to auto-detect the default editor."
msgstr ""
"Urejevalnik, ki bo uporabljen za odpiranje zabeležk. Če noben ni izbran, bo "
"avtomatsko zaznan privzeti urejevalnik."
msgid "Language"
msgstr "Jezik"
@@ -1265,9 +1334,22 @@ msgstr "Pokaži ikono v območju za obvestila(opravilna vrstica)"
msgid "Note: Does not work in all desktop environments."
msgstr ""
msgid ""
"This will allow Joplin to run in the background. It is recommended to enable "
"this setting so that your notes are constantly being synchronised, thus "
"reducing the number of conflicts."
msgstr ""
msgid "Start application minimised in the tray icon"
msgstr ""
msgid "Global zoom percentage"
msgstr "Celokupen procent povečave"
#, fuzzy
msgid "Editor font size"
msgstr "Družina urejevalnika besedilnega stila"
msgid "Editor font family"
msgstr "Družina urejevalnika besedilnega stila"
@@ -1297,6 +1379,18 @@ msgstr "Števil ur: %d"
msgid "%d hours"
msgstr "Število ur: %d"
#, fuzzy
msgid "Text editor command"
msgstr "Urejevalnik besedila"
#, fuzzy
msgid ""
"The editor command (may include arguments) that will be used to open a note. "
"If none is provided it will try to auto-detect the default editor."
msgstr ""
"Urejevalnik, ki bo uporabljen za odpiranje zabeležk. Če noben ni izbran, bo "
"avtomatsko zaznan privzeti urejevalnik."
msgid "Show advanced options"
msgstr "Pokaži napredne možnosti"
@@ -1323,6 +1417,13 @@ msgstr ""
msgid "Nextcloud WebDAV URL"
msgstr "Nextcloud WebDAV URL"
#, javascript-format
msgid ""
"Attention: If you change this location, make sure you copy all your content "
"to it before syncing, otherwise all files will be removed! See the FAQ for "
"more details: %s"
msgstr ""
msgid "Nextcloud username"
msgstr "Nextcloud uporabniško ime"
@@ -1338,10 +1439,27 @@ msgstr "WebDAV uporabniško ime"
msgid "WebDAV password"
msgstr "WebDAV geslo"
msgid "Custom TLS certificates"
msgstr ""
msgid ""
"Comma-separated list of paths to directories to load the certificates from, "
"or path to individual cert files. For example: /my/cert_dir, /other/custom."
"pem. Note that if you make changes to the TLS settings, you must save your "
"changes before clicking on \"Check synchronisation configuration\"."
msgstr ""
msgid "Ignore TLS certificate errors"
msgstr ""
#, javascript-format
msgid "Invalid option value: \"%s\". Possible values are: %s."
msgstr "Neveljavna vrednost: \"%s\". Možne vrednosti so : %s."
#, javascript-format
msgid "The tag \"%s\" already exists. Please choose a different name."
msgstr ""
msgid "Joplin Export File"
msgstr "Joplin izvozna datoteka"
@@ -1354,6 +1472,10 @@ msgstr "Joplin izvozno mesto"
msgid "Evernote Export File"
msgstr "Evernote izvozna datoteka"
#, fuzzy
msgid "Json Export Directory"
msgstr "Joplin izvozno mesto"
msgid "Directory"
msgstr "Mesto datoteke"
@@ -1428,6 +1550,12 @@ msgstr "Prihajajoči alarmi"
msgid "On %s: %s"
msgstr "Vključeno %s: %s"
msgid "Permission to use camera"
msgstr ""
msgid "Your permission to use your camera is required."
msgstr ""
msgid "There are currently no notes. Create one by clicking on the (+) button."
msgstr "Trenutno ni zabeležk. Ustvarite jo s klikom na (+) gumb."
@@ -1456,6 +1584,10 @@ msgstr "Premakni %d zabeležk v beležnico \"%s\"?"
msgid "Press to set the decryption password."
msgstr "Klikni za nastavitev dekripcijskega gesla."
#, fuzzy
msgid "Clear alarm"
msgstr "Nastavi alarm"
#, fuzzy
msgid "Save alarm"
msgstr "Nastavi alarm"
@@ -1469,8 +1601,34 @@ msgstr "Potrdi"
msgid "Cancel synchronisation"
msgstr "Prekliči sinhronizacijo"
#, fuzzy
msgid "Checking... Please wait."
msgstr "V preklicu...Prosim počakajte."
#, fuzzy
msgid "Success! Synchronisation configuration appears to be correct."
msgstr "Preveri nastavitve sinhronizacije"
msgid ""
"Error. Please check that URL, username, password, etc. are correct and that "
"the sync target is accessible. The reported error was:"
msgstr ""
#, fuzzy
msgid "The application has been authorised!"
msgstr "Aplikacija je bila uspešno avtorizirana."
#, javascript-format
msgid ""
"Could not authorise application:\n"
"\n"
"%s\n"
"\n"
"Please try again."
msgstr ""
#, fuzzy, javascript-format
msgid "Decrypting items: %d/%d"
msgid "Decrypted items: %s / %s"
msgstr "Preneseni predmeti: %d/%d."
msgid "New tags:"
@@ -1553,6 +1711,10 @@ msgstr ""
msgid "Unsupported image type: %s"
msgstr "Nepodprt tip slike: %s"
#, fuzzy
msgid "Take photo"
msgstr "Pripni fotografijo"
msgid "Attach photo"
msgstr "Pripni fotografijo"
@@ -1577,6 +1739,9 @@ msgstr "Prikaži meta podatke"
msgid "View on map"
msgstr "Prikaži na zemljevidu"
msgid "Go to source URL"
msgstr ""
msgid "Delete notebook"
msgstr "Izbriši beležnico"
@@ -1599,5 +1764,11 @@ msgstr "Trenutno nimate nobene beležnice. Ustvarite jo s klikom na (+) gumb."
msgid "Welcome"
msgstr "Dobrodošli"
#~ msgid "State: %s."
#~ msgstr "Stanje: %s."
#~ msgid "A notebook with this title already exists: \"%s\""
#~ msgstr "Beležnica s tem naslovom že obstaja: \"%s\""
#~ msgid "Searches"
#~ msgstr "Iskalni niz"

1790
CliClient/locales/sv.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,7 @@
],
"owner": "Laurent Cozic"
},
"version": "1.0.107",
"version": "1.0.118",
"bin": {
"joplin": "./main.js"
},
@@ -37,12 +37,14 @@
"fs-extra": "^5.0.0",
"html-entities": "^1.2.1",
"html-minifier": "^3.5.15",
"image-data-uri": "^2.0.0",
"image-type": "^3.0.0",
"joplin-turndown": "^4.0.3",
"joplin-turndown-plugin-gfm": "^1.0.2",
"joplin-turndown": "^4.0.9",
"joplin-turndown-plugin-gfm": "^1.0.7",
"jssha": "^2.3.0",
"levenshtein": "^1.0.5",
"lodash": "^4.17.4",
"markdown-it": "^8.4.2",
"md5": "^2.2.1",
"mime": "^2.0.3",
"moment": "^2.18.1",
@@ -56,12 +58,13 @@
"redux": "^3.7.2",
"sax": "^1.2.2",
"server-destroy": "^1.0.1",
"sharp": "^0.18.4",
"sharp": "^0.20.8",
"sprintf-js": "^1.1.1",
"sqlite3": "^3.1.8",
"sqlite3": "^4.0.1",
"string-padding": "^1.0.2",
"string-to-stream": "^1.1.0",
"strip-ansi": "^4.0.0",
"syswide-cas": "^5.2.0",
"tar": "^4.4.0",
"tcp-port-used": "^0.1.2",
"tkwidgets": "^0.5.26",

View File

@@ -22,14 +22,18 @@ trap finish EXIT
cd "$ROOT_DIR"
npm test tests-build/ArrayUtils.js
npm test tests-build/encryption.js
npm test tests-build/EnexToMd.js
npm test tests-build/HtmlToMd.js
npm test tests-build/markdownUtils.js
npm test tests-build/models_BaseItem.js
npm test tests-build/models_Folder.js
npm test tests-build/models_Note.js
npm test tests-build/models_Tag.js
npm test tests-build/models_Setting.js
npm test tests-build/pathUtils.js
npm test tests-build/services_InteropService.js
npm test tests-build/services_ResourceService.js
npm test tests-build/synchronizer.js
npm test tests-build/urlUtils.js
npm test tests-build/urlUtils.js
npm test tests-build/encryption.js
npm test tests-build/services_rest_Api.js
npm test tests-build/synchronizer.js

View File

@@ -1,5 +1,6 @@
require('app-module-path').addPath(__dirname);
const os = require('os');
const { time } = require('lib/time-utils.js');
const { filename } = require('lib/path-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
@@ -37,9 +38,14 @@ describe('EnexToMd', function() {
// if (htmlFilename !== 'text2.html') continue;
const html = await shim.fsDriver().readFile(htmlPath);
const expectedMd = await shim.fsDriver().readFile(mdPath);
let expectedMd = await shim.fsDriver().readFile(mdPath);
const actualMd = await enexXmlToMd('<div>' + html + '</div>', []);
let actualMd = await enexXmlToMd('<div>' + html + '</div>', []);
if (os.EOL === '\r\n') {
expectedMd = expectedMd.replace(/\r\n/g, '\n')
actualMd = actualMd.replace(/\r\n/g, '\n')
}
if (actualMd !== expectedMd) {
console.info('');

View File

@@ -1,5 +1,6 @@
require('app-module-path').addPath(__dirname);
const os = require('os');
const { time } = require('lib/time-utils.js');
const { filename } = require('lib/path-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
@@ -36,12 +37,17 @@ describe('HtmlToMd', function() {
const htmlPath = basePath + '/' + htmlFilename;
const mdPath = basePath + '/' + filename(htmlFilename) + '.md';
// if (htmlFilename !== 'code_1.html') continue;
// if (htmlFilename !== 'anchor_with_url_with_spaces.html') continue;
const html = await shim.fsDriver().readFile(htmlPath);
const expectedMd = await shim.fsDriver().readFile(mdPath);
let expectedMd = await shim.fsDriver().readFile(mdPath);
const actualMd = await htmlToMd.parse('<div>' + html + '</div>', []);
let actualMd = await htmlToMd.parse('<div>' + html + '</div>', []);
if (os.EOL === '\r\n') {
expectedMd = expectedMd.replace(/\r\n/g, '\n')
actualMd = actualMd.replace(/\r\n/g, '\n')
}
if (actualMd !== expectedMd) {
console.info('');

View File

@@ -0,0 +1,5 @@
<ul>
<li><div>This note has an unordered list</div></li>
<li><div>List item</div></li>
<li><div>List item</div></li>
</ul>

View File

@@ -0,0 +1,3 @@
- This note has an unordered list
- List item
- List item

View File

@@ -0,0 +1 @@
<a href="http://example.com/That is not right"/>Testing</a>

View File

@@ -0,0 +1 @@
[Testing](http://example.com/That%20is%20not%20right)

View File

@@ -0,0 +1,29 @@
Some pictures:
<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source media="(min-width: 768px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w">
<source media="(min-width: 768px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w">
<source media="(min-width: 481px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w">
<source media="(min-width: 481px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w">
<source media="(min-width: 321px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop&amp;dpr=1.5 675w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop&amp;dpr=1.5 675w">
<source media="(min-width: 321px)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop 450w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop 450w">
<source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop&amp;dpr=1.5 480w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop&amp;dpr=1.5 480w">
<source media="(min-width: 0px)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop 320w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop 320w">
<!--[if IE 9]></video><![endif]-->
<img class=" lazyloaded" title="" alt="" id="img-id-0">
</picture>
<picture>
<!--[if IE 9]><video style="display: none;"><![endif]-->
<source media="(min-width: 768px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w">
<source media="(min-width: 768px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w">
<source media="(min-width: 481px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop&amp;dpr=1.5 882w">
<source media="(min-width: 481px)" sizes="588px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=588&amp;h=900&amp;fit=crop 588w">
<source media="(min-width: 321px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop&amp;dpr=1.5 675w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop&amp;dpr=1.5 675w">
<source media="(min-width: 321px)" sizes="450px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop 450w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=450&amp;h=688&amp;fit=crop 450w">
<source media="(min-width: 0px) and (-webkit-min-device-pixel-ratio: 1.25), (min-width: px) and (min-resolution: 120dpi)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop&amp;dpr=1.5 480w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop&amp;dpr=1.5 480w">
<source media="(min-width: 0px)" sizes="320px" data-srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop 320w" srcset="https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&amp;w=320&amp;h=489&amp;fit=crop 320w">
<!--[if IE 9]></video><![endif]-->
<img class=" lazyloaded" title="" alt="" id="img-id-0" src="http://example.com/test.gif">
</picture>

View File

@@ -0,0 +1 @@
Some pictures: ![](https://static2.cbrimages.com/wp-content/uploads/2018/09/Die-01-cvrA.jpg?q=35&w=588&h=900&fit=crop&dpr=1.5) ![](http://example.com/test.gif)

View File

@@ -0,0 +1,5 @@
<p>Some text, not an image, so it should remain escaped:</p>
<p>&lt;img src="http://test.com/image.png" /&gt;</p>
<p>&lt;p class="testing"&gt;Paragraph example&lt;/p&gt;
<p>But this is code so it can be unescaped:</p>
<pre><code>&lt;img src="http://test.com/image.png" /&gt;</code></pre>

View File

@@ -0,0 +1,9 @@
Some text, not an image, so it should remain escaped:
&lt;img src="http://test.com/image.png" /&gt;
&lt;p class="testing"&gt;Paragraph example&lt;/p&gt;
But this is code so it can be unescaped:
<img src="http://test.com/image.png" />

View File

@@ -39,6 +39,7 @@ describe('markdownUtils', function() {
['![something](http://test.com/img.png)', ['http://test.com/img.png']],
['![something](http://test.com/img.png) ![something2](http://test.com/img2.png)', ['http://test.com/img.png', 'http://test.com/img2.png']],
['![something](http://test.com/img.png "Some description")', ['http://test.com/img.png']],
['![something](https://test.com/ohoh_(123).png)', ['https://test.com/ohoh_(123).png']],
];
for (let i = 0; i < testCases.length; i++) {

View File

@@ -0,0 +1,51 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseItem = require('lib/models/BaseItem.js');
const Resource = require('lib/models/Resource.js');
const BaseModel = require('lib/BaseModel.js');
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
async function allItems() {
let folders = await Folder.all();
let notes = await Note.all();
return folders.concat(notes);
}
describe('models_BaseItem', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
// it('should be able to exclude keys when syncing', asyncTest(async () => {
// let folder1 = await Folder.save({ title: "folder1" });
// let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
// await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
// let resource1 = (await Resource.all())[0];
// console.info(await Resource.serializeForSync(resource1));
// }));
// This is to handle the case where a property is removed from a BaseItem table - in that case files in
// the sync target will still have the old property but we don't need it locally.
it('should ignore properties that are present in sync file but not in database when serialising', asyncTest(async () => {
let folder = await Folder.save({ title: "folder1" });
let serialized = await Folder.serialize(folder);
serialized += "\nignore_me: true"
let unserialized = await Folder.unserialize(serialized);
expect('ignore_me' in unserialized).toBe(false);
}));
});

View File

@@ -5,6 +5,7 @@ const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const BaseModel = require('lib/BaseModel.js');
const ArrayUtils = require('lib/ArrayUtils.js');
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
@@ -34,6 +35,56 @@ describe('models_Note', function() {
expect(items.length).toBe(2);
expect(items[0].type_).toBe(BaseModel.TYPE_NOTE);
expect(items[1].type_).toBe(BaseModel.TYPE_RESOURCE);
const resource2 = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
const resource3 = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
note2.body += '<img alt="bla" src=":/' + resource2.id + '"/>';
note2.body += '<img src=\':/' + resource3.id + '\' />';
items = await Note.linkedItems(note2.body);
expect(items.length).toBe(4);
}));
it('should find linked items', asyncTest(async () => {
const testCases = [
['[](:/06894e83b8f84d3d8cbe0f1587f9e226)', ['06894e83b8f84d3d8cbe0f1587f9e226']],
['[](:/06894e83b8f84d3d8cbe0f1587f9e226) [](:/06894e83b8f84d3d8cbe0f1587f9e226)', ['06894e83b8f84d3d8cbe0f1587f9e226']],
['[](:/06894e83b8f84d3d8cbe0f1587f9e226) [](:/06894e83b8f84d3d8cbe0f1587f9e227)', ['06894e83b8f84d3d8cbe0f1587f9e226', '06894e83b8f84d3d8cbe0f1587f9e227']],
['[](:/06894e83b8f84d3d8cbe0f1587f9e226 "some title")', ['06894e83b8f84d3d8cbe0f1587f9e226']],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
const input = t[0];
const expected = t[1];
const actual = Note.linkedItemIds(input);
const contentEquals = ArrayUtils.contentEquals(actual, expected);
// console.info(contentEquals, input, expected, actual);
expect(contentEquals).toBe(true);
}
}));
it('should change the type of notes', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await Note.load(note1.id);
let changedNote = Note.changeNoteType(note1, 'todo');
expect(changedNote === note1).toBe(false);
expect(!!changedNote.is_todo).toBe(true);
await Note.save(changedNote);
note1 = await Note.load(note1.id);
changedNote = Note.changeNoteType(note1, 'todo');
expect(changedNote === note1).toBe(true);
expect(!!changedNote.is_todo).toBe(true);
note1 = await Note.load(note1.id);
changedNote = Note.changeNoteType(note1, 'note');
expect(changedNote === note1).toBe(false);
expect(!!changedNote.is_todo).toBe(false);
}));
});

View File

@@ -0,0 +1,59 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Resource = require('lib/models/Resource.js');
const BaseModel = require('lib/BaseModel.js');
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('models_Resource', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should have a "done" fetch_status when created locally', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
let ls = await Resource.localState(resource1);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_DONE);
}));
it('should have a default local state', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
let ls = await Resource.localState(resource1);
expect(!ls.id).toBe(true);
expect(ls.resource_id).toBe(resource1.id);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_DONE);
}));
it('should save and delete local state', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
await Resource.setLocalState(resource1, { fetch_status: Resource.FETCH_STATUS_IDLE });
let ls = await Resource.localState(resource1);
expect(!!ls.id).toBe(true);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_IDLE);
await Resource.delete(resource1.id);
ls = await Resource.localState(resource1);
expect(!ls.id).toBe(true);
}));
});

View File

@@ -0,0 +1,45 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { asyncTest, fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const BaseModel = require('lib/BaseModel.js');
const { shim } = require('lib/shim');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('models_Tag', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should add tags by title', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await Tag.setNoteTagsByTitles(note1.id, ['un', 'deux']);
const noteTags = await Tag.tagsByNoteId(note1.id);
expect(noteTags.length).toBe(2);
}));
it('should not allow renaming tag to existing tag names', asyncTest(async () => {
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await Tag.setNoteTagsByTitles(note1.id, ['un', 'deux']);
const tagUn = await Tag.loadByTitle('un');
const hasThrown = await checkThrowAsync(async () => await Tag.save({ id: tagUn.id, title: 'deux' }, { userSideValidation: true }));
expect(hasThrown).toBe(true);
}));
});

View File

@@ -0,0 +1,39 @@
require('app-module-path').addPath(__dirname);
const { friendlySafeFilename } = require('lib/path-utils.js');
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
describe('pathUtils', function() {
beforeEach(async (done) => {
done();
});
it('should create friendly safe filename', async (done) => {
const testCases = [
['生活', '生活'],
['not/good', 'not_good'],
['really/not/good', 'really_not_good'],
['con', '___'],
['no space at the end ', 'no space at the end'],
['nor dots...', 'nor dots'],
[' no space before either', 'no space before either'],
['thatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylong', 'thatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylongthatsreallylong'],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
expect(friendlySafeFilename(t[0])).toBe(t[1]);
}
expect(!!friendlySafeFilename('')).toBe(true);
expect(!!friendlySafeFilename('...')).toBe(true);
done();
});
});

View File

@@ -310,4 +310,51 @@ describe('services_InteropService', function() {
expect(note2_2.body.indexOf(note1_2.id) >= 0).toBe(true);
}));
it('should export into json format', asyncTest(async () => {
const service = new InteropService();
let folder1 = await Folder.save({ title: 'folder1' });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await Note.load(note1.id);
const filePath = exportDir();
await service.export({ path: filePath, format: 'json' });
// verify that the json files exist and can be parsed
const items = [folder1, note1];
for (let i = 0; i < items.length; i++) {
const jsonFile = filePath + '/' + items[i].id + '.json';
let json = await fs.readFile(jsonFile, 'utf-8');
let obj = JSON.parse(json);
expect(obj.id).toBe(items[i].id);
expect(obj.type_).toBe(items[i].type_);
expect(obj.title).toBe(items[i].title);
expect(obj.body).toBe(items[i].body);
}
}));
it('should export MD with unicode filenames', asyncTest(async () => {
const service = new InteropService();
let folder1 = await Folder.save({ title: 'folder1' });
let folder2 = await Folder.save({ title: 'ジョプリン' });
let note1 = await Note.save({ title: '生活', parent_id: folder1.id });
let note2 = await Note.save({ title: '生活', parent_id: folder1.id });
let note2b = await Note.save({ title: '生活', parent_id: folder1.id });
let note3 = await Note.save({ title: '', parent_id: folder1.id });
let note4 = await Note.save({ title: '', parent_id: folder1.id });
let note5 = await Note.save({ title: 'salut, ça roule ?', parent_id: folder1.id });
let note6 = await Note.save({ title: 'ジョプリン', parent_id: folder2.id });
const outDir = exportDir();
await service.export({ path: outDir, format: 'md' });
expect(await shim.fsDriver().exists(outDir + '/folder1/生活.md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/生活 (1).md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/生活 (2).md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/Untitled.md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/Untitled (1).md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/folder1/salut, ça roule _.md')).toBe(true);
expect(await shim.fsDriver().exists(outDir + '/ジョプリン/ジョプリン.md')).toBe(true);
}));
});

View File

@@ -8,6 +8,7 @@ const Note = require('lib/models/Note.js');
const Tag = require('lib/models/Tag.js');
const NoteTag = require('lib/models/NoteTag.js');
const Resource = require('lib/models/Resource.js');
const ItemChange = require('lib/models/ItemChange.js');
const NoteResource = require('lib/models/NoteResource.js');
const ResourceService = require('lib/services/ResourceService.js');
const fs = require('fs-extra');
@@ -79,7 +80,6 @@ describe('services_ResourceService', function() {
let note2 = await Note.save({ title: 'ma deuxième note', parent_id: folder1.id });
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
const resourcePath = Resource.fullPath(resource1);
await service.indexNoteResources();
@@ -96,4 +96,54 @@ describe('services_ResourceService', function() {
expect(!!(await Resource.load(resource1.id))).toBe(true);
}));
it('should not delete a resource that has never been associated with any note, because it probably means the resource came via sync, and associated note has not arrived yet', asyncTest(async () => {
const service = new ResourceService();
const resource = await shim.createResourceFromPath(__dirname + '/../tests/support/photo.jpg');
await service.indexNoteResources();
await service.deleteOrphanResources(0);
expect((await Resource.all()).length).toBe(1);
}));
it('should not delete resource if it is used in an IMG tag', asyncTest(async () => {
const service = new ResourceService();
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
await service.indexNoteResources();
await Note.save({ id: note1.id, body: 'This is HTML: <img src=":/' + resource1.id + '"/>' });
await service.indexNoteResources();
await service.deleteOrphanResources(0);
expect(!!(await Resource.load(resource1.id))).toBe(true);
}));
it('should not process twice the same change', asyncTest(async () => {
const service = new ResourceService();
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
note1 = await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
await service.indexNoteResources();
const before = (await NoteResource.all())[0];
await time.sleep(0.1);
await service.indexNoteResources();
const after = (await NoteResource.all())[0];
expect(before.last_seen_time).toBe(after.last_seen_time);
}));
});

View File

@@ -0,0 +1,188 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const SearchEngine = require('lib/services/SearchEngine');
const Note = require('lib/models/Note');
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
let engine = null;
describe('services_SearchEngine', function() {
beforeEach(async (done) => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
engine = new SearchEngine();
engine.setDb(db());
done();
});
it('should keep the content and FTS table in sync', async (done) => {
let rows, n1, n2, n3;
n1 = await Note.save({ title: "a" });
n2 = await Note.save({ title: "b" });
rows = await engine.search('a');
expect(rows.length).toBe(1);
expect(rows[0].title).toBe('a');
await Note.delete(n1.id);
rows = await engine.search('a');
expect(rows.length).toBe(0);
rows = await engine.search('b');
expect(rows[0].title).toBe('b');
await Note.save({ id: n2.id, title: 'c' });
rows = await engine.search('b');
expect(rows.length).toBe(0);
rows = await engine.search('c');
expect(rows[0].title).toBe('c');
await Note.save({ id: n2.id, encryption_applied: 1 });
rows = await engine.search('c');
expect(rows.length).toBe(0);
await Note.save({ id: n2.id, encryption_applied: 0 });
rows = await engine.search('c');
expect(rows.length).toBe(1);
done();
});
it('should order search results by relevance (1)', async (done) => {
const n1 = await Note.save({ title: "abcd efgh" }); // 3
const n2 = await Note.save({ title: "abcd aaaaa abcd abcd" }); // 1
const n3 = await Note.save({ title: "abcd aaaaa bbbb eeee abcd" }); // 2
const rows = await engine.search('abcd');
expect(rows[0].id).toBe(n2.id);
expect(rows[1].id).toBe(n3.id);
expect(rows[2].id).toBe(n1.id);
done();
});
it('should order search results by relevance (2)', async (done) => {
// 1
const n1 = await Note.save({ title: "abcd efgh", body: "XX abcd XX efgh" });
// 4
const n2 = await Note.save({ title: "abcd aaaaa bbbb eeee efgh" });
// 3
const n3 = await Note.save({ title: "abcd aaaaa efgh" });
// 2
const n4 = await Note.save({ title: "blablablabla blabla bla abcd X efgh" });
// 5
const n5 = await Note.save({ title: "occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh occurence many times but very abcd spread appart spread appart spread appart spread appart spread appart efgh" });
const rows = await engine.search('abcd efgh');
expect(rows[0].id).toBe(n1.id);
expect(rows[1].id).toBe(n4.id);
expect(rows[2].id).toBe(n3.id);
expect(rows[3].id).toBe(n2.id);
expect(rows[4].id).toBe(n5.id);
done();
});
it('should supports various query types', async (done) => {
let rows;
const n1 = await Note.save({ title: "abcd efgh ijkl", body: "aaaa bbbb" });
const n2 = await Note.save({ title: "iiii efgh bbbb", body: "aaaa bbbb" });
rows = await engine.search('abcd ijkl');
expect(rows.length).toBe(1);
rows = await engine.search('"abcd ijkl"');
expect(rows.length).toBe(0);
rows = await engine.search('"abcd efgh"');
expect(rows.length).toBe(1);
rows = await engine.search('title:abcd');
expect(rows.length).toBe(1);
rows = await engine.search('title:efgh');
expect(rows.length).toBe(2);
rows = await engine.search('body:abcd');
expect(rows.length).toBe(0);
rows = await engine.search('body:bbbb');
expect(rows.length).toBe(2);
rows = await engine.search('body:bbbb iiii');
expect(rows.length).toBe(1);
done();
});
it('should parse normal query strings', async (done) => {
let rows;
const testCases = [
['abcd efgh', { _: ['abcd', 'efgh'] }],
['abcd efgh', { _: ['abcd', 'efgh'] }],
['title:abcd efgh', { _: ['efgh'], title: ['abcd'] }],
['title:abcd', { title: ['abcd'] }],
['"abcd efgh"', { _: ['abcd efgh'] }],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
const input = t[0];
const expected = t[1];
const actual = engine.parseQuery(input);
expect(JSON.stringify(actual.terms._)).toBe(JSON.stringify(expected._));
expect(JSON.stringify(actual.terms.title)).toBe(JSON.stringify(expected.title));
expect(JSON.stringify(actual.terms.body)).toBe(JSON.stringify(expected.body));
}
done();
});
it('should parse query strings with wildcards', async (done) => {
let rows;
const testCases = [
['do*', ['do', 'dog', 'domino'], [] ],
// "*" is a wildcard only when used at the end (to searhc for documents with the specified prefix)
// If it's at the beginning, it's ignored, if it's in the middle, it's treated as a litteral "*".
['*an*', ['an', 'anneau'], ['piano', 'plan'] ],
['no*no', ['no*no'], ['nonono'] ],
];
for (let i = 0; i < testCases.length; i++) {
const t = testCases[i];
const input = t[0];
const shouldMatch = t[1];
const shouldNotMatch = t[2];
const regex = new RegExp(engine.parseQuery(input).terms._[0].value, 'gmi');
for (let j = 0; j < shouldMatch.length; j++) {
const r = shouldMatch[j].match(regex);
expect(!!r).toBe(true, '"' + input + '" should match "' + shouldMatch[j] + '"');
}
// for (let j = 0; j < shouldNotMatch.length; j++) {
// const r = shouldNotMatch[j].match(regex);
// // console.info(input, shouldNotMatch)
// expect(!!r).toBe(false, '"' + input + '" should not match "' + shouldNotMatch[j] + '"');
// }
}
expect(engine.parseQuery('*').termCount).toBe(0);
done();
});
});

View File

@@ -0,0 +1,289 @@
require('app-module-path').addPath(__dirname);
const { time } = require('lib/time-utils.js');
const { fileContentEqual, setupDatabase, setupDatabaseAndSynchronizer, db, synchronizer, fileApi, sleep, clearDatabase, switchClient, syncTargetId, objectsEqual, checkThrowAsync } = require('test-utils.js');
const markdownUtils = require('lib/markdownUtils.js');
const Api = require('lib/services/rest/Api');
const Folder = require('lib/models/Folder');
const Note = require('lib/models/Note');
const Tag = require('lib/models/Tag');
const Resource = require('lib/models/Resource');
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
process.on('unhandledRejection', (reason, p) => {
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
});
let api = null;
describe('services_rest_Api', function() {
beforeEach(async (done) => {
api = new Api();
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
done();
});
it('should ping', async (done) => {
const response = await api.route('GET', 'ping');
expect(response).toBe('JoplinClipperServer');
done();
});
it('should handle Not Found errors', async (done) => {
const hasThrown = await checkThrowAsync(async () => await api.route('GET', 'pong'));
expect(hasThrown).toBe(true);
done();
});
it('should get folders', async (done) => {
let f1 = await Folder.save({ title: "mon carnet" });
const response = await api.route('GET', 'folders');
expect(response.length).toBe(1);
expect(response[0].title).toBe('mon carnet');
done();
});
it('should update folders', async (done) => {
let f1 = await Folder.save({ title: "mon carnet" });
const response = await api.route('PUT', 'folders/' + f1.id, null, JSON.stringify({
title: 'modifié',
}));
let f1b = await Folder.load(f1.id);
expect(f1b.title).toBe('modifié');
done();
});
it('should delete folders', async (done) => {
let f1 = await Folder.save({ title: "mon carnet" });
await api.route('DELETE', 'folders/' + f1.id);
let f1b = await Folder.load(f1.id);
expect(!f1b).toBe(true);
done();
});
it('should create folders', async (done) => {
const response = await api.route('POST', 'folders', null, JSON.stringify({
title: 'from api',
}));
expect(!!response.id).toBe(true);
let f = await Folder.all();
expect(f.length).toBe(1);
expect(f[0].title).toBe('from api');
done();
});
it('should get one folder', async (done) => {
let f1 = await Folder.save({ title: "mon carnet" });
const response = await api.route('GET', 'folders/' + f1.id);
expect(response.id).toBe(f1.id);
const hasThrown = await checkThrowAsync(async () => await api.route('GET', 'folders/doesntexist'));
expect(hasThrown).toBe(true);
done();
});
it('should get the folder notes', async (done) => {
let f1 = await Folder.save({ title: "mon carnet" });
const response2 = await api.route('GET', 'folders/' + f1.id + '/notes');
expect(response2.length).toBe(0);
const n1 = await Note.save({ title: 'un', parent_id: f1.id });
const n2 = await Note.save({ title: 'deux', parent_id: f1.id });
const response = await api.route('GET', 'folders/' + f1.id + '/notes');
expect(response.length).toBe(2);
done();
});
it('should fail on invalid paths', async (done) => {
const hasThrown = await checkThrowAsync(async () => await api.route('GET', 'schtroumpf'));
expect(hasThrown).toBe(true);
done();
});
it('should get notes', async (done) => {
let response = null;
const f1 = await Folder.save({ title: "mon carnet" });
const f2 = await Folder.save({ title: "mon deuxième carnet" });
const n1 = await Note.save({ title: 'un', parent_id: f1.id });
const n2 = await Note.save({ title: 'deux', parent_id: f1.id });
const n3 = await Note.save({ title: 'trois', parent_id: f2.id });
response = await api.route('GET', 'notes');
expect(response.length).toBe(3);
response = await api.route('GET', 'notes/' + n1.id);
expect(response.id).toBe(n1.id);
response = await api.route('GET', 'notes/' + n3.id, { fields: 'id,title' });
expect(Object.getOwnPropertyNames(response).length).toBe(3);
expect(response.id).toBe(n3.id);
expect(response.title).toBe('trois');
done();
});
it('should create notes', async (done) => {
let response = null;
const f = await Folder.save({ title: "mon carnet" });
response = await api.route('POST', 'notes', null, JSON.stringify({
title: 'testing',
parent_id: f.id,
}));
expect(response.title).toBe('testing');
expect(!!response.id).toBe(true);
response = await api.route('POST', 'notes', null, JSON.stringify({
title: 'testing',
parent_id: f.id,
}));
expect(response.title).toBe('testing');
expect(!!response.id).toBe(true);
done();
});
it('should create notes with supplied ID', async (done) => {
let response = null;
const f = await Folder.save({ title: "mon carnet" });
response = await api.route('POST', 'notes', null, JSON.stringify({
id: '12345678123456781234567812345678',
title: 'testing',
parent_id: f.id,
}));
expect(response.id).toBe('12345678123456781234567812345678');
done();
});
it('should create notes with images', async (done) => {
let response = null;
const f = await Folder.save({ title: "mon carnet" });
response = await api.route('POST', 'notes', null, JSON.stringify({
title: 'testing image',
parent_id: f.id,
image_data_url: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAANZJREFUeNoAyAA3/wFwtO3K6gUB/vz2+Prw9fj/+/r+/wBZKAAExOgF4/MC9ff+MRH6Ui4E+/0Bqc/zutj6AgT+/Pz7+vv7++nu82c4DlMqCvLs8goA/gL8/fz09fb59vXa6vzZ6vjT5fbn6voD/fwC8vX4UiT9Zi//APHyAP8ACgUBAPv5APz7BPj2+DIaC2o3E+3o6ywaC5fT6gD6/QD9/QEVf9kD+/dcLQgJA/7v8vqfwOf18wA1IAIEVycAyt//v9XvAPv7APz8LhoIAPz9Ri4OAgwARgx4W/6fVeEAAAAASUVORK5CYII="
}));
const resources = await Resource.all();
expect(resources.length).toBe(1);
const resource = resources[0];
expect(response.body.indexOf(resource.id) >= 0).toBe(true);
done();
});
it('should create notes from HTML', async (done) => {
let response = null;
const f = await Folder.save({ title: "mon carnet" });
response = await api.route('POST', 'notes', null, JSON.stringify({
title: 'testing HTML',
parent_id: f.id,
body_html: '<b>Bold text</b>',
}));
expect(response.body).toBe('**Bold text**');
done();
});
it('should filter fields', async (done) => {
let f = api.fields_({ query: { fields: 'one,two' } }, []);
expect(f.length).toBe(2);
expect(f[0]).toBe('one');
expect(f[1]).toBe('two');
f = api.fields_({ query: { fields: 'one ,, two ' } }, []);
expect(f.length).toBe(2);
expect(f[0]).toBe('one');
expect(f[1]).toBe('two');
f = api.fields_({ query: { fields: ' ' } }, ['def']);
expect(f.length).toBe(1);
expect(f[0]).toBe('def');
done();
});
it('should handle tokens', async (done) => {
api = new Api('mytoken');
let hasThrown = await checkThrowAsync(async () => await api.route('GET', 'notes'));
expect(hasThrown).toBe(true);
const response = await api.route('GET', 'notes', { token: 'mytoken' })
expect(response.length).toBe(0);
hasThrown = await checkThrowAsync(async () => await api.route('POST', 'notes', null, JSON.stringify({title:'testing'})));
expect(hasThrown).toBe(true);
done();
});
it('should add tags to notes', async (done) => {
const tag = await Tag.save({ title: "mon étiquette" });
const note = await Note.save({ title: "ma note" });
const response = await api.route('POST', 'tags/' + tag.id + '/notes', null, JSON.stringify({
id: note.id,
}));
const noteIds = await Tag.noteIds(tag.id);
expect(noteIds[0]).toBe(note.id);
done();
});
it('should remove tags from notes', async (done) => {
const tag = await Tag.save({ title: "mon étiquette" });
const note = await Note.save({ title: "ma note" });
await Tag.addNote(tag.id, note.id);
const response = await api.route('DELETE', 'tags/' + tag.id + '/notes/' + note.id);
const noteIds = await Tag.noteIds(tag.id);
expect(noteIds.length).toBe(0);
done();
});
it('should list all tag notes', async (done) => {
const tag = await Tag.save({ title: "mon étiquette" });
const tag2 = await Tag.save({ title: "mon étiquette 2" });
const note1 = await Note.save({ title: "ma note un" });
const note2 = await Note.save({ title: "ma note deux" });
await Tag.addNote(tag.id, note1.id);
await Tag.addNote(tag.id, note2.id);
const response = await api.route('GET', 'tags/' + tag.id + '/notes');
expect(response.length).toBe(2);
expect('id' in response[0]).toBe(true);
expect('title' in response[0]).toBe(true);
const response2 = await api.route('GET', 'notes/' + note1.id + '/tags');
expect(response2.length).toBe(1);
await Tag.addNote(tag2.id, note1.id);
const response3 = await api.route('GET', 'notes/' + note1.id + '/tags');
expect(response3.length).toBe(2);
done();
});
});

View File

@@ -7,6 +7,7 @@ const fs = require('fs-extra');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const Resource = require('lib/models/Resource.js');
const ResourceFetcher = require('lib/services/ResourceFetcher');
const Tag = require('lib/models/Tag.js');
const { Database } = require('lib/database.js');
const Setting = require('lib/models/Setting.js');
@@ -872,12 +873,49 @@ describe('Synchronizer', function() {
let allResources = await Resource.all();
expect(allResources.length).toBe(1);
let resource1_2 = allResources[0];
let resourcePath1_2 = Resource.fullPath(resource1_2);
let ls = await Resource.localState(resource1_2);
expect(resource1_2.id).toBe(resource1.id);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_IDLE);
const fetcher = new ResourceFetcher(() => { return synchronizer().api() });
fetcher.queueDownload(resource1_2.id);
await fetcher.waitForAllFinished();
resource1_2 = await Resource.load(resource1.id);
ls = await Resource.localState(resource1_2);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_DONE);
let resourcePath1_2 = Resource.fullPath(resource1_2);
expect(fileContentEqual(resourcePath1, resourcePath1_2)).toBe(true);
}));
it('should handle resource download errors', asyncTest(async () => {
while (insideBeforeEach) await time.msleep(500);
let folder1 = await Folder.save({ title: "folder1" });
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
await shim.attachFileToNote(note1, __dirname + '/../tests/support/photo.jpg');
let resource1 = (await Resource.all())[0];
let resourcePath1 = Resource.fullPath(resource1);
await synchronizer().start();
await switchClient(2);
await synchronizer().start();
const fetcher = new ResourceFetcher(() => { return {
// Simulate a failed download
get: () => { return new Promise((resolve, reject) => { reject(new Error('did not work')) }); }
} });
fetcher.queueDownload(resource1.id);
await fetcher.waitForAllFinished();
resource1 = await Resource.load(resource1.id);
let ls = await Resource.localState(resource1);
expect(ls.fetch_status).toBe(Resource.FETCH_STATUS_ERROR);
expect(ls.fetch_error).toBe('did not work');
}));
it('should delete resources', asyncTest(async () => {
while (insideBeforeEach) await time.msleep(500);
@@ -926,6 +964,10 @@ describe('Synchronizer', function() {
Setting.setObjectKey('encryption.passwordCache', masterKey.id, '123456');
await encryptionService().loadMasterKeysFromSettings();
const fetcher = new ResourceFetcher(() => { return synchronizer().api() });
fetcher.queueDownload(resource1.id);
await fetcher.waitForAllFinished();
let resource1_2 = (await Resource.all())[0];
resource1_2 = await Resource.decrypt(resource1_2);
let resourcePath1_2 = Resource.fullPath(resource1_2);

View File

@@ -4,6 +4,7 @@ const { DatabaseDriverNode } = require('lib/database-driver-node.js');
const BaseModel = require('lib/BaseModel.js');
const Folder = require('lib/models/Folder.js');
const Note = require('lib/models/Note.js');
const ItemChange = require('lib/models/ItemChange.js');
const Resource = require('lib/models/Resource.js');
const Tag = require('lib/models/Tag.js');
const NoteTag = require('lib/models/NoteTag.js');
@@ -48,7 +49,9 @@ EncryptionService.fsDriver_ = fsDriver;
FileApiDriverLocal.fsDriver_ = fsDriver;
const logDir = __dirname + '/../tests/logs';
const tempDir = __dirname + '/../tests/tmp';
fs.mkdirpSync(logDir, 0o755);
fs.mkdirpSync(tempDir, 0o755);
SyncTargetRegistry.addClass(SyncTargetMemory);
SyncTargetRegistry.addClass(SyncTargetFilesystem);
@@ -80,6 +83,7 @@ BaseItem.loadClass('MasterKey', MasterKey);
Setting.setConstant('appId', 'net.cozic.joplin-cli');
Setting.setConstant('appType', 'cli');
Setting.setConstant('tempDir', tempDir);
BaseService.logger_ = logger;
@@ -119,6 +123,8 @@ async function switchClient(id) {
async function clearDatabase(id = null) {
if (id === null) id = currentClient_;
await ItemChange.waitForAllSaved();
let queries = [
'DELETE FROM notes',
'DELETE FROM folders',

0
CliClientDemo/publish.sh Normal file → Executable file
View File

View File

@@ -38,7 +38,7 @@
const node = childNodes[i];
let isVisible = node.nodeType === 1 ? window.getComputedStyle(node).display !== 'none' : true;
if (isVisible && ['input', 'textarea', 'script', 'style', 'select', 'option', 'button'].indexOf(node.nodeName.toLowerCase()) >= 0) isVisible = false;
if (isVisible && ['input', 'textarea', 'script', 'noscript', 'style', 'select', 'option', 'button'].indexOf(node.nodeName.toLowerCase()) >= 0) isVisible = false;
if (!isVisible) {
element.removeChild(node);
@@ -74,6 +74,18 @@
async function prepareCommandResponse(command) {
console.info('Got command: ' + command.name);
const clippedContentResponse = (title, html) => {
return {
name: 'clippedContent',
title: title,
html: html,
base_url: baseUrl(),
url: location.origin + location.pathname + location.search,
parent_id: command.parent_id,
tags: command.tags || '',
};
}
if (command.name === "simplifiedPageHtml") {
let article = null;
@@ -87,29 +99,20 @@
response.warning = 'Could not retrieve simplified version of page - full page has been saved instead.';
return response;
}
return {
name: 'clippedContent',
html: article.body,
title: article.title,
base_url: baseUrl(),
url: location.origin + location.pathname,
parent_id: command.parent_id,
};
return clippedContentResponse(article.title, article.body);
} else if (command.name === "completePageHtml") {
const cleanDocument = document.body.cloneNode(true);
cleanUpElement(cleanDocument);
return clippedContentResponse(pageTitle(), cleanDocument.innerHTML);
return {
name: 'clippedContent',
html: cleanDocument.innerHTML,
title: pageTitle(),
base_url: baseUrl(),
url: location.origin + location.pathname,
parent_id: command.parent_id,
};
} else if (command.name === "selectedHtml") {
const range = window.getSelection().getRangeAt(0);
const container = document.createElement('div');
container.appendChild(range.cloneContents());
return clippedContentResponse(pageTitle(), container.innerHTML);
} else if (command.name === 'screenshot') {
@@ -135,6 +138,7 @@
messageComp.style.maxWidth = messageCompWidth + 'px'
messageComp.style.border = '1px solid black'
messageComp.style.background = 'white'
messageComp.style.color = 'black';
messageComp.style.top = '10px'
messageComp.style.textAlign = 'center';
messageComp.style.padding = '10px'
@@ -212,6 +216,7 @@
crop_rect: selectionArea,
url: location.origin + location.pathname,
parent_id: command.parent_id,
tags: command.tags,
};
browser_.runtime.sendMessage({

View File

@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Joplin Web Clipper [DEV]",
"version": "1.0.5",
"version": "1.0.7",
"description": "Capture and save web pages and screenshots from your browser to Joplin.",
"homepage_url": "https://joplin.cozic.net",
"icons": {

View File

@@ -1,5 +1,7 @@
<!DOCTYPE html>
<!-- NOTE: I think this is not used at all -->
<html>
<head>
<meta charset="utf-8">

View File

@@ -100,21 +100,34 @@
flex: 0;
}
.App .Folders {
.App .Folders,
.App .Tags {
display: flex;
flex-direction: row;
align-items: center;
align-items: top;
padding: 5px 0;
}
.App .Folders label {
.App .Folders label,
.App .Tags label {
flex: 0;
white-space: nowrap;
margin-right: .5em;
}
.App .Folders select {
flex: 1;
margin-left: 10px;
}
.App .Tags input {
display: inline-block;
flex: 1;
margin-bottom: .5em;
}
.App .ClearTagButton {
margin-left: .5em;
text-decoration: none;
}
.App .StatusBar {

View File

@@ -14,10 +14,14 @@ class AppComponent extends Component {
this.state = ({
contentScriptLoaded: false,
selectedTags: [],
});
this.confirm_click = () => {
bridge().sendContentToJoplin(this.props.clippedContent);
const content = Object.assign({}, this.props.clippedContent);
content.tags = this.state.selectedTags.join(',');
content.parent_id = this.props.selectedFolderId;
bridge().sendContentToJoplin(content);
}
this.contentTitle_change = (event) => {
@@ -30,14 +34,18 @@ class AppComponent extends Component {
this.clipSimplified_click = () => {
bridge().sendCommandToActiveTab({
name: 'simplifiedPageHtml',
parent_id: this.props.selectedFolderId,
});
}
this.clipComplete_click = () => {
bridge().sendCommandToActiveTab({
name: 'completePageHtml',
parent_id: this.props.selectedFolderId,
});
}
this.clipSelection_click = () => {
bridge().sendCommandToActiveTab({
name: 'selectedHtml',
});
}
@@ -49,6 +57,7 @@ class AppComponent extends Component {
name: 'screenshot',
api_base_url: baseUrl,
parent_id: this.props.selectedFolderId,
tags: this.state.selectedTags.join(','),
});
window.close();
@@ -67,6 +76,41 @@ class AppComponent extends Component {
id: event.target.value,
});
}
this.tagCompChanged = this.tagCompChanged.bind(this);
this.onAddTagClick = this.onAddTagClick.bind(this);
this.onClearTagButtonClick = this.onClearTagButtonClick.bind(this);
}
onAddTagClick(event) {
const newTags = this.state.selectedTags.slice();
newTags.push('');
this.setState({ selectedTags: newTags });
this.focusNewTagInput_ = true;
}
onClearTagButtonClick(event) {
const index = event.target.getAttribute('data-index');
const newTags = this.state.selectedTags.slice();
newTags.splice(index, 1);
this.setState({ selectedTags: newTags });
}
tagCompChanged(event) {
const index = Number(event.target.getAttribute('data-index'));
const value = event.target.value;
if (this.state.selectedTags.length <= index) {
const newTags = this.state.selectedTags.slice();
newTags.push(value);
this.setState({ selectedTags: newTags });
} else {
if (this.state.selectedTags[index] !== value) {
const newTags = this.state.selectedTags.slice();
newTags[index] = value;
this.setState({ selectedTags: newTags });
}
}
}
async loadContentScripts() {
@@ -80,6 +124,39 @@ class AppComponent extends Component {
this.setState({
contentScriptLoaded: true,
});
let foundSelectedFolderId = false;
const searchSelectedFolder = (folders) => {
for (let i = 0; i < folders.length; i++) {
const folder = folders[i];
if (folder.id === this.props.selectedFolderId) foundSelectedFolderId = true;
if (folder.children) searchSelectedFolder(folder.children);
}
}
searchSelectedFolder(this.props.folders);
if (!foundSelectedFolderId) {
const newFolderId = this.props.folders.length ? this.props.folders[0].id : null;
this.props.dispatch({
type: 'SELECTED_FOLDER_SET',
id: newFolderId,
});
}
}
componentDidUpdate() {
if (this.focusNewTagInput_) {
this.focusNewTagInput_ = false;
let lastRef = null;
for (let i = 0; i < 100; i++) {
const ref = this.refs['tagSelector' + i];
if (!ref) break;
lastRef = ref;
}
if (lastRef) lastRef.focus();
}
}
render() {
@@ -112,24 +189,17 @@ class AppComponent extends Component {
<p className="Info">{ msg }</p>
</div>
);
} else {
if (hasContent) {
previewComponent = (
<div className="Preview">
<input className={"Title"} value={content.title} onChange={this.contentTitle_change}/>
<div className={"BodyWrapper"}>
<div className={"Body"} dangerouslySetInnerHTML={{__html: content.body_html}}></div>
</div>
<a className={"Confirm Button"} onClick={this.confirm_click}>Confirm</a>
} else if (hasContent) {
previewComponent = (
<div className="Preview">
<h2>Preview:</h2>
<input className={"Title"} value={content.title} onChange={this.contentTitle_change}/>
<div className={"BodyWrapper"}>
<div className={"Body"} dangerouslySetInnerHTML={{__html: content.body_html}}></div>
</div>
);
} else {
previewComponent = (
<div className="Preview">
<p className="Info">(No preview yet)</p>
</div>
);
}
<a className={"Confirm Button"} onClick={this.confirm_click}>Confirm</a>
</div>
);
}
const clipperStatusComp = () => {
@@ -159,8 +229,6 @@ class AppComponent extends Component {
return <div className="StatusBar"><img alt={foundState} className="Led" src={led}/><span className="ServerStatus">{ msg }{ helpLink }</span></div>
}
console.info(this.props.selectedFolderId);
const foldersComp = () => {
const optionComps = [];
@@ -189,18 +257,56 @@ class AppComponent extends Component {
);
}
const tagsComp = () => {
const comps = [];
for (let i = 0; i < this.state.selectedTags.length; i++) {
comps.push(<div>
<input
ref={'tagSelector' + i}
data-index={i}
key={i}
type="text"
list="tags"
value={this.state.selectedTags[i]}
onChange={this.tagCompChanged}
onInput={this.tagCompChanged}
/>
<a data-index={i} href="#" className="ClearTagButton" onClick={this.onClearTagButtonClick}>[x]</a>
</div>);
}
return (
<div>
{comps}
<a className="AddTagButton" href="#" onClick={this.onAddTagClick}>Add tag</a>
</div>
);
}
const tagDataListOptions = [];
for (let i = 0; i < this.props.tags.length; i++) {
const tag = this.props.tags[i];
tagDataListOptions.push(<option key={tag.id}>{tag.title}</option>);
}
return (
<div className="App">
<div className="Controls">
<ul>
<li><a className="Button" onClick={this.clipSimplified_click}>Clip simplified page</a></li>
<li><a className="Button" onClick={this.clipComplete_click}>Clip complete page</a></li>
<li><a className="Button" onClick={this.clipSelection_click}>Clip selection</a></li>
<li><a className="Button" onClick={this.clipScreenshot_click}>Clip screenshot</a></li>
</ul>
</div>
{ foldersComp() }
<div className="Tags">
<label>Tags:</label>
{tagsComp()}
<datalist id="tags">
{tagDataListOptions}
</datalist>
</div>
{ warningComponent }
<h2>Preview:</h2>
{ previewComponent }
{ clipperStatusComp() }
</div>
@@ -216,6 +322,7 @@ const mapStateToProps = (state) => {
contentUploadOperation: state.contentUploadOperation,
clipperServer: state.clipperServer,
folders: state.folders,
tags: state.tags,
selectedFolderId: state.selectedFolderId,
};
};

View File

@@ -2,7 +2,7 @@ const randomClipperPort = require('./randomClipperPort');
class Bridge {
init(browser, browserSupportsPromises, dispatch) {
async init(browser, browserSupportsPromises, dispatch) {
console.info('Popup: Init bridge');
this.browser_ = browser;
@@ -28,6 +28,7 @@ class Bridge {
base_url: command.base_url,
source_url: command.url,
parent_id: command.parent_id,
tags: command.tags || '',
};
this.dispatch({ type: 'CLIPPED_CONTENT_SET', content: content });
@@ -36,7 +37,7 @@ class Bridge {
this.browser_.runtime.onMessage.addListener(this.browser_notify);
const backgroundPage = this.browser_.extension.getBackgroundPage();
const backgroundPage = await this.backgroundPage(this.browser_);
// Not sure why the getBackgroundPage() sometimes returns null, so
// in that case default to "prod" environment, which means the live
@@ -53,6 +54,17 @@ class Bridge {
this.findClipperServerPort();
}
async backgroundPage(browser) {
const bgp = browser.extension.getBackgroundPage();
if (bgp) return bgp;
return new Promise((resolve, reject) => {
browser.runtime.getBackgroundPage((bgp) => {
resolve(bgp);
})
});
}
env() {
return this.env_;
}
@@ -111,6 +123,11 @@ class Bridge {
const folders = await this.folderTree();
this.dispatch({ type: 'FOLDERS_SET', folders: folders });
const tags = await this.clipperApiExec('GET', 'tags');
this.dispatch({ type: 'TAGS_SET', tags: tags });
bridge().restoreState();
return;
}
} catch (error) {

View File

@@ -16,6 +16,7 @@ const defaultState = {
port: null,
},
folders: [],
tags: [],
selectedFolderId: null,
env: 'prod',
};
@@ -65,6 +66,11 @@ function reducer(state = defaultState, action) {
newState.selectedFolderId = action.folders[0].id;
}
} else if (action.type === 'TAGS_SET') {
newState = Object.assign({}, state);
newState.tags = action.tags;
} else if (action.type === 'SELECTED_FOLDER_SET') {
newState = Object.assign({}, state);
@@ -88,11 +94,18 @@ function reducer(state = defaultState, action) {
return newState;
}
const store = createStore(reducer, applyMiddleware(reduxMiddleware));
async function main() {
const store = createStore(reducer, applyMiddleware(reduxMiddleware));
bridge().init(window.browser ? window.browser : window.chrome, !!window.browser, store.dispatch);
bridge().restoreState();
console.info('Popup: Init bridge and restore state...');
console.info('Popup: Creating React app...');
await bridge().init(window.browser ? window.browser : window.chrome, !!window.browser, store.dispatch);
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
console.info('Popup: Creating React app...');
ReactDOM.render(<Provider store={store}><App /></Provider>, document.getElementById('root'));
}
main().catch((error) => {
console.error('Fatal error on initialisation:', error);
});

View File

@@ -1,166 +1,20 @@
const reservedPorts = [1024, 1027, 1028, 1029, 1058, 1059, 1080, 1085, 1098, 1099, 1109, 1119, 1167, 1194, 1198, 1214, 1220, 1234, 1241, 1270, 1293, 1311, 1314, 1337, 1341, 1344,
1352, 1360, 1414, 1417, 1418, 1419, 1420, 1431, 1433, 1434, 1492, 1494, 1500, 1501, 1503, 1512, 1513, 1521, 1524, 1527, 1533, 1547, 1550, 1581, 1582, 1583, 1589, 1604, 1626, 1627,
1628, 1629, 1645, 1646, 1666, 1677, 1688, 1701, 1707, 1716, 1719, 1720, 1723, 1755, 1761, 1783, 1801, 1812, 1813, 1863, 1880, 1883, 1900, 1935, 1967, 1970, 1972, 1984, 1985, 1998,
2000, 2010, 2033, 2049, 2056, 2080, 2082, 2083, 2086, 2087, 2095, 2096, 2100, 2101, 2102, 2103, 2104, 2123, 2142, 2152, 2159, 2181, 2195, 2196, 2210, 2211, 2221, 2222, 2261, 2262,
2266, 2305, 2351, 2368, 2369, 2370, 2372, 2375, 2376, 2377, 2379, 2380, 2399, 2401, 2404, 2424, 2427, 2447, 2480, 2483, 2484, 2535, 2541, 2546, 2593, 2598, 2599, 2638, 2710, 2727,
2809, 2811, 2827, 2944, 2945, 2947, 2948, 2949, 2967, 3000, 3004, 3020, 3050, 3052, 3074, 3101, 3128, 3225, 3233, 3260, 3268, 3269, 3283, 3290, 3305, 3306, 3313, 3316, 3323, 3332,
3333, 3351, 3386, 3389, 3396, 3412, 3423, 3424, 3455, 3478, 3479, 3480, 3483, 3493, 3516, 3527, 3535, 3544, 3632, 3645, 3659, 3667, 3689, 3690, 3702, 3724, 3725, 3768, 3784, 3785,
3799, 3804, 3825, 3826, 3830, 3835, 3856, 3868, 3872, 3880, 3900, 3960, 3962, 3978, 3979, 3999, 4000, 4001, 4018, 4035, 4045, 4050, 4069, 4089, 4090, 4093, 4096, 4105, 4111, 4116,
4125, 4172, 4190, 4198, 4201, 4222, 4226, 4242, 4243, 4244, 4303, 4321, 4352, 4444, 4486, 4488, 4500, 4502, 4505, 4534, 4560, 4567, 4569, 4604, 4605, 4610, 4662, 4664, 4672, 4711,
4713, 4728, 4730, 4739, 4747, 4750, 4753, 4840, 4843, 4847, 4848, 4894, 4949, 4950, 5000, 5001, 5002, 5003, 5004, 5005, 5010, 5011, 5031, 5037, 5048, 5050, 5051, 5060, 5061, 5062,
5064, 5065, 5070, 5084, 5085, 5093, 5099, 5104, 5121, 5124, 5125, 5150, 5151, 5154, 5190, 5201, 5222, 5223, 5228, 5242, 5243, 5246, 5247, 5269, 5280, 5281, 5298, 5310, 5349, 5351,
5353, 5355, 5357, 5358, 5394, 5402, 5405, 5412, 5413, 5417, 5421, 5432, 5433, 5445, 5480, 5481, 5495, 5498, 5499, 5500, 5501, 5517, 5550, 5554, 5555, 5556, 5568, 5601, 5631, 5632,
5656, 5666, 5667, 5670, 5672, 5678, 5683, 5701, 5718, 5719, 5722, 5723, 5724, 5741, 5742, 5800, 5900, 5931, 5938, 5984, 5985, 5986, 5988, 6000, 6001, 6002, 6003, 6004, 6005, 6006,
6007, 6008, 6009, 6010, 6011, 6012, 6013, 6014, 6015, 6016, 6017, 6018, 6019, 6020, 6021, 6022, 6023, 6024, 6025, 6026, 6027, 6028, 6029, 6030, 6031, 6032, 6033, 6034, 6035, 6036,
6037, 6038, 6039, 6040, 6041, 6042, 6043, 6044, 6045, 6046, 6047, 6048, 6049, 6050, 6051, 6052, 6053, 6054, 6055, 6056, 6057, 6058, 6059, 6060, 6061, 6062, 6063, 6086, 6100, 6101,
6110, 6111, 6112, 6113, 6136, 6159, 6200, 6201, 6225, 6227, 6240, 6244, 6255, 6257, 6260, 6262, 6343, 6346, 6347, 6350, 6379, 6389, 6432, 6436, 6437, 6444, 6445, 6463, 6502, 6513,
6514, 6515, 6543, 6556, 6560, 6566, 6571, 6600, 6601, 6602, 6619, 6622, 6653, 6660, 6665, 6679, 6690, 6697, 6699, 6715, 6771, 6783, 6789, 6869, 6881, 6888, 6889, 6891, 6901, 6902,
6969, 6970, 7000, 7001, 7002, 7005, 7006, 7010, 7022, 7023, 7025, 7047, 7070, 7133, 7144, 7145, 7171, 7262, 7272, 7306, 7307, 7312, 7396, 7400, 7401, 7402, 7471, 7473, 7474, 7478,
7542, 7547, 7575, 7624, 7631, 7634, 7652, 7655, 7656, 7670, 7687, 7707, 7717, 7777, 7831, 7880, 7890, 7915, 7935, 7946, 7990, 8000, 8005, 8006, 8007, 8008, 8009, 8042, 8069, 8070,
8074, 8075, 8080, 8088, 8089, 8090, 8091, 8092, 8111, 8112, 8116, 8118, 8123, 8139, 8140, 8172, 8184, 8194, 8200, 8222, 8243, 8245, 8280, 8281, 8291, 8303, 8332, 8333, 8337, 8384,
8388, 8443, 8444, 8484, 8500, 8530, 8531, 8580, 8629, 8642, 8691, 8767, 8834, 8840, 8880, 8883, 8887, 8888, 8889, 8983, 8997, 8998, 8999, 9000, 9001, 9002, 9006, 9030, 9042, 9043,
9050, 9060, 9080, 9090, 9091, 9092, 9100, 9101, 9102, 9103, 9119, 9150, 9191, 9199, 9200, 9217, 9293, 9300, 9303, 9306, 9309, 9312, 9332, 9333, 9339, 9389, 9418, 9419, 9420, 9421,
9422, 9425, 9443, 9535, 9536, 9600, 9675, 9676, 9695, 9785, 9800, 9875, 9898, 9899, 9981, 9982, 9987, 9993, 9997, 9999, 10000, 10001, 10009, 10010, 10024, 10025, 10042, 10050, 10051,
10080, 10110, 10172, 10200, 10201, 10212, 10308, 10480, 10505, 10514, 10823, 10891, 10933, 11001, 11111, 11112, 11211, 11214, 11215, 11235, 11311, 11371, 11753, 12012, 12013, 12035,
12043, 12046, 12201, 12222, 12223, 12345, 12443, 12489, 12975, 13000, 13008, 13075, 13720, 13721, 13724, 13782, 13783, 13785, 13786, 14550, 14567, 15000, 15345, 15441, 15567, 15672,
16000, 16080, 16200, 16225, 16250, 16261, 16300, 16384, 16385, 16386, 16387, 16393, 16394, 16395, 16396, 16397, 16398, 16399, 16400, 16401, 16402, 16403, 16404, 16405, 16406, 16407,
16408, 16409, 16410, 16411, 16412, 16413, 16414, 16415, 16416, 16417, 16418, 16419, 16420, 16421, 16422, 16423, 16424, 16425, 16426, 16427, 16428, 16429, 16430, 16431, 16432, 16433,
16434, 16435, 16436, 16437, 16438, 16439, 16440, 16441, 16442, 16443, 16444, 16445, 16446, 16447, 16448, 16449, 16450, 16451, 16452, 16453, 16454, 16455, 16456, 16457, 16458, 16459,
16460, 16461, 16462, 16463, 16464, 16465, 16466, 16467, 16468, 16469, 16470, 16471, 16472, 16482, 16567, 17011, 17500, 18091, 18092, 18104, 18200, 18201, 18206, 18300, 18301, 18306,
18333, 18400, 18401, 18505, 18506, 18605, 18606, 19000, 19001, 19132, 19150, 19226, 19294, 19295, 19302, 19812, 19813, 19814, 19999, 20000, 20560, 20595, 20808, 21025, 22000, 22136,
22222, 23073, 23399, 23513, 24441, 24444, 24465, 24554, 24800, 24842, 25565, 25575, 25826, 26000, 26900, 27000, 27016, 27017, 27031, 27036, 27037, 27374, 27500, 27888, 27901, 27950,
27960, 28001, 28015, 28770, 28785, 28852, 28910, 28960, 29000, 29070, 29900, 29920, 30564, 31337, 31416, 31438, 31457, 32137, 32400, 32764, 32887, 32976, 33434, 33848, 34000, 34197,
35357, 37008, 40000, 43110, 43594, 44405, 44818, 47001, 47808, 49151];
function randomClipperPort(state, env) {
const startPorts = {
prod: 41184,
dev: 27583,
};
// From https://github.com/coverslide/node-alea
const AleaModule = function () {
// importState to sync generator states
Alea.importState = function(i){
var random = new Alea();
random.importState(i);
return random;
};
const startPort = env === 'prod' ? startPorts.prod : startPorts.dev;
return Alea;
function Alea() {
return (function(args) {
// Johannes Baagøe <baagoe@baagoe.com>, 2010
var s0 = 0;
var s1 = 0;
var s2 = 0;
var c = 1;
if (args.length === 0) {
args = [+new Date()];
}
var mash = Mash();
s0 = mash(' ');
s1 = mash(' ');
s2 = mash(' ');
for (var i = 0; i < args.length; i++) {
s0 -= mash(args[i]);
if (s0 < 0) {
s0 += 1;
}
s1 -= mash(args[i]);
if (s1 < 0) {
s1 += 1;
}
s2 -= mash(args[i]);
if (s2 < 0) {
s2 += 1;
}
}
mash = null;
var random = function() {
var t = 2091639 * s0 + c * 2.3283064365386963e-10; // 2^-32
s0 = s1;
s1 = s2;
return s2 = t - (c = t | 0);
};
random.uint32 = function() {
return random() * 0x100000000; // 2^32
};
random.fract53 = function() {
return random() +
(random() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
};
random.version = 'Alea 0.9';
random.args = args;
// my own additions to sync state between two generators
random.exportState = function(){
return [s0, s1, s2, c];
};
random.importState = function(i){
s0 = +i[0] || 0;
s1 = +i[1] || 0;
s2 = +i[2] || 0;
c = +i[3] || 0;
};
return random;
} (Array.prototype.slice.call(arguments)));
}
function Mash() {
var n = 0xefc8249d;
var mash = function(data) {
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};
mash.version = 'Mash 0.9';
return mash;
}
}
const Alea = AleaModule()
function findClipperPort(state, mode = 'prod') {
const seed = mode === 'prod' ? 1867 : 2001;
const minPort = 1024
const maxPort = 49151
let prng = null;
if (!state) {
prng = new Alea(seed)
state = { prng: prng }
state = { offset: 0 };
} else {
prng = state.prng;
state.offset++;
}
const randomPort = () => {
return minPort + Math.floor(prng() * ((maxPort + 1) - minPort));
}
let port = null;
for (let i = 0; i < maxPort; i++) {
port = randomPort();
if (reservedPorts.indexOf(port) < 0) break;
}
if (!port) throw new Error('Cannot find a non-reserved port');
state.port = port;
state.port = startPort + state.offset;
return state;
}
module.exports = findClipperPort;
module.exports = randomClipperPort;

View File

@@ -60,6 +60,14 @@ class ElectronAppWrapper {
// Fix: https://github.com/electron-userland/electron-builder/issues/2269
if (shim.isLinux()) windowOptions.icon = __dirname + '/build/icons/128x128.png';
require('electron-context-menu')({
shouldShowMenu: (event, params) => {
// params.inputFieldType === 'none' when right-clicking the text editor. This is a bit of a hack to detect it because in this
// case we don't want to use the built-in context menu but a custom one.
return params.isEditable && params.inputFieldType !== 'none';
},
});
this.win_ = new BrowserWindow(windowOptions)
this.win_.loadURL(url.format({

View File

@@ -11,7 +11,7 @@ class InteropServiceHelper {
if (module.target === 'file') {
path = bridge().showSaveDialog({
filters: [{ name: module.description, extensions: [module.fileExtension]}]
filters: [{ name: module.description, extensions: module.fileExtensions}]
});
} else {
path = bridge().showOpenDialog({

View File

@@ -23,8 +23,9 @@ const DecryptionWorker = require('lib/services/DecryptionWorker');
const InteropService = require('lib/services/InteropService');
const InteropServiceHelper = require('./InteropServiceHelper.js');
const ResourceService = require('lib/services/ResourceService');
const SearchEngine = require('lib/services/SearchEngine');
const ClipperServer = require('lib/ClipperServer');
const ExternalEditWatcher = require('lib/services/ExternalEditWatcher');
const { bridge } = require('electron').remote.require('./bridge');
const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem;
@@ -41,6 +42,7 @@ const appDefaultState = Object.assign({}, defaultState, {
noteVisiblePanes: ['editor', 'viewer'],
sidebarVisibility: true,
windowContentSize: bridge().windowContentSize(),
watchedNoteFiles: [],
});
class Application extends BaseApplication {
@@ -48,7 +50,6 @@ class Application extends BaseApplication {
constructor() {
super();
this.lastMenuScreen_ = null;
this.powerSaveBlockerId_ = null;
}
hasGui() {
@@ -142,6 +143,35 @@ class Application extends BaseApplication {
newState.sidebarVisibility = action.visibility;
break;
case 'NOTE_FILE_WATCHER_ADD':
if (newState.watchedNoteFiles.indexOf(action.id) < 0) {
newState = Object.assign({}, state);
const watchedNoteFiles = newState.watchedNoteFiles.slice();
watchedNoteFiles.push(action.id);
newState.watchedNoteFiles = watchedNoteFiles;
}
break;
case 'NOTE_FILE_WATCHER_REMOVE':
newState = Object.assign({}, state);
const idx = newState.watchedNoteFiles.indexOf(action.id);
if (idx >= 0) {
const watchedNoteFiles = newState.watchedNoteFiles.slice();
watchedNoteFiles.splice(idx, 1);
newState.watchedNoteFiles = watchedNoteFiles;
}
break;
case 'NOTE_FILE_WATCHER_CLEAR':
if (state.watchedNoteFiles.length) {
newState = Object.assign({}, state);
newState.watchedNoteFiles = [];
}
break;
}
} catch (error) {
error.message = 'In reducer: ' + error.message + ' Action: ' + JSON.stringify(action);
@@ -155,7 +185,7 @@ class Application extends BaseApplication {
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'locale' || action.type == 'SETTING_UPDATE_ALL') {
setLocale(Setting.value('locale'));
// The bridge runs within the main process, with its own instance of locale.js
// so it needs to be set too here.
// so it needs to be set too here.
bridge().setLocale(Setting.value('locale'));
this.refreshMenu();
}
@@ -191,17 +221,6 @@ class Application extends BaseApplication {
Setting.setValue('sidebarVisibility', newState.sidebarVisibility);
}
if (action.type === 'SYNC_STARTED') {
if (!this.powerSaveBlockerId_) this.powerSaveBlockerId_ = bridge().powerSaveBlockerStart('prevent-app-suspension');
}
if (action.type === 'SYNC_COMPLETED') {
if (this.powerSaveBlockerId_) {
bridge().powerSaveBlockerStop(this.powerSaveBlockerId_);
this.powerSaveBlockerId_ = null;
}
}
return result;
}
@@ -257,7 +276,7 @@ class Application extends BaseApplication {
if (moduleSource === 'file') {
path = bridge().showOpenDialog({
filters: [{ name: module.description, extensions: [module.fileExtension]}]
filters: [{ name: module.description, extensions: module.fileExtensions}]
});
} else {
path = bridge().showOpenDialog({
@@ -334,7 +353,6 @@ class Application extends BaseApplication {
}
}, {
label: _('New notebook'),
accelerator: 'CommandOrControl+B',
screens: ['Main'],
click: () => {
this.dispatch({
@@ -391,6 +409,10 @@ class Application extends BaseApplication {
label: _('Paste'),
role: 'paste',
accelerator: 'CommandOrControl+V',
}, {
label: _('Select all'),
role: 'selectall',
accelerator: 'CommandOrControl+A',
}, {
type: 'separator',
screens: ['Main'],
@@ -414,19 +436,53 @@ class Application extends BaseApplication {
name: 'textItalic',
});
},
}, {
label: _('Insert Date Time'),
screens: ['Main'],
visible: false,
accelerator: 'CommandOrControl+Shift+T',
click: () => {
this.dispatch({
type: 'WINDOW_COMMAND',
name: 'insertDateTime',
});
},
}, {
type: 'separator',
screens: ['Main'],
}, {
label: _('Edit in external editor'),
screens: ['Main'],
accelerator: 'CommandOrControl+E',
click: () => {
this.dispatch({
type: 'WINDOW_COMMAND',
name: 'commandStartExternalEditing',
});
},
}, {
type: 'separator',
screens: ['Main'],
}, {
label: _('Search in all the notes'),
screens: ['Main'],
accelerator: 'CommandOrControl+F',
accelerator: 'F6',
click: () => {
this.dispatch({
type: 'WINDOW_COMMAND',
name: 'focus_search',
});
},
}, {
label: _('Search in current note'),
screens: ['Main'],
accelerator: 'CommandOrControl+F',
click: () => {
this.dispatch({
type: 'WINDOW_COMMAND',
name: 'showLocalSearch',
});
},
}],
}, {
label: _('View'),
@@ -634,6 +690,23 @@ class Application extends BaseApplication {
document.head.appendChild(styleTag);
}
async loadCustomCss(filePath) {
let cssString = '';
if (await fs.pathExists(filePath)) {
try {
cssString = await fs.readFile(filePath, 'utf-8');
} catch (error) {
let msg = error.message ? error.message : '';
msg = 'Could not load custom css from ' + filePath + '\n' + msg;
error.message = msg;
throw error;
}
}
return cssString;
}
async start(argv) {
const electronIsDev = require('electron-is-dev');
@@ -687,7 +760,12 @@ class Application extends BaseApplication {
ids: Setting.value('collapsedFolderIds'),
});
if (shim.isLinux()) bridge().setAllowPowerSaveBlockerToggle(true);
const cssString = await this.loadCustomCss(Setting.value('profileDir') + '/userstyle.css');
this.store().dispatch({
type: 'LOAD_CUSTOM_CSS',
css: cssString
});
// Note: Auto-update currently doesn't work in Linux: it downloads the update
// but then doesn't install it on exit.
@@ -710,8 +788,15 @@ class Application extends BaseApplication {
AlarmService.garbageCollect();
}, 1000 * 60 * 60);
if (Setting.value('startMinimized') && Setting.value('showTrayIcon')) {
bridge().window().hide();
}
ResourceService.runInBackground();
SearchEngine.instance().setDb(reg.db());
SearchEngine.instance().setLogger(reg.logger());
if (Setting.value('env') === 'dev') {
AlarmService.updateAllNotifications();
} else {
@@ -734,6 +819,9 @@ class Application extends BaseApplication {
if (Setting.value('clipperServer.autoStart')) {
ClipperServer.instance().start();
}
ExternalEditWatcher.instance().setLogger(reg.logger());
ExternalEditWatcher.instance().dispatch = this.store().dispatch;
}
}

View File

@@ -1,7 +1,6 @@
const { _, setLocale } = require('lib/locale.js');
const { dirname } = require('lib/path-utils.js');
const { Logger } = require('lib/logger.js');
const { powerSaveBlocker } = require('electron');
class Bridge {
@@ -9,7 +8,6 @@ class Bridge {
this.electronWrapper_ = electronWrapper;
this.autoUpdateLogger_ = null;
this.lastSelectedPath_ = null;
this.allowPowerSaveBlockerToggle_ = false;
}
electronApp() {
@@ -24,10 +22,6 @@ class Bridge {
return this.electronWrapper_.window();
}
setAllowPowerSaveBlockerToggle(v) {
this.allowPowerSaveBlockerToggle_ = v;
}
windowContentSize() {
if (!this.window()) return { width: 0, height: 0 };
const s = this.window().getContentSize();
@@ -87,6 +81,7 @@ class Bridge {
const result = this.showMessageBox_(this.window(), {
type: 'question',
message: message,
cancelId: 1,
buttons: [_('OK'), _('Cancel')],
});
return result === 0;
@@ -125,19 +120,7 @@ class Bridge {
const { checkForUpdates } = require('./checkForUpdates.js');
checkForUpdates(inBackground, window, logFilePath);
}
powerSaveBlockerStart(type) {
if (!this.allowPowerSaveBlockerToggle_) return null;
console.info('Enable powerSaveBlockerStart: ' + type);
return powerSaveBlocker.start(type);
}
powerSaveBlockerStop(id) {
if (!this.allowPowerSaveBlockerToggle_) return null;
console.info('Disable powerSaveBlocker: ' + id);
return powerSaveBlocker.stop(id);
}
}
let bridge_ = null;

File diff suppressed because one or more lines are too long

View File

@@ -53,16 +53,20 @@ class ConfigScreenComponent extends React.Component {
const labelStyle = Object.assign({}, theme.textStyle, {
display: 'inline-block',
marginRight: 10,
color: theme.color,
});
const controlStyle = {
display: 'inline-block',
color: theme.color,
backgroundColor: theme.backgroundColor,
};
const descriptionStyle = Object.assign({}, theme.textStyle, {
color: theme.colorFaded,
marginTop: 5,
fontStyle: 'italic',
maxWidth: '70em',
});
const updateSettingValue = (key, value) => {
@@ -119,7 +123,10 @@ class ConfigScreenComponent extends React.Component {
updateSettingValue(key, event.target.value);
}
const inputStyle = Object.assign({}, controlStyle, { width: '50%', minWidth: '20em' });
const inputStyle = Object.assign({}, controlStyle, {
width: '50%',
minWidth: '20em',
border: '1px solid' });
const inputType = md.secure === true ? 'password' : 'text';
return (
@@ -148,6 +155,10 @@ class ConfigScreenComponent extends React.Component {
return output;
}
onApplyClick() {
shared.saveSettings(this);
}
onSaveClick() {
shared.saveSettings(this);
this.props.dispatch({ type: 'NAV_BACK' });
@@ -159,21 +170,19 @@ class ConfigScreenComponent extends React.Component {
render() {
const theme = themeStyle(this.props.theme);
const style = Object.assign({}, this.props.style, { overflow: 'auto' });
const style = Object.assign({
backgroundColor: theme.backgroundColor
}, this.props.style, { overflow: 'auto' });
const settings = this.state.settings;
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = {
padding: 10,
};
const containerStyle = Object.assign({}, theme.containerStyle, { padding: 10 });
const buttonStyle = {
const buttonStyle = Object.assign({}, theme.buttonStyle, {
display: this.state.changedSettingKeys.length ? 'inline-block' : 'none',
marginRight: 10,
}
});
const settingComps = shared.settingsToComponents(this, 'desktop', settings);
@@ -190,7 +199,7 @@ class ConfigScreenComponent extends React.Component {
settingComps.push(
<div key="check_sync_config_button" style={this.rowStyle_}>
<button disabled={this.state.checkSyncConfigResult === 'checking'} onClick={this.checkSyncConfig_}>{_('Check synchronisation configuration')}</button>
<button style={buttonStyle} disabled={this.state.checkSyncConfigResult === 'checking'} onClick={this.checkSyncConfig_}>{_('Check synchronisation configuration')}</button>
{ statusComp }
</div>);
}
@@ -203,8 +212,9 @@ class ConfigScreenComponent extends React.Component {
{_('Notes and settings are stored in: %s', pathUtils.toSystemSlashes(Setting.value('profileDir'), process.platform))}
</div>
{ settingComps }
<button onClick={() => {this.onSaveClick()}} style={buttonStyle}>{_('Save')}</button>
<button onClick={() => {this.onSaveClick()}} style={buttonStyle}>{_('OK')}</button>
<button onClick={() => {this.onCancelClick()}} style={buttonStyle}>{_('Cancel')}</button>
<button onClick={() => {this.onApplyClick()}} style={buttonStyle}>{_('Apply')}</button>
</div>
</div>
);
@@ -222,4 +232,4 @@ const mapStateToProps = (state) => {
const ConfigScreen = connect(mapStateToProps)(ConfigScreenComponent);
module.exports = { ConfigScreen };
module.exports = { ConfigScreen };

View File

@@ -28,16 +28,18 @@ class DropboxLoginScreenComponent extends React.Component {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = Object.assign({}, theme.containerStyle, {
padding: theme.margin,
height: style.height - theme.headerHeight - theme.margin * 2,
});
const inputStyle = Object.assign({}, theme.inputStyle, { width: 500 });
return (
<div>
<Header style={headerStyle} />
<div style={{padding: theme.margin}}>
<div style={containerStyle}>
<p style={theme.textStyle}>{_('To allow Joplin to synchronise with Dropbox, please follow the steps below:')}</p>
<p style={theme.textStyle}>{_('Step 1: Open this URL in your browser to authorise the application:')}</p>
<a style={theme.textStyle} href="#" onClick={this.shared_.loginUrl_click}>{this.state.loginUrl}</a>
@@ -59,4 +61,4 @@ const mapStateToProps = (state) => {
const DropboxLoginScreen = connect(mapStateToProps)(DropboxLoginScreenComponent);
module.exports = { DropboxLoginScreen };
module.exports = { DropboxLoginScreen };

View File

@@ -50,6 +50,13 @@ class EncryptionConfigScreenComponent extends React.Component {
renderMasterKey(mk) {
const theme = themeStyle(this.props.theme);
const passwordStyle = {
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
}
const onSaveClick = () => {
return shared.onSavePasswordClick(this, mk);
}
@@ -69,7 +76,7 @@ class EncryptionConfigScreenComponent extends React.Component {
<td style={theme.textStyle}>{mk.source_application}</td>
<td style={theme.textStyle}>{time.formatMsToLocal(mk.created_time)}</td>
<td style={theme.textStyle}>{time.formatMsToLocal(mk.updated_time)}</td>
<td style={theme.textStyle}><input type="password" value={password} onChange={(event) => onPasswordChange(event)}/> <button onClick={() => onSaveClick()}>{_('Save')}</button></td>
<td style={theme.textStyle}><input type="password" style={passwordStyle} value={password} onChange={(event) => onPasswordChange(event)}/> <button style={theme.buttonStyle} onClick={() => onSaveClick()}>{_('Save')}</button></td>
<td style={theme.textStyle}>{passwordOk}</td>
</tr>
);
@@ -81,15 +88,13 @@ class EncryptionConfigScreenComponent extends React.Component {
const masterKeys = this.state.masterKeys;
const containerPadding = 10;
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerStyle = {
const containerStyle = Object.assign({}, theme.containerStyle, {
padding: containerPadding,
overflow: 'auto',
height: style.height - theme.headerHeight - containerPadding * 2,
};
});
const mkComps = [];
let nonExistingMasterKeyIds = this.props.notLoadedMasterKeys.slice();
@@ -126,7 +131,7 @@ class EncryptionConfigScreenComponent extends React.Component {
}
const decryptedItemsInfo = <p style={theme.textStyle}>{shared.decryptedStatText(this)}</p>;
const toggleButton = <button onClick={() => { onToggleButtonClick() }}>{this.props.encryptionEnabled ? _('Disable encryption') : _('Enable encryption')}</button>
const toggleButton = <button style={theme.buttonStyle} onClick={() => { onToggleButtonClick() }}>{this.props.encryptionEnabled ? _('Disable encryption') : _('Enable encryption')}</button>
let masterKeySection = null;
@@ -213,4 +218,4 @@ const mapStateToProps = (state) => {
const EncryptionConfigScreen = connect(mapStateToProps)(EncryptionConfigScreenComponent);
module.exports = { EncryptionConfigScreen };
module.exports = { EncryptionConfigScreen };

View File

@@ -35,6 +35,7 @@ class HeaderComponent extends React.Component {
this.search_onClear = (event) => {
this.setState({ searchQuery: '' });
triggerOnQuery('');
if (this.searchElement_) this.searchElement_.focus();
}
}
@@ -107,6 +108,9 @@ class HeaderComponent extends React.Component {
color: style.color,
fontSize: style.fontSize,
fontFamily: style.fontFamily,
backgroundColor: style.searchColor,
border: '1px solid',
borderColor: style.dividerColor,
};
const searchButton = {
@@ -170,6 +174,8 @@ class HeaderComponent extends React.Component {
paddingLeft: theme.headerButtonHPadding,
paddingRight: theme.headerButtonHPadding,
color: theme.color,
searchColor: theme.backgroundColor,
dividerColor: theme.dividerColor,
textDecoration: 'none',
fontFamily: theme.fontFamily,
fontSize: theme.fontSize,
@@ -211,4 +217,4 @@ const mapStateToProps = (state) => {
const Header = connect(mapStateToProps)(HeaderComponent);
module.exports = { Header };
module.exports = { Header };

View File

@@ -35,4 +35,4 @@ class IconButton extends React.Component {
}
module.exports = { IconButton };
module.exports = { IconButton };

View File

@@ -59,7 +59,7 @@ class ImportScreenComponent extends React.Component {
async doImport() {
const filePath = this.props.filePath;
const folderTitle = await Folder.findUniqueFolderTitle(filename(filePath));
const folderTitle = await Folder.findUniqueItemTitle(filename(filePath));
const messages = this.state.messages.slice();
this.addMessage('start', _('New notebook "%s" will be created and file "%s" will be imported into it', folderTitle, basename(filePath)));

View File

@@ -5,6 +5,7 @@ const { SideBar } = require('./SideBar.min.js');
const { NoteList } = require('./NoteList.min.js');
const { NoteText } = require('./NoteText.min.js');
const { PromptDialog } = require('./PromptDialog.min.js');
const NotePropertiesDialog = require('./NotePropertiesDialog.min.js');
const Setting = require('lib/models/Setting.js');
const BaseModel = require('lib/BaseModel.js');
const Tag = require('lib/models/Tag.js');
@@ -19,13 +20,24 @@ const eventManager = require('../eventManager');
class MainScreenComponent extends React.Component {
constructor() {
super();
this.notePropertiesDialog_close = this.notePropertiesDialog_close.bind(this);
}
notePropertiesDialog_close() {
this.setState({ notePropertiesDialogOptions: {} });
}
componentWillMount() {
this.setState({
promptOptions: null,
modalLayer: {
visible: false,
message: '',
}
},
notePropertiesDialogOptions: {},
});
}
@@ -108,7 +120,7 @@ class MainScreenComponent extends React.Component {
});
} else if (command.name === 'setTags') {
const tags = await Tag.tagsByNoteId(command.noteId);
const tagTitles = tags.map((a) => { return a.title });
const tagTitles = tags.map((a) => { return a.title }).sort();
this.setState({
promptOptions: {
@@ -146,7 +158,7 @@ class MainScreenComponent extends React.Component {
},
});
} else if (command.name === 'renameTag') {
const tag = await Tag.load(command.id);
const tag = await Tag.load(command.id);
if(!tag) return;
this.setState({
@@ -161,12 +173,12 @@ class MainScreenComponent extends React.Component {
} catch (error) {
bridge().showErrorMessageBox(error.message);
}
}
}
this.setState({promptOptions: null });
}
}
})
} else if (command.name === 'search') {
if (!this.searchId_) this.searchId_ = uuid.create();
@@ -189,6 +201,13 @@ class MainScreenComponent extends React.Component {
});
}
} else if (command.name === 'commandNoteProperties') {
this.setState({
notePropertiesDialogOptions: {
noteId: command.noteId,
visible: true,
},
});
} else if (command.name === 'toggleVisiblePanes') {
this.toggleVisiblePanes();
} else if (command.name === 'toggleSidebar') {
@@ -317,14 +336,17 @@ class MainScreenComponent extends React.Component {
}
render() {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const style = Object.assign({
color: theme.color,
backgroundColor: theme.backgroundColor,
}, this.props.style);
const promptOptions = this.state.promptOptions;
const folders = this.props.folders;
const notes = this.props.notes;
const messageBoxVisible = this.props.hasDisabledSyncItems || this.props.showMissingMasterKeyMessage;
const sidebarVisibility = this.props.sidebarVisibility;
const styles = this.styles(this.props.theme, style.width, style.height, messageBoxVisible, sidebarVisibility);
const theme = themeStyle(this.props.theme);
const selectedFolderId = this.props.selectedFolderId;
const onConflictFolder = this.props.selectedFolderId === Folder.conflictFolderId();
@@ -412,10 +434,19 @@ class MainScreenComponent extends React.Component {
const modalLayerStyle = Object.assign({}, styles.modalLayer, { display: this.state.modalLayer.visible ? 'block' : 'none' });
const notePropertiesDialogOptions = this.state.notePropertiesDialogOptions;
return (
<div style={style}>
<div style={modalLayerStyle}>{this.state.modalLayer.message}</div>
<NotePropertiesDialog
theme={this.props.theme}
noteId={notePropertiesDialogOptions.noteId}
visible={!!notePropertiesDialogOptions.visible}
onClose={this.notePropertiesDialog_close}
/>
<PromptDialog
autocomplete={promptOptions && ('autocomplete' in promptOptions) ? promptOptions.autocomplete : null}
defaultValue={promptOptions && promptOptions.value ? promptOptions.value : ''}
@@ -427,6 +458,7 @@ class MainScreenComponent extends React.Component {
visible={!!this.state.promptOptions}
buttons={promptOptions && ('buttons' in promptOptions) ? promptOptions.buttons : null}
inputType={promptOptions && ('inputType' in promptOptions) ? promptOptions.inputType : null} />
<Header style={styles.header} showBackButton={false} items={headerItems} />
{messageComp}
<SideBar style={styles.sideBar} />

View File

@@ -13,9 +13,16 @@ const InteropService = require('lib/services/InteropService');
const InteropServiceHelper = require('../InteropServiceHelper.js');
const Search = require('lib/models/Search');
const Mark = require('mark.js/dist/mark.min.js');
const SearchEngine = require('lib/services/SearchEngine');
class NoteListComponent extends React.Component {
constructor() {
super();
this.itemRenderer = this.itemRenderer.bind(this);
}
style() {
const theme = themeStyle(this.props.theme);
@@ -88,14 +95,43 @@ class NoteListComponent extends React.Component {
});
}}));
menu.append(new MenuItem({label: _('Switch between note and to-do type'), click: async () => {
menu.append(new MenuItem({label: _('Duplicate'), click: async () => {
for (let i = 0; i < noteIds.length; i++) {
const note = await Note.load(noteIds[i]);
await Note.save(Note.toggleIsTodo(note), { userSideValidation: true });
eventManager.emit('noteTypeToggle', { noteId: note.id });
await Note.duplicate(noteIds[i], {
uniqueTitle: _('%s - Copy', note.title),
});
}
}}));
if (noteIds.length <= 1) {
menu.append(new MenuItem({label: _('Switch between note and to-do type'), click: async () => {
for (let i = 0; i < noteIds.length; i++) {
const note = await Note.load(noteIds[i]);
await Note.save(Note.toggleIsTodo(note), { userSideValidation: true });
eventManager.emit('noteTypeToggle', { noteId: note.id });
}
}}));
} else {
const switchNoteType = async (noteIds, type) => {
for (let i = 0; i < noteIds.length; i++) {
const note = await Note.load(noteIds[i]);
const newNote = Note.changeNoteType(note, type);
if (newNote === note) continue;
await Note.save(newNote, { userSideValidation: true });
eventManager.emit('noteTypeToggle', { noteId: note.id });
}
}
menu.append(new MenuItem({label: _('Switch to note type'), click: async () => {
await switchNoteType(noteIds, 'note');
}}));
menu.append(new MenuItem({label: _('Switch to to-do type'), click: async () => {
await switchNoteType(noteIds, 'todo');
}}));
}
menu.append(new MenuItem({label: _('Copy Markdown link'), click: async () => {
const { clipboard } = require('electron');
const links = [];
@@ -119,6 +155,13 @@ class NoteListComponent extends React.Component {
}}));
}
exportMenu.append(new MenuItem({ label: 'PDF - ' + _('PDF File') , click: () => {
this.props.dispatch({
type: 'WINDOW_COMMAND',
name: 'exportPdf',
});
}}));
const exportMenuItem = new MenuItem({label: _('Export'), submenu: exportMenu});
menu.append(exportMenuItem);
@@ -133,7 +176,10 @@ class NoteListComponent extends React.Component {
menu.popup(bridge().window());
}
itemRenderer(item, theme, width) {
itemRenderer(item) {
const theme = themeStyle(this.props.theme);
const width = this.props.style.width;
const onTitleClick = async (event, item) => {
if (event.ctrlKey) {
event.preventDefault();
@@ -189,8 +235,11 @@ class NoteListComponent extends React.Component {
let highlightedWords = [];
if (this.props.notesParentType === 'Search') {
const search = BaseModel.byId(this.props.searches, this.props.selectedSearchId);
highlightedWords = search ? Search.keywords(search.query_pattern) : [];
const query = BaseModel.byId(this.props.searches, this.props.selectedSearchId);
if (query) {
const parsedQuery = SearchEngine.instance().parseQuery(query.query_pattern);
highlightedWords = SearchEngine.instance().allParsedQueryTerms(parsedQuery);
}
}
let style = Object.assign({ width: width }, this.style().listItem);
@@ -221,7 +270,18 @@ class NoteListComponent extends React.Component {
exclude: ['img'],
acrossElements: true,
});
mark.mark(highlightedWords);
mark.unmark();
for (let i = 0; i < highlightedWords.length; i++) {
const w = highlightedWords[i];
if (w.type === 'regex') {
mark.markRegExp(new RegExp(w.value, 'gmi'), { acrossElements: true });
} else {
mark.mark([w]);
}
}
// Note: in this case it is safe to use dangerouslySetInnerHTML because titleElement
// is a span tag that we created and that contains data that's been inserted as plain text
@@ -233,6 +293,14 @@ class NoteListComponent extends React.Component {
titleComp = <span>{displayTitle}</span>
}
const watchedIconStyle = {
paddingRight: 4,
color: theme.color,
};
const watchedIcon = this.props.watchedNoteFiles.indexOf(item.id) < 0 ? null : (
<i style={watchedIconStyle} className={"fa fa-external-link"}></i>
);
// Need to include "todo_completed" in key so that checkbox is updated when
// item is changed via sync.
return <div key={item.id + '_' + item.todo_completed} style={style}>
@@ -247,6 +315,7 @@ class NoteListComponent extends React.Component {
onDragStart={(event) => onDragStart(event) }
data-id={item.id}
>
{watchedIcon}
{titleComp}
</a>
</div>
@@ -277,7 +346,7 @@ class NoteListComponent extends React.Component {
style={style}
className={"note-list"}
items={notes}
itemRenderer={ (item) => { return this.itemRenderer(item, theme, style.width) } }
itemRenderer={this.itemRenderer}
></ItemList>
);
}
@@ -293,6 +362,7 @@ const mapStateToProps = (state) => {
notesParentType: state.notesParentType,
searches: state.searches,
selectedSearchId: state.selectedSearchId,
watchedNoteFiles: state.watchedNoteFiles,
};
};

View File

@@ -0,0 +1,381 @@
const React = require('react');
const { connect } = require('react-redux');
const { _ } = require('lib/locale.js');
const moment = require('moment');
const { themeStyle } = require('../theme.js');
const { time } = require('lib/time-utils.js');
const Datetime = require('react-datetime');
const Note = require('lib/models/Note');
const formatcoords = require('formatcoords');
const { bridge } = require('electron').remote.require('./bridge');
class NotePropertiesDialog extends React.Component {
constructor() {
super();
this.okButton_click = this.okButton_click.bind(this);
this.cancelButton_click = this.cancelButton_click.bind(this);
this.state = {
formNote: null,
editedKey: null,
editedValue: null,
visible: false,
};
this.keyToLabel_ = {
id: _('ID'),
user_created_time: _('Created'),
user_updated_time: _('Updated'),
location: _('Location'),
source_url: _('URL'),
};
}
componentWillReceiveProps(newProps) {
if ('visible' in newProps && newProps.visible !== this.state.visible) {
this.setState({ visible: newProps.visible });
}
if ('noteId' in newProps) {
this.loadNote(newProps.noteId);
}
}
async loadNote(noteId) {
if (!noteId) {
this.setState({ formNote: null });
} else {
const note = await Note.load(noteId);
const formNote = this.noteToFormNote(note);
this.setState({ formNote: formNote });
}
}
latLongFromLocation(location) {
const o = {};
const l = location.split(',');
if (l.length == 2) {
o.latitude = l[0].trim();
o.longitude = l[1].trim();
} else {
o.latitude = '';
o.longitude = '';
}
return o;
}
noteToFormNote(note) {
const formNote = {};
formNote.user_updated_time = time.formatMsToLocal(note.user_updated_time);
formNote.user_created_time = time.formatMsToLocal(note.user_created_time);
formNote.source_url = note.source_url;
formNote.location = '';
if (Number(note.latitude) || Number(note.longitude)) {
formNote.location = note.latitude + ', ' + note.longitude;
}
formNote.id = note.id;
return formNote;
}
formNoteToNote(formNote) {
const note = Object.assign({ id: formNote.id }, this.latLongFromLocation(formNote.location));
note.user_created_time = time.formatLocalToMs(formNote.user_created_time);
note.user_updated_time = time.formatLocalToMs(formNote.user_updated_time);
note.source_url = formNote.source_url;
return note;
}
styles(themeId) {
const styleKey = themeId;
if (styleKey === this.styleKey_) return this.styles_;
const theme = themeStyle(themeId);
this.styles_ = {};
this.styleKey_ = styleKey;
this.styles_.modalLayer = {
zIndex: 9999,
display: 'flex',
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
backgroundColor: 'rgba(0,0,0,0.6)',
alignItems: 'flex-start',
justifyContent: 'center',
};
this.styles_.dialogBox = {
backgroundColor: theme.backgroundColor,
padding: 16,
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
marginTop: 20,
}
this.styles_.controlBox = {
marginBottom: '1em',
color: 'black', //This will apply for the calendar
};
this.styles_.button = {
minWidth: theme.buttonMinWidth,
minHeight: theme.buttonMinHeight,
marginLeft: 5,
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.editPropertyButton = {
color: theme.color,
textDecoration: 'none',
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.input = {
display:'inline-block',
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.dialogTitle = Object.assign({}, theme.h1Style, { marginBottom: '1.2em' });
return this.styles_;
}
async closeDialog(applyChanges) {
if (applyChanges) {
await this.saveProperty();
const note = this.formNoteToNote(this.state.formNote);
note.updated_time = Date.now();
await Note.save(note, { autoTimestamp: false });
} else {
await this.cancelProperty();
}
this.setState({
visible: false,
});
if (this.props.onClose) {
this.props.onClose();
}
}
okButton_click() {
this.closeDialog(true);
}
cancelButton_click() {
this.closeDialog(false);
}
editPropertyButtonClick(key, initialValue) {
this.setState({
editedKey: key,
editedValue: initialValue,
});
setTimeout(() => {
if (this.refs.editField.openCalendar) {
this.refs.editField.openCalendar();
} else {
this.refs.editField.focus();
}
}, 100);
}
async saveProperty() {
if (!this.state.editedKey) return;
return new Promise((resolve, reject) => {
const newFormNote = Object.assign({}, this.state.formNote);
if (this.state.editedKey.indexOf('_time') >= 0) {
const dt = time.anythingToDateTime(this.state.editedValue, new Date());
newFormNote[this.state.editedKey] = time.formatMsToLocal(dt.getTime());
} else {
newFormNote[this.state.editedKey] = this.state.editedValue;
}
this.setState({
formNote: newFormNote,
editedKey: null,
editedValue: null
}, () => { resolve() });
});
}
async cancelProperty() {
return new Promise((resolve, reject) => {
this.setState({
editedKey: null,
editedValue: null
}, () => { resolve() });
});
}
createNoteField(key, value) {
const styles = this.styles(this.props.theme);
const theme = themeStyle(this.props.theme);
const labelComp = <label style={Object.assign({}, theme.textStyle, {marginRight: '1em', width: '6em', display:'inline-block', fontWeight: 'bold'})}>{this.formatLabel(key)}</label>;
let controlComp = null;
let editComp = null;
let editCompHandler = null;
let editCompIcon = null;
const onKeyDown = (event) => {
if (event.keyCode === 13) {
this.saveProperty();
} else if (event.keyCode === 27) {
this.cancelProperty();
}
}
if (this.state.editedKey === key) {
if (key.indexOf('_time') >= 0) {
controlComp = <Datetime
ref="editField"
defaultValue={value}
dateFormat={time.dateFormat()}
timeFormat={time.timeFormat()}
inputProps={{
onKeyDown: (event) => onKeyDown(event, key),
style: styles.input
}}
onChange={(momentObject) => {this.setState({ editedValue: momentObject })}}
/>
editCompHandler = () => {this.saveProperty()};
editCompIcon = 'fa-save';
} else {
controlComp = <input
defaultValue={value}
type="text"
ref="editField"
onChange={(event) => {this.setState({ editedValue: event.target.value })}}
onKeyDown={(event) => onKeyDown(event)}
style={styles.input}
/>
}
} else {
let displayedValue = value;
if (key === 'location') {
try {
const dms = formatcoords(value);
displayedValue = dms.format('DDMMss', { decimalPlaces: 0 });
} catch (error) {
displayedValue = '';
}
}
if (['source_url', 'location'].indexOf(key) >= 0) {
let url = '';
if (key === 'source_url') url = value;
if (key === 'location') {
const ll = this.latLongFromLocation(value);
url = Note.geoLocationUrlFromLatLong(ll.latitude, ll.longitude);
}
controlComp = <a href="#" onClick={() => bridge().openExternal(url)} style={theme.urlStyle}>{displayedValue}</a>
} else {
controlComp = <div style={Object.assign({}, theme.textStyle, {display: 'inline-block'})}>{displayedValue}</div>
}
if (key !== 'id') {
editCompHandler = () => {this.editPropertyButtonClick(key, value)};
editCompIcon = 'fa-edit';
}
}
if (editCompHandler) {
editComp = (
<a href="#" onClick={editCompHandler} style={styles.editPropertyButton}>
<i className={'fa ' + editCompIcon} aria-hidden="true" style={{ marginLeft: '.5em'}}></i>
</a>
);
}
return (
<div key={key} style={this.styles_.controlBox} className="note-property-box">
{ labelComp }
{ controlComp }
{ editComp }
</div>
);
}
formatLabel(key) {
if (this.keyToLabel_[key]) return this.keyToLabel_[key];
return key;
}
formatValue(key, note) {
if (key === 'location') {
if (!Number(note.latitude) && !Number(note.longitude)) return null;
const dms = formatcoords(Number(note.latitude), Number(note.longitude))
return dms.format('DDMMss', { decimalPlaces: 0 });
}
if (['user_updated_time', 'user_created_time'].indexOf(key) >= 0) {
return time.formatMsToLocal(note[key]);
}
return note[key];
}
render() {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const styles = this.styles(this.props.theme);
const formNote = this.state.formNote;
const buttonComps = [];
buttonComps.push(<button key="ok" style={styles.button} onClick={this.okButton_click}>{_('Apply')}</button>);
buttonComps.push(<button key="cancel" style={styles.button} onClick={this.cancelButton_click}>{_('Cancel')}</button>);
const noteComps = [];
const modalLayerStyle = Object.assign({}, styles.modalLayer);
if (!this.state.visible) modalLayerStyle.display = 'none';
if (formNote) {
for (let key in formNote) {
if (!formNote.hasOwnProperty(key)) continue;
const comp = this.createNoteField(key, formNote[key]);
noteComps.push(comp);
}
}
return (
<div style={modalLayerStyle}>
<div style={styles.dialogBox}>
<div style={styles.dialogTitle}>{_('Note properties')}</div>
<div>{noteComps}</div>
<div style={{ textAlign: 'right', marginTop: 10 }}>
{buttonComps}
</div>
</div>
</div>
);
}
}
module.exports = NotePropertiesDialog;

View File

@@ -0,0 +1,122 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('../theme.js');
const { _ } = require('lib/locale.js');
class NoteSearchBarComponent extends React.Component {
constructor() {
super();
this.state = {
query: '',
};
this.searchInput_change = this.searchInput_change.bind(this);
this.previousButton_click = this.previousButton_click.bind(this);
this.nextButton_click = this.nextButton_click.bind(this);
this.closeButton_click = this.closeButton_click.bind(this);
}
style() {
const theme = themeStyle(this.props.theme);
let style = {
root: Object.assign({}, theme.textStyle, {
backgroundColor: theme.backgroundColor,
color: theme.colorFaded,
}),
};
return style;
}
componentDidMount() {
this.refs.searchInput.focus();
}
buttonIconComponent(iconName, clickHandler) {
const theme = themeStyle(this.props.theme);
const searchButton = {
paddingLeft: 4,
paddingRight: 4,
paddingTop: 2,
paddingBottom: 2,
textDecoration: 'none',
marginRight: 5,
};
const iconStyle = {
display: 'flex',
fontSize: Math.round(theme.fontSize) * 1.2,
color: theme.color,
};
const icon = <i style={iconStyle} className={"fa " + iconName}></i>
return (
<a
href="#"
style={searchButton}
onClick={clickHandler}
>{icon}</a>
);
}
searchInput_change(event) {
const query = event.currentTarget.value;
this.setState({ query: query });
this.triggerOnChange(query);
}
previousButton_click(event) {
if (this.props.onPrevious) this.props.onPrevious();
}
nextButton_click(event) {
if (this.props.onNext) this.props.onNext();
}
closeButton_click(event) {
if (this.props.onClose) this.props.onClose();
}
triggerOnChange(query) {
if (this.props.onChange) this.props.onChange(query);
}
focus() {
this.refs.searchInput.focus();
}
render() {
const theme = themeStyle(this.props.theme);
const closeButton = this.buttonIconComponent('fa-times', this.closeButton_click);
const previousButton = this.buttonIconComponent('fa-chevron-up', this.previousButton_click);
const nextButton = this.buttonIconComponent('fa-chevron-down', this.nextButton_click);
return (
<div style={this.props.style}>
<div style={{display: 'flex', flexDirection: 'row', alignItems: 'center' }}>
{ closeButton }
<input placeholder={_('Search...')} value={this.state.query} onChange={this.searchInput_change} ref="searchInput" type="text" style={{width: 200, marginRight: 5}}></input>
{ nextButton }
{ previousButton }
</div>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
theme: state.settings.theme,
};
};
const NoteSearchBar = connect(mapStateToProps, null, null, { withRef: true })(NoteSearchBarComponent);
module.exports = NoteSearchBar;

File diff suppressed because it is too large Load Diff

View File

@@ -73,14 +73,14 @@ class OneDriveLoginScreenComponent extends React.Component {
const style = this.props.style;
const theme = themeStyle(this.props.theme);
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const webviewStyle = {
width: this.props.style.width,
height: this.props.style.height - theme.headerHeight,
overflow: 'hidden',
color: theme.color,
backgroundColor: theme.backgroundColor,
};
const headerButtons = [
@@ -109,4 +109,4 @@ const mapStateToProps = (state) => {
const OneDriveLoginScreen = connect(mapStateToProps)(OneDriveLoginScreenComponent);
module.exports = { OneDriveLoginScreen };
module.exports = { OneDriveLoginScreen };

View File

@@ -59,7 +59,7 @@ class PromptDialog extends React.Component {
};
this.styles_.promptDialog = {
backgroundColor: 'white',
backgroundColor: theme.backgroundColor,
padding: 16,
display: 'inline-block',
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
@@ -69,6 +69,10 @@ class PromptDialog extends React.Component {
minWidth: theme.buttonMinWidth,
minHeight: theme.buttonMinHeight,
marginLeft: 5,
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.label = {
@@ -82,6 +86,10 @@ class PromptDialog extends React.Component {
this.styles_.input = {
width: 0.5 * width,
maxWidth: 400,
color: theme.color,
backgroundColor: theme.backgroundColor,
border: '1px solid',
borderColor: theme.dividerColor,
};
this.styles_.desc = Object.assign({}, theme.textStyle, {
@@ -102,7 +110,8 @@ class PromptDialog extends React.Component {
if (this.props.onClose) {
let outputAnswer = this.state.answer;
if (this.props.inputType === 'datetime') {
outputAnswer = anythingToDate(outputAnswer);
// outputAnswer = anythingToDate(outputAnswer);
outputAnswer = time.anythingToDateTime(outputAnswer);
}
this.props.onClose(accept ? outputAnswer : null, buttonType);
}
@@ -113,14 +122,14 @@ class PromptDialog extends React.Component {
this.setState({ answer: event.target.value });
}
const anythingToDate = (o) => {
if (o && o.toDate) return o.toDate();
if (!o) return null;
let m = moment(o, time.dateTimeFormat());
if (m.isValid()) return m.toDate();
m = moment(o, time.dateFormat());
return m.isValid() ? m.toDate() : null;
}
// const anythingToDate = (o) => {
// if (o && o.toDate) return o.toDate();
// if (!o) return null;
// let m = moment(o, time.dateTimeFormat());
// if (m.isValid()) return m.toDate();
// m = moment(o, time.dateFormat());
// return m.isValid() ? m.toDate() : null;
// }
const onDateTimeChange = (momentObject) => {
this.setState({ answer: momentObject });
@@ -141,6 +150,7 @@ class PromptDialog extends React.Component {
if (this.props.inputType === 'datetime') {
inputComp = <Datetime
value={this.state.answer}
inputProps={{style: styles.input}}
dateFormat={time.dateFormat()}
timeFormat={time.timeFormat()}
onChange={(momentObject) => onDateTimeChange(momentObject)}
@@ -165,7 +175,7 @@ class PromptDialog extends React.Component {
<div style={styles.modalLayer}>
<div style={styles.promptDialog}>
<label style={styles.label}>{this.props.label ? this.props.label : ''}</label>
<div style={{display: 'inline-block'}}>
<div style={{display: 'inline-block', color: 'black', backgroundColor: theme.backgroundColor}}>
{inputComp}
{descComp}
</div>
@@ -179,4 +189,4 @@ class PromptDialog extends React.Component {
}
module.exports = { PromptDialog };
module.exports = { PromptDialog };

View File

@@ -12,6 +12,7 @@ const { bridge } = require("electron").remote.require("./bridge");
const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem;
const InteropServiceHelper = require("../InteropServiceHelper.js");
const { shim } = require('lib/shim');
class SideBarComponent extends React.Component {
@@ -55,6 +56,21 @@ class SideBarComponent extends React.Component {
}
};
this.onTagDrop_ = async (event) => {
const tagId = event.currentTarget.getAttribute('tagid');
const dt = event.dataTransfer;
if (!dt) return;
if (dt.types.indexOf("text/x-jop-note-ids") >= 0) {
event.preventDefault();
const noteIds = JSON.parse(dt.getData("text/x-jop-note-ids"));
for (let i = 0; i < noteIds.length; i++) {
await Tag.addNote(tagId, noteIds[i]);
}
}
}
this.onFolderToggleClick_ = async (event) => {
const folderId = event.currentTarget.getAttribute('folderid');
@@ -163,6 +179,35 @@ class SideBarComponent extends React.Component {
return style;
}
clearForceUpdateDuringSync() {
if (this.forceUpdateDuringSyncIID_) {
clearInterval(this.forceUpdateDuringSyncIID_);
this.forceUpdateDuringSyncIID_ = null;
}
}
componentDidUpdate(prevProps) {
if (shim.isLinux()) {
// For some reason, the UI seems to sleep in some Linux distro during
// sync. Cannot find the reason for it and cannot replicate, so here
// as a test force the update at regular intervals.
// https://github.com/laurent22/joplin/issues/312#issuecomment-429472193
if (!prevProps.syncStarted && this.props.syncStarted) {
this.clearForceUpdateDuringSync();
this.forceUpdateDuringSyncIID_ = setInterval(() => {
this.forceUpdate();
}, 2000);
}
if (prevProps.syncStarted && !this.props.syncStarted) this.clearForceUpdateDuringSync();
}
}
componentWillUnmount() {
this.clearForceUpdateDuringSync();
}
itemContextMenu(event) {
const itemId = event.target.getAttribute("data-id");
if (itemId === Folder.conflictFolderId()) return;
@@ -238,14 +283,22 @@ class SideBarComponent extends React.Component {
const InteropService = require("lib/services/InteropService.js");
const exportMenu = new Menu();
const ioService = new InteropService();
const ioModules = ioService.modules();
for (let i = 0; i < ioModules.length; i++) {
const module = ioModules[i];
if (module.type !== 'exporter') continue;
exportMenu.append(new MenuItem({ label: module.fullLabel() , click: async () => {
await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceFolderIds: [itemId] });
}}));
}
menu.append(
new MenuItem({
label: _("Export"),
click: async () => {
const ioService = new InteropService();
const module = ioService.moduleByFormat_("exporter", "jex");
await InteropServiceHelper.export(this.props.dispatch.bind(this), module, { sourceFolderIds: [itemId] });
},
submenu: exportMenu,
})
);
}
@@ -346,8 +399,10 @@ class SideBarComponent extends React.Component {
data-id={tag.id}
data-type={BaseModel.TYPE_TAG}
onContextMenu={event => this.itemContextMenu(event)}
tagid={tag.id}
key={tag.id}
style={style}
onDrop={this.onTagDrop_}
onClick={() => {
this.tagItem_click(tag);
}}
@@ -445,7 +500,19 @@ class SideBarComponent extends React.Component {
);
}
let decryptionReportText = '';
if (this.props.decryptionWorker && this.props.decryptionWorker.state !== 'idle' && this.props.decryptionWorker.itemCount) {
decryptionReportText = _('Decrypting items: %d/%d', this.props.decryptionWorker.itemIndex + 1, this.props.decryptionWorker.itemCount);
}
let resourceFetcherText = '';
if (this.props.resourceFetcher && this.props.resourceFetcher.toFetchCount) {
resourceFetcherText = _('Fetching resources: %d', this.props.resourceFetcher.toFetchCount);
}
let lines = Synchronizer.reportToLines(this.props.syncReport);
if (resourceFetcherText) lines.push(resourceFetcherText);
if (decryptionReportText) lines.push(decryptionReportText);
const syncReportText = [];
for (let i = 0; i < lines.length; i++) {
syncReportText.push(
@@ -485,6 +552,8 @@ const mapStateToProps = state => {
locale: state.settings.locale,
theme: state.settings.theme,
collapsedFolderIds: state.collapsedFolderIds,
decryptionWorker: state.decryptionWorker,
resourceFetcher: state.resourceFetcher,
};
};

View File

@@ -47,17 +47,14 @@ class StatusScreenComponent extends React.Component {
const theme = themeStyle(this.props.theme);
const style = this.props.style;
const headerStyle = {
width: style.width,
};
const headerStyle = Object.assign({}, theme.headerStyle, { width: style.width });
const containerPadding = 10;
const containerStyle = {
const containerStyle = Object.assign({}, theme.containerStyle, {
padding: containerPadding,
overflowY: 'auto',
height: style.height - theme.headerHeight - containerPadding * 2,
};
});
function renderSectionTitleHtml(key, title) {
return <h2 key={'section_' + key} style={theme.h2Style}>{title}</h2>
@@ -134,4 +131,4 @@ const mapStateToProps = (state) => {
const StatusScreen = connect(mapStateToProps)(StatusScreenComponent);
module.exports = { StatusScreen };
module.exports = { StatusScreen };

View File

@@ -0,0 +1,21 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('../theme.js');
class TagItemComponent extends React.Component {
render() {
const theme = themeStyle(this.props.theme);
const style = Object.assign({}, theme.tagStyle);
const title = this.props.title;
return <span style={style}>{title}</span>;
}
}
const mapStateToProps = (state) => {
return { theme: state.settings.theme };
};
const TagItem = connect(mapStateToProps)(TagItemComponent);
module.exports = TagItem;

View File

@@ -0,0 +1,50 @@
const React = require('react');
const { connect } = require('react-redux');
const { themeStyle } = require('../theme.js');
const TagItem = require('./TagItem.min.js');
class TagListComponent extends React.Component {
render() {
const style = Object.assign({}, this.props.style);
const theme = themeStyle(this.props.theme);
const tags = this.props.items;
style.display = 'flex';
style.flexDirection = 'row';
style.borderBottom = '1px solid ' + theme.dividerColor;
style.boxSizing = 'border-box';
style.fontSize = theme.fontSize;
const tagItems = [];
if (tags || tags.length > 0) {
// Sort by id for now, but probably needs to be changed in the future.
tags.sort((a, b) => { return a.title < b.title ? -1 : +1; });
for (let i = 0; i < tags.length; i++) {
const props = {
title: tags[i].title,
key: tags[i].id
};
tagItems.push(<TagItem {...props} />);
}
}
if (tagItems.length === 0) {
style.visibility = 'hidden';
}
return (
<div className="tag-list" style={style}>
{ tagItems }
</div>
)
}
}
const mapStateToProps = (state) => {
return { theme: state.settings.theme };
};
const TagList = connect(mapStateToProps)(TagListComponent);
module.exports = TagList;

View File

@@ -30,4 +30,4 @@ class Dialogs {
const dialogs = new Dialogs();
module.exports = dialogs;
module.exports = dialogs;

View File

@@ -0,0 +1,77 @@
/*
Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage
Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
line-height: 1.3em;
color: #abb2bf;
background: #282c34;
border-radius: 5px;
}
.hljs-keyword, .hljs-operator {
color: #F92672;
}
.hljs-pattern-match {
color: #F92672;
}
.hljs-pattern-match .hljs-constructor {
color: #61aeee;
}
.hljs-function {
color: #61aeee;
}
.hljs-function .hljs-params {
color: #A6E22E;
}
.hljs-function .hljs-params .hljs-typing {
color: #FD971F;
}
.hljs-module-access .hljs-module {
color: #7e57c2;
}
.hljs-constructor {
color: #e2b93d;
}
.hljs-constructor .hljs-string {
color: #9CCC65;
}
.hljs-comment, .hljs-quote {
color: #b18eb1;
font-style: italic;
}
.hljs-doctag, .hljs-formula {
color: #c678dd;
}
.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst {
color: #e06c75;
}
.hljs-literal {
color: #56b6c2;
}
.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string {
color: #98c379;
}
.hljs-built_in, .hljs-class .hljs-title {
color: #e6c07b;
}
.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number {
color: #d19a66;
}
.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title {
color: #61aeee;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link {
text-decoration: underline;
}

View File

@@ -16,6 +16,11 @@
}
mark {
background: #F3B717;
color: black;
}
.mark-selected {
background: #CF3F00;
color: white;
}
@@ -34,9 +39,24 @@
<div id="content" ondragstart="return false;" ondrop="return false;"></div>
<script>
const { ipcRenderer } = require('electron');
const contentElement = document.getElementById('content');
const ipc = {};
window.addEventListener('message', (event) => {
// Here we only deal with messages that are sent from the main Electro process to the webview.
if (!event.data || event.data.target !== 'webview') return;
const callName = event.data.name;
const callData = event.data.data;
if (!ipc[callName]) {
console.warn('Missing IPC function:', event.data);
} else {
ipc[callName](callData);
}
});
// ----------------------------------------------------------------------
// Handle dynamically loading HLJS when a code element is present
// ----------------------------------------------------------------------
@@ -44,7 +64,7 @@
let hljsScriptAdded = false;
let hljsLoaded = false;
function loadHljs(callback) {
function loadHljs(options) {
hljsScriptAdded = true;
const script = document.createElement('script');
@@ -59,16 +79,16 @@
link.rel = 'stylesheet';
// https://ace.c9.io/build/kitchen-sink.html
// https://highlightjs.org/static/demo/
link.href = 'highlight/styles/atom-one-light.css';
link.href = 'highlight/styles/' + options.codeTheme;
document.getElementById('hlScriptContainer').appendChild(link);
}
function loadAndApplyHljs() {
function loadAndApplyHljs(options) {
var codeElements = document.getElementsByClassName('code');
if (!codeElements.length) return;
if (!hljsScriptAdded) {
this.loadHljs();
this.loadHljs(options);
return;
}
@@ -120,12 +140,16 @@
setPercentScroll(percentScroll_);
}
ipcRenderer.on('setHtml', (event, html) => {
ipc.setHtml = (event) => {
const html = event.html;
markJsHackMarkerInserted_ = false;
updateBodyHeight();
contentElement.innerHTML = html;
loadAndApplyHljs();
loadAndApplyHljs(event.options);
// Remove the bullet from "ul" for checkbox lists and extra padding
// const checkboxes = document.getElementsByClassName('checkbox');
@@ -159,10 +183,12 @@
}
}, 1);
}
});
}
let ignoreNextScrollEvent = false;
ipcRenderer.on('setPercentScroll', (event, percent) => {
ipc.setPercentScroll = (event) => {
const percent = event.percent;
if (checkScrollIID_) {
clearInterval(checkScrollIID_);
checkScrollIID_ = null;
@@ -170,10 +196,36 @@
ignoreNextScrollEvent = true;
setPercentScroll(percent);
});
}
// HACK for Mark.js bug - https://github.com/julmot/mark.js/issues/127
let markJsHackMarkerInserted_ = false;
function addMarkJsSpaceHack(document) {
if (markJsHackMarkerInserted_) return;
const prepareElementsForMarkJs = (elements, type) => {
// const markJsHackMarker_ = '&#8203; &#8203;'
const markJsHackMarker_ = ' ';
for (let i = 0; i < elements.length; i++) {
if (!type) {
elements[i].innerHTML = elements[i].innerHTML + markJsHackMarker_;
} else if (type === 'insertBefore') {
elements[i].insertAdjacentHTML('beforeBegin', markJsHackMarker_);
}
}
}
prepareElementsForMarkJs(document.getElementsByTagName('p'));
prepareElementsForMarkJs(document.getElementsByTagName('div'));
prepareElementsForMarkJs(document.getElementsByTagName('br'), 'insertBefore');
markJsHackMarkerInserted_ = true;
}
let mark_ = null;
function setMarkers(keywords) {
let markSelectedElement_ = null;
function setMarkers(keywords, options = null) {
if (!options) options = {};
if (!mark_) {
mark_ = new Mark(document.getElementById('content'), {
exclude: ['img'],
@@ -181,26 +233,68 @@
});
}
mark_.mark(keywords);
addMarkJsSpaceHack(document);
mark_.unmark()
if (markSelectedElement_) markSelectedElement_.classList.remove('mark-selected');
let selectedElement = null;
let elementIndex = 0;
const onEachElement = (element) => {
if (!('selectedIndex' in options)) return;
if (('selectedIndex' in options) && elementIndex === options.selectedIndex) {
markSelectedElement_ = element;
element.classList.add('mark-selected');
selectedElement = element;
}
elementIndex++;
}
for (let i = 0; i < keywords.length; i++) {
const keyword = keywords[i];
if (keyword.type === 'regex') {
mark_.markRegExp(new RegExp(keyword.value, 'gmi'), {
each: onEachElement,
acrossElements: true,
});
} else {
mark_.mark([keyword], {
each: onEachElement,
accuracy: 'exactly',
});
}
}
ipcProxySendToHost('setMarkerCount', elementIndex);
if (selectedElement) selectedElement.scrollIntoView();
}
let markLoaded_ = false;
ipcRenderer.on('setMarkers', (event, keywords) => {
ipc.setMarkers = (event) => {
const keywords = event.keywords;
const options = event.options;
if (!keywords.length && !markLoaded_) return;
if (!markLoaded_) {
const script = document.createElement('script');
script.onload = function() {
setMarkers(keywords);
setMarkers(keywords, options);
};
script.src = '../../node_modules/mark.js/dist/mark.min.js';
document.getElementById('markScriptContainer').appendChild(script);
markLoaded_ = true;
} else {
setMarkers(keywords);
setMarkers(keywords, options);
}
});
}
function maxScrollTop() {
return Math.max(0, contentElement.scrollHeight - contentElement.clientHeight);
@@ -211,6 +305,10 @@
document.getElementById('body').style.height = window.innerHeight + 'px';
}
const ipcProxySendToHost = (methodName, arg) => {
window.postMessage({ target: 'main', name: methodName, args: [ arg ] }, '*');
}
contentElement.addEventListener('scroll', function(e) {
if (ignoreNextScrollEvent) {
ignoreNextScrollEvent = false;
@@ -219,7 +317,8 @@
const m = maxScrollTop();
const percent = m ? contentElement.scrollTop / m : 0;
setPercentScroll(percent);
ipcRenderer.sendToHost('percentScroll', percent);
ipcProxySendToHost('percentScroll', percent);
});
document.addEventListener('contextmenu', function(event) {
@@ -229,10 +328,53 @@
if (element && !element.getAttribute('data-resource-id')) element = element.parentElement;
if (element && element.getAttribute('data-resource-id')) {
ipcRenderer.sendToHost('contextMenu', {
type: element.getAttribute('src') ? 'image' : 'link',
ipcProxySendToHost('contextMenu', {
type: element.getAttribute('src') ? 'image' : 'resource',
resourceId: element.getAttribute('data-resource-id'),
});
} else {
const selectedText = window.getSelection().toString();
if (selectedText) {
ipcProxySendToHost('contextMenu', {
type: 'text',
textToCopy: selectedText,
});
} else if (event.target.getAttribute('href')) {
ipcProxySendToHost('contextMenu', {
type: 'link',
textToCopy: event.target.getAttribute('href'),
});
}
}
});
function handleInternalLink(event, anchorNode) {
const href = anchorNode.getAttribute('href');
if (href.indexOf('#') === 0) {
event.preventDefault();
location.hash = href;
return true;
}
return false;
}
document.addEventListener('click', function(event) {
const t = event.target;
// Prevent URLs added via <a> tags from being opened within the application itself
// otherwise it would open the whole website within the WebView.
if (t && t.nodeName === 'A' && !t.hasAttribute('data-from-md')) {
if (handleInternalLink(event, t)) return;
event.preventDefault();
ipcProxySendToHost(t.getAttribute('href'));
return;
}
// If this is an internal link, jump to the anchor directly
if (t && t.nodeName === 'A' && t.hasAttribute('data-from-md')) {
if (handleInternalLink(event, t)) return;
}
});
@@ -258,4 +400,4 @@
</script>
</body>
</html>
</html>

View File

@@ -0,0 +1,36 @@
// In order to give access to the webview to certain functions of the main process, we need
// this bridge which listens from the main process and sends to the webview and the other
// way around. This is necessary after having enabled the "contextIsolation" option, which
// prevents the webview from accessing low-level methods in the main process.
const ipcRenderer = require('electron').ipcRenderer;
ipcRenderer.on('setHtml', (event, html, options) => {
window.postMessage({ target: 'webview', name: 'setHtml', data: { html: html, options: options } }, '*');
});
ipcRenderer.on('setPercentScroll', (event, percent) => {
window.postMessage({ target: 'webview', name: 'setPercentScroll', data: { percent: percent } }, '*');
});
ipcRenderer.on('setMarkers', (event, keywords, options) => {
window.postMessage({ target: 'webview', name: 'setMarkers', data: { keywords: keywords, options: options } }, '*');
});
window.addEventListener('message', (event) => {
// Here we only deal with messages that are sent from the webview to the main Electron process
if (!event.data || event.data.target !== 'main') return;
const callName = event.data.name;
const args = event.data.args;
if (args.length === 0) {
ipcRenderer.sendToHost(callName);
} else if (args.length === 1) {
ipcRenderer.sendToHost(callName, args[0]);
} else if (args.length === 2) {
ipcRenderer.sendToHost(callName, args[1]);
} else {
throw new Error('Unsupported number of args');
}
});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More