// Copyright (c) 2026 Storm Dragon // Authors: Storm Dragon, Angus Kola // SPDX-License-Identifier: GPL-3.0-or-later package presentation import ( "strings" "git.stormux.org/storm/cthulhu/internal/atspi" ) // Normalize only the presentation copy. Native names remain coordinates for // ownership and diagnostics. Orca's soffice generator speaks contents first, // then the coordinate; an empty Text value is a blank cell, not a missing name. func libreOfficeFocusSnapshot(snapshot atspi.Snapshot, options Options) atspi.Snapshot { context := snapshot.LibreOffice if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || context == nil || !context.InSpreadsheet { return snapshot } if snapshot.Role == "table" { // Orca omits table size for spreadsheets. These dimensions describe // the sheet capacity, not the populated data. snapshot.TableRowCount, snapshot.TableColumnCount = 0, 0 snapshot.Multiselectable, snapshot.SensitiveKnown = false, false return snapshot } if context.CellEditor && snapshot.Role == "paragraph" { snapshot.Role = "" snapshot.SensitiveKnown = false return snapshot } if snapshot.Role != "table cell" || !context.Cell { return snapshot } snapshot.Name = strings.TrimSpace(context.CellText) snapshot.Text = context.Coordinates // Calc cell formatting in Orca omits container selection capabilities // and insensitive-state chatter; these bits are not cell availability. snapshot.Multiselectable = false snapshot.SensitiveKnown = false if reading_options(options).OnlySpeakDisplayedText { snapshot.Text = "" return snapshot } if snapshot.Name == "" { snapshot.Name = "blank" } return snapshot } // LibreOfficeCellFormula limits Office presentation to verified Calc cells. func LibreOfficeCellFormula(snapshot atspi.Snapshot) string { context := snapshot.LibreOffice if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.Defunct || snapshot.Role != "table cell" || context == nil || !context.InSpreadsheet || !context.Cell { return "" } return context.Formula } // LibreOfficeFormulaText follows Orca's explicit formula command: non-formula // cells report their value, including "empty" when there is no value. func LibreOfficeFormulaText(snapshot atspi.Snapshot) string { context := snapshot.LibreOffice if !atspi.IsLibreOfficeProcess(snapshot.ApplicationProcess) || snapshot.Defunct || snapshot.Role != "table cell" || context == nil || !context.InSpreadsheet || !context.Cell { return "Not in a table." } if formula := LibreOfficeCellFormula(snapshot); formula != "" { return formula } if strings.TrimSpace(context.CellText) != "" { return context.CellText } return "empty" }