The pane drew each heading with `Button::selectable(..).truncate()`, so a heading wider than the
pane ended in an ellipsis and its text had to be read from the hover tooltip. Word wraps the row
instead.
`nav_heading` now wraps: the button takes `Button::wrap()` and a minimum size of the available width
and one row, so the label continues on further lines inside the pane, the row grows with the text,
and the pane still keeps its width. The trailing grow atom still keeps the text flush left under its
parent (#1199). The hover tooltip goes with the ellipsis: nothing is hidden now, and a word wider
than the pane is broken by the wrap instead of overflowing.
The navigation test asserts the wrap instead of the ellipsis. For a heading well past the width and
for a single word wider than the pane, the label has more than one line, is not elided, stays inside
the pane, does not widen it, and takes a taller row than a one-line heading in the same pane.
`docs/ui-parity.md` and `ROADMAP.md` record the new behaviour.
Co-authored-by: Brandon Thomas <brandon@storyteller.ai>
* #662: ribbon groups shrink to fit the window (compact, then one drop-down)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1285: collapsed ribbon groups stay open while used; Styles gallery trims before it folds
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon collapse: accessible name for folded groups, Tables/Links icons (#662)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon: Esc in a collapsed-group popup doesn't leave full screen; tab-strip test ignores same-named ribbon buttons (#1285)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon tab-strip test: pick the tab, not a same-named folded group (#662)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Ribbon: a folded group's open state is keyed by its place in the row, not just its title (#1285)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* rustfmt: collapsed_group signature (#1285)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
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>
* File (Backstage): an icon beside each side-menu item (#1714)
The side menu (Home, New, Open, Info, Save, Save As, Print, Export,
Close, Options) was text only. Each item now has an 18 pt icon in the
label colour, greyed out with it when no document is open. Existing
icons where they fit (house, new page, open folder, info, save, printer,
close), and three new ones drawn in code: Save As (the save disk with a
pencil), Export (a page with an arrow leaving it) and Options (a gear).
Original artwork, no asset files.
Test: every item names its own icon, and each one is a drawn icon, not
the letter-tile fallback an unknown name gets.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: one Backstage row with both the Close (#1712) and side-menu icon (#1714) notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #1348: WIP
* #1348: keep comment drafts per document, keep them on a refused edit, write them before save/close/new/open
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1348: a refused comment draft can be dropped; fields read-only where comments can't change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1348: ui-parity: one Task panes and Context menus row after the rebase
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Docs after rebasing on main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1348: keep the window open while a web save is unconfirmed; split the roadmap row by operation
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1348: pending comment drafts count as unsaved changes for the browser; a save error isn't hidden by a draft refusal
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* #1348: an agent can't replace the document over a pending comment draft without force
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
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>
* #2573: Picture Format › Size takes sizes in any unit, pixels too, and opens a Size dialog
The picture size options were too limited (#2573, and #1901's request to enter pixels without
deforming the picture): the ribbon's W/H fields were points only, rejected "300 px", resized on
every keystroke (one undo step per digit), and there was no way to scale from the original
size, lock or unlock the aspect ratio, or reset the size.
- Picture Format › Size: W/H show the interface unit (Options › Advanced) and take a size typed
in any unit, `px` included; it applies on Enter as one undo step, and the other side follows
so the picture keeps its proportions. A drag still applies live.
- The Size group's launcher (and `picture.size` run without a size) opens a Size dialog: height
and width, scale of the original size or of the size it opened with, Lock aspect ratio,
Relative to original picture size, the original size with its pixels, and Reset.
- `picture.size {"original": true, "scale"?}` sizes from the picture's original size (its pixels
at 96 ppi, read from the image adjustments started from, less what is cropped). A size past
4000 pt that keeps the proportions now shrinks as a whole instead of flattening.
- New strings translated in every interface catalog.
The crop tool already exists (Picture Format › Size › Crop) and is being extended in #2027 and
#2440; options cut off in a narrow window are what #708 and #1293 (ribbon groups that shrink to
fit) address.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* contributors: credit @matteo-andreuzza by their GitHub profile name
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Size keeps the proportions at the 1–4000 pt limits and follows the selection
Review follow-ups (CodeRabbit on #2889):
- Size dialog Reset on a photo larger than 4000 pt (a 6000 px wide one is 4500 pt) set it to
the original size, which `picture.size` then clamped side by side: the picture was flattened.
Reset now shrinks both sides by one factor.
- Locked, a side typed past the limit clamped the other on its own (15×30 pt with width 4000
became 4000×4000). Both sides now scale by one factor.
- `fit_size` (engine) only shrank: a proportional size under 1 pt (scale 1% of 50×200 pt) became
1×2 pt. It now picks the factor nearest 1 that brings both sides within 1–4000 pt, falling
back to side-by-side clamping only for shapes too long and thin for any; the dialog uses it.
- Dialogs aren't modal: picking another picture while the Size dialog was open made OK size it
with the first one's numbers. The form now follows the selection (starts over on the new
object, closes when nothing is left to size).
- Doc comments on the Size form's methods.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Size dialog reads the picture again after a crop, change or resize
Review follow-ups (CodeRabbit on #2889):
- The open Size form only compared the selected object's position. A crop from the ribbon,
Change Picture or a handle drag while the dialog is open left Reset and OK working from the
old crop and size. The form now remembers the picture, crop and size it was read from (bit for
bit, without comparing whole objects that may hold large embedded data) and reads them again
when any changes.
- An egui harness test drives the dialog end to end: launcher, a height typed in pixels, nothing
applied before OK, OK sizes in proportion as one undo step and closes the dialog.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: size fields never resize a picture just by showing it
Review follow-up (CodeRabbit on #2889): egui's DragValue clamps a value already outside its
range when it is drawn and reports that as a change. The Size fields act on changes, so:
- Picture Format's W/H resized a picture smaller than 1 pt (a 1×1 px spacer is 0.75 pt) or
larger than 4000 pt as soon as the tab was shown, an edit and an undo step nobody asked for.
The code before this PR had the same problem with its 4–2000 pt range.
- The Size dialog's scale fields silently changed a picture enlarged past 10000% (a small icon
made large), and its lengths a size outside 1–4000 pt, which OK then applied.
The range now bounds only what is typed or dragged (`clamp_existing_to_range(false)`). Both
regression tests fail without it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Shape Format and Chart Design size fields leave existing sizes alone too
Review follow-up (CodeRabbit on #2889, outside the diff): the same egui clamp as in d56a105.
Shape Format's W/H (4–2000 pt) and Chart Design's (36–2000 pt) clamped a size outside their
range as soon as the tab was shown and resized the object unasked. The new Size dialog makes this
easier to reach, since it takes shapes up to 4000 pt, but a thin line under 4 pt was already cut.
Both now show such a size as it is and act only on a new value. Shape Format's range follows
`picture.size` (1–4000 pt), so dragging a 3000 pt shape no longer snaps it back to 2000.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
* #2573: Esc cancels a size typed in Picture Format; a typed size applies when the field is left
Review follow-up (CodeRabbit on #2889, outside the diff) asked to apply typed sizes on Enter only.
That is not done: a field keeps what was typed when it loses focus, as text fields do, and
otherwise typing a height in the Size dialog and clicking OK would throw it away. A harness test
now pins that path with a real click (press, then release frames later).
Checking it turned up a real bug: Esc did not cancel in the ribbon's W/H fields. egui 0.36 keeps
a DragValue's typed text after Esc and applies it the next frame, when the field still counts as
having just lost focus but Esc is no longer pressed. The fields now remember when Esc ended the
typing and drop that late value. (In the dialog Esc cancels the whole dialog, so nothing applies
there either; both are tested.)
Docs and comments now say "applied once typed (Enter, Tab or a click elsewhere; Esc cancels)"
instead of "applied on Enter".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JZArmeAT48gF84aKj7Zx4C
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #1230: Insert Caption on pictures and shapes; Page Setup header and footer options
- Right-clicking a picture, shape, text box or chart offers Insert Caption…, as in Word.
- references.caption with a picture or shape selected puts the caption next to the
paragraph holding it, in the same cell or text box (it used to go after the whole table).
- The Caption dialog proposes Figure for a picture selected in a table, not Table.
- Page Setup: Headers and footers check boxes (Different Odd & Even Pages, Different First
Page), applied on OK only if changed, in one undo step; a title page can go unnumbered.
- Tests: engine caption_for_an_object_in_a_cell_stays_in_the_cell; kittest
right_click_on_a_picture_offers_insert_caption and
page_setup_different_first_page_leaves_the_title_page_unnumbered.
- Docs: ui-parity, target-app-parity, ROADMAP progress log.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01P8veLveuUsJJm6UEcQPEuW
* ui-parity: keep Insert Caption on the context-menu row
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* #2601: Drop Cap Options dialog
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* gaps: keep the Drop Cap Options note on the dialog-depth row
* i18n: translate the two Drop Cap disabled reasons in the audited catalogs
---------
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>
* #2551: dragging the scrollbar names the page at the top of the window
While the canvas's vertical scrollbar is dragged, a tip beside the pointer
says which page is at the top of the window, in the status bar's words
("Page 7 of 10"), so a drag through a long document shows where it will land.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #2551: the scrollbar tip names the page whose visible band is at the top, also with Hide White Space
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
No Color removed the highlight from the selection, but the Highlight
split button kept the colour picked before, so the next click on it
highlighted again. As in Word, No Color now becomes the button's choice
and the next click removes highlighting. The ribbon and the mini toolbar
share one highlight menu (the ribbon's copy is gone); No Color is
translated in the mini toolbar and no longer shows Ctrl+Alt+H beside it
in the ribbon.
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Word draws no red squiggle under the word being typed. It appears when the word ends or the
caret leaves it by a key or a click. The session records the word after a text command that
edits the caret's paragraph, with apostrophes and hyphens counted as the spelling check counts
them, and drops it once the caret is anywhere else. The layout leaves that one range out of the
spelling squiggles, and a caret move without an edit lays out only that paragraph again. F7 and
the Spelling pane still report the word, and grammar marks are unchanged.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Ruler numbers now thin out as the page shrinks on screen: a number
every 1, 2, 4, 8... units, whichever keeps them at least 30 px apart,
and the small ticks drop out below 4 px, with the text at its usual
size. A number gives way to an indent, tab or column marker sitting on
it, and the margins get ticks only. Both rulers use the caret page's
rect and scale in every layout, including One Page and Multiple Pages,
and follow the caret to another page. Tests cover the density rule, the
marks, the marker rule for indents, tab stops (set or dragged) and
table columns and rows, and the multi-page geometry.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The Quick Access Toolbar's menu ends with Hide Quick Access Toolbar, as Word's does. Show Quick Access Toolbar brings it back from the ribbon's right-click menu and from a check box on Customize Ribbon's Quick Access Toolbar page. The setting is kept between runs, and keytips skip the toolbar's digit badges while it is hidden. The UI command ui.quickAccessToolbar drives it from scripts and MCP. Regenerates docs/parity-checklist.md, which was behind the catalog. Adds my contributor entry.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* fix(ui): expose save confirmation context (#1015)
* #1015: require alert-dialog semantics in save regression
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Paste of plain text from another program gave every line after the first
a paragraph with default formatting. The text became a fragment of
unformatted paragraphs (Fragment::from_text), and insert_fragment keeps
the target's formatting only in the first one. Pasting several lines into
a right-to-left paragraph turned all but the first left-to-right, and the
text after the caret lost its paragraph formatting too.
Paste now inserts plain text as Keep Text Only does. Each line after the
first splits the paragraph as Enter does, so it keeps the paragraph's
direction, style, alignment, indents, spacing and list. Empty lines become
empty paragraphs with that formatting. Copies from WordCraft and HTML or
RTF from other programs keep their own formatting as before. A paste is
still one undo step.
Tests cover a right-to-left paragraph, empty lines and a final line break,
and a list. The typing and UI parity docs and the ROADMAP progress log
have rows for the change.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* File › Close closes the document and keeps the window (#1712)
File › Close (Mod+W, Mod+F4) quit the whole app. In Word it closes the
document and the window stays. WordCraft already has that state from
the Start screen (#1129): no page, the ribbon greyed out but for Help,
File › New and Open to go on.
`WordApp::execute` now handles `file.close` itself. After the usual
Save / Don't Save / Cancel, the document is replaced by the placeholder
blank document that marks "no document open" and the Backstage closes.
The window's close button passes `{"quit": true}`, so it still asks and
then quits. The parameter travels with the prompt, so a Cancel leaves no
state behind. With no document open, Close has nothing to close.
Tests: the Close tests that used `quit_requested` as "Close went through"
now check that the document closed and the window stayed. Closing from
the empty window asks nothing, File › New goes on from there, and the
window's close button still quits after Don't Save.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Close keeps the window for programmatic closes too (#1712, #1391)
#1391 landed on main meanwhile: a programmatic `file.close` on unsaved
work needs `{"force": true}`. Its tests, and the save prompt's focus
test, took "Close went through" to mean `quit_requested`. With #1712 a
close, forced or not, closes the document and keeps the window, so they
now check that the document closed and the app is still running. The
`force` guard itself is unchanged.
docs/control-protocol.md: a closed document leaves the window open, and
`file.new` or `file.open` goes on from there.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #1712: a direct file.close never discards unsaved changes unless forced; Don't Save forces it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Spike: Ctrl+F3 collects cuts, Ctrl+Shift+F3 inserts them and empties it (gap #24)
* Search test: a lone INSERT's witness within the box's 14 results; Table checked past it
---------
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* track-move-options: WIP
* track-move-options: Moves options in Track Changes Options and w:doNotTrackMoves
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* track-move-options: Moved from Hidden leaves the layout; per-revision hiding
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* track-move-options: Word's mark lists, (none) moves are plain, no borders on collapsed paragraphs
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* track-move-options: hr and sv translations for Moved from:/Moved to:
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
Dialogs, the Read Aloud player and the file browser used egui's small close glyph: the hit area was the glyph alone and hovering only changed its stroke. The close control is now a box at the right end of the title bar, the full title-bar height and 1.6 times as wide, as a Windows caption button on a Word dialog. The whole box closes the window. It fills red with a white cross while the pointer is over it and darker red while pressed and still under the pointer, with colours from the theme tokens in both themes. The box is pointer-only, so Tab never lands on it; dragging from it does not move the window and Escape closes dialogs as before. Its accessibility name is translated like its tooltip.
docs/parity-checklist.md is the regenerated checklist.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The web shell never loaded or saved the UiState the desktop app keeps in
ui.json, so a reload reset the theme and every other preference. It now
restores it from localStorage at startup and writes it back whenever it
changes (a reload runs no exit code).
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The font box (ribbon and mini toolbar) opens with a Recently Used Fonts
section: the fonts applied from the box, the mini toolbar or the Font
dialog, most recent first, once each, ten at most, kept in ui.json. All
Fonts follows. The sections show while nothing is typed; a query lists
its matches only. Up/Down walk the recent entries then the list and Enter
applies the highlighted one; a click on a heading keeps the list open.
The typed list is sized again when its length changes, in a discarded
pass so it never blanks; it used to stay one row tall after a one-match
query. Names over 128 bytes are not kept, and reading a saved list stops
at ten names.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
The strip kept File, the active tab and contextual tabs however narrow the window got, so
they were drawn under the buttons on the right. The strip is now planned first: the buttons
keep their room and the tabs give way in order (tab padding, Comments and Editing labels,
Share label, plain tabs into », active and contextual labels cut with …, last the active tab
into »). File always stays. A regression test checks widths 300-1280 in en, pl and de.
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
With text selected, Layout > Columns used to change the whole section. As in
Word (observed black-box), a continuous section break now goes where the
selection starts and one where it ends, splitting a paragraph there, unless that
end already meets a section boundary (the document's start or end, or an
existing break); the columns go on the section between, in one undo step.
`layout.columns` gains `apply: "selection"`, its default when text is selected
in the main text. More Columns... offers "Selected text" and picks it then.
Co-authored-by: Brandon Thomas <echelon@gmail.com>
With Different First Page on, page 1 shows the first-page header, but
Insert > Header/Footer/Page Number always wrote the default one (which
page 1 no longer shows), Edit Header without a page went to the default
too, and a double-click in page 1's header area was ignored while
another header was being edited (the usual case: edit the header, tick
Different First Page, double-click page 1). Now hf_part and edit_hf use
the slot of the caret's page, and a double-click in a header/footer
zone switches to the one that page shows even from another header.
Fixes#2826Fixes#2811
Claude-Session: https://claude.ai/code/session_013kKPnx8r1vcYumjyL3kcuz
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
A copy or cut of one equation on its own now also puts its MathML in the
platform's MathML clipboard formats, beside the HTML (with MathML, #816) and
the linear text: "MathML" and "MathML Presentation" (UTF-16LE) on Windows,
public.mathml.presentation and public.mathml on macOS. These are the names
W3C MathML 3 section 6.2.4 registers, and Microsoft's "MathML Support in
Microsoft 365" doc says Office checks them first when it pastes math. No
public clipboard format carries OMML. A copy with text around the equation
doesn't offer them, so Word keeps the text.
Not yet verified in Word: the parity docs say MathML clipboard formats, not
an editable paste.
Claude-Session: https://claude.ai/code/session_01P8veLveuUsJJm6UEcQPEuW
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
* fix(ui): draw Arabic and other non-Latin comment text in balloons
Comment balloons and the Comments pane draw comment text and author
names with the interface faces (Inter, Source Sans, CJK), which have no
Arabic, Hebrew, Thai and so on: every such letter was a box. The app now
borrows a document fallback face that covers the comments, as the window
caption does (#840), checked once per document revision.
egui also lays bidi runs and words out left to right, so a right-to-left
comment read backwards. Read-only balloons now wrap the text by word
widths, put each row in display order (Unicode bidi runs, words of a
right-to-left run reversed, brackets mirrored) and set right-to-left
paragraphs against the right edge. Text without right-to-left letters is
laid out exactly as before. The editable fields (the selected balloon and
the Comments pane) keep logical order.
Also adds my contributor entry (sync_github_name).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* One contributor entry each
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Mohamed Youssef <ms.rightsteps@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Brandon Thomas <echelon@gmail.com>
part that inherits its lines sends it, and the picker only shows No Border checked for it.
- CellProps::valign is Option<VAlign>: a cell's own Top (Align Top, w:vAlign="top") beats a
table style part's vertical alignment, and round-trips through .docx.
- tableStyle edit rejects Part fields at the top level without "part".
- "font": null or "" makes a part's font inherited; clearing the dialog's font box sends it.
- Document ui.dialog's optional "part" in docs/control-protocol.md.
Co-authored-by: Dmitrii Khlapov <19991457+dkhlapov@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* #714: table style editor formats every table style part
Modify/New Table Style: "Apply formatting to" any of the 13 ECMA-376
§17.7.6 parts (whole table, header/total row, first/last column,
odd/even row and column bands, four corner cells), each with font,
size, bold, italic, underline, colour, fill, borders (line style,
width, colour; all/none/outside/inside/each edge) and the 9-way cell
alignment, over a live preview.
- doc: TablePart, PartFormat, PartSet; TableStyleParts::part/set_part
(new parts and per-part jc/vAlign in `regions`)
- layout: generic part resolution incl. band2, corner cells, alignment
- docx: every tblStylePr type read/written with pPr jc and tcPr vAlign
- engine: table.newStyle/modifyStyle take ECMA part names, `part`,
`parts`, per-edge `borders`, `underline`, `align`/`vAlign`/`cellAlign`
- ui: dialog moved to dialogs_table_style.rs; ui.dialog takes `part`
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* i18n: Hungarian and French strings for this change
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Review fixes for #887: Bulgarian strings for the table style parts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* #714: Vietnamese strings for the table style parts (main's new vi catalog)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* hr: match the catalog's word for banded
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
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>