You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-27 20:29:45 +02:00
Compare commits
97 Commits
android-v1
...
android-v1
Author | SHA1 | Date | |
---|---|---|---|
|
5014914dc9 | ||
|
122ab83a84 | ||
|
7a985c2c8a | ||
|
b11ad30a31 | ||
|
5914fc97df | ||
|
e41ae1832d | ||
|
89b50909ed | ||
|
edccd7412f | ||
|
c76beae057 | ||
|
23c5934a7d | ||
|
a078947d6d | ||
|
5ba98b4200 | ||
|
c36513b99d | ||
|
97814531fa | ||
|
fd3e335a02 | ||
|
e676fa2b57 | ||
|
122cbbf673 | ||
|
271793b324 | ||
|
134b31933b | ||
|
0ec5518a62 | ||
|
76931370d7 | ||
|
8cf0e4517a | ||
|
e75c62bf0f | ||
|
058285e0b9 | ||
|
795568d8c2 | ||
|
df4933fddd | ||
|
4046a51472 | ||
|
45845f645d | ||
|
d7fd8944f7 | ||
|
3cee671f25 | ||
|
8f2e5faff3 | ||
|
39ddd934f6 | ||
|
9f8a46b9d9 | ||
|
c6698eaea6 | ||
|
8a96cf3434 | ||
|
74d255c056 | ||
|
71aa841265 | ||
|
14a93a9f26 | ||
|
e1fd9c6922 | ||
|
b9db747b5c | ||
|
4a56c76901 | ||
|
6bb3184a72 | ||
|
7fb8fbd450 | ||
|
9d5bba472e | ||
|
e6d821a45f | ||
|
72f0027e21 | ||
|
29a13a9943 | ||
|
3691ae4d13 | ||
|
4dda397c29 | ||
|
b4b058998d | ||
|
10919e415e | ||
|
4966d74864 | ||
|
c70ecb30a5 | ||
|
acc0d17e0f | ||
|
b509b878bf | ||
|
322ec2efa1 | ||
|
1232661b1e | ||
|
c46d123503 | ||
|
8f4060999f | ||
|
0addd86069 | ||
|
760086307b | ||
|
fc6558a64c | ||
|
eca500880d | ||
|
90bcd7c977 | ||
|
cca0c6eaf3 | ||
|
b0736002be | ||
|
51fc2d8e51 | ||
|
d87c192ff1 | ||
|
52ccf398a6 | ||
|
344d0e2687 | ||
|
1bc4d6b423 | ||
|
baa9ca7ea3 | ||
|
e4d477fb4c | ||
|
71319eee28 | ||
|
68b31526f8 | ||
|
0b2b7324d9 | ||
|
43512cf27b | ||
|
4218b65969 | ||
|
7244e12b78 | ||
|
a796ef5c66 | ||
|
9474a05aaa | ||
|
41df355a7e | ||
|
4f3ab87914 | ||
|
5d1a08707c | ||
|
4f822df80e | ||
|
951be5cbf6 | ||
|
b6c2341542 | ||
|
a6e6b49a9d | ||
|
3a4bbd571e | ||
|
feccc6150e | ||
|
a37b599a6b | ||
|
9347683fe3 | ||
|
3551c26e28 | ||
|
cfca0107eb | ||
|
81bc975193 | ||
|
cdbb7c4b0d | ||
|
87bc08bef5 |
@@ -35,38 +35,55 @@ const ConsoleWidget = require('./gui/ConsoleWidget.js');
|
||||
|
||||
class AppGui {
|
||||
|
||||
constructor(app, store) {
|
||||
this.app_ = app;
|
||||
this.store_ = store;
|
||||
constructor(app, store, keymap) {
|
||||
try {
|
||||
this.app_ = app;
|
||||
this.store_ = store;
|
||||
|
||||
BaseWidget.setLogger(app.logger());
|
||||
BaseWidget.setLogger(app.logger());
|
||||
|
||||
this.term_ = new TermWrapper(tk.terminal);
|
||||
this.term_ = new TermWrapper(tk.terminal);
|
||||
|
||||
this.renderer_ = null;
|
||||
this.logger_ = new Logger();
|
||||
this.buildUi();
|
||||
// Some keys are directly handled by the tkwidget framework
|
||||
// so they need to be remapped in a different way.
|
||||
this.tkWidgetKeys_ = {
|
||||
'focus_next': 'TAB',
|
||||
'focus_previous': 'SHIFT_TAB',
|
||||
'move_up': 'UP',
|
||||
'move_down': 'DOWN',
|
||||
'page_down': 'PAGE_DOWN',
|
||||
'page_up': 'PAGE_UP',
|
||||
};
|
||||
|
||||
this.renderer_ = new Renderer(this.term(), this.rootWidget_);
|
||||
this.renderer_ = null;
|
||||
this.logger_ = new Logger();
|
||||
this.buildUi();
|
||||
|
||||
this.app_.on('modelAction', async (event) => {
|
||||
await this.handleModelAction(event.action);
|
||||
});
|
||||
this.renderer_ = new Renderer(this.term(), this.rootWidget_);
|
||||
|
||||
this.shortcuts_ = this.setupShortcuts();
|
||||
this.app_.on('modelAction', async (event) => {
|
||||
await this.handleModelAction(event.action);
|
||||
});
|
||||
|
||||
this.inputMode_ = AppGui.INPUT_MODE_NORMAL;
|
||||
this.keymap_ = this.setupKeymap(keymap);
|
||||
|
||||
this.commandCancelCalled_ = false;
|
||||
this.inputMode_ = AppGui.INPUT_MODE_NORMAL;
|
||||
|
||||
this.currentShortcutKeys_ = [];
|
||||
this.lastShortcutKeyTime_ = 0;
|
||||
this.commandCancelCalled_ = false;
|
||||
|
||||
// Recurrent sync is setup only when the GUI is started. In
|
||||
// a regular command it's not necessary since the process
|
||||
// exits right away.
|
||||
reg.setupRecurrentSync();
|
||||
DecryptionWorker.instance().scheduleStart();
|
||||
this.currentShortcutKeys_ = [];
|
||||
this.lastShortcutKeyTime_ = 0;
|
||||
|
||||
// Recurrent sync is setup only when the GUI is started. In
|
||||
// a regular command it's not necessary since the process
|
||||
// exits right away.
|
||||
reg.setupRecurrentSync();
|
||||
DecryptionWorker.instance().scheduleStart();
|
||||
} catch (error) {
|
||||
this.fullScreen(false);
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
store() {
|
||||
@@ -105,6 +122,7 @@ class AppGui {
|
||||
buildUi() {
|
||||
this.rootWidget_ = new ReduxRootWidget(this.store_);
|
||||
this.rootWidget_.name = 'root';
|
||||
this.rootWidget_.autoShortcutsEnabled = false;
|
||||
|
||||
const folderList = new FolderListWidget();
|
||||
folderList.style = {
|
||||
@@ -269,155 +287,31 @@ class AppGui {
|
||||
|
||||
addCommandToConsole(cmd) {
|
||||
if (!cmd) return;
|
||||
const isConfigPassword = cmd.indexOf('config ') >= 0 && cmd.indexOf('password') >= 0;
|
||||
if (isConfigPassword) return;
|
||||
this.stdout(chalk.cyan.bold('> ' + cmd));
|
||||
}
|
||||
|
||||
setupShortcuts() {
|
||||
const shortcuts = {};
|
||||
setupKeymap(keymap) {
|
||||
const output = [];
|
||||
|
||||
shortcuts['TAB'] = {
|
||||
friendlyName: 'Tab',
|
||||
description: () => _('Give focus to next pane'),
|
||||
isDocOnly: true,
|
||||
}
|
||||
for (let i = 0; i < keymap.length; i++) {
|
||||
const item = Object.assign({}, keymap[i]);
|
||||
|
||||
shortcuts['SHIFT_TAB'] = {
|
||||
friendlyName: 'Shift+Tab',
|
||||
description: () => _('Give focus to previous pane'),
|
||||
isDocOnly: true,
|
||||
}
|
||||
if (!item.command) throw new Error('Missing command for keymap item: ' + JSON.stringify(item));
|
||||
|
||||
shortcuts[':'] = {
|
||||
description: () => _('Enter command line mode'),
|
||||
action: async () => {
|
||||
const cmd = await this.widget('statusBar').prompt();
|
||||
if (!cmd) return;
|
||||
this.addCommandToConsole(cmd);
|
||||
await this.processCommand(cmd);
|
||||
},
|
||||
};
|
||||
if (!('type' in item)) item.type = 'exec';
|
||||
|
||||
shortcuts['ESC'] = { // Built into terminal-kit inputField
|
||||
description: () => _('Exit command line mode'),
|
||||
isDocOnly: true,
|
||||
};
|
||||
|
||||
shortcuts['ENTER'] = {
|
||||
description: () => _('Edit the selected note'),
|
||||
action: () => {
|
||||
const w = this.widget('mainWindow').focusedWidget;
|
||||
if (w.name === 'folderList') {
|
||||
this.widget('noteList').focus();
|
||||
} else if (w.name === 'noteList' || w.name === 'noteText') {
|
||||
this.processCommand('edit $n');
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
shortcuts['CTRL_C'] = {
|
||||
description: () => _('Cancel the current command.'),
|
||||
friendlyName: 'Ctrl+C',
|
||||
isDocOnly: true,
|
||||
}
|
||||
|
||||
shortcuts['CTRL_D'] = {
|
||||
description: () => _('Exit the application.'),
|
||||
friendlyName: 'Ctrl+D',
|
||||
isDocOnly: true,
|
||||
}
|
||||
|
||||
shortcuts['DELETE'] = {
|
||||
description: () => _('Delete the currently selected note or notebook.'),
|
||||
action: async () => {
|
||||
if (this.widget('folderList').hasFocus) {
|
||||
const item = this.widget('folderList').selectedJoplinItem;
|
||||
|
||||
if (!item) return;
|
||||
|
||||
if (item.type_ === BaseModel.TYPE_FOLDER) {
|
||||
await this.processCommand('rmbook ' + item.id);
|
||||
} else if (item.type_ === BaseModel.TYPE_TAG) {
|
||||
this.stdout(_('To delete a tag, untag the associated notes.'));
|
||||
} else if (item.type_ === BaseModel.TYPE_SEARCH) {
|
||||
this.store().dispatch({
|
||||
type: 'SEARCH_DELETE',
|
||||
id: item.id,
|
||||
});
|
||||
}
|
||||
} else if (this.widget('noteList').hasFocus) {
|
||||
await this.processCommand('rmnote $n');
|
||||
} else {
|
||||
this.stdout(_('Please select the note or notebook to be deleted first.'));
|
||||
}
|
||||
if (item.command in this.tkWidgetKeys_) {
|
||||
item.type = 'tkwidgets';
|
||||
}
|
||||
};
|
||||
|
||||
shortcuts['BACKSPACE'] = {
|
||||
alias: 'DELETE',
|
||||
};
|
||||
item.canRunAlongOtherCommands = item.type === 'function' && ['toggle_metadata', 'toggle_console'].indexOf(item.command) >= 0;
|
||||
|
||||
shortcuts[' '] = {
|
||||
friendlyName: 'SPACE',
|
||||
description: () => _('Set a to-do as completed / not completed'),
|
||||
action: 'todo toggle $n',
|
||||
output.push(item);
|
||||
}
|
||||
|
||||
shortcuts['tc'] = {
|
||||
description: () => _('[t]oggle [c]onsole between maximized/minimized/hidden/visible.'),
|
||||
action: () => {
|
||||
if (!this.consoleIsShown()) {
|
||||
this.showConsole();
|
||||
this.minimizeConsole();
|
||||
} else {
|
||||
if (this.consoleIsMaximized()) {
|
||||
this.hideConsole();
|
||||
} else {
|
||||
this.maximizeConsole();
|
||||
}
|
||||
}
|
||||
},
|
||||
canRunAlongOtherCommands: true,
|
||||
}
|
||||
|
||||
shortcuts['/'] = {
|
||||
description: () => _('Search'),
|
||||
action: { type: 'prompt', initialText: 'search ""', cursorPosition: -2 },
|
||||
};
|
||||
|
||||
shortcuts['tm'] = {
|
||||
description: () => _('[t]oggle note [m]etadata.'),
|
||||
action: () => {
|
||||
this.toggleNoteMetadata();
|
||||
},
|
||||
canRunAlongOtherCommands: true,
|
||||
}
|
||||
|
||||
shortcuts['mn'] = {
|
||||
description: () => _('[M]ake a new [n]ote'),
|
||||
action: { type: 'prompt', initialText: 'mknote ""', cursorPosition: -2 },
|
||||
}
|
||||
|
||||
shortcuts['mt'] = {
|
||||
description: () => _('[M]ake a new [t]odo'),
|
||||
action: { type: 'prompt', initialText: 'mktodo ""', cursorPosition: -2 },
|
||||
}
|
||||
|
||||
shortcuts['mb'] = {
|
||||
description: () => _('[M]ake a new note[b]ook'),
|
||||
action: { type: 'prompt', initialText: 'mkbook ""', cursorPosition: -2 },
|
||||
}
|
||||
|
||||
shortcuts['yn'] = {
|
||||
description: () => _('Copy ([Y]ank) the [n]ote to a notebook.'),
|
||||
action: { type: 'prompt', initialText: 'cp $n ""', cursorPosition: -2 },
|
||||
}
|
||||
|
||||
shortcuts['dn'] = {
|
||||
description: () => _('Move the note to a notebook.'),
|
||||
action: { type: 'prompt', initialText: 'mv $n ""', cursorPosition: -2 },
|
||||
}
|
||||
|
||||
return shortcuts;
|
||||
return output;
|
||||
}
|
||||
|
||||
toggleConsole() {
|
||||
@@ -492,8 +386,16 @@ class AppGui {
|
||||
return this.logger_;
|
||||
}
|
||||
|
||||
shortcuts() {
|
||||
return this.shortcuts_;
|
||||
keymap() {
|
||||
return this.keymap_;
|
||||
}
|
||||
|
||||
keymapItemByKey(key) {
|
||||
for (let i = 0; i < this.keymap_.length; i++) {
|
||||
const item = this.keymap_[i];
|
||||
if (item.keys.indexOf(key) >= 0) return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
term() {
|
||||
@@ -524,18 +426,78 @@ class AppGui {
|
||||
}
|
||||
}
|
||||
|
||||
async processCommand(cmd) {
|
||||
async processFunctionCommand(cmd) {
|
||||
|
||||
if (cmd === 'activate') {
|
||||
|
||||
const w = this.widget('mainWindow').focusedWidget;
|
||||
if (w.name === 'folderList') {
|
||||
this.widget('noteList').focus();
|
||||
} else if (w.name === 'noteList' || w.name === 'noteText') {
|
||||
this.processPromptCommand('edit $n');
|
||||
}
|
||||
|
||||
} else if (cmd === 'delete') {
|
||||
|
||||
if (this.widget('folderList').hasFocus) {
|
||||
const item = this.widget('folderList').selectedJoplinItem;
|
||||
|
||||
if (!item) return;
|
||||
|
||||
if (item.type_ === BaseModel.TYPE_FOLDER) {
|
||||
await this.processPromptCommand('rmbook ' + item.id);
|
||||
} else if (item.type_ === BaseModel.TYPE_TAG) {
|
||||
this.stdout(_('To delete a tag, untag the associated notes.'));
|
||||
} else if (item.type_ === BaseModel.TYPE_SEARCH) {
|
||||
this.store().dispatch({
|
||||
type: 'SEARCH_DELETE',
|
||||
id: item.id,
|
||||
});
|
||||
}
|
||||
} else if (this.widget('noteList').hasFocus) {
|
||||
await this.processPromptCommand('rmnote $n');
|
||||
} else {
|
||||
this.stdout(_('Please select the note or notebook to be deleted first.'));
|
||||
}
|
||||
|
||||
} else if (cmd === 'toggle_console') {
|
||||
|
||||
if (!this.consoleIsShown()) {
|
||||
this.showConsole();
|
||||
this.minimizeConsole();
|
||||
} else {
|
||||
if (this.consoleIsMaximized()) {
|
||||
this.hideConsole();
|
||||
} else {
|
||||
this.maximizeConsole();
|
||||
}
|
||||
}
|
||||
|
||||
} else if (cmd === 'toggle_metadata') {
|
||||
|
||||
this.toggleNoteMetadata();
|
||||
|
||||
} else if (cmd === 'enter_command_line_mode') {
|
||||
|
||||
const cmd = await this.widget('statusBar').prompt();
|
||||
if (!cmd) return;
|
||||
this.addCommandToConsole(cmd);
|
||||
await this.processPromptCommand(cmd);
|
||||
|
||||
} else {
|
||||
|
||||
throw new Error('Unknown command: ' + cmd);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async processPromptCommand(cmd) {
|
||||
if (!cmd) return;
|
||||
cmd = cmd.trim();
|
||||
if (!cmd.length) return;
|
||||
|
||||
this.logger().info('Got command: ' + cmd);
|
||||
|
||||
if (cmd === 'q' || cmd === 'wq' || cmd === 'qa') { // Vim bonus
|
||||
await this.app().exit();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let note = this.widget('noteList').currentItem;
|
||||
let folder = this.widget('folderList').currentItem;
|
||||
@@ -786,35 +748,34 @@ class AppGui {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
const shortcutKey = this.currentShortcutKeys_.join('');
|
||||
let cmd = shortcutKey in this.shortcuts_ ? this.shortcuts_[shortcutKey] : null;
|
||||
let keymapItem = this.keymapItemByKey(shortcutKey);
|
||||
|
||||
// If this command is an alias to another command, resolve to the actual command
|
||||
if (cmd && cmd.alias) cmd = this.shortcuts_[cmd.alias];
|
||||
|
||||
let processShortcutKeys = !this.app().currentCommand() && cmd;
|
||||
if (cmd && cmd.canRunAlongOtherCommands) processShortcutKeys = true;
|
||||
let processShortcutKeys = !this.app().currentCommand() && keymapItem;
|
||||
if (keymapItem && keymapItem.canRunAlongOtherCommands) processShortcutKeys = true;
|
||||
if (statusBar.promptActive) processShortcutKeys = false;
|
||||
if (cmd && cmd.isDocOnly) processShortcutKeys = false;
|
||||
|
||||
if (processShortcutKeys) {
|
||||
this.logger().info('Shortcut:', shortcutKey, cmd.description());
|
||||
this.logger().info('Shortcut:', shortcutKey, keymapItem);
|
||||
|
||||
this.currentShortcutKeys_ = [];
|
||||
if (typeof cmd.action === 'function') {
|
||||
await cmd.action();
|
||||
} else if (typeof cmd.action === 'object') {
|
||||
if (cmd.action.type === 'prompt') {
|
||||
let promptOptions = {};
|
||||
if ('cursorPosition' in cmd.action) promptOptions.cursorPosition = cmd.action.cursorPosition;
|
||||
const commandString = await statusBar.prompt(cmd.action.initialText ? cmd.action.initialText : '', null, promptOptions);
|
||||
this.addCommandToConsole(commandString);
|
||||
await this.processCommand(commandString);
|
||||
} else {
|
||||
throw new Error('Unknown command: ' + JSON.stringify(cmd.action));
|
||||
}
|
||||
} else { // String
|
||||
this.stdout(cmd.action);
|
||||
await this.processCommand(cmd.action);
|
||||
|
||||
if (keymapItem.type === 'function') {
|
||||
this.processFunctionCommand(keymapItem.command);
|
||||
} else if (keymapItem.type === 'prompt') {
|
||||
let promptOptions = {};
|
||||
if ('cursorPosition' in keymapItem) promptOptions.cursorPosition = keymapItem.cursorPosition;
|
||||
const commandString = await statusBar.prompt(keymapItem.command ? keymapItem.command : '', null, promptOptions);
|
||||
this.addCommandToConsole(commandString);
|
||||
await this.processPromptCommand(commandString);
|
||||
} else if (keymapItem.type === 'exec') {
|
||||
this.stdout(keymapItem.command);
|
||||
await this.processPromptCommand(keymapItem.command);
|
||||
} else if (keymapItem.type === 'tkwidgets') {
|
||||
this.widget('root').handleKey(this.tkWidgetKeys_[keymapItem.command]);
|
||||
} else {
|
||||
throw new Error('Unknown command type: ' + JSON.stringify(keymapItem));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -283,7 +283,7 @@ class Application extends BaseApplication {
|
||||
exit: () => {},
|
||||
showModalOverlay: (text) => {},
|
||||
hideModalOverlay: () => {},
|
||||
stdoutMaxWidth: () => { return 78; },
|
||||
stdoutMaxWidth: () => { return 100; },
|
||||
forceRender: () => {},
|
||||
termSaveState: () => {},
|
||||
termRestoreState: (state) => {},
|
||||
@@ -312,6 +312,63 @@ class Application extends BaseApplication {
|
||||
return this.activeCommand_;
|
||||
}
|
||||
|
||||
async loadKeymaps() {
|
||||
const defaultKeyMap = [
|
||||
{ "keys": [":"], "type": "function", "command": "enter_command_line_mode" },
|
||||
{ "keys": ["TAB"], "type": "function", "command": "focus_next" },
|
||||
{ "keys": ["SHIFT_TAB"], "type": "function", "command": "focus_previous" },
|
||||
{ "keys": ["UP"], "type": "function", "command": "move_up" },
|
||||
{ "keys": ["DOWN"], "type": "function", "command": "move_down" },
|
||||
{ "keys": ["PAGE_UP"], "type": "function", "command": "page_up" },
|
||||
{ "keys": ["PAGE_DOWN"], "type": "function", "command": "page_down" },
|
||||
{ "keys": ["ENTER"], "type": "function", "command": "activate" },
|
||||
{ "keys": ["DELETE", "BACKSPACE"], "type": "function", "command": "delete" },
|
||||
{ "keys": [" "], "command": "todo toggle $n" },
|
||||
{ "keys": ["tc"], "type": "function", "command": "toggle_console" },
|
||||
{ "keys": ["tm"], "type": "function", "command": "toggle_metadata" },
|
||||
{ "keys": ["/"], "type": "prompt", "command": "search \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["mn"], "type": "prompt", "command": "mknote \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["mt"], "type": "prompt", "command": "mktodo \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["mb"], "type": "prompt", "command": "mkbook \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["yn"], "type": "prompt", "command": "cp $n \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["dn"], "type": "prompt", "command": "mv $n \"\"", "cursorPosition": -2 }
|
||||
];
|
||||
|
||||
// Filter the keymap item by command so that items in keymap.json can override
|
||||
// the default ones.
|
||||
const itemsByCommand = {};
|
||||
|
||||
for (let i = 0; i < defaultKeyMap.length; i++) {
|
||||
itemsByCommand[defaultKeyMap[i].command] = defaultKeyMap[i]
|
||||
}
|
||||
|
||||
const filePath = Setting.value('profileDir') + '/keymap.json';
|
||||
if (await fs.pathExists(filePath)) {
|
||||
try {
|
||||
let configString = await fs.readFile(filePath, 'utf-8');
|
||||
configString = configString.replace(/^\s*\/\/.*/, ''); // Strip off comments
|
||||
const keymap = JSON.parse(configString);
|
||||
for (let keymapIndex = 0; keymapIndex < keymap.length; keymapIndex++) {
|
||||
const item = keymap[keymapIndex];
|
||||
itemsByCommand[item.command] = item;
|
||||
}
|
||||
} catch (error) {
|
||||
let msg = error.message ? error.message : '';
|
||||
msg = 'Could not load keymap ' + filePath + '\n' + msg;
|
||||
error.message = msg;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
const output = [];
|
||||
for (let n in itemsByCommand) {
|
||||
if (!itemsByCommand.hasOwnProperty(n)) continue;
|
||||
output.push(itemsByCommand[n]);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
async start(argv) {
|
||||
argv = await super.start(argv);
|
||||
|
||||
@@ -330,16 +387,19 @@ class Application extends BaseApplication {
|
||||
await this.execCommand(argv);
|
||||
} catch (error) {
|
||||
if (this.showStackTraces_) {
|
||||
console.info(error);
|
||||
console.error(error);
|
||||
} else {
|
||||
console.info(error.message);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
} else { // Otherwise open the GUI
|
||||
this.initRedux();
|
||||
|
||||
const keymap = await this.loadKeymaps();
|
||||
|
||||
const AppGui = require('./app-gui.js');
|
||||
this.gui_ = new AppGui(this, this.store());
|
||||
this.gui_ = new AppGui(this, this.store(), keymap);
|
||||
this.gui_.setLogger(this.logger_);
|
||||
await this.gui_.start();
|
||||
|
||||
|
@@ -32,10 +32,6 @@ class BaseCommand {
|
||||
return this.compatibleUis().indexOf(ui) >= 0;
|
||||
}
|
||||
|
||||
aliases() {
|
||||
return [];
|
||||
}
|
||||
|
||||
options() {
|
||||
return [];
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { Exporter } = require('lib/services/exporter.js');
|
||||
const InteropService = require('lib/services/InteropService.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
@@ -10,15 +10,21 @@ const fs = require('fs-extra');
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'export <directory>';
|
||||
return 'export <path>';
|
||||
}
|
||||
|
||||
description() {
|
||||
return _('Exports Joplin data to the given directory. By default, it will export the complete database including notebooks, notes, tags and resources.');
|
||||
return _('Exports Joplin data to the given path. By default, it will export the complete database including notebooks, notes, tags and resources.');
|
||||
}
|
||||
|
||||
options() {
|
||||
const service = new InteropService();
|
||||
const formats = service.modules()
|
||||
.filter(m => m.type === 'exporter')
|
||||
.map(m => m.format + (m.description ? ' (' + m.description + ')' : ''));
|
||||
|
||||
return [
|
||||
['--format <format>', _('Destination format: %s', formats.join(', '))],
|
||||
['--note <note>', _('Exports only the given note.')],
|
||||
['--notebook <notebook>', _('Exports only the given notebook.')],
|
||||
];
|
||||
@@ -26,13 +32,9 @@ class Command extends BaseCommand {
|
||||
|
||||
async action(args) {
|
||||
let exportOptions = {};
|
||||
exportOptions.destDir = args.directory;
|
||||
exportOptions.writeFile = (filePath, data) => {
|
||||
return fs.writeFile(filePath, data);
|
||||
};
|
||||
exportOptions.copyFile = (source, dest) => {
|
||||
return fs.copy(source, dest, { overwrite: true });
|
||||
};
|
||||
exportOptions.path = args.path;
|
||||
|
||||
exportOptions.format = args.options.format ? args.options.format : 'jex';
|
||||
|
||||
if (args.options.note) {
|
||||
|
||||
@@ -48,10 +50,10 @@ class Command extends BaseCommand {
|
||||
|
||||
}
|
||||
|
||||
const exporter = new Exporter();
|
||||
const result = await exporter.export(exportOptions);
|
||||
const service = new InteropService();
|
||||
const result = await service.export(exportOptions);
|
||||
|
||||
reg.logger().info('Export result: ', result);
|
||||
result.warnings.map((w) => this.stdout(w));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -36,21 +36,22 @@ class Command extends BaseCommand {
|
||||
async action(args) {
|
||||
const stdoutWidth = app().commandStdoutMaxWidth();
|
||||
|
||||
if (args.command === 'shortcuts') {
|
||||
if (args.command === 'shortcuts' || args.command === 'keymap') {
|
||||
this.stdout(_('For information on how to customise the shortcuts please visit %s', 'http://joplin.cozic.net/terminal/#shortcuts'));
|
||||
this.stdout('');
|
||||
|
||||
if (app().gui().isDummy()) {
|
||||
throw new Error(_('Shortcuts are not available in CLI mode.'));
|
||||
}
|
||||
|
||||
const shortcuts = app().gui().shortcuts();
|
||||
const keymap = app().gui().keymap();
|
||||
|
||||
let rows = [];
|
||||
|
||||
for (let n in shortcuts) {
|
||||
if (!shortcuts.hasOwnProperty(n)) continue;
|
||||
const shortcut = shortcuts[n];
|
||||
if (!shortcut.description) continue;
|
||||
n = shortcut.friendlyName ? shortcut.friendlyName : n;
|
||||
rows.push([n, shortcut.description()]);
|
||||
for (let i = 0; i < keymap.length; i++) {
|
||||
const item = keymap[i];
|
||||
const keys = item.keys.map((k) => k === ' ' ? '(SPACE)' : k);
|
||||
rows.push([keys.join(', '), item.command]);
|
||||
}
|
||||
|
||||
cliUtils.printArray(this.stdout.bind(this), rows);
|
||||
@@ -78,7 +79,7 @@ class Command extends BaseCommand {
|
||||
this.stdout(_('To maximise/minimise the console, press "TC".'));
|
||||
this.stdout(_('To enter command line mode, press ":"'));
|
||||
this.stdout(_('To exit command line mode, press ESCAPE'));
|
||||
this.stdout(_('For the complete list of available keyboard shortcuts, type `help shortcuts`'));
|
||||
this.stdout(_('For the list of keyboard shortcuts and config options, type `help keymap`'));
|
||||
}
|
||||
|
||||
app().gui().showConsole();
|
||||
|
@@ -1,68 +0,0 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const { importEnex } = require('lib/import-enex');
|
||||
const { filename, basename } = require('lib/path-utils.js');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'import-enex <file> [notebook]';
|
||||
}
|
||||
|
||||
description() {
|
||||
return _('Imports an Evernote notebook file (.enex file).');
|
||||
}
|
||||
|
||||
options() {
|
||||
return [
|
||||
['-f, --force', _('Do not ask for confirmation.')],
|
||||
];
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let filePath = args.file;
|
||||
let folder = null;
|
||||
let folderTitle = args['notebook'];
|
||||
let force = args.options.force === true;
|
||||
|
||||
if (!folderTitle) folderTitle = filename(filePath);
|
||||
folder = await Folder.loadByField('title', folderTitle);
|
||||
const msg = folder ? _('File "%s" will be imported into existing notebook "%s". Continue?', basename(filePath), folderTitle) : _('New notebook "%s" will be created and file "%s" will be imported into it. Continue?', folderTitle, basename(filePath));
|
||||
const ok = force ? true : await this.prompt(msg);
|
||||
if (!ok) return;
|
||||
|
||||
let lastProgress = '';
|
||||
|
||||
let options = {
|
||||
onProgress: (progressState) => {
|
||||
let line = [];
|
||||
line.push(_('Found: %d.', progressState.loaded));
|
||||
line.push(_('Created: %d.', progressState.created));
|
||||
if (progressState.updated) line.push(_('Updated: %d.', progressState.updated));
|
||||
if (progressState.skipped) line.push(_('Skipped: %d.', progressState.skipped));
|
||||
if (progressState.resourcesCreated) line.push(_('Resources: %d.', progressState.resourcesCreated));
|
||||
if (progressState.notesTagged) line.push(_('Tagged: %d.', progressState.notesTagged));
|
||||
lastProgress = line.join(' ');
|
||||
cliUtils.redraw(lastProgress);
|
||||
},
|
||||
onError: (error) => {
|
||||
let s = error.trace ? error.trace : error.toString();
|
||||
this.stdout(s);
|
||||
},
|
||||
}
|
||||
|
||||
folder = !folder ? await Folder.save({ title: folderTitle }) : folder;
|
||||
|
||||
app().gui().showConsole();
|
||||
this.stdout(_('Importing notes...'));
|
||||
await importEnex(folder.id, filePath, options);
|
||||
cliUtils.redrawDone();
|
||||
this.stdout(_('The notes have been imported: %s', lastProgress));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Command;
|
75
CliClient/app/command-import.js
Normal file
75
CliClient/app/command-import.js
Normal file
@@ -0,0 +1,75 @@
|
||||
const { BaseCommand } = require('./base-command.js');
|
||||
const InteropService = require('lib/services/InteropService.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const Note = require('lib/models/Note.js');
|
||||
const { filename, basename, fileExtension } = require('lib/path-utils.js');
|
||||
const { importEnex } = require('lib/import-enex');
|
||||
const { cliUtils } = require('./cli-utils.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { app } = require('./app.js');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
|
||||
usage() {
|
||||
return 'import <path> [notebook]';
|
||||
}
|
||||
|
||||
description() {
|
||||
return _('Imports data into Joplin.');
|
||||
}
|
||||
|
||||
options() {
|
||||
const service = new InteropService();
|
||||
const formats = service.modules().filter(m => m.type === 'importer').map(m => m.format);
|
||||
|
||||
return [
|
||||
['--format <format>', _('Source format: %s', (['auto'].concat(formats)).join(', '))],
|
||||
['-f, --force', _('Do not ask for confirmation.')],
|
||||
];
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let folder = await app().loadItem(BaseModel.TYPE_FOLDER, args.notebook);
|
||||
|
||||
if (args.notebook && !folder) throw new Error(_('Cannot find "%s".', args.notebook));
|
||||
|
||||
const importOptions = {};
|
||||
importOptions.path = args.path;
|
||||
importOptions.format = args.options.format ? args.options.format : 'auto';
|
||||
importOptions.destinationFolderId = folder ? folder.id : null;
|
||||
|
||||
let lastProgress = '';
|
||||
|
||||
// onProgress/onError supported by Enex import only
|
||||
|
||||
importOptions.onProgress = (progressState) => {
|
||||
let line = [];
|
||||
line.push(_('Found: %d.', progressState.loaded));
|
||||
line.push(_('Created: %d.', progressState.created));
|
||||
if (progressState.updated) line.push(_('Updated: %d.', progressState.updated));
|
||||
if (progressState.skipped) line.push(_('Skipped: %d.', progressState.skipped));
|
||||
if (progressState.resourcesCreated) line.push(_('Resources: %d.', progressState.resourcesCreated));
|
||||
if (progressState.notesTagged) line.push(_('Tagged: %d.', progressState.notesTagged));
|
||||
lastProgress = line.join(' ');
|
||||
cliUtils.redraw(lastProgress);
|
||||
};
|
||||
|
||||
importOptions.onError = (error) => {
|
||||
let s = error.trace ? error.trace : error.toString();
|
||||
this.stdout(s);
|
||||
};
|
||||
|
||||
app().gui().showConsole();
|
||||
this.stdout(_('Importing notes...'));
|
||||
const service = new InteropService();
|
||||
const result = await service.import(importOptions);
|
||||
result.warnings.map((w) => this.stdout(w));
|
||||
cliUtils.redrawDone();
|
||||
if (lastProgress) this.stdout(_('The notes have been imported: %s', lastProgress));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = Command;
|
@@ -14,10 +14,6 @@ class Command extends BaseCommand {
|
||||
return _('Creates a new notebook.');
|
||||
}
|
||||
|
||||
aliases() {
|
||||
return ['mkdir'];
|
||||
}
|
||||
|
||||
async action(args) {
|
||||
let folder = await Folder.save({ title: args['new-notebook'] }, { userSideValidation: true });
|
||||
app().switchCurrentFolder(folder);
|
||||
|
@@ -10,7 +10,6 @@ const { cliUtils } = require('./cli-utils.js');
|
||||
const md5 = require('md5');
|
||||
const locker = require('proper-lockfile');
|
||||
const fs = require('fs-extra');
|
||||
const osTmpdir = require('os-tmpdir');
|
||||
const SyncTargetRegistry = require('lib/SyncTargetRegistry');
|
||||
|
||||
class Command extends BaseCommand {
|
||||
@@ -101,7 +100,7 @@ class Command extends BaseCommand {
|
||||
this.releaseLockFn_ = null;
|
||||
|
||||
// Lock is unique per profile/database
|
||||
const lockFilePath = osTmpdir() + '/synclock_' + md5(escape(Setting.value('profileDir'))); // https://github.com/pvorb/node-md5/issues/41
|
||||
const lockFilePath = require('os').tmpdir() + '/synclock_' + md5(escape(Setting.value('profileDir'))); // https://github.com/pvorb/node-md5/issues/41
|
||||
if (!await fs.pathExists(lockFilePath)) await fs.writeFile(lockFilePath, 'synclock');
|
||||
|
||||
try {
|
||||
|
@@ -133,7 +133,8 @@ class StatusBarWidget extends BaseWidget {
|
||||
resolveResult = input ? input.trim() : input;
|
||||
// Add the command to history but only if it's longer than one character.
|
||||
// Below that it's usually an answer like "y"/"n", etc.
|
||||
if (!isSecurePrompt && input && input.length > 1) this.history_.push(input);
|
||||
const isConfigPassword = input.indexOf('config ') >= 0 && input.indexOf('password') >= 0;
|
||||
if (!isSecurePrompt && input && input.length > 1 && !isConfigPassword) this.history_.push(input);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -53,9 +53,8 @@ function renderCommandHelp(cmd, width = null) {
|
||||
desc.push(label);
|
||||
}
|
||||
|
||||
if (md.description) {
|
||||
desc.push(md.description());
|
||||
}
|
||||
const description = Setting.keyDescription(md.key, 'cli');
|
||||
if (description) desc.push(description);
|
||||
|
||||
desc.push(_('Type: %s.', md.isEnum ? _('Enum') : Setting.typeToString(md.type)));
|
||||
if (md.isEnum) desc.push(_('Possible values: %s.', Setting.enumOptionsDoc(md.key, '%s (%s)')));
|
||||
|
@@ -71,37 +71,10 @@ process.stdout.on('error', function( err ) {
|
||||
|
||||
|
||||
// async function main() {
|
||||
// const WebDavApi = require('lib/WebDavApi');
|
||||
// const api = new WebDavApi('http://nextcloud.local/remote.php/dav/files/admin/Joplin', { username: 'admin', password: '1234567' });
|
||||
// const { FileApiDriverWebDav } = new require('lib/file-api-driver-webdav');
|
||||
// const driver = new FileApiDriverWebDav(api);
|
||||
|
||||
// const stat = await driver.stat('');
|
||||
// console.info(stat);
|
||||
|
||||
// // const stat = await driver.stat('testing.txt');
|
||||
// // console.info(stat);
|
||||
|
||||
|
||||
// // const content = await driver.get('testing.txta');
|
||||
// // console.info(content);
|
||||
|
||||
// // const content = await driver.get('testing.txta', { target: 'file', path: '/var/www/joplin/CliClient/testing-file.txt' });
|
||||
// // console.info(content);
|
||||
|
||||
// // const content = await driver.mkdir('newdir5');
|
||||
// // console.info(content);
|
||||
|
||||
// //await driver.put('myfile4.md', 'this is my content');
|
||||
|
||||
// // await driver.put('testimg.jpg', null, { source: 'file', path: '/mnt/d/test.jpg' });
|
||||
|
||||
// // await driver.delete('myfile4.md');
|
||||
|
||||
// // const deltaResult = await driver.delta('', {
|
||||
// // allItemIdsHandler: () => { return []; }
|
||||
// // });
|
||||
// // console.info(deltaResult);
|
||||
// const InteropService = require('lib/services/InteropService');
|
||||
// const service = new InteropService();
|
||||
// console.info(service.moduleByFormat('importer', 'enex'));
|
||||
// //await service.modules();
|
||||
// }
|
||||
|
||||
// main().catch((error) => { console.error(error); });
|
||||
|
@@ -16,30 +16,6 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Das nächste Fenster fokussieren"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Das vorherige Fenster fokussieren"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Zum Terminal-Modus wechseln"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Den Terminal-Modus verlassen"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Die ausgewählte Notiz bearbeiten"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Den momentanen Befehl abbrechen."
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Das Programm verlassen."
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Die/das momentan ausgewählte Notiz(-buch) löschen."
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr ""
|
||||
"Hebe die Markierungen zugehöriger Notizen auf, um eine Markierung zu löschen."
|
||||
@@ -49,35 +25,6 @@ msgstr ""
|
||||
"Wähle bitte zuerst eine Notiz oder ein Notizbuch aus, das gelöscht werden "
|
||||
"soll."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Ein To-Do als abgeschlossen / nicht abgeschlossen markieren"
|
||||
|
||||
#, fuzzy
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr ""
|
||||
"Schal[t]e das Terminal zwischen maximiert/minimiert/versteckt/sichtbar um."
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Suchen"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "Notiz-[M]etadata einschal[t]en."
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "Eine neue [N]otiz [m]achen"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "Ein neues [T]o-Do [m]achen"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "Ein neues Notiz[b]uch [m]achen"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "Die Notiz zu einem Notizbuch kopieren."
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Die Notiz zu einem Notizbuch verschieben."
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Drücke Strg+D oder tippe \"exit\", um das Programm zu verlassen"
|
||||
|
||||
@@ -247,14 +194,19 @@ msgstr "Die Notiz wurde gespeichert."
|
||||
msgid "Exits the application."
|
||||
msgstr "Schließt das Programm."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Exportiert Joplins Dateien zu dem angegebenen Pfad. Standardmäßig wird die "
|
||||
"komplette Datenbank inklusive Notizbüchern, Notizen, Markierungen und "
|
||||
"Anhängen exportiert."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Datumsformat"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Exportiert nur die angegebene Notiz."
|
||||
|
||||
@@ -267,6 +219,10 @@ msgstr "Zeigt die Standort-URL der Notiz an."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Zeigt die Nutzungsstatistik an."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "Tastenkürzel sind im CLI Modus nicht verfügbar."
|
||||
|
||||
@@ -311,32 +267,23 @@ msgstr "Um den Kommandozeilen Modus aufzurufen, drücke \":\""
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Um den Kommandozeilen Modus zu beenden, drücke ESCAPE"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
"Um die komplette Liste von verfügbaren Tastenkürzeln anzuzeigen, tippe `help "
|
||||
"shortcuts` ein"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Importiert eine Evernote Notizbuch-Datei (.enex Datei)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Ungültiger Befehl: %s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Nicht nach einer Bestätigung fragen."
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
"Datei \"%s\" wird in das existierende Notizbuch \"%s\" importiert. "
|
||||
"Fortfahren?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"Neues Notizbuch \"%s\" wird erstellt und die Datei \"%s\" wird hinein "
|
||||
"importiert. Fortfahren?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Gefunden: %d."
|
||||
@@ -627,9 +574,20 @@ msgstr ""
|
||||
"Wenn du das Passwort bereits eingegeben hast, werden die verschlüsselten "
|
||||
"Objekte im Hintergrund entschlüsselt und stehen in Kürze zur Verfügung."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "Datei"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Neue Notiz"
|
||||
|
||||
@@ -639,11 +597,16 @@ msgstr "Neues To-Do"
|
||||
msgid "New notebook"
|
||||
msgstr "Neues Notizbuch"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Evernote Notizen importieren"
|
||||
msgid "Import"
|
||||
msgstr "Importieren"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Evernote Export Dateien"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "Importieren"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Verlassen"
|
||||
@@ -663,6 +626,12 @@ msgstr "Einfügen"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Alle Notizen durchsuchen"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Werkzeuge"
|
||||
|
||||
@@ -704,9 +673,6 @@ msgstr "OK"
|
||||
msgid "Cancel"
|
||||
msgstr "Abbrechen"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -846,6 +812,9 @@ msgstr "Benne Notizbuch um:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Alarm erstellen:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Suchen"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
@@ -904,6 +873,12 @@ msgstr "Markierungen"
|
||||
msgid "Set alarm"
|
||||
msgstr "Alarm erstellen"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "Neues To-Do"
|
||||
@@ -925,9 +900,6 @@ msgstr "Leeren"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "OneDrive Login"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Importieren"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Optionen"
|
||||
|
||||
@@ -970,7 +942,8 @@ msgstr "Unbekanntes Argument: %s"
|
||||
msgid "File system"
|
||||
msgstr "Dateisystem"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
#, fuzzy
|
||||
msgid "Nextcloud"
|
||||
msgstr "Nextcloud (Beta)"
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -979,8 +952,9 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dev (Nur für Tests)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgstr ""
|
||||
#, fuzzy
|
||||
msgid "WebDAV"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unknown log level: %s"
|
||||
@@ -1120,9 +1094,17 @@ msgstr "Hell"
|
||||
msgid "Dark"
|
||||
msgstr "Dunkel"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Zeige unvollständige To-Dos oben in der Liste"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Dreht die Sortierreihenfolge um."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Momentanen Standort zusammen mit Notizen speichern"
|
||||
|
||||
@@ -1144,9 +1126,18 @@ msgstr "Erstellt eine neue Notiz."
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
#, fuzzy
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Einstellen des Anwendungszooms"
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
msgstr "Die Applikation automatisch aktualisieren"
|
||||
|
||||
@@ -1189,22 +1180,22 @@ msgstr ""
|
||||
"Der Pfad, mit dem synchronisiert werden soll, wenn die Dateisystem-"
|
||||
"Synchronisation aktiviert ist. Siehe `sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgstr "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgstr "Nexcloud Benutzername"
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud Benutzername"
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgstr "Nexcloud Passwort"
|
||||
msgid "Nextcloud password"
|
||||
msgstr "Nextcloud Passwort"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV URL"
|
||||
msgstr "Nexcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV username"
|
||||
msgstr "Nexcloud Benutzername"
|
||||
msgstr "Nextcloud Benutzername"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV password"
|
||||
@@ -1214,6 +1205,42 @@ msgstr "Setze ein Passwort"
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Ungültiger Optionswert: \"%s\". Mögliche Werte sind: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Evernote Export Dateien"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Evernote Export Dateien"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr ""
|
||||
"Bitte wähle aus, wohin der Synchronisations Status exportiert werden soll"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Objekte können nicht synchronisiert werden"
|
||||
|
||||
@@ -1388,6 +1415,75 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Willkommen"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Importiert eine Evernote Notizbuch-Datei (.enex Datei)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Datei \"%s\" wird in das existierende Notizbuch \"%s\" importiert. "
|
||||
#~ "Fortfahren?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Neues Notizbuch \"%s\" wird erstellt und die Datei \"%s\" wird hinein "
|
||||
#~ "importiert. Fortfahren?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Evernote Notizen importieren"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Das nächste Fenster fokussieren"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Das vorherige Fenster fokussieren"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Zum Terminal-Modus wechseln"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Den Terminal-Modus verlassen"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Die ausgewählte Notiz bearbeiten"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Den momentanen Befehl abbrechen."
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Das Programm verlassen."
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "Die/das momentan ausgewählte Notiz(-buch) löschen."
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Ein To-Do als abgeschlossen / nicht abgeschlossen markieren"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr ""
|
||||
#~ "Schal[t]e das Terminal zwischen maximiert/minimiert/versteckt/sichtbar um."
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "Notiz-[M]etadata einschal[t]en."
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "Eine neue [N]otiz [m]achen"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "Ein neues [T]o-Do [m]achen"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "Ein neues Notiz[b]uch [m]achen"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "Die Notiz zu einem Notizbuch kopieren."
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Die Notiz zu einem Notizbuch verschieben."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The target to synchonise to. If synchronising with the file system, set "
|
||||
#~ "`sync.2.path` to specify the target directory."
|
||||
|
@@ -15,63 +15,12 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr ""
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr ""
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr ""
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr ""
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr ""
|
||||
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr ""
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr ""
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr ""
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr ""
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr ""
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr ""
|
||||
|
||||
@@ -225,10 +174,14 @@ msgid "Exits the application."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr ""
|
||||
|
||||
@@ -241,6 +194,10 @@ msgstr ""
|
||||
msgid "Displays usage information."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr ""
|
||||
|
||||
@@ -276,25 +233,19 @@ msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr ""
|
||||
@@ -535,9 +486,20 @@ msgid ""
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr ""
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr ""
|
||||
|
||||
@@ -547,10 +509,14 @@ msgstr ""
|
||||
msgid "New notebook"
|
||||
msgstr ""
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgid "Export"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
@@ -571,6 +537,12 @@ msgstr ""
|
||||
msgid "Search in all the notes"
|
||||
msgstr ""
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr ""
|
||||
|
||||
@@ -612,9 +584,6 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -737,6 +706,9 @@ msgstr ""
|
||||
msgid "Set alarm:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
msgid "Layout"
|
||||
msgstr ""
|
||||
|
||||
@@ -790,6 +762,12 @@ msgstr ""
|
||||
msgid "Set alarm"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
msgid "to-do"
|
||||
msgstr ""
|
||||
|
||||
@@ -809,9 +787,6 @@ msgstr ""
|
||||
msgid "OneDrive Login"
|
||||
msgstr ""
|
||||
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
@@ -853,7 +828,7 @@ msgstr ""
|
||||
msgid "File system"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -862,7 +837,7 @@ msgstr ""
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -991,7 +966,13 @@ msgstr ""
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr ""
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reverse sort order"
|
||||
msgstr ""
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
@@ -1012,7 +993,15 @@ msgstr ""
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1052,13 +1041,13 @@ msgid ""
|
||||
"See `sync.target`."
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1074,6 +1063,38 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr ""
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Evernote Export File"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr ""
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr ""
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
# Copyright (C) YEAR Laurent Cozic
|
||||
# This file is distributed under the same license as the Joplin-CLI package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Joplin-CLI 1.0.0\n"
|
||||
@@ -16,63 +16,12 @@ msgstr ""
|
||||
"X-Generator: Poedit 1.8.7.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Eraman fokua hurrengo panelera"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Eraman fokua aurreko panelera"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Sartu komando-lerro moduan "
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Irten komando-lerro modutik"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Editatu aukeratutako oharra"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Utzi uneko komandoa"
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Irten aplikaziotik"
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Ezabatu aukeratutako oharra edo koadernoa"
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "Etiketa ezabatzeko, kendu etiketa duten oharrei"
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "Aurretik aukeratu ezabatzeko oharra edo koadernoa, mesedez."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Zeregina eginda / ez-eginda markatu"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr "[t]xandakatu [k]ontsola maximizatu/minimizatu/ezkutatu/ikusgai artean"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Bilatu"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "[t]xandakatu oharra eta [m]etadatuak"
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "[S]ortu [o]har berria"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "[S]ortu [z]ereginen zerrenda"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "[S]ortu koa[d]erno berria"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "Kopiatu ([E]raman) [o]harra koadernora"
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Eraman oharra koadernora"
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Sakatu Ktrl+D edo idatzi \"exit\" aplikaziotik irteteko"
|
||||
|
||||
@@ -240,10 +189,14 @@ msgstr "Irten aplikaziotik."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr "Esportatu Joplineko datuak esandako karpetara"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Data-formatua"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Esportatu emandako oharra soilik."
|
||||
|
||||
@@ -256,6 +209,10 @@ msgstr "Erakutsi URL geolokalizazioa oharrean."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Erakutsi erabilera datuak."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "CLI moduan ez dago lasterbiderik erabilgarri."
|
||||
|
||||
@@ -298,30 +255,21 @@ msgstr "Komando lerroa sartzeko, idatzi \":\""
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Komando lerrotik irteteko, sakatu ESC, mesedez"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr "Laster bideen zerrenda osoa ikusteko, idatzi `help shortcuts`"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Inportatu Evernote koaderno fitxategia (.enex fitxategia)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Ez dago komandorik: %s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Ez galdetu berresteko."
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
" \"%s\" izeneko fitxategia \"%s\" izeneko koadernoan inportatzekotan zaude. "
|
||||
"Jarraitu nahi duzu?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
" \"%s\" izeneko koaderno berria sortzekotan zaude eta bertan \"%s\" "
|
||||
"fitxategia bertara inportatzekotan zaude. Jarraitu nahi duzu?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Aurkitua: %d"
|
||||
@@ -608,9 +556,20 @@ msgstr ""
|
||||
"Dagoeneko pasahitza ordezkatua baduzu, itemak deszifratzen ari izango dira "
|
||||
"atzeko planoan eta laster izango dira eskuragarri."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "Fitxategia"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Ohar berria"
|
||||
|
||||
@@ -620,11 +579,16 @@ msgstr "Zeregin berria"
|
||||
msgid "New notebook"
|
||||
msgstr "Koaderno berria"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Inportatu Evernoteko oharrak"
|
||||
msgid "Import"
|
||||
msgstr "Inportatu"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Evernotetik esportatutako fitxategiak"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "Inportatu"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Irten"
|
||||
@@ -644,6 +608,12 @@ msgstr "Itsatsi"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Bilatu ohar guztietan"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Tresnak"
|
||||
|
||||
@@ -685,9 +655,6 @@ msgstr "OK"
|
||||
msgid "Cancel"
|
||||
msgstr "Utzi"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -826,6 +793,9 @@ msgstr "Berrizendatu koadernoa:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Ezarri alarma:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Bilatu"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Diseinua"
|
||||
|
||||
@@ -880,6 +850,12 @@ msgstr "Etiketak"
|
||||
msgid "Set alarm"
|
||||
msgstr "Ezarri alarma"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "Zeregin berria"
|
||||
@@ -902,9 +878,6 @@ msgstr "Garbitu"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "Logeatu OneDriven"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Inportatu"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Aukerak"
|
||||
|
||||
@@ -947,7 +920,8 @@ msgstr "Marka ezezaguna: %s"
|
||||
msgid "File system"
|
||||
msgstr "Fitxategi sistema"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
#, fuzzy
|
||||
msgid "Nextcloud"
|
||||
msgstr "NextCloud (Beta)"
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -956,8 +930,9 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dev (aprobetarako soilik)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgstr ""
|
||||
#, fuzzy
|
||||
msgid "WebDAV"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unknown log level: %s"
|
||||
@@ -1095,9 +1070,17 @@ msgstr "Argia"
|
||||
msgid "Dark"
|
||||
msgstr "Iluna"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Bete gabeko zereginak erakutsi zerrendaren goiko partean"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Alderantziz antolatzen du."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Gore geokokapena oharrekin"
|
||||
|
||||
@@ -1118,9 +1101,18 @@ msgstr "Ohar berria sortzen du."
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
#, fuzzy
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Ezarri aplikazioaren zoomaren ehunekoa"
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
msgstr "Automatikoki eguneratu aplikazioa"
|
||||
|
||||
@@ -1162,22 +1154,22 @@ msgid ""
|
||||
msgstr ""
|
||||
"Sinkronizazio sistema gaituta dagoenerako bide-izena. Ikus `sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgstr "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgstr "Nexcloud erabiltzaile-izena"
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud erabiltzaile-izena"
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgstr "Nexcloud pasahitza"
|
||||
msgid "Nextcloud password"
|
||||
msgstr "Nextcloud pasahitza"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV URL"
|
||||
msgstr "Nexcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV username"
|
||||
msgstr "Nexcloud erabiltzaile-izena"
|
||||
msgstr "Nextcloud erabiltzaile-izena"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV password"
|
||||
@@ -1187,6 +1179,41 @@ msgstr "Ezarri pasahitza"
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Balio aukera baliogabea: \"%s\". Litezkeen balioak: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Evernotetik esportatutako fitxategiak"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Evernotetik esportatutako fitxategiak"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "Aukeratu nora esportatu sinkronizazioaren egoera, mesedez"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Itemok ezin sinkronizatu"
|
||||
|
||||
@@ -1354,3 +1381,71 @@ msgstr "Oraindik ez duzu koadernorik. Sortu bat (+) botoian sakatuta."
|
||||
|
||||
msgid "Welcome"
|
||||
msgstr "Ongi etorri!"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Inportatu Evernote koaderno fitxategia (.enex fitxategia)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ " \"%s\" izeneko fitxategia \"%s\" izeneko koadernoan inportatzekotan "
|
||||
#~ "zaude. Jarraitu nahi duzu?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ " \"%s\" izeneko koaderno berria sortzekotan zaude eta bertan \"%s\" "
|
||||
#~ "fitxategia bertara inportatzekotan zaude. Jarraitu nahi duzu?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Inportatu Evernoteko oharrak"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Eraman fokua hurrengo panelera"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Eraman fokua aurreko panelera"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Sartu komando-lerro moduan "
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Irten komando-lerro modutik"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Editatu aukeratutako oharra"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Utzi uneko komandoa"
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Irten aplikaziotik"
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "Ezabatu aukeratutako oharra edo koadernoa"
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Zeregina eginda / ez-eginda markatu"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr ""
|
||||
#~ "[t]xandakatu [k]ontsola maximizatu/minimizatu/ezkutatu/ikusgai artean"
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "[t]xandakatu oharra eta [m]etadatuak"
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "[S]ortu [o]har berria"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "[S]ortu [z]ereginen zerrenda"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "[S]ortu koa[d]erno berria"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "Kopiatu ([E]raman) [o]harra koadernora"
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Eraman oharra koadernora"
|
||||
|
@@ -15,63 +15,12 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.3\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Activer le volet suivant"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Activer le volet précédent"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Démarrer le mode de ligne de commande"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Sortir du mode de ligne de commande"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Éditer la note sélectionnée"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Annuler la commande en cours."
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Quitter le logiciel."
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Supprimer la note ou carnet sélectionné."
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "Pour supprimer une vignette, enlever là des notes associées."
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "Veuillez d'abord sélectionner un carnet."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Marquer une tâches comme complétée / non-complétée"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr "Maximiser, minimiser, cacher ou rendre visible la console."
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Chercher"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "Afficher/Cacher les métadonnées des notes."
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "Créer une nouvelle note"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "Créer une nouvelle tâche"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "Créer un nouveau carnet"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "Copier la note dans un autre carnet."
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Déplacer la note vers un carnet."
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Appuyez sur Ctrl+D ou tapez \"exit\" pour sortir du logiciel"
|
||||
|
||||
@@ -146,8 +95,8 @@ msgid ""
|
||||
"current configuration."
|
||||
msgstr ""
|
||||
"Obtient ou modifie une valeur de configuration. Si la [valeur] n'est pas "
|
||||
"fournie, la valeur de [nom] est affichée. Si ni le [nom] ni la [valeur] ne "
|
||||
"sont fournis, la configuration complète est affichée."
|
||||
"fournie, la valeur de [nom] sera affichée. Si ni le [nom] ni la [valeur] ne "
|
||||
"sont fournis, la configuration complète sera affichée."
|
||||
|
||||
msgid "Also displays unset and hidden config variables."
|
||||
msgstr "Afficher également les variables cachées."
|
||||
@@ -239,12 +188,15 @@ msgid "Exits the application."
|
||||
msgstr "Quitter le logiciel."
|
||||
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Exporter les données de Joplin vers le dossier fourni. Par défaut, la base "
|
||||
"de donnée complète sera exportée, y compris les carnets, notes, tags et "
|
||||
"resources."
|
||||
"Exporter les données de Joplin. Par défaut, la base de donnée complète sera "
|
||||
"exportée, y compris les carnets, notes, tags et ressources."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Format de la destination : %s"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Exporter uniquement la note spécifiée."
|
||||
@@ -258,6 +210,11 @@ msgstr "Afficher l'URL de l'emplacement de la note."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Affiche les informations d'utilisation."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
"Pour personnaliser les raccourcis veuillez consulter la documentation à %s"
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "Les raccourcis ne sont pas disponible en mode de ligne de commande."
|
||||
|
||||
@@ -301,29 +258,19 @@ msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Pour sortir du mode ligne de commande, pressez ECHAP"
|
||||
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
msgstr ""
|
||||
"Pour la liste complète des raccourcis disponibles, tapez `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr "Pour la liste complète des raccourcis disponibles, tapez `help keymap`"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Importer un carnet Evernote (fichier .enex)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr "Importer des données dans Joplin."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Format de la source : %s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Ne pas demander de confirmation."
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
"Le fichier \"%s\" va être importé dans le carnet existant \"%s\". Continuer ?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"Un nouveau carnet \"%s\" va être créé et le fichier \"%s\" va être importé "
|
||||
"dedans. Continuer ?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Trouvés : %d."
|
||||
@@ -610,9 +557,20 @@ msgstr ""
|
||||
"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."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr "Exporter vers \"%s\" au format \"%s\". Veuillez patienter..."
|
||||
|
||||
msgid "File"
|
||||
msgstr "Fichier"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr "Dossier"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr "Importer depuis \"%s\" au format \"%s\". Veuillez patienter..."
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Nouvelle note"
|
||||
|
||||
@@ -622,11 +580,15 @@ msgstr "Nouvelle tâche"
|
||||
msgid "New notebook"
|
||||
msgstr "Nouveau carnet"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Importer notes d'Evernote"
|
||||
msgid "Import"
|
||||
msgstr "Importer"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Fichiers d'export Evernote"
|
||||
msgid "Export"
|
||||
msgstr "Exporter"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr "Cacher %s"
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Quitter"
|
||||
@@ -646,6 +608,12 @@ msgstr "Coller"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Chercher dans toutes les notes"
|
||||
|
||||
msgid "View"
|
||||
msgstr "Affichage"
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr "Basculer l'agencement de l'éditeur"
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Outils"
|
||||
|
||||
@@ -687,9 +655,6 @@ msgstr "OK"
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
|
||||
msgid "Error"
|
||||
msgstr "Erreur"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -833,6 +798,9 @@ msgstr "Renommer le carnet :"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Régler alarme :"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Chercher"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Disposition"
|
||||
|
||||
@@ -889,6 +857,14 @@ msgstr "Étiquettes"
|
||||
msgid "Set alarm"
|
||||
msgstr "Régler alarme"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
"Cette note n'a pas de contenu. Cliquer sur \"%s\" pour basculer vers "
|
||||
"l'éditeur et éditer cette note."
|
||||
|
||||
msgid "to-do"
|
||||
msgstr "tâche"
|
||||
|
||||
@@ -908,9 +884,6 @@ msgstr "Supprimer"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "Connexion OneDrive"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Importer"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Options"
|
||||
|
||||
@@ -953,8 +926,8 @@ msgstr "Paramètre inconnu : %s"
|
||||
msgid "File system"
|
||||
msgstr "Système de fichier"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgstr "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr "Nextcloud"
|
||||
|
||||
msgid "OneDrive"
|
||||
msgstr "OneDrive"
|
||||
@@ -962,8 +935,8 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dév (Pour tester uniquement)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgstr "WebDAV (Bêta)"
|
||||
msgid "WebDAV"
|
||||
msgstr "WebDAV"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unknown log level: %s"
|
||||
@@ -1101,8 +1074,14 @@ msgstr "Clair"
|
||||
msgid "Dark"
|
||||
msgstr "Sombre"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
msgstr "Tâches non-terminées en haut des listes"
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Tâches non-terminées en haut"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr "Trier les notes par"
|
||||
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Inverser l'ordre."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Enregistrer l'emplacement avec les notes"
|
||||
@@ -1122,9 +1101,19 @@ msgstr "Lors de la création d'une note :"
|
||||
msgid "Show tray icon"
|
||||
msgstr "Afficher icône dans la zone de notifications"
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Niveau de zoom"
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr "Police de l'éditeur"
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
"Le nom de la police ne sera pas vérifié. Si incorrect ou vide une police "
|
||||
"monospace sera utilisée par défaut."
|
||||
|
||||
msgid "Automatically update the application"
|
||||
msgstr "Mettre à jour le logiciel automatiquement"
|
||||
|
||||
@@ -1167,13 +1156,13 @@ msgstr ""
|
||||
"Le chemin du répertoire avec lequel synchroniser lorsque la synchronisation "
|
||||
"par système de fichier est activée. Voir `sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud : URL WebDAV"
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Nextcloud : Nom utilisateur"
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr "Nextcloud : Mot de passe"
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1189,6 +1178,40 @@ msgstr "WebDAV : Mot de passe"
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Option invalide: \"%s\". Les valeurs possibles sont : %s."
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Fichier d'export Joplin"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr "Markdown"
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr "Dossier d'export Joplin"
|
||||
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Fichiers d'export Evernote"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr "Impossible de charger module \"%s\" pour le format \"%s\""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr "Veuillez spécifier le format d'import pour %s"
|
||||
|
||||
#, javascript-format
|
||||
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é "
|
||||
"et réessayez."
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr "Il n'y a pas de données à exporter."
|
||||
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "Veuillez sélectionner le carnet où les notes doivent être importées."
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Objets qui ne peuvent pas être synchronisés"
|
||||
|
||||
@@ -1362,6 +1385,79 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Bienvenue"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Importer un carnet Evernote (fichier .enex)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Le fichier \"%s\" va être importé dans le carnet existant \"%s\". "
|
||||
#~ "Continuer ?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Un nouveau carnet \"%s\" va être créé et le fichier \"%s\" va être "
|
||||
#~ "importé dedans. Continuer ?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Importer notes d'Evernote"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Activer le volet suivant"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Activer le volet précédent"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Démarrer le mode de ligne de commande"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Sortir du mode de ligne de commande"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Éditer la note sélectionnée"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Annuler la commande en cours."
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Quitter le logiciel."
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "Supprimer la note ou carnet sélectionné."
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Marquer une tâches comme complétée / non-complétée"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr "Maximiser, minimiser, cacher ou rendre visible la console."
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "Afficher/Cacher les métadonnées des notes."
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "Créer une nouvelle note"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "Créer une nouvelle tâche"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "Créer un nouveau carnet"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "Copier la note dans un autre carnet."
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Déplacer la note vers un carnet."
|
||||
|
||||
#~ msgid "Error"
|
||||
#~ msgstr "Erreur"
|
||||
|
||||
#~ msgid "WebDAV (Beta)"
|
||||
#~ msgstr "WebDAV (Bêta)"
|
||||
|
||||
#~ msgid "Could not download the update: %s"
|
||||
#~ msgstr "Impossible de télécharger la mise à jour : %s"
|
||||
|
||||
|
@@ -17,69 +17,12 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Fokusiraj sljedeće okno"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Fokusiraj prethodno okno"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Otvori naredbeni redak"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Napusti naredbeni redak"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Uredi odabranu bilješku"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Prekini trenutnu naredbu."
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Izađi iz aplikacije."
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Obriši odabranu bilješku ili bilježnicu."
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "Da bi mogao obrisati oznaku, skini oznaku s povezanih bilješki."
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "Odaberi bilješku ili bilježnicu za brisanje."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Postavi zadatak kao završen/nezavršen"
|
||||
|
||||
#, fuzzy
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Traži"
|
||||
|
||||
#, fuzzy
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "[t]oggle note [m]etadata."
|
||||
|
||||
#, fuzzy
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "[M]ake a new [n]ote"
|
||||
|
||||
#, fuzzy
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "[M]ake a new [t]odo"
|
||||
|
||||
#, fuzzy
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "[M]ake a new note[b]ook"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Premjesti bilješku u bilježnicu."
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Pritisni Ctrl+D ili napiši \"exit\" za izlazak iz aplikacije"
|
||||
|
||||
@@ -245,13 +188,18 @@ msgstr "Bilješka je spremljena."
|
||||
msgid "Exits the application."
|
||||
msgstr "Izlaz iz aplikacije."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Izvozi podatke u dati direktorij. Po defaultu izvozi sve podatke uključujući "
|
||||
"bilježnice, bilješke, zadatke i resurse."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Format datuma"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Izvozi samo datu bilješku."
|
||||
|
||||
@@ -264,6 +212,10 @@ msgstr "Prikazuje geolokacijski URL bilješke."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Prikazuje informacije o korištenju."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "Prečaci nisu podržani u naredbenom retku."
|
||||
|
||||
@@ -307,29 +259,21 @@ msgstr "Za ulaz u naredbeni redak, pritisni \":\""
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Za izlaz iz naredbenog retka, pritisni Esc"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr "Za potpunu listu mogućih prečaca, upiši `help shortcuts`"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Uvozi Evernote bilježnicu (.enex datoteku)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Ne postoji naredba: %s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Ne pitaj za potvrdu."
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
"Datoteka \"%s\" će biti uvezena u postojeću bilježnicu \"%s\". Nastavi?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"Nova bilježnica \"%s\" će biti stvorena i datoteka \"%s\" će biti uvezena u "
|
||||
"nju. Nastavi?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Nađeno: %d."
|
||||
@@ -614,9 +558,20 @@ msgid ""
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "Datoteka"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Nova bilješka"
|
||||
|
||||
@@ -626,11 +581,16 @@ msgstr "Novi zadatak"
|
||||
msgid "New notebook"
|
||||
msgstr "Nova bilježnica"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Uvezi Evernote bilješke"
|
||||
msgid "Import"
|
||||
msgstr "Uvoz"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Evernote izvozne datoteke"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "Uvoz"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Izađi"
|
||||
@@ -650,6 +610,12 @@ msgstr "Zalijepi"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Pretraži u svim bilješkama"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Alati"
|
||||
|
||||
@@ -692,9 +658,6 @@ msgstr "U redu"
|
||||
msgid "Cancel"
|
||||
msgstr "Odustani"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -821,6 +784,9 @@ msgstr "Preimenuj bilježnicu:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Postavi upozorenje:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Traži"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Izgled"
|
||||
|
||||
@@ -876,6 +842,12 @@ msgstr "Oznake"
|
||||
msgid "Set alarm"
|
||||
msgstr "Postavi upozorenje"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "Novi zadatak"
|
||||
@@ -897,9 +869,6 @@ msgstr "Očisti"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "OneDrive Login"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Uvoz"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Opcije"
|
||||
|
||||
@@ -941,7 +910,7 @@ msgstr "Nepoznata zastavica: %s"
|
||||
msgid "File system"
|
||||
msgstr "Datotečni sustav"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -950,7 +919,7 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dev (Samo za testiranje)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -1088,9 +1057,17 @@ msgstr "Svijetla"
|
||||
msgid "Dark"
|
||||
msgstr "Tamna"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Prikaži nezavršene zadatke na vrhu liste"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Mijenja redoslijed."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Spremi geolokacijske podatke sa bilješkama"
|
||||
|
||||
@@ -1112,7 +1089,15 @@ msgstr "Stvara novu bilješku."
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1154,13 +1139,13 @@ msgstr ""
|
||||
"Putanja do direktorija za sinkronizaciju u slučaju kad je sinkronizacija sa "
|
||||
"datotečnim sustavom omogućena. Vidi `sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1176,6 +1161,41 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Nevažeća vrijednost: \"%s\". Moguće vrijednosti su: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Evernote izvozne datoteke"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Evernote izvozne datoteke"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "Odaberi lokaciju za izvoz statusa sinkronizacije"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Stavke koje se ne mogu sinkronizirati"
|
||||
|
||||
@@ -1343,6 +1363,78 @@ msgstr "Trenutno nemaš nijednu bilježnicu. Stvori novu klikom na (+) gumb."
|
||||
msgid "Welcome"
|
||||
msgstr "Dobro došli"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Uvozi Evernote bilježnicu (.enex datoteku)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Datoteka \"%s\" će biti uvezena u postojeću bilježnicu \"%s\". Nastavi?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Nova bilježnica \"%s\" će biti stvorena i datoteka \"%s\" će biti uvezena "
|
||||
#~ "u nju. Nastavi?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Uvezi Evernote bilješke"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Fokusiraj sljedeće okno"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Fokusiraj prethodno okno"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Otvori naredbeni redak"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Napusti naredbeni redak"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Uredi odabranu bilješku"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Prekini trenutnu naredbu."
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Izađi iz aplikacije."
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "Obriši odabranu bilješku ili bilježnicu."
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Postavi zadatak kao završen/nezavršen"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "[t]oggle note [m]etadata."
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "[M]ake a new [n]ote"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "[M]ake a new [t]odo"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "[M]ake a new note[b]ook"
|
||||
|
||||
#, fuzzy
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Premjesti bilješku u bilježnicu."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The target to synchonise to. If synchronising with the file system, set "
|
||||
#~ "`sync.2.path` to specify the target directory."
|
||||
|
@@ -16,65 +16,12 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.0.3\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Pannello successivo"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Pannello precedente"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Accedi alla modalità linea di comando"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Esci dalla modalità linea di comando"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Modifica la nota selezionata"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Cancella il comando corrente."
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Esci dall'applicazione."
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Elimina la nota o il blocco note selezionato."
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "Elimina un'etichetta, togli l'etichetta associata alle note."
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "Per favore seleziona la nota o il blocco note da eliminare."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Imposta un'attività come completata / non completata"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr ""
|
||||
"Scegli lo s[t]ato della [c]onsole: massimizzato/minimizzato/nascosto/"
|
||||
"visibile."
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Cerca"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "mos[t]ra/nascondi i [m]etadata nelle note."
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "Crea ([M]ake) una nuova [n]ota"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "Crea ([M]ake) una nuova at[t]ività"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "Crea ([M]ake) un nuovo [b]locco note"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "Copia ([Y]) la [n]ota in un blocco note."
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Sposta la nota in un blocco note."
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Premi Ctrl+D o digita \"exit\" per uscire dall'applicazione"
|
||||
|
||||
@@ -236,14 +183,19 @@ msgstr "La nota è stata salvata."
|
||||
msgid "Exits the application."
|
||||
msgstr "Esci dall'applicazione."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Esporta i dati da Joplin nella directory selezionata. Come impostazione "
|
||||
"predefinita verrà esportato il database completo, inclusi blocchi note, "
|
||||
"note, etichette e risorse."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Formato della data"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Esporta solo la seguente nota."
|
||||
|
||||
@@ -256,6 +208,10 @@ msgstr "Mostra l'URL di geolocalizzazione per la nota."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Mostra le informazioni di utilizzo."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "Le scorciatoie non sono disponibili nella modalità CLI."
|
||||
|
||||
@@ -298,30 +254,22 @@ msgstr "Per entrare nella modalità command line, premi \":\""
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Per uscire dalla modalità command line, premi ESC"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
"Per la lista completa delle scorciatoie disponibili, digita `help shortcuts`"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Importa un file blocco note di Evernote (.enex file)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Nessun comando: %s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Non chiedere conferma."
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
"Il file \"%s\" sarà importato nel blocco note esistente \"%s\". Continuare?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"Un nuovo blocco note \"%s\" sarà creato e al suo interno verrà importato il "
|
||||
"file \"%s\" . Continuare?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Trovato: %d."
|
||||
@@ -592,9 +540,20 @@ msgid ""
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "File"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Nuova nota"
|
||||
|
||||
@@ -604,11 +563,16 @@ msgstr "Nuova attività"
|
||||
msgid "New notebook"
|
||||
msgstr "Nuovo blocco note"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Importa le note da Evernote"
|
||||
msgid "Import"
|
||||
msgstr "Importa"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Esposta i files di Evernote"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "Importa"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Esci"
|
||||
@@ -628,6 +592,12 @@ msgstr "Incolla"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Cerca in tutte le note"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Strumenti"
|
||||
|
||||
@@ -670,9 +640,6 @@ msgstr "OK"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancella"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -799,6 +766,9 @@ msgstr "Rinomina il blocco note:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Imposta allarme:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Cerca"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Disposizione"
|
||||
|
||||
@@ -855,6 +825,12 @@ msgstr "Etichette"
|
||||
msgid "Set alarm"
|
||||
msgstr "Imposta allarme"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "Nuova attività"
|
||||
@@ -876,9 +852,6 @@ msgstr "Pulisci"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "Login OneDrive"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Importa"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Opzioni"
|
||||
|
||||
@@ -921,7 +894,7 @@ msgstr "Etichetta sconosciuta: %s"
|
||||
msgid "File system"
|
||||
msgstr "File system"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -930,7 +903,7 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dev (solo per test)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -1070,9 +1043,17 @@ msgstr "Chiaro"
|
||||
msgid "Dark"
|
||||
msgstr "Scuro"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Mostra todo inclompleti in cima alla lista"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Inverti l'ordine."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Salva geo-localizzazione con le note"
|
||||
|
||||
@@ -1094,7 +1075,15 @@ msgstr "Crea una nuova nota."
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1136,13 +1125,13 @@ msgstr ""
|
||||
"Il percorso di sincronizzazione quando la sincronizzazione è abilitata. Vedi "
|
||||
"`sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1158,6 +1147,41 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Oprione non valida: \"%s\". I valori possibili sono: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Esposta i files di Evernote"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Esposta i files di Evernote"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "Per favore seleziona la nota o il blocco note da eliminare."
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Elementi che non possono essere sincronizzati"
|
||||
|
||||
@@ -1327,6 +1351,75 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Benvenuto"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Importa un file blocco note di Evernote (.enex file)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Il file \"%s\" sarà importato nel blocco note esistente \"%s\". "
|
||||
#~ "Continuare?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Un nuovo blocco note \"%s\" sarà creato e al suo interno verrà importato "
|
||||
#~ "il file \"%s\" . Continuare?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Importa le note da Evernote"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Pannello successivo"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Pannello precedente"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Accedi alla modalità linea di comando"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Esci dalla modalità linea di comando"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Modifica la nota selezionata"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Cancella il comando corrente."
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Esci dall'applicazione."
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "Elimina la nota o il blocco note selezionato."
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Imposta un'attività come completata / non completata"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr ""
|
||||
#~ "Scegli lo s[t]ato della [c]onsole: massimizzato/minimizzato/nascosto/"
|
||||
#~ "visibile."
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "mos[t]ra/nascondi i [m]etadata nelle note."
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "Crea ([M]ake) una nuova [n]ota"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "Crea ([M]ake) una nuova at[t]ività"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "Crea ([M]ake) un nuovo [b]locco note"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "Copia ([Y]) la [n]ota in un blocco note."
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Sposta la nota in un blocco note."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The target to synchonise to. If synchronising with the file system, set "
|
||||
#~ "`sync.2.path` to specify the target directory."
|
||||
|
@@ -16,63 +16,12 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.0.5\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "次のペインへ"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "前のペインへ"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "コマンドラインモードに入る"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "コマンドラインモードの終了"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "選択したノートを編集"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "現在のコマンドをキャンセル"
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "アプリケーションを終了する"
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "選択中のノートまたはノートブックを削除"
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "タグを削除するには、関連するノートからタグを外してください。"
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "ます削除するノートかノートブックを選択してください。"
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "ToDoを完了/未完に設定"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr "コンソールを最大表示/最小表示/非表示/可視で切り替える([t][c])"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "検索"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "ノートのメタ情報を切り替える [tm]"
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "新しいノートの作成 [mn]"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "新しいToDoの作成 [mt]"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "新しいノートブックの作成 [mb]"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "ノートをノートブックにコピー [yn]"
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "ノートをノートブックに移動"
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "アプリケーションを終了するには、Ctrl+Dまたは\"exit\"と入力してください"
|
||||
|
||||
@@ -233,13 +182,18 @@ msgstr "ノートは保存されました。"
|
||||
msgid "Exits the application."
|
||||
msgstr "アプリケーションの終了。"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Joplinのデータを選択されたディレクトリに出力する。標準では、ノートブック・"
|
||||
"ノート・タグ・添付データを含むすべてのデータベースを出力します。"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "日付の形式"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "選択されたノートのみを出力する。"
|
||||
|
||||
@@ -252,6 +206,10 @@ msgstr "ノートの位置情報URLを表示する。"
|
||||
msgid "Displays usage information."
|
||||
msgstr "使い方を表示する。"
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "CLIモードではショートカットは使用できません。"
|
||||
|
||||
@@ -291,31 +249,23 @@ msgstr "コマンドラインモードに入るには、\":\"を入力してく
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "コマンドラインモードを終了するには、ESCキーを押してください。"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
"有効なすべてのキーボードショートカットを表示するには、`help shortcuts`と入力"
|
||||
"してください。"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Evernoteノートブックファイル(.enex)のインポート"
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "コマンドが違います:%s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "確認を行わない。"
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
"ファイル \"%s\" はノートブック \"%s\"に取り込まれます。よろしいですか?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"新しいノートブック\"%s\"が作成され、ファイル\"%s\"が取り込まれます。よろしい"
|
||||
"ですか?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "見つかりました:%d"
|
||||
@@ -591,9 +541,20 @@ msgid ""
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "ファイル"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "新しいノート"
|
||||
|
||||
@@ -603,11 +564,16 @@ msgstr "新しいToDo"
|
||||
msgid "New notebook"
|
||||
msgstr "新しいノートブック"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Evernoteのインポート"
|
||||
msgid "Import"
|
||||
msgstr "インポート"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Evernote Exportファイル"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "インポート"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "終了"
|
||||
@@ -627,6 +593,12 @@ msgstr "貼り付け"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "すべてのノートを検索"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "ツール"
|
||||
|
||||
@@ -669,9 +641,6 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr "キャンセル"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -801,6 +770,9 @@ msgstr "ノートブックの名前を変更:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "アラームをセット:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "検索"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "レイアウト"
|
||||
|
||||
@@ -856,6 +828,12 @@ msgstr "タグ"
|
||||
msgid "Set alarm"
|
||||
msgstr "アラームをセット"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "新しいToDo"
|
||||
@@ -877,9 +855,6 @@ msgstr "クリア"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "OneDriveログイン"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "インポート"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "オプション"
|
||||
|
||||
@@ -921,7 +896,7 @@ msgstr "不明なフラグ: %s"
|
||||
msgid "File system"
|
||||
msgstr "ファイルシステム"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -930,7 +905,7 @@ msgstr ""
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -1072,9 +1047,17 @@ msgstr "明るい"
|
||||
msgid "Dark"
|
||||
msgstr "暗い"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "未完のToDoをリストの上部に表示"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "逆順に並び替える。"
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "ノートに位置情報を保存"
|
||||
|
||||
@@ -1096,7 +1079,15 @@ msgstr "あたらしいノートを作成します。"
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1138,13 +1129,13 @@ msgstr ""
|
||||
"ファイルシステム同期の有効時に同期を行うパスです。`sync.target`も参考にしてく"
|
||||
"ださい。"
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1160,6 +1151,41 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "無効な設定値: \"%s\"。有効な値は: %sです。"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Evernote Exportファイル"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Evernote Exportファイル"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "同期状況の出力先を選択してください"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "同期が出来なかったアイテム"
|
||||
|
||||
@@ -1329,6 +1355,72 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "ようこそ"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Evernoteノートブックファイル(.enex)のインポート"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "ファイル \"%s\" はノートブック \"%s\"に取り込まれます。よろしいですか?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "新しいノートブック\"%s\"が作成され、ファイル\"%s\"が取り込まれます。よろし"
|
||||
#~ "いですか?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Evernoteのインポート"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "次のペインへ"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "前のペインへ"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "コマンドラインモードに入る"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "コマンドラインモードの終了"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "選択したノートを編集"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "現在のコマンドをキャンセル"
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "アプリケーションを終了する"
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "選択中のノートまたはノートブックを削除"
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "ToDoを完了/未完に設定"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr "コンソールを最大表示/最小表示/非表示/可視で切り替える([t][c])"
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "ノートのメタ情報を切り替える [tm]"
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "新しいノートの作成 [mn]"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "新しいToDoの作成 [mt]"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "新しいノートブックの作成 [mb]"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "ノートをノートブックにコピー [yn]"
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "ノートをノートブックに移動"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The target to synchonise to. If synchronising with the file system, set "
|
||||
#~ "`sync.2.path` to specify the target directory."
|
||||
|
@@ -15,63 +15,12 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr ""
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr ""
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr ""
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr ""
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr ""
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr ""
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr ""
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr ""
|
||||
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr ""
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr ""
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr ""
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr ""
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr ""
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr ""
|
||||
|
||||
@@ -225,10 +174,14 @@ msgid "Exits the application."
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr ""
|
||||
|
||||
@@ -241,6 +194,10 @@ msgstr ""
|
||||
msgid "Displays usage information."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr ""
|
||||
|
||||
@@ -276,25 +233,19 @@ msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr ""
|
||||
@@ -535,9 +486,20 @@ msgid ""
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr ""
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr ""
|
||||
|
||||
@@ -547,10 +509,14 @@ msgstr ""
|
||||
msgid "New notebook"
|
||||
msgstr ""
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgid "Export"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
@@ -571,6 +537,12 @@ msgstr ""
|
||||
msgid "Search in all the notes"
|
||||
msgstr ""
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr ""
|
||||
|
||||
@@ -612,9 +584,6 @@ msgstr ""
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -737,6 +706,9 @@ msgstr ""
|
||||
msgid "Set alarm:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
msgid "Layout"
|
||||
msgstr ""
|
||||
|
||||
@@ -790,6 +762,12 @@ msgstr ""
|
||||
msgid "Set alarm"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
msgid "to-do"
|
||||
msgstr ""
|
||||
|
||||
@@ -809,9 +787,6 @@ msgstr ""
|
||||
msgid "OneDrive Login"
|
||||
msgstr ""
|
||||
|
||||
msgid "Import"
|
||||
msgstr ""
|
||||
|
||||
msgid "Options"
|
||||
msgstr ""
|
||||
|
||||
@@ -853,7 +828,7 @@ msgstr ""
|
||||
msgid "File system"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -862,7 +837,7 @@ msgstr ""
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -991,7 +966,13 @@ msgstr ""
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr ""
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reverse sort order"
|
||||
msgstr ""
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
@@ -1012,7 +993,15 @@ msgstr ""
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1052,13 +1041,13 @@ msgid ""
|
||||
"See `sync.target`."
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1074,6 +1063,38 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export File"
|
||||
msgstr ""
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
msgid "Evernote Export File"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr ""
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr ""
|
||||
|
||||
|
@@ -16,64 +16,12 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.0.5\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Focus op het volgende paneel"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Focus op het vorige paneel"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Ga naar command line modus"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Ga uit command line modus"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Pas de geselecteerde notitie aan"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Annuleer het huidige commando."
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Sluit de applicatie."
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Verwijder de geselecteerde notitie of het geselecteerde notitieboek."
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "Untag de geassocieerde notities om een tag te verwijderen."
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "Selecteer eerst het notitieboek of de notitie om te verwijderen."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Zet een to-do als voltooid / niet voltooid"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr ""
|
||||
"Wissel de console tussen gemaximaliseerd/geminimaliseerd/verborgen/zichtbaar."
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Zoeken"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "Ac[t]iveer notitie [m]etadata."
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "[M]aak een nieuwe [n]otitie"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "[M]aak een nieuwe [t]o-do"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "[M]aak een nieuw notitie[b]oek"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "Kopieer [Y] de [n]otirie in een notitieboek."
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Verplaats de notitie naar een notitieboek."
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Typ Ctrl+D of \"exit\" om de applicatie te sluiten"
|
||||
|
||||
@@ -239,14 +187,19 @@ msgstr "Notitie is opgeslaan."
|
||||
msgid "Exits the application."
|
||||
msgstr "Sluit de applicatie."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Exporteert Joplin gegevens naar de opgegeven folder. Standaard zal het de "
|
||||
"volledige database exporteren, zoals notitieboeken, notities, tags en "
|
||||
"middelen."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Datumnotatie"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Exporteert alleen de opgegeven notitie."
|
||||
|
||||
@@ -259,6 +212,10 @@ msgstr "Toont een geolocatie link voor de notitie."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Toont gebruiksinformatie."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "Shortcuts zijn niet beschikbaar in command line modus."
|
||||
|
||||
@@ -301,31 +258,22 @@ msgstr "Om command line modus te gebruiken, duw \":\""
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Om command line modus te verlaten, duw ESCAPE"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
"Voor de volledige lijst van beschikbare shortcuts, typ `help shortcuts`"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Importeer een Evernote notitieboek (.enex bestand)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Geen commando gevonden: \"%s\""
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Vraag niet om bevestiging. "
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
"Bestand \"%s\" zal toegevoegd worden aan bestaand notitieboek \"%s\". "
|
||||
"Doorgaan?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"Nieuw notitieboek \"%s\" zal aangemaakt worden en bestand \"%s\" zal eraan "
|
||||
"toegevoegd worden. Doorgaan?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Gevonden: %d."
|
||||
@@ -610,9 +558,20 @@ msgstr ""
|
||||
"hoofdsleutel al ingegeven hebt, worden de versleutelde items ontsleuteld in "
|
||||
"de achtergrond. Ze zijn binnenkort beschikbaar."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "Bestand"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Nieuwe notitie"
|
||||
|
||||
@@ -622,11 +581,16 @@ msgstr "Nieuwe to-do"
|
||||
msgid "New notebook"
|
||||
msgstr "Nieuw notitieboek"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Importeer Evernote notities"
|
||||
msgid "Import"
|
||||
msgstr "Importeer"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Exporteer Evernote bestanden"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "Importeer"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Stop"
|
||||
@@ -646,6 +610,12 @@ msgstr "Plak"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Zoek in alle notities"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Tools"
|
||||
|
||||
@@ -687,9 +657,6 @@ msgstr "OK"
|
||||
msgid "Cancel"
|
||||
msgstr "Annuleer"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -828,6 +795,9 @@ msgstr "Hernoem notitieboek:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Stel melding in:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Zoeken"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
@@ -884,6 +854,12 @@ msgstr "Tags"
|
||||
msgid "Set alarm"
|
||||
msgstr "Zet melding"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "Nieuwe to-do"
|
||||
@@ -905,9 +881,6 @@ msgstr "Vrijmaken"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "OneDrive Login"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Importeer"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Opties"
|
||||
|
||||
@@ -949,8 +922,9 @@ msgstr "Onbekende optie: %s"
|
||||
msgid "File system"
|
||||
msgstr "Bestandssysteem"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgstr ""
|
||||
#, fuzzy
|
||||
msgid "Nextcloud"
|
||||
msgstr "Stel wachtwoord in"
|
||||
|
||||
msgid "OneDrive"
|
||||
msgstr "OneDrive"
|
||||
@@ -958,7 +932,7 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dev (Alleen voor testen)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -1100,9 +1074,17 @@ msgstr "Licht"
|
||||
msgid "Dark"
|
||||
msgstr "Donker"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Toon onvoltooide to-do's aan de top van de lijsten"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Draait de sorteervolgorde om."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Sla geo-locatie op bij notities"
|
||||
|
||||
@@ -1123,7 +1105,15 @@ msgstr "Maakt een nieuwe notitie aan."
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1165,14 +1155,14 @@ msgstr ""
|
||||
"Het pad om mee te synchroniseren als bestandssysteem synchronisatie is "
|
||||
"ingeschakeld. Zie `sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr "Stel wachtwoord in"
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1189,6 +1179,41 @@ msgstr "Stel wachtwoord in"
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Ongeldige optie: \"%s\". Geldige waarden zijn: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Exporteer Evernote bestanden"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Exporteer Evernote bestanden"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "Selecteer waar de synchronisatie status naar geëxporteerd moet worden"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Items die niet gesynchroniseerd kunnen worden"
|
||||
|
||||
@@ -1361,6 +1386,76 @@ msgstr ""
|
||||
msgid "Welcome"
|
||||
msgstr "Welkom"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Importeer een Evernote notitieboek (.enex bestand)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Bestand \"%s\" zal toegevoegd worden aan bestaand notitieboek \"%s\". "
|
||||
#~ "Doorgaan?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Nieuw notitieboek \"%s\" zal aangemaakt worden en bestand \"%s\" zal "
|
||||
#~ "eraan toegevoegd worden. Doorgaan?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Importeer Evernote notities"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Focus op het volgende paneel"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Focus op het vorige paneel"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Ga naar command line modus"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Ga uit command line modus"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Pas de geselecteerde notitie aan"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Annuleer het huidige commando."
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Sluit de applicatie."
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr ""
|
||||
#~ "Verwijder de geselecteerde notitie of het geselecteerde notitieboek."
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Zet een to-do als voltooid / niet voltooid"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr ""
|
||||
#~ "Wissel de console tussen gemaximaliseerd/geminimaliseerd/verborgen/"
|
||||
#~ "zichtbaar."
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "Ac[t]iveer notitie [m]etadata."
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "[M]aak een nieuwe [n]otitie"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "[M]aak een nieuwe [t]o-do"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "[M]aak een nieuw notitie[b]oek"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "Kopieer [Y] de [n]otirie in een notitieboek."
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Verplaats de notitie naar een notitieboek."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The target to synchonise to. If synchronising with the file system, set "
|
||||
#~ "`sync.2.path` to specify the target directory."
|
||||
|
@@ -16,63 +16,12 @@ msgstr ""
|
||||
"X-Generator: Poedit 2.0.5\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Dar o foco para o próximo painel"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Dar o foco para o painel anterior"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Entrar no modo de linha de comando"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Sair do modo de linha de comando"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Editar nota selecionada"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Cancelar comando atual."
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Sair da aplicação."
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Excluir nota selecionada ou notebook."
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "Para eliminar uma tag, remova a tag das notas associadas a ela."
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "Por favor, primeiro, selecione a nota ou caderno a excluir."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Marcar uma tarefa como completada / não completada"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr "al[t]ernar [c]onsole entre maximizado / minimizado / oculto / visível."
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Procurar"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "al[t]ernar [m]etadados de notas."
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "Criar ([M]ake) uma nova [n]ota"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "Criar ([M]ake) nova [t]arefa"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "Criar ([M]ake) novo caderno (note[b]ook)"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "Copiar ([Y]ank) a [n]ota a um caderno."
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Mover nota para um caderno."
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Digite Ctrl+D ou \"exit\" para sair da aplicação"
|
||||
|
||||
@@ -233,14 +182,19 @@ msgstr "Nota gravada."
|
||||
msgid "Exits the application."
|
||||
msgstr "Sai da aplicação."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Exporta os dados do Joplin para o diretório informado. Por padrão, ele "
|
||||
"exportará o banco de dados completo, incluindo cadernos, notas, tags e "
|
||||
"recursos."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Formato de data"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Exporta apenas a nota fornecida."
|
||||
|
||||
@@ -253,6 +207,10 @@ msgstr "Exibe uma URL de geolocalização para a nota."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Exibe informações de uso."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "Os atalhos não estão disponíveis no modo CLI."
|
||||
|
||||
@@ -294,31 +252,23 @@ msgstr "Para entrar no modo de linha de comando, pressione \":\""
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Para sair do modo de linha de comando, pressione o ESC"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
"Para a lista completa de atalhos de teclado disponíveis, digite `help "
|
||||
"shortcuts`"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Importa um arquivo de caderno do Evernote (arquivo .enex)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Comando inválido: \"%s\""
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Não pedir confirmação."
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr ""
|
||||
"O arquivo \"%s\" será importado para o caderno existente \"%s\". Continuar?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"O novo caderno \"%s\" será criado e o arquivo \"%s\" será importado para "
|
||||
"ele. Continuar?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Encontrado: %d."
|
||||
@@ -586,9 +536,20 @@ msgid ""
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "Arquivo"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Nova nota"
|
||||
|
||||
@@ -598,11 +559,16 @@ msgstr "Nova tarefa"
|
||||
msgid "New notebook"
|
||||
msgstr "Novo caderno"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Importar notas do Evernote"
|
||||
msgid "Import"
|
||||
msgstr "Importar"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Arquivos de Exportação do Evernote"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "Importar"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Sair"
|
||||
@@ -622,6 +588,12 @@ msgstr "Colar"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Pesquisar em todas as notas"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Ferramentas"
|
||||
|
||||
@@ -665,9 +637,6 @@ msgstr "OK"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -795,6 +764,9 @@ msgstr "Renomear caderno:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Definir alarme:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Procurar"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Layout"
|
||||
|
||||
@@ -852,6 +824,12 @@ msgstr "Tags"
|
||||
msgid "Set alarm"
|
||||
msgstr "Definir alarme"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "Nova tarefa"
|
||||
@@ -873,9 +851,6 @@ msgstr "Limpar (clear)"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "Login no OneDrive"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Importar"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Opções"
|
||||
|
||||
@@ -919,7 +894,7 @@ msgstr "Flag desconhecido: %s"
|
||||
msgid "File system"
|
||||
msgstr "Sistema de arquivos"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -928,7 +903,7 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dev (apenas para testes)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -1069,9 +1044,17 @@ msgstr "Light"
|
||||
msgid "Dark"
|
||||
msgstr "Dark"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Mostrar tarefas incompletas no topo das listas"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Inverte a ordem de classificação."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Salvar geolocalização com notas"
|
||||
|
||||
@@ -1093,7 +1076,15 @@ msgstr "Cria uma nova nota."
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1135,13 +1126,13 @@ msgstr ""
|
||||
"O caminho para sincronizar, quando a sincronização do sistema de arquivos "
|
||||
"está habilitada. Veja `sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1157,6 +1148,41 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Valor da opção inválida: \"%s\". Os valores possíveis são: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Arquivos de Exportação do Evernote"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Arquivos de Exportação do Evernote"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "Por favor, primeiro, selecione a nota ou caderno a excluir."
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr ""
|
||||
|
||||
@@ -1324,6 +1350,74 @@ msgstr "Você não possui cadernos. Crie um clicando no botão (+)."
|
||||
msgid "Welcome"
|
||||
msgstr "Bem-vindo"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Importa um arquivo de caderno do Evernote (arquivo .enex)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "O arquivo \"%s\" será importado para o caderno existente \"%s\". "
|
||||
#~ "Continuar?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "O novo caderno \"%s\" será criado e o arquivo \"%s\" será importado para "
|
||||
#~ "ele. Continuar?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Importar notas do Evernote"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Dar o foco para o próximo painel"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Dar o foco para o painel anterior"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Entrar no modo de linha de comando"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Sair do modo de linha de comando"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Editar nota selecionada"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Cancelar comando atual."
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Sair da aplicação."
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "Excluir nota selecionada ou notebook."
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Marcar uma tarefa como completada / não completada"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr ""
|
||||
#~ "al[t]ernar [c]onsole entre maximizado / minimizado / oculto / visível."
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "al[t]ernar [m]etadados de notas."
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "Criar ([M]ake) uma nova [n]ota"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "Criar ([M]ake) nova [t]arefa"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "Criar ([M]ake) novo caderno (note[b]ook)"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "Copiar ([Y]ank) a [n]ota a um caderno."
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Mover nota para um caderno."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The target to synchonise to. If synchronising with the file system, set "
|
||||
#~ "`sync.2.path` to specify the target directory."
|
||||
|
@@ -17,63 +17,12 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "Переключиться на следующую панель"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "Переключиться на предыдущую панель"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "Войти в режим командной строки"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "Выйти из режима командной строки"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "Редактировать выбранную заметку"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "Отменить текущую команду."
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "Выйти из приложения."
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "Удалить текущую выбранную заметку или блокнот."
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "Чтобы удалить тег, уберите его с ассоциированных с ним заметок."
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "Сначала выберите заметку или блокнот, которые должны быть удалены."
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "Отметить задачу как завершённую/незавершённую"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr "[tc] переключить консоль между развёрнутой/свёрнутой/скрытой/видимой."
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Поиск"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "[tm] переключить отображение метаданных заметки."
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "[mn] создать новую заметку"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "[mt] создать новую задачу"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "[mb] создать новый блокнот"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "[yn] копировать заметку в блокнот."
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "Переместить заметку в блокнот."
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "Для выхода из приложения нажмите Ctrl+D или введите «exit»"
|
||||
|
||||
@@ -240,13 +189,18 @@ msgstr "Заметка сохранена."
|
||||
msgid "Exits the application."
|
||||
msgstr "Выход из приложения."
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"Экспортирует данные Joplin в заданный каталог. По умолчанию экспортируется "
|
||||
"полная база данных, включая блокноты, заметки, теги и ресурсы."
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "Формат даты"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "Экспортирует только заданную заметку."
|
||||
|
||||
@@ -259,6 +213,10 @@ msgstr "Выводит URL геолокации для заметки."
|
||||
msgid "Displays usage information."
|
||||
msgstr "Выводит информацию об использовании."
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "Ярлыки недоступны в режиме командной строки."
|
||||
|
||||
@@ -301,30 +259,23 @@ msgstr "Чтобы войти в режим командной строки, н
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "Чтобы выйти из режима командной строки, нажмите ESCAPE"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr ""
|
||||
"Для просмотра списка доступных клавиатурных сочетаний введите `help "
|
||||
"shortcuts`"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "Импортирует файл блокнотов Evernote (.enex-файл)."
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "Нет такой команды: %s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "Не запрашивать подтверждение."
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr "Файл «%s» будет импортирован в существующий блокнот «%s». Продолжить?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr ""
|
||||
"Будет создан новый блокнот «%s» и в него будет импортирован файл «%s». "
|
||||
"Продолжить?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "Найдено: %d."
|
||||
@@ -609,9 +560,20 @@ msgstr ""
|
||||
"decrypt». Если пароль уже был вами предоставлен, зашифрованные элементы "
|
||||
"расшифруются в фоновом режиме и вскоре станут доступны."
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "Файл"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "Новая заметка"
|
||||
|
||||
@@ -621,11 +583,16 @@ msgstr "Новая задача"
|
||||
msgid "New notebook"
|
||||
msgstr "Новый блокнот"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "Импортировать заметки из Evernote"
|
||||
msgid "Import"
|
||||
msgstr "Импорт"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Файлы экспорта Evernote"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "Импорт"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "Выход"
|
||||
@@ -645,6 +612,12 @@ msgstr "Вставить"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "Поиск во всех заметках"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "Инструменты"
|
||||
|
||||
@@ -686,9 +659,6 @@ msgstr "OK"
|
||||
msgid "Cancel"
|
||||
msgstr "Отмена"
|
||||
|
||||
msgid "Error"
|
||||
msgstr "Ошибка"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -827,6 +797,9 @@ msgstr "Переименовать блокнот:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "Установить напоминание:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "Поиск"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "Вид"
|
||||
|
||||
@@ -881,6 +854,12 @@ msgstr "Теги"
|
||||
msgid "Set alarm"
|
||||
msgstr "Установить напоминание"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "Новая задача"
|
||||
@@ -902,9 +881,6 @@ msgstr "Очистить"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "Вход в OneDrive"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "Импорт"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "Настройки"
|
||||
|
||||
@@ -946,7 +922,8 @@ msgstr "Неизвестный флаг: %s"
|
||||
msgid "File system"
|
||||
msgstr "Файловая система"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
#, fuzzy
|
||||
msgid "Nextcloud"
|
||||
msgstr "Nextcloud (Beta)"
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -955,8 +932,9 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive Dev (только для тестирования)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgstr ""
|
||||
#, fuzzy
|
||||
msgid "WebDAV"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Unknown log level: %s"
|
||||
@@ -1094,9 +1072,17 @@ msgstr "Светлая"
|
||||
msgid "Dark"
|
||||
msgstr "Тёмная"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "Показывать незавершённые задачи вверху списков"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "Обращает порядок сортировки."
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "Сохранять информацию о геолокации в заметках"
|
||||
|
||||
@@ -1115,9 +1101,18 @@ msgstr "При создании новой заметки:"
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
#, fuzzy
|
||||
msgid "Global zoom percentage"
|
||||
msgstr "Масштаб приложения в процентах"
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
msgstr "Автоматически обновлять приложение"
|
||||
|
||||
@@ -1159,22 +1154,22 @@ msgstr ""
|
||||
"Путь для синхронизации при включённой синхронизации с файловой системой. См. "
|
||||
"`sync.target`."
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgstr "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgstr "Имя пользователя Nexcloud"
|
||||
msgid "Nextcloud username"
|
||||
msgstr "Имя пользователя Nextcloud"
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgstr "Пароль Nexcloud"
|
||||
msgid "Nextcloud password"
|
||||
msgstr "Пароль Nextcloud"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV URL"
|
||||
msgstr "Nexcloud WebDAV URL"
|
||||
msgstr "Nextcloud WebDAV URL"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV username"
|
||||
msgstr "Имя пользователя Nexcloud"
|
||||
msgstr "Имя пользователя Nextcloud"
|
||||
|
||||
#, fuzzy
|
||||
msgid "WebDAV password"
|
||||
@@ -1184,6 +1179,41 @@ msgstr "Установить пароль"
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "Неверное значение параметра: «%s». Доступные значения: %s."
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Файлы экспорта Evernote"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Файлы экспорта Evernote"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "Выберите, куда должен быть экспортирован статус синхронизации"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "Элементы, которые не могут быть синхронизированы"
|
||||
|
||||
@@ -1354,6 +1384,76 @@ msgstr "У вас сейчас нет блокнота. Создайте его
|
||||
msgid "Welcome"
|
||||
msgstr "Добро пожаловать"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "Импортирует файл блокнотов Evernote (.enex-файл)."
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Файл «%s» будет импортирован в существующий блокнот «%s». Продолжить?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr ""
|
||||
#~ "Будет создан новый блокнот «%s» и в него будет импортирован файл «%s». "
|
||||
#~ "Продолжить?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "Импортировать заметки из Evernote"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "Переключиться на следующую панель"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "Переключиться на предыдущую панель"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "Войти в режим командной строки"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "Выйти из режима командной строки"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "Редактировать выбранную заметку"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "Отменить текущую команду."
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "Выйти из приложения."
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "Удалить текущую выбранную заметку или блокнот."
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "Отметить задачу как завершённую/незавершённую"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr ""
|
||||
#~ "[tc] переключить консоль между развёрнутой/свёрнутой/скрытой/видимой."
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "[tm] переключить отображение метаданных заметки."
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "[mn] создать новую заметку"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "[mt] создать новую задачу"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "[mb] создать новый блокнот"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "[yn] копировать заметку в блокнот."
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "Переместить заметку в блокнот."
|
||||
|
||||
#~ msgid "Error"
|
||||
#~ msgstr "Ошибка"
|
||||
|
||||
#~ msgid "Could not download the update: %s"
|
||||
#~ msgstr "Не удалось загрузить обновление: %s"
|
||||
|
||||
|
@@ -15,63 +15,12 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
msgid "Give focus to next pane"
|
||||
msgstr "聚焦于下个面板"
|
||||
|
||||
msgid "Give focus to previous pane"
|
||||
msgstr "聚焦于上个面板"
|
||||
|
||||
msgid "Enter command line mode"
|
||||
msgstr "进入命令行模式"
|
||||
|
||||
msgid "Exit command line mode"
|
||||
msgstr "退出命令行模式"
|
||||
|
||||
msgid "Edit the selected note"
|
||||
msgstr "编辑所选笔记"
|
||||
|
||||
msgid "Cancel the current command."
|
||||
msgstr "取消当前命令。"
|
||||
|
||||
msgid "Exit the application."
|
||||
msgstr "退出程序。"
|
||||
|
||||
msgid "Delete the currently selected note or notebook."
|
||||
msgstr "删除当前所选笔记或笔记本。"
|
||||
|
||||
msgid "To delete a tag, untag the associated notes."
|
||||
msgstr "移除相关笔记的标签后才可删除此标签。"
|
||||
|
||||
msgid "Please select the note or notebook to be deleted first."
|
||||
msgstr "请选择最先删除的笔记或笔记本。"
|
||||
|
||||
msgid "Set a to-do as completed / not completed"
|
||||
msgstr "设置待办事项为已完成或未完成"
|
||||
|
||||
msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
msgstr "在最大化/最小化/隐藏/显示间切换[t]控制台[c]。"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "搜索"
|
||||
|
||||
msgid "[t]oggle note [m]etadata."
|
||||
msgstr "切换[t]笔记元数据[m]。"
|
||||
|
||||
msgid "[M]ake a new [n]ote"
|
||||
msgstr "创建[M]新笔记[n]"
|
||||
|
||||
msgid "[M]ake a new [t]odo"
|
||||
msgstr "创建[M]新待办事项[t]"
|
||||
|
||||
msgid "[M]ake a new note[b]ook"
|
||||
msgstr "创建[M]新笔记本[b]"
|
||||
|
||||
msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
msgstr "复制[Y]笔记[n]至笔记本。"
|
||||
|
||||
msgid "Move the note to a notebook."
|
||||
msgstr "移动笔记至笔记本。"
|
||||
|
||||
msgid "Press Ctrl+D or type \"exit\" to exit the application"
|
||||
msgstr "按Ctrl+D或输入\"exit\"退出程序"
|
||||
|
||||
@@ -228,13 +177,18 @@ msgstr "笔记已被保存。"
|
||||
msgid "Exits the application."
|
||||
msgstr "退出程序。"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Exports Joplin data to the given directory. By default, it will export the "
|
||||
"Exports Joplin data to the given path. By default, it will export the "
|
||||
"complete database including notebooks, notes, tags and resources."
|
||||
msgstr ""
|
||||
"导出Joplin数据至给定文件目录。默认为导出所有的数据库,包含笔记本、笔记、标签"
|
||||
"及资源。"
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Destination format: %s"
|
||||
msgstr "日期格式"
|
||||
|
||||
msgid "Exports only the given note."
|
||||
msgstr "仅导出给定笔记。"
|
||||
|
||||
@@ -247,6 +201,10 @@ msgstr "显示此笔记的地理定位URL地址。"
|
||||
msgid "Displays usage information."
|
||||
msgstr "显示使用信息。"
|
||||
|
||||
#, javascript-format
|
||||
msgid "For information on how to customise the shortcuts please visit %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shortcuts are not available in CLI mode."
|
||||
msgstr "快捷键在CLI模式下不可用。"
|
||||
|
||||
@@ -284,26 +242,21 @@ msgstr "按\":\"键进入命令行模式"
|
||||
msgid "To exit command line mode, press ESCAPE"
|
||||
msgstr "按ESC键退出命令行模式"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For the complete list of available keyboard shortcuts, type `help shortcuts`"
|
||||
"For the list of keyboard shortcuts and config options, type `help keymap`"
|
||||
msgstr "输入`help shortcuts`显示全部可用的快捷键列表。"
|
||||
|
||||
msgid "Imports an Evernote notebook file (.enex file)."
|
||||
msgstr "导入Evernote笔记本文件(.enex文件)。"
|
||||
msgid "Imports data into Joplin."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid "Source format: %s"
|
||||
msgstr "无以下命令:%s"
|
||||
|
||||
msgid "Do not ask for confirmation."
|
||||
msgstr "不再要求确认。"
|
||||
|
||||
#, javascript-format
|
||||
msgid "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
msgstr "文件\"%s\"将会被导入至现有笔记本\"%s\"。是否继续?"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
"it. Continue?"
|
||||
msgstr "将创建新笔记本\"%s\"并将文件\"%s\"导入至其中。是否继续?"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Found: %d."
|
||||
msgstr "已找到:%d条。"
|
||||
@@ -558,9 +511,20 @@ msgid ""
|
||||
"background and will be available soon."
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Exporting to \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "File"
|
||||
msgstr "文件"
|
||||
|
||||
msgid "Directory"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Importing from \"%s\" as \"%s\" format. Please wait..."
|
||||
msgstr ""
|
||||
|
||||
msgid "New note"
|
||||
msgstr "新笔记"
|
||||
|
||||
@@ -570,11 +534,16 @@ msgstr "新待办事项"
|
||||
msgid "New notebook"
|
||||
msgstr "新笔记本"
|
||||
|
||||
msgid "Import Evernote notes"
|
||||
msgstr "导入Evernote笔记"
|
||||
msgid "Import"
|
||||
msgstr "导入"
|
||||
|
||||
msgid "Evernote Export Files"
|
||||
msgstr "Evernote导出文件"
|
||||
#, fuzzy
|
||||
msgid "Export"
|
||||
msgstr "导入"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Hide %s"
|
||||
msgstr ""
|
||||
|
||||
msgid "Quit"
|
||||
msgstr "退出"
|
||||
@@ -594,6 +563,12 @@ msgstr "粘贴"
|
||||
msgid "Search in all the notes"
|
||||
msgstr "在所有笔记内搜索"
|
||||
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
msgid "Toggle editor layout"
|
||||
msgstr ""
|
||||
|
||||
msgid "Tools"
|
||||
msgstr "工具"
|
||||
|
||||
@@ -636,9 +611,6 @@ msgstr "确认"
|
||||
msgid "Cancel"
|
||||
msgstr "取消"
|
||||
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy, javascript-format
|
||||
msgid ""
|
||||
"Release notes:\n"
|
||||
@@ -765,6 +737,9 @@ msgstr "重命名笔记本:"
|
||||
msgid "Set alarm:"
|
||||
msgstr "设置提醒:"
|
||||
|
||||
msgid "Search"
|
||||
msgstr "搜索"
|
||||
|
||||
msgid "Layout"
|
||||
msgstr "布局"
|
||||
|
||||
@@ -821,6 +796,12 @@ msgstr "标签"
|
||||
msgid "Set alarm"
|
||||
msgstr "设置提醒"
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This note has no content. Click on \"%s\" to toggle the editor and edit the "
|
||||
"note."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "to-do"
|
||||
msgstr "新待办事项"
|
||||
@@ -842,9 +823,6 @@ msgstr "清除"
|
||||
msgid "OneDrive Login"
|
||||
msgstr "登陆OneDrive"
|
||||
|
||||
msgid "Import"
|
||||
msgstr "导入"
|
||||
|
||||
msgid "Options"
|
||||
msgstr "选项"
|
||||
|
||||
@@ -887,7 +865,7 @@ msgstr "未知标记:%s"
|
||||
msgid "File system"
|
||||
msgstr "文件系统"
|
||||
|
||||
msgid "Nextcloud (Beta)"
|
||||
msgid "Nextcloud"
|
||||
msgstr ""
|
||||
|
||||
msgid "OneDrive"
|
||||
@@ -896,7 +874,7 @@ msgstr "OneDrive"
|
||||
msgid "OneDrive Dev (For testing only)"
|
||||
msgstr "OneDrive开发员(仅测试用)"
|
||||
|
||||
msgid "WebDAV (Beta)"
|
||||
msgid "WebDAV"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
@@ -1031,9 +1009,17 @@ msgstr "浅色"
|
||||
msgid "Dark"
|
||||
msgstr "深色"
|
||||
|
||||
msgid "Show uncompleted todos on top of the lists"
|
||||
#, fuzzy
|
||||
msgid "Uncompleted to-dos on top"
|
||||
msgstr "在列表上方显示未完成的待办事项"
|
||||
|
||||
msgid "Sort notes by"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Reverse sort order"
|
||||
msgstr "反转排序顺序。"
|
||||
|
||||
msgid "Save geo-location with notes"
|
||||
msgstr "保存笔记时同时保存地理定位信息"
|
||||
|
||||
@@ -1055,7 +1041,15 @@ msgstr "创建新笔记。"
|
||||
msgid "Show tray icon"
|
||||
msgstr ""
|
||||
|
||||
msgid "Set application zoom percentage"
|
||||
msgid "Global zoom percentage"
|
||||
msgstr ""
|
||||
|
||||
msgid "Editor font family"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The font name will not be checked. If incorrect or empty, it will default to "
|
||||
"a generic monospace font."
|
||||
msgstr ""
|
||||
|
||||
msgid "Automatically update the application"
|
||||
@@ -1095,13 +1089,13 @@ msgid ""
|
||||
"See `sync.target`."
|
||||
msgstr "当文件系统同步开启时的同步路径。参考`sync.target`。"
|
||||
|
||||
msgid "Nexcloud WebDAV URL"
|
||||
msgid "Nextcloud WebDAV URL"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud username"
|
||||
msgid "Nextcloud username"
|
||||
msgstr ""
|
||||
|
||||
msgid "Nexcloud password"
|
||||
msgid "Nextcloud password"
|
||||
msgstr ""
|
||||
|
||||
msgid "WebDAV URL"
|
||||
@@ -1117,6 +1111,41 @@ msgstr ""
|
||||
msgid "Invalid option value: \"%s\". Possible values are: %s."
|
||||
msgstr "无效的选项值:\"%s\"。可用值为:%s。"
|
||||
|
||||
#, fuzzy
|
||||
msgid "Joplin Export File"
|
||||
msgstr "Evernote导出文件"
|
||||
|
||||
msgid "Markdown"
|
||||
msgstr ""
|
||||
|
||||
msgid "Joplin Export Directory"
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Evernote Export File"
|
||||
msgstr "Evernote导出文件"
|
||||
|
||||
#, javascript-format
|
||||
msgid "Cannot load \"%s\" module for format \"%s\""
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid "Please specify import format for %s"
|
||||
msgstr ""
|
||||
|
||||
#, javascript-format
|
||||
msgid ""
|
||||
"This item is currently encrypted: %s \"%s\". Please wait for all items to be "
|
||||
"decrypted and try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "There is no data to export."
|
||||
msgstr ""
|
||||
|
||||
#, fuzzy
|
||||
msgid "Please specify the notebook where the notes should be imported to."
|
||||
msgstr "请选择最先删除的笔记或笔记本。"
|
||||
|
||||
msgid "Items that cannot be synchronised"
|
||||
msgstr "项目无法被同步。"
|
||||
|
||||
@@ -1282,6 +1311,69 @@ msgstr "您当前没有任何笔记本。点击(+)按钮创建新笔记本。"
|
||||
msgid "Welcome"
|
||||
msgstr "欢迎"
|
||||
|
||||
#~ msgid "Imports an Evernote notebook file (.enex file)."
|
||||
#~ msgstr "导入Evernote笔记本文件(.enex文件)。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "File \"%s\" will be imported into existing notebook \"%s\". Continue?"
|
||||
#~ msgstr "文件\"%s\"将会被导入至现有笔记本\"%s\"。是否继续?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "New notebook \"%s\" will be created and file \"%s\" will be imported into "
|
||||
#~ "it. Continue?"
|
||||
#~ msgstr "将创建新笔记本\"%s\"并将文件\"%s\"导入至其中。是否继续?"
|
||||
|
||||
#~ msgid "Import Evernote notes"
|
||||
#~ msgstr "导入Evernote笔记"
|
||||
|
||||
#~ msgid "Give focus to next pane"
|
||||
#~ msgstr "聚焦于下个面板"
|
||||
|
||||
#~ msgid "Give focus to previous pane"
|
||||
#~ msgstr "聚焦于上个面板"
|
||||
|
||||
#~ msgid "Enter command line mode"
|
||||
#~ msgstr "进入命令行模式"
|
||||
|
||||
#~ msgid "Exit command line mode"
|
||||
#~ msgstr "退出命令行模式"
|
||||
|
||||
#~ msgid "Edit the selected note"
|
||||
#~ msgstr "编辑所选笔记"
|
||||
|
||||
#~ msgid "Cancel the current command."
|
||||
#~ msgstr "取消当前命令。"
|
||||
|
||||
#~ msgid "Exit the application."
|
||||
#~ msgstr "退出程序。"
|
||||
|
||||
#~ msgid "Delete the currently selected note or notebook."
|
||||
#~ msgstr "删除当前所选笔记或笔记本。"
|
||||
|
||||
#~ msgid "Set a to-do as completed / not completed"
|
||||
#~ msgstr "设置待办事项为已完成或未完成"
|
||||
|
||||
#~ msgid "[t]oggle [c]onsole between maximized/minimized/hidden/visible."
|
||||
#~ msgstr "在最大化/最小化/隐藏/显示间切换[t]控制台[c]。"
|
||||
|
||||
#~ msgid "[t]oggle note [m]etadata."
|
||||
#~ msgstr "切换[t]笔记元数据[m]。"
|
||||
|
||||
#~ msgid "[M]ake a new [n]ote"
|
||||
#~ msgstr "创建[M]新笔记[n]"
|
||||
|
||||
#~ msgid "[M]ake a new [t]odo"
|
||||
#~ msgstr "创建[M]新待办事项[t]"
|
||||
|
||||
#~ msgid "[M]ake a new note[b]ook"
|
||||
#~ msgstr "创建[M]新笔记本[b]"
|
||||
|
||||
#~ msgid "Copy ([Y]ank) the [n]ote to a notebook."
|
||||
#~ msgstr "复制[Y]笔记[n]至笔记本。"
|
||||
|
||||
#~ msgid "Move the note to a notebook."
|
||||
#~ msgstr "移动笔记至笔记本。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The target to synchonise to. If synchronising with the file system, set "
|
||||
#~ "`sync.2.path` to specify the target directory."
|
||||
|
45
CliClient/package-lock.json
generated
45
CliClient/package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "joplin",
|
||||
"version": "1.0.95",
|
||||
"version": "1.0.100",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
@@ -435,6 +435,14 @@
|
||||
"universalify": "0.1.1"
|
||||
}
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz",
|
||||
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||
"requires": {
|
||||
"minipass": "2.2.1"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
@@ -858,9 +866,9 @@
|
||||
}
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.0.4.tgz",
|
||||
"integrity": "sha512-sN4U9tIJtBRwKbwgFh9qJfrPIQ/GGTRr1MGqkgOeMTLy8/lM0FcWU//FqlnZ3Vb7gJ+Mxh3FOg1EklibdajbaQ==",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz",
|
||||
"integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
|
||||
"requires": {
|
||||
"minipass": "2.2.1"
|
||||
}
|
||||
@@ -1161,6 +1169,20 @@
|
||||
"semver": "5.4.1",
|
||||
"simple-get": "2.7.0",
|
||||
"tar": "3.2.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"tar": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-3.2.1.tgz",
|
||||
"integrity": "sha512-ZSzds1E0IqutvMU8HxjMaU8eB7urw2fGwTq88ukDOVuUIh0656l7/P7LiVPxhO5kS4flcRJQk8USG+cghQbTUQ==",
|
||||
"requires": {
|
||||
"chownr": "1.0.1",
|
||||
"minipass": "2.2.1",
|
||||
"minizlib": "1.1.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"yallist": "3.0.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"simple-concat": {
|
||||
@@ -2005,13 +2027,14 @@
|
||||
"integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0="
|
||||
},
|
||||
"tar": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-3.2.1.tgz",
|
||||
"integrity": "sha512-ZSzds1E0IqutvMU8HxjMaU8eB7urw2fGwTq88ukDOVuUIh0656l7/P7LiVPxhO5kS4flcRJQk8USG+cghQbTUQ==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-4.4.0.tgz",
|
||||
"integrity": "sha512-gJlTiiErwo96K904FnoYWl+5+FBgS+FimU6GMh66XLdLa55al8+d4jeDfPoGwSNHdtWI5FJP6xurmVqhBuGJpQ==",
|
||||
"requires": {
|
||||
"chownr": "1.0.1",
|
||||
"fs-minipass": "1.2.5",
|
||||
"minipass": "2.2.1",
|
||||
"minizlib": "1.0.4",
|
||||
"minizlib": "1.1.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"yallist": "3.0.2"
|
||||
}
|
||||
@@ -2057,9 +2080,9 @@
|
||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||
},
|
||||
"tkwidgets": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/tkwidgets/-/tkwidgets-0.5.21.tgz",
|
||||
"integrity": "sha512-gJfpYq3UM6AZ23ZM+D9BZ1PhsJLLHgjCOf487/lS9pO0uDdnkMcVXkkKEfRl00EyjPnGc88QZhEkVOvrtKsuPA==",
|
||||
"version": "0.5.25",
|
||||
"resolved": "https://registry.npmjs.org/tkwidgets/-/tkwidgets-0.5.25.tgz",
|
||||
"integrity": "sha512-f+12QbxNCLg9Jou5JoPJxATGLmzpDAQeM7QRTXvuqdEB/QvPD9+UlPUL7eYJP1QJv2zzT6EIWWbdpDkXPEtzCQ==",
|
||||
"requires": {
|
||||
"chalk": "2.3.0",
|
||||
"emphasize": "1.5.0",
|
||||
|
@@ -19,7 +19,7 @@
|
||||
],
|
||||
"owner": "Laurent Cozic"
|
||||
},
|
||||
"version": "1.0.95",
|
||||
"version": "1.0.100",
|
||||
"bin": {
|
||||
"joplin": "./main.js"
|
||||
},
|
||||
@@ -44,7 +44,6 @@
|
||||
"node-emoji": "^1.8.1",
|
||||
"node-fetch": "^1.7.1",
|
||||
"node-persist": "^2.1.0",
|
||||
"os-tmpdir": "^1.0.2",
|
||||
"promise": "^7.1.1",
|
||||
"proper-lockfile": "^2.0.1",
|
||||
"query-string": "4.3.4",
|
||||
@@ -57,8 +56,9 @@
|
||||
"string-padding": "^1.0.2",
|
||||
"string-to-stream": "^1.1.0",
|
||||
"strip-ansi": "^4.0.0",
|
||||
"tar": "^4.4.0",
|
||||
"tcp-port-used": "^0.1.2",
|
||||
"tkwidgets": "^0.5.21",
|
||||
"tkwidgets": "^0.5.25",
|
||||
"url-parse": "^1.2.0",
|
||||
"uuid": "^3.0.1",
|
||||
"word-wrap": "^1.2.3",
|
||||
|
@@ -9,7 +9,7 @@ rsync -a "$ROOT_DIR/build/locales/" "$BUILD_DIR/locales/"
|
||||
mkdir -p "$BUILD_DIR/data"
|
||||
|
||||
if [[ $TEST_FILE == "" ]]; then
|
||||
(cd "$ROOT_DIR" && npm test tests-build/synchronizer.js tests-build/encryption.js tests-build/ArrayUtils.js tests-build/models_Setting.js)
|
||||
(cd "$ROOT_DIR" && npm test tests-build/synchronizer.js tests-build/encryption.js tests-build/ArrayUtils.js tests-build/models_Setting.js tests-build/services_InteropService.js)
|
||||
else
|
||||
(cd "$ROOT_DIR" && npm test tests-build/$TEST_FILE.js)
|
||||
fi
|
252
CliClient/tests/services_InteropService.js
Normal file
252
CliClient/tests/services_InteropService.js
Normal file
@@ -0,0 +1,252 @@
|
||||
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 InteropService = require('lib/services/InteropService.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
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 fs = require('fs-extra');
|
||||
const ArrayUtils = require('lib/ArrayUtils');
|
||||
const ObjectUtils = require('lib/ObjectUtils');
|
||||
const { shim } = require('lib/shim.js');
|
||||
|
||||
process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
function exportDir() {
|
||||
return __dirname + '/export';
|
||||
}
|
||||
|
||||
function fieldsEqual(model1, model2, fieldNames) {
|
||||
for (let i = 0; i < fieldNames.length; i++) {
|
||||
const f = fieldNames[i];
|
||||
expect(model1[f]).toBe(model2[f], 'For key ' + f);
|
||||
}
|
||||
}
|
||||
|
||||
describe('services_InteropService', function() {
|
||||
|
||||
beforeEach(async (done) => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
|
||||
const dir = exportDir();
|
||||
await fs.remove(dir);
|
||||
await fs.mkdirp(dir);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should export and import folders', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
folder1 = await Folder.load(folder1.id);
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
await Folder.delete(folder1.id);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
// Check that a new folder, with a new ID, has been created
|
||||
|
||||
expect(await Folder.count()).toBe(1);
|
||||
let folder2 = (await Folder.all())[0];
|
||||
expect(folder2.id).not.toBe(folder1.id);
|
||||
expect(folder2.title).toBe(folder1.title);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
// As there was already a folder with the same title, check that the new one has been renamed
|
||||
|
||||
await Folder.delete(folder2.id);
|
||||
let folder3 = (await Folder.all())[0];
|
||||
expect(await Folder.count()).toBe(1);
|
||||
expect(folder3.title).not.toBe(folder2.title);
|
||||
|
||||
let fieldNames = Folder.fieldNames();
|
||||
fieldNames = ArrayUtils.removeElement(fieldNames, 'id');
|
||||
fieldNames = ArrayUtils.removeElement(fieldNames, 'title');
|
||||
|
||||
fieldsEqual(folder3, folder1, fieldNames);
|
||||
}));
|
||||
|
||||
it('should export and import folders and notes', 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() + '/test.jex';
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
await Folder.delete(folder1.id);
|
||||
await Note.delete(note1.id);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
expect(await Note.count()).toBe(1);
|
||||
let note2 = (await Note.all())[0];
|
||||
let folder2 = (await Folder.all())[0];
|
||||
|
||||
expect(note1.parent_id).not.toBe(note2.parent_id);
|
||||
expect(note1.id).not.toBe(note2.id);
|
||||
expect(note2.parent_id).toBe(folder2.id);
|
||||
|
||||
let fieldNames = Note.fieldNames();
|
||||
fieldNames = ArrayUtils.removeElement(fieldNames, 'id');
|
||||
fieldNames = ArrayUtils.removeElement(fieldNames, 'parent_id');
|
||||
|
||||
fieldsEqual(note1, note2, fieldNames);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
note2 = (await Note.all())[0];
|
||||
let note3 = (await Note.all())[1];
|
||||
|
||||
expect(note2.id).not.toBe(note3.id);
|
||||
expect(note2.parent_id).not.toBe(note3.parent_id);
|
||||
|
||||
fieldsEqual(note2, note3, fieldNames);
|
||||
}));
|
||||
|
||||
it('should export and import notes to specific folder', 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() + '/test.jex';
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
await Note.delete(note1.id);
|
||||
|
||||
await service.import({ path: filePath, destinationFolderId: folder1.id });
|
||||
|
||||
expect(await Note.count()).toBe(1);
|
||||
expect(await Folder.count()).toBe(1);
|
||||
|
||||
expect(await checkThrowAsync(async () => await service.import({ path: filePath, destinationFolderId: 'oops' }))).toBe(true);
|
||||
}));
|
||||
|
||||
it('should export and import tags', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
let tag1 = await Tag.save({ title: 'mon tag' });
|
||||
tag1 = await Tag.load(tag1.id);
|
||||
await Tag.addNote(tag1.id, note1.id);
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
await Folder.delete(folder1.id);
|
||||
await Note.delete(note1.id);
|
||||
await Tag.delete(tag1.id);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
expect(await Tag.count()).toBe(1);
|
||||
let tag2 = (await Tag.all())[0];
|
||||
let note2 = (await Note.all())[0];
|
||||
expect(tag1.id).not.toBe(tag2.id);
|
||||
|
||||
let fieldNames = Note.fieldNames();
|
||||
fieldNames = ArrayUtils.removeElement(fieldNames, 'id');
|
||||
fieldsEqual(tag1, tag2, fieldNames);
|
||||
|
||||
let noteIds = await Tag.noteIds(tag2.id);
|
||||
expect(noteIds.length).toBe(1);
|
||||
expect(noteIds[0]).toBe(note2.id);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
// If importing again, no new tag should be created as one with
|
||||
// the same name already existed. The newly imported note should
|
||||
// however go under that already existing tag.
|
||||
expect(await Tag.count()).toBe(1);
|
||||
noteIds = await Tag.noteIds(tag2.id);
|
||||
expect(noteIds.length).toBe(2);
|
||||
}));
|
||||
|
||||
it('should export and import resources', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
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');
|
||||
note1 = await Note.load(note1.id);
|
||||
let resourceIds = Note.linkedResourceIds(note1.body);
|
||||
let resource1 = await Resource.load(resourceIds[0]);
|
||||
|
||||
await service.export({ path: filePath });
|
||||
|
||||
await Note.delete(note1.id);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
expect(await Resource.count()).toBe(2);
|
||||
|
||||
let note2 = (await Note.all())[0];
|
||||
expect(note2.body).not.toBe(note1.body);
|
||||
resourceIds = Note.linkedResourceIds(note2.body);
|
||||
expect(resourceIds.length).toBe(1);
|
||||
let resource2 = await Resource.load(resourceIds[0]);
|
||||
expect(resource2.id).not.toBe(resource1.id);
|
||||
|
||||
let fieldNames = Note.fieldNames();
|
||||
fieldNames = ArrayUtils.removeElement(fieldNames, 'id');
|
||||
fieldsEqual(resource1, resource2, fieldNames);
|
||||
|
||||
const resourcePath1 = Resource.fullPath(resource1);
|
||||
const resourcePath2 = Resource.fullPath(resource2);
|
||||
|
||||
expect(resourcePath1).not.toBe(resourcePath2);
|
||||
expect(fileContentEqual(resourcePath1, resourcePath2)).toBe(true);
|
||||
}));
|
||||
|
||||
it('should export and import single notes', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
|
||||
await service.export({ path: filePath, sourceNoteIds: [note1.id] });
|
||||
|
||||
await Note.delete(note1.id);
|
||||
await Folder.delete(folder1.id);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
expect(await Note.count()).toBe(1);
|
||||
expect(await Folder.count()).toBe(1);
|
||||
|
||||
let folder2 = (await Folder.all())[0];
|
||||
expect(folder2.title).toBe('test');
|
||||
}));
|
||||
|
||||
it('should export and import single folders', asyncTest(async () => {
|
||||
const service = new InteropService();
|
||||
const filePath = exportDir() + '/test.jex';
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
let note1 = await Note.save({ title: 'ma note', parent_id: folder1.id });
|
||||
|
||||
await service.export({ path: filePath, sourceFolderIds: [folder1.id] });
|
||||
|
||||
await Note.delete(note1.id);
|
||||
await Folder.delete(folder1.id);
|
||||
|
||||
await service.import({ path: filePath });
|
||||
|
||||
expect(await Note.count()).toBe(1);
|
||||
expect(await Folder.count()).toBe(1);
|
||||
|
||||
let folder2 = (await Folder.all())[0];
|
||||
expect(folder2.title).toBe('folder1');
|
||||
}));
|
||||
|
||||
});
|
@@ -19,7 +19,7 @@ process.on('unhandledRejection', (reason, p) => {
|
||||
console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
|
||||
});
|
||||
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000; // The first test is slow because the database needs to be built
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 60000 + 30000; // The first test is slow because the database needs to be built
|
||||
|
||||
async function allItems() {
|
||||
let folders = await Folder.all();
|
||||
@@ -291,23 +291,30 @@ describe('Synchronizer', function() {
|
||||
}));
|
||||
|
||||
it('should delete local notes', asyncTest(async () => {
|
||||
// For these tests we pass the context around for each user. This is to make sure that the "deletedItemsProcessed"
|
||||
// property of the basicDelta() function is cleared properly at the end of a sync operation. If it is not cleared
|
||||
// it means items will no longer be deleted locally via sync.
|
||||
|
||||
let folder1 = await Folder.save({ title: "folder1" });
|
||||
let note1 = await Note.save({ title: "un", parent_id: folder1.id });
|
||||
await synchronizer().start();
|
||||
let note2 = await Note.save({ title: "deux", parent_id: folder1.id });
|
||||
let context1 = await synchronizer().start();
|
||||
|
||||
await switchClient(2);
|
||||
|
||||
await synchronizer().start();
|
||||
let context2 = await synchronizer().start();
|
||||
await Note.delete(note1.id);
|
||||
await synchronizer().start();
|
||||
context2 = await synchronizer().start({ context: context2 });
|
||||
|
||||
await switchClient(1);
|
||||
|
||||
await synchronizer().start();
|
||||
context1 = await synchronizer().start({ context: context1 });
|
||||
let items = await allItems();
|
||||
expect(items.length).toBe(1);
|
||||
expect(items.length).toBe(2);
|
||||
let deletedItems = await BaseItem.deletedItems(syncTargetId());
|
||||
expect(deletedItems.length).toBe(0);
|
||||
await Note.delete(note2.id);
|
||||
context1 = await synchronizer().start({ context: context1 });
|
||||
}));
|
||||
|
||||
it('should delete remote folder', asyncTest(async () => {
|
||||
@@ -992,7 +999,6 @@ describe('Synchronizer', function() {
|
||||
it('should create remote items with UTF-8 content', asyncTest(async () => {
|
||||
let folder = await Folder.save({ title: "Fahrräder" });
|
||||
await Note.save({ title: "Fahrräder", body: "Fahrräder", parent_id: folder.id });
|
||||
|
||||
let all = await allItems();
|
||||
|
||||
await synchronizer().start();
|
||||
|
@@ -56,7 +56,7 @@ const syncTargetId_ = SyncTargetRegistry.nameToId('nextcloud');
|
||||
//const syncTargetId_ = SyncTargetRegistry.nameToId('filesystem');
|
||||
const syncDir = __dirname + '/../tests/sync';
|
||||
|
||||
const sleepTime = syncTargetId_ == SyncTargetRegistry.nameToId('filesystem') ? 1001 : 10;//400;
|
||||
const sleepTime = syncTargetId_ == SyncTargetRegistry.nameToId('filesystem') ? 1001 : 100;//400;
|
||||
|
||||
console.info('Testing with sync target: ' + SyncTargetRegistry.idToName(syncTargetId_));
|
||||
|
||||
@@ -75,6 +75,8 @@ BaseItem.loadClass('MasterKey', MasterKey);
|
||||
Setting.setConstant('appId', 'net.cozic.joplin-cli');
|
||||
Setting.setConstant('appType', 'cli');
|
||||
|
||||
Setting.autoSaveEnabled = false;
|
||||
|
||||
function syncTargetId() {
|
||||
return syncTargetId_;
|
||||
}
|
||||
@@ -262,6 +264,7 @@ function fileApi() {
|
||||
|
||||
fileApi_.setLogger(logger);
|
||||
fileApi_.setSyncTargetId(syncTargetId_);
|
||||
fileApi_.requestRepeatCount_ = 0;
|
||||
return fileApi_;
|
||||
}
|
||||
|
||||
|
@@ -41,13 +41,14 @@ class ElectronAppWrapper {
|
||||
const windowState = windowStateKeeper({
|
||||
defaultWidth: 800,
|
||||
defaultHeight: 600,
|
||||
file: 'window-state-' + this.env_ + '.json',
|
||||
});
|
||||
|
||||
const windowOptions = {
|
||||
'x': windowState.x,
|
||||
'y': windowState.y,
|
||||
'width': windowState.width,
|
||||
'height': windowState.height,
|
||||
x: windowState.x,
|
||||
y: windowState.y,
|
||||
width: windowState.width,
|
||||
height: windowState.height,
|
||||
};
|
||||
|
||||
// Linux icon workaround for bug https://github.com/electron-userland/electron-builder/issues/2098
|
||||
@@ -63,7 +64,7 @@ class ElectronAppWrapper {
|
||||
}))
|
||||
|
||||
// Uncomment this to view errors if the application does not start
|
||||
if (this.env_ === 'dev') this.win_.webContents.openDevTools();
|
||||
// if (this.env_ === 'dev') this.win_.webContents.openDevTools();
|
||||
|
||||
this.win_.on('close', (event) => {
|
||||
// If it's on macOS, the app is completely closed only if the user chooses to close the app (willQuitApp_ will be true)
|
||||
@@ -78,7 +79,7 @@ class ElectronAppWrapper {
|
||||
this.win_ = null;
|
||||
} else {
|
||||
event.preventDefault();
|
||||
this.win_.hide();
|
||||
this.hide();
|
||||
}
|
||||
} else {
|
||||
if (this.trayShown() && !this.willQuitApp_) {
|
||||
@@ -117,6 +118,12 @@ class ElectronAppWrapper {
|
||||
return !!this.tray_;
|
||||
}
|
||||
|
||||
// This method is used in macOS only to hide the whole app (and not just the main window)
|
||||
// including the menu bar. This follows the macOS way of hidding an app.
|
||||
hide() {
|
||||
this.electronApp_.hide();
|
||||
}
|
||||
|
||||
buildDir() {
|
||||
if (this.buildDir_) return this.buildDir_;
|
||||
let dir = __dirname + '/build';
|
||||
@@ -129,10 +136,24 @@ class ElectronAppWrapper {
|
||||
return dir;
|
||||
}
|
||||
|
||||
trayIconFilename_() {
|
||||
let output = '';
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
output = 'macos-16x16Template.png'; // Electron Template Image format
|
||||
} else {
|
||||
output = '16x16.png';
|
||||
}
|
||||
|
||||
if (this.env_ === 'dev') output = '16x16-dev.png'
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
// Note: this must be called only after the "ready" event of the app has been dispatched
|
||||
createTray(contextMenu) {
|
||||
try {
|
||||
this.tray_ = new Tray(this.buildDir() + '/icons/16x16.png')
|
||||
this.tray_ = new Tray(this.buildDir() + '/icons/' + this.trayIconFilename_())
|
||||
this.tray_.setToolTip(this.electronApp_.getName())
|
||||
this.tray_.setContextMenu(contextMenu)
|
||||
|
||||
@@ -150,11 +171,32 @@ class ElectronAppWrapper {
|
||||
this.tray_ = null;
|
||||
}
|
||||
|
||||
ensureSingleInstance() {
|
||||
if (this.env_ === 'dev') return false;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const alreadyRunning = this.electronApp_.makeSingleInstance((commandLine, workingDirectory) => {
|
||||
const win = this.window();
|
||||
if (!win) return;
|
||||
if (win.isMinimized()) win.restore();
|
||||
win.show();
|
||||
win.focus();
|
||||
});
|
||||
|
||||
if (alreadyRunning) this.electronApp_.quit();
|
||||
|
||||
resolve(alreadyRunning);
|
||||
});
|
||||
}
|
||||
|
||||
async start() {
|
||||
// Since we are doing other async things before creating the window, we might miss
|
||||
// the "ready" event. So we use the function below to make sure that the app is ready.
|
||||
await this.waitForElectronAppReady();
|
||||
|
||||
const alreadyRunning = await this.ensureSingleInstance();
|
||||
if (alreadyRunning) return;
|
||||
|
||||
this.createWindow();
|
||||
|
||||
this.electronApp_.on('before-quit', () => {
|
||||
|
51
ElectronClient/app/InteropServiceHelper.js
Normal file
51
ElectronClient/app/InteropServiceHelper.js
Normal file
@@ -0,0 +1,51 @@
|
||||
const { _ } = require('lib/locale');
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
const InteropService = require('lib/services/InteropService');
|
||||
|
||||
class InteropServiceHelper {
|
||||
|
||||
static async export(dispatch, module, options = null) {
|
||||
if (!options) options = {};
|
||||
|
||||
let path = null;
|
||||
|
||||
if (module.target === 'file') {
|
||||
path = bridge().showSaveDialog({
|
||||
filters: [{ name: module.description, extensions: [module.fileExtension]}]
|
||||
});
|
||||
} else {
|
||||
path = bridge().showOpenDialog({
|
||||
properties: ['openDirectory', 'createDirectory'],
|
||||
});
|
||||
}
|
||||
|
||||
if (!path || (Array.isArray(path) && !path.length)) return;
|
||||
|
||||
if (Array.isArray(path)) path = path[0];
|
||||
|
||||
dispatch({
|
||||
type: 'WINDOW_COMMAND',
|
||||
name: 'showModalMessage',
|
||||
message: _('Exporting to "%s" as "%s" format. Please wait...', path, module.format),
|
||||
});
|
||||
|
||||
const exportOptions = {};
|
||||
exportOptions.path = path;
|
||||
exportOptions.format = module.format;
|
||||
if (options.sourceFolderIds) exportOptions.sourceFolderIds = options.sourceFolderIds;
|
||||
if (options.sourceNoteIds) exportOptions.sourceNoteIds = options.sourceNoteIds;
|
||||
|
||||
const service = new InteropService();
|
||||
const result = await service.export(exportOptions);
|
||||
|
||||
console.info('Export result: ', result);
|
||||
|
||||
dispatch({
|
||||
type: 'WINDOW_COMMAND',
|
||||
name: 'hideModalMessage',
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = InteropServiceHelper;
|
@@ -20,6 +20,8 @@ const packageInfo = require('./packageInfo.js');
|
||||
const AlarmService = require('lib/services/AlarmService.js');
|
||||
const AlarmServiceDriverNode = require('lib/services/AlarmServiceDriverNode');
|
||||
const DecryptionWorker = require('lib/services/DecryptionWorker');
|
||||
const InteropService = require('lib/services/InteropService');
|
||||
const InteropServiceHelper = require('./InteropServiceHelper.js');
|
||||
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
const Menu = bridge().Menu;
|
||||
@@ -144,6 +146,10 @@ class Application extends BaseApplication {
|
||||
this.updateTray();
|
||||
}
|
||||
|
||||
if (action.type == 'SETTING_UPDATE_ONE' && action.key == 'style.editor.fontFamily' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
this.updateEditorFont();
|
||||
}
|
||||
|
||||
if (['NOTE_UPDATE_ONE', 'NOTE_DELETE', 'FOLDER_UPDATE_ONE', 'FOLDER_DELETE'].indexOf(action.type) >= 0) {
|
||||
if (!await reg.syncTarget().syncStarted()) reg.scheduleSync();
|
||||
}
|
||||
@@ -175,6 +181,94 @@ class Application extends BaseApplication {
|
||||
updateMenu(screen) {
|
||||
if (this.lastMenuScreen_ === screen) return;
|
||||
|
||||
const sortNoteItems = [];
|
||||
const sortNoteOptions = Setting.enumOptions('notes.sortOrder.field');
|
||||
for (let field in sortNoteOptions) {
|
||||
if (!sortNoteOptions.hasOwnProperty(field)) continue;
|
||||
sortNoteItems.push({
|
||||
label: sortNoteOptions[field],
|
||||
screens: ['Main'],
|
||||
type: 'checkbox',
|
||||
checked: Setting.value('notes.sortOrder.field') === field,
|
||||
click: () => {
|
||||
Setting.setValue('notes.sortOrder.field', field);
|
||||
this.refreshMenu();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const importItems = [];
|
||||
const exportItems = [];
|
||||
const ioService = new InteropService();
|
||||
const ioModules = ioService.modules();
|
||||
for (let i = 0; i < ioModules.length; i++) {
|
||||
const module = ioModules[i];
|
||||
if (module.type === 'exporter') {
|
||||
exportItems.push({
|
||||
label: module.format + ' - ' + module.description,
|
||||
screens: ['Main'],
|
||||
click: async () => {
|
||||
await InteropServiceHelper.export(this.dispatch.bind(this), module);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
for (let j = 0; j < module.sources.length; j++) {
|
||||
const moduleSource = module.sources[j];
|
||||
let label = [module.format + ' - ' + module.description];
|
||||
if (module.sources.length > 1) {
|
||||
label.push('(' + (moduleSource === 'file' ? _('File') : _('Directory')) + ')');
|
||||
}
|
||||
importItems.push({
|
||||
label: label.join(' '),
|
||||
screens: ['Main'],
|
||||
click: async () => {
|
||||
let path = null;
|
||||
|
||||
const selectedFolderId = this.store().getState().selectedFolderId;
|
||||
|
||||
if (moduleSource === 'file') {
|
||||
path = bridge().showOpenDialog({
|
||||
filters: [{ name: module.description, extensions: [module.fileExtension]}]
|
||||
});
|
||||
} else {
|
||||
path = bridge().showOpenDialog({
|
||||
properties: ['openDirectory', 'createDirectory'],
|
||||
});
|
||||
}
|
||||
|
||||
if (!path || (Array.isArray(path) && !path.length)) return;
|
||||
|
||||
if (Array.isArray(path)) path = path[0];
|
||||
|
||||
this.dispatch({
|
||||
type: 'WINDOW_COMMAND',
|
||||
name: 'showModalMessage',
|
||||
message: _('Importing from "%s" as "%s" format. Please wait...', path, module.format),
|
||||
});
|
||||
|
||||
const importOptions = {};
|
||||
importOptions.path = path;
|
||||
importOptions.format = module.format;
|
||||
importOptions.destinationFolderId = !module.isNoteArchive && moduleSource === 'file' ? selectedFolderId : null;
|
||||
|
||||
const service = new InteropService();
|
||||
try {
|
||||
const result = await service.import(importOptions);
|
||||
console.info('Import result: ', result);
|
||||
} catch (error) {
|
||||
bridge().showErrorMessageBox(error.message);
|
||||
}
|
||||
|
||||
this.dispatch({
|
||||
type: 'WINDOW_COMMAND',
|
||||
name: 'hideModalMessage',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const template = [
|
||||
{
|
||||
label: _('File'),
|
||||
@@ -200,6 +294,7 @@ class Application extends BaseApplication {
|
||||
}
|
||||
}, {
|
||||
label: _('New notebook'),
|
||||
accelerator: 'CommandOrControl+B',
|
||||
screens: ['Main'],
|
||||
click: () => {
|
||||
this.dispatch({
|
||||
@@ -209,25 +304,39 @@ class Application extends BaseApplication {
|
||||
}
|
||||
}, {
|
||||
type: 'separator',
|
||||
}, {
|
||||
label: _('Import Evernote notes'),
|
||||
click: () => {
|
||||
const filePaths = bridge().showOpenDialog({
|
||||
properties: ['openFile', 'createDirectory'],
|
||||
filters: [
|
||||
{ name: _('Evernote Export Files'), extensions: ['enex'] },
|
||||
]
|
||||
});
|
||||
if (!filePaths || !filePaths.length) return;
|
||||
// }, {
|
||||
// label: _('Import Evernote notes'),
|
||||
// click: () => {
|
||||
// const filePaths = bridge().showOpenDialog({
|
||||
// properties: ['openFile', 'createDirectory'],
|
||||
// filters: [
|
||||
// { name: _('Evernote Export Files'), extensions: ['enex'] },
|
||||
// ]
|
||||
// });
|
||||
// if (!filePaths || !filePaths.length) return;
|
||||
|
||||
this.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Import',
|
||||
props: {
|
||||
filePath: filePaths[0],
|
||||
},
|
||||
});
|
||||
}
|
||||
// this.dispatch({
|
||||
// type: 'NAV_GO',
|
||||
// routeName: 'Import',
|
||||
// props: {
|
||||
// filePath: filePaths[0],
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
}, {
|
||||
label: _('Import'),
|
||||
submenu: importItems,
|
||||
}, {
|
||||
label: _('Export'),
|
||||
submenu: exportItems,
|
||||
}, {
|
||||
type: 'separator',
|
||||
platforms: ['darwin'],
|
||||
}, {
|
||||
label: _('Hide %s', 'Joplin'),
|
||||
platforms: ['darwin'],
|
||||
accelerator: 'CommandOrControl+H',
|
||||
click: () => { bridge().electronApp().hide() }
|
||||
}, {
|
||||
type: 'separator',
|
||||
}, {
|
||||
@@ -239,17 +348,17 @@ class Application extends BaseApplication {
|
||||
label: _('Edit'),
|
||||
submenu: [{
|
||||
label: _('Copy'),
|
||||
screens: ['Main', 'OneDriveLogin'],
|
||||
screens: ['Main', 'OneDriveLogin', 'Config', 'EncryptionConfig'],
|
||||
role: 'copy',
|
||||
accelerator: 'CommandOrControl+C',
|
||||
}, {
|
||||
label: _('Cut'),
|
||||
screens: ['Main', 'OneDriveLogin'],
|
||||
screens: ['Main', 'OneDriveLogin', 'Config', 'EncryptionConfig'],
|
||||
role: 'cut',
|
||||
accelerator: 'CommandOrControl+X',
|
||||
}, {
|
||||
label: _('Paste'),
|
||||
screens: ['Main', 'OneDriveLogin'],
|
||||
screens: ['Main', 'OneDriveLogin', 'Config', 'EncryptionConfig'],
|
||||
role: 'paste',
|
||||
accelerator: 'CommandOrControl+V',
|
||||
}, {
|
||||
@@ -266,6 +375,42 @@ class Application extends BaseApplication {
|
||||
});
|
||||
},
|
||||
}],
|
||||
}, {
|
||||
label: _('View'),
|
||||
submenu: [{
|
||||
label: _('Toggle editor layout'),
|
||||
screens: ['Main'],
|
||||
accelerator: 'CommandOrControl+L',
|
||||
click: () => {
|
||||
this.dispatch({
|
||||
type: 'WINDOW_COMMAND',
|
||||
name: 'toggleVisiblePanes',
|
||||
});
|
||||
}
|
||||
}, {
|
||||
type: 'separator',
|
||||
screens: ['Main'],
|
||||
}, {
|
||||
label: Setting.settingMetadata('notes.sortOrder.field').label(),
|
||||
screens: ['Main'],
|
||||
submenu: sortNoteItems,
|
||||
}, {
|
||||
label: Setting.settingMetadata('notes.sortOrder.reverse').label(),
|
||||
type: 'checkbox',
|
||||
checked: Setting.value('notes.sortOrder.reverse'),
|
||||
screens: ['Main'],
|
||||
click: () => {
|
||||
Setting.setValue('notes.sortOrder.reverse', !Setting.value('notes.sortOrder.reverse'));
|
||||
},
|
||||
}, {
|
||||
label: Setting.settingMetadata('uncompletedTodosOnTop').label(),
|
||||
type: 'checkbox',
|
||||
checked: Setting.value('uncompletedTodosOnTop'),
|
||||
screens: ['Main'],
|
||||
click: () => {
|
||||
Setting.setValue('uncompletedTodosOnTop', !Setting.value('uncompletedTodosOnTop'));
|
||||
},
|
||||
}],
|
||||
}, {
|
||||
label: _('Tools'),
|
||||
submenu: [{
|
||||
@@ -289,6 +434,7 @@ class Application extends BaseApplication {
|
||||
}
|
||||
},{
|
||||
label: _('General Options'),
|
||||
accelerator: 'CommandOrControl+,',
|
||||
click: () => {
|
||||
this.dispatch({
|
||||
type: 'NAV_GO',
|
||||
@@ -305,7 +451,7 @@ class Application extends BaseApplication {
|
||||
}, {
|
||||
label: _('Check for updates...'),
|
||||
click: () => {
|
||||
bridge().checkForUpdates(false, this.checkForUpdateLoggerPath());
|
||||
bridge().checkForUpdates(false, bridge().window(), this.checkForUpdateLoggerPath());
|
||||
}
|
||||
}, {
|
||||
label: _('About Joplin'),
|
||||
@@ -317,8 +463,8 @@ class Application extends BaseApplication {
|
||||
'Copyright © 2016-2018 Laurent Cozic',
|
||||
_('%s %s (%s, %s)', p.name, p.version, Setting.value('env'), process.platform),
|
||||
];
|
||||
bridge().showMessageBox({
|
||||
message: message.join('\n'),
|
||||
bridge().showInfoMessageBox(message.join('\n'), {
|
||||
icon: bridge().electronApp().buildDir() + '/icons/32x32.png',
|
||||
});
|
||||
}
|
||||
}]
|
||||
@@ -334,10 +480,13 @@ class Application extends BaseApplication {
|
||||
}
|
||||
|
||||
function removeUnwantedItems(template, screen) {
|
||||
const platform = shim.platformName();
|
||||
|
||||
let output = [];
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
const t = Object.assign({}, template[i]);
|
||||
if (t.screens && t.screens.indexOf(screen) < 0) continue;
|
||||
if (t.platforms && t.platforms.indexOf(platform) < 0) continue;
|
||||
if (t.submenu) t.submenu = removeUnwantedItems(t.submenu, screen);
|
||||
if (('submenu' in t) && isEmptyMenu(t.submenu)) continue;
|
||||
output.push(t);
|
||||
@@ -375,6 +524,21 @@ class Application extends BaseApplication {
|
||||
}
|
||||
}
|
||||
|
||||
updateEditorFont() {
|
||||
const fontFamilies = [];
|
||||
if (Setting.value('style.editor.fontFamily')) fontFamilies.push('"' + Setting.value('style.editor.fontFamily') + '"');
|
||||
fontFamilies.push('monospace');
|
||||
|
||||
// The '*' and '!important' parts are necessary to make sure Russian text is displayed properly
|
||||
// https://github.com/laurent22/joplin/issues/155
|
||||
|
||||
const css = '.ace_editor * { font-family: ' + fontFamilies.join(', ') + ' !important; }';
|
||||
const styleTag = document.createElement('style');
|
||||
styleTag.type = 'text/css';
|
||||
styleTag.appendChild(document.createTextNode(css));
|
||||
document.head.appendChild(styleTag);
|
||||
}
|
||||
|
||||
async start(argv) {
|
||||
argv = await super.start(argv);
|
||||
|
||||
@@ -422,13 +586,14 @@ class Application extends BaseApplication {
|
||||
if (shim.isWindows() || shim.isMac()) {
|
||||
const runAutoUpdateCheck = () => {
|
||||
if (Setting.value('autoUpdateEnabled')) {
|
||||
bridge().checkForUpdates(true, this.checkForUpdateLoggerPath());
|
||||
bridge().checkForUpdates(true, bridge().window(), this.checkForUpdateLoggerPath());
|
||||
}
|
||||
}
|
||||
|
||||
// Initial check on startup
|
||||
setTimeout(() => { runAutoUpdateCheck() }, 5000);
|
||||
// For those who leave the app always open
|
||||
setInterval(() => { runAutoUpdateCheck() }, 2 * 60 * 60 * 1000);
|
||||
// Then every x hours
|
||||
setInterval(() => { runAutoUpdateCheck() }, 12 * 60 * 60 * 1000);
|
||||
}
|
||||
|
||||
this.updateTray();
|
||||
|
@@ -43,7 +43,7 @@ class Bridge {
|
||||
const {dialog} = require('electron');
|
||||
if (!options) options = {};
|
||||
if (!('defaultPath' in options) && this.lastSelectedPath_) options.defaultPath = this.lastSelectedPath_;
|
||||
const filePath = dialog.showSaveDialog(options);
|
||||
const filePath = dialog.showSaveDialog(this.window(), options);
|
||||
if (filePath) {
|
||||
this.lastSelectedPath_ = filePath;
|
||||
}
|
||||
@@ -55,27 +55,30 @@ class Bridge {
|
||||
if (!options) options = {};
|
||||
if (!('defaultPath' in options) && this.lastSelectedPath_) options.defaultPath = this.lastSelectedPath_;
|
||||
if (!('createDirectory' in options)) options.createDirectory = true;
|
||||
const filePaths = dialog.showOpenDialog(options);
|
||||
const filePaths = dialog.showOpenDialog(this.window(), options);
|
||||
if (filePaths && filePaths.length) {
|
||||
this.lastSelectedPath_ = dirname(filePaths[0]);
|
||||
}
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
showMessageBox(options) {
|
||||
// Don't use this directly - call one of the showXxxxxxxMessageBox() instead
|
||||
showMessageBox_(window, options) {
|
||||
const {dialog} = require('electron');
|
||||
return dialog.showMessageBox(options);
|
||||
const nativeImage = require('electron').nativeImage
|
||||
if (!window) window = this.window();
|
||||
return dialog.showMessageBox(window, options);
|
||||
}
|
||||
|
||||
showErrorMessageBox(message) {
|
||||
return this.showMessageBox({
|
||||
return this.showMessageBox_(this.window(), {
|
||||
type: 'error',
|
||||
message: message,
|
||||
});
|
||||
}
|
||||
|
||||
showConfirmMessageBox(message) {
|
||||
const result = this.showMessageBox({
|
||||
const result = this.showMessageBox_(this.window(), {
|
||||
type: 'question',
|
||||
message: message,
|
||||
buttons: [_('OK'), _('Cancel')],
|
||||
@@ -83,12 +86,12 @@ class Bridge {
|
||||
return result === 0;
|
||||
}
|
||||
|
||||
showInfoMessageBox(message) {
|
||||
const result = this.showMessageBox({
|
||||
showInfoMessageBox(message, options = {}) {
|
||||
const result = this.showMessageBox_(this.window(), Object.assign({}, {
|
||||
type: 'info',
|
||||
message: message,
|
||||
buttons: [_('OK')],
|
||||
});
|
||||
}, options));
|
||||
return result === 0;
|
||||
}
|
||||
|
||||
@@ -108,26 +111,9 @@ class Bridge {
|
||||
return require('electron').shell.openItem(fullPath)
|
||||
}
|
||||
|
||||
async checkForUpdatesAndNotify(logFilePath) {
|
||||
if (!this.autoUpdater_) {
|
||||
this.autoUpdateLogger_ = new Logger();
|
||||
this.autoUpdateLogger_.addTarget('file', { path: logFilePath });
|
||||
this.autoUpdateLogger_.setLevel(Logger.LEVEL_DEBUG);
|
||||
this.autoUpdateLogger_.info('checkForUpdatesAndNotify: Initializing...');
|
||||
this.autoUpdater_ = require("electron-updater").autoUpdater;
|
||||
this.autoUpdater_.logger = this.autoUpdateLogger_;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.autoUpdater_.checkForUpdatesAndNotify();
|
||||
} catch (error) {
|
||||
this.autoUpdateLogger_.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
checkForUpdates(inBackground, logFilePath) {
|
||||
checkForUpdates(inBackground, window, logFilePath) {
|
||||
const { checkForUpdates } = require('./checkForUpdates.js');
|
||||
checkForUpdates(inBackground, logFilePath);
|
||||
checkForUpdates(inBackground, window, logFilePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
ElectronClient/app/build/icons/16x16-dev.png
Normal file
BIN
ElectronClient/app/build/icons/16x16-dev.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 611 B |
BIN
ElectronClient/app/build/icons/16x16@2x.png
Normal file
BIN
ElectronClient/app/build/icons/16x16@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
ElectronClient/app/build/icons/16x16@3x.png
Normal file
BIN
ElectronClient/app/build/icons/16x16@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
ElectronClient/app/build/icons/32x32@3.png
Normal file
BIN
ElectronClient/app/build/icons/32x32@3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
BIN
ElectronClient/app/build/icons/macos-16x16Template.png
Normal file
BIN
ElectronClient/app/build/icons/macos-16x16Template.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 348 B |
BIN
ElectronClient/app/build/icons/macos-16x16Template@2x.png
Normal file
BIN
ElectronClient/app/build/icons/macos-16x16Template@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 504 B |
@@ -5,21 +5,19 @@ const { _ } = require('lib/locale.js');
|
||||
|
||||
let autoUpdateLogger_ = new Logger();
|
||||
let checkInBackground_ = false;
|
||||
let isCheckingForUpdate_ = false;
|
||||
let parentWindow_ = null;
|
||||
|
||||
// Note: Electron Builder's autoUpdater is incredibly buggy so currently it's only used
|
||||
// to detect if a new version is present. If it is, the download link is simply opened
|
||||
// in a new browser window.
|
||||
autoUpdater.autoDownload = false;
|
||||
|
||||
autoUpdater.on('error', (error) => {
|
||||
autoUpdateLogger_.error(error);
|
||||
if (checkInBackground_) return;
|
||||
dialog.showErrorBox(_('Error'), error == null ? "unknown" : (error.stack || error).toString())
|
||||
})
|
||||
|
||||
function htmlToText_(html) {
|
||||
let output = html.replace(/\n/g, '');
|
||||
output = output.replace(/<li>/g, '- ');
|
||||
output = output.replace(/<p>/g, '');
|
||||
output = output.replace(/<\/p>/g, '\n');
|
||||
output = output.replace(/<\/li>/g, '\n');
|
||||
output = output.replace(/<ul>/g, '');
|
||||
output = output.replace(/<\/ul>/g, '');
|
||||
@@ -28,49 +26,108 @@ function htmlToText_(html) {
|
||||
return output;
|
||||
}
|
||||
|
||||
autoUpdater.on('update-available', (info) => {
|
||||
if (!info.version || !info.path) {
|
||||
if (checkInBackground_) return;
|
||||
dialog.showErrorBox(_('Error'), ('Could not get version info: ' + JSON.stringify(info)));
|
||||
return;
|
||||
function showErrorMessageBox(message) {
|
||||
return dialog.showMessageBox(parentWindow_, {
|
||||
type: 'error',
|
||||
message: message,
|
||||
});
|
||||
}
|
||||
|
||||
function onCheckStarted() {
|
||||
autoUpdateLogger_.info('checkForUpdates: Starting...');
|
||||
isCheckingForUpdate_ = true;
|
||||
}
|
||||
|
||||
function onCheckEnded() {
|
||||
autoUpdateLogger_.info('checkForUpdates: Done.');
|
||||
isCheckingForUpdate_ = false;
|
||||
}
|
||||
|
||||
autoUpdater.on('error', (error) => {
|
||||
autoUpdateLogger_.error(error);
|
||||
if (checkInBackground_) return onCheckEnded();
|
||||
|
||||
let msg = error == null ? "unknown" : (error.stack || error).toString();
|
||||
// Error messages can be very long even without stack trace so shorten
|
||||
// then so that the dialog box doesn't take the whole screen.
|
||||
msg = msg.substr(0,512).replace(/\\n/g, '\n');
|
||||
showErrorMessageBox(msg)
|
||||
|
||||
onCheckEnded();
|
||||
})
|
||||
|
||||
function findDownloadFilename_(info) {
|
||||
// { version: '1.0.64',
|
||||
// files:
|
||||
// [ { url: 'Joplin-1.0.64-mac.zip',
|
||||
// sha512: 'OlemXqhq/fSifx7EutvMzfoCI/1kGNl10i8nkvACEDfVXwP8hankDBXEC0+GxSArsZuxOh3U1+C+4j72SfIUew==' },
|
||||
// { url: 'Joplin-1.0.64.dmg',
|
||||
// sha512: 'jAewQQoJ3nCaOj8hWDgf0sc3LBbAWQtiKqfTflK8Hc3Dh7fAy9jRHfFAZKFUZ9ll95Bun0DVsLq8wLSUrdsMXw==',
|
||||
// size: 77104485 } ],
|
||||
// path: 'Joplin-1.0.64-mac.zip',
|
||||
// sha512: 'OlemXqhq/fSifx7EutvMzfoCI/1kGNl10i8nkvACEDfVXwP8hankDBXEC0+GxSArsZuxOh3U1+C+4j72SfIUew==',
|
||||
// releaseDate: '2018-02-16T00:13:01.634Z',
|
||||
// releaseName: 'v1.0.64',
|
||||
// releaseNotes: '<p>Still more fixes and im...' }
|
||||
|
||||
if (!info) return null;
|
||||
|
||||
if (!info.files) {
|
||||
// info.path seems to contain a default, though not a good one,
|
||||
// so the loop below if preferable to find the right file.
|
||||
return info.path;
|
||||
}
|
||||
|
||||
const downloadUrl = 'https://github.com/laurent22/joplin/releases/download/v' + info.version + '/' + info.path;
|
||||
for (let i = 0; i < info.files.length; i++) {
|
||||
const f = info.files[i].url; // Annoyingly this is called "url" but it's obviously not a url, so hopefully it won't change later on and become one.
|
||||
if (f.indexOf('.exe') >= 0) return f;
|
||||
if (f.indexOf('.dmg') >= 0) return f;
|
||||
}
|
||||
|
||||
return info.path;
|
||||
}
|
||||
|
||||
autoUpdater.on('update-available', (info) => {
|
||||
const filename = findDownloadFilename_(info);
|
||||
|
||||
if (!info.version || !filename) {
|
||||
if (checkInBackground_) return onCheckEnded();
|
||||
showErrorMessageBox(('Could not get version info: ' + JSON.stringify(info)));
|
||||
return onCheckEnded();
|
||||
}
|
||||
|
||||
const downloadUrl = 'https://github.com/laurent22/joplin/releases/download/v' + info.version + '/' + filename;
|
||||
|
||||
let releaseNotes = info.releaseNotes + '';
|
||||
if (releaseNotes) releaseNotes = '\n\n' + _('Release notes:\n\n%s', htmlToText_(releaseNotes));
|
||||
|
||||
dialog.showMessageBox({
|
||||
const buttonIndex = dialog.showMessageBox(parentWindow_, {
|
||||
type: 'info',
|
||||
message: _('An update is available, do you want to download it now?' + releaseNotes),
|
||||
buttons: [_('Yes'), _('No')]
|
||||
}, (buttonIndex) => {
|
||||
if (buttonIndex === 0) {
|
||||
require('electron').shell.openExternal(downloadUrl);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
onCheckEnded();
|
||||
|
||||
if (buttonIndex === 0) require('electron').shell.openExternal(downloadUrl);
|
||||
})
|
||||
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
if (checkInBackground_) return;
|
||||
|
||||
if (checkInBackground_) return onCheckEnded();
|
||||
dialog.showMessageBox({ message: _('Current version is up-to-date.') })
|
||||
onCheckEnded();
|
||||
})
|
||||
|
||||
// autoUpdater.on('update-downloaded', () => {
|
||||
// dialog.showMessageBox({ message: _('New version downloaded - application will quit now and update...') }, () => {
|
||||
// setTimeout(() => {
|
||||
// try {
|
||||
// autoUpdater.quitAndInstall();
|
||||
// } catch (error) {
|
||||
// autoUpdateLogger_.error(error);
|
||||
// dialog.showErrorBox(_('Error'), _('Could not install the update: %s', error.message));
|
||||
// }
|
||||
// }, 100);
|
||||
// })
|
||||
// })
|
||||
function checkForUpdates(inBackground, window, logFilePath) {
|
||||
if (isCheckingForUpdate_) {
|
||||
autoUpdateLogger_.info('checkForUpdates: Skipping check because it is already running');
|
||||
return;
|
||||
}
|
||||
|
||||
parentWindow_ = window;
|
||||
|
||||
onCheckStarted();
|
||||
|
||||
function checkForUpdates(inBackground, logFilePath) {
|
||||
if (logFilePath && !autoUpdateLogger_.targets().length) {
|
||||
autoUpdateLogger_ = new Logger();
|
||||
autoUpdateLogger_.addTarget('file', { path: logFilePath });
|
||||
@@ -85,7 +142,8 @@ function checkForUpdates(inBackground, logFilePath) {
|
||||
autoUpdater.checkForUpdates()
|
||||
} catch (error) {
|
||||
autoUpdateLogger_.error(error);
|
||||
if (!checkInBackground_) dialog.showErrorBox(_('Error'), error.message);
|
||||
if (!checkInBackground_) showErrorMessageBox(error.message);
|
||||
onCheckEnded();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -40,10 +40,6 @@ class ConfigScreenComponent extends React.Component {
|
||||
});
|
||||
}
|
||||
|
||||
output.sort((a, b) => {
|
||||
return a.label.toLowerCase() < b.label.toLowerCase() ? -1 : +1;
|
||||
});
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -63,6 +59,12 @@ class ConfigScreenComponent extends React.Component {
|
||||
display: 'inline-block',
|
||||
};
|
||||
|
||||
const descriptionStyle = Object.assign({}, theme.textStyle, {
|
||||
color: theme.colorFaded,
|
||||
marginTop: 5,
|
||||
fontStyle: 'italic',
|
||||
});
|
||||
|
||||
const updateSettingValue = (key, value) => {
|
||||
return shared.updateSettingValue(this, key, value);
|
||||
}
|
||||
@@ -71,6 +73,13 @@ class ConfigScreenComponent extends React.Component {
|
||||
|
||||
const md = Setting.settingMetadata(key);
|
||||
|
||||
const descriptionText = Setting.keyDescription(key, 'desktop');
|
||||
const descriptionComp = descriptionText ? (
|
||||
<div style={descriptionStyle}>
|
||||
{descriptionText}
|
||||
</div>
|
||||
) : null;
|
||||
|
||||
if (md.isEnum) {
|
||||
let items = [];
|
||||
const settingOptions = md.options();
|
||||
@@ -86,6 +95,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
<select value={value} style={controlStyle} onChange={(event) => { updateSettingValue(key, event.target.value) }}>
|
||||
{items}
|
||||
</select>
|
||||
{ descriptionComp }
|
||||
</div>
|
||||
);
|
||||
} else if (md.type === Setting.TYPE_BOOL) {
|
||||
@@ -100,6 +110,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
<div key={key+value.toString()} style={rowStyle}>
|
||||
<div style={controlStyle}>
|
||||
<input id={'setting_checkbox_' + key} type="checkbox" checked={!!value} onChange={(event) => { onCheckboxClick(event) }}/><label onClick={(event) => { onCheckboxClick(event) }} style={labelStyle} htmlFor={'setting_checkbox_' + key}>{md.label()}</label>
|
||||
{ descriptionComp }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -115,6 +126,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
<div key={key} style={rowStyle}>
|
||||
<div style={labelStyle}><label>{md.label()}</label></div>
|
||||
<input type={inputType} style={inputStyle} value={this.state.settings[key]} onChange={(event) => {onTextChange(event)}} />
|
||||
{ descriptionComp }
|
||||
</div>
|
||||
);
|
||||
} else if (md.type === Setting.TYPE_INT) {
|
||||
@@ -126,6 +138,7 @@ class ConfigScreenComponent extends React.Component {
|
||||
<div key={key} style={rowStyle}>
|
||||
<div style={labelStyle}><label>{md.label()}</label></div>
|
||||
<input type="number" style={controlStyle} value={this.state.settings[key]} onChange={(event) => {onNumChange(event)}} min={md.minimum} max={md.maximum} step={md.step}/>
|
||||
{ descriptionComp }
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
|
@@ -22,6 +22,10 @@ class MainScreenComponent extends React.Component {
|
||||
componentWillMount() {
|
||||
this.setState({
|
||||
promptOptions: null,
|
||||
modalLayer: {
|
||||
visible: false,
|
||||
message: '',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -163,6 +167,12 @@ class MainScreenComponent extends React.Component {
|
||||
}
|
||||
},
|
||||
});
|
||||
} else if (command.name === 'toggleVisiblePanes') {
|
||||
this.toggleVisiblePanes();
|
||||
} else if (command.name === 'showModalMessage') {
|
||||
this.setState({ modalLayer: { visible: true, message: command.message } });
|
||||
} else if (command.name === 'hideModalMessage') {
|
||||
this.setState({ modalLayer: { visible: false, message: '' } });
|
||||
} else if (command.name === 'editAlarm') {
|
||||
const note = await Note.load(command.noteId);
|
||||
|
||||
@@ -263,6 +273,17 @@ class MainScreenComponent extends React.Component {
|
||||
height: height,
|
||||
};
|
||||
|
||||
this.styles_.modalLayer = Object.assign({}, theme.textStyle, {
|
||||
zIndex: 10000,
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
backgroundColor: theme.backgroundColorTransparent,
|
||||
width: width - 20,
|
||||
height: height - 20,
|
||||
padding: 10,
|
||||
});
|
||||
|
||||
return this.styles_;
|
||||
}
|
||||
|
||||
@@ -309,9 +330,7 @@ class MainScreenComponent extends React.Component {
|
||||
title: _('Layout'),
|
||||
iconName: 'fa-columns',
|
||||
enabled: !!notes.length,
|
||||
onClick: () => {
|
||||
this.toggleVisiblePanes();
|
||||
},
|
||||
onClick: () => { this.doCommand({ name: 'toggleVisiblePanes' }) },
|
||||
});
|
||||
|
||||
if (!this.promptOnClose_) {
|
||||
@@ -353,8 +372,12 @@ class MainScreenComponent extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
const modalLayerStyle = Object.assign({}, styles.modalLayer, { display: this.state.modalLayer.visible ? 'block' : 'none' });
|
||||
|
||||
return (
|
||||
<div style={style}>
|
||||
<div style={modalLayerStyle}>{this.state.modalLayer.message}</div>
|
||||
|
||||
<PromptDialog
|
||||
autocomplete={promptOptions && ('autocomplete' in promptOptions) ? promptOptions.autocomplete : null}
|
||||
defaultValue={promptOptions && promptOptions.value ? promptOptions.value : ''}
|
||||
|
@@ -9,6 +9,8 @@ const { bridge } = require('electron').remote.require('./bridge');
|
||||
const Menu = bridge().Menu;
|
||||
const MenuItem = bridge().MenuItem;
|
||||
const eventManager = require('../eventManager');
|
||||
const InteropService = require('lib/services/InteropService');
|
||||
const InteropServiceHelper = require('../InteropServiceHelper.js');
|
||||
|
||||
class NoteListComponent extends React.Component {
|
||||
|
||||
@@ -91,6 +93,12 @@ class NoteListComponent extends React.Component {
|
||||
eventManager.emit('noteTypeToggle', { noteId: note.id });
|
||||
}
|
||||
}}));
|
||||
|
||||
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, { sourceNoteIds: noteIds });
|
||||
}}));
|
||||
}
|
||||
|
||||
menu.append(new MenuItem({label: _('Delete'), click: async () => {
|
||||
|
@@ -320,10 +320,7 @@ class NoteTextComponent extends React.Component {
|
||||
bridge().openItem(filePath);
|
||||
});
|
||||
} else {
|
||||
bridge().showMessageBox({
|
||||
type: 'error',
|
||||
message: _('Unsupported link or message: %s', msg),
|
||||
});
|
||||
bridge().showErrorMessageBox(_('Unsupported link or message: %s', msg));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -600,7 +597,14 @@ class NoteTextComponent extends React.Component {
|
||||
},
|
||||
postMessageSyntax: 'ipcRenderer.sendToHost',
|
||||
};
|
||||
const html = this.mdToHtml().render(body, theme, mdOptions);
|
||||
|
||||
let bodyToRender = body;
|
||||
if (!bodyToRender.trim() && visiblePanes.indexOf('viewer') >= 0 && visiblePanes.indexOf('editor') < 0) {
|
||||
// Fixes https://github.com/laurent22/joplin/issues/217
|
||||
bodyToRender = '*' + _('This note has no content. Click on "%s" to toggle the editor and edit the note.', _('Layout')) + '*';
|
||||
}
|
||||
|
||||
const html = this.mdToHtml().render(bodyToRender, theme, mdOptions);
|
||||
this.webview_.send('setHtml', html);
|
||||
}
|
||||
|
||||
|
@@ -54,10 +54,7 @@ class OneDriveLoginScreenComponent extends React.Component {
|
||||
this.props.dispatch({ type: 'NAV_BACK' });
|
||||
reg.scheduleSync(0);
|
||||
} catch (error) {
|
||||
bridge().showMessageBox({
|
||||
type: 'error',
|
||||
message: 'Could not login to OneDrive. Please try again.\n\n' + error.message + "\n\n" + url.match(/.{1,64}/g).join('\n'),
|
||||
});
|
||||
bridge().showErrorMessageBox('Could not login to OneDrive. Please try again.\n\n' + error.message + "\n\n" + url.match(/.{1,64}/g).join('\n'));
|
||||
}
|
||||
|
||||
this.authCode_ = null;
|
||||
|
@@ -11,6 +11,7 @@ const { themeStyle } = require('../theme.js');
|
||||
const { bridge } = require('electron').remote.require('./bridge');
|
||||
const Menu = bridge().Menu;
|
||||
const MenuItem = bridge().MenuItem;
|
||||
const InteropServiceHelper = require('../InteropServiceHelper.js');
|
||||
|
||||
class SideBarComponent extends React.Component {
|
||||
|
||||
@@ -136,7 +137,17 @@ class SideBarComponent extends React.Component {
|
||||
name: 'renameFolder',
|
||||
id: itemId,
|
||||
});
|
||||
}}))
|
||||
}}));
|
||||
|
||||
menu.append(new MenuItem({ type: 'separator' }));
|
||||
|
||||
const InteropService = require('lib/services/InteropService.js');
|
||||
|
||||
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] });
|
||||
}}));
|
||||
}
|
||||
|
||||
menu.popup(bridge().window());
|
||||
|
@@ -17,11 +17,6 @@
|
||||
.smalltalk .page {
|
||||
max-width: 30em;
|
||||
}
|
||||
.ace_editor * {
|
||||
/* Necessary to make sure Russian text is displayed properly */
|
||||
/* https://github.com/laurent22/joplin/issues/155 */
|
||||
font-family: monospace !important;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
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
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
@@ -1,7 +1,6 @@
|
||||
var locales = {};
|
||||
locales['en_GB'] = require('./en_GB.json');
|
||||
locales['de_DE'] = require('./de_DE.json');
|
||||
locales['es_CR'] = require('./es_CR.json');
|
||||
locales['es_ES'] = require('./es_ES.json');
|
||||
locales['eu'] = require('./eu.json');
|
||||
locales['fr_FR'] = require('./fr_FR.json');
|
||||
|
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2044
ElectronClient/app/package-lock.json
generated
2044
ElectronClient/app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "Joplin",
|
||||
"version": "1.0.63",
|
||||
"version": "1.0.70",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
@@ -43,10 +43,12 @@
|
||||
},
|
||||
"homepage": "https://github.com/laurent22/joplin#readme",
|
||||
"devDependencies": {
|
||||
"ajv": "^6.2.0",
|
||||
"app-builder-bin": "^1.5.0",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"electron": "^1.7.11",
|
||||
"electron-builder": "^19.45.4"
|
||||
"electron-builder": "^20.2.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"7zip-bin-mac": "^1.0.1",
|
||||
@@ -59,7 +61,7 @@
|
||||
"base-64": "^0.1.0",
|
||||
"electron-context-menu": "^0.9.1",
|
||||
"electron-log": "^2.2.11",
|
||||
"electron-updater": "^2.16.1",
|
||||
"electron-updater": "^2.18.2",
|
||||
"electron-window-state": "^4.1.1",
|
||||
"follow-redirects": "^1.2.5",
|
||||
"form-data": "^2.3.1",
|
||||
@@ -91,6 +93,7 @@
|
||||
"sqlite3": "^3.1.13",
|
||||
"string-padding": "^1.0.2",
|
||||
"string-to-stream": "^1.1.0",
|
||||
"tar": "^4.4.0",
|
||||
"tcp-port-used": "^0.1.2",
|
||||
"url-parse": "^1.2.0",
|
||||
"uuid": "^3.1.0",
|
||||
|
@@ -7,6 +7,7 @@ const globalStyle = {
|
||||
itemMarginTop: 10,
|
||||
itemMarginBottom: 10,
|
||||
backgroundColor: "#ffffff",
|
||||
backgroundColorTransparent: 'rgba(255,255,255,0.9)',
|
||||
oddBackgroundColor: "#dddddd",
|
||||
color: "#222222", // For regular text
|
||||
colorError: "red",
|
||||
|
@@ -90,6 +90,8 @@ async function main(argv) {
|
||||
if (linuxUrl) content = content.replace(/(https:\/\/github.com\/laurent22\/joplin\/releases\/download\/.*?\.AppImage)/, linuxUrl);
|
||||
|
||||
setReadmeContent(content);
|
||||
|
||||
console.info("git pull && git add -A && git commit -m 'Update readme downloads' && git push")
|
||||
}
|
||||
|
||||
main(process.argv).catch((error) => {
|
||||
|
84
README.md
84
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
Joplin is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified either from the applications directly or from your own text editor. The notes are in [Markdown format](https://daringfireball.net/projects/markdown/basics).
|
||||
|
||||
Notes exported from Evernote via .enex files [can be imported](#importing-notes-from-evernote) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.).
|
||||
Notes exported from Evernote via .enex files [can be imported](#importing) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
|
||||
|
||||
The notes can be [synchronised](#synchronisation) with various targets including [Nextcloud](https://nextcloud.com/), the file system (for example with a network directory) or with Microsoft OneDrive. When synchronising the notes, notebooks, tags and other metadata are saved to plain text files which can be easily inspected, backed up and moved around.
|
||||
|
||||
@@ -18,15 +18,15 @@ Three types of applications are available: for the **desktop** (Windows, macOS a
|
||||
|
||||
Operating System | Download
|
||||
-----------------|--------
|
||||
Windows | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.62/Joplin-Setup-1.0.62.exe'><img alt='Get it on Windows' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeWindows.png'/></a>
|
||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.62/Joplin-1.0.62.dmg'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeMacOS.png'/></a>
|
||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.62/Joplin-1.0.62-x86_64.AppImage'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeLinux.png'/></a>
|
||||
Windows | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.70/Joplin-Setup-1.0.70.exe'><img alt='Get it on Windows' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeWindows.png'/></a>
|
||||
macOS | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.70/Joplin-1.0.70.dmg'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeMacOS.png'/></a>
|
||||
Linux | <a href='https://github.com/laurent22/joplin/releases/download/v1.0.70/Joplin-1.0.70-x86_64.AppImage'><img alt='Get it on macOS' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeLinux.png'/></a>
|
||||
|
||||
## Mobile applications
|
||||
|
||||
Operating System | Download | Alt. Download
|
||||
-----------------|----------|----------------
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeAndroid.png'/></a> | or [Download APK File](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.97/joplin-v1.0.97.apk)
|
||||
Android | <a href='https://play.google.com/store/apps/details?id=net.cozic.joplin&utm_source=GitHub&utm_campaign=README&pcampaignid=MKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeAndroid.png'/></a> | or [Download APK File](https://github.com/laurent22/joplin-android/releases/download/android-v1.0.104/joplin-v1.0.104.apk)
|
||||
iOS | <a href='https://itunes.apple.com/us/app/joplin/id1315599797'><img alt='Get it on the App Store' height="40px" src='https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/BadgeIOS.png'/></a> | -
|
||||
|
||||
## Terminal application
|
||||
@@ -51,20 +51,23 @@ For usage information, please refer to the full [Joplin Terminal Application Doc
|
||||
# Features
|
||||
|
||||
- Desktop, mobile and terminal applications.
|
||||
- Import Enex files (Evernote export format)
|
||||
- End To End Encryption (E2EE)
|
||||
- Synchronisation with various services, including NextCloud, WebDAV and OneDrive. Dropbox is planned.
|
||||
- Import Enex files (Evernote export format) and Markdown files.
|
||||
- Export JEX files (Joplin Export format) and raw files.
|
||||
- Support notes, to-dos, tags and notebooks.
|
||||
- Sort notes by multiple criteria - title, updated time, etc.
|
||||
- Support for alarms (notifications) in mobile and desktop applications.
|
||||
- Offline first, so the entire data is always available on the device even without an internet connection.
|
||||
- Synchronisation with various services, including NextCloud, WebDAV and OneDrive. Dropbox is planned.
|
||||
- End To End Encryption (E2EE)
|
||||
- Synchronises to a plain text format, which can be easily manipulated, backed up, or exported to a different format.
|
||||
- Markdown notes, which are rendered with images and formatting in the desktop and mobile applications. Support for extra features such as math notation and checkboxes.
|
||||
- File attachment support - images are displayed, and other files are linked and can be opened in the relevant application.
|
||||
- Search functionality.
|
||||
- Geo-location support.
|
||||
- Supports multiple languages
|
||||
|
||||
# Importing notes from Evernote
|
||||
# Importing
|
||||
|
||||
## Importing from Evernote
|
||||
|
||||
Joplin was designed as a replacement for Evernote and so can import complete Evernote notebooks, as well as notes, tags, resources (attached files) and note metadata (such as author, geo-location, etc.) via ENEX files. In terms of data, the only two things that might slightly differ are:
|
||||
|
||||
@@ -74,17 +77,29 @@ Joplin was designed as a replacement for Evernote and so can import complete Eve
|
||||
|
||||
To import Evernote data, first export your Evernote notebooks to ENEX files as described [here](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restore-import-notes-and-notebooks). Then follow these steps:
|
||||
|
||||
On the **desktop application**, open the "File" menu, click "Import Evernote notes" and select your ENEX file. This will open a new screen which will display the import progress. The notes will be imported into a new separate notebook (so that, in case of a mistake, the notes are not mixed up with any existing notes). If needed then can then be moved to a different notebook, or the notebook can be renamed, etc.
|
||||
On the **desktop application**, open File > Import > ENEX and select your file. The notes will be imported into a new separate notebook. If needed they can then be moved to a different notebook, or the notebook can be renamed, etc.
|
||||
|
||||
On the **terminal application**, in [command-line mode](/terminal#command-line-mode), type `import-enex /path/to/file.enex`. This will import the notes into a new notebook named after the filename.
|
||||
On the **terminal application**, in [command-line mode](/terminal#command-line-mode), type `import /path/to/file.enex`. This will import the notes into a new notebook named after the filename.
|
||||
|
||||
# Importing notes from other applications
|
||||
## Importing from Markdown files
|
||||
|
||||
Joplin can import notes from plain Markdown file. You can either import a complete directory of Markdown files or individual files.
|
||||
|
||||
On the **desktop application**, open File > Import > MD and select your Markdown file or directory.
|
||||
|
||||
On the **terminal application**, in [command-line mode](/terminal#command-line-mode), type `import --format md /path/to/file.md` or `import --format md /path/to/directory/`.
|
||||
|
||||
## Importing from other applications
|
||||
|
||||
In general the way to import notes from any application into Joplin is to convert the notes to ENEX files (Evernote format) and to import these ENEX files into Joplin using the method above. Most note-taking applications support ENEX files so it should be relatively straightforward. For help about specific applications, see below:
|
||||
|
||||
* Standard Notes: Please see [this tutorial](https://programadorwebvalencia.com/migrate-notes-from-standard-notes-to-joplin/)
|
||||
* Tomboy Notes: Export the notes to ENEX files [as described here](https://askubuntu.com/questions/243691/how-can-i-export-my-tomboy-notes-into-evernote/608551) for example, and import these ENEX files into Joplin.
|
||||
|
||||
# Exporting
|
||||
|
||||
Joplin can export to the JEX format (Joplin Export file), which is a tar file that can contain multiple notes, notebooks, etc. This is a lossless format in that all the notes, but also metadata such as geo-location, updated time, tags, etc. are preserved. This format is convenient for backup purposes and can be re-imported into Joplin. A "raw" format is also available. This is the same as the JEX format except that the data is saved to a directory and each item represented by a single file.
|
||||
|
||||
# Synchronisation
|
||||
|
||||
One of the goals of Joplin was to avoid being tied to any particular company or service, whether it is Evernote, Google or Microsoft. As such the synchronisation is designed without any hard dependency to any particular service. Most of the synchronisation process is done at an abstract level and access to external services, such as Nextcloud or OneDrive, is done via lightweight drivers. It is easy to support new services by creating simple drivers that provide a filesystem-like interface, i.e. the ability to read, write, delete and list items. It is also simple to switch from one service to another or to even sync to multiple services at once. Each note, notebook, tags, as well as the relation between items is transmitted as plain text files during synchronisation, which means the data can also be moved to a different application, can be easily backed up, inspected, etc.
|
||||
@@ -108,10 +123,13 @@ If synchronisation does not work, please consult the logs in the app profile dir
|
||||
|
||||
Select the "WebDAV" synchronisation target and follow the same instructions as for Nextcloud above.
|
||||
|
||||
Known compatible services that use WebDAV:
|
||||
WebDAV-compatible services that are known to work with Joplin:
|
||||
|
||||
- [Box.com](https://www.box.com/)
|
||||
- [DriveHQ](https://www.drivehq.com)
|
||||
- [OwnCloud](https://owncloud.org/)
|
||||
- [Seafile](https://www.seafile.com/)
|
||||
- [Stack](https://www.transip.nl/stack/)
|
||||
- [Zimbra](https://www.zimbra.com/)
|
||||
|
||||
## OneDrive synchronisation
|
||||
@@ -176,9 +194,9 @@ Here is an example with the Markdown and rendered result side by side:
|
||||
|
||||
Checkboxes can be added like so:
|
||||
|
||||
-[ ] Milk
|
||||
-[ ] Rice
|
||||
-[ ] Eggs
|
||||
- [ ] Milk
|
||||
- [ ] Rice
|
||||
- [ ] Eggs
|
||||
|
||||
The checkboxes can then be ticked in the mobile and desktop applications.
|
||||
|
||||
@@ -195,34 +213,32 @@ Joplin is currently available in the languages below. If you would like to contr
|
||||
- In Poedit, open this .pot file, go into the Catalog menu and click Configuration. Change "Country" and "Language" to your own country and language.
|
||||
- From then you can translate the file. Once it is done, please either [open a pull request](https://github.com/laurent22/joplin/pulls) or send the file to [this address](https://raw.githubusercontent.com/laurent22/joplin/master/Assets/Adresse.png).
|
||||
|
||||
To **update a translation**, follow the same steps as above but instead of getting the .pot file, get the .po file for your language from there: https://github.com/laurent22/joplin/tree/master/CliClient/locales
|
||||
|
||||
This translation will apply to the three applications - desktop, mobile and terminal.
|
||||
|
||||
To **update a translation**, follow the same steps as above but instead of getting the .pot file, get the .po file for your language from the table below.
|
||||
|
||||
Current translations:
|
||||
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
| Language | Code | Last translator | Percent done
|
||||
| Language | Po File | Last translator | Percent done
|
||||
---|---|---|---|---
|
||||
 | Basque | eu | juan.abasolo@ehu.eus | 89%
|
||||
 | Croatian | hr_HR | Hrvoje Mandić <trbuhom@net.hr> | 72%
|
||||
 | Deutsch | de_DE | Tobias Strobel <git@strobeltobias.de> | 91%
|
||||
 | English | en_GB | | 100%
|
||||
 | Español | es_ES | Lucas Vieites | 79%
|
||||
 | Español (Costa Rica) | es_CR | | 68%
|
||||
 | Français | fr_FR | Laurent Cozic | 100%
|
||||
 | Italiano | it_IT | | 75%
|
||||
 | Nederlands | nl_BE | | 89%
|
||||
 | Português (Brasil) | pt_BR | | 74%
|
||||
 | Русский | ru_RU | Artyom Karlov <artyom.karlov@gmail.com> | 94%
|
||||
 | 中文 (简体) | zh_CN | RCJacH <RCJacH@outlook.com> | 75%
|
||||
 | 日本語 | ja_JP | | 73%
|
||||
 | Basque | [eu](https://github.com/laurent22/joplin/blob/master/CliClient/locales/eu.po) | juan.abasolo@ehu.eus | 81%
|
||||
 | Croatian | [hr_HR](https://github.com/laurent22/joplin/blob/master/CliClient/locales/hr_HR.po) | Hrvoje Mandić <trbuhom@net.hr> | 66%
|
||||
 | Deutsch | [de_DE](https://github.com/laurent22/joplin/blob/master/CliClient/locales/de_DE.po) | Tobias Strobel <git@strobeltobias.de> | 83%
|
||||
 | English | [en_GB](https://github.com/laurent22/joplin/blob/master/CliClient/locales/en_GB.po) | | 100%
|
||||
 | Español | [es_ES](https://github.com/laurent22/joplin/blob/master/CliClient/locales/es_ES.po) | Fernando Martín <f@mrtn.es> | 93%
|
||||
 | Français | [fr_FR](https://github.com/laurent22/joplin/blob/master/CliClient/locales/fr_FR.po) | Laurent Cozic | 100%
|
||||
 | Italiano | [it_IT](https://github.com/laurent22/joplin/blob/master/CliClient/locales/it_IT.po) | | 68%
|
||||
 | Nederlands | [nl_BE](https://github.com/laurent22/joplin/blob/master/CliClient/locales/nl_BE.po) | | 82%
|
||||
 | Português (Brasil) | [pt_BR](https://github.com/laurent22/joplin/blob/master/CliClient/locales/pt_BR.po) | | 66%
|
||||
 | Русский | [ru_RU](https://github.com/laurent22/joplin/blob/master/CliClient/locales/ru_RU.po) | Artyom Karlov <artyom.karlov@gmail.com> | 85%
|
||||
 | 中文 (简体) | [zh_CN](https://github.com/laurent22/joplin/blob/master/CliClient/locales/zh_CN.po) | RCJacH <RCJacH@outlook.com> | 68%
|
||||
 | 日本語 | [ja_JP](https://github.com/laurent22/joplin/blob/master/CliClient/locales/ja_JP.po) | | 66%
|
||||
<!-- LOCALE-TABLE-AUTO-GENERATED -->
|
||||
|
||||
# Known bugs
|
||||
|
||||
- Non-alphabetical characters such as Chinese or Arabic might create glitches in the terminal on Windows. This is a limitation of the current Windows console.
|
||||
- Auto-update is not working in the Linux desktop application.
|
||||
- While the mobile can sync and load tags, it is not currently possible to create new ones. The desktop and terminal apps can create, delete and edit tags.
|
||||
|
||||
# License
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
Joplin is a free, open source note taking and to-do application, which can handle a large number of notes organised into notebooks. The notes are searchable, can be copied, tagged and modified with your own text editor.
|
||||
|
||||
Notes exported from Evernote via .enex files [can be imported](#importing-notes-from-evernote) into Joplin, including the formatted content (which is converted to markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.).
|
||||
Notes exported from Evernote via .enex files [can be imported](http://joplin.cozic.net/#importing) into Joplin, including the formatted content (which is converted to Markdown), resources (images, attachments, etc.) and complete metadata (geolocation, updated time, created time, etc.). Plain Markdown files can also be imported.
|
||||
|
||||
The notes can be [synchronised](#synchronisation) with various targets including the file system (for example with a network directory) or with Microsoft OneDrive. When synchronising the notes, notebooks, tags and other metadata are saved to plain text files which can be easily inspected, backed up and moved around.
|
||||
|
||||
@@ -35,7 +35,7 @@ To start it, type `demo-joplin`.
|
||||
|
||||
# Usage
|
||||
|
||||
To start the application type `joplin`. This will open the user interface, which has three main panes: Notebooks, Notes and the text of the current note. There are also additional panels that can be toggled on and off via [shortcuts](#available-shortcuts).
|
||||
To start the application type `joplin`. This will open the user interface, which has three main panes: Notebooks, Notes and the text of the current note. There are also additional panels that can be toggled on and off via [shortcuts](#shortcuts).
|
||||
|
||||
<img src="https://raw.githubusercontent.com/laurent22/joplin/master/docs/images/ScreenshotTerminalCaptions.png" height="450px">
|
||||
|
||||
@@ -45,11 +45,11 @@ Joplin user interface is partly based on the text editor Vim and offers two diff
|
||||
|
||||
### Normal mode
|
||||
|
||||
Allows moving from one pane to another using the `Tab` and `Shift-Tab` keys, and to select/view notes using the arrow keys. Text area can be scrolled using the arrow keys too. Press `Enter` to edit a note. Various other [shortcuts](#available-shortcuts) are available.
|
||||
Allows moving from one pane to another using the `Tab` and `Shift-Tab` keys, and to select/view notes using the arrow keys. Text area can be scrolled using the arrow keys too. Press `Enter` to edit a note. Various other [shortcuts](#shortcuts) are available.
|
||||
|
||||
### Command-line mode
|
||||
|
||||
Press `:` to enter command line mode. From there, the Joplin commands such as `mknote` or `search` are available. See the [full list of commands](#available-commands).
|
||||
Press `:` to enter command line mode. From there, the Joplin commands such as `mknote` or `search` are available. See the [full list of commands](#commands).
|
||||
|
||||
It is possible to refer to a note or notebook by title or ID. However the simplest way is to refer to the currently selected item using one of these shortcuts:
|
||||
|
||||
@@ -96,7 +96,7 @@ The complete usage information is available from command-line mode, by typing on
|
||||
Command | Description
|
||||
--------|-------------------
|
||||
`help` | General help information
|
||||
`help shortcuts` | Lists the available shortcuts
|
||||
`help keymap` | Lists the available shortcuts
|
||||
`help [command]` | Displays information about a particular command
|
||||
|
||||
If the help is not fully visible, press `Tab` multiple times till the console is in focus and use the arrow keys or page up/down to scroll the text.
|
||||
@@ -106,7 +106,7 @@ If the help is not fully visible, press `Tab` multiple times till the console is
|
||||
To import Evernote data, follow these steps:
|
||||
|
||||
* First, export your Evernote notebooks to ENEX files as described [here](https://help.evernote.com/hc/en-us/articles/209005557-How-to-back-up-export-and-restore-import-notes-and-notebooks).
|
||||
* In Joplin, in [command-line mode](#command-line-mode), type `import-enex /path/to/file.enex`. This will import the notes into a new notebook named after the filename.
|
||||
* In Joplin, in [command-line mode](#command-line-mode), type `import /path/to/file.enex`. This will import the notes into a new notebook named after the filename.
|
||||
* Then repeat the process for each notebook that needs to be imported.
|
||||
|
||||
# Synchronisation
|
||||
@@ -124,7 +124,7 @@ You will need to set the `sync.target` config variable and all the `sync.5.path`
|
||||
:config sync.5.username YOUR_USERNAME
|
||||
:config sync.5.password YOUR_PASSWORD
|
||||
|
||||
If synchronisation does not work, please consult the logs in the app profile directory - it is often due to a misconfigured URL or password. The log should indicate what the exact issue is.
|
||||
If synchronisation does not work, please consult the logs in the app profile directory (`~/.config/joplin`)- it is often due to a misconfigured URL or password. The log should indicate what the exact issue is.
|
||||
|
||||
## WebDAV synchronisation
|
||||
|
||||
@@ -175,29 +175,82 @@ Give a new title to the note:
|
||||
|
||||
$ joplin set fe889 title "New title"
|
||||
|
||||
# Available shortcuts
|
||||
# Shortcuts
|
||||
|
||||
There are two types of shortcuts: those that manipulate the user interface directly, such as `TAB` to move from one pane to another, and those that are simply shortcuts to actual commands. In a way similar to Vim, these shortcuts are generally a verb followed by an object. For example, typing `mn` ([m]ake [n]ote), is used to create a new note: it will switch the interface to command line mode and pre-fill it with `mknote ""` from where the title of the note can be entered. See below for the full list of shortcuts:
|
||||
There are two types of shortcuts: those that manipulate the user interface directly, such as `TAB` to move from one pane to another, and those that are simply shortcuts to actual commands. In a way similar to Vim, these shortcuts are generally a verb followed by an object. For example, typing `mn` ([m]ake [n]ote), is used to create a new note: it will switch the interface to command line mode and pre-fill it with `mknote ""` from where the title of the note can be entered. See below for the full list of default shortcuts:
|
||||
|
||||
Tab Give focus to next pane
|
||||
Shift+Tab Give focus to previous pane
|
||||
: Enter command line mode
|
||||
ESC Exit command line mode
|
||||
ENTER Edit the selected note
|
||||
Ctrl+C Cancel the current command.
|
||||
Ctrl+D Exit the application.
|
||||
DELETE Delete the currently selected note or notebook.
|
||||
SPACE Set a to-do as completed / not completed
|
||||
tc [t]oggle [c]onsole between maximized/minimized/hidden/visible.
|
||||
/ Search
|
||||
tm [t]oggle note [m]etadata.
|
||||
mn [M]ake a new [n]ote
|
||||
mt [M]ake a new [t]odo
|
||||
mb [M]ake a new note[b]ook
|
||||
yn Copy ([Y]ank) the [n]ote to a notebook.
|
||||
dn Move the note to a notebook.
|
||||
: enter_command_line_mode
|
||||
TAB focus_next
|
||||
SHIFT_TAB focus_previous
|
||||
UP move_up
|
||||
DOWN move_down
|
||||
PAGE_UP page_up
|
||||
PAGE_DOWN page_down
|
||||
ENTER activate
|
||||
DELETE, BACKSPACE delete
|
||||
(SPACE) todo toggle $n
|
||||
tc toggle_console
|
||||
tm toggle_metadata
|
||||
/ search ""
|
||||
mn mknote ""
|
||||
mt mktodo ""
|
||||
mb mkbook ""
|
||||
yn cp $n ""
|
||||
dn mv $n ""
|
||||
|
||||
# Available commands
|
||||
Shortcut can be configured by adding a keymap file to the profile directory in `~/.config/joplin/keymap.json`. The content of this file is a JSON array with each entry defining a command and the keys associated with it.
|
||||
|
||||
As an example, this is the default keymap, but read below for a detailed explanation of each property.
|
||||
|
||||
```json
|
||||
[
|
||||
{ "keys": [":"], "type": "function", "command": "enter_command_line_mode" },
|
||||
{ "keys": ["TAB"], "type": "function", "command": "focus_next" },
|
||||
{ "keys": ["SHIFT_TAB"], "type": "function", "command": "focus_previous" },
|
||||
{ "keys": ["UP"], "type": "function", "command": "move_up" },
|
||||
{ "keys": ["DOWN"], "type": "function", "command": "move_down" },
|
||||
{ "keys": ["PAGE_UP"], "type": "function", "command": "page_up" },
|
||||
{ "keys": ["PAGE_DOWN"], "type": "function", "command": "page_down" },
|
||||
{ "keys": ["ENTER"], "type": "function", "command": "activate" },
|
||||
{ "keys": ["DELETE", "BACKSPACE"], "type": "function", "command": "delete" },
|
||||
{ "keys": [" "], "command": "todo toggle $n" },
|
||||
{ "keys": ["tc"], "type": "function", "command": "toggle_console" },
|
||||
{ "keys": ["tm"], "type": "function", "command": "toggle_metadata" },
|
||||
{ "keys": ["/"], "type": "prompt", "command": "search \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["mn"], "type": "prompt", "command": "mknote \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["mt"], "type": "prompt", "command": "mktodo \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["mb"], "type": "prompt", "command": "mkbook \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["yn"], "type": "prompt", "command": "cp $n \"\"", "cursorPosition": -2 },
|
||||
{ "keys": ["dn"], "type": "prompt", "command": "mv $n \"\"", "cursorPosition": -2 }
|
||||
]
|
||||
```
|
||||
|
||||
Each entry can have the following properties:
|
||||
|
||||
Name | Description
|
||||
-----|------------
|
||||
`keys` | The array of keys that will trigger the action. Special keys such as page up, down arrow, etc. needs to be specified UPPERCASE. See the [list of available special keys](https://github.com/cronvel/terminal-kit/blob/3114206a9556f518cc63abbcb3d188fe1995100d/lib/termconfig/xterm.js#L531). For example, `['DELETE', 'BACKSPACE']` means the command will run if the user pressed either the delete or backspace key. Key combinations can also be provided - in that case specify them lowercase. For example "tc" means that the command will be executed when the user pressed "t" then "c". Special keys can also be used in this fashion - simply write them one after the other. For instance, `CTRL_WCTRL_W` means the action would be executed if the user pressed "ctrl-w ctrl-w".
|
||||
`type` | The command type. It can have the value "exec", "function" or "prompt". **exec**: Simply execute the provided [command](#commands). For example `edit $n` would edit the selected note. **function**: Run a special commands (see below for the list of functions). **prompt**: A bit similar to "exec", except that the command is not going to be executed immediately - this allows the user to provide additional data. For example `mknote ""` would fill the command line with this command and allow the user to set the title. A prompt command can also take a `cursorPosition` parameter (see below)
|
||||
`command` | The command that needs to be executed
|
||||
`cusorPosition` | An integer. For prompt commands, tells where the cursor (caret) should start at. This is convenient for example to position the cursor between quotes. Use a negative value to set a position starting from the end. A value of "0" means positioning the caret at the first character. A value of "-1" means positioning it at the end.
|
||||
|
||||
This is the list of special functions:
|
||||
|
||||
Name | Description
|
||||
-----|------------
|
||||
enter_command_line_mode | Enter command line mode
|
||||
focus_next | Focus next pane (or widget)
|
||||
focus_previous | Focus previous pane (or widget)
|
||||
move_up | Move up (in a list for example)
|
||||
move_down | Move down (in a list for example)
|
||||
page_up | Page up
|
||||
page_down | Page down
|
||||
activate | Activates the selected item. If the item is a note for example it will be open in the editor
|
||||
delete | Deletes the selected item
|
||||
toggle_console | Toggle the console
|
||||
toggle_metadata | Toggle note metadata
|
||||
|
||||
# Commands
|
||||
|
||||
The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
@@ -205,6 +258,12 @@ The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
Attaches the given file to the note.
|
||||
|
||||
cat <note>
|
||||
|
||||
Displays the given note.
|
||||
|
||||
-v, --verbose Displays the complete information about note.
|
||||
|
||||
config [name] [value]
|
||||
|
||||
Gets or sets a config value. If [value] is not provided, it will show the
|
||||
@@ -215,58 +274,91 @@ The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
Possible keys/values:
|
||||
|
||||
sync.2.path File system synchronisation target directory.
|
||||
The path to synchronise with when file system
|
||||
synchronisation is enabled. See `sync.target`.
|
||||
Type: string.
|
||||
|
||||
editor Text editor.
|
||||
The editor that will be used to open a note. If
|
||||
none is provided it will try to auto-detect the
|
||||
default editor.
|
||||
Type: string.
|
||||
|
||||
locale Language.
|
||||
Type: Enum.
|
||||
Possible values: en_GB (English), es_CR (Español),
|
||||
fr_FR (Français).
|
||||
Default: "en_GB"
|
||||
|
||||
dateFormat Date format.
|
||||
Type: Enum.
|
||||
Possible values: DD/MM/YYYY (30/01/2017), DD/MM/YY
|
||||
(30/01/17), MM/DD/YYYY (01/30/2017), MM/DD/YY
|
||||
(01/30/17), YYYY-MM-DD (2017-01-30).
|
||||
Default: "DD/MM/YYYY"
|
||||
|
||||
timeFormat Time format.
|
||||
Type: Enum.
|
||||
Possible values: HH:mm (20:30), h:mm A (8:30 PM).
|
||||
Default: "HH:mm"
|
||||
|
||||
uncompletedTodosOnTop Show uncompleted to-dos on top of the lists.
|
||||
Type: bool.
|
||||
Default: true
|
||||
|
||||
trackLocation Save geo-location with notes.
|
||||
Type: bool.
|
||||
Default: true
|
||||
|
||||
sync.interval Synchronisation interval.
|
||||
Type: Enum.
|
||||
Possible values: 0 (Disabled), 300 (5 minutes), 600
|
||||
(10 minutes), 1800 (30 minutes), 3600 (1 hour),
|
||||
43200 (12 hours), 86400 (24 hours).
|
||||
Default: 300
|
||||
|
||||
sync.target Synchronisation target.
|
||||
The target to synchonise to. If synchronising with
|
||||
the file system, set `sync.2.path` to specify the
|
||||
target directory.
|
||||
Type: Enum.
|
||||
Possible values: 2 (File system), 3 (OneDrive), 4
|
||||
(OneDrive Dev (For testing only)).
|
||||
Default: 3
|
||||
editor Text editor.
|
||||
The editor that will be used to open a note. If
|
||||
none is provided it will try to auto-detect the
|
||||
default editor.
|
||||
Type: string.
|
||||
|
||||
locale Language.
|
||||
Type: Enum.
|
||||
Possible values: eu (Basque), hr_HR (Croatian),
|
||||
de_DE (Deutsch), en_GB (English), es_ES
|
||||
(Español), fr_FR (Français), it_IT (Italiano),
|
||||
nl_BE (Nederlands), pt_BR (Português (Brasil)),
|
||||
ru_RU (Русский), zh_CN (中文 (简体)), ja_JP (日本語).
|
||||
Default: "en_GB"
|
||||
|
||||
dateFormat Date format.
|
||||
Type: Enum.
|
||||
Possible values: DD/MM/YYYY (30/01/2017),
|
||||
DD/MM/YY (30/01/17), MM/DD/YYYY (01/30/2017),
|
||||
MM/DD/YY (01/30/17), YYYY-MM-DD (2017-01-30).
|
||||
Default: "DD/MM/YYYY"
|
||||
|
||||
timeFormat Time format.
|
||||
Type: Enum.
|
||||
Possible values: HH:mm (20:30), h:mm A (8:30 PM).
|
||||
Default: "HH:mm"
|
||||
|
||||
uncompletedTodosOnTop Uncompleted to-dos on top.
|
||||
Type: bool.
|
||||
Default: true
|
||||
|
||||
notes.sortOrder.field Sort notes by.
|
||||
Type: Enum.
|
||||
Possible values: user_updated_time (Updated
|
||||
date), user_created_time (Created date), title
|
||||
(Title).
|
||||
Default: "user_updated_time"
|
||||
|
||||
notes.sortOrder.reverse Reverse sort order.
|
||||
Type: bool.
|
||||
Default: true
|
||||
|
||||
trackLocation Save geo-location with notes.
|
||||
Type: bool.
|
||||
Default: true
|
||||
|
||||
sync.interval Synchronisation interval.
|
||||
Type: Enum.
|
||||
Possible values: 0 (Disabled), 300 (5 minutes),
|
||||
600 (10 minutes), 1800 (30 minutes), 3600 (1
|
||||
hour), 43200 (12 hours), 86400 (24 hours).
|
||||
Default: 300
|
||||
|
||||
sync.target Synchronisation target.
|
||||
The target to synchonise to. Each sync target may
|
||||
have additional parameters which are named as
|
||||
`sync.NUM.NAME` (all documented below).
|
||||
Type: Enum.
|
||||
Possible values: 2 (File system), 3 (OneDrive), 4
|
||||
(OneDrive Dev (For testing only)), 5 (Nextcloud),
|
||||
6 (WebDAV).
|
||||
Default: 3
|
||||
|
||||
sync.2.path Directory to synchronise with (absolute path).
|
||||
The path to synchronise with when file system
|
||||
synchronisation is enabled. See `sync.target`.
|
||||
Type: string.
|
||||
|
||||
sync.5.path Nextcloud WebDAV URL.
|
||||
Type: string.
|
||||
|
||||
sync.5.username Nextcloud username.
|
||||
Type: string.
|
||||
|
||||
sync.5.password Nextcloud password.
|
||||
Type: string.
|
||||
|
||||
sync.6.path WebDAV URL.
|
||||
Type: string.
|
||||
|
||||
sync.6.username WebDAV username.
|
||||
Type: string.
|
||||
|
||||
sync.6.password WebDAV password.
|
||||
Type: string.
|
||||
|
||||
cp <note> [notebook]
|
||||
|
||||
@@ -277,19 +369,28 @@ The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
Marks a to-do as done.
|
||||
|
||||
e2ee <command> [path]
|
||||
|
||||
Manages E2EE configuration. Commands are `enable`, `disable`, `decrypt`,
|
||||
`status` and `target-status`.
|
||||
|
||||
-p, --password <password> Use this password as master password (For
|
||||
security reasons, it is not recommended to use
|
||||
this option).
|
||||
-v, --verbose More verbose output for the `target-status`
|
||||
command
|
||||
|
||||
edit <note>
|
||||
|
||||
Edit note.
|
||||
|
||||
exit
|
||||
export <path>
|
||||
|
||||
Exits the application.
|
||||
|
||||
export <directory>
|
||||
|
||||
Exports Joplin data to the given directory. By default, it will export the
|
||||
Exports Joplin data to the given path. By default, it will export the
|
||||
complete database including notebooks, notes, tags and resources.
|
||||
|
||||
--format <format> Destination format: jex (Joplin Export File), raw
|
||||
(Joplin Export Directory)
|
||||
--note <note> Exports only the given note.
|
||||
--notebook <notebook> Exports only the given notebook.
|
||||
|
||||
@@ -301,11 +402,12 @@ The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
Displays usage information.
|
||||
|
||||
import-enex <file> [notebook]
|
||||
import <path> [notebook]
|
||||
|
||||
Imports an Evernote notebook file (.enex file).
|
||||
Imports data into Joplin.
|
||||
|
||||
-f, --force Do not ask for confirmation.
|
||||
--format <format> Source format: auto, jex, md, raw, enex
|
||||
-f, --force Do not ask for confirmation.
|
||||
|
||||
mkbook <new-notebook>
|
||||
|
||||
@@ -339,9 +441,18 @@ The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
-f, --force Deletes the notes without asking for confirmation.
|
||||
|
||||
search <pattern> [notebook]
|
||||
set <note> <name> [value]
|
||||
|
||||
Searches for the given <pattern> in all the notes.
|
||||
Sets the property <name> of the given <note> to the given [value].
|
||||
Possible properties are:
|
||||
|
||||
parent_id (text), title (text), body (text), created_time (int),
|
||||
updated_time (int), is_conflict (int), latitude (numeric), longitude
|
||||
(numeric), altitude (numeric), author (text), source_url (text), is_todo
|
||||
(int), todo_due (int), todo_completed (int), source (text),
|
||||
source_application (text), application_data (text), order (int),
|
||||
user_created_time (int), user_updated_time (int), encryption_cipher_text
|
||||
(text), encryption_applied (int)
|
||||
|
||||
status
|
||||
|
||||
@@ -353,7 +464,6 @@ The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
--target <target> Sync to provided target (defaults to sync.target config
|
||||
value)
|
||||
--random-failures For debugging purposes. Do not use.
|
||||
|
||||
tag <tag-command> [tag] [note]
|
||||
|
||||
@@ -372,6 +482,11 @@ The following commands are available in [command-line mode](#command-line-mode):
|
||||
|
||||
Marks a to-do as non-completed.
|
||||
|
||||
use <notebook>
|
||||
|
||||
Switches to [notebook] - all further operations will happen within this
|
||||
notebook.
|
||||
|
||||
version
|
||||
|
||||
Displays version information
|
||||
|
@@ -90,8 +90,8 @@ android {
|
||||
applicationId "net.cozic.joplin"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
versionCode 2097275
|
||||
versionName "1.0.97"
|
||||
versionCode 2097282
|
||||
versionName "1.0.104"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
|
@@ -1,51 +1,3 @@
|
||||
const { main } = require('./main.js');
|
||||
|
||||
main();
|
||||
|
||||
// const React = require('react'); const Component = React.Component;
|
||||
// import {
|
||||
// AppRegistry,
|
||||
// StyleSheet,
|
||||
// Text,
|
||||
// View
|
||||
// } from 'react-native';
|
||||
|
||||
// module.exports = default class Joplin extends Component {;
|
||||
// render() {
|
||||
// return (
|
||||
// <View style={styles.container}>
|
||||
// <Text style={styles.welcome}>
|
||||
// Welcome to React Native!
|
||||
// </Text>
|
||||
// <Text style={styles.instructions}>
|
||||
// To get started, edit index.ios.js
|
||||
// </Text>
|
||||
// <Text style={styles.instructions}>
|
||||
// Press Cmd+R to reload,{'\n'}
|
||||
// Cmd+D or shake for dev menu
|
||||
// </Text>
|
||||
// </View>
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// const styles = StyleSheet.create({
|
||||
// container: {
|
||||
// flex: 1,
|
||||
// justifyContent: 'center',
|
||||
// alignItems: 'center',
|
||||
// backgroundColor: '#F5FCFF',
|
||||
// },
|
||||
// welcome: {
|
||||
// fontSize: 20,
|
||||
// textAlign: 'center',
|
||||
// margin: 10,
|
||||
// },
|
||||
// instructions: {
|
||||
// textAlign: 'center',
|
||||
// color: '#333333',
|
||||
// marginBottom: 5,
|
||||
// },
|
||||
// });
|
||||
|
||||
// AppRegistry.registerComponent('Joplin', () => Joplin);
|
||||
main();
|
@@ -1302,7 +1302,7 @@
|
||||
PRODUCT_NAME = Joplin;
|
||||
PROVISIONING_PROFILE = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Debug;
|
||||
@@ -1342,7 +1342,7 @@
|
||||
PRODUCT_NAME = Joplin;
|
||||
PROVISIONING_PROFILE = "";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
TARGETED_DEVICE_FAMILY = 1;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
};
|
||||
name = Release;
|
||||
|
@@ -17,11 +17,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.10.9</string>
|
||||
<string>1.0.13</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>9</string>
|
||||
<string>13</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
@@ -15,7 +15,6 @@ ArrayUtils.removeElement = function(array, element) {
|
||||
|
||||
// https://stackoverflow.com/a/10264318/561309
|
||||
ArrayUtils.binarySearch = function(items, value) {
|
||||
|
||||
var startIndex = 0,
|
||||
stopIndex = items.length - 1,
|
||||
middle = Math.floor((stopIndex + startIndex)/2);
|
||||
@@ -37,4 +36,13 @@ ArrayUtils.binarySearch = function(items, value) {
|
||||
return (items[middle] != value) ? -1 : middle;
|
||||
}
|
||||
|
||||
ArrayUtils.findByKey = function(array, key, value) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const o = array[i];
|
||||
if (typeof o !== 'object') continue;
|
||||
if (o[key] === value) return o;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
module.exports = ArrayUtils;
|
@@ -1,5 +1,5 @@
|
||||
const { createStore, applyMiddleware } = require('redux');
|
||||
const { reducer, defaultState } = require('lib/reducer.js');
|
||||
const { reducer, defaultState, stateUtils } = require('lib/reducer.js');
|
||||
const { JoplinDatabase } = require('lib/joplin-database.js');
|
||||
const { Database } = require('lib/database.js');
|
||||
const { FoldersScreenUtils } = require('lib/folders-screen-utils.js');
|
||||
@@ -184,8 +184,9 @@ class BaseApplication {
|
||||
this.logger().debug('Refreshing notes:', parentType, parentId);
|
||||
|
||||
let options = {
|
||||
order: state.notesOrder,
|
||||
order: stateUtils.notesOrder(state.settings),
|
||||
uncompletedTodosOnTop: Setting.value('uncompletedTodosOnTop'),
|
||||
caseInsensitive: true,
|
||||
};
|
||||
|
||||
const source = JSON.stringify({
|
||||
@@ -255,14 +256,31 @@ class BaseApplication {
|
||||
|
||||
const result = next(action);
|
||||
const newState = store.getState();
|
||||
let refreshNotes = false;
|
||||
|
||||
if (action.type == 'FOLDER_SELECT' || action.type === 'FOLDER_DELETE') {
|
||||
Setting.setValue('activeFolderId', newState.selectedFolderId);
|
||||
this.currentFolder_ = newState.selectedFolderId ? await Folder.load(newState.selectedFolderId) : null;
|
||||
await this.refreshNotes(newState);
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (this.hasGui() && action.type == 'SETTING_UPDATE_ONE' && action.key == 'uncompletedTodosOnTop' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && action.key == 'uncompletedTodosOnTop') || action.type == 'SETTING_UPDATE_ALL')) {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (this.hasGui() && ((action.type == 'SETTING_UPDATE_ONE' && action.key.indexOf('notes.sortOrder') === 0) || action.type == 'SETTING_UPDATE_ALL')) {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (action.type == 'TAG_SELECT' || action.type === 'TAG_DELETE') {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (action.type == 'SEARCH_SELECT' || action.type === 'SEARCH_DELETE') {
|
||||
refreshNotes = true;
|
||||
}
|
||||
|
||||
if (refreshNotes) {
|
||||
await this.refreshNotes(newState);
|
||||
}
|
||||
|
||||
@@ -288,14 +306,6 @@ class BaseApplication {
|
||||
}
|
||||
}
|
||||
|
||||
if (action.type == 'TAG_SELECT' || action.type === 'TAG_DELETE') {
|
||||
await this.refreshNotes(newState);
|
||||
}
|
||||
|
||||
if (action.type == 'SEARCH_SELECT' || action.type === 'SEARCH_DELETE') {
|
||||
await this.refreshNotes(newState);
|
||||
}
|
||||
|
||||
if (action.type === 'NOTE_UPDATE_ONE') {
|
||||
// If there is a conflict, we refresh the folders so as to display "Conflicts" folder
|
||||
if (action.note && action.note.is_conflict) {
|
||||
@@ -303,11 +313,6 @@ class BaseApplication {
|
||||
}
|
||||
}
|
||||
|
||||
// if (action.type === 'NOTE_DELETE') {
|
||||
// // Update folders if a note is deleted in case the deleted note was a conflict
|
||||
// await FoldersScreenUtils.refreshFolders();
|
||||
// }
|
||||
|
||||
if (this.hasGui() && action.type == 'SETTING_UPDATE_ONE' && action.key == 'sync.interval' || action.type == 'SETTING_UPDATE_ALL') {
|
||||
reg.setupRecurrentSync();
|
||||
}
|
||||
|
@@ -45,6 +45,14 @@ class BaseModel {
|
||||
return null;
|
||||
}
|
||||
|
||||
static modelTypeToName(type) {
|
||||
for (let i = 0; i < BaseModel.typeEnum_.length; i++) {
|
||||
const e = BaseModel.typeEnum_[i];
|
||||
if (e[1] === type) return e[0].substr(5).toLowerCase();
|
||||
}
|
||||
throw new Error('Unknown model type: ' + type);
|
||||
}
|
||||
|
||||
static hasField(name) {
|
||||
let fields = this.fieldNames();
|
||||
return fields.indexOf(name) >= 0;
|
||||
@@ -487,15 +495,32 @@ class BaseModel {
|
||||
|
||||
}
|
||||
|
||||
BaseModel.TYPE_NOTE = 1;
|
||||
BaseModel.TYPE_FOLDER = 2;
|
||||
BaseModel.TYPE_SETTING = 3;
|
||||
BaseModel.TYPE_RESOURCE = 4;
|
||||
BaseModel.TYPE_TAG = 5;
|
||||
BaseModel.TYPE_NOTE_TAG = 6;
|
||||
BaseModel.TYPE_SEARCH = 7;
|
||||
BaseModel.TYPE_ALARM = 8;
|
||||
BaseModel.TYPE_MASTER_KEY = 9;
|
||||
BaseModel.typeEnum_ = [
|
||||
['TYPE_NOTE', 1],
|
||||
['TYPE_FOLDER', 2],
|
||||
['TYPE_SETTING', 3],
|
||||
['TYPE_RESOURCE', 4],
|
||||
['TYPE_TAG', 5],
|
||||
['TYPE_NOTE_TAG', 6],
|
||||
['TYPE_SEARCH', 7],
|
||||
['TYPE_ALARM', 8],
|
||||
['TYPE_MASTER_KEY', 9],
|
||||
];
|
||||
|
||||
for (let i = 0; i < BaseModel.typeEnum_.length; i++) {
|
||||
const e = BaseModel.typeEnum_[i];
|
||||
BaseModel[e[0]] = e[1];
|
||||
}
|
||||
|
||||
// BaseModel.TYPE_NOTE = 1;
|
||||
// BaseModel.TYPE_FOLDER = 2;
|
||||
// BaseModel.TYPE_SETTING = 3;
|
||||
// BaseModel.TYPE_RESOURCE = 4;
|
||||
// BaseModel.TYPE_TAG = 5;
|
||||
// BaseModel.TYPE_NOTE_TAG = 6;
|
||||
// BaseModel.TYPE_SEARCH = 7;
|
||||
// BaseModel.TYPE_ALARM = 8;
|
||||
// BaseModel.TYPE_MASTER_KEY = 9;
|
||||
|
||||
BaseModel.db_ = null;
|
||||
BaseModel.dispatch = function(o) {};
|
||||
|
@@ -28,8 +28,7 @@ class Cache {
|
||||
Cache.storage = async function() {
|
||||
if (Cache.storage_) return Cache.storage_;
|
||||
Cache.storage_ = require('node-persist');
|
||||
const osTmpdir = require('os-tmpdir');
|
||||
await Cache.storage_.init({ dir: osTmpdir() + '/joplin-cache', ttl: 1000 * 60 });
|
||||
await Cache.storage_.init({ dir: require('os').tmpdir() + '/joplin-cache', ttl: 1000 * 60 });
|
||||
return Cache.storage_;
|
||||
}
|
||||
|
||||
|
@@ -208,6 +208,8 @@ class MdToHtml {
|
||||
openTag = null;
|
||||
} else if (isInlineCode) {
|
||||
openTag = null;
|
||||
} else if (tag && t.type.indexOf('html_inline') >= 0) {
|
||||
openTag = null;
|
||||
} else if (tag && t.type.indexOf('_open') >= 0) {
|
||||
openTag = tag;
|
||||
} else if (tag && t.type.indexOf('_close') >= 0) {
|
||||
@@ -266,6 +268,8 @@ class MdToHtml {
|
||||
if (t.type === 'image') {
|
||||
if (tokenContent) attrs.push(['title', tokenContent]);
|
||||
output.push(this.renderImage_(attrs, options));
|
||||
} else if (t.type === 'html_inline') {
|
||||
output.push(t.content);
|
||||
} else if (t.type === 'softbreak') {
|
||||
output.push('<br/>');
|
||||
} else if (t.type === 'hr') {
|
||||
@@ -351,6 +355,7 @@ class MdToHtml {
|
||||
const md = new MarkdownIt({
|
||||
breaks: true,
|
||||
linkify: true,
|
||||
html: true,
|
||||
});
|
||||
|
||||
// This is currently used only so that the $expression$ and $$\nexpression\n$$ blocks are translated
|
||||
|
47
ReactNativeClient/lib/ObjectUtils.js
Normal file
47
ReactNativeClient/lib/ObjectUtils.js
Normal file
@@ -0,0 +1,47 @@
|
||||
const ObjectUtils = {};
|
||||
|
||||
ObjectUtils.sortByValue = function(object) {
|
||||
const temp = [];
|
||||
for (let k in object) {
|
||||
if (!object.hasOwnProperty(k)) continue;
|
||||
temp.push({
|
||||
key: k,
|
||||
value: object[k],
|
||||
});
|
||||
}
|
||||
|
||||
temp.sort(function(a, b) {
|
||||
let v1 = a.value;
|
||||
let v2 = b.value;
|
||||
if (typeof v1 === 'string') v1 = v1.toLowerCase();
|
||||
if (typeof v2 === 'string') v2 = v2.toLowerCase();
|
||||
if (v1 === v2) return 0;
|
||||
return v1 < v2 ? -1 : +1;
|
||||
});
|
||||
|
||||
const output = {};
|
||||
for (let i = 0; i < temp.length; i++) {
|
||||
const item = temp[i];
|
||||
output[item.key] = item.value;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
ObjectUtils.fieldsEqual = function(o1, o2) {
|
||||
if ((!o1 || !o2) && (o1 !== o2)) return false;
|
||||
|
||||
for (let k in o1) {
|
||||
if (!o1.hasOwnProperty(k)) continue;
|
||||
if (o1[k] !== o2[k]) return false;
|
||||
}
|
||||
|
||||
const c1 = Object.getOwnPropertyNames(o1);
|
||||
const c2 = Object.getOwnPropertyNames(o2);
|
||||
|
||||
if (c1.length !== c2.length) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = ObjectUtils;
|
@@ -37,7 +37,7 @@ class SyncTargetNextcloud extends BaseSyncTarget {
|
||||
}
|
||||
|
||||
async initFileApi() {
|
||||
const fileApi = await SyncTargetWebDAV.initFileApi_({
|
||||
const fileApi = await SyncTargetWebDAV.newFileApi_(SyncTargetNextcloud.id(), {
|
||||
path: Setting.value('sync.5.path'),
|
||||
username: Setting.value('sync.5.username'),
|
||||
password: Setting.value('sync.5.password'),
|
||||
|
@@ -28,7 +28,7 @@ class SyncTargetWebDAV extends BaseSyncTarget {
|
||||
return true;
|
||||
}
|
||||
|
||||
static async initFileApi_(options) {
|
||||
static async newFileApi_(syncTargetId, options) {
|
||||
const apiOptions = {
|
||||
baseUrl: () => options.path,
|
||||
username: () => options.username,
|
||||
@@ -38,12 +38,13 @@ class SyncTargetWebDAV extends BaseSyncTarget {
|
||||
const api = new WebDavApi(apiOptions);
|
||||
const driver = new FileApiDriverWebDav(api);
|
||||
const fileApi = new FileApi('', driver);
|
||||
fileApi.setSyncTargetId(this.id());
|
||||
fileApi.setSyncTargetId(syncTargetId);
|
||||
return fileApi;
|
||||
}
|
||||
|
||||
static async checkConfig(options) {
|
||||
const fileApi = await SyncTargetWebDAV.initFileApi_(options);
|
||||
const fileApi = await SyncTargetWebDAV.newFileApi_(SyncTargetWebDAV.id(), options);
|
||||
fileApi.requestRepeatCount_ = 0;
|
||||
|
||||
const output = {
|
||||
ok: false,
|
||||
@@ -52,7 +53,7 @@ class SyncTargetWebDAV extends BaseSyncTarget {
|
||||
|
||||
try {
|
||||
const result = await fileApi.stat('');
|
||||
if (!result) throw new Error('Could not access WebDAV directory');
|
||||
if (!result) throw new Error('WebDAV directory not found: ' + options.path);
|
||||
output.ok = true;
|
||||
} catch (error) {
|
||||
output.errorMessage = error.message;
|
||||
@@ -63,7 +64,7 @@ class SyncTargetWebDAV extends BaseSyncTarget {
|
||||
}
|
||||
|
||||
async initFileApi() {
|
||||
const fileApi = await SyncTargetWebDAV.initFileApi_({
|
||||
const fileApi = await SyncTargetWebDAV.newFileApi_(SyncTargetWebDAV.id(), {
|
||||
path: Setting.value('sync.6.path'),
|
||||
username: Setting.value('sync.6.username'),
|
||||
password: Setting.value('sync.6.password'),
|
||||
|
@@ -29,7 +29,15 @@ class WebDavApi {
|
||||
|
||||
authToken() {
|
||||
if (!this.options_.username() || !this.options_.password()) return null;
|
||||
return base64.encode(this.options_.username() + ':' + this.options_.password());
|
||||
try {
|
||||
// Note: Non-ASCII passwords will throw an error about Latin1 characters - https://github.com/laurent22/joplin/issues/246
|
||||
// Tried various things like the below, but it didn't work on React Native:
|
||||
//return base64.encode(utf8.encode(this.options_.username() + ':' + this.options_.password()));
|
||||
return base64.encode(this.options_.username() + ':' + this.options_.password());
|
||||
} catch (error) {
|
||||
error.message = 'Cannot encode username/password: ' + error.message;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
baseUrl() {
|
||||
@@ -227,10 +235,16 @@ class WebDavApi {
|
||||
|
||||
if (authToken) headers['Authorization'] = 'Basic ' + authToken;
|
||||
|
||||
// /!\ Doesn't work with UTF-8 strings as it results in truncated content. Content-Length
|
||||
// /!\ should not be needed anyway, but was required by one service. If re-implementing this
|
||||
// /!\ test with various content, including binary blobs.
|
||||
// if (typeof body === 'string') headers['Content-Length'] = body.length;
|
||||
// On iOS, the network lib appends a If-None-Match header to PROPFIND calls, which is kind of correct because
|
||||
// the call is idempotent and thus could be cached. According to RFC-7232 though only GET and HEAD should have
|
||||
// this header for caching purposes. It makes no mention of PROPFIND.
|
||||
// So possibly because of this, Seafile (and maybe other WebDAV implementations) responds with a "412 Precondition Failed"
|
||||
// error when this header is present for PROPFIND call on existing resources. This is also kind of correct because there is a resource
|
||||
// with this eTag and since this is neither a GET nor HEAD call, it is supposed to respond with 412 if the resource is present.
|
||||
// The "solution", an ugly one, is to send a purposely invalid string as eTag, which will bypass the If-None-Match check - Seafile
|
||||
// finds out that no resource has this ID and simply sends the requested data.
|
||||
// Also add a random value to make sure the eTag is unique for each call.
|
||||
if (['GET', 'HEAD'].indexOf(method) < 0) headers['If-None-Match'] = 'JoplinIgnore-' + Math.floor(Math.random() * 100000);
|
||||
|
||||
const fetchOptions = {};
|
||||
fetchOptions.headers = headers;
|
||||
@@ -246,8 +260,13 @@ class WebDavApi {
|
||||
// console.info(this.requestToCurl_(url, fetchOptions));
|
||||
|
||||
if (options.source == 'file' && (method == 'POST' || method == 'PUT')) {
|
||||
if (fetchOptions.path) {
|
||||
const fileStat = await shim.fsDriver().stat(fetchOptions.path);
|
||||
if (fileStat) fetchOptions.headers['Content-Length'] = fileStat.size + '';
|
||||
}
|
||||
response = await shim.uploadBlob(url, fetchOptions);
|
||||
} else if (options.target == 'string') {
|
||||
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = shim.stringByteLength(body) + '';
|
||||
response = await shim.fetch(url, fetchOptions);
|
||||
} else { // file
|
||||
response = await shim.fetchBlob(url, fetchOptions);
|
||||
@@ -257,10 +276,12 @@ class WebDavApi {
|
||||
|
||||
// console.info('WebDAV Response', responseText);
|
||||
|
||||
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
||||
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
||||
const shortResponseText = () => {
|
||||
return (responseText + '').substr(0, 1024);
|
||||
// Creates an error object with as much data as possible as it will appear in the log, which will make debugging easier
|
||||
const newError = (message, code = 0) => {
|
||||
// Gives a shorter response for error messages. Useful for cases where a full HTML page is accidentally loaded instead of
|
||||
// JSON. That way the error message will still show there's a problem but without filling up the log or screen.
|
||||
const shortResponseText = (responseText + '').substr(0, 1024);
|
||||
return new JoplinError(method + ' ' + path + ': ' + message + ' (' + code + '): ' + shortResponseText, code);
|
||||
}
|
||||
|
||||
let responseJson_ = null;
|
||||
@@ -268,32 +289,42 @@ class WebDavApi {
|
||||
if (!responseText) return null;
|
||||
if (responseJson_) return responseJson_;
|
||||
responseJson_ = await this.xmlToJson(responseText);
|
||||
if (!responseJson_) throw new JoplinError('Cannot parse JSON response: ' + shortResponseText(), response.status);
|
||||
if (!responseJson_) throw newError('Cannot parse XML response', response.status);
|
||||
return responseJson_;
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
// When using fetchBlob we only get a string (not xml or json) back
|
||||
if (options.target === 'file') throw new JoplinError(shortResponseText(), response.status);
|
||||
if (options.target === 'file') throw newError('fetchBlob error', response.status);
|
||||
|
||||
const json = await loadResponseJson();
|
||||
let json = null;
|
||||
try {
|
||||
json = await loadResponseJson();
|
||||
} catch (error) {
|
||||
// Just send back the plain text in newErro()
|
||||
}
|
||||
|
||||
if (json && json['d:error']) {
|
||||
const code = json['d:error']['s:exception'] ? json['d:error']['s:exception'].join(' ') : response.status;
|
||||
const message = json['d:error']['s:message'] ? json['d:error']['s:message'].join("\n") : shortResponseText();
|
||||
throw new JoplinError(method + ' ' + path + ': ' + message + ' (' + code + ')', response.status);
|
||||
const message = json['d:error']['s:message'] ? json['d:error']['s:message'].join("\n") : 'Unknown error 1';
|
||||
throw newError(message + ' (Exception ' + code + ')', response.status);
|
||||
}
|
||||
|
||||
throw new JoplinError(method + ' ' + path + ': ' + shortResponseText(), response.status);
|
||||
throw newError('Unknown error 2', response.status);
|
||||
}
|
||||
|
||||
if (options.responseFormat === 'text') return responseText;
|
||||
|
||||
// The following methods may have a response depending on the server but it's not
|
||||
// standard (some return a plain string, other XML, etc.) and we don't check the
|
||||
// response anyway since we rely on the HTTP status code so return null.
|
||||
if (['MKCOL', 'DELETE', 'PUT', 'MOVE'].indexOf(method) >= 0) return null;
|
||||
|
||||
const output = await loadResponseJson();
|
||||
|
||||
// Check that we didn't get for example an HTML page (as an error) instead of the JSON response
|
||||
// null responses are possible, for example for DELETE calls
|
||||
if (output !== null && typeof output === 'object' && !('d:multistatus' in output)) throw new Error('Not a valid JSON response: ' + shortResponseText());
|
||||
if (output !== null && typeof output === 'object' && !('d:multistatus' in output)) throw newError('Not a valid WebDAV response');
|
||||
|
||||
return output;
|
||||
}
|
||||
|
81
ReactNativeClient/lib/components/ModalDialog.js
Normal file
81
ReactNativeClient/lib/components/ModalDialog.js
Normal file
@@ -0,0 +1,81 @@
|
||||
const React = require('react');
|
||||
const { Text, Modal, View, StyleSheet, Button } = require('react-native');
|
||||
const { themeStyle } = require('lib/components/global-style.js');
|
||||
const { _ } = require('lib/locale');
|
||||
|
||||
class ModalDialog extends React.Component {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.styles_ = {};
|
||||
}
|
||||
|
||||
styles() {
|
||||
const themeId = this.props.theme;
|
||||
const theme = themeStyle(themeId);
|
||||
|
||||
if (this.styles_[themeId]) return this.styles_[themeId];
|
||||
this.styles_ = {};
|
||||
|
||||
let styles = {
|
||||
modalWrapper: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
modalContentWrapper: {
|
||||
flex:1,
|
||||
flexDirection: 'column',
|
||||
backgroundColor: theme.backgroundColor,
|
||||
borderWidth: 1,
|
||||
borderColor:theme.dividerColor,
|
||||
margin: 20,
|
||||
padding: 10,
|
||||
},
|
||||
modalContentWrapper2: {
|
||||
paddingTop: 10,
|
||||
flex:1,
|
||||
},
|
||||
title: {
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: theme.dividerColor,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
buttonRow: {
|
||||
flexDirection: 'row',
|
||||
borderTopWidth: 1,
|
||||
borderTopColor: theme.dividerColor,
|
||||
paddingTop: 10,
|
||||
},
|
||||
};
|
||||
|
||||
this.styles_[themeId] = StyleSheet.create(styles);
|
||||
return this.styles_[themeId];
|
||||
}
|
||||
|
||||
render() {
|
||||
const ContentComponent = this.props.ContentComponent;
|
||||
|
||||
return (
|
||||
<View style={this.styles().modalWrapper}>
|
||||
<Modal transparent={true} visible={true} onRequestClose={() => { }} >
|
||||
<View style={this.styles().modalContentWrapper}>
|
||||
<Text style={this.styles().title}>Title</Text>
|
||||
<View style={this.styles().modalContentWrapper2}>
|
||||
{ContentComponent}
|
||||
</View>
|
||||
<View style={this.styles().buttonRow}>
|
||||
<View style={{flex:1}}>
|
||||
<Button title={_('OK')} onPress={() => {}}></Button>
|
||||
</View>
|
||||
<View style={{flex:1, marginLeft: 5}}>
|
||||
<Button title={_('Cancel')} onPress={() => {}}></Button>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ModalDialog;
|
@@ -4,6 +4,7 @@ const { Platform, View, Text, Button, StyleSheet, TouchableOpacity, Image, Scrol
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
const { Log } = require('lib/log.js');
|
||||
const { BackButtonService } = require('lib/services/back-button.js');
|
||||
const NavService = require('lib/services/NavService.js');
|
||||
const { ReportService } = require('lib/services/report.js');
|
||||
const { Menu, MenuOptions, MenuOption, MenuTrigger } = require('react-native-popup-menu');
|
||||
const { _ } = require('lib/locale.js');
|
||||
@@ -160,10 +161,7 @@ class ScreenHeaderComponent extends Component {
|
||||
}
|
||||
|
||||
searchButton_press() {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Search',
|
||||
});
|
||||
NavService.go('Search');
|
||||
}
|
||||
|
||||
async deleteButton_press() {
|
||||
@@ -184,38 +182,23 @@ class ScreenHeaderComponent extends Component {
|
||||
}
|
||||
|
||||
log_press() {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Log',
|
||||
});
|
||||
NavService.go('Log');
|
||||
}
|
||||
|
||||
status_press() {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Status',
|
||||
});
|
||||
NavService.go('Status');
|
||||
}
|
||||
|
||||
config_press() {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'Config',
|
||||
});
|
||||
NavService.go('Config');
|
||||
}
|
||||
|
||||
encryptionConfig_press() {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'EncryptionConfig',
|
||||
});
|
||||
NavService.go('EncryptionConfig');
|
||||
}
|
||||
|
||||
warningBox_press() {
|
||||
this.props.dispatch({
|
||||
type: 'NAV_GO',
|
||||
routeName: 'EncryptionConfig',
|
||||
});
|
||||
NavService.go('EncryptionConfig');
|
||||
}
|
||||
|
||||
async debugReport_press() {
|
||||
@@ -300,6 +283,16 @@ class ScreenHeaderComponent extends Component {
|
||||
);
|
||||
}
|
||||
|
||||
function sortButton(styles, onPress) {
|
||||
return (
|
||||
<TouchableOpacity onPress={onPress}>
|
||||
<View style={styles.iconButton}>
|
||||
<Icon name='md-funnel' style={styles.topIcon} />
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
|
||||
let key = 0;
|
||||
let menuOptionComponents = [];
|
||||
|
||||
@@ -441,6 +434,7 @@ class ScreenHeaderComponent extends Component {
|
||||
const backButtonComp = backButton(this.styles(), () => this.backButton_press(), !this.props.historyCanGoBack);
|
||||
const searchButtonComp = this.props.noteSelectionEnabled ? null : searchButton(this.styles(), () => this.searchButton_press());
|
||||
const deleteButtonComp = this.props.noteSelectionEnabled ? deleteButton(this.styles(), () => this.deleteButton_press()) : null;
|
||||
const sortButtonComp = this.props.sortButton_press ? sortButton(this.styles(), () => this.props.sortButton_press()) : null;
|
||||
const windowHeight = Dimensions.get('window').height - 50;
|
||||
|
||||
const menuComp = (
|
||||
@@ -465,6 +459,7 @@ class ScreenHeaderComponent extends Component {
|
||||
{ titleComp }
|
||||
{ searchButtonComp }
|
||||
{ deleteButtonComp }
|
||||
{ sortButtonComp }
|
||||
{ menuComp }
|
||||
</View>
|
||||
{ warningComp }
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { TextInput, TouchableOpacity, Linking, View, Switch, Slider, StyleSheet, Text, Button, ScrollView } = require('react-native');
|
||||
const { TextInput, TouchableOpacity, Linking, View, Switch, Slider, StyleSheet, Text, Button, ScrollView, Platform } = require('react-native');
|
||||
const EncryptionService = require('lib/services/EncryptionService');
|
||||
const { connect } = require('react-redux');
|
||||
const { ScreenHeader } = require('lib/components/screen-header.js');
|
||||
@@ -109,13 +109,20 @@ class EncryptionConfigScreenComponent extends BaseScreenComponent {
|
||||
const passwordOk = this.state.passwordChecks[mk.id] === true ? '✔' : '❌';
|
||||
const active = this.props.activeMasterKeyId === mk.id ? '✔' : '';
|
||||
|
||||
const inputStyle = {flex:1, marginRight: 10, color: theme.color};
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
inputStyle.borderBottomWidth = 1;
|
||||
inputStyle.borderBottomColor = theme.dividerColor;
|
||||
}
|
||||
|
||||
return (
|
||||
<View key={mk.id}>
|
||||
<Text style={this.styles().titleText}>{_('Master Key %s', mk.id.substr(0,6))}</Text>
|
||||
<Text style={this.styles().normalText}>{_('Created: %s', time.formatMsToLocal(mk.created_time))}</Text>
|
||||
<View style={{flexDirection: 'row', alignItems: 'center'}}>
|
||||
<Text style={{flex:0, fontSize: theme.fontSize, marginRight: 10, color: theme.color}}>{_('Password:')}</Text>
|
||||
<TextInput secureTextEntry={true} value={password} onChangeText={(text) => onPasswordChange(text)} style={{flex:1, marginRight: 10, color: theme.color}}></TextInput>
|
||||
<TextInput secureTextEntry={true} value={password} onChangeText={(text) => onPasswordChange(text)} style={inputStyle}></TextInput>
|
||||
<Text style={{fontSize: theme.fontSize, marginRight: 10, color: theme.color}}>{passwordOk}</Text>
|
||||
<Button title={_('Save')} onPress={() => onSaveClick()}></Button>
|
||||
</View>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { ListView, View, Text, Button, StyleSheet } = require('react-native');
|
||||
const { ListView, View, Text, Button, StyleSheet, Platform } = require('react-native');
|
||||
const { connect } = require('react-redux');
|
||||
const { Log } = require('lib/log.js');
|
||||
const { reg } = require('lib/registry.js');
|
||||
@@ -43,12 +43,15 @@ class LogScreenComponent extends BaseScreenComponent {
|
||||
paddingBottom:0,
|
||||
},
|
||||
rowText: {
|
||||
fontFamily: 'monospace',
|
||||
fontSize: 10,
|
||||
color: theme.color,
|
||||
},
|
||||
};
|
||||
|
||||
if (Platform.OS !== 'ios') { // Crashes on iOS with error "Unrecognized font family 'monospace'"
|
||||
styles.rowText.fontFamily = 'monospace';
|
||||
}
|
||||
|
||||
styles.rowTextError = Object.assign({}, styles.rowText);
|
||||
styles.rowTextError.color = theme.colorError;
|
||||
|
||||
|
@@ -9,6 +9,7 @@ const Setting = require('lib/models/Setting.js');
|
||||
const Resource = require('lib/models/Resource.js');
|
||||
const Folder = require('lib/models/Folder.js');
|
||||
const { BackButtonService } = require('lib/services/back-button.js');
|
||||
const NavService = require('lib/services/NavService.js');
|
||||
const BaseModel = require('lib/BaseModel.js');
|
||||
const { ActionButton } = require('lib/components/action-button.js');
|
||||
const Icon = require('react-native-vector-icons/Ionicons').default;
|
||||
@@ -61,18 +62,29 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
this.styles_ = {};
|
||||
|
||||
this.backHandler = async () => {
|
||||
const saveDialog = async () => {
|
||||
if (this.isModified()) {
|
||||
let buttonId = await dialogs.pop(this, _('This note has been modified:'), [
|
||||
{ title: _('Save changes'), id: 'save' },
|
||||
{ title: _('Discard changes'), id: 'discard' },
|
||||
{ title: _('Cancel'), id: 'cancel' },
|
||||
{ text: _('Save changes'), id: 'save' },
|
||||
{ text: _('Discard changes'), id: 'discard' },
|
||||
{ text: _('Cancel'), id: 'cancel' },
|
||||
]);
|
||||
|
||||
if (buttonId == 'cancel') return true;
|
||||
if (buttonId == 'save') await this.saveNoteButton_press();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
this.navHandler = async () => {
|
||||
return await saveDialog();
|
||||
}
|
||||
|
||||
this.backHandler = async () => {
|
||||
const r = await saveDialog();
|
||||
if (r) return r;
|
||||
|
||||
if (!this.state.note.id) {
|
||||
return false;
|
||||
}
|
||||
@@ -145,6 +157,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
async componentWillMount() {
|
||||
BackButtonService.addHandler(this.backHandler);
|
||||
NavService.addHandler(this.navHandler);
|
||||
|
||||
await shared.initState(this);
|
||||
|
||||
@@ -157,6 +170,7 @@ class NoteScreenComponent extends BaseScreenComponent {
|
||||
|
||||
componentWillUnmount() {
|
||||
BackButtonService.removeHandler(this.backHandler);
|
||||
NavService.removeHandler(this.navHandler);
|
||||
}
|
||||
|
||||
title_changeText(text) {
|
||||
|
@@ -1,5 +1,6 @@
|
||||
const React = require('react'); const Component = React.Component;
|
||||
const { View, Button } = require('react-native');
|
||||
const { View, Button, Text } = require('react-native');
|
||||
const { stateUtils } = require('lib/reducer.js');
|
||||
const { connect } = require('react-redux');
|
||||
const { reg } = require('lib/registry.js');
|
||||
const { Log } = require('lib/log.js');
|
||||
@@ -10,7 +11,7 @@ const Note = require('lib/models/Note.js');
|
||||
const Setting = require('lib/models/Setting.js');
|
||||
const { themeStyle } = require('lib/components/global-style.js');
|
||||
const { ScreenHeader } = require('lib/components/screen-header.js');
|
||||
const { MenuOption, Text } = require('react-native-popup-menu');
|
||||
const { MenuOption } = require('react-native-popup-menu');
|
||||
const { _ } = require('lib/locale.js');
|
||||
const { ActionButton } = require('lib/components/action-button.js');
|
||||
const { dialogs } = require('lib/dialogs.js');
|
||||
@@ -23,6 +24,43 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
return { header: null };
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.sortButton_press = async () => {
|
||||
const buttons = [];
|
||||
const sortNoteOptions = Setting.enumOptions('notes.sortOrder.field');
|
||||
|
||||
const makeCheckboxText = function(selected, sign, label) {
|
||||
const s = sign === 'tick' ? '✓' : '⬤'
|
||||
return (selected ? (s + ' ') : '') + label;
|
||||
}
|
||||
|
||||
for (let field in sortNoteOptions) {
|
||||
if (!sortNoteOptions.hasOwnProperty(field)) continue;
|
||||
buttons.push({
|
||||
text: makeCheckboxText(Setting.value('notes.sortOrder.field') === field, 'bullet', sortNoteOptions[field]),
|
||||
id: { name: 'notes.sortOrder.field', value: field },
|
||||
});
|
||||
}
|
||||
|
||||
buttons.push({
|
||||
text: makeCheckboxText(Setting.value('notes.sortOrder.reverse'), 'tick', '[ ' + Setting.settingMetadata('notes.sortOrder.reverse').label() + ' ]'),
|
||||
id: { name: 'notes.sortOrder.reverse', value: !Setting.value('notes.sortOrder.reverse') },
|
||||
});
|
||||
|
||||
buttons.push({
|
||||
text: makeCheckboxText(Setting.value('uncompletedTodosOnTop'), 'tick', '[ ' + Setting.settingMetadata('uncompletedTodosOnTop').label() + ' ]'),
|
||||
id: { name: 'uncompletedTodosOnTop', value: !Setting.value('uncompletedTodosOnTop') },
|
||||
});
|
||||
|
||||
const r = await dialogs.pop(this, Setting.settingMetadata('notes.sortOrder.field').label(), buttons);
|
||||
if (!r) return;
|
||||
|
||||
Setting.setValue(r.name, r.value);
|
||||
}
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
await this.refreshNotes();
|
||||
}
|
||||
@@ -42,6 +80,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
let options = {
|
||||
order: props.notesOrder,
|
||||
uncompletedTodosOnTop: props.uncompletedTodosOnTop,
|
||||
caseInsensitive: true,
|
||||
};
|
||||
|
||||
const parent = this.parentItem(props);
|
||||
@@ -155,6 +194,7 @@ class NotesScreenComponent extends BaseScreenComponent {
|
||||
title={title}
|
||||
menuOptions={this.menuOptions()}
|
||||
parentComponent={thisComp}
|
||||
sortButton_press={this.sortButton_press}
|
||||
folderPickerOptions={{
|
||||
enabled: this.props.noteSelectionEnabled,
|
||||
mustSelect: true,
|
||||
@@ -178,11 +218,11 @@ const NotesScreen = connect(
|
||||
selectedTagId: state.selectedTagId,
|
||||
notesParentType: state.notesParentType,
|
||||
notes: state.notes,
|
||||
notesOrder: state.notesOrder,
|
||||
notesSource: state.notesSource,
|
||||
uncompletedTodosOnTop: state.settings.uncompletedTodosOnTop,
|
||||
theme: state.settings.theme,
|
||||
noteSelectionEnabled: state.noteSelectionEnabled,
|
||||
notesOrder: stateUtils.notesOrder(state.settings),
|
||||
};
|
||||
}
|
||||
)(NotesScreenComponent)
|
||||
|
@@ -33,17 +33,20 @@ dialogs.confirm = (parentComponent, message) => {
|
||||
});
|
||||
};
|
||||
|
||||
dialogs.pop = (parentComponent, message, buttons) => {
|
||||
dialogs.pop = (parentComponent, message, buttons, options = null) => {
|
||||
if (!parentComponent) throw new Error('parentComponent is required');
|
||||
if (!('dialogbox' in parentComponent)) throw new Error('A "dialogbox" component must be defined on the parent component!');
|
||||
|
||||
if (!options) options = {};
|
||||
if (!('buttonFlow' in options)) options.buttonFlow = 'auto';
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
Keyboard.dismiss();
|
||||
|
||||
let btns = [];
|
||||
for (let i = 0; i < buttons.length; i++) {
|
||||
btns.push({
|
||||
text: buttons[i].title,
|
||||
text: buttons[i].text,
|
||||
callback: () => {
|
||||
parentComponent.dialogbox.close();
|
||||
resolve(buttons[i].id);
|
||||
@@ -54,6 +57,7 @@ dialogs.pop = (parentComponent, message, buttons) => {
|
||||
parentComponent.dialogbox.pop({
|
||||
content: message,
|
||||
btns: btns,
|
||||
buttonFlow: options.buttonFlow,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@@ -18,7 +18,7 @@ class FileApiDriverMemory {
|
||||
}
|
||||
|
||||
decodeContent_(content) {
|
||||
return Buffer.from(content, 'base64').toString('ascii');
|
||||
return Buffer.from(content, 'base64').toString('utf-8');
|
||||
}
|
||||
|
||||
itemIndexByPath(path) {
|
||||
@@ -49,14 +49,13 @@ class FileApiDriverMemory {
|
||||
return Promise.resolve(item ? Object.assign({}, item) : null);
|
||||
}
|
||||
|
||||
setTimestamp(path, timestampMs) {
|
||||
async setTimestamp(path, timestampMs) {
|
||||
let item = this.itemByPath(path);
|
||||
if (!item) return Promise.reject(new Error('File not found: ' + path));
|
||||
item.updated_time = timestampMs;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
list(path, options) {
|
||||
async list(path, options) {
|
||||
let output = [];
|
||||
|
||||
for (let i = 0; i < this.items_.length; i++) {
|
||||
@@ -95,11 +94,10 @@ class FileApiDriverMemory {
|
||||
return output;
|
||||
}
|
||||
|
||||
mkdir(path) {
|
||||
async mkdir(path) {
|
||||
let index = this.itemIndexByPath(path);
|
||||
if (index >= 0) return Promise.resolve();
|
||||
if (index >= 0) return;
|
||||
this.items_.push(this.newItem(path, true));
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async put(path, content, options = null) {
|
||||
@@ -116,10 +114,9 @@ class FileApiDriverMemory {
|
||||
this.items_[index].content = this.encodeContent_(content);
|
||||
this.items_[index].updated_time = time.unix();
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
delete(path) {
|
||||
async delete(path) {
|
||||
let index = this.itemIndexByPath(path);
|
||||
if (index >= 0) {
|
||||
let item = Object.assign({}, this.items_[index]);
|
||||
@@ -128,20 +125,17 @@ class FileApiDriverMemory {
|
||||
this.deletedItems_.push(item);
|
||||
this.items_.splice(index, 1);
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
move(oldPath, newPath) {
|
||||
async move(oldPath, newPath) {
|
||||
let sourceItem = this.itemByPath(oldPath);
|
||||
if (!sourceItem) return Promise.reject(new Error('Path not found: ' + oldPath));
|
||||
this.delete(newPath); // Overwrite if newPath already exists
|
||||
sourceItem.path = newPath;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
format() {
|
||||
async format() {
|
||||
this.items_ = [];
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async delta(path, options = null) {
|
||||
@@ -159,9 +153,8 @@ class FileApiDriverMemory {
|
||||
return output;
|
||||
}
|
||||
|
||||
clearRoot() {
|
||||
async clearRoot() {
|
||||
this.items_ = [];
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -27,7 +27,6 @@ class FileApiDriverWebDav {
|
||||
const result = await this.api().execPropFind(path, 0, [
|
||||
'd:getlastmodified',
|
||||
'd:resourcetype',
|
||||
// 'd:getcontentlength', // Remove this once PUT call issue is sorted out
|
||||
]);
|
||||
|
||||
const resource = this.api().objectFromJson(result, ['d:multistatus', 'd:response', 0]);
|
||||
@@ -56,11 +55,7 @@ class FileApiDriverWebDav {
|
||||
}
|
||||
}
|
||||
|
||||
const lastModifiedString = this.api().resourcePropByName(resource, 'string', 'd:getlastmodified');
|
||||
|
||||
// const sizeDONOTUSE = Number(this.api().stringFromJson(resource, ['d:propstat', 0, 'd:prop', 0, 'd:getcontentlength', 0]));
|
||||
// if (isNaN(sizeDONOTUSE)) throw new Error('Cannot get content size: ' + JSON.stringify(resource));
|
||||
|
||||
const lastModifiedString = this.api().resourcePropByName(resource, 'string', 'd:getlastmodified');
|
||||
|
||||
// Note: Not all WebDAV servers return a getlastmodified date (eg. Seafile, which doesn't return the
|
||||
// property for folders) so we can only throw an error if it's a file.
|
||||
@@ -70,10 +65,8 @@ class FileApiDriverWebDav {
|
||||
|
||||
return {
|
||||
path: path,
|
||||
// created_time: lastModifiedDate.getTime(),
|
||||
updated_time: lastModifiedDate.getTime(),
|
||||
isDir: isDir,
|
||||
// sizeDONOTUSE: sizeDONOTUSE, // This property is used only for the WebDAV PUT hack (see below) so mark it as such so that it can be removed with the hack later on.
|
||||
};
|
||||
}
|
||||
|
||||
|
@@ -39,12 +39,14 @@ class FileApi {
|
||||
this.syncTargetId_ = null;
|
||||
this.tempDirName_ = null;
|
||||
this.driver_.fileApi_ = this;
|
||||
this.requestRepeatCount_ = null; // For testing purpose only - normally this value should come from the driver
|
||||
}
|
||||
|
||||
// Ideally all requests repeating should be done at the FileApi level to remove duplicate code in the drivers, but
|
||||
// historically some drivers (eg. OneDrive) are already handling request repeating, so this is optional, per driver,
|
||||
// and it defaults to no repeating.
|
||||
requestRepeatCount() {
|
||||
if (this.requestRepeatCount_ !== null) return this.requestRepeatCount_;
|
||||
if (this.driver_.requestRepeatCount) return this.driver_.requestRepeatCount();
|
||||
return 0;
|
||||
}
|
||||
@@ -302,7 +304,13 @@ async function basicDelta(path, getDirStatFn, options) {
|
||||
newContext.deletedItemsProcessed = true;
|
||||
|
||||
const hasMore = output.length >= outputLimit;
|
||||
if (!hasMore) newContext.statsCache = null;
|
||||
|
||||
if (!hasMore) {
|
||||
// Clear temporary info from context. It's especially important to remove deletedItemsProcessed
|
||||
// so that they are processed again on the next sync.
|
||||
newContext.statsCache = null;
|
||||
delete newContext.deletedItemsProcessed;
|
||||
}
|
||||
|
||||
return {
|
||||
hasMore: hasMore,
|
||||
|
24
ReactNativeClient/lib/fs-driver-base.js
Normal file
24
ReactNativeClient/lib/fs-driver-base.js
Normal file
@@ -0,0 +1,24 @@
|
||||
class FsDriverBase {
|
||||
|
||||
async isDirectory(path) {
|
||||
const stat = await this.stat(path);
|
||||
return !stat ? false : stat.isDirectory();
|
||||
}
|
||||
|
||||
async readDirStatsHandleRecursion_(basePath, stat, output, options) {
|
||||
if (options.recursive && stat.isDirectory()) {
|
||||
const subPath = basePath + '/' + stat.path;
|
||||
const subStats = await this.readDirStats(subPath, options);
|
||||
for (let j = 0; j < subStats.length; j++) {
|
||||
const subStat = subStats[j];
|
||||
subStat.path = stat.path + '/' + subStat.path;
|
||||
output.push(subStat);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = FsDriverBase;
|
@@ -1,7 +1,8 @@
|
||||
const fs = require('fs-extra');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const FsDriverBase = require('lib/fs-driver-base');
|
||||
|
||||
class FsDriverNode {
|
||||
class FsDriverNode extends FsDriverBase {
|
||||
|
||||
fsErrorToJsError_(error, path = null) {
|
||||
let msg = error.toString();
|
||||
@@ -81,9 +82,14 @@ class FsDriverNode {
|
||||
|
||||
async stat(path) {
|
||||
try {
|
||||
const s = await fs.stat(path);
|
||||
s.path = path;
|
||||
return s;
|
||||
const stat = await fs.stat(path);
|
||||
return {
|
||||
birthtime: stat.birthtime,
|
||||
mtime: stat.mtime,
|
||||
isDirectory: () => stat.isDirectory(),
|
||||
path: path,
|
||||
size: stat.size,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error.code == 'ENOENT') return null;
|
||||
throw error;
|
||||
@@ -94,14 +100,26 @@ class FsDriverNode {
|
||||
return fs.utimes(path, timestampDate, timestampDate);
|
||||
}
|
||||
|
||||
async readDirStats(path) {
|
||||
let items = await fs.readdir(path);
|
||||
async readDirStats(path, options = null) {
|
||||
if (!options) options = {};
|
||||
if (!('recursive' in options)) options.recursive = false;
|
||||
|
||||
let items = [];
|
||||
try {
|
||||
items = await fs.readdir(path);
|
||||
} catch (error) {
|
||||
throw this.fsErrorToJsError_(error);
|
||||
}
|
||||
|
||||
let output = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let stat = await this.stat(path + '/' + items[i]);
|
||||
const item = items[i];
|
||||
let stat = await this.stat(path + '/' + item);
|
||||
if (!stat) continue; // Has been deleted between the readdir() call and now
|
||||
stat.path = stat.path.substr(path.length + 1);
|
||||
output.push(stat);
|
||||
|
||||
output = await this.readDirStatsHandleRecursion_(path, stat, output, options);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -122,14 +140,22 @@ class FsDriverNode {
|
||||
}
|
||||
}
|
||||
|
||||
readFile(path, encoding = 'utf8') {
|
||||
if (encoding === 'Buffer') return fs.readFile(path); // Returns the raw buffer
|
||||
return fs.readFile(path, encoding);
|
||||
async readFile(path, encoding = 'utf8') {
|
||||
try {
|
||||
if (encoding === 'Buffer') return await fs.readFile(path); // Returns the raw buffer
|
||||
return await fs.readFile(path, encoding);
|
||||
} catch (error) {
|
||||
throw this.fsErrorToJsError_(error, path);
|
||||
}
|
||||
}
|
||||
|
||||
// Always overwrite destination
|
||||
async copy(source, dest) {
|
||||
return fs.copy(source, dest, { overwrite: true });
|
||||
try {
|
||||
return await fs.copy(source, dest, { overwrite: true });
|
||||
} catch (error) {
|
||||
throw this.fsErrorToJsError_(error, source);
|
||||
}
|
||||
}
|
||||
|
||||
async unlink(path) {
|
||||
|
@@ -1,6 +1,7 @@
|
||||
const RNFS = require('react-native-fs');
|
||||
const FsDriverBase = require('lib/fs-driver-base');
|
||||
|
||||
class FsDriverRN {
|
||||
class FsDriverRN extends FsDriverBase {
|
||||
|
||||
appendFileSync(path, string) {
|
||||
throw new Error('Not implemented');
|
||||
@@ -34,13 +35,18 @@ class FsDriverRN {
|
||||
};
|
||||
}
|
||||
|
||||
async readDirStats(path) {
|
||||
async readDirStats(path, options = null) {
|
||||
if (!options) options = {};
|
||||
if (!('recursive' in options)) options.recursive = false;
|
||||
|
||||
let items = await RNFS.readDir(path);
|
||||
let output = [];
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
const relativePath = item.path.substr(path.length + 1);
|
||||
output.push(this.rnfsStatToStd_(item, relativePath));
|
||||
|
||||
output = await this.readDirStatsHandleRecursion_(path, item, output, options);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -62,7 +68,7 @@ class FsDriverRN {
|
||||
const r = await RNFS.stat(path);
|
||||
return this.rnfsStatToStd_(r, path);
|
||||
} catch (error) {
|
||||
if (error && error.message && error.message.indexOf('exist') >= 0) {
|
||||
if (error && ((error.message && error.message.indexOf('exist') >= 0) || error.code === 'ENOENT')) {
|
||||
// Probably { [Error: File does not exist] framesToPop: 1, code: 'EUNSPECIFIED' }
|
||||
// which unfortunately does not have a proper error code. Can be ignored.
|
||||
return null;
|
||||
@@ -120,7 +126,7 @@ class FsDriverRN {
|
||||
try {
|
||||
await RNFS.unlink(path);
|
||||
} catch (error) {
|
||||
if (error && error.message && error.message.indexOf('exist') >= 0) {
|
||||
if (error && ((error.message && error.message.indexOf('exist') >= 0) || error.code === 'ENOENT')) {
|
||||
// Probably { [Error: File does not exist] framesToPop: 1, code: 'EUNSPECIFIED' }
|
||||
// which unfortunately does not have a proper error code. Can be ignored.
|
||||
} else {
|
||||
|
@@ -617,10 +617,6 @@ function enexXmlToMdArray(stream, resources) {
|
||||
});
|
||||
}
|
||||
|
||||
function removeTableCellNewLines(cellText) {
|
||||
return cellText.replace(/\n+/g, " ");
|
||||
}
|
||||
|
||||
function tableHasSubTables(table) {
|
||||
for (let trIndex = 0; trIndex < table.lines.length; trIndex++) {
|
||||
const tr = table.lines[trIndex];
|
||||
@@ -689,8 +685,9 @@ function drawTable(table) {
|
||||
line.push(BLOCK_CLOSE);
|
||||
} else { // Regular table rendering
|
||||
|
||||
// A cell in a Markdown table cannot have new lines so remove them
|
||||
const cellText = removeTableCellNewLines(processMdArrayNewLines(td.lines));
|
||||
// A cell in a Markdown table cannot have actual new lines so replace
|
||||
// them with <br>, which are supported by the markdown renderers.
|
||||
const cellText = processMdArrayNewLines(td.lines).replace(/\n+/g, "<br>");
|
||||
|
||||
const width = Math.max(cellText.length, 3);
|
||||
line.push(stringPadding(cellText, width, ' ', stringPadding.RIGHT));
|
||||
|
@@ -15,6 +15,16 @@ class Note extends BaseItem {
|
||||
return 'notes';
|
||||
}
|
||||
|
||||
static fieldToLabel(field) {
|
||||
const fieldsToLabels = {
|
||||
title: 'title',
|
||||
user_updated_time: 'updated date',
|
||||
user_created_time: 'created date',
|
||||
};
|
||||
|
||||
return field in fieldsToLabels ? fieldsToLabels[field] : field;
|
||||
}
|
||||
|
||||
static async serialize(note, type = null, shownKeys = null) {
|
||||
let fieldNames = this.fieldNames();
|
||||
fieldNames.push('type_');
|
||||
|
@@ -4,6 +4,8 @@ const { Logger } = require('lib/logger.js');
|
||||
const SyncTargetRegistry = require('lib/SyncTargetRegistry.js');
|
||||
const { time } = require('lib/time-utils.js');
|
||||
const { sprintf } = require('sprintf-js');
|
||||
const ObjectUtils = require('lib/ObjectUtils');
|
||||
const { toTitleCase } = require('lib/string-utils.js');
|
||||
const { _, supportedLocalesToLanguages, defaultLocale } = require('lib/locale.js');
|
||||
|
||||
class Setting extends BaseModel {
|
||||
@@ -19,12 +21,16 @@ class Setting extends BaseModel {
|
||||
static metadata() {
|
||||
if (this.metadata_) return this.metadata_;
|
||||
|
||||
// A "public" setting means that it will show up in the various config screens (or config command for the CLI tool), however
|
||||
// if if private a setting might still be handled and modified by the app. For instance, the settings related to sorting notes are not
|
||||
// public for the mobile and desktop apps because they are handled separately in menus.
|
||||
|
||||
this.metadata_ = {
|
||||
'activeFolderId': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||
'firstStart': { value: true, type: Setting.TYPE_BOOL, public: false },
|
||||
'editor': { value: '', type: Setting.TYPE_STRING, public: true, appTypes: ['cli'], label: () => _('Text editor'), description: () => _('The editor that will be used to open a note. If none is provided it will try to auto-detect the default editor.') },
|
||||
'locale': { value: defaultLocale(), type: Setting.TYPE_STRING, isEnum: true, public: true, label: () => _('Language'), options: () => {
|
||||
return supportedLocalesToLanguages();
|
||||
return ObjectUtils.sortByValue(supportedLocalesToLanguages());
|
||||
}},
|
||||
'dateFormat': { value: Setting.DATE_FORMAT_1, type: Setting.TYPE_STRING, isEnum: true, public: true, label: () => _('Date format'), options: () => {
|
||||
let options = {}
|
||||
@@ -49,16 +55,17 @@ class Setting extends BaseModel {
|
||||
output[Setting.THEME_DARK] = _('Dark');
|
||||
return output;
|
||||
}},
|
||||
// 'logLevel': { value: Logger.LEVEL_INFO, type: Setting.TYPE_STRING, isEnum: true, public: true, label: () => _('Log level'), options: () => {
|
||||
// return Logger.levelEnum();
|
||||
// }},
|
||||
// Not used for now:
|
||||
// 'todoFilter': { value: 'all', type: Setting.TYPE_STRING, isEnum: true, public: false, appTypes: ['mobile'], label: () => _('Todo filter'), options: () => ({
|
||||
// all: _('Show all'),
|
||||
// recent: _('Non-completed and recently completed ones'),
|
||||
// nonCompleted: _('Non-completed ones only'),
|
||||
// })},
|
||||
'uncompletedTodosOnTop': { value: true, type: Setting.TYPE_BOOL, public: true, label: () => _('Show uncompleted to-dos on top of the lists') },
|
||||
'uncompletedTodosOnTop': { value: true, type: Setting.TYPE_BOOL, public: true, appTypes: ['cli'], label: () => _('Uncompleted to-dos on top') },
|
||||
'notes.sortOrder.field': { value: 'user_updated_time', type: Setting.TYPE_STRING, isEnum: true, public: true, appTypes: ['cli'], label: () => _('Sort notes by'), options: () => {
|
||||
const Note = require('lib/models/Note');
|
||||
const noteSortFields = ['user_updated_time', 'user_created_time', 'title'];
|
||||
const options = {};
|
||||
for (let i = 0; i < noteSortFields.length; i++) {
|
||||
options[noteSortFields[i]] = toTitleCase(Note.fieldToLabel(noteSortFields[i]));
|
||||
}
|
||||
return options;
|
||||
}},
|
||||
'notes.sortOrder.reverse': { value: true, type: Setting.TYPE_BOOL, public: true, label: () => _('Reverse sort order'), appTypes: ['cli'] },
|
||||
'trackLocation': { value: true, type: Setting.TYPE_BOOL, public: true, label: () => _('Save geo-location with notes') },
|
||||
'newTodoFocus': { value: 'title', type: Setting.TYPE_STRING, isEnum: true, public: true, appTypes: ['desktop'], label: () => _('When creating a new to-do:'), options: () => {
|
||||
return {
|
||||
@@ -76,7 +83,8 @@ class Setting extends BaseModel {
|
||||
'encryption.enabled': { value: false, type: Setting.TYPE_BOOL, public: false },
|
||||
'encryption.activeMasterKeyId': { value: '', type: Setting.TYPE_STRING, public: false },
|
||||
'encryption.passwordCache': { value: {}, type: Setting.TYPE_OBJECT, public: false },
|
||||
'style.zoom': {value: "100", type: Setting.TYPE_INT, public: true, appTypes: ['desktop'], label: () => _('Set application zoom percentage'), minimum: "50", maximum: "500", step: "10"},
|
||||
'style.zoom': {value: "100", type: Setting.TYPE_INT, public: true, appTypes: ['desktop'], label: () => _('Global zoom percentage'), minimum: "50", maximum: "500", step: "10"},
|
||||
'style.editor.fontFamily': {value: "", type: Setting.TYPE_STRING, public: true, appTypes: ['desktop'], label: () => _('Editor font family'), description: () => _('The font name will not be checked. If incorrect or empty, it will default to a generic monospace font.')},
|
||||
'autoUpdateEnabled': { value: true, type: Setting.TYPE_BOOL, public: true, appTypes: ['desktop'], label: () => _('Automatically update the application') },
|
||||
'sync.interval': { value: 300, type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation interval'), options: () => {
|
||||
return {
|
||||
@@ -91,7 +99,7 @@ class Setting extends BaseModel {
|
||||
}},
|
||||
'noteVisiblePanes': { value: ['editor', 'viewer'], type: Setting.TYPE_ARRAY, public: false, appTypes: ['desktop'] },
|
||||
'showAdvancedOptions': { value: false, type: Setting.TYPE_BOOL, public: true, appTypes: ['mobile' ], label: () => _('Show advanced options') },
|
||||
'sync.target': { value: SyncTargetRegistry.nameToId('onedrive'), type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation target'), description: () => _('The target to synchonise to. Each sync target may have additional parameters which are named as `sync.NUM.NAME` (all documented below).'), options: () => {
|
||||
'sync.target': { value: SyncTargetRegistry.nameToId('onedrive'), type: Setting.TYPE_INT, isEnum: true, public: true, label: () => _('Synchronisation target'), description: (appType) => { return appType !== 'cli' ? null : _('The target to synchonise to. Each sync target may have additional parameters which are named as `sync.NUM.NAME` (all documented below).') }, options: () => {
|
||||
return SyncTargetRegistry.idAndLabelPlainObject();
|
||||
}},
|
||||
|
||||
@@ -101,11 +109,11 @@ class Setting extends BaseModel {
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}, public: true, label: () => _('Directory to synchronise with (absolute path)'), description: () => _('The path to synchronise with when file system synchronisation is enabled. See `sync.target`.') },
|
||||
}, public: true, label: () => _('Directory to synchronise with (absolute path)'), description: (appType) => { return appType !== 'cli' ? null : _('The path to synchronise with when file system synchronisation is enabled. See `sync.target`.'); } },
|
||||
|
||||
'sync.5.path': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud') }, public: true, label: () => _('Nexcloud WebDAV URL') },
|
||||
'sync.5.username': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud') }, public: true, label: () => _('Nexcloud username') },
|
||||
'sync.5.password': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud') }, public: true, label: () => _('Nexcloud password'), secure: true },
|
||||
'sync.5.path': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud') }, public: true, label: () => _('Nextcloud WebDAV URL') },
|
||||
'sync.5.username': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud') }, public: true, label: () => _('Nextcloud username') },
|
||||
'sync.5.password': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('nextcloud') }, public: true, label: () => _('Nextcloud password'), secure: true },
|
||||
|
||||
'sync.6.path': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('webdav') }, public: true, label: () => _('WebDAV URL') },
|
||||
'sync.6.username': { value: '', type: Setting.TYPE_STRING, show: (settings) => { return settings['sync.target'] == SyncTargetRegistry.nameToId('webdav') }, public: true, label: () => _('WebDAV username') },
|
||||
@@ -136,6 +144,12 @@ class Setting extends BaseModel {
|
||||
return key in this.metadata();
|
||||
}
|
||||
|
||||
static keyDescription(key, appType = null) {
|
||||
const md = this.settingMetadata(key);
|
||||
if (!md.description) return null;
|
||||
return md.description(appType);
|
||||
}
|
||||
|
||||
static keys(publicOnly = false, appType = null) {
|
||||
if (!this.keys_) {
|
||||
const metadata = this.metadata();
|
||||
@@ -429,7 +443,7 @@ class Setting extends BaseModel {
|
||||
// }
|
||||
// }
|
||||
|
||||
static saveAll() {
|
||||
static async saveAll() {
|
||||
if (!this.saveTimeoutId_) return Promise.resolve();
|
||||
|
||||
this.logger().info('Saving settings...');
|
||||
@@ -444,12 +458,14 @@ class Setting extends BaseModel {
|
||||
queries.push(Database.insertQuery(this.tableName(), s));
|
||||
}
|
||||
|
||||
return BaseModel.db().transactionExecBatch(queries).then(() => {
|
||||
this.logger().info('Settings have been saved.');
|
||||
});
|
||||
await BaseModel.db().transactionExecBatch(queries);
|
||||
|
||||
this.logger().info('Settings have been saved.');
|
||||
}
|
||||
|
||||
static scheduleSave() {
|
||||
if (!Setting.autoSaveEnabled) return;
|
||||
|
||||
if (this.saveTimeoutId_) clearTimeout(this.saveTimeoutId_);
|
||||
|
||||
this.saveTimeoutId_ = setTimeout(() => {
|
||||
@@ -521,4 +537,6 @@ Setting.constants_ = {
|
||||
openDevTools: false,
|
||||
}
|
||||
|
||||
Setting.autoSaveEnabled = true;
|
||||
|
||||
module.exports = Setting;
|
@@ -102,6 +102,10 @@ class Tag extends BaseItem {
|
||||
return this.modelSelectAll('SELECT * FROM tags WHERE id IN ("' + tagIds.join('","') + '")');
|
||||
}
|
||||
|
||||
static async loadByTitle(title) {
|
||||
return this.loadByField('title', title, { caseInsensitive: true });
|
||||
}
|
||||
|
||||
static async setNoteTagsByTitles(noteId, tagTitles) {
|
||||
const previousTags = await this.tagsByNoteId(noteId);
|
||||
const addedTitles = [];
|
||||
@@ -109,14 +113,14 @@ class Tag extends BaseItem {
|
||||
for (let i = 0; i < tagTitles.length; i++) {
|
||||
const title = tagTitles[i].trim().toLowerCase();
|
||||
if (!title) continue;
|
||||
let tag = await this.loadByField('title', title, { caseInsensitive: true });
|
||||
let tag = await this.loadByTitle(title);
|
||||
if (!tag) tag = await Tag.save({ title: title }, { userSideValidation: true });
|
||||
await this.addNote(tag.id, noteId);
|
||||
addedTitles.push(title);
|
||||
}
|
||||
|
||||
for (let i = 0; i < previousTags.length; i++) {
|
||||
if (addedTitles.indexOf(previousTags[i].title) < 0) {
|
||||
if (addedTitles.indexOf(previousTags[i].title.toLowerCase()) < 0) {
|
||||
await this.removeNote(previousTags[i].id, noteId);
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user