diff --git a/designer-base/src/main/java/com/fr/base/function/UITerminator.java b/designer-base/src/main/java/com/fr/base/function/UITerminator.java new file mode 100644 index 0000000000..1f1424936b --- /dev/null +++ b/designer-base/src/main/java/com/fr/base/function/UITerminator.java @@ -0,0 +1,24 @@ +package com.fr.base.function; + +import com.fr.design.utils.DesignUtils; +import com.fr.runtime.FineRuntime; + +/** + * UI 终止动作 + * + * created by Harrison on 2022/07/14 + **/ +public abstract class UITerminator { + + public void run() { + + // 先执行必须的逻辑 + FineRuntime.start(); + DesignUtils.initLookAndFeel(); + + // 在执行核心逻辑 + doRun(); + } + + protected abstract void doRun(); +} diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index 8301a0ca32..823a551ffe 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -55,6 +55,7 @@ import com.fr.stable.xml.XMLReadable; import com.fr.stable.xml.XMLTools; import com.fr.stable.xml.XMLWriter; import com.fr.stable.xml.XMLableReader; +import com.fr.start.common.DesignerStartupConfig; import com.fr.third.apache.logging.log4j.core.appender.FileAppender; import com.fr.third.apache.logging.log4j.core.layout.PatternLayout; import com.fr.third.org.apache.commons.io.FilenameUtils; @@ -188,7 +189,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private DesignerPushUpdateConfigManager designerPushUpdateConfigManager = DesignerPushUpdateConfigManager.getInstance(); private VcsConfigManager vcsConfigManager = VcsConfigManager.getInstance(); - + + private DesignerStartupConfig designerStartupConfig = DesignerStartupConfig.getInstance(); + public static final String CAS_CERTIFICATE_PATH = "certificatePath"; public static final String CAS_CERTIFICATE_PASSWORD = "certificatePass"; @@ -1000,6 +1003,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { public void setLanguage(Locale locale) { this.language = locale; } + + public boolean isStartupPageEnabled() { + return this.designerStartupConfig.isEnabled(); + } + + public void setStartupPageEnabled(boolean enabled) { + this.designerStartupConfig.setEnabled(enabled); + } /** * 返回环境名称迭代器 @@ -1119,23 +1130,26 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { public void setCurrentDirectoryPrefix(String prefix) { this.CurrentDirectoryPrefix = prefix; } - - - /** - * 返回最近打开的文件路径列表 - */ - public List getRecentOpenedFilePathList() { - - if (StringUtils.isEmpty(getCurEnvName())) { + + public List getRecentOpenedFilePathList4Env(String envName) { + + if (StringUtils.isEmpty(envName)) { return tempRecentOpenedFilePathList; } else { - if (!recentOpenedFileListMap.containsKey(getCurEnvName())) { - recentOpenedFileListMap.put(getCurEnvName(), tempRecentOpenedFilePathList); + if (!recentOpenedFileListMap.containsKey(envName)) { + recentOpenedFileListMap.put(envName, tempRecentOpenedFilePathList); } } + + return recentOpenedFileListMap.get(envName); + } - - return recentOpenedFileListMap.get(getCurEnvName()); + /** + * 返回最近打开的文件路径列表 + */ + public List getRecentOpenedFilePathList() { + + return this.getRecentOpenedFilePathList4Env(getCurEnvName()); } /** @@ -1829,6 +1843,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { readHttpsParas(reader); } else if (name.equals(EnvDetectorConfig.XML_TAG)) { readEnvDetectorConfig(reader); + } else if (name.equals(DesignerStartupConfig.XML_TAG)) { + readStartupConfig(reader); } else if (name.equals("AlphaFineConfigManager")) { readAlphaFineAttr(reader); } else if (name.equals("RecentColors")) { @@ -1869,6 +1885,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private void readEnvDetectorConfig(XMLableReader reader) { reader.readXMLObject(this.envDetectorConfig); } + + private void readStartupConfig(XMLableReader reader) { + reader.readXMLObject(this.designerStartupConfig); + } private void readHttpsParas(XMLableReader reader) { String tempVal; @@ -2084,6 +2104,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { writeHttpsParas(writer); writeAlphaFineAttr(writer); writeEnvDetectorConfig(writer); + writeStartupConfig(writer); writeRecentColor(writer); writeOpenDebug(writer); writeDesignerPushUpdateAttr(writer); @@ -2133,6 +2154,12 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { this.envDetectorConfig.writeXML(writer); } } + + private void writeStartupConfig(XMLPrintWriter writer) { + if (this.designerStartupConfig != null) { + this.designerStartupConfig.writeXML(writer); + } + } //写入uuid private void writeUUID(XMLPrintWriter writer) { 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 6cb50776c5..661d5f05ed 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -1,7 +1,7 @@ package com.fr.design; import com.fr.common.report.ReportState; -import com.fr.decision.webservice.v10.plugin.helper.PluginErrorRemindHandler; +import com.fr.design.plugin.remind.PluginErrorDesignReminder; import com.fr.design.data.DesignTableDataManager; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; @@ -35,7 +35,6 @@ import com.fr.process.engine.core.FineProcessContext; import com.fr.rpc.Result; import com.fr.stable.AssistUtils; import com.fr.stable.StringUtils; -import com.fr.env.PluginErrorRemindDialog; import com.fr.start.server.ServerTray; import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContextCallback; @@ -139,7 +138,7 @@ public class EnvChangeEntrance { if (template != null) { template.refreshToolArea(); } - pluginErrorRemind(); + PluginErrorDesignReminder.getInstance().remindStartFailedPlugins(); } catch (Exception exception) { // 失败的处理 WorkspaceExceptionHandler.getInstance().handleInSwitch(exception, selectedEnv); @@ -245,28 +244,6 @@ public class EnvChangeEntrance { } } - /** - * 插件启动错误信息提示 - */ - public void pluginErrorRemind() { - if (!WorkContext.getCurrent().isLocal()) { - return; - } - - String content = PluginErrorRemindHandler.pluginErrorContent(); - if (StringUtils.isNotEmpty(content)) { - // 该操作需要在当前awt操作之后执行,使用SwingUtilities.invokeLater将其置于awt操作对列末尾 - // 若使用UIUtil.invokeLaterIfNeeded,会立即执行,影响其他UI操作 - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - PluginErrorRemindDialog dialog = new PluginErrorRemindDialog(DesignerContext.getDesignerFrame(), content); - dialog.setVisible(true); - } - }); - } - } - /** * 判断是否需要做版本验证,判断依据为 * 1、选择的环境为远程环境 diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java index 08273202d1..a41f6cb56d 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferenceAction.java @@ -40,7 +40,9 @@ public class PreferenceAction extends UpdateAction { DesignerEnvManager.loadLogSetting(); DesignerEnvManager.getEnvManager().saveXMLFile(); JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - jt.refreshToolArea(); + if (jt != null) { + jt.refreshToolArea(); + } preferencePane.showRestartDialog(); DesignerFrameFileDealerPane.getInstance().refreshDockingView(); } diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java index 9f15abee71..51b0ed2a7a 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java @@ -14,9 +14,11 @@ import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIColorButton; import com.fr.design.gui.ibutton.UINoThemeColorButton; +import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIDictionaryComboBox; +import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ifilechooser.FileChooserArgs; import com.fr.design.gui.ifilechooser.FileChooserFactory; import com.fr.design.gui.ifilechooser.FileChooserProvider; @@ -26,6 +28,7 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.iprogressbar.UIProgressBarUI; import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; import com.fr.design.jdk.JdkVersion; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; @@ -42,8 +45,10 @@ import com.fr.general.FRFont; import com.fr.general.IOUtils; import com.fr.general.Inter; import com.fr.general.log.Log4jConfig; +import com.fr.io.attr.ImageExportAttr; import com.fr.locale.InterProviderFactory; import com.fr.log.FineLoggerFactory; +import com.fr.report.ReportConfigManager; import com.fr.stable.Constants; import com.fr.stable.os.OperatingSystem; import com.fr.third.apache.logging.log4j.Level; @@ -52,19 +57,24 @@ import com.fr.transaction.Worker; import com.fr.workspace.WorkContext; import com.fr.workspace.server.vcs.VcsOperator; import com.fr.workspace.server.vcs.git.config.GcConfig; +import org.jetbrains.annotations.NotNull; import javax.swing.BorderFactory; import javax.swing.BoxLayout; +import javax.swing.ButtonGroup; +import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.KeyStroke; +import javax.swing.ScrollPaneConstants; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import javax.swing.Timer; import javax.swing.UIManager; +import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; @@ -177,6 +187,7 @@ public class PreferencePane extends BasicPane { private UICheckBox vcsEnableCheckBox; private UICheckBox saveCommitCheckBox; private UICheckBox useIntervalCheckBox; + private UICheckBox startupPageEnabledCheckBox; private IntegerEditor saveIntervalEditor; private UICheckBox gcEnableCheckBox; private UIButton gcButton; @@ -189,6 +200,14 @@ public class PreferencePane extends BasicPane { private JProgressBar gcProgressBar; private Timer gcProgressTimer; private UIButton gcOkButton = new UIButton(i18nText("Fine-Design_Report_OK")); + + private UIRadioButton previewResolutionBtnS; + private UIRadioButton previewResolutionBtnM; + + private UIRadioButton previewRenderSpeed; + private UIRadioButton previewRenderQuality; + private static final int DPI_SCALE_S = 1; + private static final int DPI_SCALE_M = 2; public PreferencePane() { this.initComponents(); @@ -201,9 +220,13 @@ public class PreferencePane extends BasicPane { UITabbedPane jtabPane = new UITabbedPane(); JPanel generalPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); - jtabPane.addTab(i18nText("Fine-Design_Basic_General"), generalPane); + UIScrollPane generalScrollPane = patchScroll(generalPane); + jtabPane.addTab(i18nText("Fine-Design_Basic_General"), generalScrollPane); + JPanel advancePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); - jtabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), advancePane); + UIScrollPane adviceScrollPane = patchScroll(advancePane); + jtabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), adviceScrollPane); + contentPane.add(jtabPane, BorderLayout.NORTH); createFunctionPane(generalPane); @@ -219,6 +242,8 @@ public class PreferencePane extends BasicPane { createLanPane(generalPane); + // 先屏蔽下 + // createStartupPagePane(generalPane); createLengthPane(advancePane); createServerPane(advancePane); @@ -274,6 +299,7 @@ public class PreferencePane extends BasicPane { JPanel imageCompressPanel = FRGUIPaneFactory.createVerticalTitledBorderPane(i18nText("Fine-Design_Template_Preview_Performance")); imageCompressPanelCheckBox = new UICheckBox(i18nText("Fine-Design_Image_Compress")); imageCompressPanel.add(imageCompressPanelCheckBox); + imageCompressPanel.add(createImageExportSettingPane()); advancePane.add(imageCompressPanel); JPanel designerStartupOption = FRGUIPaneFactory.createTitledBorderPane(i18nText("Fine-Design_Startup_Option")); @@ -281,7 +307,43 @@ public class PreferencePane extends BasicPane { designerStartupOption.add(cloudAnalyticsDelayCheckBox); advancePane.add(designerStartupOption); } + + private JPanel createImageExportSettingPane() { + previewResolutionBtnS = new UIRadioButton(i18nText("Fine-Design_Image_Export_SD"), true); + previewResolutionBtnM = new UIRadioButton(i18nText("Fine-Design_Image_Export_HD")); + ButtonGroup previewResolutionBtnGroup = new ButtonGroup(); + previewResolutionBtnGroup.add(previewResolutionBtnS); + previewResolutionBtnGroup.add(previewResolutionBtnM); + + previewRenderSpeed = new UIRadioButton(Toolkit.i18nText("Fine-Design_Image_Export_Speed_Priority")); + previewRenderQuality = new UIRadioButton(Toolkit.i18nText("Fine-Design_Image_Export_Quality_First")); + ButtonGroup previewRenderGroup = new ButtonGroup(); + previewRenderGroup.add(previewRenderQuality); + previewRenderGroup.add(previewRenderSpeed); + JPanel imageExportSettingPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JComponent[][] templateComps = { + {new UILabel(Toolkit.i18nText("Fine-Design_Report_Engine_Enlarge_Or_Reduce") + ":"), this.previewResolutionBtnS, this.previewResolutionBtnM}, + {new UILabel(Toolkit.i18nText("Fine-Design_Image_Export_Rendering_Quality") + ":"), this.previewRenderQuality, this.previewRenderSpeed}, + }; + imageExportSettingPane.add( + TableLayoutHelper.createGapTableLayoutPane( + templateComps, + new double[]{TableLayout.FILL, TableLayout.FILL}, + new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL}, + 20, 0), + BorderLayout.CENTER); + imageExportSettingPane.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); + return imageExportSettingPane; + } + @NotNull + private UIScrollPane patchScroll(JPanel generalPane) { + UIScrollPane generalPanelWithScroll = new UIScrollPane(generalPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + generalPanelWithScroll.setBorder(new EmptyBorder(0, 0, 0, 0)); + generalPanelWithScroll.setPreferredSize(new Dimension(generalPane.getWidth(), 600)); + return generalPanelWithScroll; + } + private void createVcsSettingPane(JPanel generalPane) { JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Title")); generalPane.add(vcsPane); @@ -588,6 +650,21 @@ public class PreferencePane extends BasicPane { languageComboBox.setFont(FRFont.getInstance("Dialog", Font.PLAIN, 12));//为了在中文系统中显示韩文 return languageComboBox; } + + private void createStartupPagePane(JPanel generalPane) { + + // ben:选择版本语言; + JPanel startupPagePaneWrapper = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane(); + JPanel startupPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane("启动页配置"); + generalPane.add(startupPagePaneWrapper); + startupPagePaneWrapper.add(startupPane); + + startupPageEnabledCheckBox = new UICheckBox("启动设计器时,自动打开启动页"); + startupPane.add(startupPageEnabledCheckBox); + UILabel descLabel = new UILabel("注意:若在远程环境下直接关闭,再次启动时,启动速度会变慢"); + descLabel.setForeground(new Color(51, 51, 52, (int)Math.round(0.5 * 255))); + startupPane.add(descLabel); + } private String getDisplayShortCut(String shotrCut) { return shotrCut.replace(TYPE, DISPLAY_TYPE).replace(BACK_SLASH, DISPLAY_BACK_SLASH).replace(SLASH, DISPLAY_SLASH) @@ -757,7 +834,27 @@ public class PreferencePane extends BasicPane { this.startWithEmptyFile.setSelected(designerEnvManager.isStartWithEmptyFile()); this.imageCompressPanelCheckBox.setSelected(designerEnvManager.isImageCompress()); + + ImageExportAttr attr = ReportConfigManager.getProviderInstance().getImageExportAttr(); + if (attr.getPreviewRenderQuality() == ImageExportAttr.RENDER_SPEED) { + previewRenderSpeed.setSelected(true); + } else { + previewRenderQuality.setSelected(true); + } + + if (attr.getPreviewResolutionScale() == DPI_SCALE_S) { + previewResolutionBtnS.setSelected(true); + } else { + previewResolutionBtnM.setSelected(true); + } + boolean enabled = WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot(); + previewRenderSpeed.setEnabled(enabled); + previewRenderQuality.setEnabled(enabled); + previewResolutionBtnS.setEnabled(enabled); + previewResolutionBtnM.setEnabled(enabled); + this.cloudAnalyticsDelayCheckBox.setSelected(designerEnvManager.isCloudAnalyticsDelay()); +// this.startupPageEnabledCheckBox.setSelected(designerEnvManager.isStartupPageEnabled()); } private int chooseCase(int sign) { @@ -824,6 +921,7 @@ public class PreferencePane extends BasicPane { vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected()); vcsConfigManager.setSaveCommit(this.saveCommitCheckBox.isSelected()); vcsConfigManager.setUseInterval(this.useIntervalCheckBox.isSelected()); +// designerEnvManager.setStartupPageEnabled(this.startupPageEnabledCheckBox.isSelected()); Configurations.update(new Worker() { @Override public void run() { @@ -883,6 +981,18 @@ public class PreferencePane extends BasicPane { } }); + ImageExportAttr attr = ReportConfigManager.getProviderInstance().getImageExportAttr(); + if (previewRenderSpeed.isSelected()) { + attr.setPreviewRenderQuality(ImageExportAttr.RENDER_SPEED); + } else { + attr.setPreviewRenderQuality(ImageExportAttr.RENDER_QUALITY); + } + if (previewResolutionBtnS.isSelected()) { + attr.setPreviewResolutionScale(DPI_SCALE_S); + } else { + attr.setPreviewResolutionScale(DPI_SCALE_M); + } + } // 如果语言设置改变了,则显示重启对话框 diff --git a/designer-base/src/main/java/com/fr/design/components/loading/LoadingPane.java b/designer-base/src/main/java/com/fr/design/components/loading/LoadingPane.java new file mode 100644 index 0000000000..25b0fe1816 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/components/loading/LoadingPane.java @@ -0,0 +1,148 @@ +package com.fr.design.components.loading; + +import javax.swing.JComponent; +import javax.swing.Timer; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LayoutManager; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/4/12 + */ +public class LoadingPane extends JComponent implements ActionListener { + + private AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f); + private volatile boolean mIsRunning; + private volatile boolean mIsFadingOut; + private Timer mTimer; + private int mAngle; + private int mFadeCount; + private int mFadeLimit = 15; + private int lines = 12; + private int maxAngle = 360; + private int angleAdd = 30; + + public LoadingPane() { + + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + // do nothing + } + }); + + setLayout(getCoverLayout()); + setBackground(null); + setOpaque(false); + } + + protected LayoutManager getCoverLayout() { + return new LayoutManager() { + + @Override + public void removeLayoutComponent(Component comp) { + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + } + + @Override + public void addLayoutComponent(String name, Component comp) { + } + }; + } + + + @Override + public void paint(Graphics g) { + int w = this.getWidth(); + int h = this.getHeight(); + super.paint(g); + if (!mIsRunning) { + return; + } + Graphics2D g2 = (Graphics2D) g.create(); + float fade = (float) mFadeCount / (float) mFadeLimit; + Composite urComposite = g2.getComposite(); + g2.setComposite(composite); + g2.fillRect(0, 0, w, h); + g2.setComposite(urComposite); + int s = Math.min(w, h) / 50; + int cx = w / 2; + int cy = h / 2; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setStroke(new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + g2.setPaint(Color.BLACK); + g2.rotate(Math.PI * mAngle / 180, cx, cy); + for (int i = 0; i < lines; i++) { + float scale = (11.0f - (float) i) / 11.0f; + g2.drawLine(cx + s, cy, cx + s * 2, cy); + g2.rotate(-Math.PI / 6, cx, cy); + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, scale * fade)); + } + g2.dispose(); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (mIsRunning) { + repaint(); + mAngle += angleAdd; + if (mAngle >= maxAngle) { + mAngle = 0; + } + if (mIsFadingOut) { + if (--mFadeCount == 0) { + mIsRunning = false; + mTimer.stop(); + } + } else if (mFadeCount < mFadeLimit) { + mFadeCount++; + } + } + } + + public void start() { + if (mIsRunning) { + return; + } + mIsRunning = true; + mIsFadingOut = false; + mFadeCount = 0; + int fps = 24; + int tick = 1000 / fps; + mTimer = new Timer(tick, this); + mTimer.start(); + } + + public void stop() { + mIsRunning = false; + mIsFadingOut = true; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/components/tooltip/ModernToolTip.java b/designer-base/src/main/java/com/fr/design/components/tooltip/ModernToolTip.java new file mode 100644 index 0000000000..0a01f8bbf2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/components/tooltip/ModernToolTip.java @@ -0,0 +1,107 @@ +package com.fr.design.components.tooltip; + +import com.fr.base.GraphHelper; +import com.fr.design.gui.itooltip.UIToolTip; +import com.fr.log.FineLoggerFactory; + +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JToolTip; +import javax.swing.SwingUtilities; +import javax.swing.plaf.ToolTipUI; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.GeneralPath; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.util.Enumeration; +import java.util.Vector; + +/** + * 现代化的 UIToolTip + * 见 设计文档 + * + * created by Harrison on 2022/07/09 + **/ +public class ModernToolTip extends UIToolTip { + + public ModernToolTip() { + super(); + setUI(new ModernToolTipUI()); + } + + private class ModernToolTipUI extends ToolTipUI { + + private String[] strs; + private Icon icon; + private boolean needPaint; + public void paint(Graphics g, JComponent c) { + if (!needPaint) { + return; + } + FontMetrics metrics = GraphHelper.getFontMetrics(c.getFont()); + Dimension size = c.getSize(); + int width = size.width; + int height = size.height; + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(new Color(51, 51, 52, (int) Math.round(0.7 * 255))); + g2.fillRoundRect(0, 0, width, height, 0, 0); + + g2.setColor(Color.WHITE); + if (strs != null) { + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT); + for (int i = 0; i < strs.length; i++) { + g2.drawString(strs[i], icon.getIconWidth() + 6, (metrics.getHeight()) * (i + 1)); + } + } + } + + @Override + public Dimension getPreferredSize(JComponent c) { + FontMetrics metrics = GraphHelper.getFontMetrics(c.getFont()); + String tipText = ((JToolTip) c).getTipText(); + icon = ((UIToolTip)c).getIcon(); + needPaint = true; + if (tipText == null) { + if(icon.getIconWidth() == -1) { + needPaint = false; + } + tipText = " "; + } + BufferedReader br = new BufferedReader(new StringReader(tipText)); + String line; + int maxWidth = 0; + Vector v = new Vector(); + try { + while ((line = br.readLine()) != null) { + int width = SwingUtilities.computeStringWidth(metrics, line); + maxWidth = (maxWidth < width) ? width : maxWidth; + v.addElement(line); + } + } catch (IOException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + int lines = v.size(); + if (lines < 1) { + strs = null; + lines = 1; + } else { + strs = new String[lines]; + int i = 0; + for (Enumeration e = v.elements(); e.hasMoreElements(); i++) { + strs[i] = e.nextElement(); + } + } + int height = metrics.getHeight() * lines; + return new Dimension(maxWidth + icon.getIconWidth() + 10, Math.max(height, icon.getIconHeight()) + 6); + } + + } +} diff --git a/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java b/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java index 4b532b92d8..4720c8e103 100644 --- a/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java +++ b/designer-base/src/main/java/com/fr/design/constants/DesignerLaunchStatus.java @@ -15,7 +15,12 @@ public enum DesignerLaunchStatus implements Event { * 初始化环境完成 */ WORKSPACE_INIT_COMPLETE, - + + /** + * 设计器模块初始化开始 + */ + DESIGNER_INIT_STARTED, + /** * 设计器模块启动完成 */ diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ESDStrategyConfigPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ESDStrategyConfigPane.java index 39b4ecb00f..f3df21df9c 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ESDStrategyConfigPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ESDStrategyConfigPane.java @@ -133,7 +133,7 @@ public class ESDStrategyConfigPane extends BasicBeanPane { ob = StrategyConfigHelper.createStrategyConfig(true, false, true); } this.strategyConfig = ob; - this.updateInterval.setText(ob.getUpdateInterval() <= 0 ? "0" : String.format("%.0f", ob.getUpdateInterval() / (double) CacheConstants.MILLIS_OF_MINUTE)); + this.updateInterval.setText(ob.getUpdateInterval() <= 0 ? "0" : String.valueOf(ob.getUpdateInterval() / (double) CacheConstants.MILLIS_OF_MINUTE)); this.schemaTime.setText(StringUtils.join(",", ob.getUpdateSchema().toArray(new String[0]))); this.shouldEvolve.setSelected(ob.shouldEvolve()); this.selectBySchema.setSelected(ob.isScheduleBySchema()); @@ -185,7 +185,6 @@ public class ESDStrategyConfigPane extends BasicBeanPane { this.schemaTimeCheckTips.setVisible(true); throw new IllegalArgumentException("[ESD]Update schema time interval is to short."); } - } else { Collections.addAll(schemaTimes, text.split(",")); } @@ -200,8 +199,15 @@ public class ESDStrategyConfigPane extends BasicBeanPane { String interval = this.updateInterval.getText(); if (checkUpdateInterval(interval)) { long intervalMillis = StringUtils.isEmpty(interval) ? 0 : (long) (Double.parseDouble(interval) * CacheConstants.MILLIS_OF_MINUTE); - config.setUpdateInterval(intervalMillis); + if (intervalMillis >= CacheConstants.MILLIS_OF_MINUTE) { + config.setUpdateInterval(intervalMillis); + } else { + this.updateIntervalCheckTips.setText(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Time_Interval_Too_Short")); + this.updateIntervalCheckTips.setVisible(true); + throw new IllegalArgumentException("[ESD]Update schema time interval is to short."); + } } else { + this.updateIntervalCheckTips.setText(InterProviderFactory.getDesignI18nProvider().i18nText("Fine-Design_ESD_Error_Time_Format")); this.updateIntervalCheckTips.setVisible(true); throw new IllegalArgumentException("[ESD]Error update interval format."); } @@ -220,7 +226,7 @@ public class ESDStrategyConfigPane extends BasicBeanPane { private boolean checkUpdateInterval(String intervalValue) { try { - return !StringUtils.isEmpty(intervalValue) && !(Integer.parseInt(intervalValue) <= 0); + return !StringUtils.isEmpty(intervalValue) && !(Double.parseDouble(intervalValue) <= 0); } catch (NumberFormatException e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } @@ -228,6 +234,7 @@ public class ESDStrategyConfigPane extends BasicBeanPane { return false; } + private boolean checkCornTimeInterval (String cronText) { // 判断后两次更新时间间隔,如果小于1分钟就返回false try { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java index 112adff560..a7dbce4df4 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java @@ -13,6 +13,7 @@ import com.fr.design.data.BasicTableDataTreePane; import com.fr.design.data.BasicTableDataUtils; import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.StrategyConfigAttrUtils; +import com.fr.design.data.datapane.auth.TableDataAuthHelper; import com.fr.design.data.datapane.management.clip.TableDataTreeClipboard; import com.fr.design.data.datapane.management.search.pane.TableDataSearchRemindPane; import com.fr.design.data.datapane.management.search.pane.TreeSearchToolbarPane; @@ -22,6 +23,7 @@ import com.fr.design.data.tabledata.StoreProcedureWorkerListener; import com.fr.design.data.tabledata.paste.TableDataFollowingPasteUtils; import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.loading.TableDataLoadingPane; import com.fr.design.data.tabledata.wrapper.AbstractTableDataWrapper; import com.fr.design.data.tabledata.wrapper.TableDataWrapper; import com.fr.design.data.tabledata.wrapper.TemplateTableDataWrapper; @@ -39,7 +41,6 @@ import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; import com.fr.design.i18n.Toolkit; -import com.fr.design.icon.IconPathConstants; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.design.menu.LineSeparator; @@ -87,6 +88,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -485,7 +487,11 @@ public class TableDataTreePane extends BasicTableDataTreePane { doPropertyChange(dg, tdNamePanel, oldName); } }); - dg.setVisible(true); + // 有些数据集(DBTableData)面板的初始化过程中是包含了SwingWorker处理(查询数据连接、查表等)的 + // 如果这里直接setVisible,可能阻塞SwingWorker的done方法,导致面板渲染出现问题 + SwingUtilities.invokeLater(() -> { + dg.setVisible(true); + }); } @Override @@ -1017,8 +1023,46 @@ public class TableDataTreePane extends BasicTableDataTreePane { AbstractTableDataPane tableDataPane = wrapper.creatTableDataPane(); - //下面创建creatTableDataPane后会直接populate,所以populate时不能用后设置的一些参数,比如name - dgEdit(tableDataPane, dsName, false); + if (TableDataAuthHelper.needCheckAuthWhenEdit(wrapper.getTableData())) { + // 先打开一个Loading面板 + TableDataLoadingPane loadingPane = new TableDataLoadingPane(); + BasicDialog loadingDialog = loadingPane.showLargeWindow(SwingUtilities.getWindowAncestor(TableDataTreePane.this), null); + // 查询权限 + new SwingWorker() { + @Override + protected Boolean doInBackground() throws Exception { + // 获取无权限连接名称集合 + Collection noAuthConnections = TableDataAuthHelper.getNoAuthConnections(); + // 获取当前数据集对应的数据连接名称 + String connectionName = TableDataAuthHelper.getConnectionNameByDBTableData((DBTableData) wrapper.getTableData()); + return !noAuthConnections.contains(connectionName); + } + + @Override + protected void done() { + try { + Boolean hasAuth = get(); + if (hasAuth) { + // 有权限时,关闭Loading面板,打开编辑面板 + loadingDialog.setVisible(false); + dgEdit(tableDataPane, dsName, false); + } else { + // 无权限时,给出无权限提示 + loadingPane.switchTo(TableDataLoadingPane.NO_AUTH_PANE_NAME); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error("loading connection error in remote design", e.getMessage()); + // 查询权限失败时,给出报错提示 + loadingPane.switchTo(TableDataLoadingPane.ERROR_NAME); + } + } + }.execute(); + loadingDialog.setVisible(true); + } else { + // 无需检查权限时,直接打开数据库查询编辑面板 + //下面创建creatTableDataPane后会直接populate,所以populate时不能用后设置的一些参数,比如name + dgEdit(tableDataPane, dsName, false); + } } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java b/designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java new file mode 100644 index 0000000000..382e04dd94 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java @@ -0,0 +1,57 @@ +package com.fr.design.data.datapane.auth; + +import com.fr.base.TableData; +import com.fr.data.impl.Connection; +import com.fr.data.impl.DBTableData; +import com.fr.data.impl.NameDatabaseConnection; +import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.connection.DBConnectAuth; + +import java.util.Collection; +import java.util.Collections; + +/** + * 数据连接权限相关的工具类 + * @author Yvan + */ +public class TableDataAuthHelper { + + /** + * 编辑数据集时是否需要检查权限 + * @param tableData + * @return + */ + public static boolean needCheckAuthWhenEdit(TableData tableData) { + // 远程设计下,编辑DBTableData时需要判断权限 + return !WorkContext.getCurrent().isLocal() && tableData instanceof DBTableData; + } + + /** + * 获取无权限数据连接集合 + * 远程下需要调用RPC,为耗时操作,谨慎使用 + * @return + */ + public static Collection getNoAuthConnections() { + // 获取无权限连接集合 + Collection noAuthConnections = WorkContext.getCurrent().get(DBConnectAuth.class).getNoAuthConnections(); + return noAuthConnections == null ? Collections.emptyList() : noAuthConnections; + } + + /** + * 通过数据集获取其数据连接的名称 + * + * 注意: + * 1. Connection接口本身是不提供名称的,只有我们内部为了使用方便,将其包装成了NameDataBaseConnection + * 如果不是NameDataBaseConnection类型,则无名称,因此这里只能用判断类型的方式获取名称 + * 2. 仅支持DBTableData获取连接名 + * @return + */ + public static String getConnectionNameByDBTableData(DBTableData tableData) { + Connection database = tableData.getDatabase(); + if (database instanceof NameDatabaseConnection) { + return ((NameDatabaseConnection) database).getName(); + } + return StringUtils.EMPTY; + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java index 640fb2762a..76f32d6f0c 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java @@ -138,18 +138,34 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { if (connection instanceof NameDatabaseConnection) { this.setSelectedItem(((NameDatabaseConnection) connection).getName()); } else { - String s = DesignerEnvManager.getEnvManager().getRecentSelectedConnection(); - if (StringUtils.isNotBlank(s)) { - // 之前的写法有多线程问题,nameList异步尚未初始化完成的时候,这里可能无法匹配设置数据连接名称,导致DBTableDataPane打开后连接面板空白 - // 这里的需求无非是设置上一次使用的数据连接,做个简单检查这个连接是否存在即可,存在就设置 - if (nameList.contains(s)) { - this.setSelectedItem(s); - } - } - // alex:如果这个ComboBox还是没有选中,那么选中第一个 - if (StringUtils.isBlank(this.getSelectedItem()) && this.getConnectionSize() > 0) { - this.setSelectedItem(this.getConnection(0)); + setRecentConnection(); + } + } + + /** + * 下拉框选项设置成最近选择的connection,如果最近选择不存在,则选择列表中的第一个 + */ + protected void setRecentConnection() { + String s = DesignerEnvManager.getEnvManager().getRecentSelectedConnection(); + if (StringUtils.isNotBlank(s)) { + // 之前的写法有多线程问题,nameList异步尚未初始化完成的时候,这里可能无法匹配设置数据连接名称,导致DBTableDataPane打开后连接面板空白 + // 这里的需求无非是设置上一次使用的数据连接,做个简单检查这个连接是否存在即可,存在就设置 + if (nameList.contains(s)) { + this.setSelectedItem(s); } } + // alex:如果这个ComboBox还是没有选中,那么选中第一个 + if (StringUtils.isBlank(this.getSelectedItem()) && this.getConnectionSize() > 0) { + this.setSelectedItem(this.getConnection(0)); + } + } + + /** + * 是否无选中状态(空白item也视为无选中) + * @return + */ + protected boolean isSelectedItemEmpty() { + String selectedItem = this.getSelectedItem(); + return selectedItem == null || StringUtils.equals(selectedItem, EMPTY.toString()); } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 93f2938556..f6ddfc5b98 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -7,6 +7,7 @@ import com.fr.data.impl.Connection; import com.fr.data.impl.ConnectionBean; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; +import com.fr.data.metric.utils.DatabaseConnectionMetricHandler; import com.fr.design.ExtraDesignClassManager; import com.fr.design.data.MapCompareUtils; import com.fr.design.dialog.BasicDialog; @@ -186,6 +187,9 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh case ADDED: case UPDATED: addedOrUpdatedConnections.add(new ConnectionBean(s, StringUtils.EMPTY, connection)); + if (connection instanceof JDBCDatabaseConnection){ + DatabaseConnectionMetricHandler.handleSaveConnection((JDBCDatabaseConnection) connection, null); + } default: break; } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java index a979a20cd6..613eed9a48 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java @@ -1,26 +1,32 @@ package com.fr.design.data.datapane.connect; import com.fr.base.BaseUtils; +import com.fr.base.svg.IconUtils; import com.fr.data.core.db.TableProcedure; import com.fr.data.impl.AbstractDatabaseConnection; import com.fr.data.impl.Connection; import com.fr.design.border.UIRoundedBorder; import com.fr.design.constants.UIConstants; +import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.loading.SwitchableTableDataPane; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilist.TableViewList; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.general.GeneralContext; import com.fr.stable.ArrayUtils; +import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.ToolTipManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -45,7 +51,39 @@ public class ConnectionTableProcedurePane extends BasicPane { private java.util.List listeners = new java.util.ArrayList(); public ConnectionTableProcedurePane() { + init(null); + } + + /** + * 传入父容器 + * @param parent + */ + public ConnectionTableProcedurePane(SwitchableTableDataPane parent) { + init(parent); + } + + private void init(SwitchableTableDataPane parent) { this.setLayout(new BorderLayout(4, 4)); + // 初始化数据连接下拉框 + initConnectionComboBox(parent); + // 初始化中间的面板 + JPanel centerPane = initCenterPane(); + this.add(connectionComboBox, BorderLayout.NORTH); + this.add(centerPane, BorderLayout.CENTER); + this.setPreferredSize(new Dimension(WIDTH, getPreferredSize().height)); + addKeyMonitor(); + } + + private JPanel initCenterPane() { + JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + // 搜索面板 + centerPane.add(createSearchPane(), BorderLayout.NORTH); + // 数据库表视图面板 + centerPane.add(createTableViewBorderPane(), BorderLayout.CENTER); + return centerPane; + } + + private void initConnectionComboBox(SwitchableTableDataPane parent) { connectionComboBox = new ConnectionComboBoxPanel(com.fr.data.impl.Connection.class) { @Override @@ -60,10 +98,34 @@ public class ConnectionTableProcedurePane extends BasicPane { search(true); } } + + @Override + protected void afterRefreshItems() { + // 刷新完成后,如果未选中(在nameList初始化完成之前可能会出现),则尝试再次设置 + if (isSelectedItemEmpty()) { + setRecentConnection(); + } + // 获取数据连接之后,让父容器切换面板 + if (parent != null) { + parent.switchTo(SwitchableTableDataPane.CONTENT_PANE_NAME); + } + } + + @Override + protected void refreshItemsError() { + // 获取数据连接出现错误时,也让父容器从Loading面板切换至内容面板 + if (parent != null) { + parent.switchTo(SwitchableTableDataPane.CONTENT_PANE_NAME); + } + } }; + connectionComboBox.addComboBoxActionListener(filter); + } + + private JPanel createTableViewBorderPane() { tableViewList = new TableViewList(); ToolTipManager.sharedInstance().registerComponent(tableViewList); - connectionComboBox.addComboBoxActionListener(filter); + tableViewList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { if (evt.getClickCount() >= 2) { @@ -80,23 +142,50 @@ public class ConnectionTableProcedurePane extends BasicPane { } } }); - JPanel filterPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UIScrollPane tableViewListPane = new UIScrollPane(tableViewList); + tableViewListPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); + JPanel tableViewBorderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + tableViewBorderPane.add(tableViewListPane, BorderLayout.CENTER); JPanel checkBoxgroupPane = createCheckBoxgroupPane(); if (checkBoxgroupPane != null) { - filterPane.add(createCheckBoxgroupPane(), BorderLayout.NORTH); + tableViewBorderPane.add(createCheckBoxgroupPane(), BorderLayout.SOUTH); } + return tableViewBorderPane; + } + + /** + * 创建搜索Panel,用于搜索表或视图 + * @return + */ + private JPanel createSearchPane() { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel searchPane = new JPanel(new BorderLayout(10, 0)); + searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR)); + searchPane.setBackground(Color.WHITE); searchField = new UITextField(); - searchPane.add(searchField, BorderLayout.CENTER); + searchField.setBorderPainted(false); + searchField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Table_Search")); searchField.getDocument().addDocumentListener(searchListener); - filterPane.add(searchPane, BorderLayout.CENTER); - UIScrollPane tableViewListPane = new UIScrollPane(tableViewList); - tableViewListPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); - this.add(connectionComboBox, BorderLayout.NORTH); - this.add(tableViewListPane, BorderLayout.CENTER); - this.add(filterPane, BorderLayout.SOUTH); - this.setPreferredSize(new Dimension(WIDTH, getPreferredSize().height)); - addKeyMonitor(); + searchField.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.CHECKBOX_HOVER_SELECTED)); + } + + @Override + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR)); + } + }); + // 搜索图标 + UILabel searchLabel = new UILabel(IconUtils.readIcon("/com/fr/design/images/data/search")); + searchLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + searchPane.add(searchField, BorderLayout.CENTER); + searchPane.add(searchLabel, BorderLayout.EAST); + panel.add(searchPane, BorderLayout.CENTER); + return panel; } protected void filter(Connection connection, String conName, List nameList) { @@ -224,4 +313,4 @@ public class ConnectionTableProcedurePane extends BasicPane { */ public void actionPerformed(TableProcedure target); } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java index d0738e57b8..a430a13bd1 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java @@ -127,10 +127,12 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() + 1); itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() - 1); } + afterRefreshItems(); } catch (Exception e) { if (!(e instanceof CancellationException)) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } + refreshItemsError(); } } @@ -160,6 +162,20 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { */ protected abstract java.util.Iterator items(); + /** + * 刷新ComboBox.items之后 + */ + protected void afterRefreshItems() { + // 空实现,供子类重写 + } + + /** + * 刷新ComboBox.items时出现异常 + */ + protected void refreshItemsError() { + // 空实现,供子类重写 + } + /* * 弹出对话框编辑Items */ diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java index e73f64eb36..d0ffd7f22c 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java @@ -20,6 +20,8 @@ import com.fr.design.data.datapane.preview.sql.PreviewPerformedSqlPane; import com.fr.design.data.datapane.sqlpane.SQLEditPane; import com.fr.design.data.tabledata.strategy.StrategyConfigHandler; import com.fr.design.data.tabledata.tabledatapane.db.StrategyConfigFrom; +import com.fr.design.data.tabledata.tabledatapane.loading.SwitchableTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; @@ -36,6 +38,7 @@ import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants; import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane; import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.design.menu.SeparatorDef; import com.fr.design.menu.ToolBarDef; @@ -70,6 +73,7 @@ import javax.swing.SwingUtilities; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import java.awt.BorderLayout; +import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; @@ -86,7 +90,7 @@ import java.util.List; * @version 10.0 * Created by rinoux on 2020/7/22 */ -public class DBTableDataPane extends AbstractTableDataPane { +public class DBTableDataPane extends AbstractTableDataPane implements SwitchableTableDataPane { private static final int BOTTOM = 6; private static final String PREVIEW_BUTTON = Toolkit.i18nText("Fine-Design_Basic_Preview"); @@ -109,14 +113,42 @@ public class DBTableDataPane extends AbstractTableDataPane { private StrategyConfigHandler configHandler; + private CardLayout card; + /** 数据库查询面板真正的内容面板 */ + private JPanel contentPane; + /** 加载中面板 */ + private JPanel loadingPane; public DBTableDataPane() { + initCards(); + initContentPane(); + } + + /** + * 初始化内容面板 + */ + protected void initContentPane() { init(); initMainSplitPane(); } + /** + * 初始化cardLayout以及LoadingPane等,并且布局切到LoadingPane + */ + protected void initCards() { + card = new CardLayout(); + setLayout(card); + + loadingPane = new TipsPane(true); + contentPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + + add(LOADING_PANE_NAME, loadingPane); + add(CONTENT_PANE_NAME, contentPane); + switchTo(LOADING_PANE_NAME); + } + private void init() { - setLayout(new BorderLayout(4, 4)); + contentPane.setLayout(new BorderLayout(4, 4)); this.sqlTextPane = new SQLEditPane(); this.sqlTextPane.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL); @@ -130,7 +162,7 @@ public class DBTableDataPane extends AbstractTableDataPane { editorPane = new UITableEditorPane<>(model); - this.connectionTableProcedurePane = new ConnectionTableProcedurePane() { + this.connectionTableProcedurePane = new ConnectionTableProcedurePane(this) { @Override protected void filter(Connection connection, String conName, List nameList) { connection.addConnection(nameList, conName, new Class[]{ @@ -231,7 +263,21 @@ public class DBTableDataPane extends AbstractTableDataPane { JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, this.connectionTableProcedurePane, sqlSplitPane); mainSplitPane.setBorder(BorderFactory.createLineBorder(GUICoreUtils.getTitleLineBorderColor())); mainSplitPane.setOneTouchExpandable(true); - add(mainSplitPane, BorderLayout.CENTER); + contentPane.add(mainSplitPane, BorderLayout.CENTER); + } + + @Override + public void switchTo(String panelName) { + try { + if (panelName != null) { + card.show(this, panelName); + } + } catch (IllegalArgumentException ingore) { + // 有些直接继承此面板或者替换掉此面板的插件,在未适配此功能时会出现报错,因为不是CardLayout,无法切换,这里处理下 + FineLoggerFactory.getLogger().info("cannot switch pane by {}", this.getClass().getName()); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } } private boolean isPreviewOrRefreshButton(FocusEvent e) { diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/SwitchableTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/SwitchableTableDataPane.java new file mode 100644 index 0000000000..221ee1cbba --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/SwitchableTableDataPane.java @@ -0,0 +1,23 @@ +package com.fr.design.data.tabledata.tabledatapane.loading; + + + +/** + * 可切换的DBTableData对应的数据集面板,需要使用CardLayout布局 + * 主要是给插件适配用的 + * @author Yvan + */ +public interface SwitchableTableDataPane { + + /** Loading面板 */ + String LOADING_PANE_NAME = "Loading"; + /** 内容面板 */ + String CONTENT_PANE_NAME = "Content"; + + /** + * 根据面板名称切换面板 + * @param paneName 面板名称 + */ + void switchTo(String paneName); + +} diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TableDataLoadingPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TableDataLoadingPane.java new file mode 100644 index 0000000000..c3f12c3e7f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TableDataLoadingPane.java @@ -0,0 +1,54 @@ +package com.fr.design.data.tabledata.tabledatapane.loading; + +import com.fr.design.dialog.BasicPane; +import com.fr.design.i18n.Toolkit; + +import javax.swing.JPanel; +import java.awt.CardLayout; + +/** + * @author Yvan + */ +public class TableDataLoadingPane extends BasicPane { + + /** Loading面板 */ + public static final String LOADING_PANE_NAME = "Loading"; + /** 无权限提示面板 */ + public static final String NO_AUTH_PANE_NAME = "NoAuthority"; + /** 错误提示面板 */ + public static final String ERROR_NAME = "Error"; + + private CardLayout card; + + /** 加载中面板 */ + private JPanel loadingPane; + /** 错误提示面板 */ + private JPanel errorPane; + /** 数据连接无权限面板 */ + private JPanel noAuthorityPane; + + public TableDataLoadingPane() { + initPanes(); + } + + private void initPanes() { + card = new CardLayout(); + this.setLayout(card); + loadingPane = new TipsPane(true); + errorPane = new TipsPane(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Error")); + noAuthorityPane = new TipsPane(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_No_Auth")); + add(LOADING_PANE_NAME, loadingPane); + add(NO_AUTH_PANE_NAME, noAuthorityPane); + add(ERROR_NAME, errorPane); + switchTo(LOADING_PANE_NAME); + } + + public void switchTo(String panelName) { + card.show(this, panelName); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_DS-Database_Query"); + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TipsPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TipsPane.java new file mode 100644 index 0000000000..40fcb6ef28 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TipsPane.java @@ -0,0 +1,45 @@ +package com.fr.design.data.tabledata.tabledatapane.loading; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; + +/** + * 提示面板,支持自定义提示,支持进度条配置可选 + * @author Yvan + */ +public class TipsPane extends JPanel { + + /** + * 默认提示 + */ + private static final String LOADING = Toolkit.i18nText("Fine-Design_Basic_Loading_And_Waiting"); + + public TipsPane () { + this(LOADING, false); + } + + public TipsPane (String tip) { + this(tip, false); + } + + public TipsPane (boolean needProgressBar) { + this(LOADING, needProgressBar); + } + + public TipsPane (String tips, boolean needProgressBar) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + UILabel tipsLabel = new UILabel(tips, SwingConstants.CENTER); + this.add(tipsLabel, BorderLayout.CENTER); + if (needProgressBar) { + JProgressBar progressBar = new JProgressBar(); + progressBar.setIndeterminate(true); + this.add(progressBar, BorderLayout.SOUTH); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java index a9b97d2698..bd2e8b2afb 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java @@ -296,7 +296,7 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver, UIOb return selectedIndex; } - protected void setSelectedIndex(int newSelectedIndex, boolean fireChanged) { + public void setSelectedIndex(int newSelectedIndex, boolean fireChanged) { if (selectedIndex != newSelectedIndex) { selectedIndex = newSelectedIndex; for (int i = 0; i < labelButtonList.size(); i++) { diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java index d772591047..12ca005249 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java @@ -63,7 +63,7 @@ public class UITabGroup extends UIButtonGroup { } @Override - protected void setSelectedIndex(int newSelectedIndex, boolean fireChanged) { + public void setSelectedIndex(int newSelectedIndex, boolean fireChanged) { super.setSelectedIndex(newSelectedIndex, false); tabChanged(newSelectedIndex); } diff --git a/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java b/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java index 85d73515e5..c98455a58f 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java +++ b/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java @@ -14,11 +14,18 @@ import java.awt.event.MouseEvent; public class ActionLabel extends UILabel { private ActionListener actionListener; private Color color; + // 文字是否有下划线 + private boolean drawUnderLine = true; public ActionLabel(String text) { this(text, Color.blue); } + public ActionLabel(String text, boolean drawUnderLine) { + this(text, Color.blue); + this.drawUnderLine = drawUnderLine; + } + public ActionLabel(String text, Color color) { super(text); this.color = color; @@ -39,7 +46,9 @@ public class ActionLabel extends UILabel { super.paintComponent(_gfx); _gfx.setColor(this.color); - _gfx.drawLine(0, this.getHeight() - 1, this.getWidth(), this.getHeight() - 1); + if (drawUnderLine) { + _gfx.drawLine(0, this.getHeight() - 1, this.getWidth(), this.getHeight() - 1); + } } private MouseInputAdapter mouseInputAdapter = new MouseInputAdapter() { @@ -95,4 +104,12 @@ public class ActionLabel extends UILabel { } } }; -} \ No newline at end of file + + public boolean isDrawUnderLine() { + return drawUnderLine; + } + + public void setDrawUnderLine(boolean drawUnderLine) { + this.drawUnderLine = drawUnderLine; + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/itooltip/UIToolTip.java b/designer-base/src/main/java/com/fr/design/gui/itooltip/UIToolTip.java index 8db73f8e66..ab6fb70b41 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itooltip/UIToolTip.java +++ b/designer-base/src/main/java/com/fr/design/gui/itooltip/UIToolTip.java @@ -67,6 +67,9 @@ public class UIToolTip extends JToolTip{ this.addMouseMotionListener(new MouseMotionAdapter() { public void mouseMoved(MouseEvent e) { Container container = getComponent(); + if (container == null) { + return; + } while (!ComparatorUtils.equals(container.getClass(), UIScrollPane.class)) { if (container.getParent() == null) { break; diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeAttrChangeListener.java b/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeAttrChangeListener.java new file mode 100644 index 0000000000..c31cfe5295 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeAttrChangeListener.java @@ -0,0 +1,7 @@ +package com.fr.design.gui.itree.refreshabletree; + +import com.fr.data.impl.TreeAttr; + +public interface TreeAttrChangeListener { + void doChange(TreeAttr treeAttr); +} diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java b/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java index a848b06d69..691749fac6 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/itree/refreshabletree/TreeRootPane.java @@ -10,21 +10,24 @@ import javax.swing.BoxLayout; import javax.swing.JPanel; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.List; public class TreeRootPane extends BasicPane { + private final List listeners = new ArrayList<>(); + // 是否支持多选(checkBoxTree) //private JCheckBox multipleSelection; - private UICheckBox checkTypeCheckBox; + private final UICheckBox checkTypeCheckBox; // richer:加载的方式,支持异步加载和完全加载 - private UICheckBox loadTypeCheckBox; + private final UICheckBox loadTypeCheckBox; - private UICheckBox layerTypeCheckBox; + private final UICheckBox layerTypeCheckBox; - private UICheckBox returnFullPathCheckBox; + private final UICheckBox returnFullPathCheckBox; public TreeRootPane() { this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); @@ -41,13 +44,6 @@ public class TreeRootPane extends BasicPane { checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); loadTypeCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Load_By_Async")); loadTypeCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - loadTypeCheckBox.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - UICheckBox checkBox = (UICheckBox) e.getSource(); - doLoadTypeChange(checkBox.isSelected()); - } - }); loadTypePane.add(loadTypeCheckBox); this.add(loadTypePane); @@ -63,11 +59,27 @@ public class TreeRootPane extends BasicPane { checkTypePane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); returnFullPathPane.add(returnFullPathCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Return_Full_Path"))); returnFullPathCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + addCheckBoxListener(); this.add(returnFullPathPane); } + private void addCheckBoxListener() { + loadTypeCheckBox.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + UICheckBox checkBox = (UICheckBox) e.getSource(); + doLoadTypeChange(checkBox.isSelected()); + } + }); + + checkTypeCheckBox.addActionListener(event->fireTreeAttrChangeListener()); + loadTypeCheckBox.addActionListener(event->fireTreeAttrChangeListener()); + layerTypeCheckBox.addActionListener(event->fireTreeAttrChangeListener()); + returnFullPathCheckBox.addActionListener(event->fireTreeAttrChangeListener()); + } + private void doLoadTypeChange(Boolean selected) { //给埋点插件提供一个方法,埋埋点用 } @@ -82,6 +94,7 @@ public class TreeRootPane extends BasicPane { loadTypeCheckBox.setSelected(treeAttr.isAjax()); layerTypeCheckBox.setSelected(treeAttr.isSelectLeafOnly()); returnFullPathCheckBox.setSelected(treeAttr.isReturnFullPath()); + fireTreeAttrChangeListener(); } public TreeAttr update() { @@ -93,4 +106,17 @@ public class TreeRootPane extends BasicPane { return treeAttr; } + + public void addTreeAttrChangeListener(TreeAttrChangeListener listener) { + listeners.add(listener); + } + + public void fireTreeAttrChangeListener() { + TreeAttr treeAttr = new TreeAttr(); + treeAttr.setMultipleSelection(checkTypeCheckBox.isSelected()); + treeAttr.setAjax(loadTypeCheckBox.isSelected()); + treeAttr.setSelectLeafOnly(layerTypeCheckBox.isSelected()); + treeAttr.setReturnFullPath(returnFullPathCheckBox.isSelected()); + listeners.forEach(listener -> listener.doChange(treeAttr)); + } } diff --git a/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java b/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java index 071feee6ac..401fae8497 100644 --- a/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java +++ b/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java @@ -13,6 +13,9 @@ import javax.swing.JRadioButton; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.LayoutManager; @@ -148,6 +151,50 @@ public class FRGUIPaneFactory { public static LayoutManager createNColumnGridLayout(int nColumn) { return new FRGridLayout(nColumn); } + + /** + * 将 centerBody 为中心,创建一个布局 + * 注:只有当且仅当有一个组件,且希望组件 上下左右 居中时使用 + * @param centerBody 中心组件 + * @return 布局方式 + */ + public static LayoutManager createCenterLayout(JComponent centerBody) { + + final double yFactor = 0.30; + return new LayoutManager() { + + @Override + public void removeLayoutComponent(Component comp) { + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return centerBody.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + int width = parent.getParent().getWidth(); + int height = parent.getParent().getHeight(); + + // 这个时候大小是不确定的 + int bodyWidth = centerBody.getPreferredSize().width; + int bodyHeight = centerBody.getPreferredSize().height; + int labelX = (width - bodyWidth) / 2; + int labelY = (int) ((height - bodyHeight) * yFactor); + centerBody.setBounds(labelX, labelY, bodyWidth, bodyHeight); + } + + @Override + public void addLayoutComponent(String name, Component comp) { + } + }; + } /** * 创建一个带标题边框面板 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 4751649b83..da8f28f60d 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 @@ -29,17 +29,16 @@ import com.fr.design.fun.impl.AbstractTemplateTreeShortCutProvider; import com.fr.design.gui.iprogressbar.ProgressDialog; import com.fr.design.gui.iscrollbar.UIScrollBar; import com.fr.design.i18n.Toolkit; +import com.fr.design.lock.LockInfoDialog; import com.fr.design.mainframe.share.mini.MiniShopDisposingChecker; -import com.fr.design.mainframe.share.mini.MiniShopNativeTaskManager; import com.fr.design.mainframe.toolbar.ToolBarMenuDock; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.menu.ShortCut; import com.fr.design.os.impl.MacOsAddListenerAction; import com.fr.design.os.impl.SupportOSImpl; -import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.TemplateUtils; -import com.fr.design.lock.LockInfoDialog; +import com.fr.design.utils.gui.GUICoreUtils; import com.fr.event.EventDispatcher; import com.fr.exception.DecryptTemplateException; import com.fr.exception.TplLockedException; @@ -60,11 +59,11 @@ import com.fr.stable.os.OperatingSystem; import com.fr.stable.os.support.OSSupportCenter; import com.fr.stable.project.ProjectConstants; import com.fr.start.OemHandler; +import com.fr.start.common.DesignerOpenEmptyPanel; import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; import com.fr.workspace.connect.WorkspaceConnectionInfo; -import java.util.UUID; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JFrame; @@ -103,6 +102,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.CopyOnWriteArrayList; public class DesignerFrame extends JFrame implements JTemplateActionListener, TargetModifiedListener { @@ -171,7 +171,10 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta return; } //关闭前当前模板 停止编辑 - HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().stopEditing(); + JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (currentEditingTemplate != null) { + currentEditingTemplate.stopEditing(); + } SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(true); // 全部保存成功才退出 if (saveSomeTemplatePane.showSavePane()) { @@ -302,10 +305,15 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta } public void resizeFrame() { - - HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().setComposite(); + + JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (currentEditingTemplate != null) { + currentEditingTemplate.setComposite(); + } reCalculateFrameSize(); - HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().doResize(); + if (currentEditingTemplate != null) { + currentEditingTemplate.doResize(); + } } @Deprecated @@ -798,6 +806,17 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta } } } + + public void showEmptyJTemplate() { + + DesignerOpenEmptyPanel designerOpenEmptyPanel = new DesignerOpenEmptyPanel(); + BorderLayout layout = (BorderLayout) basePane.getLayout(); + basePane.remove(layout.getLayoutComponent(BorderLayout.CENTER)); + basePane.remove(layout.getLayoutComponent(BorderLayout.EAST)); + basePane.add(designerOpenEmptyPanel, BorderLayout.CENTER); + + layeredPane.repaint(); + } /** * 添加新建模板, 并激活. diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java index 1e072d956a..400f698185 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerUIModeConfig.java @@ -1,8 +1,11 @@ package com.fr.design.mainframe; +import com.fr.base.AutoChangeLineProvider; +import com.fr.base.DefaultAutoChangeLine; import com.fr.base.ScreenResolution; import com.fr.design.fun.ReportLengthUNITProvider; import com.fr.design.unit.UnitConvertUtil; +import com.fr.form.fit.NewUIModeAutoChangeLine; import com.fr.general.ComparatorUtils; import com.fr.stable.Constants; @@ -58,6 +61,14 @@ public class DesignerUIModeConfig { return mode.parseLengthUNIT(unitType); } + /** + * 获取不同模式下的换行逻辑 + * @return AutoChangeLineProvider + */ + public AutoChangeLineProvider getAutoChangeLineStrategy() { + return mode.getAutoChangeLineStrategy(); + } + /** * 获取不同模式下的屏幕分辨率 * @@ -75,6 +86,11 @@ public class DesignerUIModeConfig { return UnitConvertUtil.parseLengthUNIT(unitType); } + @Override + public AutoChangeLineProvider getAutoChangeLineStrategy() { + return new DefaultAutoChangeLine(); + } + @Override protected int getScreenResolution() { return ScreenResolution.getScreenResolution(); @@ -87,6 +103,11 @@ public class DesignerUIModeConfig { return new PXReportLengthUNIT(); } + @Override + public AutoChangeLineProvider getAutoChangeLineStrategy() { + return new NewUIModeAutoChangeLine(); + } + @Override protected int getScreenResolution() { return Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION; @@ -96,6 +117,8 @@ public class DesignerUIModeConfig { protected abstract ReportLengthUNITProvider parseLengthUNIT(int unitType); + public abstract AutoChangeLineProvider getAutoChangeLineStrategy(); + protected abstract int getScreenResolution(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JDashboard.java b/designer-base/src/main/java/com/fr/design/mainframe/JDashboard.java index d2b45f4ea1..e4e4e9be93 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JDashboard.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JDashboard.java @@ -1,5 +1,9 @@ package com.fr.design.mainframe; +import com.fr.report.worksheet.FormElementCase; + +import java.awt.Rectangle; + /** * @author Starryi * @version 1.0 @@ -7,4 +11,6 @@ package com.fr.design.mainframe; */ public interface JDashboard { void switchToDashBoardEditor(); + + Rectangle getElementCaseRectangle(FormElementCase elementCase); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/TransparentPane.java b/designer-base/src/main/java/com/fr/design/mainframe/TransparentPane.java index 8861a75919..26f2406985 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/TransparentPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/TransparentPane.java @@ -1,58 +1,30 @@ package com.fr.design.mainframe; +import com.fr.design.components.loading.LoadingPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; + +import javax.swing.Timer; import java.awt.AlphaComposite; -import java.awt.BasicStroke; -import java.awt.Color; import java.awt.Component; -import java.awt.Composite; import java.awt.Container; import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.LayoutManager; -import java.awt.RenderingHints; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.Timer; /** * @author hades * @version 10.0 * Created by hades on 2021/4/12 */ -public class TransparentPane extends JComponent implements ActionListener { +public class TransparentPane extends LoadingPane { private UILabel label; - private AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f); - private volatile boolean mIsRunning; - private volatile boolean mIsFadingOut; - private Timer mTimer; - private int mAngle; - private int mFadeCount; - private int mFadeLimit = 15; - private int lines = 12; - private int maxAngle = 360; - private int angleAdd = 30; + private double prec = 0.56; public TransparentPane() { - addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - // do nothing - } - }); - - setLayout(getCoverLayout()); - setBackground(null); - setOpaque(false); + super(); label = new UILabel(Toolkit.i18nText("Fine-Design_Saving_Template_Tip")); add(label); } @@ -91,72 +63,4 @@ public class TransparentPane extends JComponent implements ActionListener { }; } - - @Override - public void paint(Graphics g) { - int w = this.getWidth(); - int h = this.getHeight(); - super.paint(g); - if (!mIsRunning) { - return; - } - Graphics2D g2 = (Graphics2D) g.create(); - float fade = (float) mFadeCount / (float) mFadeLimit; - Composite urComposite = g2.getComposite(); - g2.setComposite(composite); - g2.fillRect(0, 0, w, h); - g2.setComposite(urComposite); - int s = Math.min(w, h) / 50; - int cx = w / 2; - int cy = h / 2; - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2.setStroke(new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); - g2.setPaint(Color.BLACK); - g2.rotate(Math.PI * mAngle / 180, cx, cy); - for (int i = 0; i < lines; i++) { - float scale = (11.0f - (float) i) / 11.0f; - g2.drawLine(cx + s, cy, cx + s * 2, cy); - g2.rotate(-Math.PI / 6, cx, cy); - g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, scale * fade)); - } - g2.dispose(); - } - - @Override - public void actionPerformed(ActionEvent e) { - if (mIsRunning) { - repaint(); - mAngle += angleAdd; - if (mAngle >= maxAngle) { - mAngle = 0; - } - if (mIsFadingOut) { - if (--mFadeCount == 0) { - mIsRunning = false; - mTimer.stop(); - } - } else if (mFadeCount < mFadeLimit) { - mFadeCount++; - } - } - } - - public void start() { - if (mIsRunning) { - return; - } - mIsRunning = true; - mIsFadingOut = false; - mFadeCount = 0; - int fps = 24; - int tick = 1000 / fps; - mTimer = new Timer(tick, this); - mTimer.start(); - } - - public void stop() { - mIsRunning = false; - mIsFadingOut = true; - } - } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index 2299337366..6aabb9ff53 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java @@ -502,10 +502,7 @@ public abstract class ToolBarMenuDock { addPluginManagerAction(menuDef); menuDef.addShortCut(new FunctionManagerAction()); - if (!DesignModeContext.isDuchampMode()) { - menuDef.addShortCut(new GlobalParameterAction()); - } - + menuDef.addShortCut(new GlobalParameterAction()); } diff --git a/designer-base/src/main/java/com/fr/design/notification/NotificationCenter.java b/designer-base/src/main/java/com/fr/design/notification/NotificationCenter.java index 3faadf795a..12e3503a06 100644 --- a/designer-base/src/main/java/com/fr/design/notification/NotificationCenter.java +++ b/designer-base/src/main/java/com/fr/design/notification/NotificationCenter.java @@ -2,6 +2,8 @@ package com.fr.design.notification; import com.fr.design.notification.ui.NotificationCenterPane; +import com.fr.stable.StringUtils; + import java.util.ArrayList; import java.util.List; @@ -30,6 +32,15 @@ public class NotificationCenter { NotificationCenterPane.getNotificationCenterPane().refreshButton(); } + /** + * 通过messageId删除消息 + * @param messageID + */ + public void removeNotificationByMessageID(String messageID) { + notifications.removeIf(notification -> StringUtils.equals(notification.getMessageId(), messageID)); + NotificationCenterPane.getNotificationCenterPane().refreshButton(); + } + public Notification getNotification(int index){ return notifications.get(index); } diff --git a/designer-base/src/main/java/com/fr/design/plugin/remind/PluginErrorDesignReminder.java b/designer-base/src/main/java/com/fr/design/plugin/remind/PluginErrorDesignReminder.java new file mode 100644 index 0000000000..6ba1c115ba --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/plugin/remind/PluginErrorDesignReminder.java @@ -0,0 +1,143 @@ +package com.fr.design.plugin.remind; + +import com.fr.design.dialog.NotificationDialogAction; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.notification.Notification; +import com.fr.design.notification.NotificationCenter; +import com.fr.plugin.error.PluginErrorRemindHandler; +import com.fr.plugin.error.PluginErrorReminder; +import com.fr.stable.StringUtils; +import com.fr.stable.collections.CollectionUtils; +import com.fr.workspace.WorkContext; + +import javax.swing.SwingUtilities; +import java.util.List; + +/** + * 插件错误信息提醒-设计器模块 + * + * @author Yvan + */ +public class PluginErrorDesignReminder implements PluginErrorReminder { + + private static final String MESSAGE_ID = "plugin-invalidate-remind"; + public static final String COMMA = "、"; + public static final String COLON = ":"; + public static final String NEW_LINE_TAG = "
"; + private static final int MAX_PLUGIN_NAME_PER_LINE = 3; + + private static class Holder { + private static final PluginErrorDesignReminder INSTANCE = new PluginErrorDesignReminder(); + } + + private PluginErrorDesignReminder() {} + + public static PluginErrorDesignReminder getInstance() { + return Holder.INSTANCE; + } + + @Override + public void remindStartFailedPlugins() { + + if (!WorkContext.getCurrent().isLocal()) { + return; + } + String content = PluginErrorRemindHandler.pluginErrorContent(); + if (StringUtils.isNotEmpty(content)) { + // 该操作需要在当前awt操作之后执行,使用SwingUtilities.invokeLater将其置于awt操作对列末尾 + // 若使用UIUtil.invokeLaterIfNeeded,会立即执行,影响其他UI操作 + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + PluginStartFailedRemindDialog dialog = new PluginStartFailedRemindDialog(DesignerContext.getDesignerFrame(), content); + dialog.setVisible(true); + } + }); + } + } + + @Override + public void remindInvalidatePlugins() { + + if (!WorkContext.getCurrent().isLocal()) { + return; + } + // 获取失效插件名称列表 + List embedPluginNames = PluginErrorRemindHandler.getInvalidateEmbedPluginNames(); + if (!CollectionUtils.isEmpty(embedPluginNames)) { + // 构建消息 + String message = generateMessageContent(embedPluginNames); + Notification notification = generateNotification(message, embedPluginNames); + // 添加消息 + NotificationCenter.getInstance().addNotification(notification); + } + } + + /** + * 构建消息内容 + * @param invalidatePluginNames + * @return + */ + private String generateMessageContent(List invalidatePluginNames) { + return new StringBuilder() + .append(Toolkit.i18nText("Fine-Design_Plugin_Embed_Notice")) + .append(COLON) + .append(NEW_LINE_TAG) + .append(NEW_LINE_TAG) + .append(dealWithPluginNames(invalidatePluginNames)) + .append(NEW_LINE_TAG) + .append(NEW_LINE_TAG) + .append(Toolkit.i18nText("Fine-Design_Plugin_Embed_Description")) + .append(NEW_LINE_TAG) + .toString(); + } + + /** + * 处理消息中的插件名称展示 + * 由于Notification那边展示的弹窗是随消息宽度变化的,所以插件名称很多时会变得很长。这里做个分行 + * @return + * @param invalidatePluginNames + */ + public String dealWithPluginNames(List invalidatePluginNames) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < invalidatePluginNames.size(); i++) { + String pluginName = invalidatePluginNames.get(i); + builder.append(pluginName); + if (i != invalidatePluginNames.size() - 1) { + builder.append(i % MAX_PLUGIN_NAME_PER_LINE == (MAX_PLUGIN_NAME_PER_LINE - 1) ? NEW_LINE_TAG : COMMA); + } + } + return builder.toString(); + } + + /** + * 构建通知对象 + * @param message + * @param invalidatePluginNames + * @return + */ + private Notification generateNotification(String message, List invalidatePluginNames) { + return new Notification( + MESSAGE_ID, + Notification.WARNING_MESSAGE, + message, + new NotificationDialogAction() { + @Override + public String name() { + return "plugin-invalidate-remind-show"; + } + + @Override + public void doClick() { + PluginInvalidateRemindDialog remindDialog = new PluginInvalidateRemindDialog( + DesignerContext.getDesignerFrame(), + invalidatePluginNames, + PluginErrorRemindHandler.getInvalidateEmbedPluginMarkers(), + MESSAGE_ID); + remindDialog.setVisible(true); + } + } + ); + } +} diff --git a/designer-base/src/main/java/com/fr/design/plugin/remind/PluginInvalidateRemindDialog.java b/designer-base/src/main/java/com/fr/design/plugin/remind/PluginInvalidateRemindDialog.java new file mode 100644 index 0000000000..0c9986951f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/plugin/remind/PluginInvalidateRemindDialog.java @@ -0,0 +1,211 @@ +package com.fr.design.plugin.remind; + +import com.fr.common.util.Collections; +import com.fr.design.actions.UpdateAction; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.DesignSizeI18nManager; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.notification.NotificationCenter; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.FRFont; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginMarker; +import com.fr.plugin.manage.PluginManager; +import com.fr.plugin.manage.control.PluginTaskCallback; +import com.fr.plugin.manage.control.PluginTaskResult; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextPane; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.List; + +/** + * @author Yvan + */ +public class PluginInvalidateRemindDialog extends JDialog implements ActionListener{ + + /** + * 因内置而失效的插件Marker列表 + */ + private List pluginMarkers; + + /** + * 因内置而失效的插件名称列表 + */ + private List pluginNames; + + /** + * 本弹窗对应的消息的id + * 方便弹窗逻辑执行完之后,删除通知中心的消息 + */ + private String messageID; + + + public PluginInvalidateRemindDialog(Frame parent, List pluginNames, List pluginMarkers, String messageId) { + super(parent, true); + this.pluginMarkers = pluginMarkers; + this.pluginNames = pluginNames; + this.messageID = messageId; + // 标题 + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")); + this.setResizable(false); + + this.add(initTopPane(), BorderLayout.NORTH); + this.add(initCenterPanel(), BorderLayout.CENTER); + this.add(initBottomPanel(), BorderLayout.SOUTH); + this.setSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.plugin.remind.PluginInvalidateRemindDialog.dialog")); + + GUICoreUtils.centerWindow(this); + + } + + /** + * 上层的面板,用于解释插件内置 + * @return + */ + private JPanel initTopPane() { + JPanel topPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + // 图标面板 + JPanel imagePanel = new JPanel(); + Icon icon = IOUtils.readIcon("com/fr/design/images/warnings/icon_WarningIcon_normal.png"); + UILabel imageLabel = new UILabel(); + imageLabel.setIcon(icon); + imagePanel.add(imageLabel); + imagePanel.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 10)); + + JPanel verticalPanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true); + UILabel noticeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Plugin_Embed_Notice")); + noticeLabel.setFont(FRFont.getInstance().applySize(16)); + UILabel adviceLabel = new UILabel(Toolkit.i18nText("Fine-Design_Plugin_Embed_Advice")); + UILabel descriptionLabel = new UILabel(Toolkit.i18nText("Fine-Design_Plugin_Embed_Description")); + verticalPanel.add(noticeLabel); + verticalPanel.add(adviceLabel); + verticalPanel.add(descriptionLabel); + + topPane.add(imagePanel, BorderLayout.WEST); + topPane.add(verticalPanel, BorderLayout.CENTER); + topPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 20)); + return topPane; + } + + /** + * 中层面板,用于展示内置插件列表 + * @return + */ + private JPanel initCenterPanel() { + JPanel centerPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + // "插件列表"标签面板 + UILabel textLabel = new UILabel(Toolkit.i18nText("Fine-Design_Plugin_Embed_List")); + textLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); + + JTextPane textPane = new JTextPane(); + textPane.setEditable(false); + textPane.setBackground(Color.WHITE); + SimpleAttributeSet attributeSet = new SimpleAttributeSet(); + StyleConstants.setLineSpacing(attributeSet, 0.5f); + textPane.setParagraphAttributes(attributeSet, true); + textPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + textPane.setText(generatePluginListText(pluginNames)); + JScrollPane scrollPane = new JScrollPane(textPane); + + centerPane.add(textLabel, BorderLayout.NORTH); + centerPane.add(scrollPane, BorderLayout.CENTER); + centerPane.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 10)); + centerPane.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.plugin.remind.PluginInvalidateRemindDialog.centerPane")); + return centerPane; + } + + /** + * 生成中间面板展示的插件列表 + * @param pluginNames + * @return + */ + private String generatePluginListText(List pluginNames) { + String space = " "; + StringBuilder sb = new StringBuilder(); + for (String pluginName : pluginNames) { + sb.append(space).append(pluginName).append("\n"); + } + return sb.toString(); + } + + /** + * 底层面板,用于处理用户操作 + * @return + */ + private JPanel initBottomPanel() { + JPanel bottomPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); + + UIButton ignore = new UIButton(Toolkit.i18nText("Fine-Design_Plugin_Embed_Ignore")); + UIButton delete = new UIButton(Toolkit.i18nText("Fine-Design_Plugin_Embed_Delete_Plugins")); + UILabel emptyLabel = new UILabel(); + ignore.addActionListener(this); + delete.addActionListener(new DeleteEmbedPluginsAction(this)); + bottomPane.add(ignore, BorderLayout.WEST); + bottomPane.add(emptyLabel, BorderLayout.CENTER); + bottomPane.add(delete, BorderLayout.EAST); + return bottomPane; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.dispose(); + } + + private class DeleteEmbedPluginsAction extends UpdateAction { + + private JDialog dialog; + + + DeleteEmbedPluginsAction(JDialog dialog) { + this.dialog = dialog; + } + + @Override + public void actionPerformed(ActionEvent e) { + this.dialog.dispose(); + // 删除插件 + deleteEmbedPlugins(pluginMarkers); + // 删除消息 + NotificationCenter.getInstance().removeNotificationByMessageID(messageID); + } + + /** + * 删除插件 + * @param toDelete + */ + private void deleteEmbedPlugins(List toDelete) { + if (Collections.isEmpty(toDelete)) { + return; + } + for (PluginMarker pluginMarker : toDelete) { + // 删除插件 + PluginManager.getController().uninstall(pluginMarker, false, new PluginTaskCallback() { + @Override + public void done(PluginTaskResult result) { + // 输出结果日志 + FineLoggerFactory.getLogger().info( + "Detele Embed Plugin(id = {}, version = {}) {}", + pluginMarker.getPluginID(), + pluginMarker.getVersion(), result.isSuccess() ? "Succeeded" : "Failed"); + } + }); + } + } + } +} diff --git a/designer-base/src/main/java/com/fr/env/PluginErrorRemindDialog.java b/designer-base/src/main/java/com/fr/design/plugin/remind/PluginStartFailedRemindDialog.java similarity index 96% rename from designer-base/src/main/java/com/fr/env/PluginErrorRemindDialog.java rename to designer-base/src/main/java/com/fr/design/plugin/remind/PluginStartFailedRemindDialog.java index 1558d72e95..639c7a2925 100644 --- a/designer-base/src/main/java/com/fr/env/PluginErrorRemindDialog.java +++ b/designer-base/src/main/java/com/fr/design/plugin/remind/PluginStartFailedRemindDialog.java @@ -1,4 +1,4 @@ -package com.fr.env; +package com.fr.design.plugin.remind; import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.UpdateAction; @@ -32,11 +32,11 @@ import java.util.Set; /** * 插件启动失败提示窗 */ -public class PluginErrorRemindDialog extends JDialog implements ActionListener { +public class PluginStartFailedRemindDialog extends JDialog implements ActionListener { private static final String SIM_HEI = "SimHei"; - public PluginErrorRemindDialog(Frame parent, String text) { + public PluginStartFailedRemindDialog(Frame parent, String text) { super(parent, true); //上面的标签面板 JPanel topPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); diff --git a/designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java b/designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java new file mode 100644 index 0000000000..56db4cee9e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/update/actions/NewFeatureAction.java @@ -0,0 +1,34 @@ +package com.fr.design.update.actions; + + +import com.fr.common.util.Strings; +import com.fr.design.utils.BrowseUtils; +import com.fr.general.CloudCenter; +import com.fr.log.FineLoggerFactory; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + + +/** + * 帮助-更新升级 + * 点击查看新特性 + * */ +public class NewFeatureAction implements ActionListener { + + + public static String DEFAULT_UPDATE_DETAIL_URL = "https://help.fanruan.com/finereport/doc-view-4699.html"; + + @Override + public void actionPerformed(ActionEvent e) { + try { + String url = CloudCenter.getInstance().acquireConf("fr.latest.update.detil"); + if (Strings.isEmpty(url)) { + url = DEFAULT_UPDATE_DETAIL_URL; + } + BrowseUtils.browser(url); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage()); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java b/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java index deda005c36..0dd70e03cd 100644 --- a/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java +++ b/designer-base/src/main/java/com/fr/design/update/ui/dialog/UpdateMainDialog.java @@ -9,6 +9,7 @@ import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.UIDialog; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.ActionLabel; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.i18n.Toolkit; @@ -16,6 +17,7 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.DesignerContext; import com.fr.design.update.actions.FileProcess; +import com.fr.design.update.actions.NewFeatureAction; import com.fr.design.update.domain.UpdateInfoCachePropertyManager; import com.fr.design.update.utils.UpdateFileUtils; import com.fr.design.update.ui.widget.LoadingLabel; @@ -57,7 +59,6 @@ import java.util.*; import java.util.List; import java.util.concurrent.ExecutionException; -import static com.fr.design.dialog.FineJOptionPane.OPTION_OK_CANCEL; import static java.nio.charset.StandardCharsets.*; import static javax.swing.JOptionPane.QUESTION_MESSAGE; @@ -85,7 +86,7 @@ public class UpdateMainDialog extends UIDialog { private static final String HYPHEN = "-"; - private final SimpleDateFormat CHANGELOG_FORMAT = new SimpleDateFormat("M/d/y, h:m:s a", Locale.ENGLISH); + private final SimpleDateFormat UPDATELOG_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); private final SimpleDateFormat UPDATE_INFO_TABLE_FORMAT = new SimpleDateFormat("yyyy.MM.dd"); private JSONObject downloadFileConfig; @@ -93,8 +94,6 @@ public class UpdateMainDialog extends UIDialog { private LoadingLabel loadingLabel; //更新按钮 private UIButton updateButton; - //有新版本提示标签 - private UILabel updateLabel; //jar包版本信息面板,包括当前版本和最新版本 private JPanel jarVersionInfoPane; @@ -157,13 +156,8 @@ public class UpdateMainDialog extends UIDialog { progressBar.setStringPainted(true); progressBar.setPreferredSize(PROGRESSBAR); - updateLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_New_Version_Available")); - updateLabel.setHorizontalAlignment(SwingConstants.RIGHT); - updateLabel.setVisible(false); - progressBarPane.add(GUICoreUtils.createBorderLayoutPane( - progressBar, BorderLayout.CENTER, - updateLabel, BorderLayout.EAST + progressBar, BorderLayout.CENTER ), BorderLayout.CENTER); updateActionPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ @@ -183,9 +177,9 @@ public class UpdateMainDialog extends UIDialog { double[] rowUpdatePaneSize = {UPDATE_PANE_ROW_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED}; double[] columnUpdatePaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; double[] rowUpdateContentPaneSize = {TableLayout.PREFERRED}; - double[] columnUpdateContentPaneSize = {TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}; + double[] columnUpdateContentPaneSize = {TableLayout.PREFERRED, TableLayout.FILL}; double[] rowUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_ROW_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, UPDATE_CONTENT_PANE_ROW_SIZE}; - double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.FILL, TableLayout.PREFERRED}; + double[] columnUpdateSubContentPaneSize = {UPDATE_CONTENT_PANE_COLUMN_SIZE, TableLayout.PREFERRED, TableLayout.PREFERRED}; double[] columnUpdateSubContentPaneLabelSize = {UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE, TableLayout.PREFERRED}; JPanel jarUpdateContentPane = new JPanel(); @@ -195,15 +189,15 @@ public class UpdateMainDialog extends UIDialog { JPanel jarUpdateContentPane2 = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ new Component[]{new UILabel(), new UILabel(), new UILabel()}, new Component[]{new UILabel(), updateVersionReminderPane, new UILabel()}, - new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_JAR_Version")), jarCurrentLabel), new UILabel()}, - new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Latest_JAR")), loadingLabel), new UILabel()}, + new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_JAR_Version")), jarCurrentLabel), jarRestoreLabel}, + new Component[]{new UILabel(), initPaneContent(Color.WHITE, rowUpdateContentPaneSize, columnUpdateSubContentPaneLabelSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Latest_JAR")), loadingLabel), + getNewFeatureActionLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Latest_Feature_Detail"))}, new Component[]{new UILabel(), new UILabel(), new UILabel()} }, rowUpdateSubContentPaneSize, columnUpdateSubContentPaneSize, LayoutConstants.VGAP_LARGE); jarUpdateContentPane2.setBackground(Color.WHITE); jarUpdateContentPane.add(jarUpdateContentPane2); jarVersionInfoPane = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{ new Component[]{new UILabel(), new UILabel(), new UILabel()}, - new Component[]{new UILabel(), initPaneContent(getBackground(), rowUpdateContentPaneSize, columnUpdateContentPaneSize, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_JarUpdate")), new UILabel(), jarRestoreLabel), new UILabel()}, new Component[]{new UILabel(), jarUpdateContentPane, new UILabel()} }, rowUpdatePaneSize, columnUpdatePaneSize, LayoutConstants.VGAP_LARGE); } @@ -221,7 +215,7 @@ public class UpdateMainDialog extends UIDialog { new Component[]{new UILabel(), new UILabel(), new UILabel()} }, searchRow, searchColumn, LayoutConstants.VGAP_LARGE); - String[] columnNames = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Date"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Content"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_SignHeader")}; + String[] columnNames = {com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Date"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Version"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Content"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_SignHeader")}; initUpdateInfoTable(columnNames); UIScrollPane uiScrollPane = new UIScrollPane(updateInfoTable); @@ -232,31 +226,32 @@ public class UpdateMainDialog extends UIDialog { } private void initUpdateInfoTable(String[] columnNames) { - int updateTimeColIndex = 0; - int updateTitleColIndex = 1; - int updateSignColIndex = 2; - updateInfoTable = new UpdateInfoTable(columnNames); updateInfoTable.setShowGrid(false); updateInfoTable.setCellSelectionEnabled(false); TableRowSorter sorter = new TableRowSorter<>(updateInfoTable.getDataModel()); - sorter.setSortable(updateTimeColIndex, true); - sorter.setSortable(updateTitleColIndex, false); - sorter.setSortable(updateSignColIndex, false); + sorter.setSortable(UpdateInfoTable.UPDATE_DATE_INDEX, true); + sorter.setSortable(UpdateInfoTable.UPDATE_VERSION_INDEX, true); + sorter.setSortable(UpdateInfoTable.UPDATE_TITLE_INDEX, false); + sorter.setSortable(UpdateInfoTable.SIGN_INDEX, false); updateInfoTable.setRowSorter(sorter); List sortKeys = new ArrayList<>(); - sortKeys.add(new RowSorter.SortKey(updateTimeColIndex, SortOrder.DESCENDING)); + sortKeys.add(new RowSorter.SortKey(UpdateInfoTable.UPDATE_DATE_INDEX, SortOrder.DESCENDING)); + sortKeys.add(new RowSorter.SortKey(UpdateInfoTable.UPDATE_VERSION_INDEX, SortOrder.DESCENDING)); sorter.setSortKeys(sortKeys); updateInfoTable.getTableHeader().setReorderingAllowed(false); - updateInfoTable.getColumnModel().getColumn(updateTimeColIndex).setMaxWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); - updateInfoTable.getColumnModel().getColumn(updateTimeColIndex).setMinWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); - updateInfoTable.getColumnModel().getColumn(updateSignColIndex).setMaxWidth(0); - updateInfoTable.getColumnModel().getColumn(updateSignColIndex).setMinWidth(0); - updateInfoTable.getTableHeader().getColumnModel().getColumn(updateSignColIndex).setMaxWidth(0); - updateInfoTable.getTableHeader().getColumnModel().getColumn(updateSignColIndex).setMinWidth(0); + updateInfoTable.getColumnModel().getColumn(UpdateInfoTable.UPDATE_DATE_INDEX).setMaxWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); + updateInfoTable.getColumnModel().getColumn(UpdateInfoTable.UPDATE_DATE_INDEX).setMinWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); + updateInfoTable.getColumnModel().getColumn(UpdateInfoTable.UPDATE_VERSION_INDEX).setMaxWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); + updateInfoTable.getColumnModel().getColumn(UpdateInfoTable.UPDATE_VERSION_INDEX).setMinWidth(UPDATE_INFO_TABLE_HEADER_TIME_WIDTH); + updateInfoTable.getColumnModel().getColumn(UpdateInfoTable.SIGN_INDEX).setMaxWidth(0); + updateInfoTable.getColumnModel().getColumn(UpdateInfoTable.SIGN_INDEX).setMinWidth(0); + updateInfoTable.getTableHeader().getColumnModel().getColumn(UpdateInfoTable.SIGN_INDEX).setMaxWidth(0); + updateInfoTable.getTableHeader().getColumnModel().getColumn(UpdateInfoTable.SIGN_INDEX).setMinWidth(0); updateInfoTable.getColumn(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Date")).setCellRenderer(new UpdateInfoTableCellRender()); + updateInfoTable.getColumn(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Version")).setCellRenderer(new UpdateInfoTableCellRender()); updateInfoTable.getColumn(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Content")).setCellRenderer(new UpdateInfoTextAreaCellRender()); } @@ -300,18 +295,18 @@ public class UpdateMainDialog extends UIDialog { updateButton.setEnabled(false); double[] rowSize = {TableLayout.PREFERRED}; + double[] colSize = {TableLayout.PREFERRED}; + UILabel versionLabel = new UILabel(UpdateConstants.DEFAULT_APP_NAME + StringUtils.BLANK + ProductConstants.VERSION); + versionLabel.setFont(new Font("Default", Font.BOLD, 16)); + - double[] colSize = {UPDATE_CONTENT_PANE_LABEL_COLUMN_SIZE, TableLayout.PREFERRED}; updateVersionReminderPane = initPaneContent( - Color.WHITE, rowSize, colSize, - new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Designer_Version")), - new UILabel(UpdateConstants.DEFAULT_APP_NAME + StringUtils.BLANK + ProductConstants.VERSION) + Color.WHITE, rowSize, colSize, versionLabel ); String notInstallVersion = InterProviderFactory.getProvider().getLocText("Fine-Core_Basic_About_No_Build"); String versionBuildNo = GeneralUtils.getVersion() + HYPHEN + GeneralUtils.readBuildNO(); jarCurrentLabel = new UILabel(ComparatorUtils.equals(notInstallVersion, GeneralUtils.readBuildNO()) ? notInstallVersion : versionBuildNo, SwingConstants.CENTER); - UILabel noJarPreviousRevision = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_No_Previous_Version")); UpdateActionLabel jarRestorePreviousRevision = new UpdateActionLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Restore"), false); jarRestorePreviousRevision.setForeground(new Color(RESTORE_LABEL_COLOR)); jarRestorePreviousRevision.addActionListener(new ActionListener() { @@ -323,7 +318,7 @@ public class UpdateMainDialog extends UIDialog { }); //choose RestoreLabel to show boolean isNeedRestore = ArrayUtils.isNotEmpty(UpdateFileUtils.listBackupVersions()); - jarRestoreLabel = isNeedRestore ? jarRestorePreviousRevision : noJarPreviousRevision; + jarRestoreLabel = isNeedRestore ? jarRestorePreviousRevision : null; } private void initComponents() { @@ -417,18 +412,25 @@ public class UpdateMainDialog extends UIDialog { if (downloadFileConfig == null) { throw new Exception("network error."); } - HttpGet get = new HttpGet(CloudCenter.getInstance().acquireUrlByKind("changelog10") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr()); - httpClient = HttpToolbox.getHttpClient(CloudCenter.getInstance().acquireUrlByKind("changelog10") + "&start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr()); + + HttpGet get = new HttpGet(CloudCenter.getInstance().acquireUrlByKind("updatelog") + "?start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr()); + httpClient = HttpToolbox.getHttpClient(CloudCenter.getInstance().acquireUrlByKind("updatelog") + "?start=" + lastUpdateCacheTime + "&end=" + getLatestJARTimeStr()); + + response = httpClient.execute(get); String responseText = CommonIOUtils.inputStream2String(response.getEntity().getContent(),EncodeConstants.ENCODING_UTF_8).trim(); + JSONArray array = JSONArray.create(); //假如返回"-1",说明socket出错了 if (!ComparatorUtils.equals(responseText, "-1")) { - array = new JSONArray(responseText); + JSONObject respObject = new JSONObject(responseText); + if (respObject != null && "success".equals(respObject.get("status"))) { + array = respObject.getJSONArray("data"); + } } return array; } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage()); + FineLoggerFactory.getLogger().error(e, e.getMessage()); } return JSONArray.create(); } @@ -445,7 +447,7 @@ public class UpdateMainDialog extends UIDialog { updateCachedInfoFile(jsonArray); } catch (Exception e) { getUpdateInfoSuccess = true; - FineLoggerFactory.getLogger().error(e.getMessage()); + FineLoggerFactory.getLogger().error(e, e.getMessage()); } } }; @@ -459,7 +461,7 @@ public class UpdateMainDialog extends UIDialog { } //从文件中读取缓存的更新信息 - private void getCachedUpdateInfo(String keyword) throws Exception { + private void getCachedUpdateInfo(String keyword) { String cacheInfoPath = getUpdateCacheInfo(); File cacheFile = new File(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), "resources", "offlineres", cacheInfoPath)); if (!ComparatorUtils.equals(lastUpdateCacheState, "success")) { @@ -472,22 +474,27 @@ public class UpdateMainDialog extends UIDialog { String readStr, updateTimeStr; while ((readStr = br.readLine()) != null) { String[] updateInfo = readStr.split("\\t"); - if (updateInfo.length == 2) { - updateTimeStr = updateInfo[0]; - Date updateTime = CHANGELOG_FORMAT.parse(updateTimeStr); + if (updateInfo.length == 3) { + updateTimeStr = updateInfo[UpdateInfoTable.UPDATE_DATE_INDEX]; + Date updateTime = UPDATELOG_FORMAT.parse(updateTimeStr); + + //形如 Build#release-2018.07.31.03.03.52.80 String currentNO = GeneralUtils.readBuildNO(); Date curJarDate = UPDATE_INFO_TABLE_FORMAT.parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); if (!ComparatorUtils.equals(keyword, StringUtils.EMPTY)) { - if (!containsKeyword(UPDATE_INFO_TABLE_FORMAT.format(updateTime), keyword) && !containsKeyword(updateInfo[1], keyword)) { + keyword.replace('.','-'); + if (!containsKeyword(UPDATELOG_FORMAT.format(updateTime), keyword) && !containsKeyword(updateInfo[UpdateInfoTable.UPDATE_TITLE_INDEX], keyword)) { continue; } } - if (isValidLogInfo(updateInfo[1])) { - updateInfoList.add(new Object[]{UPDATE_INFO_TABLE_FORMAT.format(updateTime), updateInfo[1], updateTime.after(curJarDate)}); + if (isValidLogInfo(updateInfo[UpdateInfoTable.UPDATE_TITLE_INDEX]) && curJarDate != null) { + updateInfoList.add(new Object[]{UPDATELOG_FORMAT.format(updateTime), updateInfo[UpdateInfoTable.UPDATE_VERSION_INDEX], updateInfo[UpdateInfoTable.UPDATE_TITLE_INDEX], updateTime.after(curJarDate)}); } } } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); } } } @@ -516,7 +523,7 @@ public class UpdateMainDialog extends UIDialog { try (BufferedWriter bufferWriter = new BufferedWriter(writerStream)) { for (int i = 0; i < jsonArray.length(); i++) { JSONObject jo = (JSONObject) jsonArray.get(i); - bufferWriter.write((String) jo.get("update") + '\t' + jo.get("title")); + bufferWriter.write((String) jo.get("updateTime") + '\t' + jo.get("version") + '\t' + jo.get("jiraId") + " " + jo.get("info")); bufferWriter.newLine(); bufferWriter.flush(); } @@ -531,22 +538,24 @@ public class UpdateMainDialog extends UIDialog { private ArrayList generateUpdateInfoList(JSONArray jsonArray, String keyword) throws Exception { for (int i = 0; i < jsonArray.length(); i++) { JSONObject jo = (JSONObject) jsonArray.get(i); - String updateTitle = (String) jo.get("title"); - String updateTimeStr = (String) jo.get("update"); - Date updateTime = CHANGELOG_FORMAT.parse(updateTimeStr); + String updateTitle = (String) jo.get("jiraId") + " " + jo.get("info"); + String updateVersionStr = (String) jo.get("version"); + String updateTimeStr = (String) jo.get("updateTime"); + Date updateTime = UPDATELOG_FORMAT.parse(updateTimeStr); //形如 Build#release-2018.07.31.03.03.52.80 String currentNO = GeneralUtils.readBuildNO(); Date curJarDate = UPDATE_INFO_TABLE_FORMAT.parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); if (curJarDate == null) { curJarDate = updateTime; } - if (!ComparatorUtils.equals(keyword, StringUtils.EMPTY)) { - if (!containsKeyword(UPDATE_INFO_TABLE_FORMAT.format(updateTime), keyword) && !containsKeyword(updateTitle, keyword)) { + if (!ComparatorUtils.equals(keyword, StringUtils.EMPTY) && keyword != null) { + keyword.replace('.', '-'); + if (!containsKeyword(UPDATELOG_FORMAT.format(updateTime), keyword) && !containsKeyword(updateTitle, keyword)) { continue; } } if (isValidLogInfo(updateTitle)) { - updateInfoList.add(new Object[]{UPDATE_INFO_TABLE_FORMAT.format(updateTime), updateTitle, updateTime.after(curJarDate)}); + updateInfoList.add(new Object[]{updateTimeStr, updateVersionStr, updateTitle, updateTime.after(curJarDate)}); } } return new ArrayList<>(updateInfoList); @@ -579,14 +588,12 @@ public class UpdateMainDialog extends UIDialog { Date currentDate = (new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss")).parse(currentNO, new ParsePosition(currentNO.indexOf("-") + 1)); if (DateUtils.subtractDate(jarDate, currentDate, DateUtils.SECOND) > 0) { updateButton.setEnabled(true); - updateLabel.setVisible(true); loadingLabel.stopLoading(buildNO.contains("-") ? buildNO.substring(buildNO.lastIndexOf("-") + 1) : buildNO); } else { loadingLabel.stopLoading(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Updater_Already_Latest_Version")); } } else { updateButton.setEnabled(true); - updateLabel.setVisible(true); loadingLabel.stopLoading(buildNO.contains("-") ? buildNO.substring(buildNO.lastIndexOf("-") + 1) : buildNO); } @@ -608,41 +615,7 @@ public class UpdateMainDialog extends UIDialog { * jar包更新按钮监听器 */ private void addActionListenerForUpdateBtn() { - updateButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")}; - int a = JOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Information"), - Toolkit.i18nText("Fine-Design_Update_Info_Title"),JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, UIManager.getIcon("OptionPane.warningIcon"), option, 1); - if (a == 0) { - progressBar.setVisible(true); - progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message")); - UpdateCallBack callBack = new UpdateProgressCallBack(progressBar); - updateButton.setEnabled(false); - updateLabel.setVisible(false); - RestoreResultDialog.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 FileProcess(callBack) { - @Override - public void onDownloadSuccess() { - progressBar.setVisible(false); - deleteForDesignerUpdate(installLib); - helper.restartForUpdate(frame); - } - @Override - public void onDownloadFailed() { - progressBar.setVisible(false); - deleteForDesignerUpdate(installLib); - FineJOptionPane.showMessageDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Failed_Message")); - helper.restartForUpdate(frame); - } - }.execute(); - } - } - }); + updateButton.addActionListener(new UpdateAction()); } private void deleteForDesignerUpdate(String installLib) { @@ -688,6 +661,13 @@ public class UpdateMainDialog extends UIDialog { return false; } + private ActionLabel getNewFeatureActionLabel(final String text){ + ActionLabel actionLabel = new ActionLabel(text, new Color(RESTORE_LABEL_COLOR)); + actionLabel.setDrawUnderLine(false); + actionLabel.addActionListener(new NewFeatureAction()); + return actionLabel; + } + /** * 显示窗口 */ @@ -705,4 +685,41 @@ public class UpdateMainDialog extends UIDialog { @Override public void checkValid() throws Exception { } -} \ No newline at end of file + + + private class UpdateAction implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")}; + int a = JOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Information"), + Toolkit.i18nText("Fine-Design_Update_Info_Title"),JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, UIManager.getIcon("OptionPane.warningIcon"), option, 1); + if (a == 0) { + progressBar.setVisible(true); + progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message")); + UpdateCallBack callBack = new UpdateProgressCallBack(progressBar); + updateButton.setEnabled(false); + RestoreResultDialog.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 FileProcess(callBack) { + @Override + public void onDownloadSuccess() { + progressBar.setVisible(false); + deleteForDesignerUpdate(installLib); + helper.restartForUpdate(frame); + } + @Override + public void onDownloadFailed() { + progressBar.setVisible(false); + deleteForDesignerUpdate(installLib); + FineJOptionPane.showMessageDialog(getParent(), Toolkit.i18nText("Fine-Design_Update_Info_Failed_Message")); + helper.restartForUpdate(frame); + } + }.execute(); + } + + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTable.java b/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTable.java index c7690f3d55..1b704826f7 100644 --- a/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTable.java +++ b/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTable.java @@ -10,6 +10,12 @@ import java.util.Vector; * Created by XINZAI on 2018/8/21. */ public class UpdateInfoTable extends JTable { + + public static int UPDATE_DATE_INDEX = 0; + public static int UPDATE_VERSION_INDEX = 1; + public static int UPDATE_TITLE_INDEX = 2; + public static int SIGN_INDEX = 3; + private UpdateInfoTableModel dataModel; public UpdateInfoTable(TableModel dm) { diff --git a/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTableCellRender.java b/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTableCellRender.java index 9a853762e8..21998babad 100644 --- a/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTableCellRender.java +++ b/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTableCellRender.java @@ -18,11 +18,11 @@ public class UpdateInfoTableCellRender extends DefaultTableCellRenderer { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); cell.setBackground((row & 1) != 0 ? new Color(0xf0f0f0) : Color.WHITE); - if ((Boolean) table.getValueAt(row, 2)) { + if ((Boolean) table.getValueAt(row, UpdateInfoTable.SIGN_INDEX)) { cell.setBackground(new Color(0xdfecfd)); } - if (column == 0) { - //设置首列日期居中显示 + if (column == UpdateInfoTable.UPDATE_DATE_INDEX || column == UpdateInfoTable.UPDATE_VERSION_INDEX) { + //设置日期,版本居中显示 setHorizontalAlignment(JLabel.CENTER); for (int i = 1; row - i >= 0; i++) { diff --git a/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTextAreaCellRender.java b/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTextAreaCellRender.java index 4f9836d4c4..93edd98392 100644 --- a/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTextAreaCellRender.java +++ b/designer-base/src/main/java/com/fr/design/update/ui/widget/UpdateInfoTextAreaCellRender.java @@ -35,9 +35,9 @@ public class UpdateInfoTextAreaCellRender extends JTextArea implements TableCell setText(value == null ? "" : value.toString()); setBackground((row & 1) != 0 ? new Color(0xf0f0f0) : Color.WHITE); - if ((Boolean) table.getValueAt(row, 2)) { + if ((Boolean) table.getValueAt(row, UpdateInfoTable.SIGN_INDEX)) { setBackground(new Color(0xdfecfd)); } return this; } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java b/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java index 739d394720..7c0daa111f 100644 --- a/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java @@ -27,4 +27,15 @@ public class ColorUtils { } } } + + public static boolean isDarkColor(Color color) { + if(color == null) { + return false; + } + int red = color.getRed(); + int green = color.getGreen(); + int blue = color.getBlue(); + int greyLevel = (int)(red * 0.299 + green * 0.587 + blue * 0.114); + return greyLevel < 192; + } } diff --git a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java index f9fb484a6a..67fb918666 100644 --- a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java @@ -24,18 +24,16 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.os.OperatingSystem; import com.fr.start.ServerStarter; +import com.fr.start.common.DesignerStartupContext; +import com.fr.startup.ui.StartupPageModel; import com.fr.value.NotNullLazyValue; import com.fr.workspace.WorkContext; import org.jetbrains.annotations.NotNull; import javax.swing.SwingUtilities; import javax.swing.UIManager; -import java.awt.Color; import java.awt.Desktop; import java.awt.Font; -import java.awt.Frame; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -50,6 +48,7 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.Locale; +import java.util.Optional; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -216,6 +215,28 @@ public class DesignUtils { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { + DesignerStartupContext context = DesignerStartupContext.getInstance(); + // 如果在启动页展示中 + if (context.isOnWaiting()) { + FileFILE fileFILE = new FileFILE(f); + // 设置上一次启动模板为 + DesignerEnvManager.getEnvManager().setLastOpenFile(fileFILE.getPath()); + StartupPageModel model = context.getStartupPageModel(); + Optional.ofNullable(model) + .ifPresent((e) -> { + // 执行上一次模板的启动 + Runnable openLastTemplateRunnable = e.getOpenLastTemplateRunnable(); + openLastTemplateRunnable.run(); + }); + return; + } + // 如果是在启动中 + if (context.isOnStartup()) { + // 之前就有这样的问题 + return; + } + + // 打开模板 DesignerContext.getDesignerFrame().openTemplate(new FileFILE(f)); } }); diff --git a/designer-base/src/main/java/com/fr/design/widget/component/CheckBoxDictPane.java b/designer-base/src/main/java/com/fr/design/widget/component/ReturnTypePane.java similarity index 50% rename from designer-base/src/main/java/com/fr/design/widget/component/CheckBoxDictPane.java rename to designer-base/src/main/java/com/fr/design/widget/component/ReturnTypePane.java index 9a76352f94..4f3b93a539 100644 --- a/designer-base/src/main/java/com/fr/design/widget/component/CheckBoxDictPane.java +++ b/designer-base/src/main/java/com/fr/design/widget/component/ReturnTypePane.java @@ -1,32 +1,29 @@ package com.fr.design.widget.component; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - import com.fr.design.designer.IntervalConstants; import com.fr.design.gui.ibutton.UIButtonGroup; -import com.fr.design.gui.ilable.UILabel; - -import javax.swing.*; - import com.fr.design.gui.icombobox.DictionaryComboBox; import com.fr.design.gui.icombobox.DictionaryConstants; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; -import com.fr.form.ui.CheckBoxGroup; -import com.fr.form.ui.ComboCheckBox; +import com.fr.form.ui.ReturnTypeProvider; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; + +public class ReturnTypePane extends JPanel { -public class CheckBoxDictPane extends JPanel { - - private DictionaryComboBox delimiterComboBox; - private UIButtonGroup returnTypeComboBox; - private DictionaryComboBox startComboBox; - private DictionaryComboBox endComboBox; - private JPanel returnStringPane; - - public CheckBoxDictPane() { + private final DictionaryComboBox delimiterComboBox; + private final UIButtonGroup returnTypeComboBox; + private final DictionaryComboBox startComboBox; + private final DictionaryComboBox endComboBox; + private final JPanel returnStringPane; + + public ReturnTypePane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); delimiterComboBox = new DictionaryComboBox(DictionaryConstants.delimiters, DictionaryConstants.delimiterDisplays); delimiterComboBox.setEditable(true); @@ -36,18 +33,13 @@ public class CheckBoxDictPane extends JPanel { endComboBox.setEditable(true); Component[][] components = new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Delimiter")), delimiterComboBox}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Combo_CheckBox_Start_Symbol")),startComboBox}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Combo_CheckBox_End_Symbol")),endComboBox} + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Combo_CheckBox_Start_Symbol")), startComboBox}, + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Combo_CheckBox_End_Symbol")), endComboBox} }; returnStringPane = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W2, IntervalConstants.INTERVAL_L1); returnTypeComboBox = new UIButtonGroup(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Array"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_String")}); - returnTypeComboBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - checkVisible(returnTypeComboBox.getSelectedIndex()); - } - }); + returnTypeComboBox.addActionListener(e -> checkVisible(returnTypeComboBox.getSelectedIndex())); JPanel headPane = TableLayoutHelper.createGapTableLayoutPane( new Component[][]{new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Date_Selector_Return_Type")), returnTypeComboBox}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L2, IntervalConstants.INTERVAL_L1); JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); @@ -57,34 +49,33 @@ public class CheckBoxDictPane extends JPanel { this.add(jPanel); } - public void checkVisible(int selectIndex){ - returnStringPane.setVisible(selectIndex == 1); + public void setReturnType(ReturnType returnType) { + int selectIndex = returnType == ReturnType.ARRAY ? 0 : 1; + returnTypeComboBox.setSelectedIndex(selectIndex,true); + checkVisible(selectIndex); } - public void populate(ComboCheckBox comboCheckBox) { - this.delimiterComboBox.setSelectedItem(comboCheckBox.getDelimiter()); - this.returnTypeComboBox.setSelectedIndex(comboCheckBox.isReturnString() ? 1 : 0); - this.startComboBox.setSelectedItem(comboCheckBox.getStartSymbol()); - this.endComboBox.setSelectedItem(comboCheckBox.getEndSymbol()); - checkVisible(this.returnTypeComboBox.getSelectedIndex()); + public void checkVisible(int selectIndex) { + returnStringPane.setVisible(selectIndex == 1); } - public void update(ComboCheckBox comboCheckBox) { - comboCheckBox.setDelimiter((String)this.delimiterComboBox.getSelectedItem()); - comboCheckBox.setReturnString(this.returnTypeComboBox.getSelectedIndex() != 0); - comboCheckBox.setStartSymbol((String)this.startComboBox.getSelectedItem()); - comboCheckBox.setEndSymbol((String)this.endComboBox.getSelectedItem()); + + public void update(ReturnTypeProvider returnTypeProvider) { + returnTypeProvider.setDelimiter((String) this.delimiterComboBox.getSelectedItem()); + returnTypeProvider.setReturnString(this.returnTypeComboBox.getSelectedIndex() != 0); + returnTypeProvider.setStartSymbol((String) this.startComboBox.getSelectedItem()); + returnTypeProvider.setEndSymbol((String) this.endComboBox.getSelectedItem()); } - public void populate(CheckBoxGroup checkBoxGroup) { - this.delimiterComboBox.setSelectedItem(checkBoxGroup.getDelimiter()); - this.returnTypeComboBox.setSelectedIndex(checkBoxGroup.isReturnString() ? 1 : 0); - this.startComboBox.setSelectedItem(checkBoxGroup.getStartSymbol()); - this.endComboBox.setSelectedItem(checkBoxGroup.getEndSymbol()); + + public void populate(ReturnTypeProvider returnTypeProvider) { + this.delimiterComboBox.setSelectedItem(returnTypeProvider.getDelimiter()); + this.returnTypeComboBox.setSelectedIndex(returnTypeProvider.isReturnString() ? 1 : 0); + this.startComboBox.setSelectedItem(returnTypeProvider.getStartSymbol()); + this.endComboBox.setSelectedItem(returnTypeProvider.getEndSymbol()); checkVisible(this.returnTypeComboBox.getSelectedIndex()); } - public void update(CheckBoxGroup checkBoxGroup) { - checkBoxGroup.setDelimiter((String)this.delimiterComboBox.getSelectedItem()); - checkBoxGroup.setReturnString(this.returnTypeComboBox.getSelectedIndex() != 0); - checkBoxGroup.setStartSymbol((String)this.startComboBox.getSelectedItem()); - checkBoxGroup.setEndSymbol((String)this.endComboBox.getSelectedItem()); + + public enum ReturnType { + STRING, + ARRAY } } diff --git a/designer-base/src/main/java/com/fr/start/BaseDesigner.java b/designer-base/src/main/java/com/fr/start/BaseDesigner.java index 97355c8fea..89c928e2c4 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java @@ -3,7 +3,6 @@ */ package com.fr.start; -import com.fr.base.extension.FileExtension; import com.fr.common.report.ReportState; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; @@ -15,6 +14,7 @@ import com.fr.design.fun.DesignerStartOpenFileProcessor; import com.fr.design.fun.impl.DesignerStartWithEmptyFile; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.toolbar.ToolBarMenuDock; import com.fr.design.monitor.DesignerLifecycleMonitorContext; import com.fr.design.ui.util.UIUtil; @@ -26,18 +26,17 @@ import com.fr.event.Null; import com.fr.exit.DesignerExiter; import com.fr.file.FILE; import com.fr.file.FILEFactory; -import com.fr.file.FileFILE; -import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.process.ProcessEventPipe; import com.fr.process.engine.core.CarryMessageEvent; import com.fr.process.engine.core.FineProcessContext; import com.fr.stable.OperatingSystem; +import com.fr.start.common.DesignerStartupContext; +import com.fr.start.common.DesignerStartupUtil; import com.fr.start.event.LazyStartupEvent; import com.fr.workspace.base.WorkspaceStatus; import java.awt.Window; -import java.io.File; import java.lang.reflect.Method; /** @@ -124,24 +123,14 @@ public abstract class BaseDesigner extends ToolBarMenuDock { try { FILE file = null; if (args != null && args.length > 0) { - // p:需要打开这个报表文件,这个代码不能删除. - for (String arg : args) { - if (ComparatorUtils.equals("demo", arg)) { - file = FILEFactory.createFILE(FILEFactory.ENV_PREFIX + DesignerEnvManager.getEnvManager().getLastOpenFile()); - break; - } - File f = new File(arg); - String path = f.getAbsolutePath(); - if (isAcceptFilePathEnd(path)) { - file = new FileFILE(f); - } - } + file = DesignerStartupUtil.convertArgs2FILE(args); } else { file = FILEFactory.createFILE(FILEFactory.ENV_PREFIX + DesignerEnvManager.getEnvManager().getLastOpenFile()); } DesignerFrame df = DesignerContext.getDesignerFrame(); isException = openFile(df, isException, file); df.fireDesignerOpened(); + FineLoggerFactory.getLogger().debug("show designer cost {} ms", DesignerStartupContext.getRecorder().getTime()); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); if (!isException) { @@ -152,21 +141,6 @@ public abstract class BaseDesigner extends ToolBarMenuDock { } } - private boolean isAcceptFilePathEnd(String path) { - FileExtension[] acceptFileExtensions = new FileExtension[]{ - FileExtension.CPT, FileExtension.XLS, FileExtension.XLSX, FileExtension.FRM, FileExtension.CHT, FileExtension.VIS - }; - for (FileExtension acceptFileExtension : acceptFileExtensions) { - String[] extensions = acceptFileExtension.getExtensions(); - for (String extension : extensions) { - if (path.endsWith("." + extension)) { - return true; - } - } - } - return false; - } - private boolean openFile(final DesignerFrame df, boolean isException, FILE file) { //启动时打开指定文件的接口 @@ -183,19 +157,52 @@ public abstract class BaseDesigner extends ToolBarMenuDock { isException = true;//此时有文件nullpointer异常,执行打开空文件 } } + + openTemplate(df, isException, file); + + if (OperatingSystem.isMacOS()) { + enableFullScreenMode(df); + } + + JTemplate selectedJTemplate = df.getSelectedJTemplate(); + if (selectedJTemplate != null) { + selectedJTemplate.requestGridFocus(); + } + return isException; + } + + private void openTemplate(DesignerFrame df, boolean isException, FILE file) { + + boolean onStartup = DesignerStartupContext.getInstance().isSupport(); + if (onStartup) { + DesignerStartupContext context = DesignerStartupContext.getInstance(); + if (context.isCreateNew()) { + df.addAndActivateJTemplate(); + // 如果没有模板,则需要确认一下 + MutilTempalteTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); + return; + } + if (context.isOpenLastFile()) { + if (file != null && file.exists() && !isException) { + df.openTemplate(file); + return; + } + } + if (context.isOpenEmpty()) { + df.showEmptyJTemplate(); + return; + } + } + if (file != null && file.exists() && !isException) { df.openTemplate(file); } else { df.addAndActivateJTemplate(); + // 如果没有模板,则需要确认一下 MutilTempalteTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); } - if (OperatingSystem.isMacOS()) { - enableFullScreenMode(df); - } - df.getSelectedJTemplate().requestGridFocus(); - return isException; } - + private void enableFullScreenMode(Window window) { String className = "com.apple.eawt.FullScreenUtilities"; String methodName = "setWindowCanFullScreen"; diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java b/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java new file mode 100644 index 0000000000..e89598ae27 --- /dev/null +++ b/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java @@ -0,0 +1,77 @@ +package com.fr.start.common; + +import com.fr.base.svg.IconUtils; +import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.file.MutilTempalteTabPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.DesignSizeI18nManager; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.utils.ColorUtils; + +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * created by Harrison on 2022/07/09 + **/ +public class DesignerOpenEmptyPanel extends JPanel { + + private static final Color BUTTON_COLOR = new Color(63, 155, 249); + private static final int ARC = 4; + + private final JPanel body; + + public DesignerOpenEmptyPanel() { + + this.body = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + UILabel createIcon = new UILabel(IconUtils.readIcon("/com/fr/design/startup/create_new_template.svg")); + JButton createButton = new JButton(Toolkit.i18nText("Fine-Design_New_Template")) { + @Override + public void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setColor(BUTTON_COLOR); + g2d.fillRoundRect(0, 0, getWidth(), getHeight(), ARC, ARC); + super.paintComponent(g2d); + } + }; + createButton.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.start.common.DesignerOpenEmptyPanel.createButton")); + createButton.setForeground(Color.WHITE); + createButton.setBorderPainted(false); + createButton.setContentAreaFilled(false); + createButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + DesignerFrame df = DesignerContext.getDesignerFrame(); + df.addAndActivateJTemplate(); + // 如果没有模板,则需要确认一下 + MutilTempalteTabPane.getInstance().setTemTemplate(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()); + } + }); + createButton.setBorder(new EmptyBorder(0, 10, 0, 10)); + JPanel createButtonPanel = new JPanel(FRGUIPaneFactory.createCenterFlowLayout()); + createButtonPanel.add(createButton); + createButtonPanel.setBorder(new EmptyBorder(0, 0, 0, 0)); + createButtonPanel.setBackground(Color.WHITE); + this.body.add(createIcon, BorderLayout.NORTH); + this.body.add(createButtonPanel, BorderLayout.SOUTH); + + setLayout(FRGUIPaneFactory.createCenterLayout(this.body)); + + ColorUtils.syncBackground(this, Color.WHITE); + + add(this.body); + } +} diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupConfig.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupConfig.java new file mode 100644 index 0000000000..5aae98f03e --- /dev/null +++ b/designer-base/src/main/java/com/fr/start/common/DesignerStartupConfig.java @@ -0,0 +1,55 @@ +package com.fr.start.common; + +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; + +public class DesignerStartupConfig implements XMLable { + + public static final String XML_TAG = "DesignerStartupConfig"; + + private static final long serialVersionUID = -8170289826729582122L; + + private static final DesignerStartupConfig INSTANCE = new DesignerStartupConfig(); + + public static DesignerStartupConfig getInstance() { + + return INSTANCE; + } + + /** + * 默认值是 false + */ + private boolean enabled = false; + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + + @Override + public Object clone() throws CloneNotSupportedException { + DesignerStartupConfig config = new DesignerStartupConfig(); + config.setEnabled(true); + return config; + } + + @Override + public void readXML(XMLableReader reader) { + if (reader.isAttr()) { + this.setEnabled(reader.getAttrAsBoolean("isEnabled", false)); + } + } + + @Override + public void writeXML(XMLPrintWriter writer) { + writer.startTAG(XML_TAG); + writer.attr("isEnabled", this.isEnabled()); + writer.end(); + } + +} diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupContext.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupContext.java new file mode 100644 index 0000000000..b996fbe4b7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/start/common/DesignerStartupContext.java @@ -0,0 +1,176 @@ +package com.fr.start.common; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.DesignerWorkspaceType; +import com.fr.start.module.StartupArgs; +import com.fr.startup.ui.StartupPageModel; +import com.fr.third.guava.collect.Lists; +import com.fr.third.org.apache.commons.lang3.time.StopWatch; + +import java.util.ArrayList; +import java.util.Iterator; + +/** + * 启动页上下文 + * + * created by Harrison on 2022/06/22 + **/ +public class DesignerStartupContext { + + /** + * 启动参数 + */ + private StartupArgs startupArgs; + + /** + * 启动数据 + */ + private StartupPageModel startupPageModel; + + /** + * 是否在起始页打开的等待过程中 + */ + private boolean onWaiting = false; + + /** + * 是否在启动中 + */ + private boolean onStartup = true; + + /** + * 是否在预热中 + */ + private boolean onWarmup = false; + + /** + * 打开上一次的文件 + */ + private boolean openLastFile; + + /** + * 打开空设计器 + */ + private boolean openEmpty; + + /** + * 直接创建一个新模板 + */ + private boolean createNew; + + /** + * 时间记录 + */ + private static StopWatch STOP_WATCH = new StopWatch(); + + public static DesignerStartupContext getInstance() { + return StartupContextHolder.INSTANCE; + } + + private static class StartupContextHolder { + private static final DesignerStartupContext INSTANCE = new DesignerStartupContext(); + } + + public static StopWatch getRecorder() { + return STOP_WATCH; + } + + /* 启动模式 */ + + /** + * 展示启动页 + * 1. 判断当前的工作目录数量 + * 2. 判断是否是 demo、还是打开目标文件 + * 3. 功能是否开启 + * + * @return 是/否 + */ + public boolean isShowStartupPage() { + + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + Iterator envNameIterator = envManager.getEnvNameIterator(); + ArrayList envs = Lists.newArrayList(envNameIterator); + return !startupArgs.isDemo() && DesignerStartupUtil.convertArgs2FILE(startupArgs.get()) == null && !envs.isEmpty() && envManager.isStartupPageEnabled(); + } + + /* 预热相关 */ + + public boolean onWarmup() { + + return this.onWarmup; + } + + public boolean canWarmup() { + + String curEnvName = DesignerEnvManager.getEnvManager().getCurEnvName(); + DesignerWorkspaceInfo workspaceInfo = DesignerEnvManager.getEnvManager().getWorkspaceInfo(curEnvName); + return workspaceInfo.getType() == DesignerWorkspaceType.Local; + } + + public void setStartupPageModel(StartupPageModel startupPageModel) { + this.startupPageModel = startupPageModel; + } + + public StartupPageModel getStartupPageModel() { + + return startupPageModel; + } + + public boolean isOnWaiting() { + return onWaiting; + } + + public void setOnWaiting(boolean onWaiting) { + this.onWaiting = onWaiting; + } + + public boolean isSupport() { + return onStartup && isShowStartupPage(); + } + + public boolean isOnStartup() { + return onStartup; + } + + public void setOnStartup(boolean onStartup) { + this.onStartup = onStartup; + } + + /* 文件相关*/ + + public boolean isOpenLastFile() { + + return this.openLastFile; + } + + public boolean isOpenEmpty() { + + return this.openEmpty; + } + + /* set */ + + public void setOnWarmup(boolean onWarmup) { + this.onWarmup = onWarmup; + } + + public void setOpenLastFile(boolean openLastFile) { + this.openLastFile = openLastFile; + } + + public void setOpenEmpty(boolean openEmpty) { + this.openEmpty = openEmpty; + } + + public boolean isCreateNew() { + return createNew; + } + + public void setCreateNew(boolean createNew) { + this.createNew = createNew; + } + + public void setStartupArgs(StartupArgs startupArgs) { + this.startupArgs = startupArgs; + } +} diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupExecutor.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupExecutor.java new file mode 100644 index 0000000000..1a033e8cd2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/start/common/DesignerStartupExecutor.java @@ -0,0 +1,32 @@ +package com.fr.start.common; + +import java.util.ArrayList; +import java.util.List; + +/** + * created by Harrison on 2022/07/03 + **/ +public class DesignerStartupExecutor { + + private List warmupTasks = new ArrayList<>(); + + public void execute(Runnable runnable) { + + if (!DesignerStartupContext.getInstance().onWarmup()) { + runnable.run(); + } + } + + public void reset() { + + warmupTasks.clear(); + } + + public static DesignerStartupExecutor getInstance() { + return DesignerStartupExecutorHolder.INSTANCE; + } + + private static class DesignerStartupExecutorHolder { + private static final DesignerStartupExecutor INSTANCE = new DesignerStartupExecutor(); + } +} diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java new file mode 100644 index 0000000000..524c474df1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/start/common/DesignerStartupPool.java @@ -0,0 +1,20 @@ +package com.fr.start.common; + +import com.fr.concurrent.FineExecutors; +import com.fr.concurrent.NamedThreadFactory; + +import java.util.concurrent.Executor; + +/** + * created by Harrison on 2022/07/03 + **/ +public class DesignerStartupPool { + + private static final Executor COMMON_EXECUTOR = FineExecutors.newCachedThreadPool(new NamedThreadFactory("startup-common")); + + public static Executor common() { + + return COMMON_EXECUTOR; + } + +} diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupUtil.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupUtil.java new file mode 100644 index 0000000000..5bc55e80c5 --- /dev/null +++ b/designer-base/src/main/java/com/fr/start/common/DesignerStartupUtil.java @@ -0,0 +1,51 @@ +package com.fr.start.common; + +import com.fr.base.extension.FileExtension; +import com.fr.design.DesignerEnvManager; +import com.fr.file.FILE; +import com.fr.file.FILEFactory; +import com.fr.file.FileFILE; +import com.fr.general.ComparatorUtils; +import org.jetbrains.annotations.Nullable; + +import java.io.File; + +/** + * created by Harrison on 2022/07/09 + **/ +public class DesignerStartupUtil { + + @Nullable + public static FILE convertArgs2FILE(String[] args) { + + // p:需要打开这个报表文件,这个代码不能删除. + FILE file = null; + for (String arg : args) { + if (ComparatorUtils.equals("demo", arg)) { + file = FILEFactory.createFILE(FILEFactory.ENV_PREFIX + DesignerEnvManager.getEnvManager().getLastOpenFile()); + break; + } + File f = new File(arg); + String path = f.getAbsolutePath(); + if (isAcceptFilePathEnd(path)) { + file = new FileFILE(f); + } + } + return file; + } + + private static boolean isAcceptFilePathEnd(String path) { + FileExtension[] acceptFileExtensions = new FileExtension[]{ + FileExtension.CPT, FileExtension.XLS, FileExtension.XLSX, FileExtension.FRM, FileExtension.CHT, FileExtension.VIS + }; + for (FileExtension acceptFileExtension : acceptFileExtensions) { + String[] extensions = acceptFileExtension.getExtensions(); + for (String extension : extensions) { + if (path.endsWith("." + extension)) { + return true; + } + } + } + return false; + } +} diff --git a/designer-realize/src/main/java/com/fr/start/module/StartupArgs.java b/designer-base/src/main/java/com/fr/start/module/StartupArgs.java similarity index 100% rename from designer-realize/src/main/java/com/fr/start/module/StartupArgs.java rename to designer-base/src/main/java/com/fr/start/module/StartupArgs.java diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageConstants.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageConstants.java new file mode 100644 index 0000000000..ae27e1a9ef --- /dev/null +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageConstants.java @@ -0,0 +1,17 @@ +package com.fr.startup.ui; + +/** + * created by Harrison on 2022/07/07 + **/ +public class StartupPageConstants { + + /** + * 圆弧长度 + */ + public static final int ARC_DIAMETER = 20; + + /** + * 内容宽度 + */ + public static final int CONTENT_WIDTH = 850; +} diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageModel.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageModel.java new file mode 100644 index 0000000000..4b82545a01 --- /dev/null +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageModel.java @@ -0,0 +1,111 @@ +package com.fr.startup.ui; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.DesignerWorkspaceType; +import com.fr.third.guava.collect.Lists; +import com.fr.workspace.connect.WorkspaceConnectionInfo; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * created by Harrison on 2022/07/06 + **/ +public class StartupPageModel { + + private StartupWorkspaceBean selectWorkspaceInfo; + + private List workspaceInfos = new ArrayList<>(); + + private Map> recentFilesMap = new HashMap<>(); + + private Runnable openLastTemplateRunnable; + + private Runnable createNewTemplateRunnable; + + private Runnable openEmptyTemplateRunnable; + + public static StartupPageModel create() { + + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + Iterator envNameIterator = envManager.getEnvNameIterator(); + List infos = Lists.newArrayList(envNameIterator) + .stream() + .map((e) -> { + DesignerWorkspaceInfo workspaceInfo = envManager.getWorkspaceInfo(e); + if (workspaceInfo.getType() == DesignerWorkspaceType.Remote) { + WorkspaceConnectionInfo connection = workspaceInfo.getConnection(); + return new StartupWorkspaceBean(e, connection.getUrl(), workspaceInfo.getType()); + } else { + return new StartupWorkspaceBean(e, workspaceInfo.getPath(), workspaceInfo.getType()); + } + }) + .collect(Collectors.toList()); + Map> recentFileMap = new HashMap<>(); + for (StartupWorkspaceBean info : infos) { + String name = info.getName(); + List recentFiles = envManager.getRecentOpenedFilePathList4Env(name); + recentFileMap.put(name, recentFiles); + } + return new StartupPageModel(infos, recentFileMap); + } + + public StartupPageModel(List workspaceInfos, Map> recentFilesMap) { + this.selectWorkspaceInfo = workspaceInfos.get(0); + this.workspaceInfos = workspaceInfos; + this.recentFilesMap = recentFilesMap; + } + + public StartupWorkspaceBean getSelectWorkspaceInfo() { + return selectWorkspaceInfo; + } + + public void setSelectWorkspaceInfo(StartupWorkspaceBean selectWorkspaceInfo) { + this.selectWorkspaceInfo = selectWorkspaceInfo; + } + + public List getWorkspaceInfos() { + return workspaceInfos; + } + + public void setWorkspaceInfos(List workspaceInfos) { + this.workspaceInfos = workspaceInfos; + } + + public Map> getRecentFilesMap() { + return recentFilesMap; + } + + public void setRecentFilesMap(Map> recentFilesMap) { + this.recentFilesMap = recentFilesMap; + } + + public Runnable getOpenLastTemplateRunnable() { + return openLastTemplateRunnable; + } + + public void setOpenLastTemplateRunnable(Runnable openLastTemplateRunnable) { + this.openLastTemplateRunnable = openLastTemplateRunnable; + } + + public Runnable getCreateNewTemplateRunnable() { + return createNewTemplateRunnable; + } + + public void setCreateNewTemplateRunnable(Runnable createNewTemplateRunnable) { + this.createNewTemplateRunnable = createNewTemplateRunnable; + } + + public Runnable getOpenEmptyTemplateRunnable() { + return openEmptyTemplateRunnable; + } + + public void setOpenEmptyTemplateRunnable(Runnable openEmptyTemplateRunnable) { + this.openEmptyTemplateRunnable = openEmptyTemplateRunnable; + } +} diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageUtil.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageUtil.java new file mode 100644 index 0000000000..896b425957 --- /dev/null +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageUtil.java @@ -0,0 +1,40 @@ +package com.fr.startup.ui; + +import com.fr.base.svg.SVGIcon; +import com.fr.design.env.DesignerWorkspaceType; + +import javax.swing.Icon; + +/** + * created by Harrison on 2022/07/11 + **/ +public class StartupPageUtil { + + /** + * 获取最近区域的 ICON + * + * @param workspaceBean 工作目录 + * @return 图标 + */ + public static Icon getIcon4RecentAreaByWorkspace(StartupWorkspaceBean workspaceBean) { + + if (workspaceBean.getType() == DesignerWorkspaceType.Local) { + return SVGIcon.readSVGIcon("/com/fr/design/startup/local_server_background_36.svg", 36, 36); + } + return SVGIcon.readSVGIcon("/com/fr/design/startup/remote_server_background_36.svg", 36, 36); + } + + /** + * 获取工作目录描述区域的 ICON + * + * @param workspaceBean 工作目录 + * @return 图标 + */ + public static Icon getIcon4DescAreaByWorkspace(StartupWorkspaceBean workspaceBean) { + + if (workspaceBean.getType() == DesignerWorkspaceType.Local) { + return SVGIcon.readSVGIcon("/com/fr/design/startup/local_server_background_28.svg", 28, 28); + } + return SVGIcon.readSVGIcon("/com/fr/design/startup/remote_server_background_28.svg", 28, 28); + } +} diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java new file mode 100644 index 0000000000..fefe6e8eca --- /dev/null +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java @@ -0,0 +1,339 @@ +package com.fr.startup.ui; + +import com.fr.base.svg.IconUtils; +import com.fr.design.DesignerEnvManager; +import com.fr.design.components.loading.LoadingPane; +import com.fr.design.dialog.UIExpandDialog; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.ui.util.UIUtil; +import com.fr.design.utils.ColorUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.collections.CollectionUtils; +import org.jetbrains.annotations.NotNull; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JLayeredPane; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; +import javax.swing.border.EmptyBorder; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.LayoutManager; +import java.awt.RenderingHints; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; +import java.util.Map; + +/** + * 启动页 + * 见设计文档 + *

+ * created by Harrison on 2022/07/06 + **/ +public class StartupPageWindow extends JFrame { + + private static final int CONTENT_LAYER = 0; + private static final int TRANSPARENT_LAYER = 1; + + private static final Color HOVER_COLOR = new Color(65, 155, 249); + private static final Color SEP_COLOR = new Color(224, 224, 225); + + private static final int GROUP_WIDTH = 600; + private static final int RECENT_FILE_LIMIT = 6; + private static final int RECENT_FILE_SCROLL = RECENT_FILE_LIMIT + 1; + private static final int WORKSPACE_PANEL_WIDTH = 180; + private static final int TITLE_FONT_SIZE = 24; + private static final int ITEM_VERTICAL_GAP = 5; + + private static final Dimension SCREEN_SIZE = new Dimension(1600, 820); + + private StartupPageWorkspacePanel workspacePanel; + + private JPanel recentOpenPanel; + + private JPanel contentPane; + + private JPanel body; + + private LoadingPane loadingPane = new LoadingPane(); + + private JLayeredPane layeredPane = new JLayeredPane() { + @Override + public void doLayout() { + for (Component comp : getComponents()) { + comp.setBounds(0, 0, getWidth(), getHeight()); + } + } + }; + + public StartupPageWindow(StartupPageModel pageModel) { + + patchUIAction(pageModel); + + setLayout(new BorderLayout()); + + this.body = FRGUIPaneFactory.createBorderLayout_S_Pane(); + // Header + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Select_Workspace")); + Font font = label.getFont(); + Font titleFont = font.deriveFont(font.getStyle(), TITLE_FONT_SIZE); + label.setFont(titleFont); + JPanel headerPanel = new JPanel(); + LayoutManager centerFlowLayout = FRGUIPaneFactory.createCenterFlowLayout(); + headerPanel.setLayout(centerFlowLayout); + headerPanel.add(label); + this.body.add(headerPanel, BorderLayout.NORTH); + + // Workspace-description + this.workspacePanel = generateWorkspacePanel(pageModel); + this.body.add(workspacePanel, BorderLayout.CENTER); + + workspacePanel.setSelectWorkspaceRunnable(new Runnable() { + @Override + public void run() { + JPanel newPanel = generateRecentOpenPanel(pageModel); + + body.remove(recentOpenPanel); + recentOpenPanel = newPanel; + body.add(recentOpenPanel, BorderLayout.SOUTH); + validate(); + repaint(); + } + }); + + this.recentOpenPanel = generateRecentOpenPanel(pageModel); + this.body.add(recentOpenPanel, BorderLayout.SOUTH); + this.contentPane = new JPanel(); + this.contentPane.setLayout(getCenterLayout(body)); + this.contentPane.add(this.body, BorderLayout.CENTER); + this.contentPane.setPreferredSize(this.body.getPreferredSize()); + + this.layeredPane.setName("layered-pane"); + this.layeredPane.add(this.contentPane, CONTENT_LAYER); + this.layeredPane.add(this.loadingPane, TRANSPARENT_LAYER); + this.layeredPane.moveToFront(this.contentPane); + + add(this.layeredPane, BorderLayout.CENTER); + + // Workspace-detail + setSize(SCREEN_SIZE); + + repaint(); + validate(); + revalidate(); + + GUICoreUtils.centerWindow(this); + } + + private void patchUIAction(StartupPageModel pageModel) { + + Runnable selectAndOpenLastTemplateRunnable = pageModel.getOpenLastTemplateRunnable(); + pageModel.setOpenLastTemplateRunnable(() -> { + enterWorkspace(selectAndOpenLastTemplateRunnable); + }); + + Runnable createNewTemplateRunnable = pageModel.getCreateNewTemplateRunnable(); + pageModel.setCreateNewTemplateRunnable(() -> { + enterWorkspace(createNewTemplateRunnable); + }); + + Runnable openEmptyTemplateRunnable = pageModel.getOpenEmptyTemplateRunnable(); + pageModel.setOpenEmptyTemplateRunnable(() -> { + enterWorkspace(openEmptyTemplateRunnable); + }); + } + + private void enterWorkspace(Runnable action) { + + loadingPane.start(); + layeredPane.moveToFront(loadingPane); + SwingWorker task = new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + action.run(); + return null; + } + + @Override + protected void done() { + + try { + Void result = get(); + setVisible(false); + } catch (Exception e) { + // 处理错误 + UIUtil.invokeLaterIfNeeded(() -> { + UIExpandDialog.Builder() + .owner(StartupPageWindow.this) + .title(Toolkit.i18nText("Fine-Design_Basic_Remote_Env_Try")) + .message(Toolkit.i18nText("Fine-Design_Basic_Connection_Failed")) + .messageType(UIExpandDialog.WARNING_MESSAGE) + .detail(e.getMessage()) + .expand(true) + .modal(false) + .build() + .setVisible(true); + }); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + layeredPane.moveToFront(contentPane); + } finally { + loadingPane.stop(); + } + } + }; + task.execute(); + } + + private JPanel generateRecentOpenPanel(StartupPageModel pageModel) { + + JPanel recentOpenPanel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setColor(Color.WHITE); + g2d.fillRoundRect(0, 0, getWidth(), getHeight(), StartupPageConstants.ARC_DIAMETER, StartupPageConstants.ARC_DIAMETER); + } + }; + recentOpenPanel.setLayout(new BorderLayout()); + recentOpenPanel.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 6)); + + StartupWorkspaceBean workspaceInfo = pageModel.getSelectWorkspaceInfo(); + JPanel workspaceWrapperYPanel = new JPanel(); + workspaceWrapperYPanel.setName("workspace-wrapper"); + { + workspaceWrapperYPanel.setLayout(new VerticalFlowLayout()); + + JPanel workspaceWrapperXPanel = new JPanel(); + workspaceWrapperXPanel.setLayout(new FlowLayout()); + workspaceWrapperXPanel.setBorder(BorderFactory.createEmptyBorder()); + + JPanel workspacePanel = new JPanel(); + workspacePanel.setLayout(new BorderLayout(0, 15)); + + UILabel workspaceIcon = new UILabel(StartupPageUtil.getIcon4RecentAreaByWorkspace(workspaceInfo)); + workspacePanel.add(workspaceIcon, BorderLayout.NORTH); + + UILabel nameLabel = new UILabel(workspaceInfo.getName()); + nameLabel.setHorizontalAlignment(SwingConstants.CENTER); + workspacePanel.add(nameLabel, BorderLayout.SOUTH); + workspaceWrapperXPanel.add(workspacePanel); + Dimension preferredSize = workspaceWrapperXPanel.getPreferredSize(); + workspaceWrapperXPanel.setPreferredSize(new Dimension(WORKSPACE_PANEL_WIDTH, (int) preferredSize.getHeight())); + + workspaceWrapperYPanel.add(workspaceWrapperXPanel); + } + recentOpenPanel.add(workspaceWrapperYPanel, BorderLayout.WEST); + + JPanel separatorPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + { + JSeparator sep = new JSeparator(); + sep.setOrientation(JSeparator.VERTICAL); + sep.setForeground(SEP_COLOR); + separatorPanel.add(sep, BorderLayout.CENTER); + } + recentOpenPanel.add(separatorPanel, BorderLayout.CENTER); + + JComponent recentOpenGroupPanel = generateRecentOpenGroupPanel(pageModel, workspaceInfo); + recentOpenPanel.add(recentOpenGroupPanel, BorderLayout.EAST); + + ColorUtils.syncBackground(recentOpenPanel, Color.WHITE); + + Dimension preferredSize = recentOpenPanel.getPreferredSize(); + recentOpenPanel.setPreferredSize(new Dimension(StartupPageConstants.CONTENT_WIDTH, (int) preferredSize.getHeight())); + + JPanel recentOpenWrapperPanel = new JPanel(); + recentOpenWrapperPanel.setName("recentOpenWrapper"); + recentOpenWrapperPanel.setLayout(new BorderLayout(0, 0)); + recentOpenWrapperPanel.setBorder(new EmptyBorder(0, 0, 0, 20)); + recentOpenWrapperPanel.add(recentOpenPanel, BorderLayout.CENTER); + + return recentOpenWrapperPanel; + } + + @NotNull + private JComponent generateRecentOpenGroupPanel(StartupPageModel pageModel, StartupWorkspaceBean workspaceInfo) { + + JPanel recentOpenGroupPanel = new JPanel(); + Map> recentFilesMap = pageModel.getRecentFilesMap(); + + boolean needScroll = false; + double itemHeight = 0.0d; + if (!CollectionUtils.isEmpty(recentFilesMap)) { + String name = workspaceInfo.getName(); + List recentFiles = recentFilesMap.get(name); + if (!CollectionUtils.isEmpty(recentFiles)) { + recentOpenGroupPanel.setLayout(new GridLayout(recentFiles.size(), 1, 50, 5)); + needScroll = recentFiles.size() > RECENT_FILE_LIMIT; + for (String recentFile : recentFiles) { + JPanel recentItemPanel = new JPanel(); + recentItemPanel.setLayout(new FlowLayout(FlowLayout.LEFT, ITEM_VERTICAL_GAP, 0)); + recentItemPanel.add(new UILabel(IconUtils.readIcon("/com/fr/design/standard/system/cpt.svg"))); + UILabel recentFileLabel = new UILabel(recentFile); + Color recentFileLabelForeground = recentFileLabel.getForeground(); + recentItemPanel.add(recentFileLabel); + recentItemPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + recentFileLabel.setForeground(HOVER_COLOR); + } + + @Override + public void mouseExited(MouseEvent e) { + recentFileLabel.setForeground(recentFileLabelForeground); + } + + @Override + public void mouseClicked(MouseEvent e) { + DesignerEnvManager.getEnvManager().setLastOpenFile(recentFile); + pageModel.getOpenLastTemplateRunnable().run(); + } + }); + Dimension preferredSize = recentItemPanel.getPreferredSize(); + itemHeight = preferredSize.getHeight(); + recentOpenGroupPanel.add(recentItemPanel); + } + } + } + Dimension preferredSize = recentOpenGroupPanel.getPreferredSize(); + recentOpenGroupPanel.setPreferredSize(new Dimension(GROUP_WIDTH, (int) preferredSize.getHeight())); + + if (needScroll) { + int scrollHeight = (int) Math.round(itemHeight * RECENT_FILE_LIMIT + ITEM_VERTICAL_GAP * (RECENT_FILE_SCROLL)); + UIScrollPane scrollPane = new UIScrollPane(recentOpenGroupPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(new EmptyBorder(0, 0, 0, 0)); + scrollPane.setPreferredSize(new Dimension(GROUP_WIDTH, scrollHeight)); + return scrollPane; + } + return recentOpenGroupPanel; + } + + private StartupPageWorkspacePanel generateWorkspacePanel(StartupPageModel pageModel) { + + return new StartupPageWorkspacePanel(pageModel); + } + + protected LayoutManager getCenterLayout(JComponent centerBody) { + + return FRGUIPaneFactory.createCenterLayout(centerBody); + } + +} diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWorkspacePanel.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWorkspacePanel.java new file mode 100644 index 0000000000..a22c32b03b --- /dev/null +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWorkspacePanel.java @@ -0,0 +1,501 @@ +package com.fr.startup.ui; + +import com.fr.base.svg.IconUtils; +import com.fr.design.components.tooltip.ModernToolTip; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.ColorUtils; +import com.fr.third.guava.collect.Lists; +import org.jetbrains.annotations.NotNull; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JToolTip; +import javax.swing.ScrollPaneConstants; +import javax.swing.border.EmptyBorder; +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.RenderingHints; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import static com.fr.startup.ui.StartupPageConstants.ARC_DIAMETER; + +/** + * created by Harrison on 2022/07/06 + **/ +public class StartupPageWorkspacePanel extends JPanel { + + /* color */ + + private static final Color SHALLOW_WHITE_COLOR = new Color(248, 250, 254); + private static final Color HOVER_COLOR = new Color(65, 155, 249); + private static final Color PATH_COLOR = new Color(51, 51, 52, (int) Math.round(255 * 0.5)); + + /* 长度 */ + + private static final int SCROLL_BAR_WIDTH = 20; + + private static final int CONTENT_WIDTH = StartupPageConstants.CONTENT_WIDTH + SCROLL_BAR_WIDTH; + private static final int BORDER_THIN = 2; + + private static final int ITEM_VERTICAL_GAP = 20; + private static final int SINGLE_ITEM_HEIGHT = 72; + private static final int SCROLL_HEIGHT = SINGLE_ITEM_HEIGHT * 4 + ITEM_VERTICAL_GAP * 4; + + private static final int NAME_LABEL_SIZE = 15; + private static final int PATH_LABEL_SIZE = 10; + + private static final Dimension LABEL_DIMENSION = new Dimension(28, 28); + private static final Dimension PATH_DIMENSION = new Dimension(100, 20); + private static final Dimension SELECT_WORKSPACE_DIMENSION = new Dimension(210, 72); + private static final Dimension SELECT_CREATE_DIMENSION = new Dimension(60, 72); + public static final int COLUMN_LIMIT = 3; + + /* model */ + + private final StartupPageModel pageModel; + + private final List> partitions; + + private Runnable selectWorkspaceRunnable; + + private final Runnable createNewTemplateRunnable; + + private final Runnable openEmptyTemplateRunnable; + + private JComponent contentPanel; + + private JPanel tailPanel; + + private boolean showMore = true; + + public StartupPageWorkspacePanel(StartupPageModel pageModel) { + + this.setLayout(new BorderLayout(0, 0)); + + this.pageModel = pageModel; + + List workspaceInfos = pageModel.getWorkspaceInfos(); + this.partitions = Lists.partition(workspaceInfos, COLUMN_LIMIT); + + this.contentPanel = generateLimitContentPanel(partitions); + this.add(contentPanel, BorderLayout.NORTH); + + this.tailPanel = generateTailPanel(); + + this.createNewTemplateRunnable = pageModel.getCreateNewTemplateRunnable(); + this.openEmptyTemplateRunnable = pageModel.getOpenEmptyTemplateRunnable(); + + this.add(tailPanel, BorderLayout.SOUTH); + this.repaint(); + } + + public void showLessContent() { + + this.remove(this.contentPanel); + + this.contentPanel = generateLimitContentPanel(this.partitions); + this.add(contentPanel, BorderLayout.NORTH); + } + + public void showMoreContent() { + + this.remove(this.contentPanel); + + this.contentPanel = generateUnLimitContentPanel(this.partitions); + this.add(contentPanel, BorderLayout.NORTH); + } + + private JComponent generateUnLimitContentPanel(List> partitions) { + + JPanel workspaceDescPanel = new JPanel(); + workspaceDescPanel.setLayout(new GridLayout(partitions.size(), 1, 0, ITEM_VERTICAL_GAP)); + for (List partition : partitions) { + JPanel partitionPanel = generatePartitionPanel(partition); + workspaceDescPanel.add(partitionPanel); + } + boolean needScroll = partitions.size() > 4; + if (needScroll) { + // 滚动条 + UIScrollPane scrollPane = new UIScrollPane(workspaceDescPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(new EmptyBorder(10, 0, 0, 0)); + scrollPane.setPreferredSize(new Dimension(CONTENT_WIDTH, SCROLL_HEIGHT)); + return scrollPane; + } + return workspaceDescPanel; + } + + private JPanel generateLimitContentPanel(List> partitions) { + + JPanel workspaceDescPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEFT, 0, ITEM_VERTICAL_GAP); + int limit = 2; + for (int i = 0; i < partitions.size(); i++) { + if (i >= limit) { + break; + } + List partition = partitions.get(i); + + JPanel partitionPanel = generatePartitionPanel(partition); + workspaceDescPanel.add(partitionPanel); + } + return workspaceDescPanel; + } + + @NotNull + private JPanel generateTailPanel() { + + JPanel tailPanel = new JPanel(); + { + tailPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); + tailPanel.setBorder(new EmptyBorder(0, 0, 0, 20)); + JPanel showAllPanel = new JPanel(); + showAllPanel.setLayout(new BorderLayout(5, 0)); + showAllPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + + UILabel fontLabel = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Expand_All")); + fontLabel.setForeground(HOVER_COLOR); + showAllPanel.add(fontLabel, BorderLayout.WEST); + + UILabel iconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/startup/show_more.svg")); + showAllPanel.add(iconLabel, BorderLayout.EAST); + + Color showAllBackground = showAllPanel.getBackground(); + + showAllPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + Color hoverColor = new Color(217, 235, 254); + showAllPanel.setBackground(hoverColor); + } + + @Override + public void mouseExited(MouseEvent e) { + ColorUtils.syncBackground(showAllPanel, showAllBackground); + } + + @Override + public void mousePressed(MouseEvent e) { + if (showMore) { + fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Collapse_Workspace")); + iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_less.svg")); + showMoreContent(); + showMore = !showMore; + } else { + fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Expand_All")); + iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_more.svg")); + showLessContent(); + showMore = !showMore; + } + } + }); + tailPanel.add(showAllPanel); + Dimension preferredSize = tailPanel.getPreferredSize(); + tailPanel.setPreferredSize(new Dimension(CONTENT_WIDTH, (int) preferredSize.getHeight())); + } + return tailPanel; + } + + @NotNull + private JPanel generatePartitionPanel(List partition) { + + JPanel partitionPanel = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 20, 0);; + partitionPanel.setName("partitionPanel"); + + for (StartupWorkspaceBean workspaceInfo : partition) { + + JPanel workspaceItemDesc = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + layoutSelectWorkspacePanel(workspaceInfo, workspaceItemDesc); + + layoutSelectAndCreatePanel(workspaceItemDesc); + + partitionPanel.add(workspaceItemDesc); + + Dimension preferredSize = partitionPanel.getPreferredSize(); + partitionPanel.setPreferredSize(new Dimension(CONTENT_WIDTH, (int) preferredSize.getHeight())); + } + return partitionPanel; + } + + private void layoutSelectWorkspacePanel(StartupWorkspaceBean workspaceInfo, JPanel workspaceItemDesc) { + + // 选择工作目录 + // 图标 / 分隔符 / 说明-进入 + // 选择并新建 + AtomicReference borderColorRef = new AtomicReference<>(null); + + JPanel selectWorkspacePanel = new JPanel() { + @Override + public JToolTip createToolTip() { + return new ModernToolTip(); + } + + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + Color borderColor = borderColorRef.get(); + + Color backColor = Color.WHITE; + g2d.setColor(backColor); + // 直角和圆角上下叠合在一起 + int rectOffset = 10; + int roundOffset = 15; + // 填充一个直角 + g2d.fillRoundRect(0, 0, getWidth() - rectOffset, getHeight(), ARC_DIAMETER, ARC_DIAMETER); + // 填充一个圆角 + g2d.fillRoundRect(getWidth() - roundOffset, 0, roundOffset, getHeight(), 0, 0); + paintBorderIfHover(g2d, borderColor, backColor); + } + + /** + * 当悬浮的时候,将边框展示出来 + * 会叠合,然后填充中间 + * + * |----【-|--】 + * | A 【C| B】 + * |----【-|--】 + * + * 见上面有两种线,分别是 A-| 和 B-【 + * 这里会将 A 和 B 叠在一起,中间则存在 C,然后将 C 的部分扩大一点,然后填充上背景 + * 则形成下面这种图形 + * + * |----】 + * |----】 + * + * @param g2d 绘画 + * @param borderColor 边框颜色 + * @param backColor 背景颜色 + */ + private void paintBorderIfHover(Graphics2D g2d, Color borderColor, Color backColor) { + + if (borderColor != null) { + g2d.setColor(borderColor); + g2d.setStroke(new BasicStroke(BORDER_THIN)); + // 需要一个修正值 + int strokeOffset = BORDER_THIN / 2; + // 直角和圆角上下叠合在一起 + int rectOffset = 10; + int roundOffset = 15; + // 画一个圆角 + int fixRoundWidth = getWidth() - rectOffset; + int fixRoundHeight = getHeight() - BORDER_THIN; + g2d.drawRoundRect(strokeOffset, strokeOffset, fixRoundWidth, fixRoundHeight, ARC_DIAMETER, ARC_DIAMETER); + // 画一个直角 + g2d.drawRoundRect(getWidth() - roundOffset, strokeOffset, roundOffset - strokeOffset, getHeight() - BORDER_THIN, 0, 0); + + g2d.setColor(backColor); + + // 绘制一个矩形,覆盖住多余的相交线 + // 需要考虑上下的线宽 + int coverHeight = getHeight() - (BORDER_THIN * 2); + // 偏左一点的 fixedX + int fixedX = getWidth() - roundOffset - BORDER_THIN; + // 圆角和直角相交的区域 + int coverWidth = 10; + g2d.fillRect(fixedX, BORDER_THIN, coverWidth, coverHeight); + } + } + }; + selectWorkspacePanel.setLayout(new BorderLayout(0,0)); + selectWorkspacePanel.setToolTipText(Toolkit.i18nText("Fine-Design_Startup_Page_Double_Click_Enter_Workspace")); + selectWorkspacePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + { + + JPanel iconPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + iconPanel.setBorder(new EmptyBorder(0, 10, 0, 10)); + Icon icon = StartupPageUtil.getIcon4DescAreaByWorkspace(workspaceInfo); + UILabel label = new UILabel(icon); + label.setPreferredSize(LABEL_DIMENSION); + iconPanel.add(label, BorderLayout.CENTER); + selectWorkspacePanel.add(iconPanel, BorderLayout.WEST); + + // desc / >箭头 + JPanel descPanel = new JPanel(); + descPanel.setLayout(FRGUIPaneFactory.createM_BorderLayout()); + descPanel.setBorder(new EmptyBorder(0, 10, 0, 0)); + + JPanel simpleDescPanelWrapper = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.CENTER, 0, 0); + JPanel simpleDescPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UILabel nameLabel = new UILabel(workspaceInfo.getName()); + Font font = nameLabel.getFont(); + Font newSizeFont = font.deriveFont(font.getStyle(), NAME_LABEL_SIZE); + nameLabel.setFont(newSizeFont); + Color nameForeground = nameLabel.getForeground(); + simpleDescPanel.add(nameLabel,BorderLayout.NORTH); + + UILabel pathLabel = new UILabel(workspaceInfo.getPath()); + pathLabel.setPreferredSize(PATH_DIMENSION); + Font pathFont = pathLabel.getFont(); + pathLabel.setFont(pathFont.deriveFont(pathFont.getStyle(), PATH_LABEL_SIZE)); + Color pathColor = PATH_COLOR; + pathLabel.setForeground(pathColor); + simpleDescPanel.add(pathLabel, BorderLayout.SOUTH); + simpleDescPanelWrapper.add(simpleDescPanel); + + descPanel.add(simpleDescPanelWrapper, BorderLayout.WEST); + + MouseAdapter selectWorkspaceMouseListener = new MouseAdapter() { + + @Override + public void mouseEntered(MouseEvent e) { + Color hoverColor = HOVER_COLOR; + borderColorRef.set(hoverColor); + nameLabel.setForeground(hoverColor); + pathLabel.setForeground(hoverColor ); + selectWorkspacePanel.getParent().repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + borderColorRef.set(Color.WHITE); + nameLabel.setForeground(nameForeground); + pathLabel.setForeground(pathColor); + selectWorkspacePanel.getParent().repaint(); + } + + @Override + public void mousePressed(MouseEvent e) { + + int clickCount = e.getClickCount(); + if (clickCount == BORDER_THIN) { + pageModel.setSelectWorkspaceInfo(workspaceInfo); + openEmptyTemplateRunnable.run(); + return; + } + // selectWorkspaceRunnable + pageModel.setSelectWorkspaceInfo(workspaceInfo); + selectWorkspaceRunnable.run(); + } + + }; + + UILabel arrowLabel = new UILabel(IconUtils.readIcon("/com/fr/design/startup/more.svg")) { + @Override + public JToolTip createToolTip() { + return new ModernToolTip(); + } + }; + arrowLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Startup_Page_Enter_Workspace")); + arrowLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + arrowLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/more_hover.svg")); + selectWorkspaceMouseListener.mouseEntered(e); + } + + @Override + public void mouseExited(MouseEvent e) { + arrowLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/more.svg")); + selectWorkspaceMouseListener.mouseExited(e); + } + + @Override + public void mousePressed(MouseEvent e) { + openEmptyTemplateRunnable.run(); + } + }); + descPanel.add(arrowLabel, BorderLayout.EAST); + + selectWorkspacePanel.add(descPanel, BorderLayout.CENTER); + selectWorkspacePanel.addMouseListener(selectWorkspaceMouseListener); + } + + ColorUtils.syncBackground(selectWorkspacePanel, Color.WHITE); + selectWorkspacePanel.setPreferredSize(SELECT_WORKSPACE_DIMENSION); + workspaceItemDesc.add(selectWorkspacePanel, BorderLayout.WEST); + } + + private void layoutSelectAndCreatePanel(JPanel workspaceItemDesc) { + + // 选择并新建 + AtomicReference borderColorRef = new AtomicReference<>(null); + JPanel selectAndCreatePanel = new JPanel() { + @Override + public JToolTip createToolTip() { + return new ModernToolTip(); + } + + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + Color borderColor = borderColorRef.get(); + + Color backColor = SHALLOW_WHITE_COLOR; + g2d.setColor(backColor); + + // 见 layoutSelectWorkspacePanel 部分的分析 + // 直角和圆角上下叠合在一起 + int rectOffset = 10; + int roundOffset = 15; + int strokeOffset = BORDER_THIN / 2; + int fixedRoundOffset = roundOffset + strokeOffset; + g2d.fillRoundRect(0, 0, getWidth() - rectOffset, getHeight(), 0, 0); + g2d.fillRoundRect(getWidth() - fixedRoundOffset, 0, roundOffset, getHeight(), ARC_DIAMETER, ARC_DIAMETER); + if (borderColor != null) { + g2d.setColor(borderColor); + g2d.setStroke(new BasicStroke(BORDER_THIN)); + // 画画的笔触需要调整一下 + g2d.drawRoundRect(strokeOffset, strokeOffset, getWidth() - rectOffset, getHeight() - BORDER_THIN, 0, 0); + g2d.drawRoundRect(getWidth() - fixedRoundOffset, strokeOffset, roundOffset - strokeOffset, getHeight() - BORDER_THIN, ARC_DIAMETER, ARC_DIAMETER); + g2d.setColor(backColor); + int fillWidth = 11; + g2d.fillRect(getWidth() - fixedRoundOffset - BORDER_THIN, BORDER_THIN, fillWidth, getHeight() - BORDER_THIN * 2); + } + } + + }; + selectAndCreatePanel.setToolTipText(Toolkit.i18nText("Fine-Design_Startup_Page_Enter_Workspace_And_Create")); + selectAndCreatePanel.setBorder(new EmptyBorder(0, 0, 0, 0)); + selectAndCreatePanel.setLayout(new BorderLayout()); + { + UILabel label = new UILabel(IconUtils.readIcon("/com/fr/design/standard/system/add.svg")); + label.setPreferredSize(new Dimension(ARC_DIAMETER, ARC_DIAMETER)); + label.setForeground(HOVER_COLOR); + selectAndCreatePanel.add(label, BorderLayout.CENTER); + selectAndCreatePanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + borderColorRef.set(HOVER_COLOR); + selectAndCreatePanel.getParent().repaint(); + label.setIcon(IconUtils.readIcon("/com/fr/design/standard/system/add_hover.svg")); + } + + @Override + public void mouseExited(MouseEvent e) { + borderColorRef.set(null); + selectAndCreatePanel.getParent().repaint(); + label.setIcon(IconUtils.readIcon("/com/fr/design/standard/system/add.svg")); + } + @Override + public void mousePressed(MouseEvent e) { + createNewTemplateRunnable.run(); + } + }); + } + ColorUtils.syncBackground(selectAndCreatePanel, Color.GREEN); + selectAndCreatePanel.setPreferredSize(SELECT_CREATE_DIMENSION); + workspaceItemDesc.add(selectAndCreatePanel, BorderLayout.EAST); + } + + public void setSelectWorkspaceRunnable(Runnable selectWorkspaceRunnable) { + + this.selectWorkspaceRunnable = selectWorkspaceRunnable; + } + +} diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupWorkspaceBean.java b/designer-base/src/main/java/com/fr/startup/ui/StartupWorkspaceBean.java new file mode 100644 index 0000000000..04d660db95 --- /dev/null +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupWorkspaceBean.java @@ -0,0 +1,49 @@ +package com.fr.startup.ui; + +import com.fr.design.env.DesignerWorkspaceType; + +/** + * created by Harrison on 2022/07/07 + **/ +public class StartupWorkspaceBean { + + private String name; + + private String path; + + private DesignerWorkspaceType type; + + public StartupWorkspaceBean(String name, String path, DesignerWorkspaceType type) { + this.name = name; + this.path = path; + this.type = type; + } + + public static StartupWorkspaceBean create(String name, String path) { + return new StartupWorkspaceBean(name, path, DesignerWorkspaceType.Local); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public DesignerWorkspaceType getType() { + return type; + } + + public void setType(DesignerWorkspaceType type) { + this.type = type; + } +} diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties index f4840b71a4..03a445fab5 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties @@ -18,4 +18,6 @@ com.fr.design.mainframe.ForbiddenPane.refreshButton=75*24 com.fr.design.cell.expand.sort.pane=257*185 com.fr.design.sort.rule.item=125*20 com.fr.design.ds.column.sort.pane=250*180 -com.fr.design.sort.expand.header.pane=95*10 \ No newline at end of file +com.fr.design.sort.expand.header.pane=95*10 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.dialog=600*500 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.centerPane=580*369 diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties index fb0ecfb3d2..3cb9b007d1 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties @@ -17,4 +17,6 @@ com.fr.design.mainframe.ForbiddenPane.refreshButton=68*24 com.fr.design.cell.expand.sort.pane=257*170 com.fr.design.sort.rule.item=125*20 com.fr.design.ds.column.sort.pane=250*165 -com.fr.design.sort.expand.header.pane=95*10 \ No newline at end of file +com.fr.design.sort.expand.header.pane=95*10 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.dialog=600*500 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.centerPane=580*369 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 19bb7e97aa..df59420a41 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 @@ -17,4 +17,6 @@ com.fr.design.mainframe.ForbiddenPane.refreshButton=80*24 com.fr.design.cell.expand.sort.pane=267*165 com.fr.design.sort.rule.item=125*20 com.fr.design.ds.column.sort.pane=250*180 -com.fr.design.sort.expand.header.pane=95*10 \ No newline at end of file +com.fr.design.sort.expand.header.pane=95*10 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.dialog=600*500 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.centerPane=580*369 diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties index 055a81109a..e665593029 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties @@ -15,7 +15,10 @@ com.fr.design.report.fit.firstColumn=80*20 com.fr.design.report.fit.column=100*20 com.fr.design.lock.LockInfoDialog=400*180 com.fr.design.mainframe.ForbiddenPane.refreshButton=68*24 +com.fr.start.common.DesignerOpenEmptyPanel.createButton=70*24 com.fr.design.cell.expand.sort.pane=227*155 com.fr.design.sort.rule.item=80*20 com.fr.design.ds.column.sort.pane=220*150 -com.fr.design.sort.expand.header.pane=108*10 \ No newline at end of file +com.fr.design.sort.expand.header.pane=108*10 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.dialog=600*500 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.centerPane=580*369 diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties index 2ee112455f..2c99349ca1 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties @@ -17,4 +17,6 @@ com.fr.design.mainframe.ForbiddenPane.refreshButton=68*24 com.fr.design.cell.expand.sort.pane=227*155 com.fr.design.sort.rule.item=80*20 com.fr.design.ds.column.sort.pane=220*150 -com.fr.design.sort.expand.header.pane=108*10 \ No newline at end of file +com.fr.design.sort.expand.header.pane=108*10 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.dialog=600*500 +com.fr.design.plugin.remind.PluginInvalidateRemindDialog.centerPane=580*369 diff --git a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_en_US.js b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_en_US.js index 162f7d1b35..ce14a01bab 100644 --- a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_en_US.js +++ b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_en_US.js @@ -54,6 +54,7 @@ var Store = { 'Designer-BBS_Username_Is_Register': 'The user has been registered', 'Designer-BBS_Please_Enter_Correct_Phone': 'Please enter the correct phone number', 'Designer-Login_Network_Connected_Failed': 'Network connection failed', + 'Designer-Login_Failed_Exceed_Limit': 'Too many password errors, please try again after 24 hours', }} window.Store = Store; \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ja_JP.js b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ja_JP.js index 455998282c..391ee7fa62 100644 --- a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ja_JP.js +++ b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ja_JP.js @@ -54,6 +54,7 @@ var Store = { 'Designer-BBS_Username_Is_Register': 'このユーザは登録済みです。', 'Designer-BBS_Please_Enter_Correct_Phone': '正確な携帯番号を入力してください。', 'Designer-Login_Network_Connected_Failed': 'インターネット接続失敗', + 'Designer-Login_Failed_Exceed_Limit': 'パスワードを連続で間違えています。24時間にもう一度試してください。', }} window.Store = Store; \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ko_KR.js b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ko_KR.js index 162f7d1b35..ce14a01bab 100644 --- a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ko_KR.js +++ b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_ko_KR.js @@ -54,6 +54,7 @@ var Store = { 'Designer-BBS_Username_Is_Register': 'The user has been registered', 'Designer-BBS_Please_Enter_Correct_Phone': 'Please enter the correct phone number', 'Designer-Login_Network_Connected_Failed': 'Network connection failed', + 'Designer-Login_Failed_Exceed_Limit': 'Too many password errors, please try again after 24 hours', }} window.Store = Store; \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_CN.js b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_CN.js index 5181aa4351..2bff62a558 100644 --- a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_CN.js +++ b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_CN.js @@ -54,6 +54,7 @@ var Store = { 'Designer-BBS_Username_Is_Register': '该用户已被注册', 'Designer-BBS_Please_Enter_Correct_Phone': '请输入正确的手机号', 'Designer-Login_Network_Connected_Failed': '网络连接失败', + 'Designer-Login_Failed_Exceed_Limit': '密码错误次数过多,请24小时后重试', }} window.Store = Store; \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_TW.js b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_TW.js index 2cef831517..8a716ea671 100644 --- a/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_TW.js +++ b/designer-base/src/main/resources/com/fr/design/login/lib/locale/login_zh_TW.js @@ -54,6 +54,7 @@ var Store = { 'Designer-BBS_Username_Is_Register': '該帳號已被註冊', 'Designer-BBS_Please_Enter_Correct_Phone': '請輸入正確的手機號', 'Designer-Login_Network_Connected_Failed': '網路連線失敗', + 'Designer-Login_Failed_Exceed_Limit': '密碼錯誤次數過多,請24小時後重試', }} window.Store = Store; \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/login/login.js b/designer-base/src/main/resources/com/fr/design/login/login.js index 8691cf1e57..7f5d4111b8 100644 --- a/designer-base/src/main/resources/com/fr/design/login/login.js +++ b/designer-base/src/main/resources/com/fr/design/login/login.js @@ -1 +1 @@ -!function(e){var t={};function i(o){if(t[o])return t[o].exports;var s=t[o]={i:o,l:!1,exports:{}};return e[o].call(s.exports,s,s.exports,i),s.l=!0,s.exports}i.m=e,i.c=t,i.d=function(e,t,o){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)i.d(o,s,function(t){return e[t]}.bind(null,s));return o},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=4)}([function(e,t,i){"use strict";var o=this&&this.__createBinding||(Object.create?function(e,t,i,o){o===undefined&&(o=i),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,o){o===undefined&&(o=i),e[o]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||t.hasOwnProperty(i)||o(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),s(i(5),t)},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=window.DesignerLoginHelper,s=function(){function e(){}return e.prototype.getParams=function(){return{designerLoginSource:window.designerLoginSource||"0",lastLoginType:window.lastLoginType||"-1",lastLoginAccount:window.lastLoginAccount||""}},e.prototype.closeWindow=function(e){o&&o.closeWindow(e)},e.prototype.serviceHref=function(){o?o.serviceHref():window.open("https://bbs.fanruan.com/thread-102821-1-1.html")},e.prototype.forgetHref=function(){o?o.forgetHref():window.open("https://id.fanruan.com/forget/forget.php?clue=activityf")},e.prototype.normalLogin=function(e,t,i){o?o.normalLogin(e,t,i):i(-1)},e.prototype.sendCaptcha=function(e,t,i){o?o.sendCaptcha(e,t,i):i(-1)},e.prototype.smsLogin=function(e,t,i,s){o?o.smsLogin(e,t,i,s):s(null)},e.prototype.smsRegister=function(e,t,i,s,n){o?o.smsRegister(e,t,i,s,n):n(-1)},e.prototype.resize=function(e,t){o&&o.resize(e,t)},e}();t["default"]=new s},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BBS_ERROR_CODE=t.NORMAL_LOGIN_RESULT=t.REGION=t.LOGIN=void 0,t.LOGIN={NORMAL_METHOD:"normal",SMS_METHOD:"sms",TABS:{LOGIN:"login",FORGET_PASSWORD:"forget",RESET_PASSWORD:"reset",REGISTER:"register"}},t.REGION=[{value:"+86",text:"Designer-Basic_Chinese_Mainland"},{value:"+886",text:"Designer-Basic_Chinese_Taiwan"},{value:"+852",text:"Designer-Basic_Chinese_Hong_Kong"},{value:"+853",text:"Designer-Basic_Chinese_Macao"},{value:"+90",text:"Designer-Basic_Turkey"},{value:"+82",text:"Designer-Basic_South_Korea"},{value:"+81",text:"Designer-Basic_Japan"},{value:"+65",text:"Designer-Basic_Singapore"},{value:"+60",text:"Designer-Basic_Malaysia"}],t.NORMAL_LOGIN_RESULT=[{status:0,message:"Designer-Login_Internal_Error"},{status:-1,message:"Designer-Login_Store_User_Not_Exist"},{status:-2,message:"Designer-Login_Store_User_Password_Error"},{status:-3,message:"Designer-Login_Unexpected_Error"},{status:-4,message:"Designer-Login_Network_Connected_Failed"}],t.BBS_ERROR_CODE=[{status:0,message:"Designer-Login_Internal_Error"},{status:-1,message:"Designer-BBS_Register_Timeout"},{status:-2,message:"Designer-BBS_Phone_Is_Register"},{status:-3,message:"Designer-BBS_Captcha_Send_Exceed_Limit"},{status:-4,message:"Designer-BBS_Phone_Format_Error"},{status:-100,message:"Designer-BBS_Captcha_Out_Of_Date"},{status:-101,message:"Designer-BBS_Captcha_Try_Exceed_Limit"},{status:-102,message:"Designer-BBS_Captcha_Error"},{status:-104,message:"Designer-BBS_Username_Format_Error"},{status:-103,message:"Designer-BBS_Please_Enter_Correct_Phone"},{status:-105,message:"Designer-BBS_Username_Too_Short"},{status:-106,message:"Designer-BBS_Username_Too_Long"},{status:-107,message:"Designer-BBS_Phone_Is_Register"},{status:-108,message:"Designer-BBS_Username_Is_Register"}]},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getError=void 0,t.getError=function(e,t){var i=BI.find(e,(function(e,i){return i.status===t}));return i&&i.message?i.message:""}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=i(0),s=i(6);BI.addI18n(Store.i18n),BI.createWidget({type:o.Vertical,element:"body",items:[{type:s["default"]}]})},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ListView=t.VirtualGroup=t.LeftRightVerticalAdapt=t.Left=t.Horizontal=t.Vertical=t.Absolute=t.Layout=t.Htape=t.CenterAdapt=t.Vtape=t.HorizontalAdapt=t.VerticalAdapt=t.BubbleCombo=t.Img=t.Tab=t.SingleSelectInsertCombo=t.SingleSelectRadioItem=t.MultiTreePopupView=t.Editor=t.NicEditor=t.RichEditor=t.MultiTreeCombo=t.DynamicDateTimeCombo=t.DynamicDateCombo=t.BarPopOver=t.MultiSelectItem=t.TextAreaEditor=t.AllValueChooserCombo=t.ButtonGroup=t.MultiSelectInsertCombo=t.TextEditor=t.Button=t.SignEditor=t.MultiFileEditor=t.SmallTextEditor=t.HtmlLabel=t.Label=t.DownListCombo=t.TextButton=t.IconChangeButton=t.IconButton=t.IconTextIconItem=t.IconTextItem=void 0,t.IconTextItem="bi.icon_text_item",t.IconTextIconItem="bi.icon_text_icon_item",t.IconButton="bi.icon_button",t.IconChangeButton="bi.icon_change_button",t.TextButton="bi.text_button",t.DownListCombo="bi.down_list_combo",t.Label="bi.label",t.HtmlLabel="bi.html_label",t.SmallTextEditor="bi.small_text_editor",t.MultiFileEditor="bi.multifile_editor",t.SignEditor="bi.sign_editor",t.Button="bi.button",t.TextEditor="bi.text_editor",t.MultiSelectInsertCombo="bi.multi_select_insert_combo",t.ButtonGroup="bi.button_group",t.AllValueChooserCombo="bi.all_value_chooser_combo",t.TextAreaEditor="bi.textarea_editor",t.MultiSelectItem="bi.multi_select_item",t.BarPopOver="bi.bar_popover",t.DynamicDateCombo="bi.dynamic_date_combo",t.DynamicDateTimeCombo="bi.dynamic_date_time_combo",t.MultiTreeCombo="bi.multi_tree_combo",t.RichEditor="bi.rich_editor",t.NicEditor="bi.nic_editor",t.Editor="bi.editor",t.MultiTreePopupView="bi.multi_tree_popup_view",t.SingleSelectRadioItem="bi.single_select_radio_item",t.SingleSelectInsertCombo="bi.single_select_insert_combo",t.Tab="bi.tab",t.Img="bi.img",t.BubbleCombo="bi.bubble_combo",t.VerticalAdapt="bi.vertical_adapt",t.HorizontalAdapt="bi.horizontal_adapt",t.Vtape="bi.vtape",t.CenterAdapt="bi.center_adapt",t.Htape="bi.htape",t.Layout="bi.layout",t.Absolute="bi.absolute",t.Vertical="bi.vertical",t.Horizontal="bi.horizontal",t.Left="bi.left",t.LeftRightVerticalAdapt="bi.left_right_vertical_adapt",t.VirtualGroup="bi.virtual_group",t.ListView="bi.list_view"},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(7),n=i(8),r=i(9),a=i(11);i(25),t.className="designer.login.login",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login",width:420},_store:function(){return BI.Models.getModel(s["default"])},watch:{loading:function(e){this.loading.setVisible(e)}},render:function(){return{type:o.Vertical,cls:"designer-login",items:[{el:{type:o.HorizontalAdapt,items:[{type:n["default"],rgap:14,tgap:14}]}},{el:{type:o.Vertical,items:[{type:r["default"]},{type:a["default"]}]},lgap:15,rgap:15,bgap:15}]}}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});BI.model("designer.login.login.model",BI.inherit(Fix.Model,{childContext:["loading"],state:function(){return{loading:!1}}})),t["default"]="designer.login.login.model"},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(1);t.className="designer.login.login.close.button",t.Widget=BI.inherit(BI.Widget,{render:function(){return{type:o.TextButton,text:String.fromCharCode(10005),cls:"background-login-close",width:18.38,height:18.38,handler:function(){s["default"].closeWindow(!1)}}}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0);i(10),t.className="designer.login.login.title",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-title"},render:function(){return{type:o.Label,text:BI.i18nText("Designer-Login_Title"),cls:"bi-font-bold",bgap:10}}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(12);i(13);var n=i(14),r=i(16),a=i(18),l=i(2),u=i(1),d=249.64,g=331.64,c=422,p=478,h=560;t.className="designer.login.login.body",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},_store:function(){return BI.Stores.getStore(s["default"])},watch:{loginMethod:function(e){this.tabOption.setValue(e),this.tab.setSelect(e),this.foot.setLoginMethod(e),this.refreshLoginButton(),e===l.LOGIN.NORMAL_METHOD?(this.tab.setHeight(d),u["default"].resize(c,p)):this.model.expand&&(u["default"].resize(c,h),this.tab.setHeight(g))},approve:function(e){this.refreshLoginButton()},expand:function(e){e&&(u["default"].resize(c,h),this.tab.setHeight(g))}},render:function(){var e=this;return{type:o.Vertical,cls:"designer-login-body",items:[{type:o.ButtonGroup,value:this.model.loginMethod,ref:function(t){e.tabOption=t},layouts:[{type:o.HorizontalAdapt}],items:[{cls:"designer-login-change-mode bi-list-item-effect bi-border-bottom bi-font-bold",width:70,height:28,value:l.LOGIN.SMS_METHOD,text:BI.i18nText("Designer-Login_Sms")},{cls:"designer-login-change-mode bi-list-item-effect bi-border-bottom bi-font-bold",width:70,height:28,value:l.LOGIN.NORMAL_METHOD,text:BI.i18nText("Designer-Login_Normal")}],listeners:[{eventName:BI.ButtonGroup.EVENT_CHANGE,action:function(t){e.store.setLoginMethod(t)}}],tgap:24,lgap:75,rgap:75},{type:o.CenterAdapt,tgap:35,items:[{type:o.Tab,cardCreator:BI.bind(this.createCard,this),showIndex:this.model.loginMethod,ref:function(t){e.tab=t},height:d,width:280}]},{type:n["default"],lgap:50,rgap:50,bgap:30,ref:function(t){e.foot=t},refreshStatus:function(t){e.store.setApprove(t)}}]}},mounted:function(){var e=u["default"].getParams(),t=e.designerLoginSource,i=e.lastLoginType;if("2"===t){var o="0"===i?l.LOGIN.NORMAL_METHOD:l.LOGIN.SMS_METHOD;this.store.setLoginMethod(o)}},createCard:function(e){var t=this;switch(e){case l.LOGIN.NORMAL_METHOD:return{type:r["default"],ref:function(e){t.normalMethod=e}};case l.LOGIN.SMS_METHOD:default:return{type:a["default"],ref:function(e){t.smsMethod=e},expand:function(){t.store.setExpand(!0)}}}},refreshLoginButton:function(){this.model.loginMethod===l.LOGIN.NORMAL_METHOD?this.normalMethod.setApprove(this.model.approve):this.smsMethod.setApprove(this.model.approve)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Model=t.className=void 0;var o=i(2);t.className="designer.login.model.login.body",t.Model=BI.inherit(Fix.Model,{context:["loading"],state:function(){return{loginMethod:o.LOGIN.SMS_METHOD,approve:!0,expand:!1}},actions:{setLoginMethod:function(e){this.model.loginMethod=e},setApprove:function(e){this.model.approve=e},setExpand:function(e){this.model.expand=e}}}),BI.store(t.className,t.Model),t["default"]=t.className},function(e,t,i){},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(1),s=i(0);i(15);var n=i(2);t.className="designer.login.login.foot",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-foot"},render:function(){var e=this,t=this.options;return{type:s.LeftRightVerticalAdapt,items:{left:[{type:s.MultiSelectItem,width:30,selected:!0,handler:function(){t.refreshStatus(this.isSelected())}},{type:s.Label,cls:"login-foot-text",textAlign:"left",text:BI.i18nText("Designer-Login_I_Have_Read")},{type:s.Label,cls:"login-foot-text",textAlign:"left",text:"《"},{type:s.TextButton,cls:"login-link",textAlign:"left",text:BI.i18nText("Designer-Login_Service_Terms"),handler:function(){o["default"].serviceHref()}},{type:s.Label,cls:"login-foot-text",textAlign:"left",text:"》"}],right:[{type:s.TextButton,cls:"login-link",textAlign:"right",text:BI.i18nText("Designer-Login_Forget_Password"),invisible:!0,tgap:2,ref:function(t){e.forgetPassword=t},handler:function(){o["default"].forgetHref()}}]}}},setLoginMethod:function(e){e===n.LOGIN.NORMAL_METHOD?this.forgetPassword.setVisible(!0):this.forgetPassword.setVisible(!1)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(3),n=i(1),r=i(17),a=i(2);t.className="designer.login.login.normal",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},_store:function(){return BI.Stores.getStore(r["default"])},watch:{errMessage:function(e){this.errMessage.setText(e)}},render:function(){var e=this;return{type:o.Vertical,items:[{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_User_Name"),bgap:3},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-username",watermark:BI.i18nText("Designer-Login_User_Name_Hint"),inputType:"text",allowBlank:!0,height:40,ref:function(t){e.userName=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Password"),bgap:3},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-password",watermark:BI.i18nText("Designer-Login_Password_Hint"),inputType:"password",allowBlank:!0,height:40,ref:function(t){e.password=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:o.Label,cls:"designer-login-error-message",textAlign:"center",text:"",height:20,bgap:10,ref:function(t){e.errMessage=t}},{type:o.Button,cls:"login-login-button bi-font-bold",text:BI.i18nText("Designer-Login"),level:"common",height:40,ref:function(t){e.loginButton=t},handler:function(){e.login()}}]}},mounted:function(){var e=this;this.element.keyup((function(t){13===t.keyCode&&e.login()}));var t=n["default"].getParams(),i=t.designerLoginSource,o=t.lastLoginType,s=t.lastLoginAccount;"2"===i&&"0"===o&&e.userName.setValue(s)},checkUsername:function(){var e=this.userName.getValue();e&&this.userName.setValue(e.replace(/\s+/g,""))},login:function(){var e=this;e.checkUsername();var t=this.userName.getValue(),i=this.password.getValue();t?i?n["default"].normalLogin(t,i,(function(t){var i=parseInt(t,10);if(i>0)n["default"].closeWindow(!0);else{var o=s.getError(a.NORMAL_LOGIN_RESULT,i);o&&e.store.setErrMessage(BI.i18nText(o))}})):this.store.setErrMessage(BI.i18nText("Designer-Login_Password_Not_Null")):this.store.setErrMessage(BI.i18nText("Designer-Login_Username_Not_Null"))},setApprove:function(e){this.loginButton.setEnable(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Model=t.className=void 0,t.className="designer.login.model.normal_method",t.Model=BI.inherit(Fix.Model,{context:[""],state:function(){return{errMessage:""}},actions:{setErrMessage:function(e){this.model.errMessage=e}}}),BI.store(t.className,t.Model),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(19),n=i(22),r=i(23),a=i(2),l=i(24),u=i(1),d=i(3);t.className="designer.login.login.sms",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},_store:function(){return BI.Stores.getStore(l["default"])},watch:{errMessage:function(e){this.errMessage.setText(e)},isRegister:function(e){var t=this.options;e&&(t.expand(),this.password.setVisible(!0),this.passwordLabel.setVisible(!0))}},render:function(){var e=this,t=this;return{type:o.Vertical,items:[{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Phone"),bgap:3},{type:o.HorizontalAdapt,bgap:7,items:[{type:s["default"],height:42,textFormatter:function(e){var i=t.getNumberTypeItem(e);return{value:i.value,text:BI.i18nText(i.text)}},value:a.REGION[0].value,items:BI.map(a.REGION,(function(e,t){return{type:n["default"],value:t.value,label:BI.i18nText(t.text),text:t.value}})),ref:function(t){e.regionCode=t}},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-username",watermark:BI.i18nText("Designer-Login_Phone_Hint"),inputType:"text",allowBlank:!0,height:40,ref:function(t){e.phone=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]}]},{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Code"),bgap:3},{type:o.Horizontal,bgap:7,items:[{type:o.Editor,cls:"bi-border-bottom designer-login-editor-password",watermark:BI.i18nText("Designer-Login_Code_Hint"),inputType:"text",allowBlank:!0,height:40,width:190,ref:function(t){e.code=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:r["default"],height:40,width:90,ref:function(t){e.accountCaptcha=t},listeners:[{eventName:"EVENT_SEND",action:function(){t.sendCaptcha()}}]}]},{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Password"),bgap:3,invisible:!0,ref:function(t){e.passwordLabel=t}},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-password",watermark:BI.i18nText("Designer-Login_Password_Setting_Hint"),inputType:"password",allowBlank:!0,height:40,invisible:!0,ref:function(t){e.password=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:o.Label,cls:"designer-login-error-message",textAlign:"center",text:"",height:20,bgap:11,ref:function(t){e.errMessage=t}},{type:o.Button,cls:"login-login-button bi-font-bold",text:BI.i18nText("Designer-Login_Register_Or_Login"),level:"common",height:40,ref:function(t){e.loginButton=t},handler:function(){e.login()}}]}},mounted:function(){var e=this;this.element.keyup((function(t){13===t.keyCode&&e.login()}));var t=u["default"].getParams(),i=t.designerLoginSource,o=t.lastLoginType,s=t.lastLoginAccount;if("2"===i&&"1"===o){var n=s.split("-")[0],r=s.split("-")[1];e.regionCode.setValue(n),e.phone.setValue(r)}},getNumberTypeItem:function(e){return BI.find(a.REGION,(function(t,i){return e===i.value}))||{}},checkPhone:function(){var e=this.phone.getValue();e&&this.phone.setValue(e.replace(/\s+/g,""))},login:function(){var e=this,t=this;t.checkPhone();var i=this.phone.getValue(),o=this.code.getValue();if(i)if(o)if(6==o.length){var s=this.regionCode.getValue();if(this.model.isRegister){var n=this.password.getValue();if(!n)return void this.store.setErrMessage(BI.i18nText("Designer-Login_Password_Not_Null"));var r=this.model.regToken;if(!r)return void this.store.setErrMessage(BI.i18nText("Designer-Login_Token_Request_Failed"));u["default"].smsRegister(s,i,n,r,(function(e){var i=parseInt(e,10);if(i>0)u["default"].closeWindow(!0);else{var o=d.getError(a.BBS_ERROR_CODE,i);o&&t.store.setErrMessage(BI.i18nText(o))}}))}else u["default"].smsLogin(s,i,o,(function(i){var o=JSON.parse(i);if(o.status>0)if(!0===o.register){var s=o.regtoken;s?(t.store.setRegister(!0),t.store.setRegToken(s)):e.store.setErrMessage(BI.i18nText("Designer-Login_Token_Request_Failed"))}else u["default"].closeWindow(!0);else{var n=d.getError(a.BBS_ERROR_CODE,o.status);n&&t.store.setErrMessage(BI.i18nText(n))}}))}else this.store.setErrMessage(BI.i18nText("Designer-BBS_Captcha_Error"));else this.store.setErrMessage(BI.i18nText("Designer-Login_Code_Not_Null"));else this.store.setErrMessage(BI.i18nText("Designer-Login_Phone_Not_Null"))},sendCaptcha:function(){var e=this;e.checkPhone();var t=this.phone.getValue();if(!t)return e.accountCaptcha.setButtonEnable(!0),void this.store.setErrMessage(BI.i18nText("Designer-Login_Phone_Not_Null"));var i=this.regionCode.getValue();u["default"].sendCaptcha(i,t,(function(t){var i=parseInt(t,10);if(1===i)e.accountCaptcha.regainCaptcha();else{if(e.accountCaptcha.setButtonEnable(!0),0===i)return void e.store.setErrMessage(BI.i18nText("Designer-BBS_Please_Enter_Correct_Phone"));var o=d.getError(a.BBS_ERROR_CODE,i);o&&e.store.setErrMessage(BI.i18nText(o))}}))},setApprove:function(e){this.loginButton.setEnable(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(20),s=i(21);t.className="designer.left_right_text_value_combo",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"",height:24,chooseType:BI.ButtonGroup.CHOOSE_TYPE_SINGLE,textFormatter:function(e){return e},value:""},render:function(){var e=this,t=this.options;return{type:s["default"],container:t.container,adjustLength:2,ref:function(t){e.combo=t},el:{type:o["default"],cls:"text-value-trigger",items:t.items,height:t.height-2,value:t.textFormatter(t.value),ref:function(t){e.trigger=t}},popup:{el:{type:"bi.text_value_combo_popup",chooseType:t.chooseType,value:t.value,items:t.items,ref:function(t){e.popup=t},listeners:[{eventName:BI.TextValueComboPopup.EVENT_CHANGE,action:function(){e.setValue(e.getValue()),e.combo.hideView(),e.fireEvent("EVENT_CHANGE",arguments)}},{eventName:BI.Controller.EVENT_CHANGE,action:function(){e.fireEvent(BI.Controller.EVENT_CHANGE,arguments)}}]},value:t.value,maxHeight:240,minHeight:25}}},setValue:function(e){this.combo.setValue(e),this.trigger.setValue(this.options.textFormatter(e))},getValue:function(){var e=this.combo.getValue();return BI.isNull(e)?"":BI.isArray(e)?e[0]:e},populate:function(e){this.options.items=e,this.combo.populate(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0,t.className="designer.left_right_text_value_combo_trigger",t.Widget=BI.inherit(BI.Trigger,{props:{baseCls:"",value:{}},render:function(){var e=this,t=this.options,i=t.value;return{type:"bi.htape",cls:"bi-border-bottom bi-border-radius",items:[{type:"bi.label",text:i.text,title:function(){return e.textRow.getText()},height:t.height,hgap:3,textAlign:"left",ref:function(t){e.textRow=t}},{type:"bi.label",text:i.value,height:t.height,width:32,textAlign:"right",ref:function(t){e.valueRow=t}},{type:"bi.trigger_icon_button",width:t.triggerWidth||t.height}]}},setValue:function(e){this.textRow.setText(e.text),this.valueRow.setText(e.value)},setText:function(e){this.textRow.setText(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o={};t.className="designer.login_combo",t.Widget=BI.inherit(BI.Widget,{_defaultConfig:function(){var e=BI.Combo.superclass._defaultConfig.apply(this,arguments);return BI.extend(e,{baseCls:(e.baseCls||"")+" bi-combo"+(BI.isIE()?" hack":""),attributes:{tabIndex:-1},trigger:"click",toggle:!0,direction:"bottom",logic:{dynamic:!0},container:null,isDefaultInit:!1,destroyWhenHide:!1,hideWhenAnotherComboOpen:!1,isNeedAdjustHeight:!0,isNeedAdjustWidth:!0,stopEvent:!1,stopPropagation:!1,adjustLength:0,adjustXOffset:0,adjustYOffset:0,hideChecker:BI.emptyFn,offsetStyle:"left",el:{},popup:{},comboClass:"bi-combo-popup",hoverClass:"bi-combo-hover",belowMouse:!1})},_init:function(){BI.Combo.superclass._init.apply(this,arguments);var e=this,t=this.options;this._initCombo(),this._initPullDownAction(),this.combo.on(BI.Controller.EVENT_CHANGE,(function(t,i,o){e.isEnabled()&&e.isValid()&&(t===BI.Events.EXPAND&&e._popupView(),t===BI.Events.COLLAPSE&&e._hideView(),t===BI.Events.EXPAND&&(e.fireEvent(BI.Controller.EVENT_CHANGE,arguments),e.fireEvent(BI.Combo.EVENT_EXPAND)),t===BI.Events.COLLAPSE&&(e.fireEvent(BI.Controller.EVENT_CHANGE,arguments),e.isViewVisible()&&e.fireEvent(BI.Combo.EVENT_COLLAPSE)),t===BI.Events.CLICK&&e.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE,o))})),e.element.on("mouseenter."+e.getName(),(function(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&e.element.addClass(t.hoverClass)})),e.element.on("mouseleave."+e.getName(),(function(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&e.element.removeClass(t.hoverClass)})),BI.createWidget(BI.extend({element:this},BI.LogicFactory.createLogic("vertical",BI.extend(t.logic,{items:[{el:this.combo}]})))),t.isDefaultInit&&this._assertPopupView(),BI.Resizers.add(this.getName(),BI.bind((function(e){this.isViewVisible()&&(BI.isNotNull(e)?this._hideIf(e):this._hideView())}),this))},_toggle:function(e){this._assertPopupViewRender(),this.popupView.isVisible()?this._hideView(e):this.isEnabled()&&this._popupView(e)},_initPullDownAction:function(){var e=this,t=this.options,i=(this.options.trigger||"").split(","),o=function(e){t.stopEvent&&e.stopEvent(),t.stopPropagation&&e.stopPropagation()},s=!1;function n(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&!0===t.toggle&&(e._hideView(i),e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.COLLAPSE,"",e.combo),e.fireEvent(BI.Combo.EVENT_COLLAPSE)),e.popupView&&e.popupView.element.off("mouseenter."+e.getName()).off("mouseleave."+e.getName()),s=!1}BI.each(i,(function(i,r){switch(r){case"hover":e.element.on("mouseenter."+e.getName(),(function(t){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&(e._popupView(t),e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.EXPAND,"",e.combo),e.fireEvent(BI.Combo.EVENT_EXPAND))})),e.element.on("mouseleave."+e.getName(),(function(t){e.popupView&&(e.popupView.element.on("mouseenter."+e.getName(),(function(t){s=!0,e.popupView.element.on("mouseleave."+e.getName(),(function(e){n(e)})),e.popupView.element.off("mouseenter."+e.getName())})),BI.defer((function(){s||n(t)}),50))}));break;case"click":var a=BI.debounce((function(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&(t.toggle?e._toggle(i):e._popupView(i),e.isViewVisible()?(e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.EXPAND,"",e.combo),e.fireEvent(BI.Combo.EVENT_EXPAND)):(e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.COLLAPSE,"",e.combo),e.fireEvent(BI.Combo.EVENT_COLLAPSE)))}),BI.EVENT_RESPONSE_TIME,{leading:!0,trailing:!1});e.element.off(r+"."+e.getName()).on(r+"."+e.getName(),(function(e){a(e),o(e)}));break;case"click-hover":a=BI.debounce((function(t){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&(e._popupView(t),e.isViewVisible()&&(e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.EXPAND,"",e.combo),e.fireEvent(BI.Combo.EVENT_EXPAND)))}),BI.EVENT_RESPONSE_TIME,{leading:!0,trailing:!1});e.element.off("click."+e.getName()).on("click."+e.getName(),(function(e){a(e),o(e)})),e.element.on("mouseleave."+e.getName(),(function(t){e.popupView&&(e.popupView.element.on("mouseenter."+e.getName(),(function(t){s=!0,e.popupView.element.on("mouseleave."+e.getName(),(function(e){n(e)})),e.popupView.element.off("mouseenter."+e.getName())})),BI.delay((function(){s||n(t)}),50))}))}}))},_initCombo:function(){this.combo=BI.createWidget(this.options.el,{value:this.options.value})},_assertPopupView:function(){var e=this,t=this.options;null==this.popupView&&(this.popupView=BI.createWidget(this.options.popup,{type:"bi.popup_view",value:t.value},this),this.popupView.on(BI.Controller.EVENT_CHANGE,(function(t,i,o){t===BI.Events.CLICK&&(e.combo.setValue(e.getValue()),e.fireEvent(BI.Combo.EVENT_CHANGE,i,o)),e.fireEvent(BI.Controller.EVENT_CHANGE,arguments)})),this.popupView.setVisible(!1),BI.nextTick((function(){e.fireEvent(BI.Combo.EVENT_AFTER_INIT)})))},_assertPopupViewRender:function(){this._assertPopupView(),this._rendered||(BI.createWidget({type:"bi.vertical",scrolly:!1,element:this.options.container||this,items:[{el:this.popupView}]}),this._rendered=!0)},_hideIf:function(e,t){if(e&&(!0!==t&&this.element.find(e.target).length>0||this.popupView&&this.popupView.element.find(e.target).length>0||"CodeMirror-cursor"===e.target.className||BI.Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length>0)){var i=this.options.direction.split(",");(BI.contains(i,"innerLeft")||BI.contains(i,"innerRight"))&&(this.adjustWidth(),this.adjustHeight())}else{if(!1!==this.options.hideChecker.apply(this,[e]))return this._hideView(),!0}},_hideView:function(){this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW),!0===this.options.destroyWhenHide?(this.popupView&&this.popupView.destroy(),this.popupView=null,this._rendered=!1):this.popupView&&this.popupView.invisible(),this.element.removeClass(this.options.comboClass),delete o[this.getName()],BI.Widget._renderEngine.createElement(document).unbind("mousedown."+this.getName()).unbind("mousewheel."+this.getName()),this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW)},_popupView:function(e){var t=this;this._assertPopupViewRender(),this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW),this.popupView.css({left:-999999999,top:-99999999}),this.popupView.visible(),BI.each(o,(function(i,s){i!==t.getName()&&s&&!0===s._hideIf(e,!0)&&delete o[i]})),this.options.hideWhenAnotherComboOpen&&(o[this.getName()]=this),this.adjustWidth(e),this.adjustHeight(e),this.element.addClass(this.options.comboClass),BI.Widget._renderEngine.createElement(document).unbind("mousedown."+this.getName()).unbind("mousewheel."+this.getName()),BI.Widget._renderEngine.createElement(document).bind("mousedown."+this.getName(),BI.bind(this._hideIf,this)).bind("mousewheel."+this.getName(),BI.bind(this._hideIf,this)),this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW)},adjustWidth:function(e){var t=this.options;if(this.popupView&&!0===t.isNeedAdjustWidth){this.resetListWidth("");var i=this.popupView.element.outerWidth(),o=this.element.outerWidth()||t.width;i>o+80?o+=80:i>o&&(o=i),this.resetListWidth(o<100?100:o)}},adjustHeight:function(e){var t=this.options,i={top:0,adaptHeight:0,left:0};if(this.popupView){var o=this.popupView.isVisible();this.popupView.visible();var s=t.belowMouse&&BI.isNotNull(e)?{element:{offset:function(){return{left:e.pageX,top:e.pageY}},bounds:function(){return{x:e.offsetX,y:e.offsetY,width:0,height:24}},outerWidth:function(){return 0},outerHeight:function(){return 24}}}:this.combo;switch(t.direction){case"bottom":case"bottom,right":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["bottom","top","right","left"],t.offsetStyle);break;case"top":case"top,right":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["top","bottom","right","left"],t.offsetStyle);break;case"left":case"left,bottom":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["left","right","bottom","top"],t.offsetStyle);break;case"right":case"right,bottom":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","bottom","top"],t.offsetStyle);break;case"top,left":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["top","bottom","left","right"],t.offsetStyle);break;case"bottom,left":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["bottom","top","left","right"],t.offsetStyle);break;case"left,top":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["left","right","top","bottom"],t.offsetStyle);break;case"right,top":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","top","bottom"],t.offsetStyle);break;case"right,innerRight":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","innerRight","innerLeft","bottom","top"],t.offsetStyle);break;case"right,innerLeft":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","innerLeft","innerRight","bottom","top"],t.offsetStyle);break;case"innerRight":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["innerRight","innerLeft","right","left","bottom","top"],t.offsetStyle);break;case"innerLeft":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["innerLeft","innerRight","left","right","bottom","top"],t.offsetStyle);break;case"top,custom":case"custom,top":i=BI.DOM.getTopAdaptPosition(s,this.popupView,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight);break;case"custom,bottom":case"bottom,custom":i=BI.DOM.getBottomAdaptPosition(s,this.popupView,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight);break;case"left,custom":case"custom,left":delete(i=BI.DOM.getLeftAdaptPosition(s,this.popupView,t.adjustXOffset||t.adjustLength)).top,delete i.adaptHeight;break;case"custom,right":case"right,custom":delete(i=BI.DOM.getRightAdaptPosition(s,this.popupView,t.adjustXOffset||t.adjustLength)).top,delete i.adaptHeight}"adaptHeight"in i&&this.resetListHeight(i.adaptHeight),"left"in i&&this.popupView.element.css({left:i.left}),"top"in i&&this.popupView.element.css({top:i.top}),this.position=i,this.popupView.setVisible(o)}},resetListHeight:function(e){this._assertPopupView(),this.popupView.resetHeight&&this.popupView.resetHeight(e)},resetListWidth:function(e){this._assertPopupView(),this.popupView.resetWidth&&this.popupView.resetWidth(e)},populate:function(e){this._assertPopupView(),this.popupView.populate.apply(this.popupView,arguments),this.combo.populate&&this.combo.populate.apply(this.combo,arguments)},_setEnable:function(e){BI.Combo.superclass._setEnable.apply(this,arguments),!0===e?this.element.removeClass("base-disabled disabled"):!1===e&&this.element.addClass("base-disabled disabled"),!e&&this.element.removeClass(this.options.hoverClass),!e&&this.isViewVisible()&&this._hideView()},setValue:function(e){this.combo.setValue(e),BI.isNull(this.popupView)?this.options.popup.value=e:this.popupView.setValue(e)},getValue:function(){return BI.isNull(this.popupView)?this.options.popup.value:this.popupView.getValue()},isViewVisible:function(){return this.isEnabled()&&this.combo.isEnabled()&&!!this.popupView&&this.popupView.isVisible()},showView:function(e){this.isEnabled()&&this.combo.isEnabled()&&!this.isViewVisible()&&this._popupView(e)},hideView:function(){this._hideView()},getView:function(){return this.popupView},getPopupPosition:function(){return this.position},toggle:function(){this._toggle()},destroyed:function(){BI.Widget._renderEngine.createElement(document).unbind("click."+this.getName()).unbind("mousedown."+this.getName()).unbind("mousewheel."+this.getName()).unbind("mouseenter."+this.getName()).unbind("mousemove."+this.getName()).unbind("mouseleave."+this.getName()).unbind("blur."+this.getName()),BI.Resizers.remove(this.getName()),this.popupView&&this.popupView._destroy(),delete o[this.getName()]}}),BI.Combo.EVENT_TRIGGER_CHANGE="EVENT_TRIGGER_CHANGE",BI.Combo.EVENT_CHANGE="EVENT_CHANGE",BI.Combo.EVENT_EXPAND="EVENT_EXPAND",BI.Combo.EVENT_COLLAPSE="EVENT_COLLAPSE",BI.Combo.EVENT_AFTER_INIT="EVENT_AFTER_INIT",BI.Combo.EVENT_BEFORE_POPUPVIEW="EVENT_BEFORE_POPUPVIEW",BI.Combo.EVENT_AFTER_POPUPVIEW="EVENT_AFTER_POPUPVIEW",BI.Combo.EVENT_BEFORE_HIDEVIEW="EVENT_BEFORE_HIDEVIEW",BI.Combo.EVENT_AFTER_HIDEVIEW="EVENT_AFTER_HIDEVIEW",BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0,t.className="designer.components.phone.editor.item",t.Widget=BI.inherit(BI.BasicButton,{props:{baseCls:"designer-login-login-body",label:"",text:""},render:function(){var e=this.options;return{type:"bi.htape",items:[{el:{type:"bi.label",text:e.label,title:e.label,textAlign:"left"},lgap:10,rgap:5},{el:{type:"bi.label",text:e.text,textAlign:"right"},width:32,rgap:10}]}},doClick:function(){BI.SingleSelectItem.superclass.doClick.apply(this,arguments),this.isValid()&&this.fireEvent("EVENT_CHANGE",this.isSelected(),this)},setSelected:function(e){BI.SingleSelectItem.superclass.setSelected.apply(this,arguments)},getValue:function(){return this.options.value}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0);t.className="designer.user.account.setting.captcha",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},render:function(){var e=this;this.options;return{type:o.TextButton,text:BI.i18nText("Designer-Login_Code_Request"),cls:"designer-login-border-bottom designer-login-code-text",handler:function(){e.setButtonEnable(!1),e.fireEvent("EVENT_SEND")},ref:function(t){e.getButton=t}}},setButtonEnable:function(e){this.captchaTime&&(e=!1),this.getButton.setEnable(e)},regainCaptcha:function(){var e=this,t=0;window.clearInterval(e.captchaTime),this.captchaTime=window.setInterval((function(){if(60===t)return window.clearInterval(e.captchaTime),e.captchaTime=null,e.getButton.setText(BI.i18nText("Designer-Login_Code_Request")),void e.setButtonEnable(!0);e.getButton.setText(BI.i18nText("Designer-Login_Code_Request_Again")+"("+(60-t)+")"),t++}),1e3),this.setButtonEnable(!1)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Model=t.className=void 0,t.className="designer.login.model.sms_method",t.Model=BI.inherit(Fix.Model,{context:[""],state:function(){return{errMessage:"",isRegister:!1,regToken:""}},actions:{setErrMessage:function(e){this.model.errMessage=e},setRegister:function(e){this.model.isRegister=e},setRegToken:function(e){this.model.regToken=e}}}),BI.store(t.className,t.Model),t["default"]=t.className},function(e,t,i){}]); \ No newline at end of file +!function(e){var t={};function i(o){if(t[o])return t[o].exports;var s=t[o]={i:o,l:!1,exports:{}};return e[o].call(s.exports,s,s.exports,i),s.l=!0,s.exports}i.m=e,i.c=t,i.d=function(e,t,o){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)i.d(o,s,function(t){return e[t]}.bind(null,s));return o},i.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=4)}([function(e,t,i){"use strict";var o=this&&this.__createBinding||(Object.create?function(e,t,i,o){o===undefined&&(o=i),Object.defineProperty(e,o,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,o){o===undefined&&(o=i),e[o]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||t.hasOwnProperty(i)||o(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),s(i(5),t)},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=window.DesignerLoginHelper,s=function(){function e(){}return e.prototype.getParams=function(){return{designerLoginSource:window.designerLoginSource||"0",lastLoginType:window.lastLoginType||"-1",lastLoginAccount:window.lastLoginAccount||""}},e.prototype.closeWindow=function(e){o&&o.closeWindow(e)},e.prototype.serviceHref=function(){o?o.serviceHref():window.open("https://bbs.fanruan.com/thread-102821-1-1.html")},e.prototype.forgetHref=function(){o?o.forgetHref():window.open("https://id.fanruan.com/forget/forget.php?clue=activityf")},e.prototype.normalLogin=function(e,t,i){o?o.normalLogin(e,t,i):i(-1)},e.prototype.sendCaptcha=function(e,t,i){o?o.sendCaptcha(e,t,i):i(-1)},e.prototype.smsLogin=function(e,t,i,s){o?o.smsLogin(e,t,i,s):s(null)},e.prototype.smsRegister=function(e,t,i,s,n){o?o.smsRegister(e,t,i,s,n):n(-1)},e.prototype.resize=function(e,t){o&&o.resize(e,t)},e}();t["default"]=new s},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BBS_ERROR_CODE=t.NORMAL_LOGIN_RESULT=t.REGION=t.LOGIN=void 0,t.LOGIN={NORMAL_METHOD:"normal",SMS_METHOD:"sms",TABS:{LOGIN:"login",FORGET_PASSWORD:"forget",RESET_PASSWORD:"reset",REGISTER:"register"}},t.REGION=[{value:"+86",text:"Designer-Basic_Chinese_Mainland"},{value:"+886",text:"Designer-Basic_Chinese_Taiwan"},{value:"+852",text:"Designer-Basic_Chinese_Hong_Kong"},{value:"+853",text:"Designer-Basic_Chinese_Macao"},{value:"+90",text:"Designer-Basic_Turkey"},{value:"+82",text:"Designer-Basic_South_Korea"},{value:"+81",text:"Designer-Basic_Japan"},{value:"+65",text:"Designer-Basic_Singapore"},{value:"+60",text:"Designer-Basic_Malaysia"}],t.NORMAL_LOGIN_RESULT=[{status:0,message:"Designer-Login_Internal_Error"},{status:-1,message:"Designer-Login_Store_User_Not_Exist"},{status:-2,message:"Designer-Login_Store_User_Password_Error"},{status:-3,message:"Designer-Login_Unexpected_Error"},{status:-4,message:"Designer-Login_Network_Connected_Failed"},{status:-5,message:"Designer-Login_Failed_Exceed_Limit"}],t.BBS_ERROR_CODE=[{status:0,message:"Designer-Login_Internal_Error"},{status:-1,message:"Designer-BBS_Register_Timeout"},{status:-2,message:"Designer-BBS_Phone_Is_Register"},{status:-3,message:"Designer-BBS_Captcha_Send_Exceed_Limit"},{status:-4,message:"Designer-BBS_Phone_Format_Error"},{status:-100,message:"Designer-BBS_Captcha_Out_Of_Date"},{status:-101,message:"Designer-BBS_Captcha_Try_Exceed_Limit"},{status:-102,message:"Designer-BBS_Captcha_Error"},{status:-104,message:"Designer-BBS_Username_Format_Error"},{status:-103,message:"Designer-BBS_Please_Enter_Correct_Phone"},{status:-105,message:"Designer-BBS_Username_Too_Short"},{status:-106,message:"Designer-BBS_Username_Too_Long"},{status:-107,message:"Designer-BBS_Phone_Is_Register"},{status:-108,message:"Designer-BBS_Username_Is_Register"}]},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getError=void 0,t.getError=function(e,t){var i=BI.find(e,(function(e,i){return i.status===t}));return i&&i.message?i.message:""}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var o=i(0),s=i(6);BI.addI18n(Store.i18n),BI.createWidget({type:o.Vertical,element:"body",items:[{type:s["default"]}]})},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ListView=t.VirtualGroup=t.LeftRightVerticalAdapt=t.Left=t.Horizontal=t.Vertical=t.Absolute=t.Layout=t.Htape=t.CenterAdapt=t.Vtape=t.HorizontalAdapt=t.VerticalAdapt=t.BubbleCombo=t.Img=t.Tab=t.SingleSelectInsertCombo=t.SingleSelectRadioItem=t.MultiTreePopupView=t.Editor=t.NicEditor=t.RichEditor=t.MultiTreeCombo=t.DynamicDateTimeCombo=t.DynamicDateCombo=t.BarPopOver=t.MultiSelectItem=t.TextAreaEditor=t.AllValueChooserCombo=t.ButtonGroup=t.MultiSelectInsertCombo=t.TextEditor=t.Button=t.SignEditor=t.MultiFileEditor=t.SmallTextEditor=t.HtmlLabel=t.Label=t.DownListCombo=t.TextButton=t.IconChangeButton=t.IconButton=t.IconTextIconItem=t.IconTextItem=void 0,t.IconTextItem="bi.icon_text_item",t.IconTextIconItem="bi.icon_text_icon_item",t.IconButton="bi.icon_button",t.IconChangeButton="bi.icon_change_button",t.TextButton="bi.text_button",t.DownListCombo="bi.down_list_combo",t.Label="bi.label",t.HtmlLabel="bi.html_label",t.SmallTextEditor="bi.small_text_editor",t.MultiFileEditor="bi.multifile_editor",t.SignEditor="bi.sign_editor",t.Button="bi.button",t.TextEditor="bi.text_editor",t.MultiSelectInsertCombo="bi.multi_select_insert_combo",t.ButtonGroup="bi.button_group",t.AllValueChooserCombo="bi.all_value_chooser_combo",t.TextAreaEditor="bi.textarea_editor",t.MultiSelectItem="bi.multi_select_item",t.BarPopOver="bi.bar_popover",t.DynamicDateCombo="bi.dynamic_date_combo",t.DynamicDateTimeCombo="bi.dynamic_date_time_combo",t.MultiTreeCombo="bi.multi_tree_combo",t.RichEditor="bi.rich_editor",t.NicEditor="bi.nic_editor",t.Editor="bi.editor",t.MultiTreePopupView="bi.multi_tree_popup_view",t.SingleSelectRadioItem="bi.single_select_radio_item",t.SingleSelectInsertCombo="bi.single_select_insert_combo",t.Tab="bi.tab",t.Img="bi.img",t.BubbleCombo="bi.bubble_combo",t.VerticalAdapt="bi.vertical_adapt",t.HorizontalAdapt="bi.horizontal_adapt",t.Vtape="bi.vtape",t.CenterAdapt="bi.center_adapt",t.Htape="bi.htape",t.Layout="bi.layout",t.Absolute="bi.absolute",t.Vertical="bi.vertical",t.Horizontal="bi.horizontal",t.Left="bi.left",t.LeftRightVerticalAdapt="bi.left_right_vertical_adapt",t.VirtualGroup="bi.virtual_group",t.ListView="bi.list_view"},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(7),n=i(8),r=i(9),a=i(11);i(25),t.className="designer.login.login",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login",width:420},_store:function(){return BI.Models.getModel(s["default"])},watch:{loading:function(e){this.loading.setVisible(e)}},render:function(){return{type:o.Vertical,cls:"designer-login",items:[{el:{type:o.HorizontalAdapt,items:[{type:n["default"],rgap:14,tgap:14}]}},{el:{type:o.Vertical,items:[{type:r["default"]},{type:a["default"]}]},lgap:15,rgap:15,bgap:15}]}}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});BI.model("designer.login.login.model",BI.inherit(Fix.Model,{childContext:["loading"],state:function(){return{loading:!1}}})),t["default"]="designer.login.login.model"},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(1);t.className="designer.login.login.close.button",t.Widget=BI.inherit(BI.Widget,{render:function(){return{type:o.TextButton,text:String.fromCharCode(10005),cls:"background-login-close",width:18.38,height:18.38,handler:function(){s["default"].closeWindow(!1)}}}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0);i(10),t.className="designer.login.login.title",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-title"},render:function(){return{type:o.Label,text:BI.i18nText("Designer-Login_Title"),cls:"bi-font-bold",bgap:10}}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(12);i(13);var n=i(14),r=i(16),a=i(18),l=i(2),u=i(1),d=249.64,g=331.64,c=422,p=478,h=560;t.className="designer.login.login.body",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},_store:function(){return BI.Stores.getStore(s["default"])},watch:{loginMethod:function(e){this.tabOption.setValue(e),this.tab.setSelect(e),this.foot.setLoginMethod(e),this.refreshLoginButton(),e===l.LOGIN.NORMAL_METHOD?(this.tab.setHeight(d),u["default"].resize(c,p)):this.model.expand&&(u["default"].resize(c,h),this.tab.setHeight(g))},approve:function(e){this.refreshLoginButton()},expand:function(e){e&&(u["default"].resize(c,h),this.tab.setHeight(g))}},render:function(){var e=this;return{type:o.Vertical,cls:"designer-login-body",items:[{type:o.ButtonGroup,value:this.model.loginMethod,ref:function(t){e.tabOption=t},layouts:[{type:o.HorizontalAdapt}],items:[{cls:"designer-login-change-mode bi-list-item-effect bi-border-bottom bi-font-bold",width:70,height:28,value:l.LOGIN.SMS_METHOD,text:BI.i18nText("Designer-Login_Sms")},{cls:"designer-login-change-mode bi-list-item-effect bi-border-bottom bi-font-bold",width:70,height:28,value:l.LOGIN.NORMAL_METHOD,text:BI.i18nText("Designer-Login_Normal")}],listeners:[{eventName:BI.ButtonGroup.EVENT_CHANGE,action:function(t){e.store.setLoginMethod(t)}}],tgap:24,lgap:75,rgap:75},{type:o.CenterAdapt,tgap:35,items:[{type:o.Tab,cardCreator:BI.bind(this.createCard,this),showIndex:this.model.loginMethod,ref:function(t){e.tab=t},height:d,width:280}]},{type:n["default"],lgap:50,rgap:50,bgap:30,ref:function(t){e.foot=t},refreshStatus:function(t){e.store.setApprove(t)}}]}},mounted:function(){var e=u["default"].getParams(),t=e.designerLoginSource,i=e.lastLoginType;if("2"===t){var o="0"===i?l.LOGIN.NORMAL_METHOD:l.LOGIN.SMS_METHOD;this.store.setLoginMethod(o)}},createCard:function(e){var t=this;switch(e){case l.LOGIN.NORMAL_METHOD:return{type:r["default"],ref:function(e){t.normalMethod=e}};case l.LOGIN.SMS_METHOD:default:return{type:a["default"],ref:function(e){t.smsMethod=e},expand:function(){t.store.setExpand(!0)}}}},refreshLoginButton:function(){this.model.loginMethod===l.LOGIN.NORMAL_METHOD?this.normalMethod.setApprove(this.model.approve):this.smsMethod.setApprove(this.model.approve)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Model=t.className=void 0;var o=i(2);t.className="designer.login.model.login.body",t.Model=BI.inherit(Fix.Model,{context:["loading"],state:function(){return{loginMethod:o.LOGIN.SMS_METHOD,approve:!0,expand:!1}},actions:{setLoginMethod:function(e){this.model.loginMethod=e},setApprove:function(e){this.model.approve=e},setExpand:function(e){this.model.expand=e}}}),BI.store(t.className,t.Model),t["default"]=t.className},function(e,t,i){},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(1),s=i(0);i(15);var n=i(2);t.className="designer.login.login.foot",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-foot"},render:function(){var e=this,t=this.options;return{type:s.LeftRightVerticalAdapt,items:{left:[{type:s.MultiSelectItem,width:30,selected:!0,handler:function(){t.refreshStatus(this.isSelected())}},{type:s.Label,cls:"login-foot-text",textAlign:"left",text:BI.i18nText("Designer-Login_I_Have_Read")},{type:s.Label,cls:"login-foot-text",textAlign:"left",text:"《"},{type:s.TextButton,cls:"login-link",textAlign:"left",text:BI.i18nText("Designer-Login_Service_Terms"),handler:function(){o["default"].serviceHref()}},{type:s.Label,cls:"login-foot-text",textAlign:"left",text:"》"}],right:[{type:s.TextButton,cls:"login-link",textAlign:"right",text:BI.i18nText("Designer-Login_Forget_Password"),invisible:!0,tgap:2,ref:function(t){e.forgetPassword=t},handler:function(){o["default"].forgetHref()}}]}}},setLoginMethod:function(e){e===n.LOGIN.NORMAL_METHOD?this.forgetPassword.setVisible(!0):this.forgetPassword.setVisible(!1)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(3),n=i(1),r=i(17),a=i(2);t.className="designer.login.login.normal",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},_store:function(){return BI.Stores.getStore(r["default"])},watch:{errMessage:function(e){this.errMessage.setText(e)}},render:function(){var e=this;return{type:o.Vertical,items:[{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_User_Name"),bgap:3},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-username",watermark:BI.i18nText("Designer-Login_User_Name_Hint"),inputType:"text",allowBlank:!0,height:40,ref:function(t){e.userName=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Password"),bgap:3},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-password",watermark:BI.i18nText("Designer-Login_Password_Hint"),inputType:"password",allowBlank:!0,height:40,ref:function(t){e.password=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:o.Label,cls:"designer-login-error-message",textAlign:"center",text:"",height:20,bgap:10,ref:function(t){e.errMessage=t}},{type:o.Button,cls:"login-login-button bi-font-bold",text:BI.i18nText("Designer-Login"),level:"common",height:40,ref:function(t){e.loginButton=t},handler:function(){e.login()}}]}},mounted:function(){var e=this;this.element.keyup((function(t){13===t.keyCode&&e.login()}));var t=n["default"].getParams(),i=t.designerLoginSource,o=t.lastLoginType,s=t.lastLoginAccount;"2"===i&&"0"===o&&e.userName.setValue(s)},checkUsername:function(){var e=this.userName.getValue();e&&this.userName.setValue(e.replace(/\s+/g,""))},login:function(){var e=this;e.checkUsername();var t=this.userName.getValue(),i=this.password.getValue();t?i?n["default"].normalLogin(t,i,(function(t){var i=parseInt(t,10);if(i>0)n["default"].closeWindow(!0);else{var o=s.getError(a.NORMAL_LOGIN_RESULT,i);o&&e.store.setErrMessage(BI.i18nText(o))}})):this.store.setErrMessage(BI.i18nText("Designer-Login_Password_Not_Null")):this.store.setErrMessage(BI.i18nText("Designer-Login_Username_Not_Null"))},setApprove:function(e){this.loginButton.setEnable(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Model=t.className=void 0,t.className="designer.login.model.normal_method",t.Model=BI.inherit(Fix.Model,{context:[""],state:function(){return{errMessage:""}},actions:{setErrMessage:function(e){this.model.errMessage=e}}}),BI.store(t.className,t.Model),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0),s=i(19),n=i(22),r=i(23),a=i(2),l=i(24),u=i(1),d=i(3);t.className="designer.login.login.sms",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},_store:function(){return BI.Stores.getStore(l["default"])},watch:{errMessage:function(e){this.errMessage.setText(e)},isRegister:function(e){var t=this.options;e&&(t.expand(),this.password.setVisible(!0),this.passwordLabel.setVisible(!0))}},render:function(){var e=this,t=this;return{type:o.Vertical,items:[{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Phone"),bgap:3},{type:o.HorizontalAdapt,bgap:7,items:[{type:s["default"],height:42,textFormatter:function(e){var i=t.getNumberTypeItem(e);return{value:i.value,text:BI.i18nText(i.text)}},value:a.REGION[0].value,items:BI.map(a.REGION,(function(e,t){return{type:n["default"],value:t.value,label:BI.i18nText(t.text),text:t.value}})),ref:function(t){e.regionCode=t}},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-username",watermark:BI.i18nText("Designer-Login_Phone_Hint"),inputType:"text",allowBlank:!0,height:40,ref:function(t){e.phone=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]}]},{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Code"),bgap:3},{type:o.Horizontal,bgap:7,items:[{type:o.Editor,cls:"bi-border-bottom designer-login-editor-password",watermark:BI.i18nText("Designer-Login_Code_Hint"),inputType:"text",allowBlank:!0,height:40,width:190,ref:function(t){e.code=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:r["default"],height:40,width:90,ref:function(t){e.accountCaptcha=t},listeners:[{eventName:"EVENT_SEND",action:function(){t.sendCaptcha()}}]}]},{type:o.Label,textAlign:"left",cls:"designer-login-text",text:BI.i18nText("Designer-Login_Password"),bgap:3,invisible:!0,ref:function(t){e.passwordLabel=t}},{type:o.Editor,cls:"bi-border-bottom designer-login-editor-password",watermark:BI.i18nText("Designer-Login_Password_Setting_Hint"),inputType:"password",allowBlank:!0,height:40,invisible:!0,ref:function(t){e.password=t},listeners:[{eventName:"EVENT_CHANGE",action:function(){e.store.setErrMessage("")}}]},{type:o.Label,cls:"designer-login-error-message",textAlign:"center",text:"",height:20,bgap:11,ref:function(t){e.errMessage=t}},{type:o.Button,cls:"login-login-button bi-font-bold",text:BI.i18nText("Designer-Login_Register_Or_Login"),level:"common",height:40,ref:function(t){e.loginButton=t},handler:function(){e.login()}}]}},mounted:function(){var e=this;this.element.keyup((function(t){13===t.keyCode&&e.login()}));var t=u["default"].getParams(),i=t.designerLoginSource,o=t.lastLoginType,s=t.lastLoginAccount;if("2"===i&&"1"===o){var n=s.split("-")[0],r=s.split("-")[1];e.regionCode.setValue(n),e.phone.setValue(r)}},getNumberTypeItem:function(e){return BI.find(a.REGION,(function(t,i){return e===i.value}))||{}},checkPhone:function(){var e=this.phone.getValue();e&&this.phone.setValue(e.replace(/\s+/g,""))},login:function(){var e=this,t=this;t.checkPhone();var i=this.phone.getValue(),o=this.code.getValue();if(i)if(o){var s=this.regionCode.getValue();if(this.model.isRegister){var n=this.password.getValue();if(!n)return void this.store.setErrMessage(BI.i18nText("Designer-Login_Password_Not_Null"));var r=this.model.regToken;if(!r)return void this.store.setErrMessage(BI.i18nText("Designer-Login_Token_Request_Failed"));u["default"].smsRegister(s,i,n,r,(function(e){var i=parseInt(e,10);if(i>0)u["default"].closeWindow(!0);else{var o=d.getError(a.BBS_ERROR_CODE,i);o&&t.store.setErrMessage(BI.i18nText(o))}}))}else u["default"].smsLogin(s,i,o,(function(i){var o=JSON.parse(i);if(o.status>0)if(!0===o.register){var s=o.regtoken;s?(t.store.setRegister(!0),t.store.setRegToken(s)):e.store.setErrMessage(BI.i18nText("Designer-Login_Token_Request_Failed"))}else u["default"].closeWindow(!0);else{var n=d.getError(a.BBS_ERROR_CODE,o.status);n&&t.store.setErrMessage(BI.i18nText(n))}}))}else this.store.setErrMessage(BI.i18nText("Designer-Login_Code_Not_Null"));else this.store.setErrMessage(BI.i18nText("Designer-Login_Phone_Not_Null"))},sendCaptcha:function(){var e=this;e.checkPhone();var t=this.phone.getValue();if(!t)return e.accountCaptcha.setButtonEnable(!0),void this.store.setErrMessage(BI.i18nText("Designer-Login_Phone_Not_Null"));var i=this.regionCode.getValue();u["default"].sendCaptcha(i,t,(function(t){var i=parseInt(t,10);if(1===i)e.accountCaptcha.regainCaptcha();else{if(e.accountCaptcha.setButtonEnable(!0),0===i)return void e.store.setErrMessage(BI.i18nText("Designer-BBS_Please_Enter_Correct_Phone"));var o=d.getError(a.BBS_ERROR_CODE,i);o&&e.store.setErrMessage(BI.i18nText(o))}}))},setApprove:function(e){this.loginButton.setEnable(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(20),s=i(21);t.className="designer.left_right_text_value_combo",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"",height:24,chooseType:BI.ButtonGroup.CHOOSE_TYPE_SINGLE,textFormatter:function(e){return e},value:""},render:function(){var e=this,t=this.options;return{type:s["default"],container:t.container,adjustLength:2,ref:function(t){e.combo=t},el:{type:o["default"],cls:"text-value-trigger",items:t.items,height:t.height-2,value:t.textFormatter(t.value),ref:function(t){e.trigger=t}},popup:{el:{type:"bi.text_value_combo_popup",chooseType:t.chooseType,value:t.value,items:t.items,ref:function(t){e.popup=t},listeners:[{eventName:BI.TextValueComboPopup.EVENT_CHANGE,action:function(){e.setValue(e.getValue()),e.combo.hideView(),e.fireEvent("EVENT_CHANGE",arguments)}},{eventName:BI.Controller.EVENT_CHANGE,action:function(){e.fireEvent(BI.Controller.EVENT_CHANGE,arguments)}}]},value:t.value,maxHeight:240,minHeight:25}}},setValue:function(e){this.combo.setValue(e),this.trigger.setValue(this.options.textFormatter(e))},getValue:function(){var e=this.combo.getValue();return BI.isNull(e)?"":BI.isArray(e)?e[0]:e},populate:function(e){this.options.items=e,this.combo.populate(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0,t.className="designer.left_right_text_value_combo_trigger",t.Widget=BI.inherit(BI.Trigger,{props:{baseCls:"",value:{}},render:function(){var e=this,t=this.options,i=t.value;return{type:"bi.htape",cls:"bi-border-bottom bi-border-radius",items:[{type:"bi.label",text:i.text,title:function(){return e.textRow.getText()},height:t.height,hgap:3,textAlign:"left",ref:function(t){e.textRow=t}},{type:"bi.label",text:i.value,height:t.height,width:32,textAlign:"right",ref:function(t){e.valueRow=t}},{type:"bi.trigger_icon_button",width:t.triggerWidth||t.height}]}},setValue:function(e){this.textRow.setText(e.text),this.valueRow.setText(e.value)},setText:function(e){this.textRow.setText(e)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o={};t.className="designer.login_combo",t.Widget=BI.inherit(BI.Widget,{_defaultConfig:function(){var e=BI.Combo.superclass._defaultConfig.apply(this,arguments);return BI.extend(e,{baseCls:(e.baseCls||"")+" bi-combo"+(BI.isIE()?" hack":""),attributes:{tabIndex:-1},trigger:"click",toggle:!0,direction:"bottom",logic:{dynamic:!0},container:null,isDefaultInit:!1,destroyWhenHide:!1,hideWhenAnotherComboOpen:!1,isNeedAdjustHeight:!0,isNeedAdjustWidth:!0,stopEvent:!1,stopPropagation:!1,adjustLength:0,adjustXOffset:0,adjustYOffset:0,hideChecker:BI.emptyFn,offsetStyle:"left",el:{},popup:{},comboClass:"bi-combo-popup",hoverClass:"bi-combo-hover",belowMouse:!1})},_init:function(){BI.Combo.superclass._init.apply(this,arguments);var e=this,t=this.options;this._initCombo(),this._initPullDownAction(),this.combo.on(BI.Controller.EVENT_CHANGE,(function(t,i,o){e.isEnabled()&&e.isValid()&&(t===BI.Events.EXPAND&&e._popupView(),t===BI.Events.COLLAPSE&&e._hideView(),t===BI.Events.EXPAND&&(e.fireEvent(BI.Controller.EVENT_CHANGE,arguments),e.fireEvent(BI.Combo.EVENT_EXPAND)),t===BI.Events.COLLAPSE&&(e.fireEvent(BI.Controller.EVENT_CHANGE,arguments),e.isViewVisible()&&e.fireEvent(BI.Combo.EVENT_COLLAPSE)),t===BI.Events.CLICK&&e.fireEvent(BI.Combo.EVENT_TRIGGER_CHANGE,o))})),e.element.on("mouseenter."+e.getName(),(function(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&e.element.addClass(t.hoverClass)})),e.element.on("mouseleave."+e.getName(),(function(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&e.element.removeClass(t.hoverClass)})),BI.createWidget(BI.extend({element:this},BI.LogicFactory.createLogic("vertical",BI.extend(t.logic,{items:[{el:this.combo}]})))),t.isDefaultInit&&this._assertPopupView(),BI.Resizers.add(this.getName(),BI.bind((function(e){this.isViewVisible()&&(BI.isNotNull(e)?this._hideIf(e):this._hideView())}),this))},_toggle:function(e){this._assertPopupViewRender(),this.popupView.isVisible()?this._hideView(e):this.isEnabled()&&this._popupView(e)},_initPullDownAction:function(){var e=this,t=this.options,i=(this.options.trigger||"").split(","),o=function(e){t.stopEvent&&e.stopEvent(),t.stopPropagation&&e.stopPropagation()},s=!1;function n(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&!0===t.toggle&&(e._hideView(i),e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.COLLAPSE,"",e.combo),e.fireEvent(BI.Combo.EVENT_COLLAPSE)),e.popupView&&e.popupView.element.off("mouseenter."+e.getName()).off("mouseleave."+e.getName()),s=!1}BI.each(i,(function(i,r){switch(r){case"hover":e.element.on("mouseenter."+e.getName(),(function(t){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&(e._popupView(t),e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.EXPAND,"",e.combo),e.fireEvent(BI.Combo.EVENT_EXPAND))})),e.element.on("mouseleave."+e.getName(),(function(t){e.popupView&&(e.popupView.element.on("mouseenter."+e.getName(),(function(t){s=!0,e.popupView.element.on("mouseleave."+e.getName(),(function(e){n(e)})),e.popupView.element.off("mouseenter."+e.getName())})),BI.defer((function(){s||n(t)}),50))}));break;case"click":var a=BI.debounce((function(i){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&(t.toggle?e._toggle(i):e._popupView(i),e.isViewVisible()?(e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.EXPAND,"",e.combo),e.fireEvent(BI.Combo.EVENT_EXPAND)):(e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.COLLAPSE,"",e.combo),e.fireEvent(BI.Combo.EVENT_COLLAPSE)))}),BI.EVENT_RESPONSE_TIME,{leading:!0,trailing:!1});e.element.off(r+"."+e.getName()).on(r+"."+e.getName(),(function(e){a(e),o(e)}));break;case"click-hover":a=BI.debounce((function(t){e.isEnabled()&&e.isValid()&&e.combo.isEnabled()&&e.combo.isValid()&&(e._popupView(t),e.isViewVisible()&&(e.fireEvent(BI.Controller.EVENT_CHANGE,BI.Events.EXPAND,"",e.combo),e.fireEvent(BI.Combo.EVENT_EXPAND)))}),BI.EVENT_RESPONSE_TIME,{leading:!0,trailing:!1});e.element.off("click."+e.getName()).on("click."+e.getName(),(function(e){a(e),o(e)})),e.element.on("mouseleave."+e.getName(),(function(t){e.popupView&&(e.popupView.element.on("mouseenter."+e.getName(),(function(t){s=!0,e.popupView.element.on("mouseleave."+e.getName(),(function(e){n(e)})),e.popupView.element.off("mouseenter."+e.getName())})),BI.delay((function(){s||n(t)}),50))}))}}))},_initCombo:function(){this.combo=BI.createWidget(this.options.el,{value:this.options.value})},_assertPopupView:function(){var e=this,t=this.options;null==this.popupView&&(this.popupView=BI.createWidget(this.options.popup,{type:"bi.popup_view",value:t.value},this),this.popupView.on(BI.Controller.EVENT_CHANGE,(function(t,i,o){t===BI.Events.CLICK&&(e.combo.setValue(e.getValue()),e.fireEvent(BI.Combo.EVENT_CHANGE,i,o)),e.fireEvent(BI.Controller.EVENT_CHANGE,arguments)})),this.popupView.setVisible(!1),BI.nextTick((function(){e.fireEvent(BI.Combo.EVENT_AFTER_INIT)})))},_assertPopupViewRender:function(){this._assertPopupView(),this._rendered||(BI.createWidget({type:"bi.vertical",scrolly:!1,element:this.options.container||this,items:[{el:this.popupView}]}),this._rendered=!0)},_hideIf:function(e,t){if(e&&(!0!==t&&this.element.find(e.target).length>0||this.popupView&&this.popupView.element.find(e.target).length>0||"CodeMirror-cursor"===e.target.className||BI.Widget._renderEngine.createElement(e.target).closest(".CodeMirror-hints").length>0)){var i=this.options.direction.split(",");(BI.contains(i,"innerLeft")||BI.contains(i,"innerRight"))&&(this.adjustWidth(),this.adjustHeight())}else{if(!1!==this.options.hideChecker.apply(this,[e]))return this._hideView(),!0}},_hideView:function(){this.fireEvent(BI.Combo.EVENT_BEFORE_HIDEVIEW),!0===this.options.destroyWhenHide?(this.popupView&&this.popupView.destroy(),this.popupView=null,this._rendered=!1):this.popupView&&this.popupView.invisible(),this.element.removeClass(this.options.comboClass),delete o[this.getName()],BI.Widget._renderEngine.createElement(document).unbind("mousedown."+this.getName()).unbind("mousewheel."+this.getName()),this.fireEvent(BI.Combo.EVENT_AFTER_HIDEVIEW)},_popupView:function(e){var t=this;this._assertPopupViewRender(),this.fireEvent(BI.Combo.EVENT_BEFORE_POPUPVIEW),this.popupView.css({left:-999999999,top:-99999999}),this.popupView.visible(),BI.each(o,(function(i,s){i!==t.getName()&&s&&!0===s._hideIf(e,!0)&&delete o[i]})),this.options.hideWhenAnotherComboOpen&&(o[this.getName()]=this),this.adjustWidth(e),this.adjustHeight(e),this.element.addClass(this.options.comboClass),BI.Widget._renderEngine.createElement(document).unbind("mousedown."+this.getName()).unbind("mousewheel."+this.getName()),BI.Widget._renderEngine.createElement(document).bind("mousedown."+this.getName(),BI.bind(this._hideIf,this)).bind("mousewheel."+this.getName(),BI.bind(this._hideIf,this)),this.fireEvent(BI.Combo.EVENT_AFTER_POPUPVIEW)},adjustWidth:function(e){var t=this.options;if(this.popupView&&!0===t.isNeedAdjustWidth){this.resetListWidth("");var i=this.popupView.element.outerWidth(),o=this.element.outerWidth()||t.width;i>o+80?o+=80:i>o&&(o=i),this.resetListWidth(o<100?100:o)}},adjustHeight:function(e){var t=this.options,i={top:0,adaptHeight:0,left:0};if(this.popupView){var o=this.popupView.isVisible();this.popupView.visible();var s=t.belowMouse&&BI.isNotNull(e)?{element:{offset:function(){return{left:e.pageX,top:e.pageY}},bounds:function(){return{x:e.offsetX,y:e.offsetY,width:0,height:24}},outerWidth:function(){return 0},outerHeight:function(){return 24}}}:this.combo;switch(t.direction){case"bottom":case"bottom,right":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["bottom","top","right","left"],t.offsetStyle);break;case"top":case"top,right":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["top","bottom","right","left"],t.offsetStyle);break;case"left":case"left,bottom":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["left","right","bottom","top"],t.offsetStyle);break;case"right":case"right,bottom":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","bottom","top"],t.offsetStyle);break;case"top,left":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["top","bottom","left","right"],t.offsetStyle);break;case"bottom,left":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight,["bottom","top","left","right"],t.offsetStyle);break;case"left,top":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["left","right","top","bottom"],t.offsetStyle);break;case"right,top":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","top","bottom"],t.offsetStyle);break;case"right,innerRight":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","innerRight","innerLeft","bottom","top"],t.offsetStyle);break;case"right,innerLeft":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["right","left","innerLeft","innerRight","bottom","top"],t.offsetStyle);break;case"innerRight":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["innerRight","innerLeft","right","left","bottom","top"],t.offsetStyle);break;case"innerLeft":i=BI.DOM.getComboPosition(s,this.popupView,t.adjustXOffset||t.adjustLength,t.adjustYOffset,t.isNeedAdjustHeight,["innerLeft","innerRight","left","right","bottom","top"],t.offsetStyle);break;case"top,custom":case"custom,top":i=BI.DOM.getTopAdaptPosition(s,this.popupView,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight);break;case"custom,bottom":case"bottom,custom":i=BI.DOM.getBottomAdaptPosition(s,this.popupView,t.adjustYOffset||t.adjustLength,t.isNeedAdjustHeight);break;case"left,custom":case"custom,left":delete(i=BI.DOM.getLeftAdaptPosition(s,this.popupView,t.adjustXOffset||t.adjustLength)).top,delete i.adaptHeight;break;case"custom,right":case"right,custom":delete(i=BI.DOM.getRightAdaptPosition(s,this.popupView,t.adjustXOffset||t.adjustLength)).top,delete i.adaptHeight}"adaptHeight"in i&&this.resetListHeight(i.adaptHeight),"left"in i&&this.popupView.element.css({left:i.left}),"top"in i&&this.popupView.element.css({top:i.top}),this.position=i,this.popupView.setVisible(o)}},resetListHeight:function(e){this._assertPopupView(),this.popupView.resetHeight&&this.popupView.resetHeight(e)},resetListWidth:function(e){this._assertPopupView(),this.popupView.resetWidth&&this.popupView.resetWidth(e)},populate:function(e){this._assertPopupView(),this.popupView.populate.apply(this.popupView,arguments),this.combo.populate&&this.combo.populate.apply(this.combo,arguments)},_setEnable:function(e){BI.Combo.superclass._setEnable.apply(this,arguments),!0===e?this.element.removeClass("base-disabled disabled"):!1===e&&this.element.addClass("base-disabled disabled"),!e&&this.element.removeClass(this.options.hoverClass),!e&&this.isViewVisible()&&this._hideView()},setValue:function(e){this.combo.setValue(e),BI.isNull(this.popupView)?this.options.popup.value=e:this.popupView.setValue(e)},getValue:function(){return BI.isNull(this.popupView)?this.options.popup.value:this.popupView.getValue()},isViewVisible:function(){return this.isEnabled()&&this.combo.isEnabled()&&!!this.popupView&&this.popupView.isVisible()},showView:function(e){this.isEnabled()&&this.combo.isEnabled()&&!this.isViewVisible()&&this._popupView(e)},hideView:function(){this._hideView()},getView:function(){return this.popupView},getPopupPosition:function(){return this.position},toggle:function(){this._toggle()},destroyed:function(){BI.Widget._renderEngine.createElement(document).unbind("click."+this.getName()).unbind("mousedown."+this.getName()).unbind("mousewheel."+this.getName()).unbind("mouseenter."+this.getName()).unbind("mousemove."+this.getName()).unbind("mouseleave."+this.getName()).unbind("blur."+this.getName()),BI.Resizers.remove(this.getName()),this.popupView&&this.popupView._destroy(),delete o[this.getName()]}}),BI.Combo.EVENT_TRIGGER_CHANGE="EVENT_TRIGGER_CHANGE",BI.Combo.EVENT_CHANGE="EVENT_CHANGE",BI.Combo.EVENT_EXPAND="EVENT_EXPAND",BI.Combo.EVENT_COLLAPSE="EVENT_COLLAPSE",BI.Combo.EVENT_AFTER_INIT="EVENT_AFTER_INIT",BI.Combo.EVENT_BEFORE_POPUPVIEW="EVENT_BEFORE_POPUPVIEW",BI.Combo.EVENT_AFTER_POPUPVIEW="EVENT_AFTER_POPUPVIEW",BI.Combo.EVENT_BEFORE_HIDEVIEW="EVENT_BEFORE_HIDEVIEW",BI.Combo.EVENT_AFTER_HIDEVIEW="EVENT_AFTER_HIDEVIEW",BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0,t.className="designer.components.phone.editor.item",t.Widget=BI.inherit(BI.BasicButton,{props:{baseCls:"designer-login-login-body",label:"",text:""},render:function(){var e=this.options;return{type:"bi.htape",items:[{el:{type:"bi.label",text:e.label,title:e.label,textAlign:"left"},lgap:10,rgap:5},{el:{type:"bi.label",text:e.text,textAlign:"right"},width:32,rgap:10}]}},doClick:function(){BI.SingleSelectItem.superclass.doClick.apply(this,arguments),this.isValid()&&this.fireEvent("EVENT_CHANGE",this.isSelected(),this)},setSelected:function(e){BI.SingleSelectItem.superclass.setSelected.apply(this,arguments)},getValue:function(){return this.options.value}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Widget=t.className=void 0;var o=i(0);t.className="designer.user.account.setting.captcha",t.Widget=BI.inherit(BI.Widget,{props:{baseCls:"designer-login-login-body"},render:function(){var e=this;this.options;return{type:o.TextButton,text:BI.i18nText("Designer-Login_Code_Request"),cls:"designer-login-border-bottom designer-login-code-text",handler:function(){e.setButtonEnable(!1),e.fireEvent("EVENT_SEND")},ref:function(t){e.getButton=t}}},setButtonEnable:function(e){this.captchaTime&&(e=!1),this.getButton.setEnable(e)},regainCaptcha:function(){var e=this,t=0;window.clearInterval(e.captchaTime),this.captchaTime=window.setInterval((function(){if(60===t)return window.clearInterval(e.captchaTime),e.captchaTime=null,e.getButton.setText(BI.i18nText("Designer-Login_Code_Request")),void e.setButtonEnable(!0);e.getButton.setText(BI.i18nText("Designer-Login_Code_Request_Again")+"("+(60-t)+")"),t++}),1e3),this.setButtonEnable(!1)}}),BI.shortcut(t.className,t.Widget),t["default"]=t.className},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Model=t.className=void 0,t.className="designer.login.model.sms_method",t.Model=BI.inherit(Fix.Model,{context:[""],state:function(){return{errMessage:"",isRegister:!1,regToken:""}},actions:{setErrMessage:function(e){this.model.errMessage=e},setRegister:function(e){this.model.isRegister=e},setRegToken:function(e){this.model.regToken=e}}}),BI.store(t.className,t.Model),t["default"]=t.className},function(e,t,i){}]); \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/standard/system/add.svg b/designer-base/src/main/resources/com/fr/design/standard/system/add.svg new file mode 100755 index 0000000000..cccd52cb5c --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/standard/system/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fr/design/standard/system/add_hover.svg b/designer-base/src/main/resources/com/fr/design/standard/system/add_hover.svg new file mode 100644 index 0000000000..777e87831e --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/standard/system/add_hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fr/design/standard/system/cpt.svg b/designer-base/src/main/resources/com/fr/design/standard/system/cpt.svg new file mode 100755 index 0000000000..0fcdcf70ae --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/standard/system/cpt.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/standard/system/home_folder.svg b/designer-base/src/main/resources/com/fr/design/standard/system/home_folder.svg new file mode 100755 index 0000000000..eaf43b0cf8 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/standard/system/home_folder.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-base/src/main/resources/com/fr/design/standard/system/remote_connect.svg b/designer-base/src/main/resources/com/fr/design/standard/system/remote_connect.svg new file mode 100755 index 0000000000..514e4c5006 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/standard/system/remote_connect.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/create_new_template.svg b/designer-base/src/main/resources/com/fr/design/startup/create_new_template.svg new file mode 100755 index 0000000000..fd61e745be --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/create_new_template.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/local_server_background_28.svg b/designer-base/src/main/resources/com/fr/design/startup/local_server_background_28.svg new file mode 100755 index 0000000000..a79e502777 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/local_server_background_28.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/local_server_background_36.svg b/designer-base/src/main/resources/com/fr/design/startup/local_server_background_36.svg new file mode 100644 index 0000000000..8ea966cbc4 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/local_server_background_36.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/more.svg b/designer-base/src/main/resources/com/fr/design/startup/more.svg new file mode 100755 index 0000000000..65f7b7c701 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/more.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/more_hover.svg b/designer-base/src/main/resources/com/fr/design/startup/more_hover.svg new file mode 100644 index 0000000000..5b4ee1d6fd --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/more_hover.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/remote_server_background_28.svg b/designer-base/src/main/resources/com/fr/design/startup/remote_server_background_28.svg new file mode 100755 index 0000000000..da22546f98 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/remote_server_background_28.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/remote_server_background_36.svg b/designer-base/src/main/resources/com/fr/design/startup/remote_server_background_36.svg new file mode 100755 index 0000000000..d10b2700a0 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/remote_server_background_36.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/show_less.svg b/designer-base/src/main/resources/com/fr/design/startup/show_less.svg new file mode 100755 index 0000000000..b929630e7f --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/show_less.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fr/design/startup/show_more.svg b/designer-base/src/main/resources/com/fr/design/startup/show_more.svg new file mode 100755 index 0000000000..1b7c059d97 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/startup/show_more.svg @@ -0,0 +1,3 @@ + + + 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 090838fd0c..cab7037cd2 100644 --- a/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java +++ b/designer-base/src/test/java/com/fr/design/EnvChangeEntranceTest.java @@ -1,12 +1,12 @@ package com.fr.design; -import com.fr.decision.webservice.v10.plugin.helper.PluginErrorRemindHandler; +import com.fr.design.plugin.remind.PluginErrorDesignReminder; +import com.fr.plugin.error.PluginErrorRemindHandler; import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.design.env.DesignerWorkspaceType; import com.fr.design.env.LocalDesignerWorkspaceInfo; import com.fr.design.env.RemoteDesignerWorkspaceInfo; import com.fr.env.CheckServiceDialog; -import com.fr.env.PluginErrorRemindDialog; import com.fr.invoke.Reflect; import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; @@ -108,33 +108,4 @@ public class EnvChangeEntranceTest { Assert.assertFalse(Reflect.on(entrance).call("isNotRememberPwd", info3).get()); Assert.assertFalse(Reflect.on(entrance).call("isNotRememberPwd", info4).get()); } - - @Test - public void testPluginErrorRemind() { - - try { - - Workspace workspace = EasyMock.mock(Workspace.class); - EasyMock.expect(workspace.isLocal()).andReturn(false).once(); - EasyMock.expect(workspace.isLocal()).andReturn(true).once(); - PowerMock.mockStatic(WorkContext.class); - EasyMock.expect(WorkContext.getCurrent()).andReturn(workspace).anyTimes(); - - PowerMock.mockStatic(PluginErrorRemindHandler.class); - EasyMock.expect(PluginErrorRemindHandler.pluginErrorContent()).andReturn("").once(); - - EasyMock.replay(workspace); - PowerMock.replayAll(); - - EnvChangeEntrance entrance = EnvChangeEntrance.getInstance(); - - entrance.pluginErrorRemind(); - entrance.pluginErrorRemind(); - - EasyMock.verify(workspace); - PowerMock.verifyAll(); - } catch (Exception e) { - Assert.fail(); - } - } -} \ No newline at end of file +} diff --git a/designer-base/src/test/java/com/fr/design/plugin/remind/PluginErrorDesignReminderTest.java b/designer-base/src/test/java/com/fr/design/plugin/remind/PluginErrorDesignReminderTest.java new file mode 100644 index 0000000000..b7df5af5a7 --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/plugin/remind/PluginErrorDesignReminderTest.java @@ -0,0 +1,72 @@ +package com.fr.design.plugin.remind; + +import com.fr.plugin.error.PluginErrorRemindHandler; +import com.fr.workspace.WorkContext; +import com.fr.workspace.empty.EmptyWorkspace; +import junit.framework.TestCase; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.powermock.api.easymock.PowerMock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author Yvan + */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(PluginErrorRemindHandler.class) +public class PluginErrorDesignReminderTest extends TestCase { + + @Before + public void before() { + WorkContext.switchTo(EmptyWorkspace.getInstance()); + } + + public void testRemindStartFailedPlugins() { + PowerMock.mockStatic(PluginErrorRemindHandler.class); + EasyMock.expect(PluginErrorRemindHandler.pluginErrorContent()).andReturn("").once(); + + PowerMock.replayAll(); + PluginErrorDesignReminder.getInstance().remindStartFailedPlugins(); + + PowerMock.verifyAll(); + } + + public void testRemindInvalidatePlugins() { + PowerMock.mockStatic(PluginErrorRemindHandler.class); + EasyMock.expect(PluginErrorRemindHandler.getInvalidateEmbedPluginNames()).andReturn(new ArrayList<>()).once(); + + PowerMock.replayAll(); + PluginErrorDesignReminder.getInstance().remindInvalidatePlugins(); + + PowerMock.verifyAll(); + } + + public void testDealWithPluginNames() { + List pluginNames1 = Arrays.asList("1"); + String content1 = PluginErrorDesignReminder.getInstance().dealWithPluginNames(pluginNames1); + Assert.assertFalse(content1.contains(PluginErrorDesignReminder.COMMA)); + Assert.assertFalse(content1.contains(PluginErrorDesignReminder.NEW_LINE_TAG)); + + List pluginNames2 = Arrays.asList("1", "2"); + String content2 = PluginErrorDesignReminder.getInstance().dealWithPluginNames(pluginNames2); + Assert.assertTrue(content2.contains(PluginErrorDesignReminder.COMMA)); + Assert.assertFalse(content2.contains(PluginErrorDesignReminder.NEW_LINE_TAG)); + + List pluginNames3 = Arrays.asList("1", "2", "3", "4"); + String content3 = PluginErrorDesignReminder.getInstance().dealWithPluginNames(pluginNames3); + Assert.assertTrue(content3.contains(PluginErrorDesignReminder.COMMA)); + Assert.assertTrue(content3.contains(PluginErrorDesignReminder.NEW_LINE_TAG)); + + List pluginNames4 = Arrays.asList("1", "2", "3"); + String content4 = PluginErrorDesignReminder.getInstance().dealWithPluginNames(pluginNames4); + Assert.assertTrue(content4.contains(PluginErrorDesignReminder.COMMA)); + Assert.assertFalse(content4.contains(PluginErrorDesignReminder.NEW_LINE_TAG)); + } +} diff --git a/designer-base/src/test/java/com/fr/design/utils/DevDebugUtils.java b/designer-base/src/test/java/com/fr/design/utils/DevDebugUtils.java index af1d984ea4..60a294d260 100644 --- a/designer-base/src/test/java/com/fr/design/utils/DevDebugUtils.java +++ b/designer-base/src/test/java/com/fr/design/utils/DevDebugUtils.java @@ -7,6 +7,6 @@ public class DevDebugUtils { public static void main(String[] args) { - org.swingexplorer.Launcher.main(new String[]{"com.fr.design.utils.DevUtils"}); + org.swingexplorer.Launcher.main(new String[]{"com.fr.startup.ui.StartupPageWindowTest"}); } } diff --git a/designer-base/src/test/java/com/fr/design/utils/DevUtils.java b/designer-base/src/test/java/com/fr/design/utils/DevUtils.java index 2d88277555..dcba96f05f 100644 --- a/designer-base/src/test/java/com/fr/design/utils/DevUtils.java +++ b/designer-base/src/test/java/com/fr/design/utils/DevUtils.java @@ -48,6 +48,12 @@ public class DevUtils { } + public static void show(Runnable runnable) { + + DesignUtils.initLookAndFeel(); + UIUtil.invokeLaterIfNeeded(runnable); + } + public static void main(String[] args) { DevUtils.prepare(); diff --git a/designer-base/src/test/java/com/fr/startup/ui/StartupPageWindowTest.java b/designer-base/src/test/java/com/fr/startup/ui/StartupPageWindowTest.java new file mode 100644 index 0000000000..c1d33a66a6 --- /dev/null +++ b/designer-base/src/test/java/com/fr/startup/ui/StartupPageWindowTest.java @@ -0,0 +1,32 @@ +package com.fr.startup.ui; + +import com.fr.design.utils.DevUtils; +import com.fr.third.guava.collect.Lists; + +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class StartupPageWindowTest { + + public static void main(String[] args) { + + DevUtils.show(new Runnable() { + @Override + public void run() { + HashMap> recentOpenFileMap = new HashMap<>(); + recentOpenFileMap.put("111", Lists.newArrayList("111.cpt", "222//3333.cpt","333.cpt", "444.cpt", "555.cpt", "666.cpt")); + StartupPageModel model = new StartupPageModel(Stream.of( + StartupWorkspaceBean.create("111", "222333344455556663333444555566633334445555666"), StartupWorkspaceBean.create("113", "222"), + StartupWorkspaceBean.create("114", "222"), StartupWorkspaceBean.create("115", "222"), StartupWorkspaceBean.create("116", "222"), + StartupWorkspaceBean.create("117", "222"), StartupWorkspaceBean.create("118", "222"), StartupWorkspaceBean.create("119", "222"), + StartupWorkspaceBean.create("121", "222"), StartupWorkspaceBean.create("122", "222"), StartupWorkspaceBean.create("123", "222"), + StartupWorkspaceBean.create("124", "222"), StartupWorkspaceBean.create("125", "222"), StartupWorkspaceBean.create("126", "222") + ).collect(Collectors.toList()), recentOpenFileMap); + StartupPageWindow window = new StartupPageWindow(model); + window.setVisible(true); + } + }); + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeAutoChangeLine.java b/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeAutoChangeLine.java deleted file mode 100644 index 0037c738d8..0000000000 --- a/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeAutoChangeLine.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.fr.design.fit.common; - -import com.fr.base.DefaultAutoChangeLine; -import com.fr.base.Style; -import com.fr.stable.unit.UNIT; - -import java.awt.Font; -import java.util.List; - -public class NewUIModeAutoChangeLine extends DefaultAutoChangeLine { - @Override - public List textAutoChangeLine(String text, Font font, Style style, UNIT unitWidth, int resolution) { - return autoChangeLine(text, font, style, unitWidth, resolution); - } - - protected double calculateShowWidth(double paintWidth, Style style, int resolution) { - return paintWidth - style.getPaddingLeft() - style.getPaddingRight() - style.getBorderLeftWidth(); - } - -} diff --git a/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeRotationDraw.java b/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeRotationDraw.java deleted file mode 100644 index 3e0b06721e..0000000000 --- a/designer-form/src/main/java/com/fr/design/fit/common/NewUIModeRotationDraw.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.fr.design.fit.common; - -import com.fr.base.BaseUtils; -import com.fr.base.DefaultRotationTextDrawProvider; -import com.fr.base.GraphHelper; -import com.fr.base.Style; -import com.fr.design.mainframe.PX; -import com.fr.stable.Constants; - -import java.awt.Font; -import java.awt.FontMetrics; -import java.awt.Graphics2D; -import java.util.List; - -public class NewUIModeRotationDraw extends DefaultRotationTextDrawProvider { - @Override - public void drawRotationText(Graphics2D g2d, String text, Style style, Font rfont, int width, int height, int horizontalAlignment, int resolution) { - FontMetrics cellFM = GraphHelper.getFontMetrics(rfont); - List lineTextList = BaseUtils.getLineTextList(text, style, rfont, height, width, resolution, new NewUIModeAutoChangeLine()); - drawRotationText(g2d, lineTextList, style, cellFM, width, height, horizontalAlignment, resolution); - } - - - protected int calculateTextWidth(int width, Style style) { - return width - style.getPaddingRight(); - } - - protected double calculateTextX(Style style, int width, int textWidth, int horizontalAlignment, int resolution) { - double textX = padding2PixExcludeRight(style.getPaddingLeft(), resolution); - if (horizontalAlignment == Constants.CENTER) { - textX += (width - textWidth - textX) / 2f; - } else if (horizontalAlignment == Constants.RIGHT) { - textX = width - style.getPaddingRight() - textWidth; - } - return textX; - } - - protected int toPXWithResolution(double pt, int resolution) { - return (int) PX.toPixWithResolution(pt, resolution); - } - - protected double padding2PixExcludeRight(int padding, int resolution) { - return PX.toPixWithResolution(padding, resolution); - } - - protected int calculateTextY(Style style, int height, int textHeight, int textAscent, List lineTextList, int resolution) { - // 计算Y的高度. - int textY = 0; - int textAllHeight = textHeight * lineTextList.size(); - double spacingBefore = toPXWithResolution(style.getSpacingBefore(), resolution); - double spacingAfter = toPXWithResolution(style.getSpacingAfter(), resolution); - double lineSpacing = toPXWithResolution(style.getLineSpacing(), resolution); - textAllHeight += spacingBefore + spacingAfter + lineSpacing * lineTextList.size(); - if (style.getVerticalAlignment() == Constants.TOP) { - } else if (style.getVerticalAlignment() == Constants.CENTER) { - if (height > textAllHeight) {// 如果所有文本的高度小于当前可以绘区域的高度,就从0开始画字符. - textY = (height - textAllHeight) / 2; - } - } else if (style.getVerticalAlignment() == Constants.BOTTOM) { - if (height > textAllHeight) { - textY = height - textAllHeight; - } - } - textY += textAscent;// 在绘画的时候,必须添加Ascent的高度. - textY += spacingBefore + lineSpacing;//james:加上"段前间距"+“行间距” - return textY; - } - -} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index b58932c8a7..a142ee297c 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java @@ -41,6 +41,7 @@ import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.fit.FormFitAttrAction; +import com.fr.design.fit.common.FormDesignerUtil; import com.fr.design.fun.PreviewProvider; import com.fr.design.fun.PropertyItemPaneProvider; import com.fr.design.gui.frpane.HyperlinkGroupPane; @@ -109,12 +110,7 @@ import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.tree.TreePath; -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; @@ -1307,4 +1303,25 @@ public class JForm extends JTemplate implements BaseJForm { private DictionaryPane dictPane; - private CheckBoxDictPane checkBoxDictPane; + private ReturnTypePane returnTypePane; private UICheckBox checkbox; public CheckBoxGroupDefinePane(XCreator xCreator) { @@ -40,12 +40,12 @@ public class CheckBoxGroupDefinePane extends ButtonGroupDefinePane { - private UICheckBox supportTagCheckBox; - private CheckBoxDictPane checkBoxDictPane; - private UITextField waterMarkDictPane; - private UICheckBox removeRepeatCheckBox; + private UICheckBox supportTagCheckBox; + private ReturnTypePane returnTypePane; + private UITextField waterMarkDictPane; + private UICheckBox removeRepeatCheckBox; public ComboCheckBoxDefinePane(XCreator xCreator) { super(xCreator); @@ -40,13 +40,13 @@ public class ComboCheckBoxDefinePane extends DictEditorDefinePane public JPanel createOtherPane(){ supportTagCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Support_Tag"), true); supportTagCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - checkBoxDictPane = new CheckBoxDictPane(); + returnTypePane = new ReturnTypePane(); double f = TableLayout.FILL; double p = TableLayout.PREFERRED; Component[][] components = new Component[][]{ new Component[]{supportTagCheckBox, null }, - new Component[]{checkBoxDictPane, null}, + new Component[]{returnTypePane, null}, }; double[] rowSize = {p, p}; double[] columnSize = {p, f}; @@ -56,7 +56,7 @@ public class ComboCheckBoxDefinePane extends DictEditorDefinePane } protected void populateSubDictionaryEditorBean(ComboCheckBox ob){ - this.checkBoxDictPane.populate(ob); + this.returnTypePane.populate(ob); waterMarkDictPane.setText(ob.getWaterMark()); formWidgetValuePane.populate(ob); this.supportTagCheckBox.setSelected(ob.isSupportTag()); @@ -65,7 +65,7 @@ public class ComboCheckBoxDefinePane extends DictEditorDefinePane protected ComboCheckBox updateSubDictionaryEditorBean(){ ComboCheckBox combo = (ComboCheckBox) creator.toData(); - checkBoxDictPane.update(combo); + returnTypePane.update(combo); formWidgetValuePane.update(combo); combo.setWaterMark(waterMarkDictPane.getText()); combo.setSupportTag(this.supportTagCheckBox.isSelected()); @@ -77,7 +77,7 @@ public class ComboCheckBoxDefinePane extends DictEditorDefinePane public DataCreatorUI dataUI() { return null; } - + @Override public String title4PopupWindow() { return "ComboCheckBox"; diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java index 9746c605d5..13049e4c95 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/TreeEditorDefinePane.java @@ -1,78 +1,50 @@ package com.fr.design.widget.ui.designer; import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; -import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itree.refreshabletree.TreeRootPane; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.widget.accessibles.AccessibleTreeModelEditor; +import com.fr.design.widget.component.ReturnTypePane; import com.fr.form.ui.TreeEditor; import javax.swing.BorderFactory; import javax.swing.JPanel; +import java.awt.BorderLayout; import java.awt.Component; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; /* * richer:tree editor */ public class TreeEditorDefinePane extends CustomWritableRepeatEditorPane { + private ReturnTypePane returnTypePane; protected TreeRootPane treeRootPane; - private UICheckBox mutiSelect; - private UICheckBox loadAsync; - private UICheckBox returnLeaf; - private UICheckBox returnPath; private AccessibleTreeModelEditor accessibleTreeModelEditor; public TreeEditorDefinePane(XCreator xCreator) { super(xCreator); - treeRootPane = new TreeRootPane(); } public JPanel createOtherPane() { - mutiSelect = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tree_Mutiple_Selection_Or_Not")); - mutiSelect.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - - loadAsync = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Load_By_Async")); - loadAsync.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - loadAsync.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - UICheckBox checkBox = (UICheckBox) e.getSource(); - doLoadTypeChange(checkBox.isSelected()); + treeRootPane = new TreeRootPane(); + returnTypePane = new ReturnTypePane(); + JPanel panel = FRGUIPaneFactory.createBorderLayout_L_Pane(); + panel.add(treeRootPane, BorderLayout.NORTH); + returnTypePane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + panel.add(returnTypePane, BorderLayout.CENTER); + treeRootPane.addTreeAttrChangeListener(treeAttr -> { + boolean showReturnTypePane = treeAttr.isMultipleSelection() && !treeAttr.isReturnFullPath(); + returnTypePane.setVisible(showReturnTypePane); + if (!showReturnTypePane) { + returnTypePane.setReturnType(ReturnTypePane.ReturnType.ARRAY); } }); - returnLeaf = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Return_Leaf")); - returnLeaf.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - - returnPath = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Return_Path")); - returnPath.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - Component[][] components = new Component[][]{ - new Component[]{mutiSelect}, - new Component[]{loadAsync}, - new Component[]{returnLeaf}, - new Component[]{returnPath} - }; - double[] rowSize = {p, p, p, p}; - double[] columnSize = {p}; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, IntervalConstants.INTERVAL_L2, IntervalConstants.INTERVAL_L1); return panel; } - private void doLoadTypeChange(Boolean selected) { - //给埋点插件提供一个方法,埋埋点用 - } - @Override public String title4PopupWindow() { return "tree"; @@ -89,10 +61,7 @@ public class TreeEditorDefinePane extends CustomWritableRepeatEditorPane template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (!(template instanceof JForm)) { - return rectangle; + if (!(template instanceof JDashboard)) { + return new Rectangle(); } - - FormDesigner designer = ((JForm) template).getFormDesign(); - if (designer == null) { - return rectangle; + try { + return ((JDashboard)template).getElementCaseRectangle((FormElementCase)elementCase); + } catch (Throwable e) { + // 兼容旧插件 + return new Rectangle(); } - XElementCase xElementCase = FormDesignerUtil.getXelementCase(designer.getRootComponent(), (FormElementCase) elementCase); - if (xElementCase != null) { - rectangle.setBounds(xElementCase.getBounds()); - - //减去内边距的宽和高 - Insets insets = xElementCase.getInsets(); - rectangle.width -= insets.left + insets.right; - rectangle.height -= insets.top + insets.bottom; - - } - return rectangle; } diff --git a/designer-realize/src/main/java/com/fr/design/report/ImageExportPane.java b/designer-realize/src/main/java/com/fr/design/report/ImageExportPane.java index d32c006a65..b8d6167335 100644 --- a/designer-realize/src/main/java/com/fr/design/report/ImageExportPane.java +++ b/designer-realize/src/main/java/com/fr/design/report/ImageExportPane.java @@ -9,8 +9,9 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.io.attr.ImageExportAttr; import com.fr.io.attr.ReportExportAttr; -import com.fr.report.ReportConfigManager; +import java.awt.Color; +import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JComponent; @@ -35,33 +36,26 @@ public class ImageExportPane extends AbstractExportPane { private UIRadioButton globalFormatJpg; private UIRadioButton globalFormatPng; - private UIRadioButton previewResolutionBtnS; - private UIRadioButton previewResolutionBtnM; - - private UIRadioButton previewRenderSpeed; - private UIRadioButton previewRenderQuality; + private UIRadioButton templateThumbnail; + private UIRadioButton templatePaging; private static final int RESOLUTION_S = 96; private static final int RESOLUTION_M = 192; private static final int RESOLUTION_L = 300; - private static final int DPI_SCALE_S = 1; - private static final int DPI_SCALE_M = 2; - private static final int GAP = 20; - public static final String GLOBAL_CONF = Toolkit.i18nText("Fine-Design_Image_Export_Global_Configuration"); - - - private ReportExportAttr reportExportAttr; + public static final String GLOBAL_CONF = Toolkit.i18nText("Fine-Design_Image_Export_Setting"); public ImageExportPane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); JPanel globalTitlePane = FRGUIPaneFactory.createTitledBorderPane(GLOBAL_CONF); - JPanel previewSetting = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Basic_Preview")); + JPanel tipsTitlePane = FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Advice")); + UILabel tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Image_Export_Tips")); + tipLabel.setForeground(Color.RED); + tipsTitlePane.add(tipLabel); this.add(globalTitlePane, BorderLayout.NORTH); - this.add(previewSetting, BorderLayout.CENTER); initGlobalSettings(); JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); @@ -69,6 +63,7 @@ public class ImageExportPane extends AbstractExportPane { {new UILabel(Toolkit.i18nText("Fine-Design_Image_Export_Resolution") + ":"), this.globalResolutionBtnS, this.globalResolutionBtnM, this.globalResolutionBtnL}, {new UILabel(Toolkit.i18nText("Fine-Design_Report_Format") + ":"), this.globalFormatJpg, null, this.globalFormatPng}, {new UILabel(Toolkit.i18nText("Fine-Design_Image_Export_Rendering_Quality") + ":"), this.globalRenderQuality, null, this.globalRenderSpeed}, + {new UILabel(Toolkit.i18nText("Fine-Design_Image_Export_Typesetting") + ":"), this.templateThumbnail, null, this.templatePaging} }; centerPane.add( TableLayoutHelper.createCommonTableLayoutPane( @@ -77,23 +72,8 @@ public class ImageExportPane extends AbstractExportPane { new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL, TableLayout.FILL}, GAP), BorderLayout.CENTER); + centerPane.add(tipsTitlePane,BorderLayout.SOUTH); globalTitlePane.add(centerPane, BorderLayout.CENTER); - JPanel templateCenterPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - JComponent[][] templateComps = { - {new UILabel(Toolkit.i18nText("Fine-Design_Report_Engine_Enlarge_Or_Reduce") + ":"), this.previewResolutionBtnS, this.previewResolutionBtnM}, - {new UILabel(Toolkit.i18nText("Fine-Design_Image_Export_Rendering_Quality") + ":"), this.previewRenderQuality, this.previewRenderSpeed}, - }; - templateCenterPane.add( - TableLayoutHelper.createCommonTableLayoutPane( - templateComps, - new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL}, - new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL}, - GAP), - BorderLayout.CENTER); - - previewSetting.add(templateCenterPane, BorderLayout.CENTER); - - } @@ -101,36 +81,29 @@ public class ImageExportPane extends AbstractExportPane { globalResolutionBtnS = new UIRadioButton("96dpi", true); globalResolutionBtnM = new UIRadioButton("192dpi"); globalResolutionBtnL = new UIRadioButton("300dpi"); - ButtonGroup globalResolutionBtnGroup = new ButtonGroup(); - globalResolutionBtnGroup.add(globalResolutionBtnS); - globalResolutionBtnGroup.add(globalResolutionBtnM); - globalResolutionBtnGroup.add(globalResolutionBtnL); + wrapButtonsInButtonGroup(globalResolutionBtnS, globalResolutionBtnM, globalResolutionBtnL); globalFormatJpg = new UIRadioButton("jpg", true); globalFormatPng = new UIRadioButton("png"); - ButtonGroup globalFormatGroup = new ButtonGroup(); - globalFormatGroup.add(globalFormatJpg); - globalFormatGroup.add(globalFormatPng); + wrapButtonsInButtonGroup(globalFormatJpg, globalFormatPng); globalRenderQuality = new UIRadioButton(Toolkit.i18nText("Fine-Design_Image_Export_Quality_First"), true); globalRenderSpeed = new UIRadioButton(Toolkit.i18nText(("Fine-Design_Image_Export_Speed_Priority"))); - ButtonGroup globalRenderGroup = new ButtonGroup(); - globalRenderGroup.add(globalRenderQuality); - globalRenderGroup.add(globalRenderSpeed); - - previewResolutionBtnS = new UIRadioButton("100%", true); - previewResolutionBtnM = new UIRadioButton("200%"); - ButtonGroup previewResolutionBtnGroup = new ButtonGroup(); - previewResolutionBtnGroup.add(previewResolutionBtnS); - previewResolutionBtnGroup.add(previewResolutionBtnM); - - previewRenderSpeed = new UIRadioButton(Toolkit.i18nText("Fine-Design_Image_Export_Speed_Priority")); - previewRenderQuality = new UIRadioButton(Toolkit.i18nText("Fine-Design_Image_Export_Quality_First")); - ButtonGroup previewRenderGroup = new ButtonGroup(); - previewRenderGroup.add(previewRenderQuality); - previewRenderGroup.add(previewRenderSpeed); + wrapButtonsInButtonGroup(globalRenderQuality, globalRenderSpeed); + + templateThumbnail = new UIRadioButton(Toolkit.i18nText("Fine-Design_Image_Export_Thumbnail")); + templatePaging = new UIRadioButton(Toolkit.i18nText("Fine-Design_Image_Export_Paging")); + wrapButtonsInButtonGroup(templateThumbnail, templatePaging); } + private void wrapButtonsInButtonGroup(AbstractButton... buttons) { + if (buttons != null) { + ButtonGroup buttonGroup = new ButtonGroup(); + for (AbstractButton button : buttons) { + buttonGroup.add(button); + } + } + } /** * 展示界面 @@ -150,10 +123,6 @@ public class ImageExportPane extends AbstractExportPane { updateBean(); } - private ImageExportAttr getGlobalImageExportAttr() { - return ReportConfigManager.getProviderInstance().getImageExportAttr(); - } - /** * 标题 * @@ -166,7 +135,11 @@ public class ImageExportPane extends AbstractExportPane { @Override public void populateBean(Object exportAttr) { - ImageExportAttr attr = getGlobalImageExportAttr(); + ReportExportAttr reportExportAttr = (ReportExportAttr) exportAttr; + ImageExportAttr attr = reportExportAttr.getImageExportAttr(); + if (attr == null) { + attr = new ImageExportAttr(); + } switch (attr.getResolution()) { case 192: globalResolutionBtnM.setSelected(true); @@ -187,24 +160,17 @@ public class ImageExportPane extends AbstractExportPane { } else { globalRenderQuality.setSelected(true); } - - if (attr.getPreviewRenderQuality() == ImageExportAttr.RENDER_SPEED) { - previewRenderSpeed.setSelected(true); - } else { - previewRenderQuality.setSelected(true); - } - - if (attr.getPreviewResolutionScale() == DPI_SCALE_S) { - previewResolutionBtnS.setSelected(true); + if (attr.isPaging()) { + templatePaging.setSelected(true); } else { - previewResolutionBtnM.setSelected(true); + templateThumbnail.setSelected(true); } - } @Override public void updateBean(Object exportAttr) { - ImageExportAttr attr = getGlobalImageExportAttr(); + ReportExportAttr reportExportAttr = (ReportExportAttr) exportAttr; + ImageExportAttr attr = new ImageExportAttr(); if (globalResolutionBtnS.isSelected()) { attr.setResolution(RESOLUTION_S); } else if (globalResolutionBtnM.isSelected()) { @@ -222,17 +188,8 @@ public class ImageExportPane extends AbstractExportPane { } else { attr.setRenderQuality(ImageExportAttr.RENDER_QUALITY); } - - if (previewRenderSpeed.isSelected()) { - attr.setPreviewRenderQuality(ImageExportAttr.RENDER_SPEED); - } else { - attr.setPreviewRenderQuality(ImageExportAttr.RENDER_QUALITY); - } - if (previewResolutionBtnS.isSelected()) { - attr.setPreviewResolutionScale(DPI_SCALE_S); - } else { - attr.setPreviewResolutionScale(DPI_SCALE_M); - } + attr.setPaging(templatePaging.isSelected()); + reportExportAttr.setImageExportAttr(attr); } @Override diff --git a/designer-realize/src/main/java/com/fr/design/widget/ui/CheckBoxGroupDefinePane.java b/designer-realize/src/main/java/com/fr/design/widget/ui/CheckBoxGroupDefinePane.java index 188e766ee3..cddcf991de 100644 --- a/designer-realize/src/main/java/com/fr/design/widget/ui/CheckBoxGroupDefinePane.java +++ b/designer-realize/src/main/java/com/fr/design/widget/ui/CheckBoxGroupDefinePane.java @@ -9,12 +9,12 @@ import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.widget.component.CheckBoxDictPane; +import com.fr.design.widget.component.ReturnTypePane; import com.fr.form.ui.CheckBoxGroup; public class CheckBoxGroupDefinePane extends FieldEditorDefinePane { - CheckBoxDictPane checkBoxDictPane; + private ReturnTypePane returnTypePane; private UICheckBox checkbox; private ButtonGroupDictPane buttonGroupDictPane; @@ -28,25 +28,25 @@ public class CheckBoxGroupDefinePane extends FieldEditorDefinePane { - private CheckBoxDictPane checkBoxDictPane; + private ReturnTypePane returnTypePane; private AccessibleDictionaryEditor dictPane; - private UICheckBox supportTagCheckBox; + private UICheckBox supportTagCheckBox; public ComboCheckBoxDefinePane() { super.initComponents(); @@ -28,7 +28,7 @@ public class ComboCheckBoxDefinePane extends CustomWritableRepeatEditorPane { - protected AccessibleTreeModelEditor treeSettingPane; - protected TreeRootPane treeRootPane; + protected AccessibleTreeModelEditor treeSettingPane; - public TreeComboBoxEditorDefinePane() { - this.initComponents(); - } + private ReturnTypePane returnTypePane; + protected TreeRootPane treeRootPane; + public TreeComboBoxEditorDefinePane() { + this.initComponents(); + } - @Override - protected JPanel setForthContentPane() { - JPanel content = FRGUIPaneFactory.createBorderLayout_L_Pane(); - content.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - treeRootPane = new TreeRootPane(); - content.add(treeRootPane, BorderLayout.NORTH); - return content; - } - @Override - protected JPanel setFirstContentPane() { - treeSettingPane = new AccessibleTreeModelEditor(); - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - JPanel north = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Create_Tree")), treeSettingPane}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W2, IntervalConstants.INTERVAL_L1); - north.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); - JPanel center = super.setFirstContentPane(); - jPanel.add(north, BorderLayout.NORTH); - jPanel.add(center, BorderLayout.CENTER); - return jPanel; - } + @Override + protected JPanel setForthContentPane() { + JPanel content = FRGUIPaneFactory.createBorderLayout_L_Pane(); + treeRootPane = new TreeRootPane(); + returnTypePane = new ReturnTypePane(); + content.add(treeRootPane, BorderLayout.NORTH); + returnTypePane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + content.add(returnTypePane, BorderLayout.CENTER); + treeRootPane.addTreeAttrChangeListener(treeAttr -> { + boolean showReturnTypePane = treeAttr.isMultipleSelection() && !treeAttr.isReturnFullPath(); + returnTypePane.setVisible(showReturnTypePane); + if (!showReturnTypePane) { + returnTypePane.setReturnType(ReturnTypePane.ReturnType.ARRAY); + } + }); + content.add(treeRootPane, BorderLayout.NORTH); + return content; + } + @Override + protected JPanel setFirstContentPane() { + treeSettingPane = new AccessibleTreeModelEditor(); + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel north = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Create_Tree")), treeSettingPane}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W2, IntervalConstants.INTERVAL_L1); + north.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + JPanel center = super.setFirstContentPane(); + jPanel.add(north, BorderLayout.NORTH); + jPanel.add(center, BorderLayout.CENTER); + return jPanel; + } - @Override - protected String title4PopupWindow() { - return "treecombobox"; - } + @Override + protected String title4PopupWindow() { + return "treecombobox"; + } - @Override - protected void populateSubCustomWritableRepeatEditorBean(TreeEditor e) { - treeSettingPane.setValue(e.getBuildModelConfig()); - treeRootPane.populate(e.getTreeAttr()); - } + @Override + protected void populateSubCustomWritableRepeatEditorBean(TreeEditor e) { + treeSettingPane.setValue(e.getBuildModelConfig()); + treeRootPane.populate(e.getTreeAttr()); + returnTypePane.populate(e); + } - @Override - protected TreeComboBoxEditor updateSubCustomWritableRepeatEditorBean() { - TreeComboBoxEditor editor = new TreeComboBoxEditor(); - editor.setBuildModelConfig(treeSettingPane.getValue()); - editor.setTreeAttr(treeRootPane.update()); - return editor; - } + @Override + protected TreeComboBoxEditor updateSubCustomWritableRepeatEditorBean() { + TreeComboBoxEditor editor = new TreeComboBoxEditor(); + editor.setBuildModelConfig(treeSettingPane.getValue()); + editor.setTreeAttr(treeRootPane.update()); + returnTypePane.update(editor); + return editor; + } - @Override - public DataCreatorUI dataUI() { - return null; - } + @Override + public DataCreatorUI dataUI() { + return null; + } } \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/widget/ui/TreeEditorDefinePane.java b/designer-realize/src/main/java/com/fr/design/widget/ui/TreeEditorDefinePane.java index 89e54cdc8d..086ef88837 100644 --- a/designer-realize/src/main/java/com/fr/design/widget/ui/TreeEditorDefinePane.java +++ b/designer-realize/src/main/java/com/fr/design/widget/ui/TreeEditorDefinePane.java @@ -8,6 +8,7 @@ import com.fr.design.gui.itree.refreshabletree.TreeRootPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.widget.accessibles.AccessibleTreeModelEditor; +import com.fr.design.widget.component.ReturnTypePane; import com.fr.form.ui.TreeEditor; @@ -19,6 +20,8 @@ import java.awt.*; * richer:tree editor */ public class TreeEditorDefinePane extends FieldEditorDefinePane { + private ReturnTypePane returnTypePane; + protected TreeRootPane treeRootPane; private AccessibleTreeModelEditor accessibleTreeModelEditor; @@ -32,6 +35,7 @@ public class TreeEditorDefinePane extends FieldEditorDefinePane { protected void populateSubFieldEditorBean(TreeEditor e) { this.accessibleTreeModelEditor.setValue(e.getBuildModelConfig()); treeRootPane.populate(e.getTreeAttr()); + returnTypePane.populate(e); if (this.removeRepeatCheckBox != null) { this.removeRepeatCheckBox.setSelected(e.isRemoveRepeat()); } @@ -42,6 +46,7 @@ public class TreeEditorDefinePane extends FieldEditorDefinePane { TreeEditor editor = new TreeEditor(); editor.setBuildModelConfig(accessibleTreeModelEditor.getValue()); editor.setTreeAttr(treeRootPane.update()); + returnTypePane.update(editor); if (this.removeRepeatCheckBox != null) { editor.setRemoveRepeat(this.removeRepeatCheckBox.isSelected()); } @@ -75,9 +80,19 @@ public class TreeEditorDefinePane extends FieldEditorDefinePane { protected JPanel setThirdContentPane() { JPanel content = FRGUIPaneFactory.createBorderLayout_L_Pane(); - content.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); treeRootPane = new TreeRootPane(); + returnTypePane = new ReturnTypePane(); content.add(treeRootPane, BorderLayout.NORTH); + returnTypePane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + content.add(returnTypePane, BorderLayout.CENTER); + treeRootPane.addTreeAttrChangeListener(treeAttr -> { + boolean showReturnTypePane = treeAttr.isMultipleSelection() && !treeAttr.isReturnFullPath(); + returnTypePane.setVisible(showReturnTypePane); + if (!showReturnTypePane) { + returnTypePane.setReturnType(ReturnTypePane.ReturnType.ARRAY); + } + }); + //content.add(treeRootPane, BorderLayout.NORTH); return content; } diff --git a/designer-realize/src/main/java/com/fr/grid/GridUI.java b/designer-realize/src/main/java/com/fr/grid/GridUI.java index 6234acc953..7ae22a51fa 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridUI.java +++ b/designer-realize/src/main/java/com/fr/grid/GridUI.java @@ -18,6 +18,7 @@ import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.mainframe.JTemplate; import com.fr.design.roleAuthority.ReportAndFSManagePane; +import com.fr.design.utils.ColorUtils; import com.fr.design.utils.gui.AdjustWorkBookDefaultStyleUtils; import com.fr.general.Background; import com.fr.general.ComparatorUtils; @@ -1196,13 +1197,13 @@ public class GridUI extends ComponentUI { } //绘制吸附辅助线 - paintAdsorbLines(g2d, grid); + paintAdsorbLines(g2d, grid, elementCase); grid.ajustEditorComponentBounds(); // refresh size } //绘制吸附辅助线 - private void paintAdsorbLines(Graphics2D g2d, Grid grid) { + private void paintAdsorbLines(Graphics2D g2d, Grid grid, TemplateElementCase elementcase) { int verticalValue = grid.getVerticalValue(); int horizontalValue = grid.getHorizontalValue(); if (grid.getAdsorbWidth() <= 0 || grid.getAdsorbHeight() <= 0) { @@ -1212,13 +1213,18 @@ public class GridUI extends ComponentUI { - columnWidthList.getRangeValue(0, horizontalValue).toPixI(resolution)); int height = (int) (grid.getAdsorbHeight() * (resolution * 1.0D / DesignerUIModeConfig.getInstance().getScreenResolution()) - rowHeightList.getRangeValue(0, verticalValue).toPixI(resolution)); - drawBoundsLine(g2d, width, height); + drawBoundsLine(g2d, width, height, elementcase); } - private void drawBoundsLine(Graphics2D g2d, int width, int height) { + private void drawBoundsLine(Graphics2D g2d, int width, int height, TemplateElementCase elementcase) { Paint oldPaint = g2d.getPaint(); Stroke oldStroke = g2d.getStroke(); - g2d.setPaint(Color.black); + Color backgroundColor = AdjustWorkBookDefaultStyleUtils.adjustBack(Color.WHITE); + if(ColorUtils.isDarkColor(backgroundColor)) { + g2d.setPaint(Color.white); + } else { + g2d.setPaint(Color.black); + } g2d.setStroke(GraphDrawHelper.getStroke(Constants.LINE_DASH_DOT)); g2d.drawLine(0, height, width, height); g2d.drawLine(width, 0, width, height); diff --git a/designer-realize/src/main/java/com/fr/grid/GridUtils.java b/designer-realize/src/main/java/com/fr/grid/GridUtils.java index 21b032265f..03d125075c 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridUtils.java +++ b/designer-realize/src/main/java/com/fr/grid/GridUtils.java @@ -448,7 +448,8 @@ public class GridUtils { int editElementcolumn = editCellElement.getColumn(); UNIT preferredHeight = PaintUtils.analyzeCellElementPreferredHeight( editCellElement, - columnWidthList.getRangeValue(editElementcolumn, editElementcolumn + editCellElement.getColumnSpan())); + columnWidthList.getRangeValue(editElementcolumn, editElementcolumn + editCellElement.getColumnSpan()), + DesignerUIModeConfig.getInstance().getAutoChangeLineStrategy()); if (editCellElement.getRowSpan() == 1) { rowHeightList.set(editCellElement.getRow(), UNIT.max(preferredHeight, rowHeightList.get(editCellElement.getRow()))); diff --git a/designer-realize/src/main/java/com/fr/start/DesignerInitial.java b/designer-realize/src/main/java/com/fr/start/DesignerInitial.java index 39c702af56..83d8a6fbdc 100644 --- a/designer-realize/src/main/java/com/fr/start/DesignerInitial.java +++ b/designer-realize/src/main/java/com/fr/start/DesignerInitial.java @@ -10,6 +10,7 @@ import com.fr.event.Listener; import com.fr.event.Null; import com.fr.invoke.Reflect; import com.fr.stable.bridge.StableFactory; +import com.fr.task.Once; /** * Created by juhaoyu on 2019-06-14. @@ -18,6 +19,26 @@ import com.fr.stable.bridge.StableFactory; public class DesignerInitial { private static volatile BaseDesigner designer; + + private static final Once OPEN_LAST_FILE_INIT = new Once(() -> { + + EventDispatcher.listen(DesignerLaunchStatus.OPEN_LAST_FILE_COMPLETE, new Listener() { + @Override + public void on(Event event, Null param) { + EventDispatcher.stopListen(this); + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + DesignerContext.getDesignerFrame().setVisible(true); + DesignerContext.getDesignerFrame().resizeFrame(); + //启动画面结束 + SplashContext.getInstance().hide(); + } + }); + DesignerLaunchStatus.setStatus(DesignerLaunchStatus.STARTUP_COMPLETE); + } + }); + }); public static void init(final String... args) { UIUtil.invokeLaterIfNeeded(new Runnable() { @@ -34,6 +55,8 @@ public class DesignerInitial { } public static void prepare() { + + DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_STARTED); UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { @@ -42,21 +65,6 @@ public class DesignerInitial { } } }); - EventDispatcher.listen(DesignerLaunchStatus.OPEN_LAST_FILE_COMPLETE, new Listener() { - @Override - public void on(Event event, Null param) { - EventDispatcher.stopListen(this); - UIUtil.invokeLaterIfNeeded(new Runnable() { - @Override - public void run() { - DesignerContext.getDesignerFrame().setVisible(true); - DesignerContext.getDesignerFrame().resizeFrame(); - //启动画面结束 - SplashContext.getInstance().hide(); - } - }); - DesignerLaunchStatus.setStatus(DesignerLaunchStatus.STARTUP_COMPLETE); - } - }); + OPEN_LAST_FILE_INIT.run(); } } diff --git a/designer-realize/src/main/java/com/fr/start/DesignerJavaRuntime.java b/designer-realize/src/main/java/com/fr/start/DesignerJavaRuntime.java index f65ae11f85..7abf5d963d 100644 --- a/designer-realize/src/main/java/com/fr/start/DesignerJavaRuntime.java +++ b/designer-realize/src/main/java/com/fr/start/DesignerJavaRuntime.java @@ -2,7 +2,6 @@ package com.fr.start; import com.fr.design.os.impl.SupportOSImpl; import com.fr.general.ComparatorUtils; -import com.fr.general.GeneralContext; import com.fr.general.GeneralUtils; import com.fr.general.IOUtils; import com.fr.locale.InterProviderFactory; @@ -15,7 +14,6 @@ import com.fr.stable.os.OperatingSystem; import java.io.BufferedReader; import java.io.File; -import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; diff --git a/designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java b/designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java index 3115781b3d..21d5fdf56e 100644 --- a/designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java +++ b/designer-realize/src/main/java/com/fr/start/LifecycleFatalErrorHandler.java @@ -26,6 +26,7 @@ import com.fr.stable.lifecycle.ErrorType; import com.fr.stable.lifecycle.ErrorTypeHelper; import com.fr.stable.lifecycle.FineLifecycleFatalError; import com.fr.stable.project.ProjectConstants; +import com.fr.start.common.DesignerStartupContext; import javax.swing.JOptionPane; import java.util.Collection; @@ -54,6 +55,12 @@ public class LifecycleFatalErrorHandler { } public void handle(FineLifecycleFatalError fatal) { + + if (DesignerStartupContext.getInstance().onWarmup()) { + // 如果是预热过程中的错误,不理 + return; + } + SplashContext.getInstance().hide(); FineProcessContext.getParentPipe().fire(new CarryMessageEvent(ReportState.STOP.getValue())); diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index f60003c9a1..9d4d3eb145 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -1,6 +1,7 @@ package com.fr.start; +import com.fr.base.function.UITerminator; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignerEnvManager; import com.fr.design.actions.file.WebPreviewUtils; @@ -32,6 +33,8 @@ import com.fr.design.mainframe.alphafine.component.AlphaFinePane; import com.fr.design.mainframe.bbs.UserInfoLabel; import com.fr.design.mainframe.bbs.UserInfoPane; import com.fr.design.mainframe.guide.entry.GuideEntryPane; +import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; +import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.MenuDef; @@ -44,6 +47,8 @@ import com.fr.design.monitor.DesignerLifecycleMonitorContext; import com.fr.design.notification.ui.NotificationCenterPane; import com.fr.design.share.SharableManager; import com.fr.design.ui.util.UIUtil; +import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.DesignerPort; import com.fr.design.utils.concurrent.ThreadFactoryBuilder; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.env.utils.DesignerInteractionHistory; @@ -61,8 +66,10 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.lifecycle.FineLifecycleFatalError; import com.fr.stable.xml.XMLTools; +import com.fr.start.common.DesignerStartupContext; import com.fr.start.common.SplashCommon; import com.fr.start.module.StartupArgs; +import com.fr.start.preload.PreLoadService; import com.fr.start.server.ServerTray; import com.fr.third.org.apache.commons.lang3.time.StopWatch; import com.fr.van.chart.map.server.ChartMapEditorAction; @@ -74,11 +81,14 @@ import javax.swing.border.MatteBorder; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; @@ -109,14 +119,19 @@ public class MainDesigner extends BaseDesigner { * @param args 参数 */ public static void main(String[] args) { - + DesignerStartupContext.getRecorder().start(); showSplash(); + startPreload0(); + DeepLinkManager.getInstance().start(args); StopWatch watch = new StopWatch(); watch.start(); DesignerLifecycleMonitorContext.getMonitor().beforeStart(); //启动运行时 FineRuntime.start(); + + startPreload1(); + DesignerSubListener.getInstance().start(); EventDispatcher.listen(LifecycleErrorEvent.SELF, new Listener() { @Override @@ -125,6 +140,8 @@ public class MainDesigner extends BaseDesigner { } }); Module designerRoot = ModuleContext.parseRoot("designer-startup.xml"); + + FineLoggerFactory.getLogger().debug("designer-startup prepared cost {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS)); //传递启动参数 designerRoot.setSingleton(StartupArgs.class, new StartupArgs(args)); try { @@ -141,6 +158,41 @@ public class MainDesigner extends BaseDesigner { watch.stop(); } + /** + * 在 {@link FineRuntime#start()} 运行后 + */ + private static void startPreload1() { + + CompletableFuture initLookAndFeel = CompletableFuture.runAsync(DesignUtils::initLookAndFeel); + PreLoadService.getInstance().addFuture(initLookAndFeel); + } + + /** + * 在 {@link FineRuntime#start()} 运行前 + */ + private static void startPreload0() { + + PreLoadService.getInstance().addRunnable(() -> { + if (DesignUtils.isPortOccupied()) { + UITerminator action = new UITerminator() { + @Override + protected void doRun() { + StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.PORT_OCCUPIED.getId(), + DesignerErrorMessage.PORT_OCCUPIED.getMessage()); + DesignerPort.getInstance().resetPort(); + } + }; + action.run(); + } + }); + + Runnable fontLoad = () -> { + Font[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); + }; + PreLoadService.getInstance().addRunnable(fontLoad); + + } + private static void showSplash() { // 快快显示启动画面 UIUtil.invokeAndWaitIfNeeded(new Runnable() { diff --git a/designer-realize/src/main/java/com/fr/start/SplashContext.java b/designer-realize/src/main/java/com/fr/start/SplashContext.java index cc9eb19336..7fc909c5f3 100644 --- a/designer-realize/src/main/java/com/fr/start/SplashContext.java +++ b/designer-realize/src/main/java/com/fr/start/SplashContext.java @@ -83,7 +83,6 @@ public class SplashContext { //取消监听 EventDispatcher.stopListen(listener); splashStrategy.hide(); - // 一次性 splashStrategy = null; } } diff --git a/designer-realize/src/main/java/com/fr/start/common/SplashPane.java b/designer-realize/src/main/java/com/fr/start/common/SplashPane.java index 74500acc35..2bbb1b1527 100644 --- a/designer-realize/src/main/java/com/fr/start/common/SplashPane.java +++ b/designer-realize/src/main/java/com/fr/start/common/SplashPane.java @@ -4,17 +4,22 @@ import com.bulenkov.iconloader.IconLoader; import com.bulenkov.iconloader.util.JBUI; import com.fr.base.GraphHelper; import com.fr.design.locale.impl.SplashMark; -import com.fr.stable.GraphicsConfig; import com.fr.general.locale.LocaleCenter; import com.fr.general.locale.LocaleMark; import com.fr.stable.GraphDrawHelper; +import com.fr.stable.GraphicsConfig; import com.fr.stable.StringUtils; import com.fr.stable.os.OperatingSystem; import com.fr.value.NotNullLazyValue; import org.jetbrains.annotations.NotNull; -import javax.swing.*; -import java.awt.*; +import javax.swing.Icon; +import javax.swing.JPanel; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.util.Locale; /** diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java index 02152beb17..8e8b5b519a 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java @@ -102,6 +102,8 @@ import com.fr.log.FineLoggerFactory; import com.fr.log.LogHandler; import com.fr.module.Activator; import com.fr.module.extension.Prepare; +import com.fr.plugin.beforeload.embed.DefaultPluginEmbedInfo; +import com.fr.plugin.beforeload.embed.PluginEmbedInfo; import com.fr.plugin.context.PluginContext; import com.fr.plugin.injectable.PluginModule; import com.fr.plugin.manage.PluginFilter; @@ -135,16 +137,19 @@ import com.fr.stable.script.ValueConverter; import com.fr.stable.xml.ObjectTokenizer; import com.fr.stable.xml.ObjectXMLWriterFinder; import com.fr.start.BBSGuestPaneProvider; +import com.fr.start.common.DesignerStartupExecutor; +import com.fr.start.common.DesignerStartupPool; import com.fr.task.Once; import com.fr.workspace.WorkContext; import com.fr.xml.ReportXMLUtils; +import javax.swing.SwingWorker; import java.awt.Image; import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.List; import java.util.Set; -import javax.swing.SwingWorker; +import java.util.concurrent.CompletableFuture; /** * Created by juhaoyu on 2018/1/31. @@ -154,7 +159,7 @@ import javax.swing.SwingWorker; public class DesignerActivator extends Activator implements Prepare { private LogHandler logHandler = null; - + private static final String PLUGIN_EXPORT_IMAGE_SETTING = "com.fr.plugin.exportimagesettings.v11"; private final Once pushUpdateTask = new Once(new Runnable() { @Override public void run() { @@ -164,40 +169,59 @@ public class DesignerActivator extends Activator implements Prepare { } }); + private boolean hasUpdated = false; + @Override public void start() { - startLoginAuthServer(); - migrateBBSInfoFromFineDB(); - FormThemeConfigMigrator.getInstance().upgrade(); - ReportThemeConfigMigrator.getInstance().upgrade(); + List markers = findMutable(InterMutableKey.Path); for (LocaleMarker marker : markers) { if (marker.match(LocaleScope.DESIGN)) { DesignI18nImpl.getInstance().addResource(marker.getPath()); } } - designerModuleStart(); - loadLogAppender(); - DesignerSocketIO.update(); - DesignerWorkspaceLoader.init(); - OSSupportCenter.buildAction(new OSBasedAction() { - @Override - public void execute(Object... objects) { - UserInfoPane.getInstance().updateBBSUserInfo(); - } - }, SupportOSImpl.BBS_USER_LOGIN_PANE); - storePassport(); - AlphaFineHelper.switchConfig4Locale(); - RecoverManager.register(new RecoverForDesigner()); - pushUpdateTask.run(); - PluginResourceLoader.INSTANCE.checkOldShopFile(); - UpmResourceLoader.INSTANCE.checkOldShopFile(); + + CompletableFuture themeConfigPrepare = CompletableFuture.runAsync(() -> { + FormThemeConfigMigrator.getInstance().upgrade(); + ReportThemeConfigMigrator.getInstance().upgrade(); + }, DesignerStartupPool.common()); + + CompletableFuture mainDesignerPrepare = CompletableFuture.runAsync(this::designerModuleStart, DesignerStartupPool.common()); + + CompletableFuture otherFeaturesPrepare = CompletableFuture.runAsync(() -> { + startBBSLoginAuthServer(); + migrateBBSInfoFromFineDB(); + OSSupportCenter.buildAction(new OSBasedAction() { + @Override + public void execute(Object... objects) { + UserInfoPane.getInstance().updateBBSUserInfo(); + } + }, SupportOSImpl.BBS_USER_LOGIN_PANE); + loadLogAppender(); + DesignerSocketIO.update(); + DesignerWorkspaceLoader.init(); + storePassport(); + AlphaFineHelper.switchConfig4Locale(); + RecoverManager.register(new RecoverForDesigner()); + }); + + CompletableFuture resourcePrepare = CompletableFuture.runAsync(() -> { + pushUpdateTask.run(); + PluginResourceLoader.INSTANCE.checkOldShopFile(); + UpmResourceLoader.INSTANCE.checkOldShopFile(); + }, DesignerStartupPool.common()); + + CompletableFuture + .allOf(mainDesignerPrepare, themeConfigPrepare, otherFeaturesPrepare, resourcePrepare) + .join(); } @Override public void afterAllStart() { - DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE); + + DesignerStartupExecutor.getInstance().execute(() -> DesignerLaunchStatus.setStatus(DesignerLaunchStatus.DESIGNER_INIT_COMPLETE)); + //生成BasicChartQuickEditor对象,需要用到ChartDesignerActivator的注册信息(DesignModuleFactory.registerChartPropertyPaneClass(ChartPropertyPane.class);) //所以不能在registerCellEditor函数中进行注册 ActionFactory.registerCellEditor(ChartCollection.class, new BasicChartQuickEditor()); @@ -497,10 +521,9 @@ public class DesignerActivator extends Activator implements Prepare { @Override public void prepare() { - - OptimizeUtil.close(() -> { + if (!OptimizeUtil.isOpen()) { LoginAuthServer.getInstance().compatibleStart(); - }); + } ContentReplacerCenter.getInstance().register(); EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { @Override @@ -521,9 +544,14 @@ public class DesignerActivator extends Activator implements Prepare { }.execute(); } }); + prepareDefaultEmbedPluginInfo(); } - - private void startLoginAuthServer() { + + private void prepareDefaultEmbedPluginInfo() { + addMutable(PluginEmbedInfo.KEY, DefaultPluginEmbedInfo.create(PLUGIN_EXPORT_IMAGE_SETTING)); + } + + private void startBBSLoginAuthServer() { OptimizeUtil.open(() -> { // 设计器启动后启动 diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java index fd8bd93079..ff7962f61a 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java @@ -17,7 +17,6 @@ import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; import com.fr.design.mainframe.messagecollect.StartupMessageCollector; import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.design.utils.DesignUtils; -import com.fr.design.utils.DesignerPort; import com.fr.env.utils.WorkspaceUtils; import com.fr.event.Event; import com.fr.event.Listener; @@ -35,12 +34,15 @@ import com.fr.stable.project.ProjectConstants; import com.fr.start.DesignerProcessType; import com.fr.start.ServerStarter; import com.fr.start.event.LazyStartupEvent; +import com.fr.start.preload.PreLoadService; import com.fr.start.server.FineEmbedServer; +import com.fr.third.guava.base.Stopwatch; import com.fr.value.NotNullLazyValue; import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; /** * Created by juhaoyu on 2018/1/8. @@ -58,17 +60,15 @@ public class DesignerStartup extends Activator { @Override public void beforeAllStart() { + BuildContext.setBuildFilePath("/com/fr/stable/build.properties"); - + registerDaoSelector(); - - // 初始化look and feel - DesignUtils.initLookAndFeel(); - if (DesignUtils.isPortOccupied()) { - StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.PORT_OCCUPIED.getId(), - DesignerErrorMessage.PORT_OCCUPIED.getMessage()); - DesignerPort.getInstance().resetPort(); - } + + Stopwatch beforeWatch = Stopwatch.createStarted(); + PreLoadService.getInstance().waitForAll(); + FineLoggerFactory.getLogger().debug( "DesignerStartup cost {} ms to wait load", beforeWatch.elapsed(TimeUnit.MILLISECONDS)); + if (DesignUtils.isStarted()) { // 如果端口被占用了 说明程序已经运行了一次,也就是说,已经建立一个监听服务器,现在只要给服务器发送命令就好了 final String[] args = startupArgsValue.getValue().get(); @@ -78,17 +78,17 @@ public class DesignerStartup extends Activator { FineLoggerFactory.getLogger().info("The Designer Has Been Started"); if (args.length == 0) { TipDialog dialog = new TipDialog(null, - DesignerProcessType.INSTANCE.obtain(), - Toolkit.i18nText("Fine-Design_Last_Designer_Process_Not_Exist"), - Toolkit.i18nText("Fine-Design_End_Occupied_Process"), - Toolkit.i18nText("Fine-Design_Basic_Cancel")) { + DesignerProcessType.INSTANCE.obtain(), + Toolkit.i18nText("Fine-Design_Last_Designer_Process_Not_Exist"), + Toolkit.i18nText("Fine-Design_End_Occupied_Process"), + Toolkit.i18nText("Fine-Design_Basic_Cancel")) { @Override protected void endEvent() { dispose(); DesignUtils.clientSend(new String[]{"end"}); RestartHelper.restart(); } - + @Override protected void cancelEvent() { dispose(); @@ -96,13 +96,13 @@ public class DesignerStartup extends Activator { }; dialog.setVisible(true); StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getId(), - DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getMessage(), - StringUtils.EMPTY); + DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getMessage(), + StringUtils.EMPTY); FineLoggerFactory.getLogger().error(DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getId() + ": " + DesignerErrorMessage.DESIGNER_PROCESS_OCCUPIED.getMessage()); } DesignerExiter.getInstance().execute(); - return; } + } @Override 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 5abeccc842..a440906aff 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 @@ -7,7 +7,7 @@ import com.fr.design.editlock.ConnectionLockChangeChecker; import com.fr.design.editlock.ServerTableDataLockChangeChecker; import com.fr.design.env.DesignerWorkspaceGenerator; import com.fr.design.env.DesignerWorkspaceInfo; -import com.fr.design.env.LocalDesignerWorkspaceInfo; +import com.fr.design.plugin.remind.PluginErrorDesignReminder; import com.fr.design.versioncheck.VersionCheckUtils; import com.fr.env.utils.WorkspaceUtils; import com.fr.event.Event; @@ -16,7 +16,6 @@ import com.fr.event.Listener; import com.fr.event.Null; import com.fr.log.FineLoggerFactory; import com.fr.module.Activator; -import com.fr.stable.StringUtils; import com.fr.value.NotNullLazyValue; import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; @@ -74,7 +73,8 @@ public class DesignerWorkspaceProvider extends Activator { EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { @Override public void on(Event event, Null aNull) { - EnvChangeEntrance.getInstance().pluginErrorRemind(); + PluginErrorDesignReminder.getInstance().remindStartFailedPlugins(); + PluginErrorDesignReminder.getInstance().remindInvalidatePlugins(); } }); } diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerPluginActivator.java b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerPluginActivator.java new file mode 100644 index 0000000000..fd6286e33d --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerPluginActivator.java @@ -0,0 +1,24 @@ +package com.fr.start.module.optimized; + +import com.fr.module.Activator; +import com.fr.module.ModuleContext; +import com.fr.plugin.PluginActivator; +import com.fr.start.common.DesignerStartupExecutor; + +/** + * created by Harrison on 2022/06/22 + **/ +public class DesignerPluginActivator extends Activator { + + @Override + public void start() { + + DesignerStartupExecutor.getInstance().execute(() -> ModuleContext.getModule(PluginActivator.class).start()); + } + + @Override + public void stop() { + + ModuleContext.getModule(PluginActivator.class).stop(); + } +} diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java new file mode 100644 index 0000000000..12e1e1f7c0 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java @@ -0,0 +1,119 @@ +package com.fr.start.module.optimized; + +import com.fr.design.ui.util.UIUtil; +import com.fr.log.FineLoggerFactory; +import com.fr.module.Activator; +import com.fr.start.SplashContext; +import com.fr.start.common.DesignerStartupContext; +import com.fr.start.module.StartupArgs; +import com.fr.start.util.DesignerStartupPageUtil; +import com.fr.start.warmup.DesignerPreWarmTask; +import com.fr.startup.ui.StartupPageModel; +import com.fr.startup.ui.StartupPageWindow; +import com.fr.third.org.apache.commons.lang3.time.StopWatch; +import com.fr.value.NotNullLazyValue; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.TimeUnit; + +/** + * 设计器起始页启动器 + * 见 设计文档 + * + * created by Harrison on 2022/07/03 + **/ +public class DesignerStartupPageActivator extends Activator { + + private final NotNullLazyValue startupArgsValue = new NotNullLazyValue() { + + @NotNull + @Override + protected StartupArgs compute() { + return findSingleton(StartupArgs.class); + } + }; + + @Override + public void start() { + + DesignerStartupContext context = DesignerStartupContext.getInstance(); + context.setStartupArgs(startupArgsValue.getValue()); + + if (context.isShowStartupPage()) { + showDesignerStartupPage(context); + } else { + DesignerStartupPageUtil.enterWorkspace(); + } + } + + private void showDesignerStartupPage(DesignerStartupContext context) { + + // 启动页关闭 + SplashContext.getInstance().hide(); + + // 预热任务启动 + DesignerPreWarmTask warmTask = new DesignerPreWarmTask(); + warmTask.start(); + + // 即时暂停 + DesignerStartupContext.getRecorder().suspend(); + + UIUtil.invokeLaterIfNeeded(() -> { + + StartupPageModel model = StartupPageModel.create(); + context.setStartupPageModel(model); + + // selectAndOpenLast + model.setOpenLastTemplateRunnable(() -> { + context.setOpenLastFile(true); + launchAfterWarmup(warmTask); + }); + + // selectAndOpenEmpty + model.setOpenEmptyTemplateRunnable(() -> { + context.setOpenEmpty(true); + launchAfterWarmup(warmTask); + }); + + // selectAndCreateNew + model.setCreateNewTemplateRunnable(() -> { + context.setCreateNew(true); + launchAfterWarmup(warmTask); + }); + + StartupPageWindow window = new StartupPageWindow(model); + window.setVisible(true); + context.setOnWaiting(true); + }); + } + + private void launchAfterWarmup(DesignerPreWarmTask warmTask) { + + StopWatch stopWatch = StopWatch.createStarted(); + + try { + DesignerStartupContext.getRecorder().resume(); + + // 等待中切换 + DesignerStartupContext.getInstance().setOnWaiting(false); + + warmTask.join(); + + FineLoggerFactory.getLogger().debug("designer-startup-page warm up cost {} ms", stopWatch.getTime(TimeUnit.MILLISECONDS)); + DesignerStartupContext.getInstance().setOnStartup(true); + DesignerStartupPageUtil.enterWorkspace(); + } finally { + UIUtil.invokeLaterIfNeeded(() -> { + // 换到 awt 线程中关闭,不然异步会出现问题。 + DesignerStartupContext.getInstance().setOnStartup(false); + }); + } + + FineLoggerFactory.getLogger().debug("designer-startup-page started cost {} ms", DesignerStartupContext.getRecorder().getTime(TimeUnit.MILLISECONDS)); + } + + @Override + public void stop() { + + } +} diff --git a/designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java b/designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java new file mode 100644 index 0000000000..b750210749 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/preload/PreLoadService.java @@ -0,0 +1,36 @@ +package com.fr.start.preload; + +import com.fr.start.common.DesignerStartupPool; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +/** + * created by Harrison on 2022/06/01 + **/ +public class PreLoadService { + + private List> futures = new ArrayList<>(); + + public static PreLoadService getInstance() { + return PreLoadServiceHolder.INSTANCE; + } + + private static class PreLoadServiceHolder { + private static final PreLoadService INSTANCE = new PreLoadService(); + } + + public void addFuture(CompletableFuture future) { + futures.add(future); + } + + public void addRunnable(Runnable runnable) { + futures.add(CompletableFuture.runAsync(runnable, DesignerStartupPool.common())); + } + + public void waitForAll() { + CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join(); + } + +} diff --git a/designer-realize/src/main/java/com/fr/start/util/DesignerStartupPageUtil.java b/designer-realize/src/main/java/com/fr/start/util/DesignerStartupPageUtil.java new file mode 100644 index 0000000000..2fd6abad93 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/util/DesignerStartupPageUtil.java @@ -0,0 +1,31 @@ +package com.fr.start.util; + +import com.fr.module.ModuleContext; +import com.fr.start.module.DesignerWorkspaceActivator; + +/** + * created by Harrison on 2022/07/11 + **/ +public class DesignerStartupPageUtil { + + /** + * 进入工作目录 + */ + public static void enterWorkspace() { + + ModuleContext + .getModule(DesignerWorkspaceActivator.class) + .start(); + } + + /** + * 退出工作目录 + */ + public static void exitWorkspace() { + + ModuleContext + .getModule(DesignerWorkspaceActivator.class) + .stop(); + } + +} diff --git a/designer-realize/src/main/java/com/fr/start/warmup/DesignerPreWarmTask.java b/designer-realize/src/main/java/com/fr/start/warmup/DesignerPreWarmTask.java new file mode 100644 index 0000000000..0130c3af3d --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/warmup/DesignerPreWarmTask.java @@ -0,0 +1,47 @@ +package com.fr.start.warmup; + +import com.fr.log.FineLoggerFactory; +import com.fr.start.common.DesignerStartupContext; +import com.fr.start.util.DesignerStartupPageUtil; + +import java.util.concurrent.CompletableFuture; + +/** + * 预热服务 + * + * created by Harrison on 2022/07/03 + **/ +public class DesignerPreWarmTask { + + private CompletableFuture warmupTask = null; + + public void start() { + + if (DesignerStartupContext.getInstance().canWarmup()) { + warmupTask = CompletableFuture.runAsync(() -> { + try { + DesignerStartupContext.getInstance().setOnWarmup(true); + + // 尝试预热,启动关闭 + // 这里测试直接启动/关闭,比等待插件启动更快 + // ps: 这里还有优化空间 + // 方向一:改成单纯的预热,不启动工程 + // 方向二:模块启动可以终止 + DesignerStartupPageUtil.enterWorkspace(); + DesignerStartupPageUtil.exitWorkspace(); + } catch (Exception e) { + FineLoggerFactory.getLogger().debug("designer warm up failed", e); + } finally { + DesignerStartupContext.getInstance().setOnWarmup(false); + } + }); + } + } + + public void join() { + + if (warmupTask != null) { + warmupTask.join(); + } + } +}