Release v0.6.8: add background image OCR and optional Tesseract
This commit is contained in:
+99
-2
@@ -420,7 +420,7 @@ void search(HWND w, HistoryView *v)
|
||||
auto generation = ++v->generation;
|
||||
v->pending.clear();
|
||||
auto *app = v->app;
|
||||
app->enqueue(
|
||||
app->enqueueHistorySearch(
|
||||
[w, app, q, generation]
|
||||
{
|
||||
try
|
||||
@@ -625,6 +625,8 @@ LRESULT CALLBACK historyProc(HWND w, UINT msg, WPARAM wp, LPARAM lp)
|
||||
int id = LOWORD(wp);
|
||||
if (id == 101 && HIWORD(wp) == EN_CHANGE)
|
||||
{
|
||||
// Reject an older result even during the debounce interval.
|
||||
++v->generation;
|
||||
SetTimer(w, 1, 180, nullptr);
|
||||
return 0;
|
||||
}
|
||||
@@ -732,7 +734,7 @@ LRESULT CALLBACK historyProc(HWND w, UINT msg, WPARAM wp, LPARAM lp)
|
||||
AppendMenuW(menu, MF_STRING, 112, L"Pin / unpin");
|
||||
AppendMenuW(menu, MF_STRING, 113, L"Delete");
|
||||
AppendMenuW(menu, MF_STRING, 114, L"Open full item");
|
||||
AppendMenuW(menu, MF_STRING, 115, L"Copy text from image (Windows OCR)");
|
||||
AppendMenuW(menu, MF_STRING, 115, L"Copy text from image (OCR)");
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
int cmd = TrackPopupMenu(menu, TPM_RETURNCMD, p.x, p.y, 0, w, nullptr);
|
||||
@@ -1057,6 +1059,99 @@ void showAutoOptions(HWND parent, SettingsView *v)
|
||||
showRequestedWindow(w);
|
||||
SetForegroundWindow(w);
|
||||
}
|
||||
struct OcrOptionsView { HWND parent; SettingsView *settings; };
|
||||
Settings ocrDraft(HWND w, OcrOptionsView *v)
|
||||
{
|
||||
auto draft = v->settings->draft;
|
||||
draft.useTesseract = checked(w, 501);
|
||||
draft.tesseractPath = value(w, 502);
|
||||
draft.tesseractLanguages = value(w, 503);
|
||||
validateSettings(draft);
|
||||
return draft;
|
||||
}
|
||||
LRESULT CALLBACK ocrOptionsProc(HWND w, UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
auto *v = reinterpret_cast<OcrOptionsView *>(GetWindowLongPtrW(w, GWLP_USERDATA));
|
||||
if (!v) return DefWindowProcW(w, msg, wp, lp);
|
||||
if (msg == WM_COMMAND)
|
||||
{
|
||||
int id = LOWORD(wp);
|
||||
try
|
||||
{
|
||||
if (id == 507)
|
||||
{
|
||||
if ((INT_PTR)ShellExecuteW(w, L"open", L"https://github.com/UB-Mannheim/tesseract/wiki#tesseract-installer-for-windows",
|
||||
nullptr, nullptr, SW_SHOWNORMAL) <= 32)
|
||||
throw std::runtime_error("Could not open the Tesseract download page in your browser");
|
||||
return 0;
|
||||
}
|
||||
if (id == 504)
|
||||
{
|
||||
wchar_t path[32768]{};
|
||||
OPENFILENAMEW picker{sizeof(picker)};
|
||||
picker.hwndOwner = w; picker.lpstrFile = path; picker.nMaxFile = std::size(path);
|
||||
picker.lpstrFilter = L"Tesseract executable (tesseract.exe)\0tesseract.exe\0Executables\0*.exe\0";
|
||||
picker.Flags = OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
if (GetOpenFileNameW(&picker)) value(w, 502, path);
|
||||
return 0;
|
||||
}
|
||||
if (id == 505 || id == IDOK)
|
||||
{
|
||||
auto draft = ocrDraft(w, v);
|
||||
if (id == 505)
|
||||
{
|
||||
draft.useTesseract = true;
|
||||
validateTesseract(draft);
|
||||
SetDlgItemTextW(w, 506, (L"Ready: " + draft.tesseractLanguages).c_str());
|
||||
return 0;
|
||||
}
|
||||
validateTesseract(draft);
|
||||
v->settings->draft.useTesseract = draft.useTesseract;
|
||||
v->settings->draft.tesseractPath = draft.tesseractPath;
|
||||
v->settings->draft.tesseractLanguages = draft.tesseractLanguages;
|
||||
DestroyWindow(w);
|
||||
return 0;
|
||||
}
|
||||
if (id == IDCANCEL) { DestroyWindow(w); return 0; }
|
||||
}
|
||||
catch (const std::exception &e) { error(w, e); return 0; }
|
||||
}
|
||||
if (msg == WM_CLOSE) { DestroyWindow(w); return 0; }
|
||||
if (msg == WM_NCDESTROY)
|
||||
{
|
||||
EnableWindow(v->parent, TRUE);
|
||||
SetForegroundWindow(v->parent);
|
||||
disposeFont(w); delete v;
|
||||
SetWindowLongPtrW(w, GWLP_USERDATA, 0);
|
||||
}
|
||||
return DefWindowProcW(w, msg, wp, lp);
|
||||
}
|
||||
void showOcrOptions(HWND parent, SettingsView *v)
|
||||
{
|
||||
HWND w = makeWindow(*v->app, L"KSwitcher.OcrOptions", L"Image text recognition", ocrOptionsProc, 640, 450);
|
||||
SetWindowLongPtrW(w, GWLP_HWNDPARENT, (LONG_PTR)parent);
|
||||
SetWindowLongPtrW(w, GWLP_USERDATA, (LONG_PTR)new OcrOptionsView{parent, v});
|
||||
label(w, L"Windows OCR is used by default. Recognition stays on this computer.", 18, 16, 600);
|
||||
checkbox(w, L"Use optional Tesseract 5 instead of Windows OCR", 501, 18, 48, 600);
|
||||
check(w, 501, v->draft.useTesseract);
|
||||
label(w, L"Tesseract executable (blank = detect installed location)", 18, 90, 600);
|
||||
edit(w, 502, 18, 118, 484);
|
||||
value(w, 502, v->draft.tesseractPath);
|
||||
button(w, L"Browse…", 504, 514, 117, 106);
|
||||
label(w, L"Languages used together (for example ukr+eng+rus)", 18, 160, 600);
|
||||
edit(w, 503, 18, 188, 602);
|
||||
value(w, 503, v->draft.tesseractLanguages);
|
||||
button(w, L"Check installation", 505, 18, 228, 180);
|
||||
control(w, L"STATIC", L"", 0, 506, 212, 232, 408, 24);
|
||||
button(w, L"Download Tesseract…", 507, 18, 266, 180);
|
||||
label(w, L"Opens the Windows installer page in your browser.", 212, 270, 408);
|
||||
label(w, L"Changing the engine or languages reprocesses saved images in the background.", 18, 314, 602);
|
||||
label(w, L"Click OK here, then Save in Settings to apply. No downloads are automatic.", 18, 344, 602);
|
||||
button(w, L"OK", IDOK, 406, 390, 100);
|
||||
button(w, L"Cancel", IDCANCEL, 520, 390, 100);
|
||||
EnableWindow(parent, FALSE);
|
||||
showRequestedWindow(w); SetForegroundWindow(w);
|
||||
}
|
||||
LRESULT CALLBACK settingsProc(HWND w, UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
if (msg == WM_DPICHANGED)
|
||||
@@ -1092,6 +1187,7 @@ LRESULT CALLBACK settingsProc(HWND w, UINT msg, WPARAM wp, LPARAM lp)
|
||||
showLogs(*v->app);
|
||||
return 0;
|
||||
}
|
||||
if (id == 257) { showOcrOptions(w, v); return 0; }
|
||||
if (id == 230)
|
||||
{
|
||||
collectLayout(w, v);
|
||||
@@ -1685,6 +1781,7 @@ void showSettings(App &app, bool visible)
|
||||
edit(w, 243, 18, 544, 742);
|
||||
button(w, L"Auto-correction options…", 255, 18, 575, 240);
|
||||
button(w, L"View log…", 256, 278, 575, 220);
|
||||
button(w, L"OCR options…", 257, 518, 575, 242);
|
||||
button(w, L"Import settings…", 250, 18, 606, 145);
|
||||
button(w, L"Export settings…", 251, 173, 606, 145);
|
||||
button(w, L"Snippets…", 252, 328, 606, 110);
|
||||
|
||||
Reference in New Issue
Block a user