- {{ t`Value Keys` }}
+ {{ t`Key Hints` }}
this.setScale(this.scale + 0.1));
this.shortcuts.ctrl.set(['Minus'], () => this.setScale(this.scale - 0.1));
},
@@ -298,6 +319,7 @@ export default defineComponent({
}
this.shortcuts.ctrl.delete(['Enter']);
this.shortcuts.ctrl.delete(['KeyE']);
+ this.shortcuts.ctrl.delete(['KeyH']);
this.shortcuts.ctrl.delete(['Equal']);
this.shortcuts.ctrl.delete(['Minus']);
},
@@ -312,6 +334,7 @@ export default defineComponent({
return this.view.state.doc.toString();
},
async setTemplate(value?: string) {
+ this.templateChanged = false;
if (!this.doc?.isCustom) {
return;
}
@@ -329,6 +352,9 @@ export default defineComponent({
this.scale = Math.max(Math.min(value, 10), 0.15);
},
+ toggleShowHints() {
+ this.showHints = !this.showHints;
+ },
async toggleEditMode() {
if (!this.doc?.isCustom) {
return;
@@ -455,8 +481,69 @@ export default defineComponent({
this.values = await getPrintTemplatePropValues(displayDoc);
this.displayDoc = displayDoc;
},
+ async selectFile() {
+ const { name: fileName, text } = await selectTextFile([
+ { name: 'Template', extensions: ['template.html', 'html'] },
+ ]);
+
+ if (!text) {
+ return;
+ }
+
+ await this.doc?.set('template', text);
+ this.view?.dispatch({
+ changes: { from: 0, to: this.view.state.doc.length, insert: text },
+ });
+
+ if (this.doc?.inserted) {
+ return;
+ }
+
+ let name: string | null = null;
+ if (fileName.endsWith('.template.html')) {
+ name = fileName.split('.template.html')[0];
+ }
+
+ if (!name && fileName.endsWith('.html')) {
+ name = fileName.split('.html')[0];
+ }
+
+ if (!name) {
+ return;
+ }
+
+ await this.doc?.set('name', name);
+ },
+ async saveFile() {
+ const name = this.doc?.name;
+ const template = this.getTemplateEditorState();
+
+ if (!name) {
+ return await showToast({
+ type: 'warning',
+ message: this.t`Print Template Name not set`,
+ });
+ }
+
+ if (!template) {
+ return await showToast({
+ type: 'warning',
+ message: this.t`Print Template is empty`,
+ });
+ }
+
+ const { canceled, filePath } = await getSavePath(name, 'template.html');
+ if (canceled || !filePath) {
+ return;
+ }
+
+ await saveExportData(template, filePath, this.t`Template file saved`);
+ },
},
computed: {
+ applyChangesShortcut() {
+ return [ShortcutKey.ctrl, ShortcutKey.enter];
+ },
view(): EditorView | null {
// @ts-ignore
const { view } = this.$refs.templateEditor ?? {};
@@ -489,11 +576,25 @@ export default defineComponent({
actions.push({
label: this.t`Print Settings`,
group: this.t`View`,
- async action() {
+ action: async () => {
await openSettings(ModelNameEnum.PrintSettings);
},
});
+ if (this.doc.isCustom) {
+ actions.push({
+ label: this.t`Select Template File`,
+ group: this.t`Action`,
+ action: this.selectFile,
+ });
+ }
+
+ actions.push({
+ label: this.t`Save Template File`,
+ group: this.t`Action`,
+ action: this.saveFile,
+ });
+
return actions;
},
fields(): Record {
diff --git a/src/utils/ui.ts b/src/utils/ui.ts
index 671bbda2..91cd3d1b 100644
--- a/src/utils/ui.ts
+++ b/src/utils/ui.ts
@@ -14,10 +14,12 @@ import { handleErrorWithDialog } from 'src/errorHandling';
import { fyo } from 'src/initFyo';
import router from 'src/router';
import { IPC_ACTIONS } from 'utils/messages';
+import { SelectFileOptions } from 'utils/types';
import { App, createApp, h } from 'vue';
import { RouteLocationRaw } from 'vue-router';
import { stringifyCircular } from './';
import { evaluateHidden } from './doc';
+import { selectFile } from './ipcCalls';
import { showSidebar } from './refs';
import {
ActionGroup,
@@ -506,3 +508,66 @@ export function focusOrSelectFormControl(
doc.name = '';
}
+
+export async function selectTextFile(filters?: SelectFileOptions['filters']) {
+ const options = {
+ title: t`Select File`,
+ filters,
+ };
+ const { success, canceled, filePath, data, name } = await selectFile(options);
+
+ if (canceled || !success) {
+ await showToast({
+ type: 'error',
+ message: t`File selection failed`,
+ });
+ return {};
+ }
+
+ const text = new TextDecoder().decode(data);
+ if (!text) {
+ await showToast({
+ type: 'error',
+ message: t`Empty file selected`,
+ });
+
+ return {};
+ }
+
+ return { text, filePath, name };
+}
+
+export enum ShortcutKey {
+ enter = 'enter',
+ ctrl = 'ctrl',
+ pmod = 'pmod',
+ shift = 'shift',
+ alt = 'alt',
+ delete = 'delete',
+ esc = 'esc',
+}
+
+export function getShortcutKeyMap(
+ platform: string
+): Record {
+ if (platform === 'Mac') {
+ return {
+ [ShortcutKey.alt]: '⌥',
+ [ShortcutKey.ctrl]: '⌃',
+ [ShortcutKey.pmod]: '⌘',
+ [ShortcutKey.shift]: 'shift',
+ [ShortcutKey.delete]: 'delete',
+ [ShortcutKey.esc]: 'esc',
+ [ShortcutKey.enter]: 'return',
+ };
+ }
+ return {
+ [ShortcutKey.alt]: 'Alt',
+ [ShortcutKey.ctrl]: 'Ctrl',
+ [ShortcutKey.pmod]: 'Ctrl',
+ [ShortcutKey.shift]: '⇧',
+ [ShortcutKey.delete]: 'Backspace',
+ [ShortcutKey.esc]: 'Esc',
+ [ShortcutKey.enter]: 'Enter',
+ };
+}