Files

49 lines
1.7 KiB
Go

// Copyright (c) 2026 Storm Dragon
// Authors: Storm Dragon, Angus Kola
// SPDX-License-Identifier: GPL-3.0-or-later
package app
// read_all_locked starts ordinary paced speech from the current virtual
// offset. Progress moves only OCR's cursor and braille; native focus is intact.
func (session *ocrSession) read_all_locked(timestamp uint32) {
if session.cursor == nil || session.readAll == nil {
session.status_locked("OCR Say All is unavailable")
return
}
lines := session.cursor.LinesFrom()
if len(lines) == 0 {
session.status_locked("OCR text boundary")
return
}
job := session.job
session.selectionAnchor = -1
ctx := session.readAll.BeginReadAll(job.ctx, timestamp)
session.readAllContext = ctx
session.readAllDone = make(chan error, 1)
parts := make([]readAllPart, 0, len(lines))
for _, line := range lines {
offset := line.Offset
parts = append(parts, readAllPart{Text: line.Text, Began: func() {
session.mu.Lock()
defer session.mu.Unlock()
if ctx.Err() != nil || !session.current_locked(job) || session.cursor == nil {
return
}
position, ok := session.cursor.Set(offset)
if !ok {
return
}
frame := session.frame_locked(position)
if session.display != nil {
session.display.EnqueueFrame(frame)
}
session.logger.Debug("OCR Say All progress", "command", "read-all", "generation", job.generation,
"focus_path", session.focus.Path, "source_path", session.source.Object.Path, "offset", position.Offset,
"selection_start", -1, "selection_end", -1, "speech_text", line.Text,
"braille_text", frame.Text, "braille_cursor", frame.Cursor)
}})
}
session.speech.Enqueue(speechRequest{ReadAll: parts, Role: "text", Cause: "read-all", context: ctx, result: session.readAllDone})
}