Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

Spreadsheet editing: start with plain ods cells, then solve repeated and empty ones

オープン
#766 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
45/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
静か
技術スタック
cpp, xml
領域
backend

調査の方向性

Start with odf_document.cpp, odf_parser.cpp, ooxml_spreadsheet_document.cpp, and the existing DocumentPath::Cell and html::edit flow. First run the existing spreadsheet translation/edit tests, then define the smaller ODS step: enable spreadsheet editability, handle cell value/type and formula behavior, and verify a soffice --convert-to round trip. Repeated and empty cells require a separate writable-node design and are not a small single-file change.

索引モデルが issue の本文から書いたものです。

説明

enhancement feature tracking

Editing is off for spreadsheets everywhere: odf::Document::is_editable returns true only for text/presentation/drawing (odf_document.cpp, // TODO fix spreadsheet editability), and xlsx returns false outright — and cannot save at all (ooxml_spreadsheet_document.cpp, UnsupportedOperation). So the practical target is ods, where save already rebuilds the package from content.xml.

The reason it is off is real, and it is the sparse sheet model. parse_sheet (odf_parser.cpp) only creates a sheet_cell Element for a cell that is non-empty; empty cells are recorded as a range in the sheet's position-keyed maps with null_element_id. And a cell with table:number-columns-repeated / number-rows-repeated gets one Element per column repeat, all pointing at the same pugi::xml_node, flagged is_repeated — which element_is_editable already refuses. Both are exactly the cases where writing through the current editor would be wrong: text_set_content splices the DOM of one text run, so writing a repeated cell writes all of its repeats, and an empty cell has no text run to splice at all.

First step: the cells that already work

A non-empty, non-repeated cell already has a paragraph → text subtree, element_is_editable already walks the parent chain and clears it, and DocumentPath already addresses a cell by position (DocumentPath::Cell, "cell" prefix) rather than by sibling index — so the path survives a sheet that is mostly holes. The missing piece is mostly the document-level gate.

  • Let is_editable be true for DocumentType::spreadsheet, so translate emits contenteditable + data-odr-path for those cells and html::edit can navigate back to them.
  • office:value has to move with the text. A cell carries office:value-type plus a typed attribute; the <text:p> is only the display form. Typing 42 into a float cell and rewriting only the paragraph leaves the old office:value behind, and LibreOffice reads the attribute — the cell silently reverts. So a cell edit is not a text edit: it needs to re-infer the type (or drop to string and clear the typed attributes), which is the first thing that pushes past modifiedText.
  • Formula cells (table:formula) have the same problem, worse: the text is a cached result. Simplest honest behaviour is to refuse, or to clear the formula and keep the literal.
  • A round-trip test through soffice --convert-to is the check that the saved package is actually valid, not just that the bytes changed.

The broader solution: repeated and empty cells

Both are the same shape — the element tree does not have a place to write to — and both are fixed at write time, not at parse time. Neither should inflate the model: expanding repeats or materialising every empty cell up front is what #762 is already dying from.

  • Repeated cells: split on write. Editing one cell of a number-columns-repeated="10" run means rewriting that run as up to three nodes (before / the edited one / after) and fixing the repeat counts, then repointing the affected registry entries. Same on the row axis with number-rows-repeated, which is the harder one because a row split rewrites whole <table:table-row> nodes.
  • Empty cells: materialise on write (#236). An empty cell has a position and a style but no Element. The write path needs to be able to take a DocumentPath::Cell position, create the <table:table-cell> (splitting the surrounding repeat run to make room), give it a <text:p>, and register the new Element — i.e. the same splitting primitive as above, plus insertion.
  • That primitive — give me a writable, unshared xml node for position (c, r) — is the piece worth designing first; both cases and any later style edit go through it. // TODO covered cells / // TODO mark as repeated in odf_parser.cpp sit next to it and are probably worth cleaning up in the same pass, since covered cells must never become writable targets.

What the diff protocol needs

html::edit accepts one thing: {"modifiedText": {path: string}}, and it hard-requires element.as_text(). An empty cell has no text element, so it can never appear in that map — the browser has nothing to attach data-odr-path to either, since translate_sheet writes empty cells as bare <td>. That means:

  • the renderer must mark editable cells (not only text runs) with a path, and
  • the diff needs a cell-shaped entry — value plus type — that edit can apply to a position that has no Element yet.

Worth deciding whether that is a new key alongside modifiedText or a general "modifiedCells" that supersedes the text case for sheets.

Scope

Step one is small and shippable on its own (gate + value/type handling + a round-trip test). The splitting/materialising work is the real body and only makes sense for ods until xlsx can save at all. Related: #236 (empty cells, subsumed by this), #238 (cell overflow), #762 (why nothing here may expand the model).

主要言語
C++
スター
41
フォーク
10
平均マージ
12時間 4分
マージ済み PR(30日)
297

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

opendocument-app/OpenDocument.core のほかの issue

opendocument-app/OpenDocument.core の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。