From d29a874bafb3c60287c14ccdbeb0e3d906c500c2 Mon Sep 17 00:00:00 2001 From: "Adrien Minne (adrm)" Date: Mon, 30 Sep 2024 09:54:48 +0200 Subject: [PATCH] [FIX] paint format: properly paint borders and tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the paint format tool was moved from the clipboard plugin to its own store, it didn't handle the borders and tables properly. This commit fixes that by adding the two ClipboardHandlers to the PaintFormatStore. closes odoo/o-spreadsheet#5034 Task: 4213894 Signed-off-by: Lucas Lefèvre (lul) --- .../paint_format_button/paint_format_store.ts | 26 ++++++++++++++----- tests/grid/grid_component.test.ts | 17 +++++++++++- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/components/paint_format_button/paint_format_store.ts b/src/components/paint_format_button/paint_format_store.ts index d5d500272e..3b93a0abfc 100644 --- a/src/components/paint_format_button/paint_format_store.ts +++ b/src/components/paint_format_button/paint_format_store.ts @@ -1,4 +1,7 @@ +import { ClipboardHandler } from "../../clipboard_handlers/abstract_clipboard_handler"; +import { BorderClipboardHandler } from "../../clipboard_handlers/borders_clipboard"; import { CellClipboardHandler } from "../../clipboard_handlers/cell_clipboard"; +import { TableClipboardHandler } from "../../clipboard_handlers/tables_clipboard"; import { SELECTION_BORDER_COLOR } from "../../constants"; import { getClipboardDataPositions } from "../../helpers/clipboard/clipboard_helpers"; import { Get } from "../../store_engine"; @@ -16,7 +19,11 @@ export class PaintFormatStore extends SpreadsheetStore { mutators = ["activate", "cancel", "pasteFormat"] as const; protected highlightStore = this.get(HighlightStore); - private cellClipboardHandler = new CellClipboardHandler(this.getters, this.model.dispatch); + private clipboardHandlers: ClipboardHandler[] = [ + new CellClipboardHandler(this.getters, this.model.dispatch), + new BorderClipboardHandler(this.getters, this.model.dispatch), + new TableClipboardHandler(this.getters, this.model.dispatch), + ]; private status: "inactive" | "oneOff" | "persistent" = "inactive"; private copiedData?: ClipboardContent; @@ -42,10 +49,12 @@ export class PaintFormatStore extends SpreadsheetStore { pasteFormat(target: Zone[]) { if (this.copiedData) { const sheetId = this.getters.getActiveSheetId(); - this.cellClipboardHandler.paste({ zones: target, sheetId }, this.copiedData, { - isCutOperation: false, - pasteOption: "onlyFormat", - }); + for (const handler of this.clipboardHandlers) { + handler.paste({ zones: target, sheetId }, this.copiedData, { + isCutOperation: false, + pasteOption: "onlyFormat", + }); + } } if (this.status === "oneOff") { this.cancel(); @@ -60,7 +69,12 @@ export class PaintFormatStore extends SpreadsheetStore { const sheetId = this.getters.getActiveSheetId(); const zones = this.getters.getSelectedZones(); - return this.cellClipboardHandler.copy(getClipboardDataPositions(sheetId, zones)); + const copiedData = {}; + for (const handler of this.clipboardHandlers) { + Object.assign(copiedData, handler.copy(getClipboardDataPositions(sheetId, zones))); + } + + return copiedData as ClipboardContent; } get highlights(): Highlight[] { diff --git a/tests/grid/grid_component.test.ts b/tests/grid/grid_component.test.ts index c57b0f77b5..e7f3b73ac7 100644 --- a/tests/grid/grid_component.test.ts +++ b/tests/grid/grid_component.test.ts @@ -5,6 +5,7 @@ import { PaintFormatStore } from "../../src/components/paint_format_button/paint import { CellPopoverStore } from "../../src/components/popover"; import { BACKGROUND_GRAY_COLOR, + DEFAULT_BORDER_DESC, DEFAULT_CELL_HEIGHT, DEFAULT_CELL_WIDTH, GRID_ICON_EDGE_LENGTH, @@ -40,6 +41,7 @@ import { selectColumn, selectHeader, selectRow, + setBorders, setCellContent, setCellFormat, setSelection, @@ -64,6 +66,7 @@ import { } from "../test_helpers/dom_helper"; import { getActiveSheetFullScrollInfo, + getBorder, getCell, getCellContent, getCellText, @@ -849,15 +852,17 @@ describe("Grid component", () => { highlightStore = env.getStore(HighlightStore); }); - test("can paste format with mouse once", async () => { + test("can paste format and borders with mouse once", async () => { setCellContent(model, "B2", "b2"); selectCell(model, "B2"); setStyle(model, "B2", { bold: true }); + setBorders(model, "B2", { top: DEFAULT_BORDER_DESC }); paintFormatStore.activate({ persistent: false }); gridMouseEvent(model, "pointerdown", "C8"); expect(getCell(model, "C8")).toBeUndefined(); gridMouseEvent(model, "pointerup", "C8"); expect(getCell(model, "C8")!.style).toEqual({ bold: true }); + expect(getBorder(model, "C8")).toEqual({ top: DEFAULT_BORDER_DESC }); gridMouseEvent(model, "pointerdown", "D8"); expect(getCell(model, "D8")).toBeUndefined(); @@ -865,6 +870,16 @@ describe("Grid component", () => { expect(getCell(model, "D8")).toBeUndefined(); }); + test("Paste format works with table style", () => { + createTable(model, "A1:B2", { styleId: "TableStyleLight11" }); + selectCell(model, "A1"); + paintFormatStore.activate({ persistent: false }); + gridMouseEvent(model, "pointerdown", "C8"); + gridMouseEvent(model, "pointerup", "C8"); + + expect(getCell(model, "C8")?.style).toMatchObject({ fillColor: "#748747" }); + }); + test("can keep the paint format mode persistently", async () => { setCellContent(model, "B2", "b2"); selectCell(model, "B2");