Exemplo n.º 1
0
def toggle_search_highlights(browser: Browser, checked: bool):
    """Toggle search highlights on or off"""
    browser._highlight_results = checked
    if not checked:
        clear_highlights(browser.editor.web)
    else:
        on_browser_did_change_row(browser)
Exemplo n.º 2
0
def _on_edit_window(browser: Browser) -> bool:
    """Launch BrowserEditCurrent instance"""
    cids = browser.selectedCards()
    if not cids or not browser.card:
        tooltip("No cards selected")
        return False
    elif len(cids) > 1:
        tooltip("Please select just one card")
        return False

    hide_browser_editor(browser)

    browser.external_editor = aqt.dialogs.open("BrowserEditCurrent",
                                               browser.mw, browser,
                                               browser.card)

    return True
Exemplo n.º 3
0
def on_bulk_convert(browser: Browser):
    selected_nids = browser.selectedNotes()
    if selected_nids:
        dialog = BulkConvertDialog(browser)
        if dialog.exec():
            bulk_convert(browser, selected_nids, dialog.selected_fields())
    else:
        tooltip("No cards selected.")
Exemplo n.º 4
0
def on_batch_edit(browser: Browser) -> None:
    """ Open BatchEditDialog when menu entry is clicked.

    :param browser: Anki browser
    """
    selected_notes = browser.selectedNotes()
    if not selected_notes:
        tooltip("No cards selected.")
        return
    dialog = AddIpaTranscriptDialog(browser, selected_notes)
    dialog.exec_()
Exemplo n.º 5
0
def on_browser_menus_did_init(browser: Browser):
    """Setup menu entries and hotkeys"""
    browser._highlight_results = config["local"]["highlight_by_default"]

    try:
        # used by multiple add-ons, so we check for its existence first
        menu = browser.menuView
    except AttributeError:
        browser.menuView = QMenu("&View")
        browser.menuBar().insertMenu(browser.mw.form.menuTools.menuAction(),
                                     browser.menuView)
        menu = browser.menuView

    menu.addSeparator()

    a = menu.addAction("Highlight Search Results")
    a.setCheckable(True)
    a.setChecked(browser._highlight_results)
    a.setShortcut(QKeySequence(config["local"]["hotkey_toggle_highlights"]))
    a.toggled.connect(
        lambda toggled: toggle_search_highlights(browser, toggled))
Exemplo n.º 6
0
def on_merge_selected(browser: Browser) -> None:
    cids = browser.selectedCards()

    if len(cids) < 2:
        tooltip("At least two cards must be selected.")
        return

    browser.model.beginReset()
    browser.mw.checkpoint(_("Merge fields of selected cards"))

    merge_cards_fields(cids)

    browser.model.endReset()
    browser.mw.reset()

    tooltip(f"{len(cids)} cards merged.", parent=browser)
Exemplo n.º 7
0
def on_run_ocr(browser: Browser):
    selected_nids = browser.selectedNotes()
    num_notes = len(selected_nids)
    config = mw.addonManager.getConfig(__name__)
    if num_notes == 0:
        showInfo("No cards selected.")
        return
    elif askUser(
            f"Are you sure you wish to run OCR processing on {num_notes} notes?"
    ) is False:
        return

    if config.get("tesseract_install_valid") is not True and config.get(
            "text_output_location") == "new_field":
        showInfo(
            f"Note that because this addon changes the note template, you will see a warning about changing the database and uploading to AnkiWeb. \n"
            f"This is normal, and will be shown each time you modify a note template.\n"
            f"This message will be only be shown once.")
        mw.addonManager.writeConfig(__name__, config)

    config[
        "tesseract_install_valid"] = True  # Stop the above msg appearing multiple times

    progress = mw.progress
    ocr = OCR(col=mw.col, progress=progress, languages=config["languages"])
    progress.start(immediate=True, min=0, max=num_notes)
    try:
        ocr.run_ocr_on_notes(note_ids=selected_nids,
                             overwrite_existing=config["overwrite_existing"])
        progress.finish()
        showInfo(f"Processed OCR for {num_notes} cards")

    except pytesseract.TesseractNotFoundError:
        progress.finish()
        showCritical(
            text=f"Could not find a valid Tesseract-OCR installation! \n"
            f"Please visit the addon page in at https://ankiweb.net/shared/info/450181164 for"
            f" install instructions")
    except Exception as errmsg:
        progress.finish()
        showCritical(
            f"Error encountered during processing, attempting to stop AnkiOCR gracefully. Error below:\n"
            f"{errmsg}")
    finally:
        browser.model.reset()
        mw.requireReset()
Exemplo n.º 8
0
def on_rm_ocr_fields(browser: Browser):
    config = mw.addonManager.getConfig(__name__)
    selected_nids = browser.selectedNotes()
    num_notes = len(selected_nids)
    if num_notes == 0:
        showInfo("No cards selected.")
        return
    elif askUser(f"Are you sure you wish to remove the OCR field from {num_notes} notes?") is False:
        return

    progress = mw.progress
    progress.start(immediate=True)
    ocr = OCR(col=mw.col, progress=progress, languages=config["languages"])
    ocr.remove_ocr_on_notes(note_ids=selected_nids)
    mw.progress.finish()
    browser.model.reset()
    mw.requireReset()
    log_messages = logger.handlers[0].flush()
    showInfo(f"Removed the OCR field from {num_notes} cards\n"
             f"{log_messages}")
Exemplo n.º 9
0
def on_run_ocr(browser: Browser):
    time_start = time.time()

    selected_nids = browser.selectedNotes()
    config = mw.addonManager.getConfig(__name__)
    num_notes = len(selected_nids)
    num_batches = ceil(num_notes / config["batch_size"])

    if num_notes == 0:
        showInfo("No cards selected.")
        return
    elif askUser(f"Are you sure you wish to run OCR processing on {num_notes} notes?") is False:
        return

    if config.get("tesseract_install_valid") is not True and config.get("text_output_location") == "new_field":
        showInfo(
            f"Note that because this addon changes the note template, you will see a warning about changing the "
            f"database and uploading to AnkiWeb. \n "
            f"This is normal, and will be shown each time you modify a note template.\n"
            f"This message will be only be shown once.")

    config["tesseract_install_valid"] = True  # Stop the above msg appearing multiple times
    mw.addonManager.writeConfig(__name__, config)

    try:
        progress = mw.progress
        progress.start(immediate=True, min=0, max=num_batches)
        progress.update(value=0, max=num_batches, label="Starting OCR processing...")
    except TypeError:  # old version of Qt/Anki
        progress = None

    ocr = OCR(col=mw.col,
              progress=progress,
              languages=config["languages"],
              text_output_location=config["text_output_location"],
              tesseract_exec_pth=config["tesseract_exec_path"] if config["override_tesseract_exec"] else None,
              batch_size=config["batch_size"], num_threads=config["num_threads"], use_batching=config["use_batching"],
              use_multithreading=config["use_multithreading"])
    try:
        ocr.run_ocr_on_notes(note_ids=selected_nids)
        if progress:
            progress.finish()
        time_taken = time.time() - time_start
        log_messages = logger.handlers[0].flush()
        showInfo(
            f"Processed OCR for {num_notes} notes in {round(time_taken, 1)}s ({round(time_taken / num_notes, 1)}s per note)\n"
            f"{log_messages}")

    except pytesseract.TesseractNotFoundError:
        if progress:
            progress.finish()
        showCritical(text=f"Could not find a valid Tesseract-OCR installation! \n"
                          f"Please visit the addon page in at https://ankiweb.net/shared/info/450181164 for"
                          f" install instructions")

    except (RuntimeError, Exception) as exc:
        from . import __version__ as anki_ocr_version
        from anki.buildinfo import version as anki_version
        import sys
        import platform

        if progress:
            progress.finish()
        msg = f"Error encountered during processing. Debug info: \n" \
              f"Anki Version: {anki_version} , AnkiOCR Version: {anki_ocr_version}\n" \
              f"Platform: {platform.system()} , Python Version: {sys.version}"
        log_messages = logger.handlers[0].flush()
        if len(log_messages) > 0:
            msg += f"Logging message generated during processing:\n{log_messages}"
        exception_str: List[str] = traceback.format_exception(etype=type(exc), value=exc, tb=exc.__traceback__)
        msg += "".join(exception_str)
        showInfo(msg)

    finally:

        browser.model.reset()
        mw.requireReset()