Browse Source

Merge pull request #10188 in DESIGN/design from final/11.0 to persist/11.0

* commit '73a96ffffd0c02f43a8962de81d43d13401c2e5a': (21 commits)
  REPORT-80583 多结果数据集预览要弹参数面板
  REPORT-80491 linux设计器调用系统文件夹,设计器闪退
  REPORT-80583 多数据集预览参数设置
  REPORT-80922 远程设计下存储过程结果加载状态NPE
  REPORT-79767 格式刷复制背景颜色-设计器显示与预览颜色不同
  REPORT-80511 启始页启动速度优化 1-记录时间不准,要从头开始记录 2-去掉预热的影响,对直接启动的客户不友好 3-不去每次都读图片,在等待时候,IO 频率极高。
  Revert "REPORT-70593 图片控件合并主代码"
  REPORT-79934 新建模板的A0单元格样式与模板主题的默认单元格样式不一致
  REPORT-79909 补充注释
  重构getFileNameIndex
  REPORT-79909 设计器启动失败,有模板名称叫WorkBook88888888888888.cpt导致
  REPORT-79909 设计器启动失败,有模板名称叫WorkBook88888888888888.cpt导致
  REPORT-79111 数据集分组插件-安装之后,复制决策报表的报表块,数据查询无法一起复制 【问题原因】粘贴的逻辑里将BasicTableDataTreePane强转成了TableDataTreePane,导致插件里实现的BasicTableDataTreePane的子类对象强转失败报错 【改动思路】删掉强转的逻辑,后续的调用也均为抽象类中的抽象方法,可以保证不影响插件 【review建议】
  REPORT-70593 图片控件仅决策报表使用,挪个位置
  Revert "REPORT-70593 图片控件仅决策报表使用,挪个位置"
  REPORT-70593 图片控件仅决策报表使用,挪个位置
  REPORT-79344【运营产品化二期】埋点暂不生效 1、release提交一份
  REPORT-70593 图片控件设计器插件,原插件禁用。方案参考https://kms.fineres.com/pages/viewpage.action?pageId=457117391
  REPORT-79345 【冒烟】切换远程,日志刷报错write failed
  REPORT-77649 feat:fvs图表超链界面populate不refresh超链类型,ps:refresh应该都没有必要 先只改fvs
  ...
fix-lag
superman 2 years ago
parent
commit
9f870d759f
  1. 10
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  2. 4
      designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java
  3. 12
      designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java
  4. 14
      designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java
  5. 28
      designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java
  6. 10
      designer-base/src/main/java/com/fr/design/mainframe/DesignerContext.java
  7. 1
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  8. 73
      designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java
  9. 99
      designer-base/src/main/java/com/fr/design/mainframe/theme/utils/CellElementStylePaster.java
  10. 2
      designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java
  11. 8
      designer-base/src/main/java/com/fr/design/os/impl/SupportOSImpl.java
  12. 5
      designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java
  13. 23
      designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java
  14. 27
      designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java
  15. 20
      designer-realize/src/main/java/com/fr/design/cell/clipboard/CellElementsClip.java
  16. 26
      designer-realize/src/main/java/com/fr/design/mainframe/FormatBrushAction.java
  17. 2
      designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java
  18. 5
      designer-realize/src/main/java/com/fr/start/MainDesigner.java
  19. 2
      designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java
  20. 16
      designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java

10
designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java

@ -625,6 +625,8 @@ public abstract class DesignTableDataManager {
// 把storeProcedure写成xml文件到out // 把storeProcedure写成xml文件到out
DataCoreXmlUtils.writeXMLStoreProcedure(writer, storeProcedure, null); DataCoreXmlUtils.writeXMLStoreProcedure(writer, storeProcedure, null);
if (storeProcedure.getDataModelList().size() > 0 && !storeProcedure.isFirstExpand()) { if (storeProcedure.getDataModelList().size() > 0 && !storeProcedure.isFirstExpand()) {
// 存储过程有些特殊处理
// 这个就简单直接获取暂存列表吧
return storeProcedure.getDataModelList().toArray(new ProcedureDataModel[0]); return storeProcedure.getDataModelList().toArray(new ProcedureDataModel[0]);
} }
ParameterProvider[] inParameters = DataOperator.getInstance().getStoreProcedureParameters(storeProcedure); ParameterProvider[] inParameters = DataOperator.getInstance().getStoreProcedureParameters(storeProcedure);
@ -633,11 +635,13 @@ public abstract class DesignTableDataManager {
showParaWindow(parameterMap, inParameters); showParaWindow(parameterMap, inParameters);
} }
storeProcedure.setFirstExpand(false); storeProcedure.setFirstExpand(false);
} else {
ParameterProvider[] parameters = DataOperator.getInstance().getTableDataParameters(tableData);
if (parameters.length > 0) {
showParaWindow(parameterMap, parameters);
}
} }
// 存储过程有些特殊处理
// 这个就简单直接获取暂存列表吧
// TODO 参数处理?
if (needLoadingBar) { if (needLoadingBar) {
MultiResultTableDataWrapper.loadingBar.start(); MultiResultTableDataWrapper.loadingBar.start();
} }

4
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.TableDataSource;
import com.fr.data.impl.storeproc.StoreProcedure; import com.fr.data.impl.storeproc.StoreProcedure;
import com.fr.design.DesignModelAdapter; import com.fr.design.DesignModelAdapter;
import com.fr.design.data.BasicTableDataTreePane;
import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane; import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; 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.ElementCaseEditor;
import com.fr.form.ui.Widget; import com.fr.form.ui.Widget;
import com.fr.form.ui.concept.data.ValueInitializer; import com.fr.form.ui.concept.data.ValueInitializer;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.report.cell.FloatElement; import com.fr.report.cell.FloatElement;
import com.fr.report.cell.tabledata.ElementUsedTableDataProvider; import com.fr.report.cell.tabledata.ElementUsedTableDataProvider;
@ -57,7 +57,7 @@ public class TableDataFollowingPasteUtils {
} }
// 获取当前的TableDataTreePane // 获取当前的TableDataTreePane
DesignModelAdapter<?, ?> currentModelAdapter = DesignModelAdapter.getCurrentModelAdapter(); DesignModelAdapter<?, ?> currentModelAdapter = DesignModelAdapter.getCurrentModelAdapter();
TableDataTreePane tableDataTreePane = (TableDataTreePane) TableDataTreePane.getInstanceWithoutRefreshEverytime(currentModelAdapter); BasicTableDataTreePane tableDataTreePane = TableDataTreePane.getInstanceWithoutRefreshEverytime(currentModelAdapter);
// 粘贴(添加)数据集 // 粘贴(添加)数据集
for (Map.Entry<String, TableData> dataWrapperEntry : tableDataWrapperMap.entrySet()) { for (Map.Entry<String, TableData> dataWrapperEntry : tableDataWrapperMap.entrySet()) {
String dsName = dataWrapperEntry.getKey(); String dsName = dataWrapperEntry.getKey();

12
designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java

@ -187,18 +187,20 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper {
protected Void doInBackground() throws Exception { protected Void doInBackground() throws Exception {
loadingBar.close(); loadingBar.close();
PreviewTablePane.resetPreviewTable(); PreviewTablePane.resetPreviewTable();
connectionBar.start();
// 存储过程需要先测试一下连接 // 存储过程需要先测试一下连接
if (tableData instanceof StoreProcedure) { if (tableData instanceof StoreProcedure) {
boolean status = DataOperator.getInstance().testConnection(((StoreProcedure) getTableData()).getDatabaseConnection()); try {
if (!status) { connectionBar.start();
boolean success = DataOperator.getInstance().testConnection(((StoreProcedure) getTableData()).getDatabaseConnection());
if (!success) {
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"));
}
} finally {
connectionBar.close(); connectionBar.close();
throw new Exception(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"));
} }
} }
connectionBar.close();
tableData.resetDataModelList(); tableData.resetDataModelList();
// 获取结果 // 获取结果

14
designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java

@ -41,6 +41,8 @@ public class HistoryTemplateListCache implements CallbackEvent {
private List<JTemplate<?, ?>> historyList; private List<JTemplate<?, ?>> historyList;
private JTemplate<?, ?> editingTemplate; private JTemplate<?, ?> editingTemplate;
private JTemplate<?, ?> openingOrEditingTemplate;
public static HistoryTemplateListCache getInstance() { public static HistoryTemplateListCache getInstance() {
return Holder.INSTANCE; return Holder.INSTANCE;
} }
@ -98,8 +100,15 @@ public class HistoryTemplateListCache implements CallbackEvent {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
} }
} }
public void setCurrentOpeningTemplate(JTemplate<?, ?> jt) {
this.openingOrEditingTemplate = jt;
}
public JTemplate<?, ?> getCurrentOpeningOrEditingTemplate() {
return openingOrEditingTemplate;
}
/** /**
* 需要使用 {@link JTemplate#isValid(JTemplate)} 来判断空 * 需要使用 {@link JTemplate#isValid(JTemplate)} 来判断空
* *
@ -116,6 +125,7 @@ public class HistoryTemplateListCache implements CallbackEvent {
*/ */
public void setCurrentEditingTemplate(JTemplate<?, ?> jt) { public void setCurrentEditingTemplate(JTemplate<?, ?> jt) {
this.editingTemplate = jt; this.editingTemplate = jt;
this.openingOrEditingTemplate = jt;
if (!JTemplate.isValid(jt)) { if (!JTemplate.isValid(jt)) {
return; return;

28
designer-base/src/main/java/com/fr/design/gui/core/WidgetOption.java

@ -1,14 +1,32 @@
package com.fr.design.gui.core; package com.fr.design.gui.core;
import com.fr.base.BaseUtils; import com.fr.base.BaseUtils;
import com.fr.base.svg.IconUtils; import com.fr.form.ui.Button;
import com.fr.form.ui.*; 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 com.fr.general.ComparatorUtils;
import javax.swing.*;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import javax.swing.Icon;
public abstract class WidgetOption implements Serializable { public abstract class WidgetOption implements Serializable {

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;
} }

1
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -190,6 +190,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public JTemplate(T t, FILE file, boolean isNewFile, Parameter[] parameters) { public JTemplate(T t, FILE file, boolean isNewFile, Parameter[] parameters) {
super(t); super(t);
HistoryTemplateListCache.getInstance().setCurrentOpeningTemplate(this);
if (isNewFile) { if (isNewFile) {
// REPORT-58486: 必须在初始的UndoState创建前设置主题,使得初始的UndoState就包含了主题效果 // REPORT-58486: 必须在初始的UndoState创建前设置主题,使得初始的UndoState就包含了主题效果
setUpTheme4NewTemplate(); setUpTheme4NewTemplate();

73
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 com.fr.stable.StringUtils;
import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultMutableTreeNode;
import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -27,19 +28,18 @@ public class JTemplateNameHelper {
DefaultMutableTreeNode gen = (DefaultMutableTreeNode) tt.getModel().getRoot(); DefaultMutableTreeNode gen = (DefaultMutableTreeNode) tt.getModel().getRoot();
String[] str = new String[gen.getChildCount()]; String[] str = new String[gen.getChildCount()];
List<Integer> reportNum = new ArrayList<>(); List<BigInteger> reportNum = new ArrayList<>();
for (int j = 0; j < gen.getChildCount(); j++) { for (int j = 0; j < gen.getChildCount(); j++) {
str[j] = gen.getChildAt(j).toString(); str[j] = gen.getChildAt(j).toString();
//返回文件名中的index(算法中没有再匹配文件后缀了,因为DefaultMutableTreeNode中已经匹配过了) //返回文件名中的index(算法中没有再匹配文件后缀了,因为DefaultMutableTreeNode中已经匹配过了)
Integer index = getFileNameIndex(prefix, str[j]); BigInteger index = getFileNameIndex(prefix, str[j]);
if (index != null) { if (index != null) {
reportNum.add(index); reportNum.add(index);
} }
} }
Collections.sort(reportNum); Collections.sort(reportNum);
int idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1) + 1 : 1; BigInteger idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1).add(BigInteger.valueOf(1)) : BigInteger.valueOf(1);
idx = idx.add(BigInteger.valueOf(currentIndex));
idx = idx + currentIndex;
currentIndex++; currentIndex++;
return prefix + idx; return prefix + idx;
} }
@ -52,35 +52,56 @@ public class JTemplateNameHelper {
* @Author Henry.Wang * @Author Henry.Wang
* @Date 2021/4/9 11:13 * @Date 2021/4/9 11:13
**/ **/
private static Integer getFileNameIndex(String prefix, String fileName) { private static BigInteger getFileNameIndex(String prefix, String fileName) {
if (fileName.length() <= prefix.length()) { //如果文件名长度小于等于前缀长度或者匹配前缀失败,直接返回就可以了
if ((prefix.length() >= fileName.length()) || (!StringUtils.equals(prefix, fileName.substring(0, prefix.length())))) {
return null; return null;
} }
char[] chars = new char[fileName.length()]; BigInteger integer = null;
int i = 0; integer = matchFileNameIndex(prefix, fileName);
for (; i < fileName.length(); i++) { 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); char c = fileName.charAt(i);
//匹配前缀 if (isDot(c)) {
if (i < prefix.length()) { break;
if (c != prefix.charAt(i)) {
return null;
}
} else { } else {
if (c == '.') { if (isNotNumber(c)) {
break; return null;
} else {
//匹配0~9
if (c < 48 || c > 57) {
return null;
}
chars[i - prefix.length()] = c;
} }
result.append(c);
} }
} }
String s = new String(chars).substring(0, i - prefix.length()); if (StringUtils.isBlank(result.toString())) {
if (StringUtils.isBlank(s)) {
return null; 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 == '.';
} }
} }

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;
}
}

2
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) { private static DefaultTemplateCellElement themingCellElement(DefaultTemplateCellElement cellElement) {
JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); JTemplate<?,?> template = HistoryTemplateListCache.getInstance().getCurrentOpeningOrEditingTemplate();
if (JTemplate.isValid(template)) { if (JTemplate.isValid(template)) {
TemplateTheme theme = template.getTemplateTheme(); TemplateTheme theme = template.getTemplateTheme();
ThemedCellStyle themedCellStyle = theme.getCellStyleList().getUse4Default(); ThemedCellStyle themedCellStyle = theme.getCellStyleList().getUse4Default();

8
designer-base/src/main/java/com/fr/design/os/impl/SupportOSImpl.java

@ -152,7 +152,13 @@ public enum SupportOSImpl implements SupportOS {
@Override @Override
public boolean support() { public boolean support() {
return (OperatingSystem.isLinux() && Arch.getArch() == Arch.ARM) || MACOS_12_VERSION_ADAPTER.support(); boolean javafxExist = true;
try {
Class.forName("javafx.stage.FileChooser");
} catch (ClassNotFoundException e) {
javafxExist = false;
}
return !javafxExist || (OperatingSystem.isLinux() && Arch.getArch() == Arch.ARM) || MACOS_12_VERSION_ADAPTER.support();
} }
}, },

5
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 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 StartupPageWorkspacePanel workspacePanel;
private JPanel recentOpenPanel; private JPanel recentOpenPanel;
@ -136,8 +138,7 @@ public class StartupPageWindow extends JFrame {
@Override @Override
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
super.paintComponent(g); super.paintComponent(g);
BufferedImage image = IOUtils.readImage("com/fr/design/startup/startup_page_background.jpg"); g.drawImage(BACKGROUND_IMAGE, 0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height, this);
g.drawImage(image, 0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height, this);
} }
}; };
this.contentPane.setLayout(getCenterLayout(body)); this.contentPane.setLayout(getCenterLayout(body));

23
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 junit.framework.TestCase;
import com.fr.invoke.Reflect;
/** /**
* @author shine * @author shine
* @version 10.0 * @version 10.0
@ -18,6 +20,27 @@ public class JTemplateNameHelperTest extends TestCase {
String name1 = JTemplateNameHelper.newTemplateNameByIndex("TEST"); String name1 = JTemplateNameHelper.newTemplateNameByIndex("TEST");
assertEquals("TEST2", name1); 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());
} }
} }

27
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.ChartHyperRelateCellLink;
import com.fr.chart.web.ChartHyperRelateFloatLink; import com.fr.chart.web.ChartHyperRelateFloatLink;
import com.fr.design.ExtraDesignClassManager; import com.fr.design.ExtraDesignClassManager;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.beans.BasicBeanPane; import com.fr.design.beans.BasicBeanPane;
import com.fr.design.chart.javascript.ChartEmailPane; import com.fr.design.chart.javascript.ChartEmailPane;
import com.fr.design.chart.series.SeriesCondition.impl.ChartHyperPoplinkPane; 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); constructor = creator.getUpdatePane().getConstructor(HashMap.class, boolean.class);
return constructor.newInstance(getHyperLinkEditorMap(), false); return constructor.newInstance(getHyperLinkEditorMap(), false);
} catch (InstantiationException e) { } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} catch (IllegalAccessException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e); FineLoggerFactory.getLogger().error(e.getMessage(), e);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
FineLoggerFactory.getLogger().warn(e.getMessage(), e);
return super.createPaneByCreators(creator); return super.createPaneByCreators(creator);
} catch (InvocationTargetException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} }
return null; return null;
} }
@ -144,9 +142,11 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane {
return new NameJavaScriptGroup(res_array); return new NameJavaScriptGroup(res_array);
} }
public void populate(Plot plot) { private void refreshNameableCreator() {
setPlot(plot); if (DesignModeContext.isDuchampMode()) {
HashMap paneMap = getHyperlinkMap(plot); return;
}
HashMap paneMap = getHyperlinkMap();
//安装平台内打开插件时,添加相应按钮 //安装平台内打开插件时,添加相应按钮
Set<HyperlinkProvider> providers = ExtraDesignClassManager.getInstance().getArray(HyperlinkProvider.XML_TAG); Set<HyperlinkProvider> providers = ExtraDesignClassManager.getInstance().getArray(HyperlinkProvider.XML_TAG);
@ -166,6 +166,12 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane {
} }
refreshNameableCreator(creators); refreshNameableCreator(creators);
}
public void populate(Plot plot) {
setPlot(plot);
refreshNameableCreator();
java.util.List<NameObject> nameObjects = new ArrayList<NameObject>(); java.util.List<NameObject> nameObjects = new ArrayList<NameObject>();
@ -174,8 +180,7 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane {
NameJavaScript javaScript = nameGroup.getNameHyperlink(i); NameJavaScript javaScript = nameGroup.getNameHyperlink(i);
if (javaScript != null && javaScript.getJavaScript() != null) { if (javaScript != null && javaScript.getJavaScript() != null) {
JavaScript script = javaScript.getJavaScript(); JavaScript script = javaScript.getJavaScript();
UIMenuNameableCreator uiMenuNameableCreator = new UIMenuNameableCreator(javaScript.getName(), script, getUseMap(paneMap, script.getClass())); nameObjects.add(new NameObject(javaScript.getName(), script));
nameObjects.add(new NameObject(uiMenuNameableCreator.getName(), uiMenuNameableCreator.getObj()));
} }
} }
@ -188,7 +193,7 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane {
return plot.getHotHyperLink(); return plot.getHotHyperLink();
} }
protected HashMap getHyperlinkMap(Plot plot) { protected HashMap getHyperlinkMap() {
HashMap<Class, Class> map = new HashMap<Class, Class>(); HashMap<Class, Class> map = new HashMap<Class, Class>();
map.put(ReportletHyperlink.class, ReportletHyperlinkPane.class); map.put(ReportletHyperlink.class, ReportletHyperlinkPane.class);

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();
} }

5
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -119,12 +119,13 @@ public class MainDesigner extends BaseDesigner {
* @param args 参数 * @param args 参数
*/ */
public static void main(String[] args) { public static void main(String[] args) {
StopWatch watch = new StopWatch();
watch.start();
DesignerStartupContext.getRecorder().start(); DesignerStartupContext.getRecorder().start();
showSplash(); showSplash();
startPreload0(); startPreload0();
StopWatch watch = new StopWatch();
watch.start();
DesignerLifecycleMonitorContext.getMonitor().beforeStart(); DesignerLifecycleMonitorContext.getMonitor().beforeStart();
//启动运行时 //启动运行时
FineRuntime.start(); FineRuntime.start();

2
designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java

@ -160,6 +160,7 @@ public class DesignerActivator extends Activator implements Prepare {
private LogHandler<DesignerLogAppender> logHandler = null; private LogHandler<DesignerLogAppender> logHandler = null;
private static final String PLUGIN_EXPORT_IMAGE_SETTING = "com.fr.plugin.exportimagesettings.v11"; 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() { private final Once pushUpdateTask = new Once(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -551,6 +552,7 @@ public class DesignerActivator extends Activator implements Prepare {
private void prepareDefaultEmbedPluginInfo() { private void prepareDefaultEmbedPluginInfo() {
addMutable(PluginEmbedInfo.KEY, DefaultPluginEmbedInfo.create(PLUGIN_EXPORT_IMAGE_SETTING)); addMutable(PluginEmbedInfo.KEY, DefaultPluginEmbedInfo.create(PLUGIN_EXPORT_IMAGE_SETTING));
addMutable(PluginEmbedInfo.KEY, DefaultPluginEmbedInfo.create(PICTURE_WIDGET_PLUGIN_ID));
} }
private void startBBSLoginAuthServer() { private void startBBSLoginAuthServer() {

16
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.common.DesignerStartupContext;
import com.fr.start.module.StartupArgs; import com.fr.start.module.StartupArgs;
import com.fr.start.util.DesignerStartupPageUtil; import com.fr.start.util.DesignerStartupPageUtil;
import com.fr.start.warmup.DesignerPreWarmTask;
import com.fr.startup.metric.DesignerMetrics; import com.fr.startup.metric.DesignerMetrics;
import com.fr.startup.metric.DesignerStartupModel; import com.fr.startup.metric.DesignerStartupModel;
import com.fr.startup.ui.StartupPageModel; import com.fr.startup.ui.StartupPageModel;
@ -63,10 +62,6 @@ public class DesignerStartupPageActivator extends Activator {
// 启动页关闭 // 启动页关闭
SplashContext.getInstance().hide(); SplashContext.getInstance().hide();
// 预热任务启动
DesignerPreWarmTask warmTask = new DesignerPreWarmTask();
warmTask.start();
// 即时暂停 // 即时暂停
suspendRecorder(context); suspendRecorder(context);
@ -79,21 +74,21 @@ public class DesignerStartupPageActivator extends Activator {
model.setOpenLastTemplateRunnable(() -> { model.setOpenLastTemplateRunnable(() -> {
context.setOpenLastFile(true); context.setOpenLastFile(true);
handleModel(model); handleModel(model);
launchAfterWarmup(warmTask); launchAfterWarmup();
}); });
// selectAndOpenEmpty // selectAndOpenEmpty
model.setOpenEmptyTemplateRunnable(() -> { model.setOpenEmptyTemplateRunnable(() -> {
context.setOpenEmpty(true); context.setOpenEmpty(true);
handleModel(model); handleModel(model);
launchAfterWarmup(warmTask); launchAfterWarmup();
}); });
// selectAndCreateNew // selectAndCreateNew
model.setCreateNewTemplateRunnable(() -> { model.setCreateNewTemplateRunnable(() -> {
context.setCreateNew(true); context.setCreateNew(true);
handleModel(model); handleModel(model);
launchAfterWarmup(warmTask); launchAfterWarmup();
}); });
StartupPageWindow window = new StartupPageWindow(model); 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(); StopWatch stopWatch = StopWatch.createStarted();
@ -133,9 +128,6 @@ public class DesignerStartupPageActivator extends Activator {
// 等待中切换 // 等待中切换
DesignerStartupContext.getInstance().setOnWaiting(false); DesignerStartupContext.getInstance().setOnWaiting(false);
warmTask.join();
FineLoggerFactory.getLogger().debug("designer-startup-page warm up cost {} ms", stopWatch.getTime(TimeUnit.MILLISECONDS));
DesignerStartupContext.getInstance().setOnStartup(true); DesignerStartupContext.getInstance().setOnStartup(true);
DesignerStartupPageUtil.enterWorkspace(); DesignerStartupPageUtil.enterWorkspace();
} finally { } finally {

Loading…
Cancel
Save