diff --git a/apps/client/src/widgets/type_widgets/options/images/images.ts b/apps/client/src/widgets/type_widgets/options/images/images.ts
index 904cd4eb6..50e14cf66 100644
--- a/apps/client/src/widgets/type_widgets/options/images/images.ts
+++ b/apps/client/src/widgets/type_widgets/options/images/images.ts
@@ -17,6 +17,37 @@ const TPL = /*html*/`
.batch-ocr-button {
margin-top: 10px;
}
+ .ocr-language-checkboxes {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: 8px;
+ margin-bottom: 10px;
+ max-height: 200px;
+ overflow-y: auto;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ padding: 10px;
+ }
+ .ocr-language-display {
+ background-color: #f8f9fa;
+ min-height: 38px;
+ padding: 8px 12px;
+ border: 1px solid #dee2e6;
+ border-radius: 4px;
+ font-family: monospace;
+ font-size: 0.9em;
+ }
+ .ocr-language-display .placeholder-text {
+ color: #6c757d;
+ font-style: italic;
+ }
+ .ocr-language-display .language-code {
+ background-color: #e9ecef;
+ padding: 2px 6px;
+ border-radius: 3px;
+ margin-right: 4px;
+ font-weight: 500;
+ }
${t("images.images_section_title")}
@@ -72,23 +103,76 @@ const TPL = /*html*/`
@@ -130,7 +214,8 @@ export default class ImageOptions extends OptionsWidget {
// OCR elements
private $ocrEnabled!: JQuery;
private $ocrAutoProcess!: JQuery;
- private $ocrLanguage!: JQuery;
+ private $ocrLanguageCheckboxes!: JQuery;
+ private $ocrLanguageDisplay!: JQuery;
private $ocrMinConfidence!: JQuery;
private $ocrSettingsWrapper!: JQuery;
private $batchOcrButton!: JQuery;
@@ -164,7 +249,8 @@ export default class ImageOptions extends OptionsWidget {
// OCR settings
this.$ocrEnabled = this.$widget.find(".ocr-enabled");
this.$ocrAutoProcess = this.$widget.find(".ocr-auto-process");
- this.$ocrLanguage = this.$widget.find(".ocr-language");
+ this.$ocrLanguageCheckboxes = this.$widget.find(".ocr-language-checkboxes");
+ this.$ocrLanguageDisplay = this.$widget.find(".ocr-language-display");
this.$ocrMinConfidence = this.$widget.find(".ocr-min-confidence");
this.$ocrSettingsWrapper = this.$widget.find(".ocr-settings-wrapper");
this.$batchOcrButton = this.$widget.find(".batch-ocr-button");
@@ -179,7 +265,7 @@ export default class ImageOptions extends OptionsWidget {
this.$ocrAutoProcess.on("change", () => this.updateCheckboxOption("ocrAutoProcessImages", this.$ocrAutoProcess));
- this.$ocrLanguage.on("change", () => this.updateOption("ocrLanguage", this.$ocrLanguage.val()));
+ this.$ocrLanguageCheckboxes.on("change", "input[type='checkbox']", () => this.updateOcrLanguages());
this.$ocrMinConfidence.on("change", () => this.updateOption("ocrMinConfidence", String(this.$ocrMinConfidence.val()).trim() || "0.6"));
@@ -197,7 +283,7 @@ export default class ImageOptions extends OptionsWidget {
// OCR settings
this.setCheckboxState(this.$ocrEnabled, options.ocrEnabled);
this.setCheckboxState(this.$ocrAutoProcess, options.ocrAutoProcessImages);
- this.$ocrLanguage.val(options.ocrLanguage || "eng");
+ this.setOcrLanguages(options.ocrLanguage || "eng");
this.$ocrMinConfidence.val(options.ocrMinConfidence || "0.6");
this.setImageCompression();
@@ -220,6 +306,59 @@ export default class ImageOptions extends OptionsWidget {
}
}
+ setOcrLanguages(languageString: string) {
+ // Clear all checkboxes first
+ this.$ocrLanguageCheckboxes.find('input[type="checkbox"]').prop('checked', false);
+
+ if (languageString) {
+ // Split by '+' to handle multi-language format like "ron+eng"
+ const languages = languageString.split('+');
+
+ languages.forEach(lang => {
+ const checkbox = this.$ocrLanguageCheckboxes.find(`input[data-language="${lang.trim()}"]`);
+ if (checkbox.length > 0) {
+ checkbox.prop('checked', true);
+ }
+ });
+ }
+
+ this.updateOcrLanguageDisplay();
+ }
+
+ updateOcrLanguages() {
+ const selectedLanguages: string[] = [];
+
+ this.$ocrLanguageCheckboxes.find('input[type="checkbox"]:checked').each(function() {
+ selectedLanguages.push($(this).val() as string);
+ });
+
+ // Join with '+' for Tesseract multi-language format
+ const languageString = selectedLanguages.join('+');
+
+ this.updateOption("ocrLanguage", languageString || "eng");
+ this.updateOcrLanguageDisplay();
+ }
+
+ updateOcrLanguageDisplay() {
+ const selectedLanguages: string[] = [];
+
+ this.$ocrLanguageCheckboxes.find('input[type="checkbox"]:checked').each(function() {
+ selectedLanguages.push($(this).val() as string);
+ });
+
+ const displayContent = this.$ocrLanguageDisplay.find('.placeholder-text, .language-code');
+ displayContent.remove();
+
+ if (selectedLanguages.length === 0) {
+ this.$ocrLanguageDisplay.html(`${t("images.ocr_no_languages_selected")}`);
+ } else {
+ const languageTags = selectedLanguages.map(lang =>
+ `${lang}`
+ ).join('');
+ this.$ocrLanguageDisplay.html(languageTags);
+ }
+ }
+
async startBatchOcr() {
this.$batchOcrButton.prop("disabled", true);
this.$batchOcrProgress.show();