Commit Graph
14 Commits
Author SHA1 Message Date
22e99fc2b7 Tables can be copied and cut: whole tables, rows and cells (#1744) (#1784)
* #1744: WIP

* #1744: Select Table copies and cuts the whole table

Copy of a whole-table selection used to keep only the cells' paragraphs
(copy_blocks flattened a cross-cell range), and Cut only cleared the text.
Now Copy puts the table on the clipboard and Cut removes the table.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1744: selected table rows and cells copy as a table; Cut clears their text

Copy of whole rows, cells of a row or a block of cells puts a table of just
those cells on the clipboard (Table::slice). Cut of rows or cells clears their
text and keeps the rows and cells, as in Word (Word check A).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1744: review fixes

Table::slice widens every row to a merged cell partly selected (no ragged
copy); an empty selected table or cell copies and cuts; a text selection over
exactly a nested table copies it; one selected_table per Cut; tests for
slice merges/widths/controls, tracked and locked cuts, and the text route.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #1744: Cut clears every cell Copy takes; Spike stays off for empty cell selections

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* #1744: a copied part of a percentage-width table keeps a point width

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* ROADMAP: tidy merged header

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* ROADMAP: keep only the #1744 rows over main's version

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* ROADMAP: remove conflict markers; keep only the #1744 rows over main's version

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* #1744: rename the range Cut helper clear_range_cells (main added clear_cells)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Remove conflict markers from ROADMAP.md; leave main's header line alone

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* cargo fmt

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Import Path in table structure after merging main

---------

Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-29 21:47:27 -04:00
Martin BallandClaude Opus 5.5 4963e30eed #3692: a row's gridAfter is bounded like the DOCX reader's
Audit finding 35: Table::cols() added a deserialized row's grid_after
(u32) unchecked, and layout_table sized its column vectors from it, so a
small native JSON document could ask for a 16 GB grid (and overflow the
sum on 32-bit wasm). Row::grid_after() now clamps to MAX_COLS as
first_grid() does and the importer does; cols() sums with saturating
adds; layout reads the bounded value. Test:
tests_budget::a_huge_grid_after_is_bounded_like_the_docx_readers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 21:01:25 -04:00
dotCooCoo 17ba445b1a Tables: Split Table fixes the vertical merges and row content controls it splits
Split Table moved the rows below the caret into a new table and left
their cells and controls as they were. A cell merged down across the
split left the second table starting with a cell that continues a merge
from no cell above, and the first table ending with a merge that no row
continues. A row content control around rows on both sides stayed open
in the first table, and its close went to the second, so a saved file
lost the control around the rows below the split.

Table::split_off now does the split: a merge that the split cuts ends
in the first table and starts again in the second, and a row content
control that the split cuts closes after the first table and opens
again, without its id, before the second.
2026-10-24 10:50:29 -07:00
Jayesh Prajapati 4e692b4123 #3637: A table cell span from a .json file no longer overflows (#3927)
Insert Column, Merge Cells and Delete Column did arithmetic on the raw
CellProps::span, which a .json document can set to any u32, so a span
near u32::MAX overflowed (a panic in debug, a wrapped span in release).
They now work from the clamped span() and cap the result at MAX_COLS.
2026-10-23 11:20:58 -04:00
aiongg 0d3b8eb0cb Integration: track t04
crates/formats/src/odt.rs: t01's Body::new/take_blocks kept; take_blocks finishes tables with t04's TableB::finish (column widths). Test files: both tracks' tests kept whole. Docs: status lines combined, rows unioned or word-merged.
2026-10-22 01:46:17 +00:00
aiongg 53418631eb Merge PR #1739: Tables nest 24 deep at most, so pasting a table into its own cell can't build a document that crashes (#1596)
ROADMAP.md: main's status line kept; both progress-log lines added.
docs/target-app-parity.md: main's status line and Tables row kept, #1596 sentence added to the row; log row added.
2026-10-22 01:20:47 +00:00
aiongg abd1c7fb36 Merge PR #1760: Tables: rows with gridBefore/gridAfter keep their grid columns 2026-10-22 01:19:46 +00:00
NetterSilverandClaude Haiku 5.5 70c5c44f01 Promote the cell below when deleting a vertical merge's first row (#2649)
Found while testing crates/doc/src/table.rs:129 (Table::delete_row), called from crates/engine/src/cmd/table.rs:526 (del_row)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-18 03:43:16 -04:00
aa665b16a9 #2592: Split Cells and Convert Text to Table dialogs (#2593)
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-18 03:21:14 -04:00
dfgodvanandClaude Opus 5.5 e4d9eb61b9 Tables: rows with gridBefore/gridAfter keep their grid columns (part of #1174)
A row that skips grid columns before its first cell (w:gridBefore) was laid
out from column 0, so its cells sat one or more columns to the left and
wrapped at the wrong width (a text cell landing on a 5 pt column sets one
letter per line). Row::first_grid() gives the column the row's first cell
starts at; Table::grid_col, cell_at_grid and cols(), the layout passes,
vertical-merge matching, cell selection and the insert-column spot count
from it, and cols() also counts gridAfter.

The skipped columns stay empty and borderless, as in Word: a row's own
first and last cell carry the table's outer side borders, and AutoFit gives
the skipped columns the row's wBefore/wAfter width.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 13:54:55 +03:00
rabisandClaude Opus 5.5 9e608e85aa #1596: tables nest 24 deep at most; a paste that would go deeper keeps their text as paragraphs
Pasting a table into its own cell doubled the nesting each time, and about a
dozen pastes built a document that overflowed the stack when it was saved as
JSON, copied, closed or replaced by a new one.

Tables now nest at most 24 deep (wordcraft_doc::table::MAX_TABLE_DEPTH), the
depth the .docx reader and writer already keep. Document::insert_fragment
turns a table that would go deeper into its paragraphs, in document order;
Document::insert_block refuses it, so Insert > Table in a cell 24 tables deep
fails with a message and leaves the document as it was. The depth is measured
without recursion. Word has no limit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:25:07 +02:00
968c66a13e Fixes: tracked paste marks, plain paste blank lines, ^p in Replace, Delete/Split columns and cells, Font dialog keeps untouched formatting (#417, #422, #423, #431, #432, #466) (#479)
- Paste under Track Changes marks the paragraph marks it adds as inserted, so Reject All
  joins the paragraphs again (#417).
- Keep Text Only / Paste Special text paste treat paragraph separators as text, not Enter:
  an empty list item between them no longer ends the list (#422).
- Untracked Replace All splits paragraphs at CR / U+2029 in the replacement like a single
  Replace does (#423).
- Delete Columns deletes every grid column the selected cells cover (#431).
- Split Cells refines the grid inside the split cell only; other rows' cells widen over the
  new grid columns, keeping the table width (#432).
- Font dialog sends only the properties the user changed and shows small caps, all caps,
  hidden and spacing from the selection (format.state reports them) (#466).

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-11 17:36:30 -04:00
053bb0fd85 Content controls: keep, show and edit w:sdt (#381) (#392)
* Content controls: keep, show and edit w:sdt (#381)

Content controls are now part of the model instead of being unwrapped on open:
ControlStart/ControlEnd markers around their content (inline or around whole
paragraphs), with table, row and cell wraps for controls around tables,
repeating-section rows and cells. All sdtPr properties round-trip (title, tag,
id, lock, placeholder, temporary, rich/plain text, w14 check box, combo box,
drop-down list, date, picture, building block gallery, w15 repeating
sections); unknown children are kept verbatim. The writer plans per block list
which controls are written inline and which around blocks so the XML always
nests, and drops markers that lost their partner.

Editing: deletions keep a marker whose partner is outside the range, typing
replaces a shown placeholder, emptying a control brings it back, sdtLocked and
contentLocked refuse with a status message. Developer tab with insert
commands, Design Mode, Properties dialog; frames and title tabs on the page,
check boxes toggle on click, list and calendar pickers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* #381: refresh catalog count and parity checklist after rebase

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
2026-10-11 16:36:53 -04:00
Brandon ThomasandClaude Opus 5.5 d1e80df4da M0.1–M0.6: workspace, geom, document model, fonts, layout, render
Clean-room foundations for WordCraft: Arc-shared document model with
paragraph/run editing, styles, lists, sections and tables; Word-style
font substitution; first-fit line breaking with tabs, lists, alignment,
pagination, tables, headers/footers and hit testing; vello_cpu page
rasteriser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 22:30:16 -04:00