diff --git a/build.gradle b/build.gradle index 617b9d0fa..781c65e22 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,17 @@ dependencies { api project(':designer-realize') } +configurations.all { + resolutionStrategy { + force 'com.fr.third:jxbrowser:6.23' + force 'com.fr.third:jxbrowser-mac:6.23' + force 'com.fr.third:jxbrowser-win64:6.23' + force 'com.fr.third:jxbrowser:7.5' + force 'com.fr.third:jxbrowser-mac:7.5' + force 'com.fr.third:jxbrowser-win64:7.5' + } +} + allprojects { apply plugin: 'java' apply plugin: 'java-library' @@ -57,9 +68,19 @@ allprojects { } dependencies { - implementation 'com.fr.third:jxbrowser:6.23' - implementation 'com.fr.third:jxbrowser-mac:6.23' - implementation 'com.fr.third:jxbrowser-win64:6.23' + implementation ('com.fr.third:jxbrowser:6.23') { + force = true + } + implementation ('com.fr.third:jxbrowser-mac:6.23') { + force = true + } + implementation ('com.fr.third:jxbrowser-win64:6.23') { + force = true + } + implementation 'com.fr.third:jxbrowser:7.5' + implementation 'com.fr.third:jxbrowser-mac:7.5' + implementation 'com.fr.third:jxbrowser-win64:7.5' + implementation 'com.fr.third:jxbrowser-swing:7.5' implementation 'com.fr.third.server:servlet-api:3.0' implementation 'org.swingexplorer:swexpl:2.0.1' implementation 'org.swingexplorer:swag:1.0' diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index 5196c783a..4ab6b3089 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -18,7 +18,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.DesignUtils; -import com.fr.env.CheckServiceDialog; +import com.fr.design.versioncheck.VersionCheckUtils; import com.fr.env.EnvListPane; import com.fr.env.RemoteWorkspaceURL; import com.fr.env.TestConnectionResult; @@ -96,6 +96,7 @@ public class EnvChangeEntrance { */ public void switch2Env(final String envName) { switch2Env(envName, PopTipStrategy.LATER); + VersionCheckUtils.showVersionCheckDialog(envName); } /** @@ -145,7 +146,6 @@ public class EnvChangeEntrance { if (template != null) { template.refreshToolArea(); } - showServiceDialog(selectedEnv); pluginErrorRemind(); } catch (WorkspaceAuthException | RegistEditionException e) { // String title = Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Auth_Failed"); @@ -294,8 +294,7 @@ public class EnvChangeEntrance { if(StringUtils.isEmpty(areaText)){ return; } - CheckServiceDialog dialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), areaText, localBranch, remoteBranch); - dialog.setVisible(true); + } } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java index 2800e6f75..462f70b34 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java @@ -46,6 +46,8 @@ import java.awt.Frame; import java.awt.datatransfer.StringSelection; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -107,11 +109,11 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener { topPanel.add(imagePanel, BorderLayout.WEST); topPanel.add(messagePanel, BorderLayout.CENTER); - topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,0,10)); + topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); //中间的SQL面板 centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - centerPanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); + centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); JScrollPane scrollPane = new JScrollPane(); JTextArea checkArea = new JTextArea(sql); checkArea.setEditable(false); @@ -135,7 +137,7 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener { UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK")); okButton.addActionListener(this); bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - bottomPanel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); bottomPanel.add(okButton, BorderLayout.EAST); this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql")); @@ -144,6 +146,12 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener { this.add(centerPanel, BorderLayout.CENTER); this.add(bottomPanel, BorderLayout.SOUTH); this.setSize(600, 400); + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + close(); + } + }); GUICoreUtils.centerWindow(this); } @@ -167,42 +175,34 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener { parameterMap.put(parameter.getName(), parameter.getValue()); } } - boolean showOriginSql = true; for (ParameterProvider parameter : DataOperator.getInstance().getTableDataParameters(tableData)) { if (parameterMap.containsKey(parameter.getName())) { - Object value = parameterMap.get(parameter.getName()); - if (value != null && !StringUtils.EMPTY.equals(value)) { - showOriginSql = false; - } - parameter.setValue(value); + parameter.setValue(parameterMap.get(parameter.getName())); } } String sql; // 计算高亮文本位置 List specialCharParamIndex = null; boolean highlight = true; - if (showOriginSql) { - sql = tableData.getQuery(); - } else { - NameSpace ns = ParameterMapNameSpace.create(parameterMap); - calculator.pushNameSpace(ns); - Parameter[] paras = processParameters(tableData, calculator); - // 所有被转义参数的集合 - Set specialCharParam = EscapeSqlHelper.getInstance().getSpecialCharParam(paras); - // 将参数转义等 - Set tableDataProviders = getTableDataProviders(); - for (TableDataProvider provider : tableDataProviders) { - provider.processParametersBeforeAnalyzeSQL(paras, calculator); - } + NameSpace ns = ParameterMapNameSpace.create(parameterMap); + calculator.pushNameSpace(ns); + Parameter[] paras = processParameters(tableData, calculator); + // 所有被转义参数的集合 + refreshEscapeSqlHelper(); + Set specialCharParam = EscapeSqlHelper.getInstance().getSpecialCharParam(paras); + // 将参数转义等 + Set tableDataProviders = getTableDataProviders(); + for (TableDataProvider provider : tableDataProviders) { + provider.processParametersBeforeAnalyzeSQL(paras, calculator); + } - if (!specialCharParam.isEmpty()) { - specialCharParamIndex = ParameterHelper.analyzeCurrentContextTableData4Template(tableData.getQuery(), paras, specialCharParam); - } - String oldSql = ParameterHelper.analyzeCurrentContextTableData4Templatee(tableData.getQuery(), paras); - sql = processExtraSQL(paras, oldSql, calculator, tableDataProviders); - if (!StringUtils.equals(oldSql, sql)) { - highlight = false; - } + if (!specialCharParam.isEmpty()) { + specialCharParamIndex = ParameterHelper.analyzeCurrentContextTableData4Template(tableData.getQuery(), paras, specialCharParam); + } + String oldSql = ParameterHelper.analyzeCurrentContextTableData4Templatee(tableData.getQuery(), paras); + sql = processExtraSQL(paras, oldSql, calculator, tableDataProviders); + if (!StringUtils.equals(oldSql, sql)) { + highlight = false; } // sql内容复制到剪切板 StringSelection selection = new StringSelection(sql); @@ -217,6 +217,13 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener { pane.setVisible(true); } + private static void refreshEscapeSqlHelper() { + EscapeSqlHelper.getInstance().setUseForbidWord(ConfigService.getInstance().getPSIConfig().isUseForbidWord()); + EscapeSqlHelper.getInstance().setSelectedForbidWord(ConfigService.getInstance().getPSIConfig().getSelectedForbidWord()); + EscapeSqlHelper.getInstance().setUseEscapeSpecialChar(ConfigService.getInstance().getPSIConfig().isUseEscapeSpecialChar()); + EscapeSqlHelper.getInstance().setSelectedSpecialChar(ConfigService.getInstance().getPSIConfig().getSelectedSpecialChar()); + } + private static boolean isShowSpecialCharSqlPane(List specialCharParamIndex) { return specialCharParamIndex != null && !specialCharParamIndex.isEmpty(); } @@ -274,4 +281,8 @@ public class PreviewPerformedSqlPane extends JDialog implements ActionListener { public void actionPerformed(ActionEvent e) { this.dispose(); } + + private void close() { + this.dispose(); + } } diff --git a/designer-base/src/main/java/com/fr/design/dialog/NotificationDialog.java b/designer-base/src/main/java/com/fr/design/dialog/NotificationDialog.java new file mode 100644 index 000000000..db3be1387 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/dialog/NotificationDialog.java @@ -0,0 +1,176 @@ +package com.fr.design.dialog; + + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.gui.GUICoreUtils; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.ScrollPaneConstants; +import javax.swing.UIManager; + +/** + * 带查看详情的简要通知框 + * + */ +public class NotificationDialog extends JDialog { + public static final int ERROR_MESSAGE = 0; + public static final int NEW_MESSAGE = 1; + public static final int WARNING_MESSAGE = 2; + public static final String HTML_TAG_1 = ""; + public static final String HTML_TAG_2 = ""; + private UILabel messageText; + private NotificationDialogAction notificationDialogAction; + + public NotificationDialog(Frame owner, String title, boolean isModal, int messageType, String message,NotificationDialogAction action) { + super(owner); + setTitle(title); + initComponents(messageType, message, isModal,action); + } + + public NotificationDialog(Builder builder) { + super(builder.owner); + setTitle(builder.title); + initComponents(builder.messageType, builder.message, builder.modal, builder.action); + } + + public void initComponents(int messageType, String message, boolean isModal,NotificationDialogAction action) { + notificationDialogAction = action; + setModal(isModal); + setResizable(false); + + //消息内容 + UILabel icon = new UILabel(getIconForType(messageType)); + JPanel iconPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + iconPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 8)); + iconPanel.add(icon); + add(iconPanel, BorderLayout.WEST); + + messageText = new UILabel(HTML_TAG_1 + message + HTML_TAG_2); + messageText.setForeground(new Color(51, 51, 52)); + JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 10)); + JScrollPane jScrollPane = new JScrollPane(messageText, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + jScrollPane.setBorder(BorderFactory.createEmptyBorder()); + centerPanel.add(jScrollPane, BorderLayout.CENTER); + add(centerPanel, BorderLayout.CENTER); + + //查看详情 + UILabel detailLabel = new UILabel(); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); + detailLabel.setForeground(Color.BLUE); + JPanel detailPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + detailPanel.add(detailLabel, BorderLayout.EAST); + add(detailPanel, BorderLayout.SOUTH); + setPreferredSize(new Dimension(262, 135)); + + detailLabel.addMouseListener(detailClickListener); + messageText.addMouseListener(detailClickListener); + + pack(); + if (getOwner() != null) { + GUICoreUtils.setWindowCenter(getOwner(), this); + } + } + + private MouseListener detailClickListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if(notificationDialogAction != null){ + hideDialog(); + notificationDialogAction.doClick(); + } + } + }; + + + /** + * 设置通知消息 + */ + public void setMessage(String message){ + messageText.setText(HTML_TAG_1 + message + HTML_TAG_2); + } + + private void hideDialog(){ + this.dispose(); + } + + protected Icon getIconForType(int messageType) { + String propertyName; + switch (messageType) { + case 0: + propertyName = "OptionPane.circularErrorIcon"; + break; + case 1: + propertyName = "OptionPane.newMessageIcon"; + break; + case 2: + propertyName = "OptionPane.warningIcon"; + break; + default: + return null; + } + return UIManager.getIcon(propertyName); + } + + public static Builder Builder() { + return new NotificationDialog.Builder(); + } + + public static final class Builder { + public int messageType = WARNING_MESSAGE; + public String message; + public boolean modal = true; + public Frame owner = null; + public String title; + public NotificationDialogAction action; + private Builder() { + + } + + public NotificationDialog build() { + return new NotificationDialog(this); + } + + public Builder owner(Frame owner) { + this.owner = owner; + return this; + } + + public Builder messageType(int messageType) { + this.messageType = messageType; + return this; + } + + public Builder message(String message) { + this.message = message; + return this; + } + + public Builder modal(boolean modal) { + this.modal = modal; + return this; + } + + public Builder title(String title) { + this.title = title; + return this; + } + + public Builder notificationDialogAction(NotificationDialogAction action) { + this.action = action; + return this; + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/dialog/NotificationDialogAction.java b/designer-base/src/main/java/com/fr/design/dialog/NotificationDialogAction.java new file mode 100644 index 000000000..3cd4e85e8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/dialog/NotificationDialogAction.java @@ -0,0 +1,5 @@ +package com.fr.design.dialog; + +public interface NotificationDialogAction { + void doClick(); +} diff --git a/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java b/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java index 6d1a729d9..abb9d613d 100644 --- a/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java +++ b/designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java @@ -176,6 +176,9 @@ public class UILookAndFeel extends MetalLookAndFeel { table.put("OptionPane.narrow.right", loadIcon("Icon_Narrow_Right_16x16.png", this)); table.put("OptionPane.narrow.down", loadIcon("Icon_Narrow_Down_16x16.png", this)); table.put("OptionPane.warningIcon", loadIcon("WarningIcon.png", this)); + table.put("OptionPane.circularWarningIcon", loadIcon("circularWarningIcon.png", this)); + table.put("OptionPane.newMessageIcon", loadIcon("newMessageIcon.png", this)); + table.put("OptionPane.circularErrorIcon", loadIcon("circularErrorIcon.png", this)); table.put("OptionPane.questionIcon", loadIcon("QuestionIcon.png", this)); table.put("OptionPane.tipIcon", loadIcon("TipIcon.png", this)); table.put("ScrollPane.border", new UIScrollPaneBorder()); diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java index 6e0313ec7..384d2bb52 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java @@ -12,6 +12,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.widget.EventCreator; import com.fr.form.event.Listener; import com.fr.form.ui.Widget; +import com.fr.general.FRFont; import com.fr.general.NameObject; import com.fr.report.web.util.ReportEngineEventMapping; import com.fr.stable.ArrayUtils; @@ -26,10 +27,13 @@ import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.lang.reflect.Constructor; @@ -103,6 +107,15 @@ public abstract class UIListGroupControlPane extends UIControlPane implements L contentPane.add(wrapperPane); nameEdListMap.put(event, wrapperPane); } + contentPane.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + if (selectNameEdList != null) { + selectNameEdList.stopEditing(); + } + } + }); } protected void populateNameObjects(Widget widget) { @@ -456,7 +469,7 @@ public abstract class UIListGroupControlPane extends UIControlPane implements L getHelper().popupEditDialog(null, this.selectNameEdList, this); } - protected String getWrapperLabelText(){ + protected String getWrapperLabelText() { return StringUtils.EMPTY; } @@ -466,9 +479,18 @@ public abstract class UIListGroupControlPane extends UIControlPane implements L public ListWrapperPane(String labelText, UINameEdList nameEdList) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - UILabel label = new UILabel(labelText + getWrapperLabelText()); + UILabel label = new UILabel(labelText + getWrapperLabelText()) { + @Override + public void paint(Graphics g) { + ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f)); + super.paint(g); + } + }; label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); - label.setBackground(Color.decode("#FFFFFF")); + label.setOpaque(true); + label.setBackground(Color.WHITE); + label.setForeground(Color.decode("#333334")); + label.setFont(label.getFont().deriveFont(11F)); label.setPreferredSize(new Dimension(224, 26)); this.nameEdList = nameEdList; this.add(label, BorderLayout.NORTH); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index 73f3254db..331438565 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java @@ -52,6 +52,7 @@ import com.fr.file.FILEFactory; import com.fr.file.FileFILE; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralContext; +import com.fr.general.GeneralUtils; import com.fr.general.IOUtils; import com.fr.invoke.Reflect; import com.fr.log.FineLoggerFactory; @@ -864,7 +865,9 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta JTemplate editingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); StringBuilder defaultTitleSB = new StringBuilder(); - defaultTitleSB.append(ProductConstants.PRODUCT_NAME); + defaultTitleSB.append(ProductConstants.APP_NAME); + defaultTitleSB.append(" "); + defaultTitleSB.append(GeneralUtils.getVersion()); defaultTitleSB.append(" "); defaultTitleSB.append(ProductConstants.BRANCH); defaultTitleSB.append(" "); diff --git a/designer-base/src/main/java/com/fr/design/mod/ContentObjectManager.java b/designer-base/src/main/java/com/fr/design/mod/ContentObjectManager.java index b70ea88b0..6c8a123fd 100644 --- a/designer-base/src/main/java/com/fr/design/mod/ContentObjectManager.java +++ b/designer-base/src/main/java/com/fr/design/mod/ContentObjectManager.java @@ -9,6 +9,8 @@ import com.fr.data.SimpleDSColumn; import com.fr.data.condition.FormulaCondition; import com.fr.data.impl.FormulaDictionary; import com.fr.data.impl.NameTableData; +import com.fr.design.mod.impl.repalce.JavaScriptContentReplacer; +import com.fr.design.mod.impl.repalce.VanChartHtmlLabelContentReplacer; import com.fr.form.main.FormHyperlink; import com.fr.form.ui.CardSwitchButton; import com.fr.form.ui.WidgetTitle; @@ -22,6 +24,8 @@ import com.fr.report.cell.cellattr.core.group.DSColumn; import com.fr.report.cell.cellattr.core.group.FunctionGrouper; import com.fr.report.cell.cellattr.core.group.SelectCount; import com.fr.stable.Filter; +import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -45,10 +49,12 @@ public class ContentObjectManager { /** * 放置所有需要替换内容的对象 */ - private Map> objectMap; + private Map> objectMap; private final Set set = new HashSet<>(); + private final Map map = new HashMap<>(); + private ContentObjectManager() { set.add(Formula.class.getName()); set.add(JavaScriptImpl.class.getName()); @@ -70,6 +76,8 @@ public class ContentObjectManager { set.add(SelectCount.class.getName()); set.add(WidgetTitle.class.getName()); set.add(FunctionGrouper.class.getName()); + map.put(JavaScriptImpl.class.getName(), new JavaScriptContentReplacer()); + map.put(VanChartHtmlLabel.class.getName(), new VanChartHtmlLabelContentReplacer()); } public void searchObject(Object ob) { @@ -84,12 +92,32 @@ public class ContentObjectManager { objectMap = ClassHelper.searchObject(ob, set, filter); } public void clearObject() { + if (objectMap != null) { + objectMap.clear(); + } objectMap = null; } @Nullable - public Map> getObjectMap() { + public Map> getObjectMap() { return objectMap; } + public boolean needContentTip(Object ob, Set nameSet) { + objectMap = ClassHelper.searchObject(ob, set, ModClassFilter.getInstance()); + for (Map.Entry> entry : objectMap.entrySet()) { + for (Object o : entry.getValue()) { + for (String name : nameSet) { + ContentReplacer contentReplacer = map.get(entry.getKey()); + if (contentReplacer!= null && contentReplacer.contain(o, name)) { + clearObject(); + return true; + } + } + } + } + clearObject(); + return false; + } + } diff --git a/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java b/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java index 1d8e73e84..f2afd5d8d 100644 --- a/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java +++ b/designer-base/src/main/java/com/fr/design/mod/ContentReplaceUtil.java @@ -168,5 +168,12 @@ public class ContentReplaceUtil { return content; } + public static boolean containsName(String content, String name) { + if (StringUtils.isNotEmpty(content)) { + return content.contains(name); + } + return false; + } + } diff --git a/designer-base/src/main/java/com/fr/design/mod/ContentReplacer.java b/designer-base/src/main/java/com/fr/design/mod/ContentReplacer.java index 3f7126535..a9d54b6a4 100644 --- a/designer-base/src/main/java/com/fr/design/mod/ContentReplacer.java +++ b/designer-base/src/main/java/com/fr/design/mod/ContentReplacer.java @@ -10,4 +10,9 @@ public interface ContentReplacer { void replace(T t, String oldName, String newName); + + default boolean contain(T t, String name) { + return false; + } + } diff --git a/designer-base/src/main/java/com/fr/design/mod/ContentReplacerCenter.java b/designer-base/src/main/java/com/fr/design/mod/ContentReplacerCenter.java index cccc08c9a..7440895a8 100644 --- a/designer-base/src/main/java/com/fr/design/mod/ContentReplacerCenter.java +++ b/designer-base/src/main/java/com/fr/design/mod/ContentReplacerCenter.java @@ -29,9 +29,9 @@ import com.fr.event.EventDispatcher; import com.fr.event.Listener; import com.fr.log.FineLoggerFactory; import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Set; /** * 默认联动内容替换器实现 @@ -106,14 +106,14 @@ public class ContentReplacerCenter { } private void onRename(List contentChangeItemList, List contentChangeList) { - Map> objectMap = ContentObjectManager.getInstance().getObjectMap(); + Map> objectMap = ContentObjectManager.getInstance().getObjectMap(); if (objectMap != null) { long start = System.currentTimeMillis(); for (ContentChange contentChange : contentChangeList) { - Set set = objectMap.get(contentChange.type()); + Collection objects = objectMap.get(contentChange.type()); // 所有需要处理的js等对象 - if (set != null) { - for (Object ob : set) { + if (objects != null) { + for (Object ob : objects) { fireChange(ob, contentChange, contentChangeItemList); } } diff --git a/designer-base/src/main/java/com/fr/design/mod/impl/repalce/JavaScriptContentReplacer.java b/designer-base/src/main/java/com/fr/design/mod/impl/repalce/JavaScriptContentReplacer.java index 118f1b79c..763b0b4a0 100644 --- a/designer-base/src/main/java/com/fr/design/mod/impl/repalce/JavaScriptContentReplacer.java +++ b/designer-base/src/main/java/com/fr/design/mod/impl/repalce/JavaScriptContentReplacer.java @@ -19,4 +19,8 @@ public class JavaScriptContentReplacer implements ContentReplacer map) { + super(network, map); + this.component = component; + } + + @Override + protected Response next(UrlRequest urlRequest, String path) { + if (path.startsWith("emb:dynamic")) { + String text = htmlText(map); + return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, "text/html", text.getBytes(StandardCharsets.UTF_8))); + } else { + int index = path.indexOf("="); + if (index > 0) { + path = path.substring(index + 1); + } else { + path = path.substring(4); + } + InputStream inputStream = IOUtils.readResource(path); + return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, getMimeType(path), IOUtils.inputStream2Bytes(inputStream))); + } + } + + private String htmlText(Map map) { + PathGroup pathGroup = AtomBuilder.create().buildAssembleFilePath(ModernRequestClient.KEY, component); + StylePath[] stylePaths = pathGroup.toStylePathGroup(); + StringBuilder styleText = new StringBuilder(); + for (StylePath path : stylePaths) { + if (StringUtils.isNotBlank(path.toFilePath())) { + styleText.append(""); + } + } + String result = ModernUIConstants.HTML_TPL.replaceAll("##style##", styleText.toString()); + ScriptPath[] scriptPaths = pathGroup.toScriptPathGroup(); + StringBuilder scriptText = new StringBuilder(); + for (ScriptPath path : scriptPaths) { + if (StringUtils.isNotBlank(path.toFilePath())) { + scriptText.append(""); + } + } + result = result.replaceAll("##script##", scriptText.toString()); + if (map != null) { + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + result = result.replaceAll("\\$\\{" + key + "}", value); + } + } + return result; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java b/designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java new file mode 100644 index 000000000..7b4977e77 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java @@ -0,0 +1,134 @@ +package com.fr.design.ui.compatible; + +import com.fr.base.TemplateUtils; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.EncodeConstants; +import com.fr.stable.StringUtils; +import com.fr.third.org.apache.commons.codec.net.URLCodec; +import com.teamdev.jxbrowser.net.HttpHeader; +import com.teamdev.jxbrowser.net.HttpStatus; +import com.teamdev.jxbrowser.net.Network; +import com.teamdev.jxbrowser.net.UrlRequest; +import com.teamdev.jxbrowser.net.UrlRequestJob; +import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2020/3/25 + */ +public class NxInterceptRequestCallback implements InterceptRequestCallback { + + Network network; + Map map; + + public NxInterceptRequestCallback(Network network) { + this.network = network; + } + + public NxInterceptRequestCallback(Network network, Map map) { + this.network = network; + this.map = map; + } + + @Override + public Response on(Params params) { + UrlRequest urlRequest = params.urlRequest(); + String path = urlRequest.url(); + if (path.startsWith("file:")) { + Optional optional = generateFileProtocolUrlRequestJob(urlRequest, path); + if (optional.isPresent()) { + return InterceptRequestCallback.Response.intercept(optional.get()); + } + } else { + return next(urlRequest, path); + } + return Response.proceed(); + } + + Response next(UrlRequest urlRequest, String path) { + return Response.proceed(); + } + + private Optional generateFileProtocolUrlRequestJob(UrlRequest urlRequest, String path) { + try { + String url = new URLCodec().decode(path); + String filePath = TemplateUtils.renderParameter4Tpl(url, map); + File file = new File(URI.create(filePath).getPath()); + InputStream inputStream = IOUtils.readResource(file.getAbsolutePath()); + String mimeType = getMimeType(path); + byte[] bytes; + if (isPlainText(mimeType)) { + String text = IOUtils.inputStream2String(inputStream, EncodeConstants.ENCODING_UTF_8); + text = TemplateUtils.renderParameter4Tpl(text, map); + bytes = text.getBytes(StandardCharsets.UTF_8); + } else { + bytes = IOUtils.inputStream2Bytes(inputStream); + } + return Optional.of(generateBasicUrlRequestJob(urlRequest, mimeType, bytes)); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return Optional.empty(); + } + + private boolean isPlainText(String mimeType) { + return ArrayUtils.contains(new String[]{"text/html", "text/javascript", "text/css"}, mimeType); + } + + UrlRequestJob generateBasicUrlRequestJob(UrlRequest urlRequest, String mimeType, byte[] bytes) { + UrlRequestJob.Options options = UrlRequestJob.Options + .newBuilder(urlRequest.id(), HttpStatus.OK) + .addHttpHeader(HttpHeader.of("Content-Type", mimeType)) + .build(); + UrlRequestJob urlRequestJob = network.newUrlRequestJob(options); + urlRequestJob.write(bytes); + urlRequestJob.complete(); + return urlRequestJob; + } + + String getMimeType(String path) { + if (StringUtils.isBlank(path)) { + return "text/html"; + } + if (path.endsWith(".html")) { + return "text/html"; + } + if (path.endsWith(".css")) { + return "text/css"; + } + if (path.endsWith(".js")) { + return "text/javascript"; + } + if (path.endsWith(".svg")) { + return "image/svg+xml"; + } + if (path.endsWith(".png")) { + return "image/png"; + } + if (path.endsWith(".jpeg")) { + return "image/jpeg"; + } + if (path.endsWith(".gif")) { + return "image/gif"; + } + Path file = new File(path).toPath(); + try { + return Files.probeContentType(file); + } catch (IOException e) { + return "text/html"; + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/update/actions/SyncFileProcess.java b/designer-base/src/main/java/com/fr/design/update/actions/SyncFileProcess.java new file mode 100644 index 000000000..ea2db1398 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/update/actions/SyncFileProcess.java @@ -0,0 +1,61 @@ +package com.fr.design.update.actions; + +import com.fr.decision.update.SyncExecutor; +import com.fr.decision.update.info.UpdateCallBack; +import com.fr.decision.update.info.UpdateProgressCallBack; +import com.fr.design.i18n.Toolkit; +import com.fr.design.versioncheck.VersionCheckUtils; +import com.fr.log.FineLoggerFactory; +import java.util.concurrent.ExecutionException; +import javax.swing.JProgressBar; +import javax.swing.SwingWorker; + +public abstract class SyncFileProcess extends SwingWorker { + private String buildNo; + private JProgressBar bar; + + public SyncFileProcess(JProgressBar bar, String buildNo) { + this.bar = bar; + this.buildNo = buildNo; + } + + @Override + protected Boolean doInBackground() throws Exception { + UpdateCallBack callBack = new UpdateProgressCallBack(bar); + boolean result = SyncExecutor.getInstance().execute(callBack, buildNo); + if (result) { + bar.setValue(0); + bar.setString(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugins")); + VersionCheckUtils.syncPlugins(VersionCheckUtils.checkLocalAndRemotePlugin()); + } + return result; + } + + @Override + protected void done() { + boolean success = false; + try { + success = get(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (success) { + onDownloadSuccess(); + } else { + onDownloadFailed(); + } + } + + /** + * 下载成功 + */ + public abstract void onDownloadSuccess(); + + /** + * 下载失败 + */ + public abstract void onDownloadFailed(); +} diff --git a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java new file mode 100644 index 000000000..11780409a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java @@ -0,0 +1,346 @@ +package com.fr.design.versioncheck; + +import com.fr.base.FRContext; +import com.fr.design.DesignerEnvManager; +import com.fr.design.dialog.NotificationDialog; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.DesignerWorkspaceType; +import com.fr.design.env.RemoteWorkspace; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.env.CheckServiceDialog; +import com.fr.env.VersionCheckMessageDialog; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralUtils; +import com.fr.invoke.Reflect; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.locale.InterProviderFactory; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.context.PluginMarker; +import com.fr.plugin.manage.PluginManager; +import com.fr.plugin.manage.control.PluginControllerHelper; +import com.fr.plugin.manage.control.PluginTaskCallback; +import com.fr.plugin.manage.control.PluginTaskResult; +import com.fr.plugin.manage.control.ProgressCallback; +import com.fr.rpc.Result; +import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; +import com.fr.workspace.base.WorkspaceAPI; +import com.fr.workspace.connect.WorkspaceConnectionInfo; +import com.fr.workspace.engine.base.FineObjectPool; +import com.fr.workspace.engine.channel.http.FunctionalHttpRequest; +import com.fr.workspace.engine.exception.WorkspaceConnectionException; +import com.fr.workspace.engine.rpc.WorkspaceProxyPool; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.lang.reflect.Method; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +/** + * @author pengda + * @version 10.0 + * Created on 2021-06-02 + */ +public class VersionCheckUtils { + public static final String INCONSISTENCY = "inconsistency"; + public static final String MISSING = "missing"; + private static final String ID = "id"; + private static final String VERSION = "version"; + private static final String NAME = "name"; + + + public static boolean versionCheck(String envName) { + return checkLocalAndRemoteJartime(envName) && checkLocalAndRemotePlugin().size() == 0; + } + + public static boolean versionCheck(DesignerWorkspaceInfo selectedEnv) { + return checkLocalAndRemoteJartime(selectedEnv) && checkLocalAndRemotePlugin().size() == 0; + } + + public static void showVersionCheckDialog(String envName) { + if (!VersionCheckUtils.versionCheck(envName)) { + VersionCheckMessageDialog versionCheckMessageDialog = new VersionCheckMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Check_Brief_Info"), envName); + versionCheckMessageDialog.setVisible(true); + } + } + + public static boolean checkLocalAndRemoteJartime(String envName) { + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + return checkLocalAndRemoteJartime(selectedEnv); + } + + public static boolean checkLocalAndRemoteJartime(DesignerWorkspaceInfo selectedEnv) { + //是否需要做服务校验 + if (needCheckBranch(selectedEnv)) { + String localBranch; + String remoteBranch = getRemoteBranch(selectedEnv); + localBranch = GeneralUtils.readFullBuildNO(); + //通过是否包含#来避免当前版本为非安装版本(主要是内部开发版本) + if (localBranch.contains("#") && ComparatorUtils.equals(localBranch, remoteBranch)) { + //说明版本一致,仅做日志记录 + FineLoggerFactory.getLogger().info("Remote Designer version consistency"); + return true; + } else { + return false; + } + } + return true; + } + + public static List getNoExistServiceDescription(String envName) { + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); + List noExistServiceDescription = new ArrayList<>(); + Set noExistServiceSet = getNoExistServiceSet(connectionInfo); + for (Class clazz : noExistServiceSet) { + WorkspaceAPI workspaceAPI = (WorkspaceAPI) clazz.getAnnotation(WorkspaceAPI.class); + if (workspaceAPI == null) { + FineLoggerFactory.getLogger().info("workspace service {} get annotation failed", clazz); + continue; + } + if (workspaceAPI.ignore()) { + continue; + } + String descriptionOfCN = InterProviderFactory.getProvider().getLocText(workspaceAPI.description()); + noExistServiceDescription.add(descriptionOfCN); + } + return noExistServiceDescription; + } + + public static String getRemoteBranch(String envName) { + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + return getRemoteBranch(selectedEnv); + } + + public static String getRemoteBranch(DesignerWorkspaceInfo selectedEnv) { + String remoteBranch = StringUtils.EMPTY; + WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); + try { + remoteBranch = new FunctionalHttpRequest(connectionInfo).getServerBranch(); + } catch (WorkspaceConnectionException e) { + remoteBranch = Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old") + formatBranch(GeneralUtils.readFullBuildNO()); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return remoteBranch; + } + + /** + * 获取不存在的服务列表 + * + * @param info 环境连接信息 + * @return 以Set形式返回不存在的服务 + */ + public static Set getNoExistServiceSet(WorkspaceConnectionInfo info) { + Set noExistServiceSet = new HashSet(); + Set remoteServiceSet = new HashSet(); + Set localServiceSet = FineObjectPool.getInstance().getServerPool().keySet(); + + try { + JSONArray serviceArray = new FunctionalHttpRequest(info).getServiceList(); + for (int i = 0; i < serviceArray.size(); i++) { + try { + Class clazz = Class.forName((String) serviceArray.get(i)); + remoteServiceSet.add(clazz); + } catch (Exception e) { + continue; + } + } + noExistServiceSet.addAll(localServiceSet); + noExistServiceSet.removeAll(remoteServiceSet); + return noExistServiceSet; + } catch (WorkspaceConnectionException e) { + FineLoggerFactory.getLogger().info(e.getMessage()); + //根据本地的服务列表做逐一检测 + for (Class clazz : localServiceSet) { + Method testMethod = Reflect.on(Method.class).create(clazz, "connectTest", new Class[0], String.class, new Class[0], 1025, 8, null, null, null, null).get(); + WorkspaceProxyPool proxyPool = (WorkspaceProxyPool) (((RemoteWorkspace) WorkContext.getCurrent()).getClient()).getPool(); + Result result = proxyPool.testInvoker(testMethod); + Exception invokeException = (Exception) result.getException(); + if (invokeException != null) { + Exception cause = (Exception) invokeException.getCause(); + //获取被包装最底层的异常 + while (cause != null) { + invokeException = cause; + cause = (Exception) invokeException.getCause(); + } + //该异常表示服务不存在 + if (invokeException instanceof ClassNotFoundException) { + noExistServiceSet.add(clazz); + } + } + } + return noExistServiceSet; + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return noExistServiceSet; + } + } + + /** + * 格式化分支版本号 + * + * @param buildNO 初始的分支版本号 + * @return 格式化后的版本号 + */ + private static String formatBranch(String buildNO) { + Date jarDate = (new SimpleDateFormat("yyyy.MM.dd")).parse(buildNO, new ParsePosition(buildNO.indexOf("-") + 1)); + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + return df.format(jarDate); + } + + private static boolean needCheckBranch(DesignerWorkspaceInfo selectedEnv) { + if (selectedEnv.getType() == DesignerWorkspaceType.Remote) { + return true; + } + return false; + } + + public static JSONArray checkLocalAndRemotePlugin() { + JSONArray differentPlugins = new JSONArray(); + JSONArray remotePlugins = FRContext.getCommonOperator().getPluginStatus(); + Map localPluginsMap = new HashMap<>(); + List localPlugins = PluginManager.getContexts(); + for (PluginContext pluginContext : localPlugins) { + localPluginsMap.put(pluginContext.getID(), pluginContext); + } + JSONObject remotePlugin; + for (int i = 0; i < remotePlugins.size(); i++) { + remotePlugin = remotePlugins.getJSONObject(i); + if (localPluginsMap.containsKey(remotePlugin.getString(ID))) { + if (ComparatorUtils.equals(localPluginsMap.get(remotePlugin.getString(ID)).getVersion(), remotePlugin.getString(VERSION))) { + continue; + } else { + if (remotePlugin.getString(NAME) == null) { + remotePlugin.put(NAME, localPluginsMap.get(remotePlugin.getString(ID)).getName()); + } + remotePlugin.put("type", INCONSISTENCY); + } + } else { + remotePlugin.put("type", MISSING); + if (remotePlugin.getString(NAME) == null) { + remotePlugin.put(NAME, remotePlugin.getString("id")); + } + } + differentPlugins.put(remotePlugin); + } + return differentPlugins; + } + + public static void syncPlugins(JSONArray differentPlugins) { + Set uninstallFailed = uninstallPlugins(differentPlugins); + List plugins = getSyncPlugins(differentPlugins, uninstallFailed); + installPlugins(plugins); + } + + private static List getSyncPlugins(JSONArray differentPlugins, Set uninstallFailed) { + JSONObject differentPlugin; + String id; + String version; + List plugins = new ArrayList<>(); + if (differentPlugins != null) { + for (int i = 0; i < differentPlugins.size(); i++) { + differentPlugin = differentPlugins.getJSONObject(i); + id = differentPlugin.getString(ID); + if (uninstallFailed.contains(id)) { + continue; + } + version = differentPlugin.getString(VERSION); + plugins.add(PluginMarker.create(id, version)); + } + } + return plugins; + } + + private static Set uninstallPlugins(JSONArray differentPlugins) { + Set pluginsNeedUninstall = new HashSet<>(); + Map localPluginsMap = new HashMap<>(); + List localPlugins = PluginManager.getContexts(); + for (PluginContext pluginContext : localPlugins) { + localPluginsMap.put(pluginContext.getID(), pluginContext); + } + for (int i = 0; i < differentPlugins.size(); i++) { + String id = differentPlugins.getJSONObject(i).getString(ID); + if (localPluginsMap.containsKey(id)) { + pluginsNeedUninstall.add(localPluginsMap.get(id).getMarker()); + } + } + Set uninstallFailedID = new HashSet<>(); + CountDownLatch latch = new CountDownLatch(pluginsNeedUninstall.size()); + for (PluginMarker pluginMarker : pluginsNeedUninstall) { + PluginManager.getController().uninstall(pluginMarker, true, new PluginTaskCallback() { + @Override + public void done(PluginTaskResult result) { + latch.countDown(); + if (!result.isSuccess()) { + uninstallFailedID.add(pluginMarker.getPluginID()); + } + } + }); + } + try { + latch.await(5000, TimeUnit.MILLISECONDS); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return uninstallFailedID; + } + + public static JSONArray getPluginsSyncFailed(JSONArray differentPlugins){ + JSONArray pluginsNeedSync = JSONArray.create(); + List localPlugins = PluginManager.getContexts(); + Map localPluginsInfo = new HashMap<>(); + for (int i = 0; i < localPlugins.size(); i++) { + localPluginsInfo.put(localPlugins.get(i).getID(), localPlugins.get(i).getVersion()); + } + for (int i = 0; i < differentPlugins.size(); i++) { + JSONObject plugin = differentPlugins.getJSONObject(i); + String id = plugin.getString(ID); + if (localPluginsInfo.containsKey(id) && ComparatorUtils.equals(plugin.getString(VERSION), localPluginsInfo.get(id))) { + continue; + } + pluginsNeedSync.add(plugin); + } + return pluginsNeedSync; + } + + private static void installPlugins(List plugins) { + CountDownLatch latch = new CountDownLatch(plugins.size()); + for (int i = 0; i < plugins.size(); i++) { + PluginControllerHelper.installOnline(plugins.get(i), new ProgressCallback() { + @Override + public void updateProgress(String description, double progress) { + + } + + @Override + public void done(PluginTaskResult result) { + latch.countDown(); + FineLoggerFactory.getLogger().info("installPlugin: " + result.getCurrentTask().getMarker().getPluginID()); + } + }); + } + try { + latch.await(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + } +} diff --git a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java index efee9bfdf..7e9e74ebc 100644 --- a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java +++ b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java @@ -1,32 +1,64 @@ package com.fr.env; -import com.fr.design.DesignerEnvManager; -import com.fr.design.env.RemoteDesignerWorkspaceInfo; +import com.fr.decision.update.data.UpdateConstants; +import com.fr.design.RestartHelper; +import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.update.actions.SyncFileProcess; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.env.utils.DisplayUtils; +import com.fr.design.versioncheck.VersionCheckUtils; +import com.fr.general.CloudCenter; +import com.fr.general.CloudCenterConfig; +import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.GeneralContext; import com.fr.general.IOUtils; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.process.engine.core.FineProcessContext; +import com.fr.process.engine.core.FineProcessEngineEvent; +import com.fr.stable.CommonUtils; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; +import com.sun.java.swing.plaf.motif.MotifProgressBarUI; +import java.awt.Color; +import java.awt.Component; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.File; +import java.util.List; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.JDialog; +import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; -import javax.swing.JTextArea; -import javax.swing.JTextPane; +import javax.swing.JProgressBar; +import javax.swing.JScrollPane; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.Locale; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingWorker; +import javax.swing.UIManager; + + +import static javax.swing.JOptionPane.QUESTION_MESSAGE; /** * @author: Maksim @@ -36,11 +68,34 @@ import java.util.Locale; public class CheckServiceDialog extends JDialog implements ActionListener { private JPanel topPanel; private JPanel centerPanel; - private JPanel bottomPanel; - private UICheckBox remindBox; + private UIButton ignoreButton; + private UIButton syncButton; + private JProgressBar progressBar; + private String remoteBuildNo; + private static final Dimension PROGRESSBAR = new Dimension(120, 15); + private JSONArray differentPlugins; + private UILabel affectedFunctionsLabel; + private UILabel jarCheckResultLabel; + private UILabel jarCheckTitleLabel; + private UILabel pluginCheckTitleLabel; + + private JPanel affectedFunctionsDetailsPane; + private JPanel pluginsCheckResultPanel; + private JPanel detailsInnerPane; + private JPanel detailsPane; + private JScrollPane jScrollPane; + private Component[][] detailsComponents; + private Component[][] hideAffectedFunctionsComponents; + private boolean showAffectedFunctions = true; + private boolean jarConsistency; + private double p = TableLayout.PREFERRED; + private double f = TableLayout.FILL; - public CheckServiceDialog(Frame parent, String areaText, String localBranch, String remoteBranch){ - super(parent,true); + public CheckServiceDialog(Frame parent, String localBranch, String remoteBranch, List noExistServiceDescription) { + super(parent, true); + this.remoteBuildNo = remoteBranch; + this.differentPlugins = VersionCheckUtils.checkLocalAndRemotePlugin(); + this.jarConsistency = ComparatorUtils.equals(localBranch, remoteBranch); //上面的标签面板 topPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); JPanel imagePanel = new JPanel(); @@ -49,90 +104,299 @@ public class CheckServiceDialog extends JDialog implements ActionListener { JLabel imageLabel = new JLabel(); imageLabel.setIcon(icon); imagePanel.add(imageLabel); - imagePanel.setPreferredSize(new Dimension(110,100)); + imagePanel.setPreferredSize(new Dimension(110, 100)); JPanel verticalPanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); FRFont font = FRFont.getInstance(); font = font.applySize(15).applyStyle(1); - JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Inconsistency")); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Branch_Inconsistency")); label.setFont(font); - label.setPreferredSize(new Dimension(650,30)); - - String text = Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Local_Designer") + localBranch - + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Remote_Server") + - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old") + - localBranch; - String delimiter = DisplayUtils.getDisplayLength(text) > 70? "
":"/"; - JLabel label2 = new JLabel(""+Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Local_Designer") - + localBranch + delimiter + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Remote_Server") + - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old")+ localBranch +""); - label2.setPreferredSize(new Dimension(600,30)); - - JTextPane tipsPane = new JTextPane(); - tipsPane.setEditable(false); - tipsPane.setBackground(verticalPanel.getBackground()); - tipsPane.setPreferredSize(new Dimension(500,40)); - tipsPane.setText(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Need_Update")); + label.setPreferredSize(new Dimension(650, 30)); + UILabel label2 = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Inconsistency_Risk")); + label2.setPreferredSize(new Dimension(600, 30)); verticalPanel.add(label); verticalPanel.add(label2); - verticalPanel.add(tipsPane); - topPanel.add(imagePanel,BorderLayout.WEST); - topPanel.add(verticalPanel,BorderLayout.CENTER); - topPanel.setBorder(BorderFactory.createEmptyBorder(10,10,0,10)); + topPanel.add(imagePanel, BorderLayout.WEST); + topPanel.add(verticalPanel, BorderLayout.CENTER); + topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); //中间的文本域面板 centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - centerPanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); - centerPanel.setPreferredSize(new Dimension(480,320)); - - JLabel titleLabel = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Affected_Function")); - titleLabel.setPreferredSize(new Dimension(400,40)); - JTextArea checkArea = new JTextArea(areaText); - checkArea.setEnabled(false); - centerPanel.add(titleLabel,BorderLayout.NORTH); - centerPanel.add(checkArea,BorderLayout.CENTER); - - //下面的按钮面板 - remindBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Remind_Show")); - remindBox.addActionListener(remindCheckboxListener); - UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Button_Confirm")); - JPanel buttonPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - buttonPanel.setBorder(BorderFactory.createEmptyBorder(0,10,10,10)); - buttonPanel.add(remindBox, BorderLayout.WEST); - buttonPanel.add(okButton,BorderLayout.EAST); - okButton.addActionListener(this ); - bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); - bottomPanel.add(buttonPanel); + centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + centerPanel.setPreferredSize(new Dimension(480, 320)); + + UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Details")); + titleLabel.setPreferredSize(new Dimension(400, 40)); + //详情面板 + detailsPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); + detailsPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 0)); + detailsPane.setBackground(Color.WHITE); + + jarCheckTitleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_JAR_Check_title")); + jarCheckTitleLabel.setBackground(Color.WHITE); + + //插件的检测结果相关面板 + pluginCheckTitleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Check_title")); + pluginCheckTitleLabel.setBackground(Color.WHITE); + initPluginsCheckResultPanel(differentPlugins); + + //jar包检测结果相关面板 + initJarCheckResultPanel(remoteBranch, noExistServiceDescription); + + double[] detailsRowSize; + double[] detailsColumnSize = {f}; + + detailsComponents = new Component[][]{{jarCheckTitleLabel}, {jarCheckResultLabel}, {affectedFunctionsLabel}, {affectedFunctionsDetailsPane}, {pluginCheckTitleLabel}, {pluginsCheckResultPanel}}; + hideAffectedFunctionsComponents = new Component[][]{{jarCheckTitleLabel}, {jarCheckResultLabel}, {affectedFunctionsLabel}, {pluginCheckTitleLabel}, {pluginsCheckResultPanel}}; + if (noExistServiceDescription.size() > 0 && !ComparatorUtils.equals(remoteBranch, localBranch)) { + detailsRowSize = new double[]{p, p, p, p, p, p}; + detailsInnerPane = TableLayoutHelper.createTableLayoutPane(detailsComponents, detailsRowSize, detailsColumnSize); + } else { + detailsRowSize = new double[]{p, p, 0, 0, p, p}; + detailsInnerPane = TableLayoutHelper.createTableLayoutPane(detailsComponents, detailsRowSize, detailsColumnSize); + } + detailsInnerPane.setBackground(Color.WHITE); + jScrollPane = new JScrollPane(detailsInnerPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + jScrollPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + detailsPane.add(jScrollPane); + + centerPanel.add(titleLabel, BorderLayout.NORTH); + centerPanel.add(detailsPane, BorderLayout.CENTER); + JPanel buttonPanel = FRGUIPaneFactory.createBorderLayout_M_Pane(); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); + if (isOnline()) { + ignoreButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_Ignore")); + ignoreButton.addActionListener(this); + syncButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_To_Local")); + syncButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Sync_To_Local_Tip")); + syncButton.addMouseListener(syncButtonClickListener); + progressBar = new JProgressBar(); + progressBar.setUI(new MotifProgressBarUI()); + progressBar.setForeground(UpdateConstants.BAR_COLOR); + progressBar.setVisible(false); + progressBar.setStringPainted(true); + progressBar.setPreferredSize(PROGRESSBAR); + buttonPanel.add(ignoreButton, BorderLayout.WEST); + buttonPanel.add(progressBar, BorderLayout.CENTER); + buttonPanel.add(syncButton, BorderLayout.EAST); + } else { + UILabel adviceLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Suggestion")); + centerPanel.add(adviceLabel, BorderLayout.SOUTH); + UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Button_Confirm")); + okButton.addActionListener(this); + buttonPanel.add(okButton, BorderLayout.EAST); + } this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Title_Hint")); this.setResizable(false); - - this.add(topPanel,BorderLayout.NORTH); + this.add(topPanel, BorderLayout.NORTH); this.add(centerPanel, BorderLayout.CENTER); - this.add(buttonPanel,BorderLayout.SOUTH); - this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US)? 750:600, 500)); - + this.add(buttonPanel, BorderLayout.SOUTH); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 750 : 600, 500)); GUICoreUtils.centerWindow(this); } + + /** + * 插件检测的结果 + */ + private void initPluginsCheckResultPanel(JSONArray differentPlugins) { + + if (differentPlugins.size() > 0) { + int size = differentPlugins.size(); + Component[][] pluginCheckResultComponents = new Component[size][1]; + double[] pluginCheckResultColumnSize = new double[size]; + for (int i = 0; i < size; i++) { + JSONObject plugin = differentPlugins.getJSONObject(i); + JLabel pluginLabel; + if (ComparatorUtils.equals(VersionCheckUtils.INCONSISTENCY, plugin.getString("type"))) { + pluginLabel = new JLabel("\"" + plugin.getString("name") + "\"" + Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Inconsistency_Info") + plugin.getString("version")); + } else if (ComparatorUtils.equals(VersionCheckUtils.MISSING, plugin.getString("type"))) { + pluginLabel = new JLabel("\"" + plugin.getString("name") + "\"" + Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Missing_Info") + plugin.getString("version")); + } else { + continue; + } + pluginLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/fail.png")); + pluginCheckResultComponents[i][0] = pluginLabel; + pluginCheckResultColumnSize[i] = p; + } + double[] pluginCheckResultRowSize = {f}; + pluginsCheckResultPanel = TableLayoutHelper.createTableLayoutPane(pluginCheckResultComponents, pluginCheckResultColumnSize, pluginCheckResultRowSize); + } else { + UILabel pluginCheckResultLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Consistency")); + pluginCheckResultLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/success.png")); + pluginsCheckResultPanel = TableLayoutHelper.createTableLayoutPane(new Component[][]{{pluginCheckResultLabel}}, new double[]{p}, new double[]{f}); + } + pluginsCheckResultPanel.setBackground(Color.WHITE); + } + + /** + * jar包检测的结果 + */ + private void initJarCheckResultPanel(String remoteBranch, List noExistServiceDescription) { + jarCheckResultLabel = new UILabel(); + jarCheckResultLabel.setBackground(Color.WHITE); + if (jarConsistency) { + jarCheckResultLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Sync_JAR_Consistency")); + jarCheckResultLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/success.png")); + } else { + jarCheckResultLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Sync_JAR_Inconsistency_Info") + remoteBranch); + jarCheckResultLabel.setIcon(IOUtils.readIcon("com/fr/design/icon/versioncheck/fail.png")); + Component[][] noExistServiceComponents; + int noExistService = noExistServiceDescription.size(); + if (noExistService > 0) { + affectedFunctionsLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Affected_Function")); + affectedFunctionsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + affectedFunctionsLabel.setBackground(Color.WHITE); + affectedFunctionsLabel.addMouseListener(affectedFunctionsClickListener); + noExistServiceComponents = new Component[noExistServiceDescription.size()][1]; + double[] noExistServiceColumnSize = new double[noExistService]; + for (int i = 0; i < noExistService; i++) { + JLabel noExitServiceLabel = new JLabel(" " + noExistServiceDescription.get(i)); + noExistServiceComponents[i][0] = noExitServiceLabel; + noExistServiceColumnSize[i] = p; + } + double[] noExistServiceRowSize = {f}; + affectedFunctionsDetailsPane = TableLayoutHelper.createTableLayoutPane(noExistServiceComponents, noExistServiceColumnSize, noExistServiceRowSize); + affectedFunctionsDetailsPane.setBackground(Color.WHITE); + } + } + } + @Override public void actionPerformed(ActionEvent e) { this.dispose(); } + private boolean isOnline() { + if (CloudCenterConfig.getInstance().isOnline()) { + String ping = CloudCenter.getInstance().acquireConf("ping", StringUtils.EMPTY); + if (StringUtils.isNotEmpty(ping)) { + try { + return StringUtils.isEmpty(HttpToolbox.get(ping)); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + } + return false; + } - private ActionListener remindCheckboxListener = new ActionListener() { + private MouseListener affectedFunctionsClickListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (showAffectedFunctions) { + showAffectedFunctions = false; + detailsInnerPane.removeAll(); + affectedFunctionsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + TableLayoutHelper.addComponent2ResultPane(hideAffectedFunctionsComponents, new double[]{p, p, p, p, p}, new double[]{f}, detailsInnerPane); + jScrollPane.validate(); + jScrollPane.repaint(); + } else { + showAffectedFunctions = true; + detailsInnerPane.removeAll(); + affectedFunctionsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + TableLayoutHelper.addComponent2ResultPane(detailsComponents, new double[]{p, p, p, p, p, p}, new double[]{f}, detailsInnerPane); + jScrollPane.validate(); + jScrollPane.repaint(); + } + } + }; + private MouseListener syncButtonClickListener = new MouseAdapter() { @Override - public void actionPerformed(ActionEvent e) { - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - String remindTime = format.format(new Date()); - //环境已切换,通过当前环境获取,一定是远程环境 - String currentEnvName = DesignerEnvManager.getEnvManager().getCurEnvName(); - RemoteDesignerWorkspaceInfo currentEnv = (RemoteDesignerWorkspaceInfo)DesignerEnvManager.getEnvManager().getWorkspaceInfo(currentEnvName); - currentEnv.setRemindTime(remindBox.isSelected()? remindTime : ""); + public void mouseClicked(MouseEvent e) { + String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")}; + int a = FineJOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Basic_Sync_Info_Information"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, IOUtils.readIcon("com/fr/design/icon/versioncheck/question.png"), option, 1); + if (0 == a) { + //jar包一致的话只更新插件 + progressBar.setVisible(true); + progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message")); + syncButton.setEnabled(false); + if (!jarConsistency) { + deletePreviousPropertyFile(); + final String installLib = StableUtils.pathJoin(StableUtils.getInstallHome(), ProjectConstants.LOGS_NAME, UpdateConstants.INSTALL_LIB); + final JFrame frame = DesignerContext.getDesignerFrame(); + final RestartHelper helper = new RestartHelper(); + FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY); + new SyncFileProcess(progressBar, remoteBuildNo) { + @Override + public void onDownloadSuccess() { + deleteForDesignerUpdate(installLib); + progressBar.setVisible(false); + JSONArray syncFailedPlugins = VersionCheckUtils.getPluginsSyncFailed(differentPlugins); + if (syncFailedPlugins.size() > 0) { + SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(DesignerContext.getDesignerFrame(), syncFailedPlugins); + syncFailedPluginsDialog.setVisible(true); + } + helper.restartForUpdate(frame); + } + + @Override + public void onDownloadFailed() { + progressBar.setVisible(false); + deleteForDesignerUpdate(installLib); + ErrorDialog errorDialog = new ErrorDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Fail")); + errorDialog.setVisible(true); + helper.restartForUpdate(frame); + } + }.execute(); + } else { + //到这边说明主jar是一致的,就只尝试同步插件 + new SwingWorker() { + + @Override + protected JSONArray doInBackground() { + progressBar.setString(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugins")); + progressBar.setValue(0); + VersionCheckUtils.syncPlugins(differentPlugins); + return VersionCheckUtils.getPluginsSyncFailed(differentPlugins); + } + + @Override + protected void done() { + progressBar.setVisible(false); + JSONArray syncFailedPlugins = null; + try { + syncFailedPlugins = get(); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + if (syncFailedPlugins != null && syncFailedPlugins.size() > 0) { + SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(DesignerContext.getDesignerFrame(), syncFailedPlugins); + syncFailedPluginsDialog.setVisible(true); + } else { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Sync_Success"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + FineJOptionPane.INFORMATION_MESSAGE); + } + close(); + } + }.execute(); + } + } } }; + private boolean deletePreviousPropertyFile() { + File moveFile = new File(RestartHelper.MOVE_FILE); + File delFile = new File(RestartHelper.RECORD_FILE); + if (StableUtils.mkdirs(moveFile) && StableUtils.mkdirs(delFile)) { + return StableUtils.deleteFile(moveFile) && StableUtils.deleteFile(delFile); + } + return false; + } + + private void close() { + this.dispose(); + } + + private void deleteForDesignerUpdate(String installLib) { + File dir = new File(installLib); + CommonUtils.deleteFile(dir); + } } diff --git a/designer-base/src/main/java/com/fr/env/ErrorDialog.java b/designer-base/src/main/java/com/fr/env/ErrorDialog.java new file mode 100644 index 000000000..be91955f2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/ErrorDialog.java @@ -0,0 +1,73 @@ +package com.fr.env; + +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.CloudCenter; +import com.fr.general.GeneralContext; +import com.fr.general.IOUtils; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Locale; +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; + +/** + * 主jar下载失败的弹出框 + * + * */ + +public class ErrorDialog extends JDialog implements ActionListener { + public ErrorDialog(Frame parent, String message) { + super(parent, true); + init(message); + } + + private void init(String message){ + //主体内容 + JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + //带超链的提示信息 + JPanel messagePanel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + messagePanel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); + + MessageWithLink messageWithLink = new MessageWithLink(message + ",", Toolkit.i18nText("Fine-Design_Basic_Sync_Help"), CloudCenter.getInstance().acquireUrlByKind("help.replacejars", "https://help.fanruan.com/finereport/doc-view-3268.html")); + messageWithLink.setPreferredSize(new Dimension(108, 20)); + JPanel messageLinkPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + messageLinkPane.setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 0)); + messageLinkPane.add(messageWithLink); + + //错误提示图标 + UILabel imageLabel = new UILabel(IOUtils.readIcon("com/fr/design/icon/versioncheck/bigfail.png")); + messagePanel.add(imageLabel); + messagePanel.add(messageLinkPane); + + //确定按钮 + UIButton ok = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Button_OK")); + ok.addActionListener(this); + ok.setSize(new Dimension(44, 20)); + JPanel okPanel = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + okPanel.add(ok); + + centerPanel.add(messagePanel, BorderLayout.CENTER); + centerPanel.add(okPanel, BorderLayout.SOUTH); + + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")); + this.setResizable(false); + this.add(centerPanel, BorderLayout.CENTER); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 282 : 262, 118)); + GUICoreUtils.centerWindow(this); + } + + @Override + public void actionPerformed(ActionEvent e) { + this.dispose(); + } +} diff --git a/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java new file mode 100644 index 000000000..9bf63460d --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java @@ -0,0 +1,120 @@ +package com.fr.env; + +import com.fr.design.RestartHelper; +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextarea.UITextArea; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.CloudCenter; +import com.fr.general.GeneralContext; +import com.fr.general.IOUtils; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.stable.StringUtils; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.Locale; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.UIManager; + +/** + * @author pengda + * @version 10.0 + * Created on 2021-06-02 + */ +public class SyncFailedPluginsDialog extends JDialog { + private UILabel detailsLabel; + private JScrollPane scrollPane; + public SyncFailedPluginsDialog(Frame parent, JSONArray syncFailedPlugins) { + super(parent, true); + JPanel body = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + JPanel northPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + northPane.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); + JPanel imagePanel = new JPanel(); + Icon icon = IOUtils.readIcon("com/fr/design/icon/versioncheck/warning.png"); + JLabel imageLabel = new JLabel(); + imageLabel.setIcon(icon); + imagePanel.add(imageLabel); + imagePanel.setPreferredSize(new Dimension(20, 20)); + + JPanel messagePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + MessageWithLink messageWithLink = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Fail_Suggestion"),Toolkit.i18nText("Fine-Design_Basic_Sync_Deal_Immediately"), + CloudCenter.getInstance().acquireUrlByKind("help.installplugins", "https://help.fanruan.com/finereport/doc-view-2198.html")); + messageWithLink.setPreferredSize(new Dimension(316, 20)); + + messagePane.add(messageWithLink); + messagePane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); + + northPane.add(imageLabel, BorderLayout.WEST); + northPane.add(messagePane, BorderLayout.CENTER); + + JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + detailsLabel = new UILabel(Toolkit.i18nText("Fine_Designer_Look_Detail")); + detailsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + detailsLabel.addMouseListener(detailsLabelClickListener); + JPanel detailsTitlePanel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + detailsTitlePanel.add(detailsLabel); + detailsTitlePanel.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); + + UITextArea detailsTextArea = new UITextArea(); + StringBuilder detailsText = new StringBuilder(StringUtils.EMPTY); + for (int i = 0; i < syncFailedPlugins.size(); i++) { + JSONObject plugin = syncFailedPlugins.getJSONObject(i); + detailsText.append(plugin.getString("name")).append(",").append(Toolkit.i18nText("Fine-Design_Basic_Sync_Server_Version")).append(plugin.getString("version")).append("\n"); + } + detailsTextArea.setText(detailsText.toString()); + detailsTextArea.setEditable(false); + scrollPane = new JScrollPane(detailsTextArea); + centerPanel.add(detailsTitlePanel,BorderLayout.NORTH); + centerPanel.add(scrollPane,BorderLayout.CENTER); + + JPanel southPane = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane(); + UIButton restartButton = new UIButton(Toolkit.i18nText("Fine-Design_Updater_Restart_Designer")); + restartButton.addMouseListener(restartButtonClickListener); + southPane.add(restartButton); + + body.add(northPane,BorderLayout.NORTH); + body.add(centerPanel,BorderLayout.CENTER); + body.add(southPane,BorderLayout.SOUTH); + + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")); + this.setResizable(false); + this.add(body, BorderLayout.CENTER); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 400 : 380, 225)); + GUICoreUtils.centerWindow(this); + } + + private MouseListener detailsLabelClickListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if(scrollPane.isVisible()){ + scrollPane.setVisible(false); + detailsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right")); + }else{ + scrollPane.setVisible(true); + detailsLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down")); + } + } + }; + + private MouseListener restartButtonClickListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + RestartHelper.restartForUpdate(DesignerContext.getDesignerFrame()); + } + }; +} diff --git a/designer-base/src/main/java/com/fr/env/VersionCheckMessageDialog.java b/designer-base/src/main/java/com/fr/env/VersionCheckMessageDialog.java new file mode 100644 index 000000000..5fd4c9ec0 --- /dev/null +++ b/designer-base/src/main/java/com/fr/env/VersionCheckMessageDialog.java @@ -0,0 +1,105 @@ +package com.fr.env; + +import com.fr.design.versioncheck.VersionCheckUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralContext; +import com.fr.general.GeneralUtils; +import com.fr.general.IOUtils; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; + +/** + * @author pengda + * @version 10.0 + * Created on 2021-06-02 + */ +public class VersionCheckMessageDialog extends JDialog implements ActionListener { + private UILabel imageLabel; + private UILabel detailLabel; + private JPanel centerPanel; + private JPanel detailPanel; + private JPanel body; + private String envName; + + public VersionCheckMessageDialog(Frame parent, String message, String envName) { + super(parent, true); + this.envName = envName; + init(message); + } + + private void init(String message) { + JPanel imagePanel = new JPanel(); + imageLabel = new UILabel(IOUtils.readIcon("com/fr/design/images/warnings/warning32.png")); + imagePanel.add(imageLabel); + JPanel messagePanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); + UILabel messageText = new UILabel(); + messageText.setText("" + message + ""); + messagePanel.add(messageText); + + centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + centerPanel.setBorder(BorderFactory.createEmptyBorder(15, 10, 10, 10)); + centerPanel.add(imagePanel, BorderLayout.WEST); + centerPanel.add(messagePanel, BorderLayout.CENTER); + + detailLabel = new UILabel(); + detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail")); + detailLabel.setForeground(Color.BLUE); + + detailPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + detailPanel.add(detailLabel, BorderLayout.EAST); + + String localBranch = GeneralUtils.readFullBuildNO(); + String remoteBranch = VersionCheckUtils.getRemoteBranch(envName); + List noExistServiceDescription; + if(ComparatorUtils.equals(localBranch,remoteBranch)) { + noExistServiceDescription = new ArrayList<>(); + }else{ + noExistServiceDescription = VersionCheckUtils.getNoExistServiceDescription(this.envName); + } + + detailPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + hideDialog(); + CheckServiceDialog checkServiceDialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), localBranch, remoteBranch, noExistServiceDescription); + checkServiceDialog.setVisible(true); + } + }); + + body = FRGUIPaneFactory.createBorderLayout_S_Pane(); + body.add(centerPanel, BorderLayout.CENTER); + body.add(detailPanel, BorderLayout.SOUTH); + + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Sync_Prompt")); + this.setResizable(false); + this.add(body, BorderLayout.NORTH); + this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 300 : 280, 135)); + GUICoreUtils.centerWindow(this); + } + + private void hideDialog(){ + this.dispose(); + } + + @Override + public void actionPerformed(ActionEvent e) { + hideDialog(); + } +} diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties index 4ebb3e1ed..c00c5eb62 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties @@ -1,4 +1,4 @@ com.fr.design.mainframe.check.CheckButton=230*118 com.fr.design.mainframe.check.CheckFontInfoDialog.collapse=490*185 -com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=490*31 +com.fr.design.mainframe.check.CheckFontInfoDialog.messageWithLink=490*35 com.fr.design.mainframe.check.CheckFontInfoDialog.unfold=490*280 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/arrowright.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/arrowright.png new file mode 100644 index 000000000..faa3f898d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/arrowright.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/bigfail.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/bigfail.png new file mode 100644 index 000000000..0f09b2cba Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/bigfail.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/fail.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/fail.png new file mode 100644 index 000000000..611cab720 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/fail.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/question.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/question.png new file mode 100644 index 000000000..cf46cd468 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/question.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/success.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/success.png new file mode 100644 index 000000000..f88e68ece Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/success.png differ diff --git a/designer-base/src/main/resources/com/fr/design/icon/versioncheck/warning.png b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/warning.png new file mode 100644 index 000000000..4d2a189b6 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/icon/versioncheck/warning.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/circularErrorIcon.png b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/circularErrorIcon.png new file mode 100644 index 000000000..bcd2b0611 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/circularErrorIcon.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/circularWarningIcon.png b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/circularWarningIcon.png new file mode 100644 index 000000000..69fc1527d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/circularWarningIcon.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/lookandfeel/newMessageIcon.png b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/newMessageIcon.png new file mode 100644 index 000000000..5ee181668 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/lookandfeel/newMessageIcon.png differ diff --git a/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java b/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java index 07a1d54f8..090838fd0 100644 --- a/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java +++ b/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java @@ -60,7 +60,7 @@ public class EnvChangeEntranceTest { EasyMock.replay(request, selectedEnv, connectionInfo); PowerMock.replayAll(); - entrance.showServiceDialog(selectedEnv); + //entrance.showServiceDialog(selectedEnv); }catch (Exception e){ Assert.fail(); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartHtmlLabelPaneWithBackGroundLabel.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartHtmlLabelPaneWithBackGroundLabel.java index f9c9f7d49..4e29e3c82 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartHtmlLabelPaneWithBackGroundLabel.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartHtmlLabelPaneWithBackGroundLabel.java @@ -22,6 +22,6 @@ public class VanChartHtmlLabelPaneWithBackGroundLabel extends VanChartHtmlLabelP new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Background")), panel}, }; - return TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{d, f}); + return TableLayoutHelper.createTableLayoutPane(components, new double[]{p, p}, new double[]{d, f}); } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/other/condition/item/VanChartLabelConditionPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/other/condition/item/VanChartLabelConditionPane.java index 115bdb948..87d89e8f0 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/other/condition/item/VanChartLabelConditionPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/other/condition/item/VanChartLabelConditionPane.java @@ -3,11 +3,14 @@ package com.fr.van.chart.designer.other.condition.item; import com.fr.chart.base.DataSeriesCondition; import com.fr.chart.chartattr.Plot; import com.fr.design.condition.ConditionAttributesPane; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; import com.fr.plugin.chart.base.AttrLabel; import com.fr.van.chart.designer.PlotFactory; import com.fr.van.chart.designer.style.label.VanChartPlotLabelPane; import javax.swing.JPanel; +import java.awt.Component; public class VanChartLabelConditionPane extends AbstractNormalMultiLineConditionPane { @@ -22,7 +25,15 @@ public class VanChartLabelConditionPane extends AbstractNormalMultiLineCondition @Override protected JPanel initContentPane() { dataLabelContentsPane = createLabelPane(); - return dataLabelContentsPane; + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double e = 220; + + Component[][] components = new Component[][]{ + new Component[]{null, dataLabelContentsPane} + }; + + return TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{f, e}); } protected VanChartPlotLabelPane createLabelPane() { diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java index 10e672f58..0f75896e1 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java @@ -32,6 +32,8 @@ abstract class ModelUtil { //直接遍历出来目标值,然后按需处理 xCreator.traversalNameRelatedXCreators(nameRelatedCreators); Map renameMap = new HashMap<>(); + // 避免与旧名称重复 + initDuplicated(nameRelatedCreators, duplicated); for (XCreator target : nameRelatedCreators) { String uniqueName = uniqueName(form, target, duplicated); String oldName = target.toData().getWidgetName(); @@ -42,6 +44,12 @@ abstract class ModelUtil { } EventDispatcher.fire(WidgetNameModifyEvent.INSTANCE, new ContentChangeItem(renameMap, xCreator.toData(), ChangeItem.WIDGET_NAME)); } + + private static void initDuplicated(Set nameRelatedCreators, Set duplicated) { + for (XCreator xCreator : nameRelatedCreators) { + duplicated.add(xCreator.toData().getWidgetName()); + } + } private static String uniqueName(Form form, XCreator xCreator, Set duplicated) { diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index 3cd33d6c3..01d53f850 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -5,11 +5,13 @@ package com.fr.design.designer.creator; import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.UpdateAction; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.events.DesignerEditor; import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.fun.ShareWidgetUIProcessor; import com.fr.design.fun.WidgetPropertyUIProvider; import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.layout.FRGUIPaneFactory; @@ -298,6 +300,10 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo @Override public JComponent createToolPane(BaseJForm jform, FormDesigner formEditor) { if (!DesignerMode.isAuthorityEditing()) { + ShareWidgetUIProcessor exportProcessor = ExtraDesignClassManager.getInstance().getSingle(ShareWidgetUIProcessor.MARK_STRING); + if (exportProcessor != null) { + return exportProcessor.createToolPane(this, jform, formEditor); + } if (isDedicateContainer() && this.getComponentCount() > 0) { // 图表块和报表块由于控件树处不显示,但对应的属性表要显示,此处处理下 XCreator child = ((XLayoutContainer) this).getXCreator(0); @@ -789,7 +795,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo public boolean isTopable() { return true; } - + } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java index 7401b5ede..bfa841a4a 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWTitleLayout.java @@ -112,6 +112,21 @@ public class XWTitleLayout extends DedicateLayoutContainer { return null; } + + /** + * 返回body组件 + * @return body组件 + */ + public XCreator getBodyCreator() { + for (int i=0; i < getXCreatorCount(); i++) { + XCreator creator = getXCreator(i); + if (creator.hasTitleStyle()) { + return creator; + } + } + return null; + } + /** * 编辑状态的时候需要重新绘制下边框 * @@ -196,4 +211,4 @@ public class XWTitleLayout extends DedicateLayoutContainer { super.setShareId(shareId); this.getEditingChildCreator().setShareId(shareId); } -} \ No newline at end of file +} diff --git a/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java b/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java index f310adc42..e3b9b8175 100644 --- a/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java +++ b/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java @@ -1,13 +1,11 @@ package com.fr.design.designer.treeview; import com.fr.base.BaseUtils; -import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.design.constants.UIConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.form.ui.AbstractBorderStyleWidget; +import com.fr.design.mainframe.share.util.ShareComponentUtils; import com.fr.log.FineLoggerFactory; -import com.fr.stable.StringUtils; import javax.swing.BorderFactory; import javax.swing.Icon; @@ -38,7 +36,7 @@ public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { } if (icon != null) { setIcon(icon); - this.needAddShareIcon = isShareWidget((XCreator) value); + this.needAddShareIcon = ShareComponentUtils.isShareWidgetWithChild((XCreator) value); } } @@ -47,14 +45,6 @@ public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { return this; } - private boolean isShareWidget(XCreator xCreator) { - if (!xCreator.toData().acceptType(AbstractBorderStyleWidget.class)) { - return false; - } - ExtendSharableAttrMark attrMark = ((AbstractBorderStyleWidget) xCreator.toData()).getWidgetAttrMark(ExtendSharableAttrMark.XML_TAG); - return attrMark != null && StringUtils.isNotEmpty(attrMark.getShareId()); - - } public void paint(Graphics g) { super.paint(g); diff --git a/designer-form/src/main/java/com/fr/design/fun/ShareWidgetUIProcessor.java b/designer-form/src/main/java/com/fr/design/fun/ShareWidgetUIProcessor.java new file mode 100644 index 000000000..510b2cddd --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/fun/ShareWidgetUIProcessor.java @@ -0,0 +1,29 @@ +package com.fr.design.fun; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.BaseJForm; +import com.fr.design.mainframe.FormDesigner; +import com.fr.stable.fun.mark.Immutable; + +import javax.swing.JComponent; + + +/** + * Created by kerry on 5/28/21 + */ +public interface ShareWidgetUIProcessor extends Immutable { + + String MARK_STRING = "ShareWidgetUIProcessor"; + + int CURRENT_LEVEL = 1; + + /** + * 生成属性配置界面 + * + * @param xCreator 选中的Xcreator + * @param formDesigner 表单设计器 + * @return 属性配置界面 + */ + JComponent createToolPane(XCreator xCreator, BaseJForm jform, FormDesigner formDesigner); + +} diff --git a/designer-form/src/main/java/com/fr/design/fun/impl/AbstractShareWidgetUIProcessor.java b/designer-form/src/main/java/com/fr/design/fun/impl/AbstractShareWidgetUIProcessor.java new file mode 100644 index 000000000..e0eddd09d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/fun/impl/AbstractShareWidgetUIProcessor.java @@ -0,0 +1,19 @@ +package com.fr.design.fun.impl; + +import com.fr.design.fun.ShareWidgetUIProcessor; +import com.fr.stable.fun.mark.API; + +/** + * Created by kerry on 5/28/21 + */ +@API(level = ShareWidgetUIProcessor.CURRENT_LEVEL) +public abstract class AbstractShareWidgetUIProcessor implements ShareWidgetUIProcessor { + + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index 170704aa6..8fbc4d06d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -4,6 +4,7 @@ import com.fr.base.BaseUtils; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo; import com.fr.design.mainframe.share.collect.ComponentCollector; import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; @@ -89,7 +90,7 @@ public class FormWidgetDetailPane extends FormDockView{ cardLayout.show(centerPane, paneList.get(newSelectedIndex).getTitle()); } }; - headGroup.setSelectedIndex(ONLINE_TAB); + headGroup.setSelectedIndex(ComponentReuseNotificationInfo.getInstance().isClickedWidgetLib() ? 0 : ONLINE_TAB); this.add(headGroup, BorderLayout.NORTH); this.add(centerPane, BorderLayout.CENTER); } @@ -105,12 +106,11 @@ public class FormWidgetDetailPane extends FormDockView{ } - public void enterWidgetLib() { + public void enterWidgetLib() { EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); ComponentReuseNotifyUtil.enterWidgetLibExtraAction(false); } - /** * 定位 * diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/SharableXMLUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/SharableXMLUtils.java deleted file mode 100644 index baacf4272..000000000 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/SharableXMLUtils.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.fr.design.mainframe.share.util; - -import com.fr.form.share.encrypt.engine.SharableReadHelper; -import com.fr.stable.xml.XMLConf; -import com.fr.stable.xml.helper.XMLReadHelper; - -public class SharableXMLUtils { - public static synchronized void registerSharableReadHelper() { - XMLReadHelper readHelper = XMLConf.getReadHelper(); - XMLReadHelper helper = new SharableReadHelper(readHelper); - XMLConf.registerXMLHelper(helper); - } -} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java index 485c44149..80162a406 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java @@ -5,6 +5,7 @@ import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWTitleLayout; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.FormSelection; @@ -91,6 +92,19 @@ public class ShareComponentUtils { return false; } + public static boolean isShareWidgetWithChild(XCreator xCreator) { + boolean result = isShareWidget(xCreator); + if (result) { + return true; + } + //做下兼容处理,老的组件结构的共享信息存储在子组件上 + if (xCreator instanceof XWTitleLayout) { + XCreator child = ((XWTitleLayout) xCreator).getBodyCreator(); + return isShareWidget(child); + } + return false; + } + public static List getHelpConfigXCreatorList(XCreator root) { List helpConfigXCreatorList = new ArrayList<>(); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/CellWidgetPropertyPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/CellWidgetPropertyPane.java index 246bb72aa..0ddfdd3d7 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/CellWidgetPropertyPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/CellWidgetPropertyPane.java @@ -106,6 +106,9 @@ public class CellWidgetPropertyPane extends BasicPane { final CellSelection finalCS = (CellSelection) ePane.getSelection(); final TemplateElementCase tplEC = ePane.getEditingElementCase(); final Widget cellWidget = cellEditorDefPane.update(); + if(cellWidget == null){ + return; + } if (finalCS.isSelectedOneCell(ePane)) { if (tplEC.getTemplateCellElement(cellElement.getColumn(), cellElement.getRow()) == null) {//cellElement未加入到report中时要添加进去 tplEC.addCellElement(cellElement); @@ -141,6 +144,9 @@ public class CellWidgetPropertyPane extends BasicPane { final CellSelection finalCS = (CellSelection) selection; final TemplateElementCase tplEC = ePane.getEditingElementCase(); final Widget cellWidget = cellEditorDefPane.update(); + if(cellWidget == null){ + return; + } if(finalCS.isSelectedOneCell(ePane)){ if(tplEC.getTemplateCellElement(cellElement.getColumn(), cellElement.getRow())== null){//cellElement未加入到report中时要添加进去 tplEC.addCellElement(cellElement); diff --git a/designer-realize/src/main/java/com/fr/design/share/SharableManager.java b/designer-realize/src/main/java/com/fr/design/share/SharableManager.java index ba3b83064..05f893fad 100644 --- a/designer-realize/src/main/java/com/fr/design/share/SharableManager.java +++ b/designer-realize/src/main/java/com/fr/design/share/SharableManager.java @@ -9,7 +9,6 @@ import com.fr.design.mainframe.share.collect.ComponentCollector; import com.fr.design.mainframe.share.collect.SharableCollectorManager; import com.fr.design.mainframe.share.encrypt.clipboard.impl.EncryptSelectionClipboardHandler; import com.fr.design.mainframe.share.encrypt.clipboard.impl.EncryptTransferableClipboardHandler; -import com.fr.design.mainframe.share.util.SharableXMLUtils; import com.fr.design.mainframe.share.util.ShareComponentUtils; import com.fr.design.share.utils.EffectItemUtils; import com.fr.json.JSONArray; @@ -18,7 +17,6 @@ import java.util.List; public class SharableManager { public static void start() { - SharableXMLUtils.registerSharableReadHelper(); SharableCollectorManager.getInstance().execute(); ClipboardFilter.registerClipboardHandler(EncryptSelectionClipboardHandler.getInstance()); ClipboardFilter.registerClipboardHandler(EncryptTransferableClipboardHandler.getInstance()); diff --git a/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java index a07478c9d..c04932d0d 100644 --- a/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java +++ b/designer-realize/src/main/java/com/fr/design/share/effect/EffectItemGroup.java @@ -111,8 +111,11 @@ public class EffectItemGroup { ChartCollection chartCollection = (ChartCollection) value; for (int index = 0; index < chartCollection.getChartCount(); index++) { Chart chart= (Chart) chartCollection.getChart(index, ChartProvider.class); - SourceNode chartSourceNode = SourceNodeUtils.createSourceNode(chart.getPlot(), chartCollection.getChartName(index), cellSourceNode); Plot plot = chart.getPlot(); + if (plot == null) { + continue; + } + SourceNode chartSourceNode = SourceNodeUtils.createSourceNode(plot, chartCollection.getChartName(index), cellSourceNode); initChartPlot(plot, chartSourceNode, false); } @@ -126,8 +129,11 @@ public class EffectItemGroup { ChartCollection chartCollection = (ChartCollection) editor.getChartCollection(); for (int index = 0; index < chartCollection.getChartCount(); index++) { Chart chart= (Chart) chartCollection.getChart(index, ChartProvider.class); - SourceNode plotSourceNode = SourceNodeUtils.createSourceNode(chart.getPlot(), chartCollection.getChartName(index), null); Plot plot = chart.getPlot(); + if (plot == null) { + continue; + } + SourceNode plotSourceNode = SourceNodeUtils.createSourceNode(plot, chartCollection.getChartName(index), null); initChartPlot(plot, plotSourceNode, false); } diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java index 4fef5f51a..0eeda7731 100644 --- a/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/EffectContent.java @@ -56,8 +56,8 @@ public class EffectContent extends JPanel { Object[] columnNames = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_From"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Rename")}; JTable table = new JTable(new EffectTableModel(effectItemGroup, columnNames)); table.setRowHeight(25); - table.getColumnModel().getColumn(0).setPreferredWidth(235); - table.getColumnModel().getColumn(1).setPreferredWidth(325); + table.getColumnModel().getColumn(0).setPreferredWidth(230); + table.getColumnModel().getColumn(1).setPreferredWidth(320); table.setDefaultEditor(EffectTableModel.class, new EffectItemEditor(table)); diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java index 82eb60f08..93f07b260 100644 --- a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareGeneratePane.java @@ -1,5 +1,6 @@ package com.fr.design.share.ui.generate; +import com.fr.design.designer.creator.XCreator; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; @@ -11,11 +12,14 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.design.mainframe.share.Bean.ComponentGenerateInfo; import com.fr.design.mainframe.share.action.ShareUIAspect; import com.fr.design.mainframe.share.collect.ComponentCollector; import com.fr.design.mainframe.share.exception.LackOfValueException; import com.fr.design.mainframe.share.generate.ComponentGeneratorCenter; +import com.fr.design.mainframe.share.select.ComponentTransformerFactory; +import com.fr.design.mod.ContentObjectManager; import com.fr.form.share.exception.NetWorkFailedException; import com.fr.form.share.group.DefaultShareGroup; import com.fr.design.mainframe.share.util.ShareUIUtils; @@ -31,6 +35,8 @@ import com.fr.form.ui.Widget; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; +import java.util.HashSet; +import java.util.Set; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.SwingWorker; @@ -56,7 +62,7 @@ import static javax.swing.JOptionPane.ERROR_MESSAGE; **/ public class ShareGeneratePane extends BasicPane { - private static final Dimension DIALOG_SIZE = new Dimension(670, 740); + private static final Dimension DIALOG_SIZE = new Dimension(670, 760); private static final Dimension DIALOG_NORMAL_SIZE = new Dimension(670, 610); private static final Border DIALOG_BORDER = BorderFactory.createEmptyBorder(0, 6, 4, 6); @@ -100,8 +106,9 @@ public class ShareGeneratePane extends BasicPane { JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); this.mainPane = FRGUIPaneFactory.createCardLayout_S_Pane(); - this.simplePane = new ShareMainPane(shareCover, rec, false, effectItemGroups); - this.uploadPane = new ShareMainPane(shareCover, rec, true, effectItemGroups); + boolean needContentTip = needContentTip(); + this.simplePane = new ShareMainPane(shareCover, rec, false, effectItemGroups, needContentTip); + this.uploadPane = new ShareMainPane(shareCover, rec, true, effectItemGroups, needContentTip); //暂时换一下,目前不用上传 this.mainPane.add(simplePane, ShareUIUtils.convertStateChange(ItemEvent.DESELECTED)); this.mainPane.add(uploadPane, ShareUIUtils.convertStateChange(ItemEvent.SELECTED)); @@ -161,6 +168,21 @@ public class ShareGeneratePane extends BasicPane { } } + + private boolean needContentTip() { + long start = System.currentTimeMillis(); + XCreator xCreator = ComponentTransformerFactory.getInstance().transform(WidgetPropertyPane.getInstance().getEditingFormDesigner().getSelectionModel().getSelection()).getMiddle(); + Set xCreators = new HashSet<>(); + xCreator.traversalNameRelatedXCreators(xCreators); + Set nameSet = new HashSet<>(); + for (XCreator creator : xCreators) { + nameSet.add(creator.toData().getWidgetName()); + } + boolean result = ContentObjectManager.getInstance().needContentTip(shareWidget, nameSet); + FineLoggerFactory.getLogger().debug("needContentTip spend {} ms", (System.currentTimeMillis() - start)); + return result; + } + private JPanel createUploadCheckBox() { JPanel panel = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java index df1d2c04b..a4fc73fbe 100644 --- a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java @@ -131,13 +131,15 @@ public class ShareMainPane extends JPanel { private boolean upload; private List effectItemGroups; + private final boolean needContentTip; - public ShareMainPane(Image shareCover, Rectangle rec, boolean upload, List effectItemGroups) { + public ShareMainPane(Image shareCover, Rectangle rec, boolean upload, List effectItemGroups, boolean needContentTip) { this.shareCover = shareCover; this.rec = rec; this.upload = upload; this.effectItemGroups = effectItemGroups; + this.needContentTip = needContentTip; initCover(shareCover); this.setLayout(FRGUIPaneFactory.createBorderLayout()); @@ -174,7 +176,14 @@ public class ShareMainPane extends JPanel { private JPanel createOverviewPane(boolean upload) { JPanel componentPane = createComponentOverviewPane(upload); String title = Toolkit.i18nText("Fine-Design_Share_Overview"); - JPanel overviewPane = FRGUIPaneFactory.createTitledBorderPane(title); + JPanel overviewPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(title); + if (needContentTip) { + UILabel tipsLabel = ShareUIUtils.createTipsLabel(Toolkit.i18nText("Fine-Design_Share_Generate_Content_Tip")); + tipsLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + JPanel panel = new JPanel(FRGUIPaneFactory.createBorderLayout()); + panel.add(tipsLabel); + overviewPane.add(panel, BorderLayout.NORTH); + } overviewPane.add(componentPane, BorderLayout.CENTER); return overviewPane; diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java index 0a572e672..220a4e39e 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java @@ -9,6 +9,7 @@ import com.fr.design.env.DesignerWorkspaceGenerator; import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.design.env.LocalDesignerWorkspaceInfo; import com.fr.design.i18n.Toolkit; +import com.fr.design.versioncheck.VersionCheckUtils; import com.fr.env.TestConnectionResult; import com.fr.event.Event; import com.fr.event.EventDispatcher; @@ -69,7 +70,7 @@ public class DesignerWorkspaceProvider extends Activator { @Override public void on(Event event, Null aNull) { try { - EnvChangeEntrance.getInstance().showServiceDialog(selectEnv); + VersionCheckUtils.showVersionCheckDialog(selectEnv.getName()); } catch (Exception e) { FineLoggerFactory.getLogger().warn("Check Service Failed"); }