Index: /main/trunk/model-interfaces-dev/atea/ocr/src/components/MainPage.vue
===================================================================
--- /main/trunk/model-interfaces-dev/atea/ocr/src/components/MainPage.vue	(revision 35751)
+++ /main/trunk/model-interfaces-dev/atea/ocr/src/components/MainPage.vue	(revision 35752)
@@ -24,4 +24,9 @@
                 </button>
 
+                <button class="btn-primary" @click="download" :disabled="ocrResult === null || ocrResult.length === 0">
+                    <span class="material-icons">download</span>
+                    <span>{{ translations.get("MainPage_Download") }}</span>
+                </button>
+
                 <button class="btn-primary" @click="reset(false)" :disabled="ocrInProgress">
                     <span class="material-icons">restart_alt</span>
@@ -36,8 +41,6 @@
             <img class="image-display" :src="imageUrl" />
 
-            <div class="text-container">
-                <span v-if="ocrResult === null && !ocrInProgress" class="text-placeholder">{{ translations.get("MainPage_OCRHint") }}</span>
-                <pre>{{ ocrResult }}</pre>
-            </div>
+            <textarea class="text-container" v-model="ocrResult" :placeholder="translations.get('MainPage_OCRHint')"
+                @input="modalChecks.ocrTextEdited = true" />
         </div>
     </div>
@@ -135,8 +138,4 @@
 .ocr-progress {
     grid-column-start: span 2;
-}
-
-.text-container {
-    overflow: scroll;
 }
 </style>
@@ -171,4 +170,8 @@
                 description: "",
                 buttons: []
+            },
+            modalChecks: {
+                ocrTextEdited: false,
+                pendingReset: false
             }
         }
@@ -210,4 +213,16 @@
 
         async doOcr() {
+            if (this.modalChecks.ocrTextEdited) {
+                this.modal.title = this.translations.get("OCREditedModal_Title");
+                this.modal.description = this.translations.get("OCREditedModal_Description");
+                this.modal.buttons = [
+                    this.translations.get("OCREditedModal_ButtonContinue"),
+                    this.translations.get("OCREditedModal_ButtonCancel")
+                ];
+                this.modal.show = true;
+
+                return;
+            }
+
             try {
                 this.ocrInProgress = true;
@@ -225,4 +240,5 @@
 
                 this.ocrResult = result[0].text;
+                this.modalChecks.ocrTextEdited = false;
             }
             catch (ex) {
@@ -253,5 +269,6 @@
         reset(hard) {
             if (!hard) {
-                // TODO: Translate
+                this.modalChecks.pendingReset = true;
+
                 this.modal.title = this.translations.get("NewImageModal_Title");
                 this.modal.description = this.translations.get("NewImageModal_Description");
@@ -259,6 +276,5 @@
                     this.translations.get("NewImageModal_ButtonContinue"),
                     this.translations.get("NewImageModal_ButtonCancel")
-                ]
-                this.modal.resetConfirmation = true;
+                ];
                 this.modal.show = true;
 
@@ -274,14 +290,30 @@
         },
 
-        onModalClose(button) {
+        async onModalClose(button) {
             this.modal.show = false;
 
-            if (this.modal.resetConfirmation) {
+            if (this.modalChecks.pendingReset) {
+                console.log("reset is indeed pending");
                 if (button === "Continue") {
                     this.reset(true);
                 }
 
-                this.modal.resetConfirmation = false;
-            }
+                this.modalChecks.pendingReset = false;
+            }
+            else if (this.modalChecks.ocrTextEdited) {
+                if (button === "Continue") {
+                    this.modalChecks.ocrTextEdited = false;
+                    await this.doOcr();
+                }
+            }
+        },
+
+        async download() {
+            const blob = new Blob([ this.ocrResult ], { type: "text/plain;charset=utf-8" });
+            const date = new Date();
+            const fileName = `ocr-${date.getHours()}${date.getMinutes()}${date.getSeconds()}.txt`;
+
+            const { saveAs } = await import("file-saver");
+            saveAs(blob, fileName);
         }
     }
Index: /main/trunk/model-interfaces-dev/atea/ocr/src/components/ModalDialog.vue
===================================================================
--- /main/trunk/model-interfaces-dev/atea/ocr/src/components/ModalDialog.vue	(revision 35751)
+++ /main/trunk/model-interfaces-dev/atea/ocr/src/components/ModalDialog.vue	(revision 35752)
@@ -1,5 +1,5 @@
 <template>
 <div class="background-cover">
-    <div class="paper">
+    <div class="paper modal">
         <span class="heading3">{{ title }}</span>
         <hr />
@@ -28,4 +28,8 @@
 }
 
+.modal {
+    max-width: 50%;
+}
+
 .buttons {
     display: flex;
