diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java b/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java index 4c39e28545..b82423fe71 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java @@ -5,6 +5,7 @@ import com.fr.base.chart.BaseChartCollection; import com.fr.data.TableDataSource; import com.fr.data.impl.storeproc.StoreProcedure; import com.fr.design.DesignModelAdapter; +import com.fr.design.data.BasicTableDataTreePane; import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.datapane.TableDataTreePane; import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; @@ -22,7 +23,6 @@ import com.fr.form.ui.DictionaryContainer; import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.concept.data.ValueInitializer; -import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.report.cell.FloatElement; import com.fr.report.cell.tabledata.ElementUsedTableDataProvider; @@ -57,7 +57,7 @@ public class TableDataFollowingPasteUtils { } // 获取当前的TableDataTreePane DesignModelAdapter currentModelAdapter = DesignModelAdapter.getCurrentModelAdapter(); - TableDataTreePane tableDataTreePane = (TableDataTreePane) TableDataTreePane.getInstanceWithoutRefreshEverytime(currentModelAdapter); + BasicTableDataTreePane tableDataTreePane = TableDataTreePane.getInstanceWithoutRefreshEverytime(currentModelAdapter); // 粘贴(添加)数据集 for (Map.Entry dataWrapperEntry : tableDataWrapperMap.entrySet()) { String dsName = dataWrapperEntry.getKey(); diff --git a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java index 0b093e4ef1..d7f46ea76b 100644 --- a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java +++ b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java @@ -41,6 +41,8 @@ public class HistoryTemplateListCache implements CallbackEvent { private List> historyList; private JTemplate editingTemplate; + private JTemplate openingOrEditingTemplate; + public static HistoryTemplateListCache getInstance() { return Holder.INSTANCE; } @@ -98,8 +100,15 @@ public class HistoryTemplateListCache implements CallbackEvent { FineLoggerFactory.getLogger().error(e.getMessage(), e); } } - - + + public void setCurrentOpeningTemplate(JTemplate jt) { + this.openingOrEditingTemplate = jt; + } + + public JTemplate getCurrentOpeningOrEditingTemplate() { + return openingOrEditingTemplate; + } + /** * 需要使用 {@link JTemplate#isValid(JTemplate)} 来判断空 * @@ -116,6 +125,7 @@ public class HistoryTemplateListCache implements CallbackEvent { */ public void setCurrentEditingTemplate(JTemplate jt) { this.editingTemplate = jt; + this.openingOrEditingTemplate = jt; if (!JTemplate.isValid(jt)) { return; diff --git a/designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java b/designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java index 71289376a0..258f558a71 100644 --- a/designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java +++ b/designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java @@ -1,14 +1,32 @@ package com.fr.design.gui.core; import com.fr.base.BaseUtils; -import com.fr.base.svg.IconUtils; -import com.fr.form.ui.*; +import com.fr.form.ui.Button; +import com.fr.form.ui.CheckBox; +import com.fr.form.ui.CheckBoxGroup; +import com.fr.form.ui.ComboBox; +import com.fr.form.ui.ComboCheckBox; +import com.fr.form.ui.DateEditor; +import com.fr.form.ui.FreeButton; +import com.fr.form.ui.IframeEditor; +import com.fr.form.ui.Label; +import com.fr.form.ui.ListEditor; +import com.fr.form.ui.MultiFileEditor; +import com.fr.form.ui.NumberEditor; +import com.fr.form.ui.Password; +import com.fr.form.ui.RadioGroup; +import com.fr.form.ui.TextArea; +import com.fr.form.ui.TextEditor; +import com.fr.form.ui.TreeComboBoxEditor; +import com.fr.form.ui.TreeEditor; +import com.fr.form.ui.UserDefinedWidgetConfig; +import com.fr.form.ui.Widget; +import com.fr.form.ui.WidgetConfig; +import com.fr.form.ui.WidgetInfoConfig; import com.fr.general.ComparatorUtils; - - -import javax.swing.*; import java.io.Serializable; import java.util.ArrayList; +import javax.swing.Icon; public abstract class WidgetOption implements Serializable { 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/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index a445621146..fe0e4ee4ff 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -190,6 +190,7 @@ public abstract class JTemplate> public JTemplate(T t, FILE file, boolean isNewFile, Parameter[] parameters) { super(t); + HistoryTemplateListCache.getInstance().setCurrentOpeningTemplate(this); if (isNewFile) { // REPORT-58486: 必须在初始的UndoState创建前设置主题,使得初始的UndoState就包含了主题效果 setUpTheme4NewTemplate(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java index 22d5985ba9..96ca5b4843 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java @@ -5,6 +5,7 @@ import com.fr.design.gui.itree.filetree.TemplateFileTree; import com.fr.stable.StringUtils; import javax.swing.tree.DefaultMutableTreeNode; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -27,19 +28,18 @@ public class JTemplateNameHelper { DefaultMutableTreeNode gen = (DefaultMutableTreeNode) tt.getModel().getRoot(); String[] str = new String[gen.getChildCount()]; - List reportNum = new ArrayList<>(); + List reportNum = new ArrayList<>(); for (int j = 0; j < gen.getChildCount(); j++) { str[j] = gen.getChildAt(j).toString(); //返回文件名中的index(算法中没有再匹配文件后缀了,因为DefaultMutableTreeNode中已经匹配过了) - Integer index = getFileNameIndex(prefix, str[j]); + BigInteger index = getFileNameIndex(prefix, str[j]); if (index != null) { reportNum.add(index); } } Collections.sort(reportNum); - int idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1) + 1 : 1; - - idx = idx + currentIndex; + BigInteger idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1).add(BigInteger.valueOf(1)) : BigInteger.valueOf(1); + idx = idx.add(BigInteger.valueOf(currentIndex)); currentIndex++; return prefix + idx; } @@ -52,35 +52,56 @@ public class JTemplateNameHelper { * @Author Henry.Wang * @Date 2021/4/9 11:13 **/ - private static Integer getFileNameIndex(String prefix, String fileName) { - if (fileName.length() <= prefix.length()) { + private static BigInteger getFileNameIndex(String prefix, String fileName) { + //如果文件名长度小于等于前缀长度或者匹配前缀失败,直接返回就可以了 + if ((prefix.length() >= fileName.length()) || (!StringUtils.equals(prefix, fileName.substring(0, prefix.length())))) { return null; } - char[] chars = new char[fileName.length()]; - int i = 0; - for (; i < fileName.length(); i++) { + BigInteger integer = null; + integer = matchFileNameIndex(prefix, fileName); + return integer; + } + + /** + * 匹配文件名称的数字后缀Index + * @param prefix 前缀 + * @param fileName 文件名称全名 + * @return 返回对应的数字后缀Index + */ + private static BigInteger matchFileNameIndex(String prefix, String fileName) { + StringBuilder result = new StringBuilder(); + for (int i = prefix.length(); i < fileName.length(); i++) { char c = fileName.charAt(i); - //匹配前缀 - if (i < prefix.length()) { - if (c != prefix.charAt(i)) { - return null; - } + if (isDot(c)) { + break; } else { - if (c == '.') { - break; - } else { - //匹配0~9 - if (c < 48 || c > 57) { - return null; - } - chars[i - prefix.length()] = c; + if (isNotNumber(c)) { + return null; } + result.append(c); } } - String s = new String(chars).substring(0, i - prefix.length()); - if (StringUtils.isBlank(s)) { + if (StringUtils.isBlank(result.toString())) { return null; } - return Integer.valueOf(s); + return new BigInteger(result.toString(), 10); + } + + /** + * 是否不属于数字0-9 + * @param c 用于判断的char + * @return 返回对应判断结果 + */ + private static boolean isNotNumber(char c) { + return c < 48 || c > 57; + } + + /** + * 是否属于'.' + * @param c 用于判断的char + * @return 返回对应判断结果 + */ + private static boolean isDot(char c) { + return c == '.'; } } 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-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java index 123875eefc..8b1abe71b4 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java @@ -32,7 +32,7 @@ public class DefaultThemedTemplateCellElementCase { } private static DefaultTemplateCellElement themingCellElement(DefaultTemplateCellElement cellElement) { - JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentOpeningOrEditingTemplate(); if (JTemplate.isValid(template)) { TemplateTheme theme = template.getTemplateTheme(); ThemedCellStyle themedCellStyle = theme.getCellStyleList().getUse4Default(); diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java index cb0442abd8..f15de856e9 100644 --- a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java @@ -74,6 +74,8 @@ public class StartupPageWindow extends JFrame { private static final Dimension SCREEN_SIZE = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + private static final BufferedImage BACKGROUND_IMAGE = IOUtils.readImage("com/fr/design/startup/startup_page_background.jpg"); + private StartupPageWorkspacePanel workspacePanel; private JPanel recentOpenPanel; @@ -136,8 +138,7 @@ public class StartupPageWindow extends JFrame { @Override protected void paintComponent(Graphics g) { super.paintComponent(g); - BufferedImage image = IOUtils.readImage("com/fr/design/startup/startup_page_background.jpg"); - g.drawImage(image, 0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height, this); + g.drawImage(BACKGROUND_IMAGE, 0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height, this); } }; this.contentPane.setLayout(getCenterLayout(body)); diff --git a/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java b/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java index 032e715f60..0202028480 100644 --- a/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java +++ b/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java @@ -2,6 +2,8 @@ package com.fr.design.mainframe; import junit.framework.TestCase; +import com.fr.invoke.Reflect; + /** * @author shine * @version 10.0 @@ -18,6 +20,27 @@ public class JTemplateNameHelperTest extends TestCase { String name1 = JTemplateNameHelper.newTemplateNameByIndex("TEST"); assertEquals("TEST2", name1); + } + + public void testGetFileNameIndex() { + //正常情况 + assertEquals("1", Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "WorkBook1").toString()); + + //正常情况 + assertEquals("8888888888", Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "WorkBook8888888888").toString()); + + //正常情况 + assertEquals("88812214128888881231238123123", Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "WorkBook88812214128888881231238123123").toString()); + + //前缀不匹配 + assertNull(Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "Work123", "WorkBook8888888888").get()); + + //前缀为空 + assertNull(Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "", "WorkBook8888888888").get()); + + //文件长度小于前缀 + assertNull(Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "").get()); + } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java b/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java index f3a19a41e3..6e5b346a18 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java @@ -6,6 +6,7 @@ import com.fr.chart.web.ChartHyperPoplink; import com.fr.chart.web.ChartHyperRelateCellLink; import com.fr.chart.web.ChartHyperRelateFloatLink; import com.fr.design.ExtraDesignClassManager; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.beans.BasicBeanPane; import com.fr.design.chart.javascript.ChartEmailPane; import com.fr.design.chart.series.SeriesCondition.impl.ChartHyperPoplinkPane; @@ -78,14 +79,11 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane { constructor = creator.getUpdatePane().getConstructor(HashMap.class, boolean.class); return constructor.newInstance(getHyperLinkEditorMap(), false); - } catch (InstantiationException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } catch (IllegalAccessException e) { + } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } catch (NoSuchMethodException e) { + FineLoggerFactory.getLogger().warn(e.getMessage(), e); return super.createPaneByCreators(creator); - } catch (InvocationTargetException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); } return null; } @@ -144,9 +142,11 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane { return new NameJavaScriptGroup(res_array); } - public void populate(Plot plot) { - setPlot(plot); - HashMap paneMap = getHyperlinkMap(plot); + private void refreshNameableCreator() { + if (DesignModeContext.isDuchampMode()) { + return; + } + HashMap paneMap = getHyperlinkMap(); //安装平台内打开插件时,添加相应按钮 Set providers = ExtraDesignClassManager.getInstance().getArray(HyperlinkProvider.XML_TAG); @@ -166,6 +166,12 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane { } refreshNameableCreator(creators); + } + + public void populate(Plot plot) { + setPlot(plot); + + refreshNameableCreator(); java.util.List nameObjects = new ArrayList(); @@ -174,8 +180,7 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane { NameJavaScript javaScript = nameGroup.getNameHyperlink(i); if (javaScript != null && javaScript.getJavaScript() != null) { JavaScript script = javaScript.getJavaScript(); - UIMenuNameableCreator uiMenuNameableCreator = new UIMenuNameableCreator(javaScript.getName(), script, getUseMap(paneMap, script.getClass())); - nameObjects.add(new NameObject(uiMenuNameableCreator.getName(), uiMenuNameableCreator.getObj())); + nameObjects.add(new NameObject(javaScript.getName(), script)); } } @@ -188,7 +193,7 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane { return plot.getHotHyperLink(); } - protected HashMap getHyperlinkMap(Plot plot) { + protected HashMap getHyperlinkMap() { HashMap map = new HashMap(); map.put(ReportletHyperlink.class, ReportletHyperlinkPane.class); 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(); } diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index 122f5f9183..24c02893bc 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -119,12 +119,13 @@ public class MainDesigner extends BaseDesigner { * @param args 参数 */ public static void main(String[] args) { + StopWatch watch = new StopWatch(); + watch.start(); + DesignerStartupContext.getRecorder().start(); showSplash(); startPreload0(); - StopWatch watch = new StopWatch(); - watch.start(); DesignerLifecycleMonitorContext.getMonitor().beforeStart(); //启动运行时 FineRuntime.start(); diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java index 9787a12158..e7a00a4f19 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java @@ -160,6 +160,7 @@ public class DesignerActivator extends Activator implements Prepare { private LogHandler logHandler = null; private static final String PLUGIN_EXPORT_IMAGE_SETTING = "com.fr.plugin.exportimagesettings.v11"; + private static final String PICTURE_WIDGET_PLUGIN_ID = "com.fr.plugin.widget.picture.v11"; private final Once pushUpdateTask = new Once(new Runnable() { @Override public void run() { @@ -551,6 +552,7 @@ public class DesignerActivator extends Activator implements Prepare { private void prepareDefaultEmbedPluginInfo() { addMutable(PluginEmbedInfo.KEY, DefaultPluginEmbedInfo.create(PLUGIN_EXPORT_IMAGE_SETTING)); + addMutable(PluginEmbedInfo.KEY, DefaultPluginEmbedInfo.create(PICTURE_WIDGET_PLUGIN_ID)); } private void startBBSLoginAuthServer() { diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java index ccae1a19a6..e41dafcc8f 100644 --- a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java @@ -9,7 +9,6 @@ import com.fr.start.SplashContext; import com.fr.start.common.DesignerStartupContext; import com.fr.start.module.StartupArgs; import com.fr.start.util.DesignerStartupPageUtil; -import com.fr.start.warmup.DesignerPreWarmTask; import com.fr.startup.metric.DesignerMetrics; import com.fr.startup.metric.DesignerStartupModel; import com.fr.startup.ui.StartupPageModel; @@ -63,10 +62,6 @@ public class DesignerStartupPageActivator extends Activator { // 启动页关闭 SplashContext.getInstance().hide(); - // 预热任务启动 - DesignerPreWarmTask warmTask = new DesignerPreWarmTask(); - warmTask.start(); - // 即时暂停 suspendRecorder(context); @@ -79,21 +74,21 @@ public class DesignerStartupPageActivator extends Activator { model.setOpenLastTemplateRunnable(() -> { context.setOpenLastFile(true); handleModel(model); - launchAfterWarmup(warmTask); + launchAfterWarmup(); }); // selectAndOpenEmpty model.setOpenEmptyTemplateRunnable(() -> { context.setOpenEmpty(true); handleModel(model); - launchAfterWarmup(warmTask); + launchAfterWarmup(); }); // selectAndCreateNew model.setCreateNewTemplateRunnable(() -> { context.setCreateNew(true); handleModel(model); - launchAfterWarmup(warmTask); + launchAfterWarmup(); }); StartupPageWindow window = new StartupPageWindow(model); @@ -123,7 +118,7 @@ public class DesignerStartupPageActivator extends Activator { }); } - private void launchAfterWarmup(DesignerPreWarmTask warmTask) { + private void launchAfterWarmup() { StopWatch stopWatch = StopWatch.createStarted(); @@ -133,9 +128,6 @@ public class DesignerStartupPageActivator extends Activator { // 等待中切换 DesignerStartupContext.getInstance().setOnWaiting(false); - warmTask.join(); - - FineLoggerFactory.getLogger().debug("designer-startup-page warm up cost {} ms", stopWatch.getTime(TimeUnit.MILLISECONDS)); DesignerStartupContext.getInstance().setOnStartup(true); DesignerStartupPageUtil.enterWorkspace(); } finally {