Browse Source

REPORT-79767 格式刷复制背景颜色-设计器显示与预览颜色不同

【问题原因】
复制粘贴,剪切粘贴,格式刷,三种场景下,单元格内样式和主题色的使用比较混乱,
需要进一步规范下。
比如
什么情况下需要使用原来的样式,
什么情况下需要转换为自定义样式,
什么情况下需要清除主题色,将主题色变为自定义色

【改动思路】
1. 当复制样式的模板和粘贴样式模板相同时,保持样式和主题色不变,不做任何转换
2. 当复制样式的模板和粘贴样式的模板不同时,如果两个模板对应的主题样式单元格不同,
那么需要转换主题单元格样式为自定义样式,以保持被复制的样式。
3. 当复制样式的模板和粘贴样式的模板不同时,清除单元格内的主题色
release/11.0
Starryi 2 years ago
parent
commit
4267f0a4c8
  1. 10
      designer-base/src/main/java/com/fr/design/mainframe/DesignerContext.java
  2. 99
      designer-base/src/main/java/com/fr/design/mainframe/theme/utils/CellElementStylePaster.java
  3. 20
      designer-realize/src/main/java/com/fr/design/cell/clipboard/CellElementsClip.java
  4. 26
      designer-realize/src/main/java/com/fr/design/mainframe/FormatBrushAction.java
  5. 2
      designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java

10
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.base.clipboard.DesignerClipboard;
import com.fr.design.designer.TargetComponent; import com.fr.design.designer.TargetComponent;
import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicDialog;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.stable.StableUtils; import com.fr.stable.StableUtils;
@ -25,6 +26,8 @@ public class DesignerContext {
private static Clipboard clipboard = null; //当前的剪贴板. private static Clipboard clipboard = null; //当前的剪贴板.
private static int formatState = FORMAT_STATE_NULL; private static int formatState = FORMAT_STATE_NULL;
private static Style[][] referencedStyle = null; private static Style[][] referencedStyle = null;
private static String referencedStyleFromTemplatePath = null;
private static TargetComponent referencedElementCasePane; private static TargetComponent referencedElementCasePane;
private static int referencedIndex = 0; private static int referencedIndex = 0;
private static ThreadLocal<BasicDialog> reportWriteThread = new ThreadLocal<BasicDialog>(); private static ThreadLocal<BasicDialog> reportWriteThread = new ThreadLocal<BasicDialog>();
@ -114,12 +117,19 @@ public class DesignerContext {
public static void setReferencedStyle(Style[][] styles) { public static void setReferencedStyle(Style[][] styles) {
referencedStyle = styles; referencedStyle = styles;
JTemplate<?,?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
referencedStyleFromTemplatePath = currentTemplate != null ? currentTemplate.getPath() : null;
} }
public static Style[][] getReferencedStyle() { public static Style[][] getReferencedStyle() {
return referencedStyle; return referencedStyle;
} }
public static String getReferencedStyleFromTemplatePath() {
return referencedStyleFromTemplatePath;
}
public static void setReferencedElementCasePane(TargetComponent t) { public static void setReferencedElementCasePane(TargetComponent t) {
referencedElementCasePane = t; referencedElementCasePane = t;
} }

99
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 <T>
*/
private interface CloneExecutor<T> {
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> T convertThemedColorToCustomColor(T o, CloneExecutor<T> 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;
}
}

20
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.base.TableData;
import com.fr.design.base.clipboard.ClipboardHelper; import com.fr.design.base.clipboard.ClipboardHelper;
import com.fr.design.data.tabledata.paste.TableDataFollowingPasteUtils; 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.grid.selection.CellSelection;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.report.cell.CellElement; import com.fr.report.cell.CellElement;
@ -20,11 +23,13 @@ import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* The clip of CellElement. * The clip of CellElement.
*/ */
public class CellElementsClip implements Cloneable, java.io.Serializable { public class CellElementsClip implements Cloneable, java.io.Serializable {
private String copyFromTemplatePath;
private int columnSpan = 0; private int columnSpan = 0;
private int rowSpan = 0; private int rowSpan = 0;
private FU[] columnWidth; private FU[] columnWidth;
@ -39,6 +44,7 @@ public class CellElementsClip implements Cloneable, java.io.Serializable {
this.rowHeight = rowHeight; this.rowHeight = rowHeight;
this.clips = clips; this.clips = clips;
this.elementUsedTableDatas = TableDataFollowingPasteUtils.transferProvider2TableDataMap(clips); this.elementUsedTableDatas = TableDataFollowingPasteUtils.transferProvider2TableDataMap(clips);
this.copyFromTemplatePath = this.getCurrentTemplatePath();
} }
public CellElementsClip(int columnSpan, int rowSpan, TemplateCellElement[] clips) { public CellElementsClip(int columnSpan, int rowSpan, TemplateCellElement[] clips) {
@ -46,6 +52,7 @@ public class CellElementsClip implements Cloneable, java.io.Serializable {
this.rowSpan = rowSpan; this.rowSpan = rowSpan;
this.clips = clips; this.clips = clips;
this.elementUsedTableDatas = TableDataFollowingPasteUtils.transferProvider2TableDataMap(clips); this.elementUsedTableDatas = TableDataFollowingPasteUtils.transferProvider2TableDataMap(clips);
this.copyFromTemplatePath = this.getCurrentTemplatePath();
} }
public int getColumnSpan() { public int getColumnSpan() {
@ -133,6 +140,12 @@ public class CellElementsClip implements Cloneable, java.io.Serializable {
return null; return null;
} }
String pasteToTemplatePath = this.getCurrentTemplatePath();
boolean pastingToDifferentTemplate = copyFromTemplatePath != null && pasteToTemplatePath != null && !Objects.equals(copyFromTemplatePath, pasteToTemplatePath);
if (pastingToDifferentTemplate) {
cellElement = CellElementStylePaster.convertStyleAndColor(cellElement);
}
// peter:因为前面已经将这个位置的元素删除了,所以不需要override了. // peter:因为前面已经将这个位置的元素删除了,所以不需要override了.
ec.addCellElement((TemplateCellElement) cellElement.deriveCellElement( ec.addCellElement((TemplateCellElement) cellElement.deriveCellElement(
column + cellElement.getColumn(), row + cellElement.getRow() 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. * Clone.
*/ */
@ -183,6 +201,8 @@ public class CellElementsClip implements Cloneable, java.io.Serializable {
public Object clone() throws CloneNotSupportedException { public Object clone() throws CloneNotSupportedException {
CellElementsClip cloned = (CellElementsClip) super.clone(); CellElementsClip cloned = (CellElementsClip) super.clone();
cloned.copyFromTemplatePath = this.copyFromTemplatePath;
if (this.clips != null) { if (this.clips != null) {
cloned.clips = new TemplateCellElement[this.clips.length]; cloned.clips = new TemplateCellElement[this.clips.length];
for (int i = 0; i < this.clips.length; i++) { for (int i = 0; i < this.clips.length; i++) {

26
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.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.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.CellSelection;
import com.fr.grid.selection.Selection; import com.fr.grid.selection.Selection;
@ -13,6 +15,7 @@ import com.fr.report.elementcase.TemplateElementCase;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.util.Objects;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
@ -48,7 +51,7 @@ public class FormatBrushAction extends ElementCaseAction {
if (cellRectangleCount > 1) { if (cellRectangleCount > 1) {
//格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示 //格式刷只支持单次选择的区域,如果用ctrl复选选中了多片区域,点击格式刷按钮时弹出提示
//判断是不是连续区域 //判断是不是连续区域
//荣国是连续区域,那么这些长方形的长加起来应该等于 //如果是连续区域,那么这些长方形的长加起来应该等于
if (!isContinueArea()) { if (!isContinueArea()) {
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Can_Not_Use_Format_Brush")); JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Can_Not_Use_Format_Brush"));
ePane.setFormatState(DesignerContext.FORMAT_STATE_NULL); 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) { if (referencedStyle == null) {
return; return;
@ -132,7 +142,17 @@ public class FormatBrushAction extends ElementCaseAction {
cellElement = DefaultThemedTemplateCellElementCase.createInstance(column, row); cellElement = DefaultThemedTemplateCellElementCase.createInstance(column, row);
elementCase.addCellElement(cellElement); 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);
} }
} }

2
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) { if (reportPane.getCellNeedTOFormat() != null) {
reportPane.getFormatBrushAction().updateFormatBrush(DesignerContext.getReferencedStyle(), reportPane.getCellNeedTOFormat(), reportPane); reportPane.getFormatBrushAction().updateFormatBrush(DesignerContext.getReferencedStyleFromTemplatePath(), DesignerContext.getReferencedStyle(), reportPane.getCellNeedTOFormat(), reportPane);
reportPane.fireTargetModified(); reportPane.fireTargetModified();
} }

Loading…
Cancel
Save