From 4267f0a4c85a98ab8321cfebf7213ae7bde109f3 Mon Sep 17 00:00:00 2001 From: Starryi Date: Wed, 21 Sep 2022 13:22:05 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-79767=20=E6=A0=BC=E5=BC=8F=E5=88=B7?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E8=83=8C=E6=99=AF=E9=A2=9C=E8=89=B2-?= =?UTF-8?q?=E8=AE=BE=E8=AE=A1=E5=99=A8=E6=98=BE=E7=A4=BA=E4=B8=8E=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E9=A2=9C=E8=89=B2=E4=B8=8D=E5=90=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【问题原因】 复制粘贴,剪切粘贴,格式刷,三种场景下,单元格内样式和主题色的使用比较混乱, 需要进一步规范下。 比如 什么情况下需要使用原来的样式, 什么情况下需要转换为自定义样式, 什么情况下需要清除主题色,将主题色变为自定义色 【改动思路】 1. 当复制样式的模板和粘贴样式模板相同时,保持样式和主题色不变,不做任何转换 2. 当复制样式的模板和粘贴样式的模板不同时,如果两个模板对应的主题样式单元格不同, 那么需要转换主题单元格样式为自定义样式,以保持被复制的样式。 3. 当复制样式的模板和粘贴样式的模板不同时,清除单元格内的主题色 --- .../fr/design/mainframe/DesignerContext.java | 10 ++ .../theme/utils/CellElementStylePaster.java | 99 +++++++++++++++++++ .../cell/clipboard/CellElementsClip.java | 20 ++++ .../design/mainframe/FormatBrushAction.java | 26 ++++- .../java/com/fr/grid/GridMouseAdapter.java | 2 +- 5 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/theme/utils/CellElementStylePaster.java diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerContext.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerContext.java index 49fffa6cef..4079ae7b22 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerContext.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerContext.java @@ -7,6 +7,7 @@ import com.fr.base.Style; import com.fr.design.base.clipboard.DesignerClipboard; import com.fr.design.designer.TargetComponent; import com.fr.design.dialog.BasicDialog; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.log.FineLoggerFactory; import com.fr.stable.StableUtils; @@ -25,6 +26,8 @@ public class DesignerContext { private static Clipboard clipboard = null; //当前的剪贴板. private static int formatState = FORMAT_STATE_NULL; private static Style[][] referencedStyle = null; + private static String referencedStyleFromTemplatePath = null; + private static TargetComponent referencedElementCasePane; private static int referencedIndex = 0; private static ThreadLocal reportWriteThread = new ThreadLocal(); @@ -114,12 +117,19 @@ public class DesignerContext { public static void setReferencedStyle(Style[][] styles) { referencedStyle = styles; + + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + referencedStyleFromTemplatePath = currentTemplate != null ? currentTemplate.getPath() : null; } public static Style[][] getReferencedStyle() { return referencedStyle; } + public static String getReferencedStyleFromTemplatePath() { + return referencedStyleFromTemplatePath; + } + public static void setReferencedElementCasePane(TargetComponent t) { referencedElementCasePane = t; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/CellElementStylePaster.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/CellElementStylePaster.java new file mode 100644 index 0000000000..983beda5e8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/CellElementStylePaster.java @@ -0,0 +1,99 @@ +package com.fr.design.mainframe.theme.utils; + +import com.fr.base.CloneTransformer; +import com.fr.base.NameStyle; +import com.fr.base.Style; +import com.fr.base.theme.FineColorSynchronizer; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.settings.ThemedCellStyle; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.JTemplate; +import com.fr.log.FineLoggerFactory; +import com.fr.report.cell.TemplateCellElement; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/9/21 + * + * 如果粘贴到的模板主题单元格样式与复制过来的主题单元格样式不同,那么需要转换复制过来的主题单元格样式为自定义样式,以保持被复制的样式。 + * 转换非主题单元格样式内的主题色,以及单元格内的其他主题色,为自定义色 + */ +public class CellElementStylePaster { + + /** + * 为没有实现FCloneable接口的类而抽象出的clone方法包装接口, + * 使用者需要实现此接口方法,调用真正的clone方法. + * @param + */ + private interface CloneExecutor { + T clone(T o) throws Exception; + } + private static boolean needConvertThemedStyleToCustomStyle(NameStyle nameStyle) { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentOpeningOrEditingTemplate(); + if (template != null) { + TemplateTheme theme = template.getTemplateTheme(); + if (theme != null) { + ThemedCellStyle themedCellStyle = theme.getCellStyleList().find(nameStyle.getName()); + return !nameStyle.getRealStyle().equals(themedCellStyle.getStyle()); + } + } + return false; + } + + + private static T convertThemedColorToCustomColor(T o, CloneExecutor executor) { + CloneTransformer.setTransformer(new FineColorSynchronizer.FineColorTransformer(fineColor -> { + fineColor.setHor(-1); + fineColor.setVer(-1); + })); + + Object cloned = null; + try { + cloned = executor.clone(o); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + CloneTransformer.clearTransformer(); + return (T) cloned; + } + + /** + * + * @param cellElement 粘贴到的单元格 + * @return + * 如果粘贴到的模板主题单元格样式与复制过来的主题单元格样式不同,那么需要转换复制过来的主题单元格样式为自定义样式,以保持被复制的样式。 + * 转换非主题单元格样式内的主题色,以及单元格内的其他主题色,为自定义色 + */ + public static TemplateCellElement convertStyleAndColor(TemplateCellElement cellElement) { + Style backupStyle = cellElement.getStyle(); + cellElement = convertThemedColorToCustomColor(cellElement, o -> (TemplateCellElement) o.clone()); + + Style style = convertStyleAndColor(backupStyle); + cellElement.setStyle(style); + + return cellElement; + } + + /** + * + * @param style + * @return + * 如果粘贴到的模板主题单元格样式与复制过来的主题单元格样式不同,那么需要转换复制过来的主题单元格样式为自定义样式,以保持被复制的样式。 + * 转换非主题单元格样式内的主题色 + */ + public static Style convertStyleAndColor(Style style) { + if (style instanceof NameStyle) { + NameStyle nameStyle = (NameStyle) style; + if (needConvertThemedStyleToCustomStyle(nameStyle)) { + style = nameStyle.getRealStyle(); + } + } + if (!(style instanceof NameStyle)) { + style = convertThemedColorToCustomColor(style, o -> (Style) o.clone()); + } + + return style; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/cell/clipboard/CellElementsClip.java b/designer-realize/src/main/java/com/fr/design/cell/clipboard/CellElementsClip.java index b54c871e0a..cef0d1d841 100644 --- a/designer-realize/src/main/java/com/fr/design/cell/clipboard/CellElementsClip.java +++ b/designer-realize/src/main/java/com/fr/design/cell/clipboard/CellElementsClip.java @@ -6,6 +6,9 @@ package com.fr.design.cell.clipboard; import com.fr.base.TableData; import com.fr.design.base.clipboard.ClipboardHelper; import com.fr.design.data.tabledata.paste.TableDataFollowingPasteUtils; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.theme.utils.CellElementStylePaster; import com.fr.grid.selection.CellSelection; import com.fr.log.FineLoggerFactory; import com.fr.report.cell.CellElement; @@ -20,11 +23,13 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; /** * The clip of CellElement. */ public class CellElementsClip implements Cloneable, java.io.Serializable { + private String copyFromTemplatePath; private int columnSpan = 0; private int rowSpan = 0; private FU[] columnWidth; @@ -39,6 +44,7 @@ public class CellElementsClip implements Cloneable, java.io.Serializable { this.rowHeight = rowHeight; this.clips = clips; this.elementUsedTableDatas = TableDataFollowingPasteUtils.transferProvider2TableDataMap(clips); + this.copyFromTemplatePath = this.getCurrentTemplatePath(); } public CellElementsClip(int columnSpan, int rowSpan, TemplateCellElement[] clips) { @@ -46,6 +52,7 @@ public class CellElementsClip implements Cloneable, java.io.Serializable { this.rowSpan = rowSpan; this.clips = clips; this.elementUsedTableDatas = TableDataFollowingPasteUtils.transferProvider2TableDataMap(clips); + this.copyFromTemplatePath = this.getCurrentTemplatePath(); } public int getColumnSpan() { @@ -133,6 +140,12 @@ public class CellElementsClip implements Cloneable, java.io.Serializable { return null; } + String pasteToTemplatePath = this.getCurrentTemplatePath(); + boolean pastingToDifferentTemplate = copyFromTemplatePath != null && pasteToTemplatePath != null && !Objects.equals(copyFromTemplatePath, pasteToTemplatePath); + if (pastingToDifferentTemplate) { + cellElement = CellElementStylePaster.convertStyleAndColor(cellElement); + } + // peter:因为前面已经将这个位置的元素删除了,所以不需要override了. ec.addCellElement((TemplateCellElement) cellElement.deriveCellElement( column + cellElement.getColumn(), row + cellElement.getRow() @@ -176,6 +189,11 @@ public class CellElementsClip implements Cloneable, java.io.Serializable { } } + private String getCurrentTemplatePath() { + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + return currentTemplate != null ? currentTemplate.getPath() : null; + } + /** * Clone. */ @@ -183,6 +201,8 @@ public class CellElementsClip implements Cloneable, java.io.Serializable { public Object clone() throws CloneNotSupportedException { CellElementsClip cloned = (CellElementsClip) super.clone(); + cloned.copyFromTemplatePath = this.copyFromTemplatePath; + if (this.clips != null) { cloned.clips = new TemplateCellElement[this.clips.length]; for (int i = 0; i < this.clips.length; i++) { diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/FormatBrushAction.java b/designer-realize/src/main/java/com/fr/design/mainframe/FormatBrushAction.java index 1256c76644..9ec053bd01 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/FormatBrushAction.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/FormatBrushAction.java @@ -4,6 +4,8 @@ import com.fr.base.Style; import com.fr.design.actions.ElementCaseAction; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.theme.utils.CellElementStylePaster; import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; @@ -13,6 +15,7 @@ import com.fr.report.elementcase.TemplateElementCase; import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; +import java.util.Objects; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; @@ -48,7 +51,7 @@ public class FormatBrushAction extends ElementCaseAction { if (cellRectangleCount > 1) { //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 //判断是不是连续区域 - //荣国是连续区域,那么这些长方形的长加起来应该等于 + //如果是连续区域,那么这些长方形的长加起来应该等于 if (!isContinueArea()) { JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Can_Not_Use_Format_Brush")); ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); @@ -103,7 +106,14 @@ public class FormatBrushAction extends ElementCaseAction { } - public void updateFormatBrush(Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { + /** + * 将格式刷获取到的样式,应用到指定单元格区域 + * @param referencedStyleFromTemplatePath 格式刷获取到的样式来自哪张模板 + * @param referencedStyle 格式刷获取到的样式 + * @param cs 应用格式刷区域的指定单元格区域 + * @param reportPane 应用格式刷的报表块面板 + */ + public void updateFormatBrush(String referencedStyleFromTemplatePath, Style[][] referencedStyle, CellSelection cs, ElementCasePane reportPane) { //得到被参照的单元格的行列数 if (referencedStyle == null) { return; @@ -132,7 +142,17 @@ public class FormatBrushAction extends ElementCaseAction { cellElement = DefaultThemedTemplateCellElementCase.createInstance(column, row); elementCase.addCellElement(cellElement); } - cellElement.setStyle(referencedStyle[i % columnSpan][j % rowSpan]); + Style style = referencedStyle[i % columnSpan][j % rowSpan]; + + JTemplate pasteToTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + String pasteToTemplatePath = pasteToTemplate != null ? pasteToTemplate.getPath() : null; + boolean pastingToDifferentTemplate = referencedStyleFromTemplatePath != null && pasteToTemplatePath != null && !Objects.equals(referencedStyleFromTemplatePath, pasteToTemplatePath); + + if (pastingToDifferentTemplate) { + style = CellElementStylePaster.convertStyleAndColor(style); + } + + cellElement.setStyle(style); } } diff --git a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java index 61e6484c65..c213a90e46 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java +++ b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java @@ -295,7 +295,7 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous } if (reportPane.getCellNeedTOFormat() != null) { - reportPane.getFormatBrushAction().updateFormatBrush(DesignerContext.getReferencedStyle(), reportPane.getCellNeedTOFormat(), reportPane); + reportPane.getFormatBrushAction().updateFormatBrush(DesignerContext.getReferencedStyleFromTemplatePath(), DesignerContext.getReferencedStyle(), reportPane.getCellNeedTOFormat(), reportPane); reportPane.fireTargetModified(); }