diff --git a/build.gradle b/build.gradle index a3892da963..8e2e8b627b 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ plugins { // 模块参数 ext { frVersion = "" + cbbVersion = "" outputPath = "build" ignoreTestFailureSetting = true languageLevelSetting = 1.8 @@ -44,6 +45,9 @@ allprojects { repositories { mavenLocal() + maven { + url 'https://maven.ej-technologies.com/repository' + } } idea { @@ -57,6 +61,9 @@ allprojects { } dependencies { + implementation 'com.fr.essential:fine-essential:' + cbbVersion + implementation 'com.fr.cbb:fine-universal-skeleton:' + cbbVersion + implementation 'com.install4j:install4j-runtime:8.0.4' implementation 'com.fr.third:jxbrowser:6.23' implementation 'com.fr.third:jxbrowser-mac:6.23' implementation 'com.fr.third:jxbrowser-win64:6.23' diff --git a/designer-base/src/main/java/com/fr/base/svg/IconUtils.java b/designer-base/src/main/java/com/fr/base/svg/IconUtils.java index 79d3cef76b..fd99f0e994 100644 --- a/designer-base/src/main/java/com/fr/base/svg/IconUtils.java +++ b/designer-base/src/main/java/com/fr/base/svg/IconUtils.java @@ -6,8 +6,7 @@ import com.fr.stable.bridge.StableFactory; import com.fr.stable.fun.ResourcePathTransformer; import com.fr.stable.plugin.ExtraClassManagerProvider; -import javax.swing.Icon; -import javax.swing.ImageIcon; +import javax.swing.*; import java.util.Arrays; import java.util.HashSet; import java.util.Set; diff --git a/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java b/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java index 9667895eec..172b10dac5 100644 --- a/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java +++ b/designer-base/src/main/java/com/fr/base/svg/SVGIcon.java @@ -2,10 +2,8 @@ package com.fr.base.svg; import com.fr.general.IOUtils; -import javax.swing.Icon; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Graphics2D; +import javax.swing.*; +import java.awt.*; import java.awt.image.BufferedImage; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/designer-base/src/main/java/com/fr/base/svg/SVGLoader.java b/designer-base/src/main/java/com/fr/base/svg/SVGLoader.java deleted file mode 100644 index 3c0b7a0363..0000000000 --- a/designer-base/src/main/java/com/fr/base/svg/SVGLoader.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.fr.base.svg; - -import com.fr.general.IOUtils; -import org.apache.batik.transcoder.TranscoderException; -import org.apache.batik.transcoder.TranscoderInput; -import org.apache.xmlgraphics.java2d.Dimension2DDouble; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.awt.Image; -import java.io.IOException; -import java.net.URL; - -/** - * SVG图标加载器 - * @author Yvan - * @version 10.0 - * Created by Yvan on 2020/12/17 - */ -public class SVGLoader { - public static final int ICON_DEFAULT_SIZE = 16; - - public SVGLoader() { - } - - @Nullable - public static Image load(@NotNull String url) { - try { - URL resource = IOUtils.getResource(url, SVGLoader.class); - if (resource == null) { - return null; - } - return load(resource, SVGIcon.SYSTEM_SCALE); - } catch (IOException ignore) { - return null; - } - } - - @Nullable - public static Image load(@NotNull URL url) throws IOException { - return load(url, SVGIcon.SYSTEM_SCALE); - } - - @Nullable - public static Image load(@NotNull URL url, double scale) throws IOException { - try { - String svgUri = url.toString(); - TranscoderInput input = new TranscoderInput(svgUri); - return SVGTranscoder.createImage(scale, input).getImage(); - } catch (TranscoderException ignore) { - return null; - } - } - - @Nullable - public static Image load(@NotNull URL url, double scale, Dimension2DDouble dimension) throws IOException { - try { - String svgUri = url.toString(); - TranscoderInput input = new TranscoderInput(svgUri); - return SVGTranscoder.createImage(scale, input, - (float) (dimension.getWidth() * scale), (float) (dimension.getHeight() * scale)).getImage(); - } catch (TranscoderException ignore) { - return null; - } - } - - - @Nullable - public static Image load(@NotNull URL url, double scale, double overriddenWidth, double overriddenHeight) throws IOException { - try { - String svgUri = url.toString(); - TranscoderInput input = new TranscoderInput(svgUri); - return SVGTranscoder.createImage(scale, input, (float) (overriddenWidth * scale), (float) (overriddenHeight * scale)).getImage(); - } catch (TranscoderException ignore) { - return null; - } - } - - @Nullable - public static Image load(@NotNull String url, float width, float height) { - try { - URL resource = IOUtils.getResource(url, SVGLoader.class); - if (resource == null) { - return null; - } - TranscoderInput input = new TranscoderInput(resource.toString()); - return SVGTranscoder.createImage(SVGIcon.SYSTEM_SCALE, input, -1, -1, width, height).getImage(); - } catch (TranscoderException ignore) { - return null; - } - } -} diff --git a/designer-base/src/main/java/com/fr/base/svg/SVGTranscoder.java b/designer-base/src/main/java/com/fr/base/svg/SVGTranscoder.java deleted file mode 100644 index dd47bc5757..0000000000 --- a/designer-base/src/main/java/com/fr/base/svg/SVGTranscoder.java +++ /dev/null @@ -1,181 +0,0 @@ -package com.fr.base.svg; - -import com.fr.stable.AssistUtils; -import com.fr.value.AtomicNotNullLazyValue; -import org.apache.batik.anim.dom.SAXSVGDocumentFactory; -import org.apache.batik.anim.dom.SVGOMDocument; -import org.apache.batik.bridge.BridgeContext; -import org.apache.batik.bridge.UserAgent; -import org.apache.batik.transcoder.SVGAbstractTranscoder; -import org.apache.batik.transcoder.TranscoderException; -import org.apache.batik.transcoder.TranscoderInput; -import org.apache.batik.transcoder.TranscoderOutput; -import org.apache.batik.transcoder.image.ImageTranscoder; -import org.apache.batik.util.XMLResourceDescriptor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.w3c.dom.Element; -import org.w3c.dom.svg.SVGDocument; - -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.awt.Rectangle; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.StringReader; - -/** - * 可以根据某个缩放倍数scale,将SVG图片转化为Image对象 - * @author Yvan - * @version 10.0 - * Created by Yvan on 2020/12/17 - */ -public class SVGTranscoder extends ImageTranscoder { - - private static final float DEFAULT_VALUE = -1.0F; - public static final float ICON_DEFAULT_SIZE = 16F; - private float origDocWidth; - private float origDocHeight; - @Nullable - private BufferedImage image; - private final double scale; - - @NotNull - private static AtomicNotNullLazyValue iconMaxSize = new AtomicNotNullLazyValue() { - @NotNull - @Override - protected Double compute() { - double maxSize = Double.MAX_VALUE; - if (!GraphicsEnvironment.isHeadless()) { - GraphicsDevice defaultScreenDevice = GraphicsEnvironment - .getLocalGraphicsEnvironment() - .getDefaultScreenDevice(); - Rectangle bounds = defaultScreenDevice.getDefaultConfiguration().getBounds(); - AffineTransform tx = defaultScreenDevice - .getDefaultConfiguration() - .getDefaultTransform(); - maxSize = Math.max(bounds.width * tx.getScaleX(), bounds.height * tx.getScaleY()); - } - return maxSize; - } - }; - - public SVGTranscoder(double scale) { - this.scale = scale; - this.width = ICON_DEFAULT_SIZE; - this.height = ICON_DEFAULT_SIZE; - } - - public SVGTranscoder(double scale, float width, float height) { - this.scale = scale; - this.width = width; - this.height = height; - } - - public final float getOrigDocWidth() { - return this.origDocWidth; - } - - public final void setOrigDocWidth(float origDocWidth) { - this.origDocWidth = origDocWidth; - } - - public final float getOrigDocHeight() { - return this.origDocHeight; - } - - public final void setOrigDocHeight(float origDocHeight) { - this.origDocHeight = origDocHeight; - } - - public static double getIconMaxSize() { - return iconMaxSize.getValue(); - } - - @Nullable - public final BufferedImage getImage() { - return this.image; - } - - @NotNull - public static SVGTranscoder createImage(double scale, @NotNull TranscoderInput input) throws TranscoderException { - return createImage(scale, input, -1, -1); - } - - @NotNull - public static SVGTranscoder createImage(double scale, @NotNull TranscoderInput input, float overriddenWidth, float overriddenHeight) throws TranscoderException { - return createImage(scale, input, overriddenWidth, overriddenHeight, ICON_DEFAULT_SIZE, ICON_DEFAULT_SIZE); - } - - @NotNull - public static SVGTranscoder createImage(double scale, @NotNull TranscoderInput input, float overriddenWidth, float overriddenHeight, float width, float height) throws TranscoderException { - SVGTranscoder transcoder = new SVGTranscoder(scale, width, height); - if (!AssistUtils.equals(overriddenWidth, DEFAULT_VALUE)) { - transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_WIDTH, overriddenWidth); - } - - if (!AssistUtils.equals(overriddenHeight, DEFAULT_VALUE)) { - transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_HEIGHT, overriddenHeight); - } - - double iconMaxSize = SVGTranscoder.iconMaxSize.getValue(); - transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_MAX_WIDTH, (float) iconMaxSize); - transcoder.addTranscodingHint(SVGAbstractTranscoder.KEY_MAX_HEIGHT, (float) iconMaxSize); - transcoder.transcode(input, null); - return transcoder; - } - - private static SVGDocument createFallbackPlaceholder() { - try { - String fallbackIcon = "\n" + - " \n" + - " \n" + - " \n" + - "\n"; - - SAXSVGDocumentFactory factory = new SAXSVGDocumentFactory(XMLResourceDescriptor.getXMLParserClassName()); - return (SVGDocument) factory.createDocument(null, new StringReader(fallbackIcon)); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - @Override - protected void setImageSize(float docWidth, float docHeight) { - super.setImageSize((float) (docWidth * this.scale), (float) (docHeight * this.scale)); - this.origDocWidth = docWidth; - this.origDocHeight = docHeight; - } - - @Override - @NotNull - public BufferedImage createImage(int width, int height) { - return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); - } - - @Override - public void writeImage(@NotNull BufferedImage image, @Nullable TranscoderOutput output) { - this.image = image; - } - - @Override - @NotNull - protected UserAgent createUserAgent() { - return new SVGAbstractTranscoderUserAgent() { - @Override - @NotNull - public SVGDocument getBrokenLinkDocument(@NotNull Element e, @NotNull String url, @NotNull String message) { - return createFallbackPlaceholder(); - } - }; - } - - /** - * 开放访问权限 - */ - @Override - public BridgeContext createBridgeContext(SVGOMDocument doc) { - return super.createBridgeContext(doc); - } -} diff --git a/designer-base/src/main/java/com/fr/base/svg/SystemScaleUtils.java b/designer-base/src/main/java/com/fr/base/svg/SystemScaleUtils.java deleted file mode 100644 index 4b79748065..0000000000 --- a/designer-base/src/main/java/com/fr/base/svg/SystemScaleUtils.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.fr.base.svg; - -import com.bulenkov.iconloader.util.UIUtil; -import com.fr.log.FineLoggerFactory; -import com.fr.stable.StableUtils; -import com.fr.stable.os.OperatingSystem; -import org.jetbrains.annotations.NotNull; - -import java.awt.GraphicsConfiguration; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; -import java.lang.reflect.Method; -import java.util.concurrent.atomic.AtomicReference; - -/** - * 获取系统Scale相关的工具类 - * @author Yvan - * @version 10.0 - * Created by Yvan on 2020/12/17 - */ -public class SystemScaleUtils { - - private static final AtomicReference JRE_HIDPI = new AtomicReference<>(); - - private static final String HI_DPI = "hidpi"; - - /** - * 判断是否支持高清 - * @return - */ - public static boolean isJreHiDPIEnabled() { - if (JRE_HIDPI.get() != null) { - return JRE_HIDPI.get(); - } - if (OperatingSystem.isMacos()) { - // 如果是mac os系统,直接返回true - return true; - } - if (OperatingSystem.isWindows() && StableUtils.getMajorJavaVersion() <= 8) { - // 如果是jdk8 + Windows系统,直接返回false - return false; - } - synchronized (JRE_HIDPI) { - if (JRE_HIDPI.get() != null) { - return JRE_HIDPI.get(); - } - boolean result = false; - if (getBooleanProperty(HI_DPI, true)) { - try { - GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); - Class sunGraphicsEnvironmentClass = Class.forName("sun.java2d.SunGraphicsEnvironment"); - if (sunGraphicsEnvironmentClass.isInstance(ge)) { - try { - Method method = sunGraphicsEnvironmentClass.getDeclaredMethod("isUIScaleEnabled"); - method.setAccessible(true); - result = (Boolean)method.invoke(ge); - } - catch (NoSuchMethodException e) { - FineLoggerFactory.getLogger().error(e.getMessage()); - } - } - } - catch (Throwable ignore) { - } - } - JRE_HIDPI.set(result); - return result; - } - } - - public static boolean getBooleanProperty(@NotNull final String key, final boolean defaultValue) { - final String value = System.getProperty(key); - return value == null ? defaultValue : Boolean.parseBoolean(value); - } - - /** - * 获取系统Scale - * @return - */ - public static float sysScale() { - // 如果检测到是retina,直接返回2 - if (UIUtil.isRetina()) { - return 2.0f; - } - float scale = 1.0f; - // 先判断是否支持高清,不支持代表此时是Windows + jdk8 的设计器,返回的scale值为1.0 - if (isJreHiDPIEnabled()) { - // 获取屏幕图形设备对象 - GraphicsDevice graphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - if (graphicsDevice != null) { - // 获取图形配置对象 - GraphicsConfiguration configuration = graphicsDevice.getDefaultConfiguration(); - if (configuration != null && configuration.getDevice().getType() != GraphicsDevice.TYPE_PRINTER) { - // 获取屏幕缩放率,Windows+jdk11环境下会得到用户设置的dpi值 - scale = (float) configuration.getDefaultTransform().getScaleX(); - } - } - } - return scale; - } -} diff --git a/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java b/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java index 3eb3b78579..013c703fb2 100644 --- a/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java +++ b/designer-base/src/main/java/com/fr/design/DesignModelAdapter.java @@ -4,6 +4,7 @@ import com.fr.base.Parameter; import com.fr.base.ParameterConfig; import com.fr.base.TableData; import com.fr.base.io.BaseBook; +import com.fr.base.param.ParameterSource; import com.fr.data.TableDataSource; import com.fr.data.operator.DataOperator; import com.fr.design.file.HistoryTemplateListCache; @@ -19,8 +20,8 @@ import com.fr.stable.Filter; import com.fr.stable.ParameterProvider; import com.fr.stable.StringUtils; import com.fr.stable.js.WidgetName; - import com.fr.util.ParameterApplyHelper; + import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -283,9 +284,9 @@ public abstract class DesignModelAdapter map, ParameterProvider[] parameterProviders, Filter filter) { if (filter != null) { - ParameterApplyHelper.addPara2Map(map, parameterProviders, filter); + ParameterApplyHelper.addPara2Map(map, parameterProviders, filter, null, ParameterSource.DEFAULT_SOURCE); } else { - ParameterApplyHelper.addPara2Map(map, parameterProviders); + ParameterApplyHelper.addPara2Map(map, parameterProviders, null, ParameterSource.DEFAULT_SOURCE); } } @@ -378,7 +379,7 @@ public abstract class DesignModelAdapter map) { // 添加全局参数 Parameter[] glbParas = ParameterConfig.getInstance().getGlobalParameters(); - ParameterApplyHelper.addPara2Map(map, glbParas); + ParameterApplyHelper.addPara2Map(map, glbParas, null, ParameterSource.GLOBAL_SOURCE); } 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 5a777b895d..2fa06a5642 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 @@ -108,7 +108,7 @@ public class PreferencePane extends BasicPane { private static final int CACHING_DEFAULT = 5; private static final int CACHING_GAP = 5; private static final int MEMORY_TIP_LABEL_MAX_WIDTH = 230; - private static final int OFFSET_HEIGHT = 50; + private static final int OFFSET_HEIGHT = 60; private static final String TYPE = "pressed"; private static final String DISPLAY_TYPE = "+"; diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/AdvancePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/AdvancePane.java index 2041230957..7784aa5712 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/AdvancePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/AdvancePane.java @@ -15,9 +15,9 @@ import com.fr.stable.StringUtils; import javax.swing.JPanel; import javax.swing.SwingConstants; +import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; -import java.awt.Dimension; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; @@ -34,13 +34,12 @@ public class AdvancePane extends BasicPane { public AdvancePane() { - + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); DBCP_VALIDATION_QUERY.addFocusListener(new JTextFieldHintListener(DBCP_VALIDATION_QUERY)); - ; double p = TableLayout.PREFERRED; - DBCP_VALIDATION_QUERY.setColumns(15); + DBCP_VALIDATION_QUERY.setColumns(20); double[] rowSizeDbcp = {p, p, p, p}; - double[] columnDbcp = {p, p}; + double[] columnDbcp = {190, p}; Component[][] comps = { {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Max_Active") + ":", SwingConstants.RIGHT), DBCP_MAX_ACTIVE}, {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Dbcp_Validation_Query") + ":", SwingConstants.RIGHT), DBCP_VALIDATION_QUERY}, @@ -49,9 +48,8 @@ public class AdvancePane extends BasicPane { }; JPanel contextPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowSizeDbcp, columnDbcp, 11, 11); - this.add(contextPane); - this.setPreferredSize(new Dimension(630, 120)); - this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout()); + jPanel.add(contextPane, BorderLayout.CENTER); + this.add(jPanel); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java index 91e8006d10..4d5556ef95 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java @@ -7,6 +7,7 @@ import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; import com.fr.data.operator.DataOperatorProvider; +import com.fr.data.security.ssl.impl.NormalSsl; import com.fr.data.solution.ExceptionSolutionSelector; import com.fr.data.solution.entity.DriverPage; import com.fr.data.solution.processor.ClassNotFoundExceptionSolutionProcessor; @@ -61,7 +62,7 @@ import java.util.concurrent.ExecutionException; * Database Connection pane. */ public abstract class DatabaseConnectionPane extends BasicBeanPane { - private static int MAX_MAIN_PANEL_HEIGHT = 430; + private static int MAX_MAIN_PANEL_HEIGHT = 410; private static int MAX_MAIN_PANEL_WIDTH = 675; private UILabel message; @@ -312,6 +313,15 @@ public abstract class DatabaseConnectionPane jdbcMap = new HashMap(); + private JPanel linkPanel; static { jdbcMap.put(OTHER_DB, new DriverURLName[]{new DriverURLName("sun.jdbc.odbc.JdbcOdbcDriver", "jdbc:odbc:"), @@ -193,7 +197,9 @@ public class JDBCDefPane extends JPanel { userNameTextField = new UITextField(15); userNameTextField.setName(USER_NAME); passwordTextField = new UIPasswordFieldWithFixedLength(15); - dbtypeButton = new UIButton("."); + dbtypeButton = new UIButton(); + dbtypeButton.setIcon(new ImageIcon(UIConstants.ACCESSIBLE_EDITOR_DOT)); + dbtypeButton.setPreferredSize(new Dimension(20, 20)); dbtypeButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Click_Get_Default_URL")); dbtypeButton.addActionListener(dbtypeButtonActionListener); @@ -477,11 +483,16 @@ public class JDBCDefPane extends JPanel { } ActionListener driverListener = new ActionListener() { + @Override public void actionPerformed(ActionEvent e) { + linkPanel.setVisible(DriverClasses.MYSQL.toString().equalsIgnoreCase((String) dbtypeComboBox.getSelectedItem()) + && driverComboBox.getSelectedItem() != null + && ComparatorUtils.equals(DriverClasses.MYSQL.getDriverClass(), driverComboBox.getSelectedItem().toString().trim())); + odbcTipsLink.setVisible(driverComboBox.getSelectedItem() != null + && ComparatorUtils.equals("sun.jdbc.odbc.JdbcOdbcDriver", driverComboBox.getSelectedItem().toString().trim())); // 选择的如果是ODBC就显示提示 if (driverComboBox.getSelectedItem() == null || ComparatorUtils.equals(driverComboBox.getSelectedItem(), StringUtils.EMPTY)) { return; } - odbcTipsLink.setVisible(ComparatorUtils.equals("sun.jdbc.odbc.JdbcOdbcDriver", driverComboBox.getSelectedItem())); // 选择的如果是ODBC就显示提示 Iterator> jdbc = jdbcMap.entrySet().iterator(); while (jdbc.hasNext()) { Entry entry = jdbc.next(); @@ -494,7 +505,6 @@ public class JDBCDefPane extends JPanel { } } } - }; ActionListener dbtypeButtonActionListener = new ActionListener() { @@ -738,4 +748,7 @@ public class JDBCDefPane extends JPanel { } + public void addLinkPane(JPanel panel) { + linkPanel = panel; + } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/SshPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/SshPane.java new file mode 100644 index 0000000000..9a870d07d2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/SshPane.java @@ -0,0 +1,301 @@ +package com.fr.design.data.datapane.connect; + +import com.fr.data.impl.JDBCDatabaseConnection; +import com.fr.data.security.ssh.BaseSsh; +import com.fr.data.security.ssh.Ssh; +import com.fr.data.security.ssh.SshException; +import com.fr.data.security.ssh.SshType; +import com.fr.data.security.ssh.impl.KeyVerifySsh; +import com.fr.data.security.ssh.impl.NormalSsh; +import com.fr.design.border.UITitledBorder; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicPane; +import com.fr.design.editor.editor.NotNegativeIntegerEditor; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ipasswordfield.UIPasswordFieldWithFixedLength; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.file.FILE; +import com.fr.file.FILEChooserPane; +import com.fr.file.filter.ChooseFileFilter; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; +import com.fr.third.guava.collect.HashBiMap; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static com.fr.design.i18n.Toolkit.i18nText; + +/** + * @author xiqiu + * @date 2021/12/23 + * @description + */ +public class SshPane extends BasicPane { + private static HashBiMap typeMap; + + static { + typeMap = HashBiMap.create(); + typeMap.put(Toolkit.i18nText("Fine-Design_Basic_Password"), SshType.NORMAL); + typeMap.put(Toolkit.i18nText("Fine-Design_Basic_Ssh_Public_Key"), SshType.KEY); + } + + private UICheckBox usingSsh = new UICheckBox(i18nText("Fine-Design_Basic_Ssh_Using")); + private NotNegativeIntegerEditor port = new NotNegativeIntegerEditor(20); + private UITextField ip = new UITextField(20); + private UIComboBox type = new UIComboBox(); + private UITextField user = new UITextField(20); + private JPasswordField password = new UIPasswordFieldWithFixedLength(20); + private JPasswordField secret = new UIPasswordFieldWithFixedLength(20); + private KeyFileUITextField keyPath = new KeyFileUITextField(18); + private JPanel contextPane; + private Component[][] passwordComps; + private Component[][] keyComps; + private double p = TableLayout.PREFERRED; + private double f = TableLayout.FILL; + private JPanel jPanel; + private UIButton fileChooserButton = new UIButton(); + private double[] columnSize = new double[]{195, p}; + + public SshPane() { + fileChooserButton.setIcon(new ImageIcon(UIConstants.ACCESSIBLE_EDITOR_DOT)); + this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Ssh_Settings"))); + this.setLayout(FRGUIPaneFactory.createLabelFlowLayout()); + typeMap.keySet().forEach(key -> type.addItem(key)); + type.setSelectedItem(typeMap.inverse().get(SshType.KEY)); + jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + fileChooserButton.setPreferredSize(new Dimension(20, 20)); + type.setEditable(false); + type.setSelectedItem(Toolkit.i18nText("Fine-Design_Basic_Ssh_Private_Key")); + JPanel filePanel = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{{keyPath, fileChooserButton}}, new double[]{p}, new double[]{f, 20}, 0); + Component[] compIp = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Host") + ":", SwingConstants.RIGHT), ip}; + Component[] compPort = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Port") + ":", SwingConstants.RIGHT), port}; + Component[] compUserName = {new UILabel(Toolkit.i18nText("Fine-Design_Report_UserName") + ":", SwingConstants.RIGHT), user}; + Component[] compMethod = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Verify_Method") + ":", SwingConstants.RIGHT), type}; + Component[] compPassword = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Password") + ":", SwingConstants.RIGHT), password}; + Component[] compKey = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Private_Key") + ":", SwingConstants.RIGHT), filePanel}; + Component[] comSecret = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssh_Secret") + ":", SwingConstants.RIGHT), secret}; + + passwordComps = new Component[][]{ + compIp, + compPort, + compUserName, + compMethod, + compPassword + }; + keyComps = new Component[][]{ + compIp, + compPort, + compUserName, + compMethod, + compKey, + comSecret + }; + usingSsh.setSelected(true); + contextPane = TableLayoutHelper.createGapTableLayoutPane(keyComps, new double[]{p, p, p, p, p, p}, columnSize, 11, 11); + jPanel.add(usingSsh, BorderLayout.NORTH); + jPanel.add(contextPane, BorderLayout.CENTER); + this.add(jPanel); + + usingSsh.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + changePane(); + } + }); + + type.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + changePaneForType(); + } + }); + fileChooserButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(ProjectConstants.RESOURCES_NAME, new ChooseFileFilter(true)); + int type = fileChooser.showOpenDialog(SshPane.this, StringUtils.EMPTY); + if (type == FILEChooserPane.OK_OPTION) { + final FILE file = fileChooser.getSelectedFILE(); + if (file == null) { + keyPath.setText(StringUtils.EMPTY); + } else { + keyPath.setText(file.getPath()); + } + } + fileChooser.removeAllFilter(); + } + }); + } + + + private void changePane() { + contextPane.setVisible(usingSsh.isSelected()); + } + + private void changePaneForType() { + contextPane.removeAll(); + switch (typeMap.get(type.getSelectedItem())) { + case NORMAL: + TableLayoutHelper.addComponent2ResultPane(passwordComps, new double[]{p, p, p, p, p}, columnSize, contextPane); + break; + case KEY: + TableLayoutHelper.addComponent2ResultPane(keyComps, new double[]{p, p, p, p, p, p}, columnSize, contextPane); + break; + default: + throw new SshException("un support ssh type"); + } + jPanel.revalidate(); + jPanel.repaint(); + } + + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Ssh_Settings"); + } + + + public void populate(JDBCDatabaseConnection jdbcDatabase) { + if (jdbcDatabase.getSsh() == null) { + jdbcDatabase.setSsh(new NormalSsh()); + } + Ssh ssh = jdbcDatabase.getSsh(); + switch (ssh.getSshType()) { + case KEY: + type.setSelectedItem(typeMap.inverse().get(ssh.getSshType())); + KeyVerifySsh keyVerifySsh = (KeyVerifySsh) ssh; + keyPath.setText(keyVerifySsh.getPrivateKeyPath()); + secret.setText(keyVerifySsh.getSecret()); + password.setText(StringUtils.EMPTY); + setCommonConfig(keyVerifySsh); + break; + case NORMAL: + type.setSelectedItem(typeMap.inverse().get(ssh.getSshType())); + NormalSsh normalSsh = (NormalSsh) ssh; + password.setText(normalSsh.getSecret()); + keyPath.setText(StringUtils.EMPTY); + secret.setText(StringUtils.EMPTY); + setCommonConfig(normalSsh); + break; + default: + throw new SshException("un support ssh type"); + } + usingSsh.setSelected(ssh.isUsingSsh()); + changePane(); + } + + private void setCommonConfig(BaseSsh baseSsh) { + ip.setText(baseSsh.getIp()); + port.setValue(baseSsh.getPort()); + user.setText(baseSsh.getUser()); + } + + public void update(JDBCDatabaseConnection jdbcDatabase) { + Ssh ssh; + switch (typeMap.get(type.getSelectedItem())) { + case NORMAL: + NormalSsh normalSsh = new NormalSsh(); + normalSsh.setSecret(new String(password.getPassword()).trim()); + getCommonConfig(normalSsh); + ssh = normalSsh; + break; + case KEY: + KeyVerifySsh keyVerifySsh = new KeyVerifySsh(); + keyVerifySsh.setPrivateKeyPath(keyPath.getText().trim()); + keyVerifySsh.setSecret(new String(secret.getPassword()).trim()); + getCommonConfig(keyVerifySsh); + ssh = keyVerifySsh; + break; + default: + throw new SshException("un support ssh type"); + } + jdbcDatabase.setSsh(ssh); + } + + private void getCommonConfig(BaseSsh baseSsh) { + baseSsh.setUsingSsh(usingSsh.isSelected()); + baseSsh.setIp(ip.getText().trim()); + baseSsh.setPort(port.getValue()); + baseSsh.setUser(user.getText().trim()); + } + + public static class KeyFileUITextField extends UITextField { + private static final Pattern ERROR_START = Pattern.compile("^([/\\\\.]+).*"); + private static final Pattern MUTI_DOT = Pattern.compile("\\.+"); + private static final String PREFIX = ProjectConstants.RESOURCES_NAME + "/"; + private static final String UPPER = ".."; + + public KeyFileUITextField(int columns) { + this(); + this.setColumns(columns); + } + + + public KeyFileUITextField() { + super(); + this.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + String text = KeyFileUITextField.this.getTextOrigin(); + if (!StringUtils.isEmpty(text)) { + if (text.contains(UPPER)) { + text = MUTI_DOT.matcher(text).replaceAll("."); + KeyFileUITextField.this.setTextOrigin(text); + } + Matcher matcher = ERROR_START.matcher(text); + if (matcher.matches()) { + text = text.substring(matcher.group(1).length()); + KeyFileUITextField.this.setTextOrigin(text); + } + } + } + }); + } + + public String getTextOrigin() { + return super.getText(); + } + + public void setTextOrigin(String text) { + super.setText(text); + } + + @Override + public String getText() { + // 获取的时候,不为空,给他加上前缀就好了,否则还是空 + if (!StringUtils.isEmpty(super.getText())) { + return PREFIX + super.getText(); + } + return StringUtils.EMPTY; + } + + @Override + public void setText(String text) { + // 设置的时候,不为空,说明文件指定了(文件需要是resource下),替换掉前缀 + if (!StringUtils.isEmpty(text) && text.startsWith(PREFIX)) { + super.setText(text.replaceFirst(PREFIX, "")); + } else { + super.setText(text); + } + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java new file mode 100644 index 0000000000..2d9c26e235 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/SslPane.java @@ -0,0 +1,164 @@ +package com.fr.design.data.datapane.connect; + +import com.fr.data.impl.JDBCDatabaseConnection; +import com.fr.data.security.ssl.Ssl; +import com.fr.data.security.ssl.SslException; +import com.fr.data.security.ssl.SslType; +import com.fr.data.security.ssl.impl.NormalSsl; +import com.fr.design.border.UITitledBorder; +import com.fr.design.constants.UIConstants; +import com.fr.design.data.datapane.connect.SshPane.KeyFileUITextField; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.file.FILE; +import com.fr.file.FILEChooserPane; +import com.fr.file.filter.ChooseFileFilter; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; + +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import static com.fr.design.i18n.Toolkit.i18nText; + +/** + * @author xiqiu + * @date 2022/1/4 + * @description + */ +public class SslPane extends BasicPane { + UICheckBox usingSsl = new UICheckBox(i18nText("Fine-Design_Basic_Ssl_Using")); + private KeyFileUITextField keyPathCa = new KeyFileUITextField(18); + private UIButton fileChooserButtonCa = new UIButton(); + private KeyFileUITextField keyPathClientCert = new KeyFileUITextField(18); + private UIButton fileChooserButtonClientCert = new UIButton(); + private KeyFileUITextField keyPathClientKey = new KeyFileUITextField(18); + private UIButton fileChooserButtonClientKey = new UIButton(); + private UICheckBox verifyCa = new UICheckBox(i18nText("Fine-Design_Basic_Ssl_Verify_Ca")); +// private UITextField cipher = new UITextField(20); + private JPanel jPanel; + private Component[][] usingComps; + private double p = TableLayout.PREFERRED; + private double f = TableLayout.FILL; + private JPanel contextPane; + private double[] columnSize = new double[]{195, p}; + + public SslPane() { + fileChooserButtonCa.setIcon(new ImageIcon(UIConstants.ACCESSIBLE_EDITOR_DOT)); + fileChooserButtonClientCert.setIcon(new ImageIcon(UIConstants.ACCESSIBLE_EDITOR_DOT)); + fileChooserButtonClientKey.setIcon(new ImageIcon(UIConstants.ACCESSIBLE_EDITOR_DOT)); + this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Ssl_Settings"))); + this.setLayout(FRGUIPaneFactory.createLabelFlowLayout()); + jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + Dimension dimension = new Dimension(20, 20); + fileChooserButtonCa.setPreferredSize(dimension); + fileChooserButtonClientCert.setPreferredSize(dimension); + fileChooserButtonClientKey.setPreferredSize(dimension); + JPanel filePanelCa = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{{keyPathCa, fileChooserButtonCa}}, new double[]{p}, new double[]{f, 20}, 0); + Component[] compCa = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Ca") + ":", SwingConstants.RIGHT), filePanelCa}; + Component[] compVerifyCa = {null, verifyCa}; + JPanel filePanelClientCert = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{{keyPathClientCert, fileChooserButtonClientCert}}, new double[]{p}, new double[]{f, 20}, 0); + Component[] compClientCert = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Client_Cert") + ":", SwingConstants.RIGHT), filePanelClientCert}; + JPanel filePanelClientKey = TableLayoutHelper.createCommonTableLayoutPane(new Component[][]{{keyPathClientKey, fileChooserButtonClientKey}}, new double[]{p}, new double[]{f, 20}, 0); + Component[] compClientKey = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Client_Key") + ":", SwingConstants.RIGHT), filePanelClientKey}; +// Component[] comCipher = {new UILabel(Toolkit.i18nText("Fine-Design_Basic_Ssl_Cipher") + ":", SwingConstants.RIGHT), cipher}; + usingComps = new Component[][]{ + compCa, + compVerifyCa, + compClientCert, + compClientKey, +// comCipher + }; + usingSsl.setSelected(true); + contextPane = TableLayoutHelper.createGapTableLayoutPane(usingComps, new double[]{p, p, p, p}, columnSize, 11, 11); + jPanel.add(usingSsl, BorderLayout.NORTH); + jPanel.add(contextPane, BorderLayout.CENTER); + this.add(jPanel); + usingSsl.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + changePane(); + } + }); + fileChooserButtonCa.addActionListener(new TextFieldActionListener(keyPathCa)); + fileChooserButtonClientCert.addActionListener(new TextFieldActionListener(keyPathClientCert)); + fileChooserButtonClientKey.addActionListener(new TextFieldActionListener(keyPathClientKey)); + } + + private void changePane() { + contextPane.setVisible(usingSsl.isSelected()); + } + + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Ssl_Settings"); + } + + public void populate(JDBCDatabaseConnection jdbcDatabase) { + Ssl ssl = jdbcDatabase.getSsl(); + if (ssl == null) { + ssl = new NormalSsl(); + jdbcDatabase.setSsl(ssl); + } + if (ssl.getSslType() == SslType.NORMAL) { + NormalSsl normalSsl = (NormalSsl) ssl; + keyPathCa.setText(normalSsl.getCaCertificate()); + keyPathClientCert.setText(normalSsl.getClientCertificate()); + keyPathClientKey.setText(normalSsl.getClientPrivateKey()); + verifyCa.setSelected(normalSsl.isVerifyCa()); +// cipher.setText(normalSsl.getCipher()); + } else { + throw new SslException("un support ssl type"); + } + usingSsl.setSelected(ssl.isUsingSsl()); + changePane(); + } + + public void update(JDBCDatabaseConnection jdbcDatabase) { + NormalSsl normalSsl = new NormalSsl(); +// normalSsl.setCipher(cipher.getText().trim()); + normalSsl.setVerifyCa(verifyCa.isSelected()); + normalSsl.setCaCertificate(keyPathCa.getText().trim()); + normalSsl.setClientCertificate(keyPathClientCert.getText().trim()); + normalSsl.setClientPrivateKey(keyPathClientKey.getText().trim()); + normalSsl.setUsingSsl(usingSsl.isSelected()); + jdbcDatabase.setSsl(normalSsl); + } + + private class TextFieldActionListener implements ActionListener { + private UITextField textField; + + public TextFieldActionListener(UITextField textField) { + this.textField = textField; + } + + @Override + public void actionPerformed(ActionEvent e) { + FILEChooserPane fileChooser = FILEChooserPane.getInstanceWithDesignatePath(ProjectConstants.RESOURCES_NAME, new ChooseFileFilter(true)); + int type = fileChooser.showOpenDialog(SslPane.this, StringUtils.EMPTY); + if (type == FILEChooserPane.OK_OPTION) { + final FILE file = fileChooser.getSelectedFILE(); + if (file == null) { + textField.setText(StringUtils.EMPTY); + } else { + textField.setText(file.getPath()); + } + } + fileChooser.removeAllFilter(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java index 08274fd71d..515bd8dd08 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java @@ -63,26 +63,27 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { public StoreProcedureDataWrapper(Component component, StoreProcedure storeProcedure, String storeprocedureName, String dsName) { this(component, storeProcedure, storeprocedureName, dsName, true); } - + /** - * @param: component loadingBar的父弹框(如果不设置父弹框的话,可能出现loadingBar隐藏在一个弹框后的情况) - * @param: storeProcedure 存储过程 - * @param: storeprocedureName 存储过程的名字(某些情况下可以为空) - * @param: dsName 存储过程一个返回数据集的名字 - * @param: needLoad 是否要加载 + * @param component loadingBar的父弹框(如果不设置父弹框的话,可能出现loadingBar隐藏在一个弹框后的情况) + * @param storeProcedure 存储过程 + * @param storeprocedureName 存储过程的名字(某些情况下可以为空) + * @param dsName 存储过程一个返回数据集的名字 + * @param needLoad 是否要加载 **/ public StoreProcedureDataWrapper(Component component, StoreProcedure storeProcedure, String storeprocedureName, String dsName, boolean needLoad) { this.dsName = dsName; this.storeProcedure = storeProcedure; this.storeProcedure.setCalculating(false); this.storeprocedureName = storeprocedureName; - if (needLoad) { - setWorker(); - } if (component == null) { component = new JFrame(); } + if (needLoad) { + setWorker(component); + } loadingBar = new AutoProgressBar(component, Toolkit.i18nText("Fine-Design_Basic_Loading_Data"), "", 0, 100) { + @Override public void doMonitorCanceled() { getWorker().cancel(true); } @@ -93,16 +94,17 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { * 数据集执行结果返回的所有字段 * * @return 数据集执行结果返回的所有字段 - * - * - * @date 2014-12-3-下午7:43:17 - * - */ + * @date 2014-12-3-下午7:43:17 + */ + @Override public List calculateColumnNameList() { if (columnNameList != null) { return columnNameList; } - if (!createStore(false)) { + + try { + createStore(false); + } catch (Exception e) { FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Engine_No_TableData")); return new ArrayList(); } @@ -114,11 +116,9 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { * 生成子节点 * * @return 节点数组 - * - * - * @date 2014-12-3-下午7:06:47 - * - */ + * @date 2014-12-3-下午7:06:47 + */ + @Override public ExpandMutableTreeNode[] load() { List namelist; if (storeProcedure.isCalculating()) { @@ -134,23 +134,16 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { return res; } - private boolean createStore(boolean needLoadingBar) { - try { - dataModels = DesignTableDataManager.createLazyDataModel(storeProcedure, needLoadingBar); - if (dataModels == null || dataModels.length == 0) { - return false; - } - for (int i = 0; i < dataModels.length; i++) { - if (ComparatorUtils.equals(this.dsName, storeprocedureName + "_" + dataModels[i].getName())) { - procedureDataModel = dataModels[i]; + private void createStore(boolean needLoadingBar) throws Exception { + dataModels = DesignTableDataManager.createLazyDataModel(storeProcedure, needLoadingBar); + if (dataModels != null && dataModels.length != 0) { + for (ProcedureDataModel dataModel : dataModels) { + if (ComparatorUtils.equals(this.dsName, storeprocedureName + "_" + dataModel.getName())) { + procedureDataModel = dataModel; break; } } - return true; - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); } - return false; } @Override @@ -159,17 +152,15 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { } /** - * 预览数据 - * - * @param previewModel 预览模式, 全部还是一个 - * - * - * @date 2014-12-3-下午7:05:50 - * - */ + * 预览数据 + * + * @param previewModel 预览模式, 全部还是一个 + * @date 2014-12-3-下午7:05:50 + */ public void previewData(final int previewModel) { this.previewModel = previewModel; connectionBar = new AutoProgressBar(new JFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Now_Create_Connection"), "", 0, 100) { + @Override public void doMonitorCanceled() { connectionBar.close(); worker.cancel(true); @@ -178,8 +169,9 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { worker.execute(); } - private void setWorker() { + private void setWorker(final Component parent) { worker = new SwingWorker() { + @Override protected Void doInBackground() throws Exception { loadingBar.close(); PreviewTablePane.resetPreviewTable(); @@ -195,6 +187,7 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { return null; } + @Override public void done() { try { get(); @@ -206,13 +199,15 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { case StoreProcedureDataWrapper.PREVIEW_ONE: previewData(); break; + default: + break; } } catch (Exception e) { + loadingBar.close(); if (!(e instanceof CancellationException)) { FineLoggerFactory.getLogger().error(e.getMessage(), e); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), e.getMessage()); + FineJOptionPane.showMessageDialog(parent, e.getMessage()); } - loadingBar.close(); } } }; @@ -227,10 +222,9 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { /** * 预览返回的一个数据集 * - * - * @date 2014-12-3-下午7:42:53 - * - */ + * @date 2014-12-3-下午7:42:53 + */ + @Override public void previewData() { previewData(-1, -1); } @@ -240,13 +234,11 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { /** * 预览返回的一个数据集,带有显示值和实际值的标记结果 * - * @param keyIndex 实际值 - * @param valueIndex 显示值 - * - * - * @date 2014-12-3-下午7:42:27 - * - */ + * @param keyIndex 实际值 + * @param valueIndex 显示值 + * @date 2014-12-3-下午7:42:27 + */ + @Override public void previewData(final int keyIndex, final int valueIndex) { PreviewTablePane.previewStoreData(procedureDataModel, keyIndex, valueIndex); } @@ -257,7 +249,9 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { */ public void previewAllTable() { if (procedureDataModel == null) { - if (!createStore(true)) { + try { + createStore(true); + } catch (Exception e) { return; } } @@ -269,6 +263,7 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { return dsName; } + @Override public TableData getTableData() { return storeProcedure; } @@ -282,10 +277,12 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { * * @return 是否异常 */ + @Override public boolean isUnusual() { return false; } + @Override public boolean equals(Object obj) { return obj instanceof StoreProcedureDataWrapper && ComparatorUtils.equals(this.dsName, ((StoreProcedureDataWrapper) obj).getTableDataName()) diff --git a/designer-base/src/main/java/com/fr/design/deeplink/DeepLink.java b/designer-base/src/main/java/com/fr/design/deeplink/DeepLink.java new file mode 100644 index 0000000000..5b40c88450 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/deeplink/DeepLink.java @@ -0,0 +1,15 @@ +package com.fr.design.deeplink; + +import java.util.Map; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/6 + */ +public abstract class DeepLink { + + public abstract boolean accept(String url, String host, String path, Map params); + + public abstract void run(String url, String host, String path, Map params); +} diff --git a/designer-base/src/main/java/com/fr/design/deeplink/DeepLinkCore.java b/designer-base/src/main/java/com/fr/design/deeplink/DeepLinkCore.java new file mode 100644 index 0000000000..55a45709bf --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/deeplink/DeepLinkCore.java @@ -0,0 +1,184 @@ +package com.fr.design.deeplink; + +import com.fr.design.constants.DesignerLaunchStatus; +import com.fr.design.startup.FineStartupNotificationFactory; +import com.fr.design.startup.FineStartupNotificationProvider; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; +import com.fr.event.Null; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; +import com.fr.stable.os.OperatingSystem; +import com.fr.third.org.apache.http.NameValuePair; +import com.fr.web.URLUtils; + +import javax.swing.SwingUtilities; +import java.awt.Color; +import java.awt.Frame; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/6 + */ +public class DeepLinkCore { + + protected DeepLinkCore(){} + private static final DeepLinkCore instance = new DeepLinkCore(); + public static DeepLinkCore getInstance(){ + return instance; + } + + private String pendingURL; + + private final List deepLinkList = new ArrayList<>(); + + private boolean isDesignerStartupCompleted = false; + + public void register(DeepLink deepLink) { + if (deepLink != null) { + deepLinkList.add(deepLink); + } + } + + public void start(String[] args) { + if (OperatingSystem.isWindows()) { + if (args.length > 0) { + receiveDeeplink(args[0]); + } + } + + if (OperatingSystem.isWindows() && args.length > 0) { + receiveDeeplink(args[0]); + } + + FineStartupNotificationFactory.getNotification() + .registerStartupListener(new FineStartupNotificationProvider.Listener() { + @Override + public void startupPerformed(String parameters) { + receiveDeeplink(parameters); + } + }); + + EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { + @Override + public void on(Event event, Null param) { + EventDispatcher.stopListen(this); + isDesignerStartupCompleted = true; + if (canConsumePendingURL()) { + consumePendingURL(); + } + } + }); + } + + public void receiveDeeplink(String url) { + if (canAcceptNewURL()) { + acceptNewURL(url); + if (canConsumePendingURL()) { + consumePendingURL(); + } + } + } + + public void receiveDeeplink2(String url) { + if (canAcceptNewURL()) { + acceptNewURL(url); + if (canConsumePendingURL()) { + consumePendingURL(); + } else { + Frame frame = new Frame("can not ConsumePendingURL"); + frame.setSize(400, 400); + frame.setBackground(Color.BLACK); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent windowEvent){ + frame.dispose(); + } + }); + frame.setVisible(true); + } + } else { + Frame frame = new Frame("can not AcceptNewURL"); + frame.setSize(400, 400); + frame.setBackground(Color.BLACK); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent windowEvent){ + frame.dispose(); + } + }); + frame.setVisible(true); + } + } + + private boolean canAcceptNewURL() { + return StringUtils.isEmpty(this.pendingURL); + } + + private void acceptNewURL(String url) { + this.pendingURL = url; + } + + private boolean canConsumePendingURL() { + return StringUtils.isNotEmpty(this.pendingURL) && isDesignerStartupCompleted; + } + + private void consumePendingURL() { + String host = null; + String path = null; + Map params = new HashMap<>(); + + URL url = null; + try { + url = new URL(null, this.pendingURL, new URLStreamHandler() { + @Override + protected URLConnection openConnection(URL u) throws IOException { + return null; + } + }); + } catch (MalformedURLException ignored) {} + + if (url != null) { + host = url.getHost(); + path = url.getPath(); + + List pairs = URLUtils.parse(url.getQuery()); + for (NameValuePair pair: pairs) { + params.put(pair.getName(), pair.getValue()); + } + } + + FineLoggerFactory.getLogger().info("consume deep link: " + this.pendingURL); + performDeepLinks(this.pendingURL, host, path, params); + + markPendingURLConsumed(); + } + + private void performDeepLinks(String url, String host, String path, Map params) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + for (DeepLink deepLink: deepLinkList) { + if (deepLink.accept(url, host, path, params)) { + deepLink.run(url, host, path, params); + } + } + } + }); + } + + private void markPendingURLConsumed() { + this.pendingURL = null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/editor/editor/NotNegativeIntegerEditor.java b/designer-base/src/main/java/com/fr/design/editor/editor/NotNegativeIntegerEditor.java new file mode 100644 index 0000000000..98c59c1736 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/editor/editor/NotNegativeIntegerEditor.java @@ -0,0 +1,33 @@ +package com.fr.design.editor.editor; + +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; + +/** + * @author xiqiu + * @date 2022/1/10 + * @description 一个简单的非负整数框 + */ +public class NotNegativeIntegerEditor extends IntegerEditor { + private static final String NEG = "-"; + + public NotNegativeIntegerEditor(int columns) { + this(); + this.setColumns(columns); + } + + public NotNegativeIntegerEditor() { + super(); + this.numberField.addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent evt) { + char keyChar = evt.getKeyChar(); + if (NEG.equals(keyChar + "")) { + numberField.setText(numberField.getTextValue().replace(NEG, "")); + } + } + }); + } +} + diff --git a/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java b/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java index f35fbdf116..f671f220bf 100644 --- a/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java +++ b/designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java @@ -1,6 +1,6 @@ package com.fr.design.extra; -import com.fr.base.FRContext; +import com.fr.decision.webservice.v10.plugin.helper.category.impl.PluginResourceLoader; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.UIDialog; @@ -15,12 +15,12 @@ import com.fr.general.IOUtils; import com.fr.general.http.HttpToolbox; import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; +import com.fr.plugin.PluginStoreConfig; import com.fr.plugin.PluginStoreConstants; import com.fr.stable.CommonUtils; import com.fr.stable.EnvChangedListener; import com.fr.stable.ProductConstants; import com.fr.stable.StableUtils; -import com.fr.stable.StringUtils; import javax.swing.JOptionPane; import javax.swing.SwingWorker; @@ -44,15 +44,15 @@ public class WebViewDlgHelper { private static final String LATEST = "latest"; private static final String SHOP_SCRIPTS = "shop_scripts"; private static final int VERSION_8 = 8; - private static String installHome = FRContext.getCommonOperator().getWebRootPath(); + private static String installHome = PluginStoreConstants.getLocalInstallHome(); private static final String MAIN_JS_PATH = "/scripts/plugin.html"; - private static final String ENV_VERSION = "ENV_VERSION"; static { GeneralContext.addEnvChangedListener(new EnvChangedListener() { @Override public void envChanged() { - installHome = FRContext.getCommonOperator().getWebRootPath(); + installHome = PluginStoreConstants.getLocalInstallHome(); + PluginResourceLoader.INSTANCE.checkOldShopFile(); } }); } @@ -74,8 +74,11 @@ public class WebViewDlgHelper { } return; } - String jar_version = PluginStoreConstants.getProps(ENV_VERSION, StringUtils.EMPTY); - if (ComparatorUtils.equals(jar_version, ProductConstants.VERSION)) { + // 检测更新前先刷新一下版本号 + PluginStoreConstants.refreshProps(); + + String jarVersion = PluginStoreConfig.getInstance().getEnvVersion(); + if (ComparatorUtils.equals(jarVersion, ProductConstants.VERSION)) { updateShopScripts(SHOP_SCRIPTS); showPluginDlg(); } else { @@ -133,7 +136,7 @@ public class WebViewDlgHelper { * * @param filePath 待删除文件路径 */ - private static void deleteExtraFile(String filePath){ + private static void deleteExtraFile(String filePath) { CommonIOUtils.deleteFile(new File(filePath)); } @@ -259,7 +262,7 @@ public class WebViewDlgHelper { try { if (get()) { File scriptZip = new File(StableUtils.pathJoin(PluginConstants.DOWNLOAD_PATH, PluginConstants.TEMP_FILE)); - if(scriptZip.exists()){ + if (scriptZip.exists()) { IOUtils.unzip(scriptZip, installHome); CommonUtils.deleteFile(scriptZip); } @@ -283,7 +286,7 @@ public class WebViewDlgHelper { protected Void doInBackground() throws Exception { String url = CloudCenter.getInstance().acquireUrlByKind("shop.plugin.update"); if (url != null) { - String text = HttpToolbox.get(url + "?" + PluginUtils.FR_VERSION + "=" + ProductConstants.VERSION + "&version=" + PluginStoreConstants.getProps("VERSION")); + String text = HttpToolbox.get(url + "?" + PluginUtils.FR_VERSION + "=" + ProductConstants.VERSION + "&version=" + PluginStoreConfig.getInstance().getVersion()); JSONObject resultJSONObject = new JSONObject(text); String isLatest = resultJSONObject.optString("result"); if (!ComparatorUtils.equals(isLatest, LATEST)) { diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java index c1be964145..a6346c4dde 100644 --- a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java +++ b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java @@ -815,10 +815,11 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { String formulaText = formulaTextArea.getText().trim(); String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText); if (unSupportFormula != null) { - showMessageDialog(Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula, false); + showMessageDialog(Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula, false, true); return; } + boolean calException = false; String messageTips; FormulaCheckResult checkResult = FormulaChecker.check(formulaText); if (checkResult.grammarValid()) { @@ -847,6 +848,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { } catch (Exception ce) { //模拟计算如果出现错误,则抛出错误 calResult = ce.getMessage(); + calException = true; FineLoggerFactory.getLogger().error(ce.getMessage(), ce); messageTips = messageTips + Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Error") + ":" + calResult; } @@ -855,7 +857,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { messageTips = checkResult.getTips(); } if (checkResult.isValid()) { - showMessageDialog(messageTips, checkResult.isValid()); + showMessageDialog(messageTips, checkResult.isValid(), calException); } else { confirmCheckResult(checkResult, messageTips); } @@ -872,7 +874,7 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { private boolean confirmCheckResult(FormulaCheckResult checkResult, String messageTips) { if (checkResult.isValid()) { - showMessageDialog(checkResult.getTips(), checkResult.isValid()); + showMessageDialog(checkResult.getTips(), checkResult.isValid(), false); } else { int columns = checkResult.getFormulaCoordinates().getColumns(); String position = StringUtils.EMPTY; @@ -898,8 +900,8 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { return true; } - private void showMessageDialog(String message, boolean formulaValid) { - if (formulaValid) { + private void showMessageDialog(String message, boolean formulaValid, boolean calException) { + if (formulaValid && !calException) { FineJOptionPane.showMessageDialog( FormulaPane.this, message); diff --git a/designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java b/designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java index 28bb985552..6e128a4356 100644 --- a/designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java +++ b/designer-base/src/main/java/com/fr/design/formula/FunctionConstants.java @@ -36,6 +36,7 @@ import java.util.Comparator; import java.util.Enumeration; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -46,6 +47,7 @@ public final class FunctionConstants { public static NameAndFunctionList COMMON = getCommonFunctionList(); public static NameAndTypeAndFunctionList[] EMBFUNCTIONS = getEmbededFunctionListArray(); public static FunctionGroup ALL = getAllFunctionGroup(); + public static List abandonFormulas = Arrays.asList("CIRCULAR", "CROSSLAYERTOTAL", "HIERARCHY", "LAYERTOTAL"); static { loadEmbededFunctions(); @@ -54,7 +56,8 @@ public final class FunctionConstants { /** * Don't let anyone instantiate this class. */ - private FunctionConstants() {} + private FunctionConstants() { + } private static void loadEmbededFunctions() { String pkgName = "com.fr.function"; @@ -88,7 +91,10 @@ public final class FunctionConstants { Class cls = Class.forName(pkgName + "." + fileName.substring(0, fileName.length() - 6)); if (StableUtils.classInstanceOf(cls, iface)) { Function inst; - inst = (Function)cls.newInstance(); + inst = (Function) cls.newInstance(); + if (abandonFormulas.contains(inst.getClass().getSimpleName())) { + continue; + } for (NameAndTypeAndFunctionList EMBFUNCTION : EMBFUNCTIONS) { if (EMBFUNCTION.test(inst)) { break; @@ -300,11 +306,12 @@ public final class FunctionConstants { Collections.addAll(all, CUSTOM.getDescriptions()); //hugh:自定义函数分组 Set containers = ExtraClassManager.getInstance().getArray(FunctionDefContainer.MARK_STRING); - if(!containers.isEmpty()){ - for(Mutable container : containers){ - Collections.addAll(all,createFunctionGroup(((FunctionDefContainer)container)).getDescriptions()); + if (!containers.isEmpty()) { + for (Mutable container : containers) { + Collections.addAll(all, createFunctionGroup(((FunctionDefContainer) container)).getDescriptions()); } } + all = all.stream().filter(n -> !abandonFormulas.contains(n.getName())).collect(Collectors.toList()); Collections.sort(all, new Comparator() { @Override diff --git a/designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedTokenFunction.java b/designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedTokenFunction.java index dd830ed572..fb4eea22b7 100644 --- a/designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedTokenFunction.java +++ b/designer-base/src/main/java/com/fr/design/formula/exception/function/MismatchedTokenFunction.java @@ -90,6 +90,8 @@ public class MismatchedTokenFunction implements Function"; + } else if (tokenType == 33 || tokenType == 26 || tokenType == 31) { + return Toolkit.i18nText("Fine-Design_Basic_Formula_Right_Closing_Symbol"); } else { String[] tokenNames = (String[]) getFieldValue(exception, "tokenNames"); return tokenType >= 0 && tokenType < tokenNames.length ? TranslateTokenUtils.translateToken(tokenNames[tokenType]) : "<" + tokenType + ">"; diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java index 6b41986939..7198eeef09 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java @@ -16,12 +16,13 @@ import com.fr.stable.StringUtils; import javax.swing.JOptionPane; import javax.swing.JTree; import javax.swing.SwingWorker; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; -import java.awt.event.MouseEvent; import java.util.Enumeration; /** @@ -40,7 +41,7 @@ public class TableSearchTreeComboBox extends FRTreeComboBox { public TableSearchTreeComboBox(ChoosePane parent, JTree tree, TreeCellRenderer renderer) { super(tree, renderer); this.parent = parent; - setUI(new TableSearchTreeComboBoxUI()); + initPopupListener(); } protected UIComboBoxEditor createEditor() { @@ -158,12 +159,6 @@ public class TableSearchTreeComboBox extends FRTreeComboBox { } } - private static final TableNameFilter EMPTY_FILTER = new TableNameFilter() { - public boolean accept(TableProcedure procedure) { - return true; - } - }; - /** * 表名模糊搜索实现 */ @@ -184,15 +179,31 @@ public class TableSearchTreeComboBox extends FRTreeComboBox { } } - /** - * 重写FRTreeComboBoxUI,实现点击下拉时触发模糊搜索 - */ - private class TableSearchTreeComboBoxUI extends FRTreeComboBoxUI { - - @Override - public void mouseClicked(MouseEvent e) { - searchExecute(); + private static final TableNameFilter EMPTY_FILTER = new TableNameFilter() { + public boolean accept(TableProcedure procedure) { + return true; } + }; + + private void initPopupListener() { + // 点击下拉时触发模糊搜索 + this.addPopupMenuListener(new PopupMenuListener() { + + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + searchExecute(); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + + } + }); } /** diff --git a/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java b/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java index 4d36883240..fb6a7e88be 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java +++ b/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java @@ -197,7 +197,9 @@ public class JavaFxNativeFileChooser implements FileChooserProvider { private File currentDirectory; public Builder fileSelectionMode(FileSelectionMode fileSelectionMode) { - this.fileSelectionMode = fileSelectionMode; + if (fileSelectionMode != null) { + this.fileSelectionMode = fileSelectionMode; + } return this; } @@ -209,13 +211,17 @@ public class JavaFxNativeFileChooser implements FileChooserProvider { } public Builder filters(FileChooser.ExtensionFilter[] filters) { - this.filters = filters; + if (filters != null) { + this.filters = filters; + } return this; } public Builder filters(ExtensionFilter[] filters) { - for (ExtensionFilter filter : filters) { - this.filters = ArrayUtils.add(this.filters, new FileChooser.ExtensionFilter(filter.getDes(), filter.getExtensions())); + if (filters != null) { + for (ExtensionFilter filter : filters) { + this.filters = ArrayUtils.add(this.filters, new FileChooser.ExtensionFilter(filter.getDes(), filter.getExtensions())); + } } return this; } diff --git a/designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java b/designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java index 10bee69d27..65bec03a84 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/JSContentPane.java @@ -1,5 +1,6 @@ package com.fr.design.javascript; +import com.fr.base.svg.IconUtils; import com.fr.design.DesignerEnvManager; import com.fr.design.border.UIRoundedBorder; import com.fr.design.constants.KeyWords; @@ -16,6 +17,7 @@ import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.syntax.ui.rsyntaxtextarea.RSyntaxTextArea; import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants; +import com.fr.design.i18n.Toolkit; import com.fr.design.javascript.beautify.JavaScriptFormatHelper; import com.fr.design.javascript.jsapi.JSImplPopulateAction; import com.fr.design.javascript.jsapi.JSImplUpdateAction; @@ -92,7 +94,7 @@ public class JSContentPane extends BasicPane { private void addNewPaneLabel(){ - UILabel advancedEditorLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Advanced_Editor"), SwingConstants.LEFT); + UILabel advancedEditorLabel = new UILabel(Toolkit.i18nText("Fine-Design_Advanced_Editor"), IconUtils.readIcon("com/fr/design/images/edit/advancedEditor.svg"), SwingConstants.LEFT); advancedEditorLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); advancedEditorLabel.addMouseListener(new MouseAdapter() { @@ -104,7 +106,7 @@ public class JSContentPane extends BasicPane { jsImplUpdateAction.update(javaScript); newJavaScriptImplPane.populate(javaScript); if(advancedEditorDialog == null || !advancedEditorDialog.isVisible()) { - advancedEditorDialog = newJavaScriptImplPane.showWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { + advancedEditorDialog = newJavaScriptImplPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { @Override public void doOk() { if (javaScript != null) { @@ -117,7 +119,7 @@ public class JSContentPane extends BasicPane { public void doCancel() { super.doCancel(); } - }); + },new Dimension(900,800)); advancedEditorDialog.setModal(modal); advancedEditorDialog.setResizable(true); advancedEditorDialog.pack(); @@ -126,7 +128,7 @@ public class JSContentPane extends BasicPane { advancedEditorDialog.requestFocus(); } }); - labelPane.add(advancedEditorLabel,BorderLayout.CENTER); + labelPane.add(advancedEditorLabel,BorderLayout.EAST); } protected UIScrollPane createContentTextAreaPanel(){ @@ -181,7 +183,7 @@ public class JSContentPane extends BasicPane { } }); - labelPane.add(label,BorderLayout.EAST); + labelPane.add(label,BorderLayout.CENTER); JPanel jsParaPane = new JPanel(new BorderLayout(4, 4)); jsParaPane.setPreferredSize(new Dimension(300, 80)); UIScrollPane scrollPane = new UIScrollPane(funNameLabel); diff --git a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java index b1516fe366..8e8ef45b9f 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java @@ -1,5 +1,6 @@ package com.fr.design.javascript; +import com.fr.base.svg.IconUtils; import com.fr.design.border.UIRoundedBorder; import com.fr.design.constants.UIConstants; import com.fr.design.gui.autocomplete.AutoCompleteExtraRefreshComponent; @@ -12,7 +13,7 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextarea.UITextArea; -import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.gui.itextfield.PlaceholderTextField; import com.fr.design.i18n.Toolkit; import com.fr.design.javascript.jsapi.JSAPITreeHelper; import com.fr.design.javascript.jsapi.JSAPIUserObject; @@ -26,8 +27,10 @@ import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; import java.awt.BorderLayout; +import java.awt.CardLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Cursor; import java.awt.Desktop; import java.awt.Dimension; import java.awt.event.ActionEvent; @@ -69,7 +72,7 @@ import javax.swing.tree.TreePath; public class JSContentWithDescriptionPane extends JSContentPane implements KeyListener { //搜索关键词输入框 - private UITextField keyWordTextField = new UITextField(16); + private PlaceholderTextField keyWordTextField = new PlaceholderTextField(16); //搜索出的提示列表 private JList tipsList; private DefaultListModel tipsListModel = new DefaultListModel(); @@ -105,10 +108,15 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com"; - private static final String DOCUMENT_SEARCH_URL = CloudCenter.getInstance().acquireUrlByKind("af.doc_search"); + private static final String DOCUMENT_SEARCH_URL = "https://help.fanruan.com/finereport/api-helpdoc-title-"; private String currentValue; + private static CardLayout card; + + private static final String RELOAD_CARD = "reloadCard"; + private static final String DOC_LIST_CARD = "docListCard"; + public JSContentWithDescriptionPane(String[] args) { this.setLayout(new BorderLayout()); //=============================== @@ -156,6 +164,14 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi this.add(functionNameAndDescriptionPanel, BorderLayout.SOUTH); } + public void populate(String js) { + contentTextArea.setText(js); + ifHasBeenWriten = 1; + currentPosition = contentTextArea.getCaretPosition(); + beginPosition = getBeginPosition(); + insertPosition = beginPosition; + } + private void initContextAreaListener() { contentTextArea.addKeyListener(new KeyAdapter() { @Override @@ -186,6 +202,27 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi uninstallAutoCompletion(); } }); + contentTextArea.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + insertPosition = contentTextArea.getCaretPosition(); + if (ifHasBeenWriten == 0) { + contentTextArea.setText(StringUtils.EMPTY); + ifHasBeenWriten = 1; + contentTextArea.setForeground(Color.black); + insertPosition = 0; + } + } + + @Override + public void mouseReleased(MouseEvent e) { + currentPosition = contentTextArea.getCaretPosition(); + if (currentPosition == insertPosition) { + beginPosition = getBeginPosition(); + insertPosition = beginPosition; + } + } + }); } @Override @@ -281,9 +318,9 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi String value = ((JSAPIUserObject) userObject).getValue(); if (StringUtils.equals(value, directCategory)) { moduleTree.setSelectionPath(new TreePath(treeModel.getPathToRoot(node))); + moduleTree.scrollPathToVisible(moduleTree.getSelectionPath()); return true; } - return false; } for (int i = 0; i < node.getChildCount(); i++) { if (setModuleTreeSelection(node.getChildAt(i), directCategory, treeModel)) { @@ -315,7 +352,7 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi private void doHelpDocumentSearch() { Object value = interfaceNameList.getSelectedValue(); if (value != null) { - String url = DOCUMENT_SEARCH_URL + value.toString(); + String url = CloudCenter.getInstance().acquireUrlByKind("af.doc_search", DOCUMENT_SEARCH_URL) + value.toString(); try { String result = HttpToolbox.get(url); JSONObject jsonObject = new JSONObject(result); @@ -340,39 +377,60 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi } private void initHelpDocumentPane(JPanel descriptionAndDocumentPanel) { - UIScrollPane helpDOCScrollPane; + card = new CardLayout(); + JPanel mainPane = new JPanel(card); + initHelpDocumentList(); + UIScrollPane helpDOCScrollPane = new UIScrollPane(helpDOCList); + helpDOCScrollPane.setPreferredSize(new Dimension(200, 200)); + helpDOCScrollPane.setBorder(null); + mainPane.add(helpDOCScrollPane, DOC_LIST_CARD); + + UILabel imageLabel = new UILabel(); + imageLabel.setIcon(IconUtils.readIcon("com/fr/design/javascript/jsapi/images/connectFailed.svg")); + imageLabel.setPreferredSize(new Dimension(180, 65)); + JPanel imagePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + imagePane.setBorder(BorderFactory.createEmptyBorder(0, 42, 0, 0)); + imagePane.add(imageLabel); + imagePane.setBackground(Color.WHITE); + + UILabel failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Net_Connect_Failed"), 0); + failedLabel.setPreferredSize(new Dimension(180, 20)); + UILabel reloadLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Reload"), 0); + reloadLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + reloadLabel.setPreferredSize(new Dimension(180, 20)); + reloadLabel.setForeground(Color.blue); + JPanel labelPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, 0, 0, 0); + + labelPane.setBorder(BorderFactory.createEmptyBorder(35, 45, 0, 0)); + labelPane.setBackground(Color.WHITE); + labelPane.add(imagePane); + labelPane.add(failedLabel); + labelPane.add(reloadLabel); + JPanel containerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + containerPanel.add(labelPane, BorderLayout.CENTER); + reloadLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (isNetworkOk()) { + doHelpDocumentSearch(); + card.show(mainPane, DOC_LIST_CARD); + } + } + }); + mainPane.add(containerPanel, RELOAD_CARD); if (isNetworkOk()) { - helpDOCList = new JList(new DefaultListModel()); - initHelpDOCListRender(); - initHelpDOCListListener(); - helpDOCScrollPane = new UIScrollPane(helpDOCList); doHelpDocumentSearch(); + card.show(mainPane, DOC_LIST_CARD); } else { - UILabel label1 = new UILabel(Toolkit.i18nText("Fine-Design_Net_Connect_Failed"), 0); - label1.setPreferredSize(new Dimension(180, 20)); - UILabel label2 = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Reload"), 0); - label2.setPreferredSize(new Dimension(180, 20)); - label2.setForeground(Color.blue); - JPanel labelPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, 0, 0, 0); - labelPane.setBackground(Color.WHITE); - labelPane.add(label1); - labelPane.add(label2); - JPanel containerPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - containerPanel.add(labelPane, BorderLayout.CENTER); - helpDOCScrollPane = new UIScrollPane(containerPanel); - label2.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - descriptionAndDocumentPanel.removeAll(); - initHelpDocumentPane(descriptionAndDocumentPanel); - - } - }); + card.show(mainPane, RELOAD_CARD); } - helpDOCScrollPane.setPreferredSize(new Dimension(200, 200)); - helpDOCScrollPane.setBorder(null); - descriptionAndDocumentPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Relevant_Cases"), helpDOCScrollPane), BorderLayout.EAST); + descriptionAndDocumentPanel.add(this.createNamePane(Toolkit.i18nText("Fine-Design_Relevant_Cases"), mainPane), BorderLayout.EAST); + } + private void initHelpDocumentList() { + helpDOCList = new JList(new DefaultListModel()); + initHelpDOCListRender(); + initHelpDOCListListener(); } private void initHelpDOCListListener() { @@ -383,19 +441,21 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi Object value = helpDOCList.getSelectedValue(); if (value instanceof HelpDocument) { String url = ((HelpDocument) value).getDocumentUrl(); - try { - Desktop.getDesktop().browse(new URI(url)); - } catch (IOException ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - } catch (URISyntaxException ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - } + browse(url); } } } }); } + private void browse(String url){ + try { + Desktop.getDesktop().browse(new URI(url)); + } catch (IOException | URISyntaxException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + } + private void initHelpDOCListRender() { helpDOCList.setCellRenderer(new DefaultListCellRenderer() { @Override @@ -558,7 +618,12 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi } private void initInterfaceNameModule() { - moduleTree.setSelectionPath(moduleTree.getPathForRow(0)); + DefaultTreeModel defaultTreeModel = (DefaultTreeModel) moduleTree.getModel(); + TreeNode root = (TreeNode) defaultTreeModel.getRoot(); + while (root.getChildCount() > 0){ + root = root.getChildAt(0); + } + moduleTree.setSelectionPath(new TreePath(defaultTreeModel.getPathToRoot(root))); } private void setDescription(String interfaceName) { @@ -652,6 +717,7 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi tipsPane.setBorder(BorderFactory.createEmptyBorder(30, 2, 0, 0)); JPanel searchPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); searchPane.setLayout(new BorderLayout(4, 4)); + keyWordTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Search_Interface")); searchPane.add(keyWordTextField, BorderLayout.CENTER); //搜索按钮 diff --git a/designer-base/src/main/java/com/fr/design/mainframe/BaseJForm.java b/designer-base/src/main/java/com/fr/design/mainframe/BaseJForm.java index d3cff1ff95..dc36836c16 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/BaseJForm.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/BaseJForm.java @@ -10,7 +10,7 @@ import javax.swing.JComponent; * Date: 13-7-15 * Time: 上午10:28 */ -public interface BaseJForm extends JTemplateProvider { +public interface BaseJForm extends JTemplateProvider, JDashboard { String XML_TAG = "JForm"; int FORM_TAB = 0; @@ -58,4 +58,9 @@ public interface BaseJForm extends JTemplateProvider { * @param ecContainer ElementCase所在container */ void tabChanged(int index, FormElementCaseContainerProvider ecContainer); + + @Override + default void switchToDashBoardEditor() { + tabChanged(FORM_TAB); + } } \ No newline at end of file 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 be841f79a3..2534de5266 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 @@ -28,6 +28,8 @@ 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.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; @@ -157,6 +159,11 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta @Override public void windowClosing(WindowEvent e) { + // 检查mini商城是否存在未结束的后台任务 + if (!MiniShopDisposingChecker.check()) { + return; + } + // 关闭前check if (!TemplateSavingChecker.check()) { return; 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 new file mode 100644 index 0000000000..d2b45f4ea1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/JDashboard.java @@ -0,0 +1,10 @@ +package com.fr.design.mainframe; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/3/1 + */ +public interface JDashboard { + void switchToDashBoardEditor(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index f1a40ccdc7..f37b817e99 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -2,6 +2,7 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.Parameter; +import com.fr.base.TRL; import com.fr.base.extension.FileExtension; import com.fr.base.io.BaseBook; import com.fr.base.iofile.attr.DesignBanCopyAttrMark; @@ -105,9 +106,9 @@ import javax.swing.JOptionPane; import javax.swing.SwingConstants; import javax.swing.undo.UndoManager; import java.awt.BorderLayout; -import java.io.ByteArrayOutputStream; import java.awt.Dimension; import java.awt.FontMetrics; +import java.io.ByteArrayOutputStream; import java.util.Set; import java.util.concurrent.Callable; @@ -1000,7 +1001,7 @@ public abstract class JTemplate> return true; } - public boolean isNewCreateTpl(){ + public boolean isNewCreateTpl() { return isNewCreateTpl; } @@ -1543,7 +1544,7 @@ public abstract class JTemplate> /** * 设置新引擎后,有不支持的功能时,设计器中模板的标题需要加上“兼容模式”或者“不支持分页引擎”来提示用户 - * */ + */ private String compatibilityTip() { if (!CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())) { return StringUtils.EMPTY; @@ -1888,6 +1889,15 @@ public abstract class JTemplate> templateThemeButton.setToolTipText(name); } + /** + * 定位 + * + * @param trl + */ + public void navigate(TRL trl) { + + } + public void generateForBiddenTemplate() { } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java index 88a4623071..2dc68704ec 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/form/FormECDesignerProvider.java @@ -1,10 +1,6 @@ package com.fr.design.mainframe.form; -import java.awt.Dimension; -import java.awt.image.BufferedImage; - -import javax.swing.JComponent; - +import com.fr.base.TRL; import com.fr.design.designer.TargetComponent; import com.fr.design.mainframe.JTemplate; import com.fr.design.menu.MenuDef; @@ -12,6 +8,10 @@ import com.fr.design.menu.ShortCut; import com.fr.design.menu.ToolBarDef; import com.fr.form.FormElementCaseProvider; +import javax.swing.JComponent; +import java.awt.Dimension; +import java.awt.image.BufferedImage; + public interface FormECDesignerProvider { String XML_TAG = "FormElementCaseDesigner"; @@ -92,4 +92,6 @@ public interface FormECDesignerProvider { void refreshPropertyPane(); void removeSelection(); + + default void navigate(TRL trl) {} } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java b/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java index 1cb8e5d1aa..621956ce6a 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/loghandler/DesignerLogHandler.java @@ -1,31 +1,46 @@ package com.fr.design.mainframe.loghandler; +import com.finebi.cbb.base.tuple.Pair; import com.fr.base.BaseUtils; +import com.fr.base.TRL; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.imenu.UIMenuItem; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; import com.fr.design.ui.util.UIUtil; +import com.fr.file.FILEFactory; import com.fr.general.ComparatorUtils; import com.fr.general.log.Log4jConfig; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; - +import com.fr.stable.project.ProjectConstants; import com.fr.third.apache.logging.log4j.Level; import com.fr.third.apache.logging.log4j.core.LogEvent; +import com.fr.third.guava.base.Splitter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import javax.swing.AbstractAction; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JCheckBoxMenuItem; import javax.swing.JComponent; +import javax.swing.JEditorPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JTextPane; import javax.swing.KeyStroke; +import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultEditorKit; import javax.swing.text.Document; +import javax.swing.text.Element; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; +import javax.swing.text.html.HTML; +import javax.swing.text.html.HTMLDocument; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; @@ -36,8 +51,14 @@ import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.io.IOException; import java.text.SimpleDateFormat; +import java.util.ArrayDeque; +import java.util.ArrayList; import java.util.Date; +import java.util.Deque; +import java.util.List; +import java.util.regex.Pattern; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; @@ -61,6 +82,8 @@ public class DesignerLogHandler { private static final String ACTION_MAP_KEY = "clear"; + private static final Pattern pattern = Pattern.compile("\\([^(]*.(?>cpt|frm|cptx)[^)]*\\)"); + public static DesignerLogHandler getInstance() { return HOLDER.singleton; @@ -215,13 +238,61 @@ public class DesignerLogHandler { popup.show(jTextArea, event.getX(), event.getY()); checkEnabled(); } + if (event.getButton() == MouseEvent.BUTTON1) { + String url = findTplLinkFromMouseEvent(event); + if (StringUtils.isNotEmpty(url)) { + navigate(url); + } + } } }); } + /** + * 将模板定位链接导航到指定的位置 + * + * @param href 模板定位链接 + */ + private void navigate(String href) { + if (!href.startsWith(TRL.PREFIX)) { + return; + } + TRL trl = new TRL(href); + DesignerContext.getDesignerFrame().openTemplate(FILEFactory.createFILE(ProjectConstants.REPORTLETS_NAME + FILEFactory.SEPARATOR + trl.getTemplatePath())); + JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (currentEditingTemplate != null) { + currentEditingTemplate.navigate(trl); + } + } + + /** + * 鼠标事件中定位到模板链接 + * + * @param event 鼠标事件 + * @return 模板链接 + */ + private String findTplLinkFromMouseEvent(MouseEvent event) { + JEditorPane editor = (JEditorPane) event.getSource(); + int pos = editor.getUI().viewToModel(editor, event.getPoint()); + if (pos >= 0 && editor.getDocument() instanceof HTMLDocument) { + HTMLDocument hdoc = (HTMLDocument) editor.getDocument(); + Element elem = hdoc.getCharacterElement(pos); + Object a = elem.getAttributes().getAttribute(HTML.Tag.A); + if (a instanceof AttributeSet) { + AttributeSet set = (AttributeSet) a; + String url = (String) set.getAttribute(HTML.Attribute.HREF); + if (StringUtils.isNotEmpty(url)) { + return url; + } + } + } + return StringUtils.EMPTY; + } + private JTextPane initLogJTextArea() { final JTextPane resultPane = new JTextPane(); + resultPane.setContentType("text/html"); InputMap inputMap = resultPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER), DefaultEditorKit.copyAction); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, DEFAULT_MODIFIER), DefaultEditorKit.selectAllAction); @@ -294,6 +365,9 @@ public class DesignerLogHandler { SimpleAttributeSet attrSet = new SimpleAttributeSet(); if (style == DesignerLogger.ERROR_INT) { + if (renderLink(str)) { + return; + } StyleConstants.setForeground(attrSet, Color.RED); StyleConstants.setBold(attrSet, true); } else if (style == DesignerLogger.WARN_INT) { @@ -314,6 +388,86 @@ public class DesignerLogHandler { } } + /** + * 渲染模板链接 + * + * @param str 可能包含模板链接字符串 + * @return 是否处理成功 + */ + private boolean renderLink(String str) { + Document doc = jTextArea.getStyledDocument(); + if (doc instanceof HTMLDocument) { + String[] tplLink = findTplLink(str); + return tplLink != null + && tplLink.length > 0 + && link2Html(str, tplLink); + } + return false; + } + + /** + * 处理模板链接 + * + * @param s 含有模板链接 + * @param tplLink 模板链接 + * @return 是否处理成功 + */ + private boolean link2Html(String s, String[] tplLink) { + List lineSeg = splitLineSeg(s, tplLink); + String html = buildHtml(lineSeg, tplLink); + try { + Document doc = jTextArea.getStyledDocument(); + HTMLDocument htmlDocument = (HTMLDocument) doc; + htmlDocument.insertAfterEnd(htmlDocument.getCharacterElement(doc.getLength()), html); + } catch (BadLocationException | IOException ignored) { + // 这里出问题不记录日志否则会导致死循环 + return false; + } + return true; + } + + @NotNull + private String buildHtml(List lineSeg, String[] tplLink) { + StringBuilder sb = new StringBuilder(""); + for (int i = 0; i < tplLink.length; i++) { + sb.append("") + .append(lineSeg.get(i)) + .append("") + .append(tplLink[i]) + .append(""); + } + if (lineSeg.size() > tplLink.length) { + sb.append("").append(lineSeg.get(lineSeg.size() - 1)).append(""); + } + sb.append(""); + return sb.toString(); + } + + /** + * 将非公式部分切割为数组 + */ + @NotNull + private List splitLineSeg(String s, String[] tplLink) { + String seg = s.replaceAll("\\n", "
"); + List lineSeg = new ArrayList<>(2); + List lineSegTmp = new ArrayList<>(); + String tmp = seg; + for (String link : tplLink) { + lineSegTmp = Splitter.on(link).omitEmptyStrings().splitToList(tmp); + lineSeg.add(lineSegTmp.get(0)); + if (lineSegTmp.size() > 1) { + tmp = lineSegTmp.get(1); + } + } + if (lineSegTmp.size() > 1) { + lineSeg.add(lineSegTmp.get(1)); + } + return lineSeg; + } + + private String appendLocaleMark(String str, int style) { if (style == DesignerLogger.ERROR_INT) { @@ -375,4 +529,34 @@ public class DesignerLogHandler { }; } + + /** + * 尝试找到模板链接 + * + * @param s 可能含有模板链接的字符串 + * @return 模板链接 + */ + @Nullable + public static String[] findTplLink(String s) { + List list = new ArrayList<>(); + // 栈配对 + Deque> stack = new ArrayDeque<>(); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c == '(') { + stack.push(new Pair<>(c, i)); + } else if (c == ')') { + Pair left = stack.peek(); + if (left != null && left.getFirst() == '(') { + Pair pop = stack.pop(); + String link = s.substring(pop.getSecond(), i + 1); + if (link.contains(ProjectConstants.CPT_SUFFIX) + || link.contains(ProjectConstants.FRM_SUFFIX)) { + list.add(link); + } + } + } + } + return list.toArray(new String[0]); + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/ComponentShareUtil.java b/designer-base/src/main/java/com/fr/design/mainframe/share/ComponentShareUtil.java index cec7fbc8fc..2445826128 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/share/ComponentShareUtil.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/ComponentShareUtil.java @@ -34,6 +34,10 @@ public class ComponentShareUtil { return localeMark.getValue(); } + public static boolean isShowMiniShopWindow() { + return isShowOnlineWidgetRepoPane(); + } + /** * 判断是否可触达 * diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopDisposingChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopDisposingChecker.java new file mode 100644 index 0000000000..dd76befe66 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopDisposingChecker.java @@ -0,0 +1,37 @@ +package com.fr.design.mainframe.share.mini; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; + +import javax.swing.JOptionPane; +import java.awt.Component; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/8 + */ +public class MiniShopDisposingChecker { + + public static boolean check() { + return check(DesignerContext.getDesignerFrame()); + } + + public static boolean check(Component optionParentComponent) { + if (MiniShopNativeTaskManager.getInstance().hasExecutingTasks()) { + int result = FineJOptionPane.showConfirmDialog( + optionParentComponent, + Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Close_Tip"), + "", + FineJOptionPane.YES_NO_OPTION + ); + if (result == JOptionPane.YES_OPTION) { + MiniShopNativeTaskManager.getInstance().cancelAllExecutingTasks(); + return true; + } + return false; + } + return true; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopNativeTask.java b/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopNativeTask.java new file mode 100644 index 0000000000..9144f2fa0d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopNativeTask.java @@ -0,0 +1,11 @@ +package com.fr.design.mainframe.share.mini; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/8 + */ +public interface MiniShopNativeTask { + void execute(); + void cancel(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopNativeTaskManager.java b/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopNativeTaskManager.java new file mode 100644 index 0000000000..514ff84c82 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/mini/MiniShopNativeTaskManager.java @@ -0,0 +1,42 @@ +package com.fr.design.mainframe.share.mini; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/8 + */ +public class MiniShopNativeTaskManager { + private MiniShopNativeTaskManager() { + } + private static class HOLDER { + private static final MiniShopNativeTaskManager singleton = new MiniShopNativeTaskManager(); + } + public static MiniShopNativeTaskManager getInstance() { + return MiniShopNativeTaskManager.HOLDER.singleton; + } + + + private static final Set executingTasks = new HashSet<>(); + + public void addStartedTask(MiniShopNativeTask task) { + executingTasks.add(task); + } + + public void removeCompletedTask(MiniShopNativeTask task) { + executingTasks.remove(task); + } + + public boolean hasExecutingTasks() { + return !executingTasks.isEmpty(); + } + + public void cancelAllExecutingTasks() { + for (MiniShopNativeTask executingTask: executingTasks) { + executingTask.cancel(); + } + executingTasks.clear(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java index 9e88dfba1a..92acb5c71e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java @@ -206,7 +206,7 @@ public abstract class TemplateThemeProfilePane extends }); } - public UIButton createSaveButton() { + public UIButton createSaveButton(final TemplateThemeProfileDialog profileDialog) { saveButton = new UIButton(); saveButton.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save")); saveButton.setEnabled(false); @@ -224,6 +224,7 @@ public abstract class TemplateThemeProfilePane extends @Override public void run() { DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save_Successfully")); + profileDialog.exit(); } }); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java index da0649d804..bf65b9be28 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java @@ -7,6 +7,7 @@ import com.fr.design.mainframe.theme.TemplateThemeGridPagesPane; import com.fr.design.mainframe.theme.TemplateThemeGridPane; import javax.swing.JPanel; +import java.awt.Window; /** * @author Starryi @@ -19,13 +20,17 @@ public class TemplateThemeGridPagesDialog extends TemplateThemeDialog implements protected TemplateThemeGridPagesPane overallPane; - public TemplateThemeGridPagesDialog() { - super(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); + public TemplateThemeGridPagesDialog(Window parentWindow) { + super(parentWindow, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); setupContentPane(); setupActionButtons(); } + public TemplateThemeGridPagesDialog() { + this(DesignerContext.getDesignerFrame()); + } + @Override protected JPanel createContentPane() { overallPane = new TemplateThemeGridPagesPane(this); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java index a76597f8e8..0a26a6691e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java @@ -90,7 +90,7 @@ public class TemplateThemeProfileDialog extends Templat })); } - uiButtonList.add(profilePane.createSaveButton()); + uiButtonList.add(profilePane.createSaveButton(TemplateThemeProfileDialog.this)); uiButtonList.add(profilePane.createSaveAsButton(TemplateThemeProfileDialog.this)); uiButtonList.add(createCancelButton()); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java index 420a7ed439..9818e60b5c 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java @@ -1,11 +1,18 @@ package com.fr.design.mainframe.theme.dialog; +import java.awt.Window; + /** * @author Starryi * @version 1.0 * Created by Starryi on 2021/8/13 */ public class TemplateThemeUsingDialog extends TemplateThemeGridPagesDialog { + public TemplateThemeUsingDialog(Window parentWindow) { + super(parentWindow); + overallPane.showThemeUsingPane(); + } + public TemplateThemeUsingDialog() { super(); overallPane.showThemeUsingPane(); diff --git a/designer-base/src/main/java/com/fr/design/report/fit/FormFitAttrModelType.java b/designer-base/src/main/java/com/fr/design/report/fit/FormFitAttrModelType.java index a77566442d..c43aa057d8 100644 --- a/designer-base/src/main/java/com/fr/design/report/fit/FormFitAttrModelType.java +++ b/designer-base/src/main/java/com/fr/design/report/fit/FormFitAttrModelType.java @@ -27,8 +27,8 @@ public enum FormFitAttrModelType { @Override public Item[] getAbsoluteLayoutSaleAttr() { return new Item[]{ - new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fit"), WAbsoluteLayout.STATE_FIT), - new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), WAbsoluteLayout.STATE_FIXED) + new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WAbsoluteLayout.STATE_FIT), + new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit-No"), WAbsoluteLayout.STATE_FIXED) }; } @@ -73,7 +73,7 @@ public enum FormFitAttrModelType { return new Item[]{ new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL), new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN), - new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), 2)}; + new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit-No"), 2)}; } @Override @@ -81,7 +81,7 @@ public enum FormFitAttrModelType { return new Item[]{ new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Bidirectional_Adaptive"), WFitLayout.STATE_FULL), new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Horizontal_Adaptive"), WFitLayout.STATE_ORIGIN), - new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode_Fixed"), 2)}; + new Item(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit-No"), 2)}; } diff --git a/designer-base/src/main/java/com/fr/design/selection/Selectedable.java b/designer-base/src/main/java/com/fr/design/selection/Selectedable.java index 5e78482e82..8900054431 100644 --- a/designer-base/src/main/java/com/fr/design/selection/Selectedable.java +++ b/designer-base/src/main/java/com/fr/design/selection/Selectedable.java @@ -1,25 +1,29 @@ package com.fr.design.selection; +import com.fr.base.TRL; + /** - * * @author zhou * @since 2012-7-26上午10:20:32 */ public interface Selectedable { - public S getSelection(); + S getSelection(); + + void setSelection(S selectElement); - public void setSelection(S selectElement); + /** + * Adds a ChangeListener to the listener list. + */ + void addSelectionChangeListener(SelectionListener selectionListener); - /** - * Adds a ChangeListener to the listener list. - */ - public void addSelectionChangeListener(SelectionListener selectionListener); + /** + * removes a ChangeListener from the listener list. + */ + void removeSelectionChangeListener(SelectionListener selectionListener); - /** - * removes a ChangeListener from the listener list. - */ - public void removeSelectionChangeListener(SelectionListener selectionListener); + // august:这儿就不要加fireSelectionChangeListener方法了。因为这个方法一般要定义成私有的,不然外部随即的调用! + default void navigate(TRL trl) { - // august:这儿就不要加fireSelectionChangeListener方法了。因为这个方法一般要定义成私有的,不然外部随即的调用! + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/startup/FineStartupNotificationFactory.java b/designer-base/src/main/java/com/fr/design/startup/FineStartupNotificationFactory.java new file mode 100644 index 0000000000..b303d491ff --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/startup/FineStartupNotificationFactory.java @@ -0,0 +1,33 @@ +package com.fr.design.startup; + +import org.jetbrains.annotations.NotNull; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/11 + */ +public class FineStartupNotificationFactory { + private static final FineStartupNotificationProvider DEFAULT = Install4jStartupNotificationProvider.getInstance(); + private static FineStartupNotificationProvider provider; + + public FineStartupNotificationFactory() { + } + + public static FineStartupNotificationProvider getNotification() { + return provider; + } + + public static void setLogger(@NotNull FineStartupNotificationProvider provider) { + FineStartupNotificationFactory.provider = provider; + } + + public static void reset() { + provider = DEFAULT; + } + + + static { + provider = DEFAULT; + } +} diff --git a/designer-base/src/main/java/com/fr/design/startup/FineStartupNotificationProvider.java b/designer-base/src/main/java/com/fr/design/startup/FineStartupNotificationProvider.java new file mode 100644 index 0000000000..b90390a703 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/startup/FineStartupNotificationProvider.java @@ -0,0 +1,14 @@ +package com.fr.design.startup; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/11 + */ +public interface FineStartupNotificationProvider { + void registerStartupListener(Listener listener); + + interface Listener { + void startupPerformed(String parameters); + } +} diff --git a/designer-base/src/main/java/com/fr/design/startup/Install4jStartupNotificationProvider.java b/designer-base/src/main/java/com/fr/design/startup/Install4jStartupNotificationProvider.java new file mode 100644 index 0000000000..dbc7be2b72 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/startup/Install4jStartupNotificationProvider.java @@ -0,0 +1,35 @@ +package com.fr.design.startup; + +import com.install4j.api.launcher.StartupNotification; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/11 + */ +public class Install4jStartupNotificationProvider implements FineStartupNotificationProvider { + + private Install4jStartupNotificationProvider() { + } + private static final Install4jStartupNotificationProvider INSTANCE = new Install4jStartupNotificationProvider(); + public static Install4jStartupNotificationProvider getInstance() { + return INSTANCE; + } + + @Override + public void registerStartupListener(Listener listener) { + boolean supported = false; + try { + supported = Class.forName("com.install4j.api.launcher.StartupNotification") != null; + } catch (Throwable ignored) {} + + if (supported) { + StartupNotification.registerStartupListener(new StartupNotification.Listener() { + @Override + public void startupPerformed(String parameters) { + listener.startupPerformed(parameters); + } + }); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/style/AbstractPopBox.java b/designer-base/src/main/java/com/fr/design/style/AbstractPopBox.java index 4df9b75144..9cff473c11 100644 --- a/designer-base/src/main/java/com/fr/design/style/AbstractPopBox.java +++ b/designer-base/src/main/java/com/fr/design/style/AbstractPopBox.java @@ -10,8 +10,6 @@ import javax.swing.JWindow; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.util.ArrayList; -import java.util.List; import java.awt.AWTEvent; import java.awt.Dimension; import java.awt.Point; @@ -21,6 +19,8 @@ import java.awt.Window; import java.awt.event.AWTEventListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; /** * @author kunsnat E-mail:kunsnat@gmail.com diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java index d755d4e05f..0b56fc0ad6 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java @@ -17,8 +17,11 @@ import com.teamdev.jxbrowser.engine.EngineOptions; import com.teamdev.jxbrowser.engine.RenderingMode; import com.teamdev.jxbrowser.event.Observer; import com.teamdev.jxbrowser.js.JsObject; +import com.teamdev.jxbrowser.net.Network; import com.teamdev.jxbrowser.net.Scheme; +import com.teamdev.jxbrowser.net.callback.VerifyCertificateCallback; import com.teamdev.jxbrowser.view.swing.BrowserView; +import org.jetbrains.annotations.Nullable; import java.awt.BorderLayout; @@ -108,6 +111,17 @@ public class NewModernUIPane extends ModernUIPane { } Engine engine = Engine.newInstance(builder.build()); + if (DesignerEnvManager.getEnvManager().isOpenDebug()) { + // 调试模式下,禁止HTTPS证书验证,使得可以正常访问商城测试服务器等 + Network network = engine.network(); + network.set(VerifyCertificateCallback.class, new VerifyCertificateCallback() { + @Nullable + @Override + public Response on(Params params) { + return VerifyCertificateCallback.Response.valid(); + } + }); + } browser = engine.newBrowser(); // 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的 diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java b/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java index f3284c11e5..576c5a9b96 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java @@ -1,6 +1,6 @@ package com.fr.design.upm; -import com.fr.base.FRContext; +import com.fr.decision.webservice.v10.plugin.helper.category.impl.BaseResourceLoader; import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.UIDialog; @@ -12,8 +12,11 @@ import com.fr.design.update.ui.dialog.UpdateMainDialog; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; +import com.fr.general.CommonIOUtils; import com.fr.general.GeneralContext; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; +import com.fr.plugin.PluginStoreConstants; import com.fr.stable.StableUtils; import com.fr.workspace.Workspace; import com.fr.workspace.WorkspaceEvent; @@ -33,7 +36,7 @@ public class UpmFinder { private static final String MAIN_RESOURCE_PATH = UPM_DIR + "/plugin_design.html"; private static final String JXBROWSER = "com.teamdev.jxbrowser.browser.Browser"; - public static String installHome = FRContext.getCommonOperator().getWebRootPath(); + public static String installHome = PluginStoreConstants.getLocalInstallHome(); private static UIDialog dialog = null; @@ -41,7 +44,8 @@ public class UpmFinder { EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener() { @Override public void on(Event event, Workspace param) { - installHome = FRContext.getCommonOperator().getWebRootPath(); + installHome = PluginStoreConstants.getLocalInstallHome(); + UpmResourceLoader.INSTANCE.checkOldShopFile(); } }); } @@ -75,24 +79,24 @@ public class UpmFinder { } private static void showUpmPane() { - if (!checkUPMResourcesExist()){ + if (!checkUPMResourcesExist()) { // upm下载 int val = FineJOptionPane.showConfirmDialog(null, Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Need_Install"), Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE); - if (val == JOptionPane.OK_OPTION){ + if (val == JOptionPane.OK_OPTION) { try { UpmResourceLoader.INSTANCE.download(); - UpmResourceLoader.INSTANCE.install(); + installUpmResource(); + FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Basic_Plugin_Shop_Installed"), Toolkit.i18nText("Fine-Design_Basic_Message"), JOptionPane.INFORMATION_MESSAGE); - } catch (Exception e){ + } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); FineJOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Updater_Download_Failed"), Toolkit.i18nText("Fine-Design_Basic_Message"), JOptionPane.INFORMATION_MESSAGE); } } - } - else { + } else { UpmShowPane upmPane = new UpmShowPane(); if (dialog == null) { dialog = new UpmShowDialog(DesignerContext.getDesignerFrame(), upmPane); @@ -102,6 +106,15 @@ public class UpmFinder { } } + private static void installUpmResource() { + String installHome = PluginStoreConstants.getLocalInstallHome(); + File scriptZip = new File(BaseResourceLoader.SCRIPT_DOWNLOAD_PATH); + if (scriptZip.exists()) { + IOUtils.unzip(scriptZip, installHome); + CommonIOUtils.deleteFile(scriptZip); + } + } + private static void showUpdatePane() { JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Update_Info_Plugin_Message")); if (!GeneralContext.getLocale().equals(Locale.JAPANESE) && !GeneralContext.getLocale().equals(Locale.JAPAN) 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 f066d648a2..f9fb484a6a 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 @@ -5,6 +5,7 @@ import com.fr.base.ServerConfig; import com.fr.concurrent.NamedThreadFactory; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; +import com.fr.design.deeplink.DeepLinkCore; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.fun.DesignerEnvProcessor; import com.fr.design.gui.UILookAndFeel; @@ -26,10 +27,15 @@ import com.fr.start.ServerStarter; 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; @@ -213,6 +219,14 @@ public class DesignUtils { DesignerContext.getDesignerFrame().openTemplate(new FileFILE(f)); } }); + } else { + String url = line; + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + DeepLinkCore.getInstance().receiveDeeplink2(url); + } + }); } } } diff --git a/designer-base/src/main/java/com/fr/design/utils/LoadingUtils.java b/designer-base/src/main/java/com/fr/design/utils/LoadingUtils.java index d464dec796..a5a6803d3f 100644 --- a/designer-base/src/main/java/com/fr/design/utils/LoadingUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/LoadingUtils.java @@ -21,7 +21,7 @@ public class LoadingUtils { public static JPanel createLoadingPane() { JPanel jPanel = new JPanel(); UILabel loadingLabel = new UILabel(LOADING_ICON); - UILabel tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Open_Template_Loading")); + UILabel tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Loading")); tipLabel.setForeground(TIP_COLOR); jPanel.setLayout(new LayoutManager() { @Override diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index 426fd18e26..30f55d7ef0 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -47,9 +47,9 @@ import com.fr.stable.StringUtils; import com.fr.stable.os.windows.WindowsDetector; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; - import com.fr.workspace.Workspace; import com.fr.workspace.WorkspaceEvent; + import javax.swing.AbstractAction; import javax.swing.AbstractListModel; import javax.swing.ActionMap; @@ -202,6 +202,16 @@ public class FILEChooserPane extends BasicPane { return INSTANCE; } + public static FILEChooserPane getInstanceWithDesignatePath(String path, FILEFilter filter) { + INSTANCE.showLoc = false; + INSTANCE.showEnv = false; + INSTANCE.showWebReport = false; + INSTANCE.setDesignateModel(path); + INSTANCE.removeAllFilter(); + INSTANCE.addChooseFILEFilter(filter, 0); + return INSTANCE; + } + public static FILEChooserPane getMultiEnvInstance(boolean showLoc, boolean showWebReport) { INSTANCE.showEnv = true; INSTANCE.showLoc = showLoc; @@ -499,7 +509,7 @@ public class FILEChooserPane extends BasicPane { } private String calProperFileName(String fileName, ChooseFileFilter fileFilter) { - if(fileFilter == null){ + if (fileFilter == null) { return fileName; } String filterExtension = fileFilter.getExtensionString(); @@ -516,10 +526,10 @@ public class FILEChooserPane extends BasicPane { return fileNameWithOutExtension + filterExtension; } - private boolean isMapping(String fromExtension, String toExtension){ - if(FileExtension.CPTX.matchExtension(fromExtension)){ + private boolean isMapping(String fromExtension, String toExtension) { + if (FileExtension.CPTX.matchExtension(fromExtension)) { return FileExtension.CPT.matchExtension(toExtension); - }else if(FileExtension.CPT.matchExtension(fromExtension)){ + } else if (FileExtension.CPT.matchExtension(fromExtension)) { return FileExtension.CPTX.matchExtension(toExtension); } return false; @@ -678,7 +688,7 @@ public class FILEChooserPane extends BasicPane { * 移除文件后缀的方法 * 解决cptx文件的另存为操作默认会出现双后缀的bug(xxx.cptx.cpt) **/ - private String removeSuffix(String text){ + private String removeSuffix(String text) { return FileExtension.CPTX.matchExtension(text) ? text.substring(0, text.length() - FileExtension.CPTX.getSuffix().length()) : text; } @@ -783,7 +793,7 @@ public class FILEChooserPane extends BasicPane { ChooseFileFilter supportedTypes = new ChooseFileFilter(FRContext.getFileNodes().getSupportedTypes(), appName + Toolkit.i18nText("Fine-Design_Report_Template_File")); Set providers = ExtraReportClassManager.getInstance().getArray(ReportSupportedFileProvider.XML_TAG); for (ReportSupportedFileProvider provider : providers) { - for (FileExtension fileExtension : provider.getFileExtensions()){ + for (FileExtension fileExtension : provider.getFileExtensions()) { supportedTypes.addExtension(fileExtension.getExtension()); } } @@ -884,7 +894,7 @@ public class FILEChooserPane extends BasicPane { saveDictionary(); dialogExit(); } else { - FineJOptionPane.showMessageDialog(this, Toolkit.i18nText("Fine-Design_Basic_App_Template_Report_Not_Exist")); + FineJOptionPane.showMessageDialog(this, Toolkit.i18nText("Fine-Design_Basic_App_File_Not_Exist")); return; } } @@ -915,7 +925,7 @@ public class FILEChooserPane extends BasicPane { if (access(selectedFile) && access(currentDirectory)) { if (selectedFile.exists()) { int selVal = FineJOptionPane.showConfirmDialog(dialog, Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Cover_The_Current_File") + " ?", - Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (selVal == JOptionPane.YES_OPTION) { option = JOPTIONPANE_OK_OPTION; saveDictionary(); @@ -1031,6 +1041,14 @@ public class FILEChooserPane extends BasicPane { setPlaceListModel(new PlaceListModel()); } + private void setDesignateModel(String path) { + if (placesList == null) { + return; + } + setPlaceListModel(new DesignateRemotePlaceListModel(path)); + } + + private void setMultiPlaceListModel() { if (placesList == null) { return; @@ -1125,6 +1143,7 @@ public class FILEChooserPane extends BasicPane { private abstract class AbstractPlaceListModel extends AbstractListModel { + private static final long serialVersionUID = 8473695327688235386L; protected List filesOfSystem = new ArrayList(); protected void processSystemFile() { @@ -1157,7 +1176,8 @@ public class FILEChooserPane extends BasicPane { protected void setCD(final FILE lastDirectory) { for (int i = 0; i < this.getSize(); i++) { FILE file = this.getElementAt(i); - if (ComparatorUtils.equals(lastDirectory.prefix(), file.prefix())) { + //前缀相同不代表能用啊,比如说 repolets 和 resource ,都是 env下的,但就不该去显示resource下的文件呀 + if (ComparatorUtils.equals(lastDirectory.prefix(), file.prefix()) && lastDirectory.getPath() != null && lastDirectory.getPath().startsWith(file.getPath())) { setCurrentDirectory(lastDirectory); return; } @@ -1166,7 +1186,60 @@ public class FILEChooserPane extends BasicPane { } } + /** + * 一个简单的指定远程目录的 placelistmodel + */ + private class DesignateRemotePlaceListModel extends AbstractPlaceListModel { + private static final long serialVersionUID = -6340666958714469249L; + + private FileNodeFILE envFILE; + + public DesignateRemotePlaceListModel(String path) { + envFILE = new DesignateFileNodeFILE(new FileNode(path, true)) { + @Override + public String getName() { + return Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Env_Directory_Designate"); + } + }; + } + + @Override + public FILE getElementAt(int index) { + if (index < 1) { + return envFILE; + } + throw new IndexOutOfBoundsException(); + } + + @Override + public int getSize() { + return 1; + } + + @Override + protected void setCD(FILE lastDirectory) { + setCurrentDirectory(envFILE); + } + + /** + * 简单的重写了标签的FileNodeFILE + */ + private class DesignateFileNodeFILE extends FileNodeFILE { + + public DesignateFileNodeFILE(FileNode node) { + super(node); + } + + @Override + public Icon getIcon() { + return BaseUtils.readIcon("/com/fr/base/images/oem/logo.png"); + } + } + } + + private class PlaceListModel extends AbstractPlaceListModel { + private static final long serialVersionUID = 6138969918807381364L; private FileNodeFILE envFILE; private FileNodeFILE webReportFILE; @@ -1217,6 +1290,7 @@ public class FILEChooserPane extends BasicPane { private class MultiLocalEnvPlaceListModel extends AbstractPlaceListModel { + private static final long serialVersionUID = 6300018896958532154L; private List envFiles = new ArrayList(); private FileNodeFILE webReportFILE; diff --git a/designer-base/src/main/java/com/fr/file/FILEFactory.java b/designer-base/src/main/java/com/fr/file/FILEFactory.java index 3d48bab341..d558483784 100644 --- a/designer-base/src/main/java/com/fr/file/FILEFactory.java +++ b/designer-base/src/main/java/com/fr/file/FILEFactory.java @@ -1,6 +1,5 @@ package com.fr.file; -import com.fr.base.FRContext; import com.fr.design.file.NodeAuthProcessor; import com.fr.file.filetree.FileNode; import com.fr.workspace.WorkContext; @@ -10,6 +9,7 @@ public class FILEFactory { public static final String FILE_PREFIX = "file://"; public static final String ENV_PREFIX = "env://"; public static final String WEBREPORT_PREFIX = "webreport://"; + public static final String SEPARATOR = "/"; private FILEFactory() { } diff --git a/designer-base/src/main/java/com/fr/file/filter/ChooseFileFilter.java b/designer-base/src/main/java/com/fr/file/filter/ChooseFileFilter.java index 147e1946d4..0f6057d0ab 100644 --- a/designer-base/src/main/java/com/fr/file/filter/ChooseFileFilter.java +++ b/designer-base/src/main/java/com/fr/file/filter/ChooseFileFilter.java @@ -31,6 +31,15 @@ public class ChooseFileFilter extends FileFilter implements FILEFilter, java.io. this(extension, null); } + public ChooseFileFilter(boolean noRestrict) { + if (noRestrict) { + this.filters = null; + this.fullDescription = FileExtension.ALL.getExtension(); + } else { + this.filters = new ArrayList<>(); + } + } + public ChooseFileFilter(String extension, String description) { this(); if (extension != null) { @@ -314,4 +323,4 @@ public class ChooseFileFilter extends FileFilter implements FILEFilter, java.io. return (o instanceof ChooseFileFilter) && ComparatorUtils.equals(((ChooseFileFilter) o).getDescription(), getDescription()); } -} \ No newline at end of file +} diff --git a/designer-base/src/main/resources/com/fr/design/images/edit/advancedEditor.svg b/designer-base/src/main/resources/com/fr/design/images/edit/advancedEditor.svg new file mode 100644 index 0000000000..6ddc105cb9 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/edit/advancedEditor.svg @@ -0,0 +1,10 @@ + + + 高级编辑 + + + + + + + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/sort/asc.svg b/designer-base/src/main/resources/com/fr/design/images/sort/asc.svg deleted file mode 100644 index 67dd9e829e..0000000000 --- a/designer-base/src/main/resources/com/fr/design/images/sort/asc.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - 升序备份 - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/sort/des.svg b/designer-base/src/main/resources/com/fr/design/images/sort/des.svg deleted file mode 100644 index 2fcef077e6..0000000000 --- a/designer-base/src/main/resources/com/fr/design/images/sort/des.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - 降序 - - - - - - - - - - - - - - \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/sort/nosort.svg b/designer-base/src/main/resources/com/fr/design/images/sort/nosort.svg deleted file mode 100644 index ca04928fc8..0000000000 --- a/designer-base/src/main/resources/com/fr/design/images/sort/nosort.svg +++ /dev/null @@ -1,41 +0,0 @@ - - - 不排序 - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/javascript/jsapi/category.json b/designer-base/src/main/resources/com/fr/design/javascript/jsapi/category.json index ad17929765..ece3628ab5 100644 --- a/designer-base/src/main/resources/com/fr/design/javascript/jsapi/category.json +++ b/designer-base/src/main/resources/com/fr/design/javascript/jsapi/category.json @@ -41,7 +41,6 @@ }, "Fine-Design_JSAPI_Form": { "Fine-Design_JSAPI_Form_Component_Get": {}, - "Fine-Design_JSAPI_Form_Component_Universal": {}, "Fine-Design_JSAPI_Form_Component_Tab": {} } } \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/javascript/jsapi/images/connectFailed.svg b/designer-base/src/main/resources/com/fr/design/javascript/jsapi/images/connectFailed.svg new file mode 100644 index 0000000000..6b0dfbc665 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/javascript/jsapi/images/connectFailed.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/javascript/jsapi/jsapi.json b/designer-base/src/main/resources/com/fr/design/javascript/jsapi/jsapi.json index e268f70e18..dcad373927 100644 --- a/designer-base/src/main/resources/com/fr/design/javascript/jsapi/jsapi.json +++ b/designer-base/src/main/resources/com/fr/design/javascript/jsapi/jsapi.json @@ -29,5 +29,5 @@ "importExcel_Append", "importExcel_Cover", "stash", "clear"], "Fine-Design_JSAPI_Cpt_View_Preview_Report_Location":["centerReport"], "Fine-Design_JSAPI_Form_Component_Get":["getAllWidgets"], - "Fine-Design_JSAPI_Form_Component_Tab":["showCardByIndex", "showCardByIndex", "getShowIndex", "setTitleVisible"] + "Fine-Design_JSAPI_Form_Component_Tab":["showCardByIndex", "getShowIndex", "setTitleVisible"] } \ No newline at end of file diff --git a/designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java b/designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java new file mode 100644 index 0000000000..c7dd1de70a --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/mainframe/loghandler/DesignerLogHandlerTest.java @@ -0,0 +1,50 @@ +package com.fr.design.mainframe.loghandler; + +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * @author vito + * @version 10.0 + * Created by vito on 2022/1/25 + */ +public class DesignerLogHandlerTest { + + @Test + public void findTplLink() { + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)", "(公式定位测试/单sheet2(2).cpt:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1),出错公式(公式定位测试/单sheet2(2).cpt:0:A1),的飞机啊") + ); + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).frm:0:A1)", "(公式定位测试/单sheet2(2).frm:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).frm:0:A1),出错公式(公式定位测试/单sheet2(2).frm:0:A1),的飞机啊") + ); + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊") + ); + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式(计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊") + ); + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式)计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊") + ); + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机)啊") + ); + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机(啊") + ); + Assert.assertArrayEquals( + new String[]{"(公式定位测试/单sheet2(1).cpt:0:A1)"}, + DesignerLogHandler.findTplLink("错误代码:11300310 公式(0fdasf)计算错误:(公式定位测试/单sheet2(1).cpt:0:A1)的飞机啊") + ); + } +} \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChangeConfigPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChangeConfigPane.java index bbc923f4d8..a04acb83de 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChangeConfigPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChangeConfigPane.java @@ -10,7 +10,9 @@ import com.fr.chart.base.AttrChangeConfig; import com.fr.chart.base.AttrChangeType; import com.fr.chart.chartattr.Chart; import com.fr.chart.chartattr.ChartCollection; +import com.fr.chart.chartattr.SwitchTitle; import com.fr.design.beans.BasicBeanPane; +import com.fr.design.dialog.AttrScrollPane; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.formula.TinyFormulaPane; import com.fr.design.gui.ibutton.UIButtonGroup; @@ -22,6 +24,7 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPane; import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; import com.fr.van.chart.designer.TableLayout4VanChartHelper; import javax.swing.BorderFactory; @@ -77,11 +80,26 @@ public class ChangeConfigPane extends BasicBeanPane { private int selectedChart; // 设置面板里面选取的图表,不是真正切换的图表 public ChangeConfigPane(){ + init(); + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 15)); + this.add(createScrollPane(), BorderLayout.CENTER); + } + + private JPanel createScrollPane() { + return new AttrScrollPane() { + @Override + protected JPanel createContentPane() { + return contentPane; + } + }; + } + + private void init() { initButtonGroup(); configPane = createConfigPane(); contentPane = createContentPane(); contentPane.setBorder(BorderFactory.createEmptyBorder(CONSTANT_TEN, CONSTANT_THIRTY, CONSTANT_TEN, CONSTANT_THIRTY)); - this.add(contentPane, BorderLayout.CENTER); } private JPanel createContentPane() { @@ -172,19 +190,20 @@ public class ChangeConfigPane extends BasicBeanPane { chartTypesPane = new JPanel(); chartTypesPane.setLayout(new BoxLayout(chartTypesPane, BoxLayout.Y_AXIS)); + chartTypesPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); switchTitlePane.setLayout(new CardLayout()); - buttonContentPane.add(chartTypesPane, BorderLayout.NORTH); - buttonContentPane.add( - TableLayout4VanChartHelper.createGapTableLayoutPane( - Toolkit.i18nText("Fine-Design_Chart_Switch_Title_Label"), - switchTitlePane, - EDIT_AREA_WIDTH - ), - BorderLayout.CENTER + JPanel titleEditPane = TableLayout4VanChartHelper.createGapTableLayoutPane( + Toolkit.i18nText("Fine-Design_Chart_Switch_Title_Label"), + switchTitlePane, + EDIT_AREA_WIDTH ); + titleEditPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + + buttonContentPane.add(chartTypesPane, BorderLayout.NORTH); + buttonContentPane.add(titleEditPane, BorderLayout.CENTER); - UIExpandablePane expandablePane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Chart_Button_Content"), 20, buttonContentPane) { + UIExpandablePane expandablePane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Chart_Button_And_Rotation_Content"), 20, buttonContentPane) { protected void setcontentPanelontentPanelBorder() { } @@ -212,6 +231,7 @@ public class ChangeConfigPane extends BasicBeanPane { populateSwitchTitlePane(i, collection); } + showSwitchTitleCard(collection.getChartName(select)); chartTypesPane.revalidate(); switchTitlePane.revalidate(); selectedChart = select; @@ -219,18 +239,16 @@ public class ChangeConfigPane extends BasicBeanPane { private void populateSwitchTitlePane(int chartIndex, ChartCollection collection) { Chart chart = collection.getChart(chartIndex, Chart.class); - Object switchTitle = chart.getSwitchTitle(); - String result; - if (switchTitle != null) { - if (switchTitle instanceof BaseFormula) { - result = ((BaseFormula) switchTitle).getContent(); + SwitchTitle switchTitle = chart.getSwitchTitle(); + Object content = switchTitle.getContent(); + String result = StringUtils.EMPTY; + if (content != null) { + if (content instanceof BaseFormula) { + result = ((BaseFormula) content).getContent(); } else { - result = Utils.objectToString(switchTitle); + result = Utils.objectToString(content); } - } else { - result = collection.getChartName(chartIndex); } - TinyFormulaPane title = new TinyFormulaPane(); title.populateBean(result); switchTitles.add(title); @@ -329,7 +347,7 @@ public class ChangeConfigPane extends BasicBeanPane { } else { titleObj = titleString; } - collection.getChart(i, Chart.class).setSwitchTitle(titleObj); + collection.getChart(i, Chart.class).setSwitchTitle(new SwitchTitle(titleObj)); } } @@ -357,8 +375,7 @@ public class ChangeConfigPane extends BasicBeanPane { @Override public void mouseClicked(MouseEvent e) { resetChangeChartButtons(); - CardLayout cardLayout = (CardLayout) switchTitlePane.getLayout(); - cardLayout.show(switchTitlePane, collection.getChartName(buttonIndex)); + showSwitchTitleCard(collection.getChartName(buttonIndex)); ChangeChartButton.this.setSelected(true); selectedChart = buttonIndex; } @@ -375,4 +392,9 @@ public class ChangeConfigPane extends BasicBeanPane { changeChartButton.setSelected(false); } } + + private void showSwitchTitleCard(String chartName) { + CardLayout cardLayout = (CardLayout) switchTitlePane.getLayout(); + cardLayout.show(switchTitlePane, chartName); + } } diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/report/CategoryPlotMoreCateReportDataContentPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/report/CategoryPlotMoreCateReportDataContentPane.java index d4e1f64e77..4b8d5aac8f 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/report/CategoryPlotMoreCateReportDataContentPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/report/CategoryPlotMoreCateReportDataContentPane.java @@ -19,14 +19,14 @@ import com.fr.van.chart.designer.TableLayout4VanChartHelper; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.JPanel; -import java.util.ArrayList; -import java.util.List; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; /** @@ -40,7 +40,7 @@ public class CategoryPlotMoreCateReportDataContentPane extends CategoryPlotRepor private JPanel boxPane; private UIButton addButton; - private ArrayList formualList = new ArrayList(); + private List formualList = new ArrayList(); private UIObserverListener uiobListener = null; public List getFormualList() { @@ -190,10 +190,9 @@ public class CategoryPlotMoreCateReportDataContentPane extends CategoryPlotRepor Plot plot = collection.getSelectedChart().getPlot(); if (definition instanceof NormalReportDataDefinition) { NormalReportDataDefinition reportDefinition = (NormalReportDataDefinition) definition; - reportDefinition.clearMoreCate(); updateMoreCate(reportDefinition, plot); - + collection.updateAxisCategoryStyles(); } } diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/CategoryPlotMoreCateTableDataContentPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/CategoryPlotMoreCateTableDataContentPane.java index 3bf0225ef2..87c47b18b7 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/CategoryPlotMoreCateTableDataContentPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/data/table/CategoryPlotMoreCateTableDataContentPane.java @@ -15,9 +15,13 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.mainframe.chart.gui.ChartDataPane; import com.fr.design.utils.gui.GUICoreUtils; - -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; @@ -39,7 +43,7 @@ public class CategoryPlotMoreCateTableDataContentPane extends CategoryPlotTableD private JPanel boxPane; - private ArrayList boxList = new ArrayList(); + private List boxList = new ArrayList(); private UIButton addButton; private UIObserverListener uiobListener = null; @@ -242,6 +246,7 @@ public class CategoryPlotMoreCateTableDataContentPane extends CategoryPlotTableD normal.clearMoreCate(); updateMoreCate(normal, plot); } + collection.updateAxisCategoryStyles(); } protected void updateMoreCate(NormalTableDataDefinition normal, Plot plot) { @@ -252,5 +257,4 @@ public class CategoryPlotMoreCateTableDataContentPane extends CategoryPlotTableD } } } - } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisPane.java b/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisPane.java index 35b6d63e70..75a3c0f2ca 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisPane.java @@ -54,7 +54,7 @@ public class VanChartCustomAxisPane extends BasicScrollPane { } if(axisPane != null) { - axisPane.populateBean((VanChartCustomPlot) chart.getPlot()); + axisPane.populateBean((VanChart) chart); } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisTabPane.java b/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisTabPane.java index 93ac30c52e..5f9927c6b1 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisTabPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/custom/style/VanChartCustomAxisTabPane.java @@ -87,11 +87,16 @@ public class VanChartCustomAxisTabPane extends VanChartCustomPlotTabPane customPlotList = plot.getCustomPlotList(); ArrayList plotOrder = plot.getDiffAxisOrder(); @@ -100,12 +105,13 @@ public class VanChartCustomAxisTabPane extends VanChartCustomPlotTabPane switchButton; + private ColorSelectBoxWithOutTransparent colorSelect; + private UINumberDragPaneWithPercent opacity; + + private JPanel centerPane; + + public VanChartGanttTimeLinePane() { + this.setLayout(new BorderLayout()); + this.add(createSwitchButtonPane(), BorderLayout.NORTH); + this.add(createCenterPane(), BorderLayout.CENTER); + } + + private JPanel createSwitchButtonPane() { + double[] columnSize = {TableLayout.PREFERRED, TableLayout.FILL}; + double[] rowSize = {TableLayout.PREFERRED, TableLayout.PREFERRED}; + String[] array = new String[]{Toolkit.i18nText("Fine-Design_Chart_Guide_Line_Not_Show"), Toolkit.i18nText("Fine-Design_Chart_Guide_Line_Show")}; + switchButton = new UIButtonGroup<>(array); + switchButton.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + setCenterPaneVisibility(); + } + }); + UILabel text = new UILabel(Toolkit.i18nText("Fine-Design_Chart_Guide_Line_Current_Line"), SwingConstants.LEFT); + return TableLayout4VanChartHelper.createGapTableLayoutPane(new Component[][] { + new Component[]{null, null}, + new Component[] {text, switchButton} + }, rowSize, columnSize); + } + + private JPanel createCenterPane() { + double[] columnSize = {TableLayout.FILL, TableLayout4VanChartHelper.EDIT_AREA_WIDTH}; + double[] rowSize = {TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED}; + + colorSelect = new ColorSelectBoxWithOutTransparent(100); + opacity = new UINumberDragPaneWithPercent(0, 100); + + centerPane = TableLayout4VanChartHelper.createGapTableLayoutPane(new Component[][] { + new Component[]{null, null}, + new Component[] {new UILabel(Toolkit.i18nText("Fine-Design_Chart_Color")), colorSelect}, + new Component[] {new UILabel(Toolkit.i18nText("Fine-Design_Report_Alpha")), opacity} + }, rowSize, columnSize); + + centerPane.setVisible(false); + + return centerPane; + } + + public void populateBean(Plot plot) { + if (plot instanceof VanChartGanttPlot) { + VanChartGanttPlot ganttPlot = (VanChartGanttPlot) plot; + setShowTimeLine(ganttPlot.isShowTimeLine()); + setTimeLineColor(ganttPlot.getTimeLineColor()); + setTimeLineOpacity(ganttPlot.getTimeLineOpacity()); + + centerPane.setVisible(ganttPlot.isShowTimeLine()); + } + } + + public void updateBean(Plot plot) { + if (plot instanceof VanChartGanttPlot) { + VanChartGanttPlot ganttPlot = (VanChartGanttPlot) plot; + ganttPlot.setShowTimeLine(isShowTimeLine()); + ganttPlot.setTimeLineColor(getTimeLineColor()); + ganttPlot.setTimeLineOpacity(getTimeLineOpacity()); + } + } + + private void setCenterPaneVisibility() { + centerPane.setVisible(switchButton.getSelectedIndex() == 1); + } + + public boolean isShowTimeLine() { + return switchButton.getSelectedIndex() == 1; + } + + public void setShowTimeLine(boolean showTimeLine) { + switchButton.setSelectedIndex(showTimeLine ? 1 : 0); + } + + public Color getTimeLineColor() { + return colorSelect.getSelectObject(); + } + + public void setTimeLineColor(Color timeLineColor) { + colorSelect.setSelectObject(timeLineColor); + } + + public double getTimeLineOpacity() { + return opacity.updateBean(); + } + + public void setTimeLineOpacity(double timeLineOpacity) { + opacity.populateBean(timeLineOpacity); + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartGuideLinesPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartGuideLinesPane.java deleted file mode 100644 index 4b7b140cdf..0000000000 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/component/VanChartGuideLinesPane.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.fr.van.chart.designer.component; - -public class VanChartGuideLinesPane { -} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisPane.java index e8379e78b4..ef532d12ba 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisPane.java @@ -1,5 +1,6 @@ package com.fr.van.chart.designer.style.axis; +import com.fr.chart.chartattr.Chart; import com.fr.chart.chartattr.Plot; import com.fr.chart.chartglyph.ConditionAttr; import com.fr.chart.chartglyph.ConditionCollection; @@ -41,6 +42,7 @@ public class VanChartAxisPane extends BasicBeanPane { protected VanChartAxisPlot editingPlot; protected VanChartStylePane parent; + private Chart chart; public VanChartAxisPane(VanChartAxisPlot plot, VanChartStylePane parent){ this.editingPlot = plot; @@ -188,6 +190,7 @@ public class VanChartAxisPane extends BasicBeanPane { if(chart == null){ return; } + this.chart = chart; Plot plot = chart.getPlot(); populateBean(plot); @@ -208,10 +211,12 @@ public class VanChartAxisPane extends BasicBeanPane { } for(VanChartAxis axis : editingPlot.getXAxisList()){ + axis.setChart(chart); VanChartXYAxisPaneInterface axisPane = xAxisPaneMap.get(axis.getAxisName()); axisPane.populate(axis); } for(VanChartAxis axis : editingPlot.getYAxisList()){ + axis.setChart(chart); VanChartXYAxisPaneInterface axisPane = yAxisPaneMap.get(axis.getAxisName()); axisPane.populate(axis); } @@ -237,6 +242,7 @@ public class VanChartAxisPane extends BasicBeanPane { if(chart == null){ return; } + this.chart = chart; Plot plot = chart.getPlot(); @@ -281,4 +287,8 @@ public class VanChartAxisPane extends BasicBeanPane { public VanChart updateBean() { return null; } + + public void setChart(Chart chart) { + this.chart = chart; + } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisPaneHelper.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisPaneHelper.java new file mode 100644 index 0000000000..770043af9c --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisPaneHelper.java @@ -0,0 +1,30 @@ +package com.fr.van.chart.designer.style.axis; + +import com.fr.design.layout.TableLayout; +import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPane; +import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPaneWithThemeStyle; +import com.fr.design.mainframe.chart.mode.ChartEditContext; +import com.fr.van.chart.designer.TableLayout4VanChartHelper; + +import javax.swing.JPanel; + +public class VanChartAxisPaneHelper { + public static ChartTextAttrPane createAxisTextAttrPane() { + return ChartEditContext.supportTheme() ? new ChartTextAttrPaneWithThemeStyle() { + protected double getEdithAreaWidth() { + return TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; + } + } : new ChartTextAttrPane() { + @Override + protected JPanel getContentPane(JPanel buttonPane) { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double e = TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; + double[] columnSize = {f, e}; + double[] rowSize = {p, p, p}; + + return TableLayout4VanChartHelper.createGapTableLayoutPane(getComponents(buttonPane), rowSize, columnSize); + } + }; + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisStyleSettingPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisStyleSettingPane.java new file mode 100644 index 0000000000..5deb498319 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartAxisStyleSettingPane.java @@ -0,0 +1,166 @@ +package com.fr.van.chart.designer.style.axis; + +import com.fr.base.BaseFormula; +import com.fr.chart.base.TextAttr; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.gui.frpane.UINumberDragPane; +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPane; +import com.fr.design.utils.gui.UIComponentUtils; +import com.fr.design.widget.FRWidgetFactory; +import com.fr.plugin.chart.attr.axis.VanChartAxisLabelStyle; +import com.fr.van.chart.designer.TableLayout4VanChartHelper; +import com.fr.van.chart.designer.style.axis.component.AxisLabelDisplayComboBox; + +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class VanChartAxisStyleSettingPane extends BasicBeanPane { + private static final double ROTATION_MAX = 90.0; + + private AxisLabelDisplayComboBox labelDisplayComboBox; + private JPanel labelDisplayPane; + private ChartTextAttrPane labelTextAttrPane; + private UINumberDragPane labelTextRotation; + private UIButtonGroup labelGapStyle; + private UITextField labelGapValue; + private JPanel labelGapPane; + private JPanel labelGapValuePane; + private JPanel contentPane; + + private boolean showLabelDisplayPane = true; + + public VanChartAxisStyleSettingPane(boolean showLabelDisplayPane, ChartTextAttrPane textAttrPane) { + this.showLabelDisplayPane = showLabelDisplayPane; + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double s = TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; + double[] column = {f, s}; + double[] row = {p, p, p}; + + labelDisplayComboBox = new AxisLabelDisplayComboBox(); + labelDisplayPane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Axis_Label_Show"), labelDisplayComboBox, TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH); + labelDisplayPane.setVisible(showLabelDisplayPane); + + labelTextAttrPane = textAttrPane; + labelTextRotation = new UINumberDragPane(-ROTATION_MAX, ROTATION_MAX); + + labelGapStyle = new UIButtonGroup<>(new String[]{Toolkit.i18nText("Fine-Design_Chart_Automatic"), Toolkit.i18nText("Fine-Design_Chart_Fixed")}); + labelGapValue = new UITextField(); + labelGapPane = createLabelGapPane(row, column); + + this.setLayout(new BorderLayout()); + contentPane = new JPanel(new BorderLayout()); + contentPane.add(labelDisplayPane, BorderLayout.NORTH); + contentPane.add(labelTextAttrPane, BorderLayout.CENTER); + contentPane.add(labelGapPane, BorderLayout.SOUTH); + this.add(contentPane, BorderLayout.NORTH); + initListner(); + } + + public VanChartAxisStyleSettingPane(ChartTextAttrPane textAttrPane) { + this(true, textAttrPane); + } + + @Override + public Dimension getPreferredSize() { + Dimension defaultSize = super.getPreferredSize(); + return new Dimension(defaultSize.width, contentPane.getPreferredSize().height); + } + + private void initListner() { + labelDisplayComboBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + checkLabelGapPane(); + } + }); + + labelGapStyle.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + checkLabelGapValuePane(); + } + }); + } + + private void checkLabelGapPane() { + if (labelGapPane != null) { + boolean visible = true; + + if (showLabelDisplayPane && labelDisplayPane != null && labelDisplayComboBox != null) { + visible = labelDisplayComboBox.getSelectedIndex() == 0; + } + + labelGapPane.setVisible(visible); + } + } + + private void checkLabelGapValuePane() { + if (labelGapValuePane != null && labelGapStyle != null) { + labelGapValuePane.setVisible(labelGapStyle.getSelectedIndex() == 1); + } + } + + @Override + public void populateBean(VanChartAxisLabelStyle style) { + labelDisplayComboBox.populateBean(style.getLabelDisplay()); + labelTextAttrPane.populate(style.getTextAttr()); + labelTextRotation.populateBean((double) style.getTextAttr().getRotation()); + labelGapStyle.setSelectedIndex(style.isAutoLabelGap() ? 0 : 1); + labelGapValue.setText(style.getLabelIntervalNumber().getContent()); + + checkLabelGapPane(); + checkLabelGapValuePane(); + } + + @Override + public VanChartAxisLabelStyle updateBean() { + VanChartAxisLabelStyle style = new VanChartAxisLabelStyle(); + style.setLabelDisplay(labelDisplayComboBox.updateBean()); + TextAttr textAttr = style.getTextAttr(); + labelTextAttrPane.update(textAttr); + textAttr.setRotation(labelTextRotation.updateBean().intValue()); + style.setTextAttr(textAttr); + style.setAutoLabelGap(labelGapStyle.getSelectedIndex() == 0); + if (style.isAutoLabelGap()) { + style.setLabelIntervalNumber(BaseFormula.createFormulaBuilder().build("0")); + } else { + style.setLabelIntervalNumber(BaseFormula.createFormulaBuilder().build(labelGapValue.getText())); + } + return style; + } + + @Override + protected String title4PopupWindow() { + return null; + } + + private JPanel createLabelGapPane(double[] row, double[] col) { + Component[][] gapComponents = new Component[][]{ + new Component[]{null, null}, + new Component[]{ + FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Chart_TextRotation")), + UIComponentUtils.wrapWithBorderLayoutPane(labelTextRotation) + }, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Label_Interval")), labelGapStyle} + }; + + JPanel gapDetailPane = TableLayout4VanChartHelper.createGapTableLayoutPane(gapComponents, row, col); + labelGapValuePane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText(""), labelGapValue, TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH); + + JPanel panel = new JPanel(new BorderLayout()); + panel.add(gapDetailPane, BorderLayout.CENTER); + panel.add(labelGapValuePane, BorderLayout.SOUTH); + + return panel; + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartBaseAxisPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartBaseAxisPane.java index aff9d64c30..29bbf6a9bb 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartBaseAxisPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartBaseAxisPane.java @@ -3,7 +3,9 @@ package com.fr.van.chart.designer.style.axis; import com.fr.base.BaseFormula; import com.fr.base.BaseUtils; import com.fr.base.Utils; +import com.fr.base.chart.chartdata.TopDefinitionProvider; import com.fr.chart.base.TextAttr; +import com.fr.chart.chartattr.Chart; import com.fr.chart.chartattr.Title; import com.fr.design.beans.FurtherBasicBeanPane; import com.fr.design.formula.TinyFormulaPane; @@ -13,30 +15,27 @@ import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.gui.icombobox.LineComboBox; import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.style.FormatPane; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.PaneTitleConstants; import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPane; -import com.fr.design.mainframe.chart.gui.style.ChartTextAttrPaneWithThemeStyle; import com.fr.design.mainframe.chart.gui.style.ColorSelectBoxWithThemeStyle; -import com.fr.design.mainframe.chart.mode.ChartEditContext; import com.fr.design.utils.gui.UIComponentUtils; import com.fr.design.widget.FRWidgetFactory; import com.fr.plugin.chart.attr.axis.VanChartAxis; +import com.fr.plugin.chart.attr.axis.VanChartAxisLabelStyle; import com.fr.plugin.chart.base.OverlapHandleType; import com.fr.plugin.chart.base.VanChartConstants; import com.fr.plugin.chart.type.AxisTickLineType; import com.fr.stable.Constants; import com.fr.stable.CoreConstants; import com.fr.stable.StableUtils; -import com.fr.stable.StringUtils; import com.fr.van.chart.designer.TableLayout4VanChartHelper; import com.fr.van.chart.designer.component.VanChartHtmlLabelPane; import com.fr.van.chart.designer.style.VanChartStylePane; -import com.fr.van.chart.designer.style.axis.component.AxisLabelDisplayComboBox; +import com.fr.van.chart.designer.style.axis.component.VanChartCategoryStylePaneWithCheckBox; import javax.swing.BorderFactory; import javax.swing.Icon; @@ -47,16 +46,21 @@ import javax.swing.event.ChangeListener; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Component; +import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; /** * 坐标轴的基础配置项。分类,时间,值等公共的部分。 */ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { - private static final long serialVersionUID = -5717246802333308973L; private static final double ROTATION_MAX = 90.0; + private static final String WHOLE_DISPLAY = "wholeDisplay"; // 整体显示 + private static final String LAYER_DISPLAY = "layerDisplay"; // 分层显示 + protected UIButtonGroup showTitle; protected TinyFormulaPane titleContent; protected UIButtonGroup titleAlignPane; @@ -66,24 +70,19 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { protected JPanel titlePane; protected UIButtonGroup showLabel; - protected ChartTextAttrPane labelTextAttrPane; - protected UINumberDragPane labelTextRotation; - - private AxisLabelDisplayComboBox labelDisplayComboBox; - - //轴标签缩略间隔显示 恢复用注释。下面6行删除。 - protected UITextField labelGapValue; + protected UIButtonGroup showLogic; private UIButtonGroup overlapHandleTypeGroup; - protected UIButtonGroup labelGapStyle; //轴标签缩略间隔显示 恢复用注释。取消注释。 //protected UISpinner labelGapValue; - protected JPanel labelPanel; - private JPanel labelGapPane; - private JPanel labelGapStylePane; - private JPanel labelGapValuePane; - private JPanel labelDisplayPane; + protected JPanel labelContentPane; + private VanChartAxisStyleSettingPane labelPane; + private JPanel showLogicPane; + private JPanel labelStylePane; + private JPanel categoryStylePane; + private VanChartAxisStyleSettingPane wholeDisplayLabelPanel; + private List categoryStyles = new ArrayList<>(); protected LineComboBox axisLineStyle; @@ -107,6 +106,8 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { protected JPanel centerPane; private VanChartHtmlLabelPane htmlLabelPane; + private VanChartStylePane parent; + public VanChartBaseAxisPane() { this(true); } @@ -117,6 +118,7 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { } public void setParentPane(VanChartStylePane parent) { + this.parent = parent; htmlLabelPane.setParent(parent); } @@ -214,189 +216,102 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { protected JPanel createLabelPane(double[] row, double[] col) { initLabelComponents(); - labelGapPane = createLabelGapPane(row, col); - labelPanel = createLabelDetailPanel(); + labelPane = new VanChartAxisStyleSettingPane(showLabelDisplay(), getChartTextAttrPane()); + wholeDisplayLabelPanel = new VanChartAxisStyleSettingPane(showLabelDisplay(), getChartTextAttrPane()); + wholeDisplayLabelPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); addComponentsListener(); JPanel showLabelPane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Axis_Label"), showLabel); + JPanel labelContentPane = createLabelContentPane(); JPanel labelPane = new JPanel(new BorderLayout()); labelPane.add(showLabelPane, BorderLayout.NORTH); - labelPane.add(labelPanel, BorderLayout.CENTER); + labelPane.add(labelContentPane, BorderLayout.CENTER); return TableLayout4VanChartHelper.createExpandablePaneWithTitle(PaneTitleConstants.CHART_STYLE_LABEL_TITLE, labelPane); } private void initLabelComponents() { showLabel = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Use_Show"), Toolkit.i18nText("Fine-Design_Chart_Hidden")}); - - labelDisplayComboBox = new AxisLabelDisplayComboBox(); - labelDisplayPane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Axis_Label_Show"), labelDisplayComboBox, TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH); - labelDisplayPane.setVisible(showLabelDisplay()); - - labelTextAttrPane = getChartTextAttrPane(); - labelTextRotation = new UINumberDragPane(-ROTATION_MAX, ROTATION_MAX); - labelGapStyle = new UIButtonGroup<>(new String[]{Toolkit.i18nText("Fine-Design_Chart_Automatic"), Toolkit.i18nText("Fine-Design_Chart_Fixed")}); - labelGapValue = new UITextField(); - } - - private JPanel createLabelGapPane(double[] row, double[] col) { - Component[][] gapComponents = new Component[][]{ - new Component[]{null, null}, - new Component[]{ - FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Chart_TextRotation")), - UIComponentUtils.wrapWithBorderLayoutPane(labelTextRotation) - }, - new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Label_Interval")), labelGapStyle} - }; - - JPanel gapDetailPane = TableLayout4VanChartHelper.createGapTableLayoutPane(gapComponents, row, col); - labelGapValuePane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText(""), labelGapValue, TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH); - - JPanel panel = new JPanel(new BorderLayout()); - panel.add(gapDetailPane, BorderLayout.CENTER); - panel.add(labelGapValuePane, BorderLayout.SOUTH); - - return panel; - } - - private JPanel createLabelDetailPanel() { - JPanel panel = new JPanel(new BorderLayout()); - panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); - - panel.add(labelDisplayPane, BorderLayout.NORTH); - panel.add(labelTextAttrPane, BorderLayout.CENTER); - panel.add(labelGapPane, BorderLayout.SOUTH); - - return panel; + showLogic = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Axis_Style_Whole_Display"), Toolkit.i18nText("Fine-Design_Chart_Axis_Style_Layer_Display")}); + initButtonGroupListener(); } - private void addComponentsListener() { - // 显示/隐藏 - showLabel.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - checkLabelPane(); - } - }); - - // 间隔/缩略/换行 - labelDisplayComboBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - checkLabelGapPane(); - } - }); - - // 自动/固定 - labelGapStyle.addActionListener(new ActionListener() { + private void initButtonGroupListener() { + showLogic.addChangeListener(new ChangeListener() { @Override - public void actionPerformed(ActionEvent e) { - checkLabelGapValuePane(); + public void stateChanged(ChangeEvent e) { + showLabelStyleCard(); } }); } -// protected JPanel createLabelPane(double[] row, double[] col){ -// double p = TableLayout.PREFERRED; -// showLabel = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Use_Show"), Toolkit.i18nText("Fine-Design_Chart_Hidden")}); -// labelTextAttrPane = getChartTextAttrPane(); -// -// JPanel rotationPane = createLabelRotationPane(col); -// JPanel overlapPane = createLabelOverlapPane(); -// -// -// Component[][] components = new Component[][]{ -// new Component[]{labelTextAttrPane, null}, -// new Component[]{rotationPane, null}, -// new Component[]{overlapPane, null}, -// }; -// -// JPanel showLabelPane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Axis_Label"),showLabel); -// labelPanel = TableLayout4VanChartHelper.createGapTableLayoutPane(components, new double[]{p, p, p}, col); -// labelPanel.setBorder(BorderFactory.createEmptyBorder(0,10,0,0)); -// showLabel.addActionListener(new ActionListener() { -// @Override -// public void actionPerformed(ActionEvent e) { -// checkLabelPane(); -// } -// }); -// JPanel jPanel = new JPanel(new BorderLayout()); -// jPanel.add(showLabelPane, BorderLayout.NORTH); -// jPanel.add(labelPanel, BorderLayout.CENTER); -// return TableLayout4VanChartHelper.createExpandablePaneWithTitle(PaneTitleConstants.CHART_STYLE_LABEL_TITLE, jPanel); -// } - - private JPanel createLabelRotationPane(double[] col) { - labelTextRotation = new UINumberDragPane(-ROTATION_MAX, ROTATION_MAX); - - Component[][] gapComponents = new Component[][]{ - new Component[]{ - FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Chart_TextRotation")), - UIComponentUtils.wrapWithBorderLayoutPane(labelTextRotation) - } - }; - return TableLayout4VanChartHelper.createGapTableLayoutPane(gapComponents, new double[]{TableLayout.PREFERRED}, col); + private void showLabelStyleCard() { + CardLayout layout = (CardLayout) labelStylePane.getLayout(); + if (showLogic.getSelectedIndex() == 0) { + layout.show(labelStylePane, WHOLE_DISPLAY); + } else { + layout.show(labelStylePane, LAYER_DISPLAY); + } + labelStylePane.revalidate(); } - private JPanel createLabelOverlapPane() { - - labelGapStyle = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Automatic"), Toolkit.i18nText("Fine-Design_Chart_Fixed")}); - labelGapStylePane = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Label_Interval"), labelGapStyle, TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH); - - //轴标签缩略间隔显示 恢复用注释。取消注释。 - //labelGapValue = new UISpinner(0, Integer.MAX_VALUE, 1, 1); - labelGapValuePane = TableLayout4VanChartHelper.createGapTableLayoutPane(StringUtils.EMPTY, labelGapValue, TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH); - - JPanel panel = new JPanel(new BorderLayout(0, 0)); - addOverlapGroupButton(panel); - panel.add(labelGapStylePane, BorderLayout.CENTER); - panel.add(labelGapValuePane, BorderLayout.SOUTH); - - labelGapStyle.addActionListener(new ActionListener() { + /** + * 创建显示逻辑以及其下面面板 + * + * @return + */ + private JPanel createLabelContentPane() { + labelContentPane = new JPanel(new BorderLayout()); + showLogicPane = new JPanel(new BorderLayout()); + labelStylePane = new JPanel(new CardLayout()) { @Override - public void actionPerformed(ActionEvent e) { - checkLabelGapValuePane(); + public Dimension getPreferredSize() { + switch (showLogic.getSelectedIndex()) { + case 0: + return wholeDisplayLabelPanel.getPreferredSize(); + case 1: + return categoryStylePane.getPreferredSize(); + case -1: + default: + return super.getPreferredSize(); + } } - }); - - return panel; + }; + labelStylePane.add(wholeDisplayLabelPanel, WHOLE_DISPLAY); + labelStylePane.add(createCategoryStylePane(), LAYER_DISPLAY); + showLogicPane.add(TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Axis_Label_Show_Logic"), showLogic), BorderLayout.NORTH); + showLogicPane.add(labelStylePane, BorderLayout.CENTER); + showLogicPane.setVisible(false); + labelContentPane.add(labelPane, BorderLayout.NORTH); + labelContentPane.add(showLogicPane, BorderLayout.CENTER); + return labelContentPane; } - protected void addOverlapGroupButton(JPanel panel) { - overlapHandleTypeGroup = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Label_OverlapAbbreviate"), Toolkit.i18nText("Fine-Design_Chart_Label_OverlapInterval")}, - new OverlapHandleType[]{OverlapHandleType.ABBREVIATE, OverlapHandleType.INTERVAL}); - JPanel north = TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Label_WhenOverlap"), overlapHandleTypeGroup, TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH); - - panel.add(north, BorderLayout.NORTH); + /** + * 创建多分类轴标签设置面板 + * + * @return + */ + private JPanel createCategoryStylePane() { + categoryStylePane = new JPanel(new BorderLayout()); + categoryStylePane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + return categoryStylePane; + } - overlapHandleTypeGroup.addChangeListener(new ChangeListener() { + private void addComponentsListener() { + // 显示/隐藏 + showLabel.addActionListener(new ActionListener() { @Override - public void stateChanged(ChangeEvent e) { - checkLabelGapAndStylePane(); + public void actionPerformed(ActionEvent e) { + checkLabelPane(); } }); - } protected ChartTextAttrPane getChartTextAttrPane() { - return ChartEditContext.supportTheme() ? new ChartTextAttrPaneWithThemeStyle() { - protected double getEdithAreaWidth() { - return TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; - } - } : new ChartTextAttrPane() { - @Override - protected JPanel getContentPane(JPanel buttonPane) { - double p = TableLayout.PREFERRED; - double f = TableLayout.FILL; - double e = TableLayout4VanChartHelper.SECOND_EDIT_AREA_WIDTH; - double[] columnSize = {f, e}; - double[] rowSize = {p, p, p}; - - return TableLayout4VanChartHelper.createGapTableLayoutPane(getComponents(buttonPane), rowSize, columnSize); - } - }; + return VanChartAxisPaneHelper.createAxisTextAttrPane(); } protected JPanel createLineStylePane(double[] row, double[] col) { @@ -537,7 +452,6 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { protected void checkAllUse() { checkCardPane(); checkLabelPane(); - checkLabelGapPane(); checkTitlePane(); //区域显示策略 恢复用注释。删除下面一行。 checkMaxProPortionUse(); @@ -570,14 +484,8 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { protected void checkLabelPane() { if (showLabel != null) { boolean enabled = showLabel.getSelectedIndex() == 0; - if (labelPanel != null) { - labelPanel.setVisible(enabled); - } - if (enabled) { - //轴标签缩略间隔显示 恢复用注释。下面1行删除。 - checkLabelGapValuePane(); - //轴标签缩略间隔显示 恢复用注释。取消注释。 - //checkLabelGapAndStylePane(); + if (labelContentPane != null) { + labelContentPane.setVisible(enabled); } } } @@ -588,39 +496,6 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { } } - private void checkLabelGapAndStylePane() { - if (overlapHandleTypeGroup != null && labelGapStylePane != null) { - boolean visible = overlapHandleTypeGroup.getSelectedItem() == OverlapHandleType.INTERVAL; - - labelGapStylePane.setVisible(visible); - } - checkLabelGapValuePane(); - } - - protected void checkLabelGapPane() { - if (labelGapPane != null) { - boolean visible = true; - - if (showLabelDisplay() && labelDisplayPane != null && labelDisplayComboBox != null) { - visible = labelDisplayComboBox.getSelectedIndex() == 0; - } - - labelGapPane.setVisible(visible); - } - } - - protected void checkLabelGapValuePane() { - if (labelGapValuePane != null && labelGapStyle != null) { - boolean visible = labelGapStyle.getSelectedIndex() == 1; - //轴标签缩略间隔显示 恢复用注释。取消注释。 -// if (overlapHandleTypeGroup != null) { -// visible = visible && overlapHandleTypeGroup.getSelectedItem() == OverlapHandleType.INTERVAL; -// } - labelGapValuePane.setVisible(visible); - } - } - - /** * 是否是指定类型 * @@ -694,33 +569,138 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { } //标签 - private void populateLabel(VanChartAxis axis) { + protected void populateLabel(VanChartAxis axis) { if (showLabel != null) { showLabel.setSelectedIndex(axis.isShowAxisLabel() ? 0 : 1); } - TextAttr labelTextAttr = axis.getTextAttr(); - if (labelTextAttrPane != null) { - labelTextAttrPane.populate(labelTextAttr); + + labelPane.populateBean(getAxisLabelStyle(axis)); + populateShowLogicPane(axis); + switchLabelPane(axis); + labelContentPane.validate(); + } + + /** + * 切换显示是单分类样式设置面板还是多分类样式设置面板 + */ + private void switchLabelPane(VanChartAxis axis) { + labelPane.setVisible(!axis.isMultiCategory()); + showLogicPane.setVisible(axis.isMultiCategory()); + } + + private void populateShowLogicPane(VanChartAxis axis) { + if (showLogic != null) { + showLogic.setSelectedIndex(axis.getLabelDisplayMode()); } - if (labelTextRotation != null) { - labelTextRotation.populateBean((double) labelTextAttr.getRotation()); + populateWholeDisplayPane(axis); + populateLayerDisplayPane(axis); + showLabelStyleCard(); + labelStylePane.revalidate(); + } + + /** + * populate整体显示那个card面板 + */ + private void populateWholeDisplayPane(VanChartAxis axis) { + wholeDisplayLabelPanel.populateBean(getAxisLabelStyle(axis)); + } + + private VanChartAxisLabelStyle getAxisLabelStyle(VanChartAxis axis) { + VanChartAxisLabelStyle style = new VanChartAxisLabelStyle(); + style.setLabelDisplay(axis.getLabelDisplay()); + style.setTextAttr(axis.getTextAttr()); + style.setAutoLabelGap(axis.isAutoLabelGap()); + style.setLabelIntervalNumber(axis.getLabelNumber()); + return style; + } + + /** + * populate分层显示那个card面板 + * + * @param axis + */ + private void populateLayerDisplayPane(VanChartAxis axis) { + Chart chart = axis.getChart(); + if (chart == null) { + return; } - //轴标签缩略间隔显示 恢复用注释。取消注释。 -// if (overlapHandleTypeGroup != null) { -// overlapHandleTypeGroup.setSelectedItem(axis.getOverlapHandleType()); -// } - if (labelDisplayComboBox != null) { - labelDisplayComboBox.populateBean(axis.getLabelDisplay()); + categoryStylePane.removeAll(); + categoryStyles.clear(); + populateCateLabelStyle(axis); + + categoryStylePane.revalidate(); + } + + + /** + * populate分类标签 + * + * @param axis + */ + private void populateCateLabelStyle(VanChartAxis axis) { + Chart chart = axis.getChart(); + int size; + TopDefinitionProvider definition = chart.getFilterDefinition(); + size = definition == null ? 1 : definition.getMoreCateSize() + 1; + + for (int i = 0; i < size; i++) { + populateCategoryStyles(axis, i); + } + } + + private void populateCategoryStyles(VanChartAxis axis, int index) { + VanChartCategoryStylePaneWithCheckBox pane = new VanChartCategoryStylePaneWithCheckBox(parent, this, Toolkit.i18nText("Fine-Design_Chart_Style_Category") + (index + 1)); + VanChartAxisLabelStyle style = populateAxisCategoryStyles(axis, index); + pane.populate(style); + categoryStyles.add(pane); + categoryStylePane.add(createCateLableStylePanel(), BorderLayout.NORTH); + + } + + private VanChartAxisLabelStyle populateAxisCategoryStyles(VanChartAxis axis, int index) { + VanChartAxisLabelStyle style; + if (axis.getCategoryStylesSize() > index && axis.getCategoryStyle(index) != null) { + style = axis.getCategoryStyle(index); + } else { + style = new VanChartAxisLabelStyle(); + axis.addCategoryStyle(style); } - if (labelGapStyle != null) { - labelGapStyle.setSelectedIndex(axis.isAutoLabelGap() ? 0 : 1); + return style; + } + + private JPanel createCateLableStylePanel() { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double e = TableLayout4VanChartHelper.EDIT_AREA_WIDTH; + double[] row = getCateLableStylePaneRow(); + double[] column = {f, p}; + + JPanel content = TableLayoutHelper.createTableLayoutPane(getCateLabelStyleComponents(), row, column); + + Component[][] components = new Component[][]{ + new Component[]{null, null}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Chart_Style_Category")), content} + }; + + return TableLayoutHelper.createTableLayoutPane(components, new double[]{p, p}, new double[]{f, e}); + } + + private Component[][] getCateLabelStyleComponents() { + Component[][] components = new Component[categoryStyles.size()][]; + for (int i = 0; i < categoryStyles.size(); i++) { + components[i] = new Component[2]; + components[i][0] = categoryStyles.get(i); + components[i][1] = null; } - if (labelGapValue != null) { - //轴标签缩略间隔显示 恢复用注释。下面1行删除。 - labelGapValue.setText(axis.getLabelNumber().getContent()); - //轴标签缩略间隔显示 恢复用注释。取消注释。 - //labelGapValue.setValue(axis.getIntervalNumber()); + return components; + } + + private double[] getCateLableStylePaneRow() { + double[] row = new double[categoryStyles.size()]; + for (int i = 0; i < categoryStyles.size(); i++) { + row[i] = TableLayout.PREFERRED; } + return row; } //轴线样式 @@ -833,37 +813,54 @@ public class VanChartBaseAxisPane extends FurtherBasicBeanPane { } //标签 - private void updateLabel(VanChartAxis axis) { + protected void updateLabel(VanChartAxis axis) { if (showLabel != null) { axis.setShowAxisLabel(showLabel.getSelectedIndex() == 0); } - TextAttr labelTextAttr = axis.getTextAttr(); - if (labelTextAttrPane != null) { - labelTextAttrPane.update(labelTextAttr); - } - if (labelTextRotation != null) { - labelTextAttr.setRotation(labelTextRotation.updateBean().intValue()); - } - //轴标签缩略间隔显示 恢复用注释。取消注释。 -// if (overlapHandleTypeGroup != null) { -// axis.setOverlapHandleType(overlapHandleTypeGroup.getSelectedItem()); -// } - if (labelDisplayComboBox != null) { - axis.setLabelDisplay(labelDisplayComboBox.updateBean()); + if (!axis.isMultiCategory()) { + axis.setLabelDisplayMode(VanChartAxis.WHOLE_DISPLAY); + updateLabelPaneStyle(axis, labelPane); + } else { + updateShowLogicPane(axis); } - if (labelGapStyle != null) { - axis.setAutoLabelGap(labelGapStyle.getSelectedIndex() == 0); + switchLabelPane(axis); + } + + private void updateShowLogicPane(VanChartAxis axis) { + if (showLogic != null) { + axis.setLabelDisplayMode(showLogic.getSelectedIndex()); } - if (labelGapValue != null) { - //轴标签缩略间隔显示 恢复用注释。下面5行删除。 - if (axis.isAutoLabelGap()) { - axis.setLabelIntervalNumber(BaseFormula.createFormulaBuilder().build("1")); - } else { - axis.setLabelIntervalNumber(BaseFormula.createFormulaBuilder().build(labelGapValue.getText())); - } - //轴标签缩略间隔显示 恢复用注释。取消注释。 - //axis.setIntervalNumber((int) labelGapValue.getValue()); + + updateWholeDisplayPane(axis); + updateLayerDisplayPane(axis); + } + + /** + * update整体显示那个card面板 + */ + private void updateWholeDisplayPane(VanChartAxis axis) { + updateLabelPaneStyle(axis, wholeDisplayLabelPanel); + } + + private void updateLabelPaneStyle(VanChartAxis axis, VanChartAxisStyleSettingPane pane) { + VanChartAxisLabelStyle style = pane.updateBean(); + axis.setLabelDisplay(style.getLabelDisplay()); + axis.setTextAttr(style.getTextAttr()); + axis.setAutoLabelGap(style.isAutoLabelGap()); + axis.setLabelIntervalNumber(style.getLabelIntervalNumber()); + } + + /** + * update分层显示那个card面板 + * + * @param axis + */ + private void updateLayerDisplayPane(VanChartAxis axis) { + List styles = new ArrayList<>(); + for (VanChartCategoryStylePaneWithCheckBox categoryStyle : categoryStyles) { + styles.add(categoryStyle.update()); } + axis.setCategoryStyles(styles); } //轴线样式 diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java index 1a0b78982f..500667963b 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartTimeAxisPane.java @@ -85,11 +85,6 @@ public class VanChartTimeAxisPane extends VanChartBaseAxisPane { return false; } - @Override - protected void addOverlapGroupButton(JPanel panel) { - //do nothing - } - private JPanel createValueDefinition(){ timeMinMaxValuePane = new TimeMinMaxValuePane(); return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Value_Definition"), timeMinMaxValuePane); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartValueAxisPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartValueAxisPane.java index 7633d0c1e4..032642c93a 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartValueAxisPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/VanChartValueAxisPane.java @@ -66,11 +66,6 @@ public class VanChartValueAxisPane extends VanChartBaseAxisPane { return false; } - @Override - protected void addOverlapGroupButton(JPanel panel) { - //do nothing - } - protected JPanel createMinMaxValuePane(double[] row, double[] col){ JPanel panel = createCommenValuePane(row,col); return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Value_Definition"), panel); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/component/VanChartCategoryStylePaneWithCheckBox.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/component/VanChartCategoryStylePaneWithCheckBox.java new file mode 100644 index 0000000000..acc87572ff --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/component/VanChartCategoryStylePaneWithCheckBox.java @@ -0,0 +1,97 @@ +package com.fr.van.chart.designer.style.axis.component; + +import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; +import com.fr.design.gui.frpane.UIBubbleFloatPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.i18n.Toolkit; +import com.fr.plugin.chart.attr.axis.VanChartAxisLabelStyle; +import com.fr.stable.Constants; +import com.fr.van.chart.designer.style.axis.VanChartAxisPaneHelper; +import com.fr.van.chart.designer.style.axis.VanChartAxisStyleSettingPane; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class VanChartCategoryStylePaneWithCheckBox extends JPanel { + private UICheckBox checkBox; // 复选框 + private UIButton settingButton; // 设置按钮 + private VanChartAxisStyleSettingPane settingPane; // 设置弹窗面板 + + private JPanel showOnPane; + private AbstractAttrNoScrollPane parent; + + private VanChartAxisLabelStyle axis; + + public VanChartCategoryStylePaneWithCheckBox(AbstractAttrNoScrollPane parent, JPanel showOnPane, String checkBoxName) { + this.parent = parent; + this.showOnPane = showOnPane; + + this.setLayout(new BorderLayout()); + checkBox = new UICheckBox(checkBoxName); + checkBox.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + checkBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + /* 为什么需要这句话呢?因为这个checkBox是动态加上去的,没有走最上层父组件ChartStylePane的initAllListener方法, + * 所以不会触发update监听,下面的bubble弹窗则是不属于ChartStylePane的单独悬浮组件,也只能这样触发update监听 + */ + if(parent != null){ + parent.attributeChanged(); + } + } + }); + settingButton = new UIButton(Toolkit.i18nText("Fine-Design_Chart_Axis_Style_Setting")); + + this.add(checkBox, BorderLayout.CENTER); + this.add(settingButton, BorderLayout.EAST); + + initListener(); + } + + private void initListener() { + if(settingButton != null) { + settingButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + if (settingPane == null) { + settingPane = new VanChartAxisStyleSettingPane(VanChartAxisPaneHelper.createAxisTextAttrPane()); + } + + Point comPoint = settingButton.getLocationOnScreen(); + Point arrowPoint = new Point(comPoint.x +settingButton.getWidth() - 25, comPoint.y + settingButton.getHeight()); + Dimension size = settingPane.getPreferredSize(); + UIBubbleFloatPane pane = new UIBubbleFloatPane(Constants.LEFT, arrowPoint, settingPane, size.width, 230) { + + @Override + public void updateContentPane() { + axis = settingPane.updateBean(); + if(parent != null){//条件属性没有parent + parent.attributeChanged(); + } + } + }; + pane.show(showOnPane, axis); + super.mouseReleased(e); + } + }); + } + } + + public void populate(VanChartAxisLabelStyle style) { + this.axis = style; + checkBox.setSelected(axis.isShowLabel()); + } + + public VanChartAxisLabelStyle update() { + axis.setShowLabel(checkBox.isSelected()); + return axis; + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/gauge/VanChartGaugeDetailAxisPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/gauge/VanChartGaugeDetailAxisPane.java index 91de3ed359..7817b75f58 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/gauge/VanChartGaugeDetailAxisPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/gauge/VanChartGaugeDetailAxisPane.java @@ -1,5 +1,6 @@ package com.fr.van.chart.designer.style.axis.gauge; +import com.fr.chart.base.TextAttr; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; @@ -35,6 +36,7 @@ public class VanChartGaugeDetailAxisPane extends VanChartValueAxisPane { private static final long serialVersionUID = -9213466625457882224L; + private ChartTextAttrPane labelTextAttrPane; private ColorSelectBox mainTickColor; private ColorSelectBox secTickColor; @@ -83,12 +85,12 @@ public class VanChartGaugeDetailAxisPane extends VanChartValueAxisPane { protected JPanel createLabelPane(double[] row, double[] col) { showLabel = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Chart_Use_Show"), Toolkit.i18nText("Fine-Design_Chart_Hidden")}); labelTextAttrPane = getChartTextAttrPane(); - labelPanel = new JPanel(new BorderLayout()); - labelPanel.add(labelTextAttrPane); - labelPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0)); + labelContentPane = new JPanel(new BorderLayout()); + labelContentPane.add(labelTextAttrPane); + labelContentPane.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 0)); JPanel panel = new JPanel(new BorderLayout(0, 6)); panel.add(TableLayout4VanChartHelper.createGapTableLayoutPane(Toolkit.i18nText("Fine-Design_Chart_Axis_Label"), showLabel), BorderLayout.NORTH); - panel.add(labelPanel, BorderLayout.CENTER); + panel.add(labelContentPane, BorderLayout.CENTER); showLabel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -183,23 +185,44 @@ public class VanChartGaugeDetailAxisPane extends VanChartValueAxisPane { public void populateBean(VanChartAxis axis) { VanChartGaugeAxis gaugeAxis = (VanChartGaugeAxis) axis; + labelTextAttrPane.populate(axis.getTextAttr()); + super.populateBean(gaugeAxis); + } + + @Override + protected void populateLabel(VanChartAxis axis) { + VanChartGaugeAxis gaugeAxis = (VanChartGaugeAxis) axis; + + if (showLabel != null) { + showLabel.setSelectedIndex(axis.isShowAxisLabel() ? 0 : 1); + } if (mainTickColor != null) { mainTickColor.setSelectObject(gaugeAxis.getMainTickColor()); } if (secTickColor != null) { secTickColor.setSelectObject(gaugeAxis.getSecTickColor()); } - super.populateBean(gaugeAxis); } public void updateBean(VanChartAxis axis) { VanChartGaugeAxis gaugeAxis = (VanChartGaugeAxis) axis; + TextAttr textAttr = axis.getTextAttr(); + labelTextAttrPane.update(textAttr); + super.updateBean(gaugeAxis); + } + + @Override + protected void updateLabel(VanChartAxis axis) { + VanChartGaugeAxis gaugeAxis = (VanChartGaugeAxis) axis; + + if (showLabel != null) { + axis.setShowAxisLabel(showLabel.getSelectedIndex() == 0); + } if (mainTickColor != null) { gaugeAxis.setMainTickColor(mainTickColor.getSelectObject()); } if (secTickColor != null) { gaugeAxis.setSecTickColor(secTickColor.getSelectObject()); } - super.updateBean(gaugeAxis); } } \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartGantAreaPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartGantAreaPane.java new file mode 100644 index 0000000000..382a918270 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartGantAreaPane.java @@ -0,0 +1,15 @@ +package com.fr.van.chart.designer.style.background; + +import com.fr.chart.chartattr.Plot; +import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; +import com.fr.van.chart.designer.style.VanChartStylePane; + +public class VanChartGantAreaPane extends VanChartAreaPane { + public VanChartGantAreaPane(Plot plot, VanChartStylePane parent) { + super(plot, parent); + } + + protected void initPlotPane(boolean b, AbstractAttrNoScrollPane parent) { + plotPane = new VanChartGantPlotAreaBackgroundPane(parent); + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartGantPlotAreaBackgroundPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartGantPlotAreaBackgroundPane.java new file mode 100644 index 0000000000..fbea849909 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/background/VanChartGantPlotAreaBackgroundPane.java @@ -0,0 +1,102 @@ +package com.fr.van.chart.designer.style.background; + +import com.fr.chart.chartattr.Chart; +import com.fr.chart.chartattr.Plot; +import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.chart.gui.ColorSelectBoxWithOutTransparent; +import com.fr.plugin.chart.gantt.VanChartGanttPlot; +import com.fr.van.chart.designer.TableLayout4VanChartHelper; + +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; + +public class VanChartGantPlotAreaBackgroundPane extends VanChartAreaBackgroundPane { + private ColorSelectBoxWithOutTransparent axisColorPane; + private ColorSelectBoxWithOutTransparent contentColorPane; + + public VanChartGantPlotAreaBackgroundPane(AbstractAttrNoScrollPane parent) { + super(true, parent); + } + + @Override + protected JPanel createContentPane() { + JPanel contentPane = new JPanel(new BorderLayout()); + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] columnSize = {f}; + double[] rowSize = {p, p}; + Component[][] components = new Component[][]{ + new Component[]{createAxisBorderPane()}, + new Component[]{createContentBorderPane()} + }; + + contentPane.add(TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize), BorderLayout.CENTER); + return contentPane; + } + + @Override + public void updateBean(Chart chart) { + if (chart == null) { + chart = new Chart(); + } + + Plot plot = chart.getPlot(); + if (plot instanceof VanChartGanttPlot) { + VanChartGanttPlot ganttPlot = (VanChartGanttPlot) plot; + ganttPlot.setAxisBorderColor(axisColorPane.getSelectObject()); + ganttPlot.setContentBorderColor(contentColorPane.getSelectObject()); + } + } + + @Override + public void populateBean(Chart chart) { + if (chart == null) { + chart = new Chart(); + } + + Plot plot = chart.getPlot(); + if (plot instanceof VanChartGanttPlot) { + VanChartGanttPlot ganttPlot = (VanChartGanttPlot) plot; + axisColorPane.setSelectObject(ganttPlot.getAxisBorderColor()); + contentColorPane.setSelectObject(ganttPlot.getContentBorderColor()); + } + } + + private JPanel createAxisBorderPane() { + axisColorPane = new ColorSelectBoxWithOutTransparent(100); + return TableLayout4VanChartHelper.createExpandablePaneWithTitle( + Toolkit.i18nText("Fine-Design_Chart_Gant_Axis_Border"), + createBorderPane(axisColorPane) + ); + } + + private JPanel createContentBorderPane() { + contentColorPane = new ColorSelectBoxWithOutTransparent(100); + return TableLayout4VanChartHelper.createExpandablePaneWithTitle( + Toolkit.i18nText("Fine-Design_Chart_Gant_Content_Border"), + createBorderPane(contentColorPane) + ); + } + + private JPanel createBorderPane(ColorSelectBoxWithOutTransparent colorPane) { + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] columnSize = {f, TableLayout4VanChartHelper.EDIT_AREA_WIDTH}; + double[] rowSize = {p, p}; + + Component[][] components = new Component[][]{ + new Component[]{null, null}, + new Component[]{ + new UILabel(Toolkit.i18nText("Fine-Design_Chart_Color")), + colorPane + } + }; + + return TableLayout4VanChartHelper.createGapTableLayoutPane(components, rowSize, columnSize); + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/VanChartGanttStylePane.java b/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/VanChartGanttStylePane.java index b12e0579fa..7d1de704fc 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/VanChartGanttStylePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/VanChartGanttStylePane.java @@ -4,6 +4,8 @@ import com.fr.chart.chartattr.Plot; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.frpane.AttributeChangeListener; import com.fr.van.chart.designer.style.VanChartStylePane; +import com.fr.van.chart.designer.style.background.VanChartAreaPane; +import com.fr.van.chart.designer.style.background.VanChartGantAreaPane; import com.fr.van.chart.gantt.designer.style.axis.GanttProcessAxisPane; import com.fr.van.chart.gantt.designer.style.axis.GanttTimeAxisPane; @@ -31,4 +33,8 @@ public class VanChartGanttStylePane extends VanChartStylePane { private void addProjectAxisPane(List paneList, Plot plot) { paneList.add(new GanttProcessAxisPane()); } + + protected VanChartAreaPane createVanChartAreaPane() { + return new VanChartGantAreaPane(getChart().getPlot(), VanChartGanttStylePane.this); + } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/series/VanChartGanttSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/series/VanChartGanttSeriesPane.java index 9236773e71..a62f054e7f 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/series/VanChartGanttSeriesPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/series/VanChartGanttSeriesPane.java @@ -5,6 +5,7 @@ import com.fr.design.beans.BasicBeanPane; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.icombobox.LineComboBox; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.gui.ChartStylePane; @@ -14,6 +15,7 @@ import com.fr.plugin.chart.gantt.VanChartGanttPlot; import com.fr.stable.CoreConstants; import com.fr.van.chart.designer.TableLayout4VanChartHelper; import com.fr.van.chart.designer.component.VanChartBeautyPane; +import com.fr.van.chart.designer.component.VanChartGanttTimeLinePane; import com.fr.van.chart.designer.component.VanChartMarkerPane; import com.fr.van.chart.designer.component.marker.VanChartCommonMarkerPane; import com.fr.van.chart.designer.style.series.VanChartAbstractPlotSeriesPane; @@ -30,6 +32,8 @@ public class VanChartGanttSeriesPane extends VanChartAbstractPlotSeriesPane { private LineComboBox lineWidth;//线型 private ColorSelectBoxWithOutTransparent colorSelect;//颜色 + private VanChartGanttTimeLinePane timeLinePane; + public VanChartGanttSeriesPane(ChartStylePane parent, Plot plot) { super(parent, plot); } @@ -45,7 +49,8 @@ public class VanChartGanttSeriesPane extends VanChartAbstractPlotSeriesPane { new Component[]{createGanntStylePane()}, new Component[]{createLinkLinePane()}, new Component[]{createMarkerPane()}, - new Component[]{createLargeDataModelPane()} + new Component[]{createLargeDataModelPane()}, + new Component[]{createGuideLinePane()} }; contentPane = TableLayoutHelper.createTableLayoutPane(components, row, col); @@ -96,6 +101,11 @@ public class VanChartGanttSeriesPane extends VanChartAbstractPlotSeriesPane { return TableLayout4VanChartHelper.createExpandablePaneWithTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Gannt_Marker"), markerPane); } + protected JPanel createGuideLinePane() { + timeLinePane = new VanChartGanttTimeLinePane(); + return TableLayout4VanChartHelper.createExpandablePaneWithTitle(Toolkit.i18nText("Fine-Design_Chart_Guide_Line_Identify"), timeLinePane); + } + @Override public void populateBean(Plot plot) { super.populateBean(plot); @@ -104,10 +114,10 @@ public class VanChartGanttSeriesPane extends VanChartAbstractPlotSeriesPane { VanChartGanttPlot ganttPlot = (VanChartGanttPlot)plot; seriesNewLine.setSelectedIndex(ganttPlot.isSeriesNewLineEnable() ? 0 : 1); - lineWidth.setSelectedLineStyle(ganttPlot.getLineWidth()); colorSelect.setSelectObject(ganttPlot.getLineColor()); + timeLinePane.populateBean(plot); } } @@ -121,6 +131,7 @@ public class VanChartGanttSeriesPane extends VanChartAbstractPlotSeriesPane { ganttPlot.setLineWidth(lineWidth.getSelectedLineStyle()); ganttPlot.setLineColor(colorSelect.getSelectObject()); + timeLinePane.updateBean(plot); } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartFormatComBoxWithCheckBox.java b/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartFormatComBoxWithCheckBox.java index 95da8ea986..f17d07a249 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartFormatComBoxWithCheckBox.java +++ b/designer-chart/src/main/java/com/fr/van/chart/gantt/designer/style/tooltip/VanChartFormatComBoxWithCheckBox.java @@ -53,7 +53,7 @@ public class VanChartFormatComBoxWithCheckBox extends JPanel { } }); - formatComBox.setPreferredSize(new Dimension(40, 20)); + formatComBox.setPreferredSize(new Dimension(55, 20)); if (showSelectBox()) { this.add(isSelectedBox, BorderLayout.CENTER); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/events/AddingWidgetListenerTable.java b/designer-form/src/main/java/com/fr/design/designer/beans/events/AddingWidgetListenerTable.java index 4825e88883..5d0889c358 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/events/AddingWidgetListenerTable.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/events/AddingWidgetListenerTable.java @@ -28,23 +28,13 @@ public class AddingWidgetListenerTable { public void beforeAdded() { for (final AddingWidgetListener listener : listeners) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - listener.beforeAdded(); - } - }); + listener.beforeAdded(); } } public void afterAdded(boolean addResult) { for (final AddingWidgetListener listener : listeners) { - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - listener.afterAdded(addResult); - } - }); + listener.afterAdded(addResult); } } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/DraggingModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/DraggingModel.java index 6308ff70b5..95e003faf3 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/DraggingModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/DraggingModel.java @@ -14,7 +14,6 @@ public class DraggingModel { private MouseEvent currentDragEvent; private int creatorLeftTopX = -999; // 隐藏 private int creatorLeftTopY = -999; // 隐藏 - private boolean dragNewWidget; // 是否正在拖拽一个新的组件下来 public DraggingModel() { @@ -40,11 +39,6 @@ public class DraggingModel { return this; } - public DraggingModel dragNewWidget(boolean dragNewWidget) { - this.dragNewWidget = dragNewWidget; - return this; - } - public FormDesigner getDesigner() { return designer; } @@ -79,10 +73,6 @@ public class DraggingModel { return creatorLeftTopY; } - public boolean isDragNewWidget() { - return dragNewWidget; - } - public void moveTo(int x, int y) { XLayoutContainer container = designer.getDraggingHotspotLayout(); LayoutAdapter adapter = container.getLayoutAdapter(); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index 14fc9ea248..792e97045e 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -54,6 +54,7 @@ import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.List; import java.util.Set; +import java.util.StringJoiner; /** * @author richer @@ -943,4 +944,14 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo return false; } + + @Override + public String toString() { + return new StringJoiner(", ", XCreator.class.getSimpleName() + "[", "]") + .add("data=" + data) + .add("shareId='" + shareId + "'") + .add("isHelpBtnOnFocus=" + isHelpBtnOnFocus) + .add("selected=" + selected) + .toString(); + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java index bdaf40d226..2f4a699379 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java @@ -20,6 +20,7 @@ import com.fr.form.FormProvider; import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.ElementCaseEditorProvider; import com.fr.report.fit.ReportFitAttr; +import com.fr.report.fit.ReportFitConfig; import com.fr.stable.ArrayUtils; import com.fr.stable.CoreGraphHelper; import com.fr.stable.core.PropertyChangeAdapter; @@ -127,7 +128,8 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme private CRPropertyDescriptor getReportFitEditor() { this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); FitProvider wbTpl = designer.getTarget(); - ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); + //这边获取到的全局要考虑到服务器的配置 + ReportFitAttr fitAttr = wbTpl.getReportFitAttr() == null ? ReportFitConfig.getInstance().getFrmFitAttr() : wbTpl.getReportFitAttr(); ElementCaseEditor editor = this.toData(); //兼容之前报表块(之前三个选项为:默认 横向 双向 现在是:横向 双向 不自适应) if (editor.getFitStateInPC() == 0) { diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java index ea61700522..886089a0be 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java @@ -764,6 +764,7 @@ public class XWFitLayout extends XLayoutContainer { creator.setBackupBound(creator.getBounds()); } } + LayoutUtils.layoutContainer(this); } private Rectangle recalculateWidgetBounds(Rectangle rec, int[] hors, int[] veris) { @@ -831,11 +832,7 @@ public class XWFitLayout extends XLayoutContainer { this.remove(oldCreator); this.add(newCreator); dealDirections(newCreator, false); - //对于新增的绝对布局的组件,需要更新下内部组件的大小 - if (newCreator.acceptType(XWAbsoluteLayout.class)){ - ((XWAbsoluteLayout) newCreator).updateBoundsWidget(); - newCreator.setBackupBound(newCreator.getBounds()); - } + this.updateBoundsWidget(); isRefreshing = false; LayoutUtils.layoutContainer(this); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWParameterLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWParameterLayout.java index a41ec46f6f..aacdf6d04b 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWParameterLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWParameterLayout.java @@ -270,4 +270,16 @@ public class XWParameterLayout extends XWAbsoluteLayout { public boolean isTopable() { return false; } + + /** + * 修改form布局的宽度时,需要同时修改表单参数界面的布局的宽度。 + * */ + @Override + public void doLayout() { + layout(); + if (data != null && data instanceof WParameterLayout) { + ((WParameterLayout) data).setDesignWidth(getWidth()); + } + } + } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java index 850378af21..ec070ad867 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java @@ -8,6 +8,7 @@ import com.fr.base.ScreenResolution; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRWCardTagLayoutAdapter; +import com.fr.design.designer.beans.models.ModelUtil; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; @@ -136,6 +137,9 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout { WTabFitLayout fitLayout = new WTabFitLayout(widgetName, tabFitIndex, currentCard); fitLayout.setTabNameIndex(getTabNameIndex()); XWTabFitLayout tabFitLayout = new XWTabFitLayout(fitLayout, new Dimension()); + + FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + ModelUtil.renameWidgetName(formDesigner.getTarget(), tabFitLayout); WCardTagLayout layout = (WCardTagLayout) this.toData(); if(!ComparatorUtils.equals(layout.getTemplateStyle().getStyle(), DefaultTemplateStyle.DEFAULT_TEMPLATE_STYLE)){ diff --git a/designer-form/src/main/java/com/fr/design/fit/NewJForm.java b/designer-form/src/main/java/com/fr/design/fit/NewJForm.java index 0a12a74257..660a5c483e 100644 --- a/designer-form/src/main/java/com/fr/design/fit/NewJForm.java +++ b/designer-form/src/main/java/com/fr/design/fit/NewJForm.java @@ -2,25 +2,27 @@ package com.fr.design.fit; import com.fr.base.DynamicUnitList; import com.fr.base.Parameter; +import com.fr.base.TRL; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRFitLayoutAdapter; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XComponent; +import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XElementCase; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWTitleLayout; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.mainframe.DesignerUIModeConfig; -import com.fr.design.preview.DeveloperPreview; -import com.fr.design.preview.FormAdaptivePreview; import com.fr.design.fit.toolbar.SwitchAction; import com.fr.design.fun.PreviewProvider; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.design.preview.DeveloperPreview; +import com.fr.design.preview.FormAdaptivePreview; import com.fr.design.preview.FormPreview; import com.fr.design.preview.MobilePreview; import com.fr.design.utils.ComponentUtils; @@ -29,6 +31,7 @@ import com.fr.form.FormElementCaseProvider; import com.fr.form.fit.NewFormMarkAttr; import com.fr.form.main.Form; import com.fr.form.ui.ElementCaseEditor; +import com.fr.general.ComparatorUtils; import com.fr.stable.ArrayUtils; import javax.swing.JComponent; @@ -176,11 +179,13 @@ public class NewJForm extends JForm { FRFitLayoutAdapter layoutAdapter = (FRFitLayoutAdapter) adapter; layoutAdapter.setEdit(true); layoutAdapter.calculateBounds(backupBounds, xwTitleLayout.getBounds(), xwTitleLayout, row, difference); + } else { + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xwTitleLayout); + if (parent != null && parent.toData() != null) { + parent.toData().setBounds(xwTitleLayout.toData(), xwTitleLayout.getBounds()); + } } - XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xwTitleLayout); - if (parent != null && parent.toData() != null) { - parent.toData().setBounds(xwTitleLayout.toData(), xwTitleLayout.getBounds()); - } + } @@ -215,6 +220,7 @@ public class NewJForm extends JForm { return new PreviewProvider[]{new FormPreview(), new MobilePreview()}; } + @Override public UIButton[] createExtraButtons() { UIButton[] extraButtons = super.createExtraButtons(); return addAdaptiveSwitchButton(extraButtons); @@ -228,4 +234,25 @@ public class NewJForm extends JForm { public boolean isNewJFrom() { return jFormType == null || jFormType.isNewType(); } + + @Override + public void navigate(TRL trl) { + String blockName = trl.unescapeNext(); + JForm.traversalXCreator(formDesign.getRootComponent(), xCreator -> { + if (!ComparatorUtils.equals(xCreator.toData().getWidgetName(), blockName)) { + return; + } + if (xCreator instanceof XElementCase) { + getFormDesign().getSelectionModel().selectACreator(xCreator); + xCreator.startEditing(); + if (getElementCaseDesign() != null) { + getElementCaseDesign().navigate(trl); + } + } else { + tabChanged(FORM_TAB); + getFormDesign().getSelectionModel().reset(); + getFormDesign().getSelectionModel().selectACreator(xCreator); + } + }, XCreator.class); + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java index f48b60320d..0555cf1723 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java @@ -459,13 +459,11 @@ public class EditingMouseListener extends MouseInputAdapter { if (isSelectionDrag()) { stateModel.changeSelection(e); - return; } // 调整大小这边单独提出来,不跟后面拖组件混在一起,实在不好管理 if (stateModel.isDraggingSize()) { stateModel.dragging(e); - return; } designer.startDraggingFormWidget(lastXCreator, lastPressEvent, e); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index aa58d713e5..62e256379c 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -264,11 +264,7 @@ public class FormCreatorDropTarget extends DropTarget { Point loc = dtde.getLocation(); int x = designer.getRelativeX(loc.x); int y = designer.getRelativeY(loc.y); - if (model.isDragNewWidget()) { - designer.addNewWidget(creator, x, y); - } else { - designer.changeWidgetPlace(creator, x, y); - } + designer.addWidgetToForm(creator, x, y); // 放到事件末尾执行 SwingUtilities.invokeLater(new Runnable() { @Override diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java index ef1177ece9..24ed004fff 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java @@ -1248,16 +1248,16 @@ public class FormDesigner extends TargetComponent
implements TreeSelection * @param currentDragEvent */ public void startDraggingNewWidget(XCreator xCreator, MouseEvent startDragEvent, MouseEvent currentDragEvent) { - if (currentDragEvent == null || this.getDropTarget() != null) { + if (currentDragEvent == null) { return; } + instantiateCreator(xCreator); draggingModel = new DraggingModel() .designer(this) .creator(xCreator) .startDragEvent(startDragEvent) - .currentDragEvent(currentDragEvent) - .dragNewWidget(true); + .currentDragEvent(currentDragEvent); this.setDropTarget(new FormCreatorDropTarget(this, xCreator)); repaint(); } @@ -1270,15 +1270,15 @@ public class FormDesigner extends TargetComponent implements TreeSelection * @param currentDragEvent */ public void startDraggingFormWidget(XCreator xCreator, MouseEvent startDragEvent, MouseEvent currentDragEvent) { - if (currentDragEvent == null || this.getDropTarget() != null) { + if (currentDragEvent == null) { return; } + backUpCreator(xCreator); draggingModel = new DraggingModel() .designer(this) .creator(xCreator) .startDragEvent(startDragEvent) - .currentDragEvent(currentDragEvent) - .dragNewWidget(false); + .currentDragEvent(currentDragEvent); XLayoutContainer container = this.getDraggingHotspotLayout(); LayoutAdapter adapter = container.getLayoutAdapter(); adapter.dragging(this.getDraggingModel()); @@ -1318,7 +1318,14 @@ public class FormDesigner extends TargetComponent implements TreeSelection DraggingModel model = this.draggingModel; MouseEvent dragEvent = model.getCurrentDragEvent(); XCreator hotspot = this.getComponentAt(dragEvent.getX(), dragEvent.getY()); - return XCreatorUtils.getHotspotContainer(hotspot); + XLayoutContainer container = XCreatorUtils.getHotspotContainer(hotspot); + XLayoutContainer topLayout = container.getTopLayout(); + // REPORT-66939 Tab比较特殊,它是又多个LayoutContainer组成,直接返回container会导致误判,需要先找到最上层topLayout,取其父layout才是正确结果 + if (topLayout != null && container != topLayout) { + return (XLayoutContainer) topLayout.getParent(); + } else { + return container; + } } /** @@ -1520,7 +1527,10 @@ public class FormDesigner extends TargetComponent implements TreeSelection private DesignerBaseOperate getLayoutBaseOperate(){ FormSelection selection = this.getSelectionModel().getSelection(); XCreator creator = selection.getSelectedCreator(); - XLayoutContainer container = (XLayoutContainer) creator.getParent(); + XLayoutContainer container = null; + if (creator != null) { + container = (XLayoutContainer) creator.getParent(); + } if (container == null) { return new DefaultDesignerBaseOperate(); } @@ -1987,27 +1997,25 @@ public class FormDesigner extends TargetComponent implements TreeSelection return spacingLineDrawer; } - private void instantiateCreator(XCreator creator) { - ModelUtil.renameWidgetName(this.getTarget(), creator); - creator.addNotify(); - - ComponentAdapter adapter = new CompositeComponentAdapter(this, creator); - adapter.initialize(); - creator.putClientProperty(AdapterBus.CLIENT_PROPERTIES, adapter); - } + public void instantiateCreator(XCreator creator) { + if (creator != null) { + ModelUtil.renameWidgetName(this.getTarget(), creator); + creator.addNotify(); - public void addNewWidget(XCreator creator, int x, int y) { - instantiateCreator(creator); - addWidgetToForm(creator, x, y); + ComponentAdapter adapter = new CompositeComponentAdapter(this, creator); + adapter.initialize(); + creator.putClientProperty(AdapterBus.CLIENT_PROPERTIES, adapter); + } } - public void changeWidgetPlace(XCreator creator, int x, int y) { - creator.backupCurrentSize(); - creator.backupParent(); - addWidgetToForm(creator, x, y); + public void backUpCreator(XCreator creator) { + if (creator != null) { + creator.backupCurrentSize(); + creator.backupParent(); + } } - private void addWidgetToForm(XCreator creator, int x, int y) { + public void addWidgetToForm(XCreator creator, int x, int y) { if(creator == null) { return; } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java index 1d641decef..8307e945f6 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java @@ -116,8 +116,8 @@ public class FormDesignerUI extends ComponentUI { designer.getPainter().paint(g, designer.getArea().getHorizontalValue(), designer.getArea().getVerticalValue() + designer.getParaHeight()); } - DraggingModel draggingModel = designer.getDraggingModel(); - if (draggingModel != null && draggingModel.getCreator() != null) { + + if (needPaintDraggingBean()) { // 当前正在添加的组件 paintDraggingBean(g); } @@ -217,6 +217,19 @@ public class FormDesignerUI extends ComponentUI { ComponentUtils.resetBuffer(dbcomponents); } + private boolean needPaintDraggingBean() { + DraggingModel draggingModel = designer.getDraggingModel(); + if (draggingModel == null || draggingModel.getCreator() == null) { + return false; + } + + XCreator creator = draggingModel.getCreator(); + int leftTopX = draggingModel.getCreatorLeftTopX(); + int leftTopY = draggingModel.getCreatorLeftTopY(); + + return leftTopX + creator.getWidth() > 0 && leftTopY + creator.getHeight() > 0; + } + private void paintAuthorityCreator(Graphics2D g2d, Rectangle creatorBounds) { back_or_selection_rect.setRect(creatorBounds.getX(), creatorBounds.getY(), diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java b/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java index bf047a3bee..1230e0fae3 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java @@ -2,6 +2,7 @@ package com.fr.design.mainframe; import com.fr.base.Parameter; import com.fr.base.TableData; +import com.fr.base.param.ParameterSource; import com.fr.data.TableDataSource; import com.fr.design.DesignModelAdapter; import com.fr.design.file.HistoryTemplateListPane; @@ -14,8 +15,8 @@ import com.fr.script.Calculator; import com.fr.stable.EmbParaFilter; import com.fr.stable.ParameterProvider; import com.fr.stable.js.WidgetName; - import com.fr.util.ParameterApplyHelper; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -55,7 +56,7 @@ public class FormModelAdapter extends DesignModelAdapter> Map map = new HashMap<>(); addGlobalParameters(map); updateTableDataParameters(oldName, tdName, tableData, map, parameterProvider -> !EmbParaFilter.isFRLayerTypePara(parameterProvider)); - ParameterApplyHelper.addPara2Map(map, this.getBook().getTemplateParameters()); + ParameterApplyHelper.addPara2Map(map, this.getBook().getTemplateParameters(), null, ParameterSource.DEFAULT_SOURCE); parameters = map.values().toArray(new Parameter[0]); jTemplate.populateParameter(); } @@ -158,7 +159,7 @@ public class FormModelAdapter extends DesignModelAdapter> addTableDataParameters(map, parameterProvider -> !EmbParaFilter.isFRLayerTypePara(parameterProvider)); - ParameterApplyHelper.addPara2Map(map, this.getBook().getTemplateParameters()); + ParameterApplyHelper.addPara2Map(map, this.getBook().getTemplateParameters(), null, ParameterSource.DEFAULT_SOURCE); return map.values().toArray(new Parameter[0]); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java index 7a084c2f0f..2f78a98f09 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormParaWidgetPane.java @@ -18,6 +18,10 @@ import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.ComponentShareUtil; +import com.fr.design.mainframe.share.ui.online.OnlineWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; +import com.fr.design.mainframe.share.util.OnlineShopUtils; import com.fr.design.module.DesignModuleFactory; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.gui.LayoutUtils; @@ -262,7 +266,13 @@ public class FormParaWidgetPane extends JPanel { jPanel.addMouseListener(new MouseListener() { @Override public void mouseClicked(MouseEvent e) { - FormWidgetDetailPane.getInstance().enterWidgetLib(); + if (OnlineShopUtils.testConnection() && ComponentShareUtil.isShowMiniShopWindow()) { + MiniComponentShopDialog.getInstance().show(); + } else { + OnlineWidgetRepoPane.getInstance().switch2InternetErrorPane(); + FormWidgetDetailPane.getInstance().switch2Local(); + FormWidgetDetailPane.getInstance().enterWidgetLib(); + } } @Override 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 ec3852437b..449aa51906 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 @@ -96,6 +96,7 @@ import com.fr.stable.ProductConstants; import com.fr.stable.StringUtils; import com.fr.stable.bridge.StableFactory; import com.fr.web.controller.ViewRequestConstants; +import org.jetbrains.annotations.Nullable; import javax.swing.BorderFactory; import javax.swing.Icon; @@ -125,7 +126,7 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm { public int compare(OnlineShareWidget o1, OnlineShareWidget o2) { double t1 = getSortValue(o1, parameterMap); double t2 = getSortValue(o2, parameterMap); - return ComparatorUtils.compareCommonType(t2, t1); + // Comparator中比较double/float相等时,不允许误差. 否则会违背 "若x = y , y = z, 则x = z"的约定。 + // 因为允许误差的情况下,x和y间的误差在允许范围内,被判定相等,y和z间的误差在允许范围内,被判定相等, + // 但x和z间的误差可能超出允许范围,从而不相等,因此会违背上述约定。 + // 产生IllegalArgumentException: Comparison method violates its general contract! + return Double.compare(t2, t1); } }); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java index 8f21bd3f23..91b51b399e 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/LocalWidgetBlock.java @@ -250,6 +250,7 @@ public class LocalWidgetBlock extends PreviewWidgetBlock ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); return null; } + compatibleProcessAbsoluteLayoutResolution(creatorSource); creatorSource.setWidgetID(UUID.randomUUID().toString()); ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java index 7b0bf57080..61c913201b 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java @@ -194,6 +194,7 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); return; } + compatibleProcessAbsoluteLayoutResolution(creatorSource); creatorSource.setWidgetID(UUID.randomUUID().toString()); ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); SharableWidgetProvider bindInfo = ShareUtils.getElCaseBindInfoById(shareId); @@ -336,41 +337,42 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { null, this ); - return; - } - //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 - if (!isRightClickPopupMenuVisible() && (isMouseEnter || downloading)) { - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - //画白色的编辑层 - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 20 / 100.0F)); - g2d.setColor(COVER_COLOR); - g2d.fillRect(x, y, w, h); - g2d.setComposite(oldComposite); - //画编辑按钮图标 - BufferedImage image = (process > 0 || downloading) ? WIDGET_DOWNLOADING_ICON : WIDGET_DOWNLOAD_ICON; - g2d.drawImage( - image, - (x + w / 2 - 12), - (y + h / 2 - 16), - image.getWidth(), - image.getHeight(), - null, - this - ); - Stroke oldStroke = g2d.getStroke(); - g2d.setStroke(XCreatorConstants.STROKE); - g2d.setColor(Color.decode("#419BF9")); - double arcAngle = downloading ? (36 + 360 * 0.9 * process) : 0.0; - g2d.drawArc(x + w / 2 - 12, y + h / 2 - 16, 24, 24, 90, -(int) arcAngle); - g2d.setColor(Color.WHITE); - g2d.setStroke(oldStroke); - } + } else { + //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 + if (!isRightClickPopupMenuVisible() && (isMouseEnter || downloading)) { + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + //画白色的编辑层 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 20 / 100.0F)); + g2d.setColor(COVER_COLOR); + g2d.fillRect(x, y, w, h); + g2d.setComposite(oldComposite); + //画编辑按钮图标 + BufferedImage image = (process > 0 || downloading) ? WIDGET_DOWNLOADING_ICON : WIDGET_DOWNLOAD_ICON; + g2d.drawImage( + image, + (x + w / 2 - 12), + (y + h / 2 - 16), + image.getWidth(), + image.getHeight(), + null, + this + ); + Stroke oldStroke = g2d.getStroke(); + g2d.setStroke(XCreatorConstants.STROKE); + g2d.setColor(Color.decode("#419BF9")); + double arcAngle = downloading ? (36 + 360 * 0.9 * process) : 0.0; + g2d.drawArc(x + w / 2 - 12, y + h / 2 - 16, 24, 24, 90, -(int) arcAngle); + g2d.setColor(Color.WHITE); + g2d.setStroke(oldStroke); + } - boolean isUnusable = !getWidget().isCompatibleWithCurrentEnv(); - if (isUnusable) { - paintUnusableMask((Graphics2D) g); + boolean isUnusable = !getWidget().isCompatibleWithCurrentEnv(); + if (isUnusable) { + paintUnusableMask((Graphics2D) g); + } } + if (this.parentPane != null) { this.parentPane.refreshShowPaneUI(); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java index 5a19d0216f..93b9f93403 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java @@ -12,7 +12,12 @@ import com.fr.design.mainframe.share.collect.ComponentCollector; import com.fr.design.mainframe.share.ui.online.CarouselStateManger; import com.fr.design.mainframe.share.ui.online.embed.AnimatePopupDialog; import com.fr.design.mainframe.share.ui.online.embed.FirstDragAnimateStateManager; +import com.fr.form.main.Form; +import com.fr.form.main.WidgetGather; import com.fr.form.share.constants.ShareComponentConstants; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.WAbsoluteLayout; +import com.fr.general.FRScreen; import com.fr.module.ModuleContext; import org.jetbrains.annotations.NotNull; import javax.swing.ImageIcon; @@ -285,4 +290,18 @@ public abstract class PreviewWidgetBlock extends JPanel implements MouseListe } + protected void compatibleProcessAbsoluteLayoutResolution(Widget widget) { + Form.traversalWidget(widget, new WidgetGather() { + @Override + public void dealWith(Widget widget) { + ((WAbsoluteLayout) widget).setDesigningResolution(FRScreen.p1440.getDimension()); + } + + @Override + public boolean dealWithAllCards() { + return true; + } + }, WAbsoluteLayout.class); + } + } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java index 59a09c466c..1d4990c7d7 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineDownloadPackagePane.java @@ -72,22 +72,6 @@ public class OnlineDownloadPackagePane extends OnlineWidgetSelectPane { return false; } - protected JPanel createWidgetPane() { - return new JPanel() { - @Override - public void paint(Graphics g) { - super.paint(g); - Graphics2D g2d = (Graphics2D) g; - Composite oldComposite = g2d.getComposite(); - AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.65f); - g2d.setComposite(composite); - g2d.setColor(Color.DARK_GRAY); - g2d.fillRect(0, 0, getWidth(), getHeight()); - g2d.setComposite(oldComposite); - } - }; - } - protected JPanel createContentPane(JPanel widgetPane) { JPanel panel = new JPanel() { @Override @@ -114,7 +98,20 @@ public class OnlineDownloadPackagePane extends OnlineWidgetSelectPane { parentPane.resetWidgetDetailPane(packageId, getSharableWidgetProviders()); } } - }); + }) { + @Override + public void paint(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.65f); + g2d.setComposite(composite); + g2d.setColor(Color.DARK_GRAY); + g2d.fillRect(0, 0, getWidth(), getHeight()); + g2d.setComposite(oldComposite); + + super.paint(g); + } + }; panel.add(downloadProgressPane); panel.add(widgetPane, BorderLayout.CENTER); return panel; @@ -125,10 +122,16 @@ public class OnlineDownloadPackagePane extends OnlineWidgetSelectPane { final com.fr.design.extra.Process downloadProcess = aDouble -> { OnlineDownloadPackagePane.this.process = 0.8 * aDouble; downloadProgressPane.updateProgress(process); + if (downloadProgressPane != null) { + downloadProgressPane.repaint(); + } }; final com.fr.design.extra.Process installProcess = aDouble -> { OnlineDownloadPackagePane.this.process = 0.8 + 0.2 * aDouble; downloadProgressPane.updateProgress(process); + if (downloadProgressPane != null) { + downloadProgressPane.repaint(); + } }; downloadProcess.process(0.0D); @@ -220,6 +223,9 @@ public class OnlineDownloadPackagePane extends OnlineWidgetSelectPane { File file = new File(filePath); installProcess.process(0.0D); downloadProgressPane.changeState(); + if (downloadProgressPane != null) { + downloadProgressPane.repaint(); + } InstallUtils.InstallResult result = null; try { if (file.exists()) { @@ -250,4 +256,12 @@ public class OnlineDownloadPackagePane extends OnlineWidgetSelectPane { } } } + + @Override + public void refreshShowPaneUI() { + if (downloadProgressPane != null && downloadProgressPane.isShowing()) { + downloadProgressPane.invalidate(); + downloadProgressPane.repaint(); + } + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java index b9e430fe46..b4d3bcc68d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java @@ -1,29 +1,44 @@ package com.fr.design.mainframe.share.ui.online; import com.fr.base.BaseUtils; +import com.fr.base.Style; +import com.fr.config.constant.Constant; import com.fr.design.dialog.BasicPane; +import com.fr.design.form.util.FontTransformUtil; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.share.ui.base.LoadingPane; import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; import com.fr.design.mainframe.share.util.OnlineShopUtils; +import com.fr.design.mainframe.theme.edit.ui.LabelUtils; import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.general.FRFont; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; +import com.fr.stable.Constants; import com.fr.stable.StringUtils; import javax.swing.BorderFactory; +import javax.swing.BoxLayout; import javax.swing.JPanel; +import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.SwingWorker; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; +import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.util.List; import java.util.concurrent.ExecutionException; @@ -35,13 +50,8 @@ public class OnlineWidgetRepoPane extends BasicPane { private static final String MARKET_URL = "https://market.fanruan.com/reuse"; private static List[] sharableWidgets; private OnlineWidgetTabPane componentTabPane; - private JPanel centerPane; private boolean isShowPackagePanel = false; - private CardLayout cardLayout; - private Status currentStatus; - - - enum Status {LOADING, DISCONNECTED, NORMAL} + private LoadableContentPane loadableContentPane; public static boolean loadWidgets() { if (sharableWidgets != null){ @@ -82,16 +92,15 @@ public class OnlineWidgetRepoPane extends BasicPane { } private void initPane() { - cardLayout = new CardLayout(); - this.setLayout(cardLayout); - this.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); - this.centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + this.setLayout(new BorderLayout()); + + this.loadableContentPane = new LoadableContentPane(createInternetErrorPane()); + this.loadableContentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); - this.add(new LoadingPane(), Status.LOADING.name()); - this.add(this.centerPane, Status.NORMAL.name()); - this.add(createInternetErrorPane(), Status.DISCONNECTED.name()); + DisabledContentPane disabledContentPane = new DisabledContentPane(this.loadableContentPane); + this.add(disabledContentPane, BorderLayout.CENTER); - switchPane(Status.LOADING); + this.loadableContentPane.showLoading(); setContent(); } @@ -105,18 +114,15 @@ public class OnlineWidgetRepoPane extends BasicPane { } private void addCenterPane() { - this.centerPane.removeAll(); - this.centerPane.add(this.componentTabPane, BorderLayout.CENTER); - this.switchPane(Status.NORMAL); + JPanel contentPane = this.loadableContentPane.getContentPane(); + contentPane.removeAll(); + contentPane.setLayout(new BorderLayout()); + contentPane.add(this.componentTabPane, BorderLayout.CENTER); + this.loadableContentPane.showContent(); } public void switch2InternetErrorPane() { - switchPane(Status.DISCONNECTED); - } - - private void switchPane(Status status) { - this.currentStatus = status; - cardLayout.show(this, status.name()); + this.loadableContentPane.showError(); } private void synchronizedLoadingContent() { @@ -147,16 +153,18 @@ public class OnlineWidgetRepoPane extends BasicPane { if (componentTabPane != null) { componentTabPane.removeTabChangeListener(tabChangeListener); } - this.componentTabPane = new OnlineWidgetTabPane(sharableWidgets[0].toArray(new OnlineShareWidget[sharableWidgets[0].size()]), - sharableWidgets[1].toArray(new OnlineShareWidget[sharableWidgets[1].size()])); + this.componentTabPane = new OnlineWidgetTabPane( + sharableWidgets[0].toArray(new OnlineShareWidget[0]), + sharableWidgets[1].toArray(new OnlineShareWidget[0]) + ); this.componentTabPane.addTabChangeListener(tabChangeListener); } else { - switchPane(Status.DISCONNECTED); + this.loadableContentPane.showError(); } return loadWidgetsSuccess; } - private OnlineWidgetTabPane.TabChangeListener tabChangeListener = new OnlineWidgetTabPane.TabChangeListener() { + private final OnlineWidgetTabPane.TabChangeListener tabChangeListener = new OnlineWidgetTabPane.TabChangeListener() { @Override public void tabChange(int selectedIndex) { setShowPackagePanel(selectedIndex != 0); @@ -173,7 +181,7 @@ public class OnlineWidgetRepoPane extends BasicPane { private JPanel createInternetErrorPane() { JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); - UILabel imagePanel = new UILabel(BaseUtils.readIcon("/com/fr/base/images/share/internet_error.png")); + UILabel imagePanel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/internet_error.png")); imagePanel.setPreferredSize(new Dimension(240, 96)); imagePanel.setHorizontalAlignment(SwingConstants.CENTER); panel.add(imagePanel); @@ -240,4 +248,105 @@ public class OnlineWidgetRepoPane extends BasicPane { this.componentTabPane.completeEmbedFilter(); } } + + private static class LoadableContentPane extends JPanel { + private enum Status { + LOADING, + DISCONNECTED, + NORMAL + } + private final CardLayout cardLayout; + private final JPanel contentPane; + + public LoadableContentPane(JPanel errorPane) { + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + + this.add(new LoadingPane(), Status.LOADING.name()); + contentPane = new JPanel(); + this.add(contentPane, Status.NORMAL.name()); + this.add(errorPane, Status.DISCONNECTED.name()); + } + + private void switchPane(Status status) { + cardLayout.show(this, status.name()); + } + + public void showLoading() { + switchPane(Status.LOADING); + } + + public void showError() { + switchPane(Status.DISCONNECTED); + } + + public void showContent() { + switchPane(Status.NORMAL); + } + + public JPanel getContentPane() { + return contentPane; + } + } + + private static class DisabledContentPane extends JPanel { + private final CardLayout cardLayout; + + public DisabledContentPane(JPanel contentPane) { + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + + this.add(new MaskPane(), "Disabled"); + this.add(contentPane, "Enabled"); + + MiniComponentShopDialog.getInstance().addWindowAdapter(new WindowAdapter() { + @Override + public void windowOpened(WindowEvent e) { + super.windowOpened(e); + setEnabled(false); + } + + @Override + public void windowClosed(WindowEvent e) { + super.windowClosed(e); + setEnabled(true); + } + }); + + setEnabled(true); + } + + @Override + public void setEnabled(boolean enabled) { + String constrains = enabled ? "Enabled" : "Disabled"; + cardLayout.show(this, constrains); + } + } + + private static class MaskPane extends JPanel { + private static final int PADDING = 30; + private final String text; + private final Style style; + public MaskPane() { + setLayout(new BorderLayout()); + + text = Toolkit.i18nText("Fine-Design_Share_Online_Repo_Pane_Forbidden_Tip"); + style = Style.getInstance(FRFont.getInstance().applyForeground(new Color(0x8F8F92))) + .deriveHorizontalAlignment(SwingConstants.CENTER) + .deriveVerticalAlignment(SwingConstants.CENTER) + .deriveTextStyle(Style.TEXTSTYLE_WRAPTEXT); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + + Graphics2D g2d = (Graphics2D) g; + g.translate(PADDING, 0); + BaseUtils.drawStringStyleInRotation(g2d, this.getWidth() - PADDING * 2, this.getHeight(), text, style, FontTransformUtil.getDesignerFontResolution()); + g.translate(-PADDING, 0); + + } + } + } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java index 52ea26bc26..ca0e8aa6a8 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetTabPane.java @@ -1,18 +1,30 @@ package com.fr.design.mainframe.share.ui.online; import com.fr.design.gui.ibutton.UITabGroup; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.EastRegionContainerPane; +import com.fr.design.mainframe.FormWidgetDetailPane; +import com.fr.design.mainframe.share.ComponentShareUtil; import com.fr.design.mainframe.share.collect.ComponentCollector; import com.fr.design.mainframe.share.sort.OnlineWidgetSortType; -import com.fr.design.mainframe.share.ComponentShareUtil; import com.fr.design.mainframe.share.ui.online.embed.OnlineEmbedFilterShowPane; +import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; import com.fr.design.mainframe.share.ui.online.widgetpackage.OnlineWidgetPackagesShowPane; +import com.fr.design.mainframe.share.util.OnlineShopUtils; import com.fr.form.share.bean.OnlineShareWidget; import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JComponent; import javax.swing.JPanel; +import javax.swing.plaf.basic.BasicButtonUI; import java.awt.BorderLayout; import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.util.ArrayList; import java.util.EventListener; import java.util.List; @@ -24,12 +36,16 @@ public class OnlineWidgetTabPane extends JPanel { private static final String COMPONENT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share"); private static final String COMPONENT_PACKAGE = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Package"); private static final String COMPONENT_EMBED = "COMPONENT_EMBED"; + private static final int COMPONENT_PACKAGE_TAB_INDEX = 0; + private static final int COMPONENT_TAB_INDEX = 1; + private UITabGroup headGroup; private CardLayout cardLayout; private JPanel centerPane; private boolean packagePaneCreated = false; - private List tabChangeListeners; + private final List tabChangeListeners; private OnlineEmbedFilterShowPane embedFilterShowPane; + private OnlineWidgetPackagesShowPane widgetPackagesShowPane; public OnlineWidgetTabPane(OnlineShareWidget[] sharableWidgets, OnlineShareWidget[] sharableWidgetPackage) { tabChangeListeners = new ArrayList<>(); @@ -44,19 +60,20 @@ public class OnlineWidgetTabPane extends JPanel { this.centerPane.add(new OnlineWidgetShowPane(sharableWidgets), COMPONENT); this.centerPane.add( embedFilterShowPane = new OnlineEmbedFilterShowPane(new OnlineWidgetShowPane(sharableWidgets, OnlineWidgetSortType.SALES)), COMPONENT_EMBED); //延迟组件包面板的初始化,防止组件面板里组件的缩略图和组件包面板里组件的缩略图一起加载 - this.headGroup = new UITabGroup(new String[]{COMPONENT, COMPONENT_PACKAGE}) { + this.headGroup = new UITabGroup(new String[]{COMPONENT_PACKAGE, COMPONENT}) { public void tabChanged(int newSelectedIndex) { for (TabChangeListener changeListener : tabChangeListeners) { changeListener.tabChange(newSelectedIndex); } - if (newSelectedIndex == 0) { + if (newSelectedIndex == COMPONENT_TAB_INDEX) { cardLayout.show(centerPane, ComponentShareUtil.needShowEmbedFilterPane() ? COMPONENT_EMBED : COMPONENT); } else { ComponentShareUtil.completeEmbedFilter(); ComponentCollector.getInstance().collectCmpPktClick(); //延迟组件包面板的初始化,防止组件面板里组件和缩略图和组件包面板里组件的缩略图一起加载 if (!packagePaneCreated) { - centerPane.add(new OnlineWidgetPackagesShowPane(sharableWidgetPackages), COMPONENT_PACKAGE); + widgetPackagesShowPane = new OnlineWidgetPackagesShowPane(sharableWidgetPackages); + centerPane.add(widgetPackagesShowPane, COMPONENT_PACKAGE); packagePaneCreated = true; } cardLayout.show(centerPane, COMPONENT_PACKAGE); @@ -64,15 +81,46 @@ public class OnlineWidgetTabPane extends JPanel { } }; - this.headGroup.setSelectedIndex(0); + this.headGroup.setSelectedIndex(COMPONENT_PACKAGE_TAB_INDEX); this.centerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - jPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); - jPanel.add(headGroup, BorderLayout.CENTER); - this.add(jPanel, BorderLayout.NORTH); + JPanel fixedContentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + fixedContentPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + fixedContentPane.add(headGroup, BorderLayout.NORTH); + + fixedContentPane.add(createMiniShopEntryPane(), BorderLayout.CENTER); + this.add(fixedContentPane, BorderLayout.NORTH); this.add(centerPane, BorderLayout.CENTER); } + + + private JPanel createMiniShopEntryPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + JButton button = new JButton(Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Entry_Text")); + button.setPreferredSize(new Dimension(button.getWidth(), 20)); + button.setUI(new BasicButtonUI()); + button.setOpaque(true); + button.setBackground(Color.WHITE); + button.setForeground(new Color(0x419BF9)); + button.setBorder(BorderFactory.createLineBorder(new Color(0x419BF9), 1, true)); + + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (OnlineShopUtils.testConnection() && ComponentShareUtil.isShowMiniShopWindow()) { + MiniComponentShopDialog.getInstance().showFromOnlineRepoPane(); + FormWidgetDetailPane.getInstance().switch2Local(); + FormWidgetDetailPane.getInstance().enterWidgetLib(); + } else { + OnlineWidgetRepoPane.getInstance().switch2InternetErrorPane(); + } + } + }); + container.add(button, BorderLayout.NORTH); + return container; + } + public void completeEmbedFilter(){ if (embedFilterShowPane!= null){ embedFilterShowPane.completeEmbedFilter(); @@ -85,14 +133,18 @@ public class OnlineWidgetTabPane extends JPanel { } } public void refreshPane() { - this.headGroup.setSelectedIndex(0); - this.cardLayout.show(centerPane, ComponentShareUtil.needShowEmbedFilterPane() ? COMPONENT_EMBED : COMPONENT); + this.headGroup.setSelectedIndex(COMPONENT_PACKAGE_TAB_INDEX); + this.cardLayout.show(centerPane, COMPONENT_PACKAGE); } public void refreshShowPaneUI(){ if (embedFilterShowPane != null) { this.embedFilterShowPane.refreshUI(); } + + if (headGroup.getSelectedIndex() == COMPONENT_PACKAGE_TAB_INDEX && widgetPackagesShowPane != null) { + widgetPackagesShowPane.refreshShowPaneUI(); + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/AsyncInstallation.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/AsyncInstallation.java new file mode 100644 index 0000000000..42602b8651 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/AsyncInstallation.java @@ -0,0 +1,38 @@ +package com.fr.design.mainframe.share.ui.online.installation; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/5 + */ +public abstract class AsyncInstallation implements Installation { + private AsyncActionListener actionListener; + + public void setActionListener(AsyncActionListener actionListener) { + this.actionListener = actionListener; + } + + protected void notifyProgress(double value) { + if (this.actionListener != null) { + this.actionListener.onProgress(value); + } + } + protected void notifySuccess() { + if (this.actionListener != null) { + this.actionListener.onSuccess(); + } + } + protected void notifyFailed() { + if (this.actionListener != null) { + this.actionListener.onFailed(); + } + } + + public abstract void cancel(); + + public interface AsyncActionListener { + void onProgress(double value); + void onSuccess(); + void onFailed(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/ComponentInstallation.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/ComponentInstallation.java new file mode 100644 index 0000000000..172bb7d9f3 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/ComponentInstallation.java @@ -0,0 +1,148 @@ +package com.fr.design.mainframe.share.ui.online.installation; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.extra.Process; +import com.fr.design.login.DesignerLoginHelper; +import com.fr.design.login.DesignerLoginSource; +import com.fr.design.mainframe.share.collect.ComponentCollector; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.form.share.Group; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.group.DefaultShareGroup; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.form.share.utils.ShareUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; + +import javax.swing.SwingWorker; +import java.io.File; +import java.io.IOException; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/5 + */ +public class ComponentInstallation extends AsyncInstallation { + private final OnlineShareWidget widget; + private SwingWorker worker; + + public ComponentInstallation(OnlineShareWidget widget) { + this.widget = widget; + } + + @Override + public void install() { + if (!checkLoginStatus()) { + notifyFailed(); + return; + } + notifyProgress(0.0D); + worker = createWorker(); + worker.execute(); + } + + private SwingWorker createWorker() { + return new SwingWorker() { + + @Override + protected Boolean doInBackground() { + + String tempFilePath = fetchRemoteReuFile2TempDir(); + if (StringUtils.isEmpty(tempFilePath)) { + return false; + } + if (isCancelled()) { + return false; + } + ShareComponentUtils.checkReadMe(); + if (isCancelled()) { + return false; + } + installTempReuFile(tempFilePath); + StableUtils.deleteFile(new File(tempFilePath)); + return true; + } + + @Override + protected void done() { + boolean result = false; + try { + result = get(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException | CancellationException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + notifyProgress(0.0D); + if (result) { + notifySuccess(); + } else { + notifyFailed(); + } + } + }; + } + + private boolean checkLoginStatus() { + String userName = DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); + if (StringUtils.isEmpty(userName)) { + DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL); + return false; + } + return true; + } + + private String createLocalReuFilename() { + String filename = widget.getFileLoca(); + if (StringUtils.isEmpty(filename) || !filename.endsWith(".reu")) { + filename = widget.getName() + "." + widget.getUuid() + ".reu"; + } + return filename; + } + + private String fetchRemoteReuFile2TempDir() { + try { + String filename = createLocalReuFilename(); + return DownloadUtils.download(widget.getId(), filename, new Process() { + @Override + public void process(Double value) { + notifyProgress(value); + } + }); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return null; + } + } + + private void installTempReuFile(String tempFilePath) { + File file = new File(tempFilePath); + try { + Group targetGroup = getTargetGroup(); + if (file.exists() && targetGroup.installUniqueIdModule(file)) { + ShareUtils.recordInstallTime(file.getName(), System.currentTimeMillis()); + ComponentCollector.getInstance().collectCmpDownLoad(widget.getUuid()); + } + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + private Group getTargetGroup() { + return DefaultShareGroupManager.getInstance().getGroup(DefaultShareGroup.GROUP_NAME); + } + + @Override + public void cancel() { + if (worker != null) { + worker.cancel(false); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/ComponentsPackageInstallation.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/ComponentsPackageInstallation.java new file mode 100644 index 0000000000..39107a5a11 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/ComponentsPackageInstallation.java @@ -0,0 +1,180 @@ +package com.fr.design.mainframe.share.ui.online.installation; + +import com.fr.design.extra.Process; +import com.fr.design.mainframe.share.ui.base.ImitationProgress; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.share.util.InstallUtils; +import com.fr.design.mainframe.share.util.ShareComponentUtils; +import com.fr.form.share.Group; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StableUtils; +import org.jetbrains.annotations.Nullable; + +import javax.swing.SwingWorker; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/5 + */ +public class ComponentsPackageInstallation extends AsyncInstallation { + private final OnlineShareWidget packageWidget; + private final int childrenCount; + private ImitationThread imitationThread; + private DownLoadSwingWorker worker; + + public ComponentsPackageInstallation(OnlineShareWidget packageWidget, int childrenCount) { + this.packageWidget = packageWidget; + this.childrenCount = childrenCount; + } + + @Override + public void install() { + + final Process downloadProcess = new Process() { + @Override + public void process(Double value) { + notifyProgress(0.8 * value); + } + }; + final Process installProcess = new Process() { + + @Override + public void process(Double value) { + notifyProgress(0.8 + 0.2 * value); + } + }; + + downloadProcess.process(0.0D); + + //假进度线程 + final ImitationProgress imitationProgress = new ImitationProgress(downloadProcess, childrenCount); + imitationThread = new ImitationThread(imitationProgress); + imitationThread.setName("Component-ImitationProcessThread"); + + //下载线程 + worker = new DownLoadSwingWorker(installProcess, packageWidget); + + imitationThread.start(); + worker.execute(); + } + + @Override + public void cancel() { + if (imitationThread != null) { + imitationThread.interrupt(); + } + if (worker != null) { + worker.cancel(false); + } + } + + /** + * 假进度线程 + */ + private static class ImitationThread extends Thread { + + private final ImitationProgress imitationProgress; + + public ImitationThread(ImitationProgress progress) { + imitationProgress = progress; + } + + @Override + public void run() { + imitationProgress.start(); + } + + public void complete() { + imitationProgress.completed(); + this.interrupt(); + } + + public void stopThread() { + imitationProgress.stop(); + this.interrupt(); + } + } + + private class DownLoadSwingWorker extends SwingWorker { + final Process installProcess; + final OnlineShareWidget onlineShareWidget; + + public DownLoadSwingWorker(Process installProcess, OnlineShareWidget onlineShareWidget) { + this.installProcess = installProcess; + this.onlineShareWidget = onlineShareWidget; + } + + @Override + @Nullable + protected Group doInBackground() { + final String filePath; + List failureList = new ArrayList<>(); + try { + filePath = DownloadUtils.downloadPackage(onlineShareWidget.getId(), onlineShareWidget.getName(), DownLoadSwingWorker.this::isCancelled); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + imitationThread.stopThread(); + return null; + } + if (this.isCancelled()) { + imitationThread.stopThread(); + StableUtils.deleteFile(new File(filePath)); + return null; + } + + //等待假进度线程结束 + imitationThread.complete(); + try { + imitationThread.join(); + } catch (InterruptedException ignore) { + } + + //再判断一次 + if (this.isCancelled()) { + StableUtils.deleteFile(new File(filePath)); + return null; + } + ShareComponentUtils.checkReadMe(); + //安装 + File file = new File(filePath); + installProcess.process(0.0D); + InstallUtils.InstallResult result = null; + try { + if (file.exists()) { + result = InstallUtils.installReusFile(file, System.currentTimeMillis(), failureList, installProcess); + } + } finally { + //删掉下载组件的目录 + StableUtils.deleteFile(file); + } + return result == null ? null : result.group; + } + + @Override + protected void done() { + Group group = null; + try { + group = get(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException | CancellationException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + notifyProgress(0.0D); + if (group != null) { + notifySuccess(); + } else { + notifyFailed(); + } + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/Installation.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/Installation.java new file mode 100644 index 0000000000..3fc80a8bfd --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/Installation.java @@ -0,0 +1,10 @@ +package com.fr.design.mainframe.share.ui.online.installation; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/5 + */ +public interface Installation { + void install(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/TemplateThemeInstallation.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/TemplateThemeInstallation.java new file mode 100644 index 0000000000..4de568db7f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/installation/TemplateThemeInstallation.java @@ -0,0 +1,210 @@ +package com.fr.design.mainframe.share.ui.online.installation; + +import com.fr.base.theme.FormTheme; +import com.fr.base.theme.FormThemeConfig; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.design.DesignerEnvManager; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.i18n.Toolkit; +import com.fr.design.login.DesignerLoginHelper; +import com.fr.design.login.DesignerLoginSource; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.theme.dialog.TemplateThemeUsingDialog; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; +import com.fr.transaction.CallBackAdaptor; +import com.fr.workspace.WorkContext; + +import javax.swing.JOptionPane; +import javax.swing.SwingWorker; +import java.awt.Window; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.HashMap; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/5 + */ +public class TemplateThemeInstallation extends AsyncInstallation { + private final Window parentWindow; + private final String themePath; + private SwingWorker worker; + + public TemplateThemeInstallation(Window parentWindow, String themePath) { + this.parentWindow = parentWindow; + this.themePath = themePath; + } + + public TemplateThemeInstallation(String themePath) { + this(DesignerContext.getDesignerFrame(), themePath); + } + + @Override + public void install() { + fetchTheme(); + } + + private void fetchTheme() { + if (!checkAuthority()) { + onThemeFetched(null); + return; + } + + worker = new SwingWorker() { + + @Override + protected FormTheme doInBackground() { + return DownloadUtils.downloadThemeFile(themePath); + } + + @Override + protected void done() { + FormTheme theme = null; + try { + theme = get(); + } catch (InterruptedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + Thread.currentThread().interrupt(); + } catch (ExecutionException | CancellationException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + onThemeFetched(theme); + } + }; + worker.execute(); + } + + private boolean checkAuthority() { + if (!WorkContext.getCurrent().isRoot()) { + FineJOptionPane.showMessageDialog(parentWindow, + Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Message"), + Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Title"), + JOptionPane.WARNING_MESSAGE); + return false; + } + + String userName = DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); + if (StringUtils.isEmpty(userName)) { + DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL, new HashMap<>(), parentWindow); + return false; + } + + return true; + } + + public void onThemeFetched(FormTheme theme) { + if (theme == null) { + notifyFailed(); + return; + } + saveTheme(theme); + } + + private FormTheme ensureThemeHasUniqueName(FormTheme theme, String expectedName) { + if (!FormThemeConfig.getInstance().contains(expectedName)) { + theme.setName(expectedName); + return theme; + } else { + String newName = (String) FineJOptionPane.showInputDialog( + parentWindow, + Toolkit.i18nText("Fine-Design_Share_Rename_Suitable_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Rename"), + FineJOptionPane.QUESTION_MESSAGE, null, null, + expectedName); + + return StringUtils.isEmpty(newName) ? null : ensureThemeHasUniqueName(theme, newName); + } + } + + private void saveTheme(FormTheme theme) { + final FormTheme uniqueNamedTheme = ensureThemeHasUniqueName(theme, theme.getName()); + if (uniqueNamedTheme != null) { + FormThemeConfig.getInstance().addTheme(theme, true, new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + onThemeSaved(uniqueNamedTheme); + } + + @Override + public void afterRollback() { + super.afterRollback(); + onThemeSaved(null); + } + }); + } else { + onThemeSaved(null); + } + } + + public void onThemeSaved(FormTheme theme) { + if (theme == null) { + notifyFailed(); + return; + } + + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (currentTemplate.getUsingTemplateThemeConfig() instanceof FormThemeConfig) { + TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(parentWindow); + dialog.addWindowListener(new UsingDialogAdapter(theme, currentTemplate)); + dialog.setVisible(true); + } else { + FineJOptionPane.showConfirmDialog( + MiniComponentShopDialog.getInstance().getWindow(), + Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_Success_Tip"), + "", + FineJOptionPane.YES_NO_OPTION + ); + } + notifySuccess(); + } + + public void applyTheme(JTemplate template, final String name, Window dialog) { + TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); + TemplateTheme theme = config.cachedFetch(name); + template.setTemplateTheme(theme); + dialog.repaint(); + } + + @Override + public void cancel() { + if (worker != null) { + worker.cancel(true); + } + } + + private class UsingDialogAdapter extends WindowAdapter { + private final FormTheme theme; + private final JTemplate currentFormTemplate; + + public UsingDialogAdapter(FormTheme theme, JTemplate currentFormTemplate) { + this.theme = theme; + this.currentFormTemplate = currentFormTemplate; + } + + @Override + public void windowOpened(WindowEvent e) { + super.windowOpened(e); + Window window = e.getWindow(); + int returnVal = FineJOptionPane.showConfirmDialog( + window, + Toolkit.i18nText("Fine-Design_Share_Apply_Suitable_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), + FineJOptionPane.OK_CANCEL_OPTION); + if (returnVal == JOptionPane.YES_OPTION) { + applyTheme(currentFormTemplate, theme.getName(), window); + } + window.removeWindowListener(this); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopDialog.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopDialog.java new file mode 100644 index 0000000000..be2d724667 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopDialog.java @@ -0,0 +1,139 @@ +package com.fr.design.mainframe.share.ui.online.mini; + +import com.fr.base.ScreenResolution; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.mini.MiniShopDisposingChecker; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.stable.Constants; +import com.fr.stable.unit.FU; +import com.fr.stable.unit.UNIT; + +import javax.swing.JFrame; +import java.awt.Container; +import java.awt.Window; +import java.awt.event.WindowEvent; +import java.awt.event.WindowListener; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/4 + */ +public class MiniComponentShopDialog { + private static class HOLDER { + private static final MiniComponentShopDialog singleton = new MiniComponentShopDialog(); + } + public static MiniComponentShopDialog getInstance() { + return MiniComponentShopDialog.HOLDER.singleton; + } + + private final Set windowListeners = new HashSet<>(); + private JFrame frame; + + private JFrame createFrame() { + final JFrame frame = new JFrame(); + final MiniComponentShopPane shopPane = new MiniComponentShopPane(); + + final UNIT width = FU.getInstance(900 * Constants.FU_PER_OLD_PIX); + final UNIT height = FU.getInstance(600 * Constants.FU_PER_OLD_PIX); + int resolution = ScreenResolution.getScreenResolution(); + frame.setSize(width.toPixI(resolution), height.toPixI(resolution)); + frame.setTitle(Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Window_Title")); + frame.add(shopPane); + frame.setResizable(false); + frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); + frame.addWindowListener(new WindowListener() { + @Override + public void windowOpened(WindowEvent e) { + for (WindowListener listener: windowListeners) { + listener.windowOpened(e); + } + } + + @Override + public void windowClosing(WindowEvent e) { + for (WindowListener listener : windowListeners) { + listener.windowClosing(e); + } + if (MiniShopDisposingChecker.check(frame.getContentPane())) { + e.getWindow().dispose(); + } + } + + @Override + public void windowClosed(WindowEvent e) { + for (WindowListener listener: windowListeners) { + listener.windowClosed(e); + } + shopPane.reload(); + } + + @Override + public void windowIconified(WindowEvent e) { + for (WindowListener listener: windowListeners) { + listener.windowIconified(e); + } + } + + @Override + public void windowDeiconified(WindowEvent e) { + for (WindowListener listener: windowListeners) { + listener.windowDeiconified(e); + } + } + + @Override + public void windowActivated(WindowEvent e) { + for (WindowListener listener: windowListeners) { + listener.windowActivated(e); + } + } + + @Override + public void windowDeactivated(WindowEvent e) { + for (WindowListener listener: windowListeners) { + listener.windowDeactivated(e); + } + } + }); + GUICoreUtils.centerWindow(frame); + return frame; + } + + public void show() { + if (frame == null) { + frame = createFrame(); + } + if (!frame.isVisible()) { + for (WindowListener listener: windowListeners) { + listener.windowOpened(null); + } + } + frame.setVisible(true); + } + + public void showFromOnlineRepoPane() { + show(); + } + + public Container getContentPane() { + if (frame != null) { + return frame.getContentPane(); + } + return null; + } + + public Window getWindow() { + return frame; + } + + public void addWindowAdapter(WindowListener windowListener) { + windowListeners.add(windowListener); + if (frame != null) { + frame.removeWindowListener(windowListener); + frame.addWindowListener(windowListener); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopPane.java new file mode 100644 index 0000000000..f9d3849f78 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/MiniComponentShopPane.java @@ -0,0 +1,85 @@ +package com.fr.design.mainframe.share.ui.online.mini; + +import com.fr.design.mainframe.share.ui.online.mini.bridge.ComposedNativeBridges; +import com.fr.design.mainframe.share.util.OnlineShopUtils; +import com.fr.design.ui.ModernUIPane; +import com.fr.design.ui.compatible.ModernUIPaneFactory; +import com.fr.design.upm.event.CertificateEvent; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; +import com.teamdev.jxbrowser.chromium.JSObject; +import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; +import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; +import com.teamdev.jxbrowser.js.JsObject; +import org.jetbrains.annotations.Nullable; + +import javax.swing.JPanel; +import java.awt.BorderLayout; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/12/20 + */ +public class MiniComponentShopPane extends JPanel { + private final ModernUIPane modernUIPane; + private final Listener loginListener; + private final Listener logoutListener; + + public MiniComponentShopPane() { + setLayout(new BorderLayout()); + modernUIPane = ModernUIPaneFactory.modernUIPaneBuilder() + .withURL(OnlineShopUtils.getWebMiniShopPath()) + .prepareForV6(new ScriptContextAdapter() { + @Override + public void onScriptContextCreated(ScriptContextEvent event) { + super.onScriptContextCreated(event); + JSObject window = event.getBrowser().executeJavaScriptAndReturnValue("window").asObject(); + window.setProperty("ShopHelper", new ComposedNativeBridges(window)); + } + }) + .prepareForV7(new InjectJsCallback() { + @Nullable + @Override + public Response on(Params params) { + // 7.x + JsObject window = params.frame().executeJavaScript("window"); + if (window != null) { + window.putProperty("ShopHelper", new ComposedNativeBridges(window)); + } + return InjectJsCallback.Response.proceed(); + } + }) + .build(); + + add(modernUIPane, BorderLayout.CENTER); + + loginListener = new Listener() { + @Override + public void on(Event event, String param) { + reload(); + } + }; + logoutListener = new Listener() { + @Override + public void on(Event event, String param) { + reload(); + } + }; + + EventDispatcher.listen(CertificateEvent.LOGIN, loginListener); + EventDispatcher.listen(CertificateEvent.LOGOUT, logoutListener); + } + + public void dispose() { + modernUIPane.disposeBrowser(); + EventDispatcher.stopListen(loginListener); + EventDispatcher.stopListen(logoutListener); + } + + public void reload() { + modernUIPane.redirect(OnlineShopUtils.getWebMiniShopPath()); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/ComposedNativeBridges.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/ComposedNativeBridges.java new file mode 100644 index 0000000000..3a09774c53 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/ComposedNativeBridges.java @@ -0,0 +1,29 @@ +package com.fr.design.mainframe.share.ui.online.mini.bridge; + +import com.teamdev.jxbrowser.chromium.JSAccessible; +import com.teamdev.jxbrowser.js.JsAccessible; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/12/20 + */ +public class ComposedNativeBridges { + @JSAccessible + @JsAccessible + public final Object Browser; + + @JSAccessible + @JsAccessible + public final Object Auth; + + @JSAccessible + @JsAccessible + public final Object Product; + + public ComposedNativeBridges(Object window) { + this.Browser = new NativeBrowserBridge(); + this.Auth = new NativeAuthBridge(); + this.Product = new NativeProductBridge(window); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeAuthBridge.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeAuthBridge.java new file mode 100644 index 0000000000..42f3a6c655 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeAuthBridge.java @@ -0,0 +1,37 @@ +package com.fr.design.mainframe.share.ui.online.mini.bridge; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.bridge.exec.JSBridge; +import com.fr.design.login.DesignerLoginHelper; +import com.fr.design.login.DesignerLoginSource; +import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; +import com.teamdev.jxbrowser.chromium.JSAccessible; +import com.teamdev.jxbrowser.js.JsAccessible; + +import java.awt.Window; +import java.util.HashMap; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/12/20 + */ +public class NativeAuthBridge { + @JSAccessible + @JsAccessible + @JSBridge + public String getLoginUsername() { + return DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); + } + + @JSAccessible + @JsAccessible + @JSBridge + public void goLogin() { + Window parentWindow = MiniComponentShopDialog.getInstance().getWindow(); + if (parentWindow != null) { + parentWindow.toFront(); + DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL, new HashMap<>(), parentWindow); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeBrowserBridge.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeBrowserBridge.java new file mode 100644 index 0000000000..ee77a8b95a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeBrowserBridge.java @@ -0,0 +1,26 @@ +package com.fr.design.mainframe.share.ui.online.mini.bridge; + +import com.fr.design.bridge.exec.JSBridge; +import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; +import com.teamdev.jxbrowser.chromium.JSAccessible; +import com.teamdev.jxbrowser.js.JsAccessible; + +import java.awt.Window; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/12/20 + */ +public class NativeBrowserBridge { + + @JSAccessible + @JsAccessible + @JSBridge + public void dispose() { + Window nativeWindow = MiniComponentShopDialog.getInstance().getWindow(); + if (nativeWindow != null) { + nativeWindow.dispose(); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java new file mode 100644 index 0000000000..e6a4f720cc --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeProductBridge.java @@ -0,0 +1,512 @@ + +package com.fr.design.mainframe.share.ui.online.mini.bridge; + +import com.fr.design.bridge.exec.JSBridge; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.EastRegionContainerPane; +import com.fr.design.mainframe.FormWidgetDetailPane; +import com.fr.design.mainframe.share.ui.local.LocalWidgetRepoPane; +import com.fr.design.mainframe.share.ui.online.installation.AsyncInstallation; +import com.fr.design.mainframe.share.ui.online.installation.ComponentInstallation; +import com.fr.design.mainframe.share.ui.online.installation.ComponentsPackageInstallation; +import com.fr.design.mainframe.share.ui.online.installation.TemplateThemeInstallation; +import com.fr.design.mainframe.share.ui.online.mini.MiniComponentShopDialog; +import com.fr.design.mainframe.share.util.OnlineShopUtils; +import com.fr.form.share.Group; +import com.fr.form.share.SharableWidgetProvider; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.form.share.group.DefaultShareGroupManager; +import com.fr.json.JSONObject; +import com.fr.stable.StringUtils; +import com.teamdev.jxbrowser.chromium.JSAccessible; +import com.teamdev.jxbrowser.js.JsAccessible; + +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; +import java.awt.Window; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/12/20 + */ +public class NativeProductBridge { + private static final Map createdComponentInstallationTasks = new HashMap<>(); + private static final Map createdComponentsPackageInstallationTasks = new HashMap<>(); + private static final Map createdTemplateThemeInstallationTasks = new HashMap<>(); + + private static final Map startedComponentInstallationTasks = new HashMap<>(); + private static final Map startedComponentsPackageInstallationTasks = new HashMap<>(); + private static final Map startedTemplateThemeInstallationTasks = new HashMap<>(); + + private final Object window; + + private final Map> componentDownloadTaskStartListeners = new HashMap<>(); + private final Map> componentsPackageDownloadTaskStartListeners = new HashMap<>(); + private final Map> themeDownloadTaskStartListeners = new HashMap<>(); + + public NativeProductBridge(Object window) { + this.window = window; + } + + @JSAccessible + @JsAccessible + @JSBridge + public boolean isProductDownloaded(String uuid) { + for (Group group : DefaultShareGroupManager.getInstance().getAllGroup()) { + SharableWidgetProvider[] widgetProviderList = group.getAllBindInfoList(); + for (SharableWidgetProvider widget: widgetProviderList) { + if (StringUtils.equals(uuid, widget.getId())) { + return true; + } + } + } + return false; + } + + @JSAccessible + @JsAccessible + @JSBridge + public void addProductDownloadTaskStartListener(String json, Object function) { + JSONObject object = new JSONObject(json); + OnlineShareWidget widget = OnlineShareWidget.parseFromJSONObject(object); + String uuid = widget.getUuid(); + boolean isPackage = widget.isWidgetPackage(); + + Map> downloadTaskGetters = + isPackage ? componentsPackageDownloadTaskStartListeners : componentDownloadTaskStartListeners; + Set startListeners = downloadTaskGetters.get(widget.getUuid()); + if (startListeners == null) { + startListeners = new HashSet<>(); + } + startListeners.add(function); + downloadTaskGetters.put(widget.getUuid(), startListeners); + + + } + + @JSAccessible + @JsAccessible + @JSBridge + public void removeProductDownloadTaskStartListener(String json, Object function) { + JSONObject object = new JSONObject(json); + OnlineShareWidget widget = OnlineShareWidget.parseFromJSONObject(object); + String uuid = widget.getUuid(); + boolean isPackage = widget.isWidgetPackage(); + + Map> downloadTaskGetters = isPackage ? componentsPackageDownloadTaskStartListeners : componentDownloadTaskStartListeners; + + Set startListeners = downloadTaskGetters.get(uuid); + if (startListeners == null) { + startListeners = new HashSet<>(); + } + startListeners.remove(function); + downloadTaskGetters.put(uuid, startListeners); + } + + @JSAccessible + @JsAccessible + @JSBridge + public Object getExecutingProductDownloadTask(String json) { + JSONObject object = new JSONObject(json); + OnlineShareWidget widget = OnlineShareWidget.parseFromJSONObject(object); + String uuid = widget.getUuid(); + boolean isPackage = widget.isWidgetPackage(); + + Map executingDownloadTask = + isPackage ? startedComponentsPackageInstallationTasks : startedComponentInstallationTasks; + NativeTaskBridge task = executingDownloadTask.get(uuid); + if (task != null) { + task.checkJSEnvChange(this.window); + } + return task; + } + + @JSAccessible + @JsAccessible + @JSBridge + public Object createProductDownloadTask(String json) { + JSONObject object = new JSONObject(json); + OnlineShareWidget widget = OnlineShareWidget.parseFromJSONObject(object); + int childrenCount = object.optInt("pkgsize", 0); + if (childrenCount > 0) { + if (createdComponentsPackageInstallationTasks.containsKey(widget.getUuid())) { + return createdComponentsPackageInstallationTasks.get(widget.getUuid()); + } else { + ComponentsPackageInstallationTask task = new ComponentsPackageInstallationTask(this, window, widget, childrenCount); + createdComponentsPackageInstallationTasks.put(widget.getUuid(), task); + return task; + } + + } else { + if (createdComponentInstallationTasks.containsKey(widget.getUuid())) { + return createdComponentInstallationTasks.get(widget.getUuid()); + } else { + ComponentInstallationTask task = new ComponentInstallationTask(this, window, widget); + createdComponentInstallationTasks.put(widget.getUuid(), task); + return task; + } + } + } + + @JSAccessible + @JsAccessible + @JSBridge + public void addThemeDownloadTaskStartListener(String themePath, Object function) { + Set startListeners = themeDownloadTaskStartListeners.get(themePath); + if (startListeners == null) { + startListeners = new HashSet<>(); + } + startListeners.add(function); + themeDownloadTaskStartListeners.put(themePath, startListeners); + } + + @JSAccessible + @JsAccessible + @JSBridge + public void removeThemeDownloadTaskStartListener(String themePath, Object function) { + Set startListeners = themeDownloadTaskStartListeners.get(themePath); + if (startListeners == null) { + startListeners = new HashSet<>(); + } + startListeners.remove(function); + themeDownloadTaskStartListeners.put(themePath, startListeners); + } + + @JSAccessible + @JsAccessible + @JSBridge + public Object getExecutingThemeDownloadTask(String themePath) { + NativeTaskBridge task = startedTemplateThemeInstallationTasks.get(themePath); + if (task != null) { + task.checkJSEnvChange(this.window); + } + return task; + } + + @JSAccessible + @JsAccessible + @JSBridge + public Object createTemplateThemeDownloadTask(String themePath) { + if (createdTemplateThemeInstallationTasks.containsKey(themePath)) { + return createdTemplateThemeInstallationTasks.get(themePath); + } else { + TemplateThemeInstallationTask task = new TemplateThemeInstallationTask(this, window, themePath); + createdTemplateThemeInstallationTasks.put(themePath, task); + return task; + } + } + + public static class ComponentInstallationTask extends NativeTaskBridge { + private final NativeProductBridge env; + private final OnlineShareWidget widget; + private final ComponentInstallation action; + + public ComponentInstallationTask(NativeProductBridge env, Object window, OnlineShareWidget widget) { + super(window); + this.env = env; + this.widget = widget; + action = new ComponentInstallation(widget); + action.setActionListener(new AsyncInstallation.AsyncActionListener() { + @Override + public void onProgress(double value) { + fireProgressEvent(Double.toString(value)); + } + + @Override + public void onSuccess() { + fireSuccessEvent(null); + LocalWidgetRepoPane.getInstance().refreshPane(); + if (!DesignerContext.getDesignerFrame().isActive()) { + FormWidgetDetailPane.getInstance().switch2Local(); + EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); + } + } + + @Override + public void onFailed() { + fireFailureEvent(null); + } + }); + } + + @JSAccessible + @JsAccessible + @JSBridge + @Override + public void execute() { + if (isExecuting) { + return; + } + super.execute(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + boolean allowedDownload = true; + if (!widget.isCompatibleWithCurrentEnv()) { + int result = FineJOptionPane.showConfirmDialog( + MiniComponentShopDialog.getInstance().getContentPane(), + Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Incompatible_Component_Tip"), + "", + FineJOptionPane.YES_NO_OPTION + ); + allowedDownload = result == JOptionPane.YES_OPTION; + } + if (allowedDownload) { + fireStartEvent(null); + action.install(); + } else { + fireFailureEvent(null); + } + } + }); + } + + @JSAccessible + @JsAccessible + @JSBridge + @Override + public void cancel() { + super.cancel(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + action.cancel(); + } + }); + } + + @Override + protected void fireStartEvent(String event) { + startedComponentInstallationTasks.put(widget.getUuid(), this); + Set startListeners = env.componentDownloadTaskStartListeners.get(widget.getUuid()); + SafeJSFunctionInvoker.invoke(startListeners, env.window); + super.fireStartEvent(event); + } + + @Override + protected void fireFailureEvent(String event) { + startedComponentInstallationTasks.remove(widget.getUuid()); + createdComponentInstallationTasks.remove(widget.getUuid()); + super.fireFailureEvent(event); + } + + @Override + protected void fireSuccessEvent(String event) { + startedComponentInstallationTasks.remove(widget.getUuid()); + createdComponentInstallationTasks.remove(widget.getUuid()); + super.fireSuccessEvent(event); + } + } + + public static class ComponentsPackageInstallationTask extends NativeTaskBridge { + + private final NativeProductBridge env; + private final ComponentsPackageInstallation action; + private final OnlineShareWidget widget; + private final int childrenCount; + + public ComponentsPackageInstallationTask(NativeProductBridge env, Object window, OnlineShareWidget widget, int childrenCount) { + super(window); + this.env = env; + this.widget = widget; + this.childrenCount = childrenCount; + action = new ComponentsPackageInstallation(widget, childrenCount); + action.setActionListener(new AsyncInstallation.AsyncActionListener() { + @Override + public void onProgress(double value) { + fireProgressEvent(Double.toString(value)); + } + + @Override + public void onSuccess() { + fireSuccessEvent(null); + LocalWidgetRepoPane.getInstance().refreshPane(); + if (!DesignerContext.getDesignerFrame().isActive()) { + FormWidgetDetailPane.getInstance().switch2Local(); + EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); + } + } + + @Override + public void onFailed() { + fireFailureEvent(null); + } + }); + } + + @JSAccessible + @JsAccessible + @JSBridge + @Override + public void execute() { + if (isExecuting) { + return; + } + super.execute(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + boolean allowedDownload; + OnlineShareWidget[] childrenWidgets = OnlineShopUtils.getPackageWidgets(widget, false); + boolean isCompatibleWithCurrentEnv = true; + for (OnlineShareWidget children: childrenWidgets) { + if (!children.isCompatibleWithCurrentEnv()) { + isCompatibleWithCurrentEnv = false; + break; + } + } + int result; + if (!isCompatibleWithCurrentEnv) { + result = FineJOptionPane.showConfirmDialog( + MiniComponentShopDialog.getInstance().getContentPane(), + Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Incompatible_Components_Package_Tip", childrenCount), + "", + FineJOptionPane.YES_NO_OPTION + ); + } else { + result = FineJOptionPane.showConfirmDialog( + MiniComponentShopDialog.getInstance().getContentPane(), + Toolkit.i18nText("Fine-Design_Share_Online_Mini_Shop_Download_Components_Package_Tip", childrenCount), + "", + FineJOptionPane.YES_NO_OPTION + ); + } + allowedDownload = result == JOptionPane.YES_OPTION; + if (allowedDownload) { + fireStartEvent(null); + action.install(); + } else { + fireFailureEvent(null); + } + } + }); + } + + @JSAccessible + @JsAccessible + @JSBridge + @Override + public void cancel() { + super.cancel(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + action.cancel(); + } + }); + } + + @Override + protected void fireStartEvent(String event) { + startedComponentsPackageInstallationTasks.put(widget.getUuid(), this); + super.fireStartEvent(event); + + Set startListeners = env.componentsPackageDownloadTaskStartListeners.get(widget.getUuid()); + SafeJSFunctionInvoker.invoke(startListeners, env.window); + } + + @Override + protected void fireFailureEvent(String event) { + startedComponentsPackageInstallationTasks.remove(widget.getUuid()); + createdComponentsPackageInstallationTasks.remove(widget.getUuid()); + super.fireFailureEvent(event); + } + + @Override + protected void fireSuccessEvent(String event) { + startedComponentsPackageInstallationTasks.remove(widget.getUuid()); + createdComponentsPackageInstallationTasks.remove(widget.getUuid()); + super.fireSuccessEvent(event); + } + } + + public static class TemplateThemeInstallationTask extends NativeTaskBridge { + private final NativeProductBridge env; + private final String themePath; + private final TemplateThemeInstallation action; + public TemplateThemeInstallationTask(NativeProductBridge env, Object window, String themePath) { + super(window); + this.env = env; + this.themePath = themePath; + Window miniShopWindow = MiniComponentShopDialog.getInstance().getWindow(); + action = new TemplateThemeInstallation(miniShopWindow, themePath); + action.setActionListener(new AsyncInstallation.AsyncActionListener() { + @Override + public void onProgress(double value) { + fireProgressEvent(Double.toString(value)); + } + + @Override + public void onSuccess() { + fireSuccessEvent(null); + } + + @Override + public void onFailed() { + fireFailureEvent(null); + } + }); + } + + @JSAccessible + @JsAccessible + @JSBridge + @Override + public void execute() { + if (isExecuting) { + return; + } + super.execute(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + fireStartEvent(null); + action.install(); + } + }); + } + + @JSAccessible + @JsAccessible + @JSBridge + @Override + public void cancel() { + super.cancel(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + action.cancel(); + } + }); + } + + @Override + protected void fireStartEvent(String event) { + startedTemplateThemeInstallationTasks.put(themePath, this); + Set startListeners = env.themeDownloadTaskStartListeners.get(themePath); + SafeJSFunctionInvoker.invoke(startListeners, env.window); + super.fireStartEvent(event); + } + + @Override + protected void fireFailureEvent(String event) { + startedTemplateThemeInstallationTasks.remove(themePath); + createdTemplateThemeInstallationTasks.remove(themePath); + super.fireFailureEvent(event); + } + + @Override + protected void fireSuccessEvent(String event) { + startedTemplateThemeInstallationTasks.remove(themePath); + createdTemplateThemeInstallationTasks.remove(themePath); + super.fireSuccessEvent(event); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeTaskBridge.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeTaskBridge.java new file mode 100644 index 0000000000..2929a35408 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/NativeTaskBridge.java @@ -0,0 +1,84 @@ +package com.fr.design.mainframe.share.ui.online.mini.bridge; + +import com.fr.design.bridge.exec.JSBridge; +import com.fr.design.mainframe.share.mini.MiniShopNativeTask; +import com.fr.design.mainframe.share.mini.MiniShopNativeTaskManager; +import com.teamdev.jxbrowser.chromium.JSAccessible; +import com.teamdev.jxbrowser.js.JsAccessible; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/12/20 + */ +public class NativeTaskBridge implements MiniShopNativeTask { + + private Object window; + protected final Set statusCbs = new HashSet<>(); + protected boolean isExecuting = false; + + public NativeTaskBridge(Object window) { + this.window = window; + } + + public void checkJSEnvChange(Object window) { + if (this.window != window) { + this.window = window; + this.statusCbs.clear(); + } + } + + @JSBridge + @JSAccessible + @JsAccessible + public void addStatusCallback(Object cb) { + this.statusCbs.add(cb); + } + + @JSBridge + @JSAccessible + @JsAccessible + public void removeStatusCallback(Object cb) { + this.statusCbs.remove(cb); + } + + @JSBridge + @JSAccessible + @JsAccessible + @Override + public void execute() { + if (!isExecuting) { + isExecuting = true; + } + } + + @JSBridge + @JSAccessible + @JsAccessible + @Override + public void cancel() { + MiniShopNativeTaskManager.getInstance().removeCompletedTask(this); + fireFailureEvent(null); + } + + protected void fireStartEvent(String event) { + MiniShopNativeTaskManager.getInstance().addStartedTask(this); + SafeJSFunctionInvoker.invoke(statusCbs, window, "START", event); + } + protected void fireProgressEvent(String event) { + SafeJSFunctionInvoker.invoke(statusCbs, window, "PROGRESS", event); + } + protected void fireSuccessEvent(String event) { + isExecuting = false; + MiniShopNativeTaskManager.getInstance().removeCompletedTask(this); + SafeJSFunctionInvoker.invoke(statusCbs, window, "SUCCESS", event); + } + protected void fireFailureEvent(String event) { + isExecuting = false; + MiniShopNativeTaskManager.getInstance().removeCompletedTask(this); + SafeJSFunctionInvoker.invoke(statusCbs, window, "FAILURE", event); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/SafeJSFunctionInvoker.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/SafeJSFunctionInvoker.java new file mode 100644 index 0000000000..e5bf71da87 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/mini/bridge/SafeJSFunctionInvoker.java @@ -0,0 +1,44 @@ +package com.fr.design.mainframe.share.ui.online.mini.bridge; + +import com.teamdev.jxbrowser.chromium.JSFunction; +import com.teamdev.jxbrowser.chromium.JSObject; +import com.teamdev.jxbrowser.js.JsFunction; +import com.teamdev.jxbrowser.js.JsObject; + +import java.util.Collection; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/17 + */ +public class SafeJSFunctionInvoker { + + public static void invoke(Collection functions, Object instance, Object... args) { + if (functions != null) { + for (Object function: functions) { + invoke(function, instance, args); + } + } + } + + public static void invoke(Object function, Object instance, Object... args) { + if (function != null) { + if (function instanceof JSFunction && instance instanceof JSObject) { + invokeV6((JSFunction) function, (JSObject) instance, args); + } else if (function instanceof JsFunction && instance instanceof JsObject) { + invokeV7((JsFunction) function, (JsObject) instance, args); + } + } + } + + private static void invokeV6(JSFunction function, JSObject instance, Object... args) { + if (!function.getContext().isDisposed()) { + function.invoke(instance, args); + } + } + + private static void invokeV7(JsFunction function, JsObject instance, Object... args) { + function.invoke(instance, args); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java index 1697593627..d133cd0583 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java @@ -48,6 +48,7 @@ public class OnlineWidgetPackagesShowPane extends AbstractOnlineWidgetShowPane { private JPanel detailPane; private String currentPackageId; private OnlineWidgetSelectPane onlineWidgetSelectPane; + private OnlineDownloadPackagePane onlineDownloadPackagePane; private UILabel downloadLabel; private final Map cachePanelMap = new HashMap<>(); @@ -109,15 +110,15 @@ public class OnlineWidgetPackagesShowPane extends AbstractOnlineWidgetShowPane { private void downLoadPackage() { downloadLabel.setVisible(false); detailPane.removeAll(); - OnlineDownloadPackagePane widgetSelectPane = new OnlineDownloadPackagePane(this, onlineWidgetSelectPane.getSharableWidgetProviders(), 50); - detailPane.add(widgetSelectPane, BorderLayout.CENTER); + onlineDownloadPackagePane = new OnlineDownloadPackagePane(this, onlineWidgetSelectPane.getSharableWidgetProviders(), 50); + detailPane.add(onlineDownloadPackagePane, BorderLayout.CENTER); cardLayout.show(centerPane, WIDGET_DETAIL); - cachePanelMap.put(currentPackageId, widgetSelectPane); + cachePanelMap.put(currentPackageId, onlineDownloadPackagePane); for (OnlineShareWidget onlineShareWidget : getSharableWidgetProviders()) { if (StringUtils.equals(onlineShareWidget.getId(), currentPackageId)) { - widgetSelectPane.downloadWidget(onlineShareWidget); + onlineDownloadPackagePane.downloadWidget(onlineShareWidget); break; } } @@ -193,4 +194,10 @@ public class OnlineWidgetPackagesShowPane extends AbstractOnlineWidgetShowPane { protected FilterPane createFilterPane() { return FilterPane.createOnlinePackageFilterPane(); } + + public void refreshShowPaneUI() { + if (onlineDownloadPackagePane != null && onlineDownloadPackagePane.isShowing()) { + onlineDownloadPackagePane.refreshShowPaneUI(); + } + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/OnlineShopUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/OnlineShopUtils.java index 7341d7cbb6..fef0caed2c 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/OnlineShopUtils.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/OnlineShopUtils.java @@ -42,6 +42,10 @@ public class OnlineShopUtils { } + public static String getWebMiniShopPath() { + return ComponentReuseConfigManager.getInstance().getWebMiniShopUrl(); + } + public static String getReuInfoPath() { return ComponentReuseConfigManager.getInstance().getMiniShopUrl(); } @@ -252,7 +256,12 @@ public class OnlineShopUtils { } public static OnlineShareWidget[] getPackageWidgets(OnlineShareWidget widgetPackage) { - String plistUrl = getPackageChildrenPath() + widgetPackage.getId() + "?designerVersion="+ ProductConstants.RELEASE_VERSION; + return getPackageWidgets(widgetPackage, true); + } + + public static OnlineShareWidget[] getPackageWidgets(OnlineShareWidget widgetPackage, boolean requireCompatible) { + String targetDesignerVersion = requireCompatible ? ProductConstants.RELEASE_VERSION : "0"; + String plistUrl = getPackageChildrenPath() + widgetPackage.getId() + "?designerVersion="+ targetDesignerVersion; OnlineShareWidget[] widgets = getOnlineShareWidgets(plistUrl); for (OnlineShareWidget widget : widgets) { widget.setParentPackage(widgetPackage); diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java index 3eb947488e..8f1e1c994c 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java @@ -7,22 +7,28 @@ import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.*; import com.fr.design.fit.common.TemplateTool; import com.fr.design.fit.attrpane.PcFitExpandablePane; +import com.fr.design.gui.ilable.UIAutoChangeLineLabel; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.style.FollowingThemePane; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.design.mainframe.widget.accessibles.AccessibleElementCaseToolBarEditor; import com.fr.design.widget.ui.designer.component.PaddingBoundPane; import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.PaddingMargin; import com.fr.form.web.FormToolBarManager; import com.fr.general.ComparatorUtils; +import com.fr.report.fit.FitProvider; import com.fr.report.fit.ReportFitAttr; +import com.fr.report.fit.ReportFitConfig; import javax.swing.BorderFactory; import javax.swing.JPanel; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Component; import java.util.ArrayList; import java.util.List; @@ -78,11 +84,23 @@ public class ElementEditorDefinePane extends WTitleLayoutDefinePane params) { + return OperatingSystem.isMacos() && StringUtils.isEmpty(host) && StringUtils.isEmpty(path) && params.isEmpty(); + } + + @Override + public void run(String url, String host, String path, Map params) { + File file = new File(url); + if (file.exists()) { + DesignerContext.getDesignerFrame().openTemplate(new FileFILE(file)); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/deeplink/TemplateThemeInstallationDeepLink.java b/designer-realize/src/main/java/com/fr/design/deeplink/TemplateThemeInstallationDeepLink.java new file mode 100644 index 0000000000..9c9d146695 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/deeplink/TemplateThemeInstallationDeepLink.java @@ -0,0 +1,53 @@ +package com.fr.design.deeplink; + +import com.fr.design.mainframe.share.ui.online.installation.Installation; +import com.fr.design.mainframe.share.ui.online.installation.TemplateThemeInstallation; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.EncodeConstants; +import com.fr.stable.StringUtils; +import com.fr.third.springframework.web.util.UriUtils; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2022/1/10 + */ +public class TemplateThemeInstallationDeepLink extends DeepLink { + public TemplateThemeInstallationDeepLink() { + } + private static class Holder { + public static TemplateThemeInstallationDeepLink INSTANCE = new TemplateThemeInstallationDeepLink(); + } + public static TemplateThemeInstallationDeepLink getInstance() { + return TemplateThemeInstallationDeepLink.Holder.INSTANCE; + } + + public static final String HOST = "template_theme"; + public static final String PATH = "/add"; + public static final String FILE_KEY = "file"; + + @Override + public boolean accept(String url, String host, String path, Map params) { + return host != null && StringUtils.equals(HOST, host) + && path != null && StringUtils.equals(PATH, path) + && params != null && params.containsKey(FILE_KEY) + ; + } + + @Override + public void run(String url, String host, String path, Map params) { + String remoteFileAddress = (String) params.get(FILE_KEY); + try { + remoteFileAddress = UriUtils.decode(remoteFileAddress, EncodeConstants.ENCODING_UTF_8); + FineLoggerFactory.getLogger().info("TemplateThemeInstallationDeepLink: " + remoteFileAddress); + + Installation installation = new TemplateThemeInstallation(remoteFileAddress); + installation.install(); + } catch (UnsupportedEncodingException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java index 638254226f..20b674a48e 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java @@ -4,13 +4,13 @@ import com.fr.base.BaseUtils; import com.fr.base.DynamicUnitList; import com.fr.base.Parameter; import com.fr.base.ScreenResolution; +import com.fr.base.TRL; import com.fr.base.extension.FileExtension; -import com.fr.base.theme.TemplateThemeCompatible; -import com.fr.base.vcs.DesignerMode; import com.fr.base.theme.ReportTheme; -import com.fr.base.theme.ReportThemeConfig; import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeCompatible; import com.fr.base.theme.TemplateThemeConfig; +import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignModelAdapter; import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.AllowAuthorityEditAction; @@ -717,10 +717,10 @@ public class JWorkBook extends JTemplate { } protected void addShortCut(MenuDef exportMenuDef, MenuDef excelExportMenuDef) { - if (CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())){ + if (CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())) { exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), new CSVExportAction(this), new TextExportAction(this)); - }else { + } else { exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), new CSVExportAction(this), new TextExportAction(this), new EmbeddedExportExportAction(this)); } @@ -758,15 +758,14 @@ public class JWorkBook extends JTemplate { new ReportWatermarkAction(this), new NameSeparator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Utils_Current_Sheet")), }, this.reportComposite.getEditingReportComponent().shortcut4TemplateMenu()); - if (enableNewEngine){ + if (enableNewEngine) { return ArraysUtil.insert(commonShortCut, new CalculateAttrAction(this), 5); - }else { + } else { return commonShortCut; } } - /** * 模板的工具 * @@ -1243,6 +1242,7 @@ public class JWorkBook extends JTemplate { return ViewRequestConstants.REPORT_VIEW_PATH; } + @Override protected void addChooseFILEFilter(FILEChooserPane fileChooser) { String appName = ProductConstants.APP_NAME; fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPT, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); @@ -1304,7 +1304,7 @@ public class JWorkBook extends JTemplate { @Override public void setTemplateTheme(TemplateTheme newTheme, TemplateThemeCompatible compatible) { - ReportTheme oldTheme = getTarget().getTemplateTheme(); + ReportTheme oldTheme = getTarget().getTemplateTheme(); boolean shouldCreateUndoState = compatible == TemplateThemeCompatible.NONE && !StringUtils.equals(oldTheme.getName(), newTheme.getName()); getTarget().setTemplateTheme(newTheme, compatible); @@ -1318,4 +1318,9 @@ public class JWorkBook extends JTemplate { super.setTemplateTheme(newTheme, compatible); } + + @Override + public void navigate(TRL trl) { + reportComposite.selectCell(trl); + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java index 5fe5618293..d0f6a114d8 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java @@ -1,7 +1,7 @@ package com.fr.design.mainframe; import com.fr.base.ScreenResolution; -import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.base.TRL; import com.fr.design.base.mode.DesignModeContext; import com.fr.design.designer.EditingState; import com.fr.design.event.RemoveListener; @@ -13,14 +13,13 @@ import com.fr.grid.Grid; import com.fr.log.FineLoggerFactory; import com.fr.main.impl.WorkBook; import com.fr.report.report.TemplateReport; +import com.fr.stable.StringUtils; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; import java.util.ArrayList; /** @@ -80,6 +79,22 @@ public class ReportComponentComposite extends JComponent implements RemoveListen } }; + /** + * 选中格子 + * + * @param trl 模板资源路径 + */ + public void selectCell(TRL trl) { + String sheetIndexStr = trl.next(); + if(StringUtils.isEmpty(sheetIndexStr)) { + return; + } + int sheetIndex = Integer.parseInt(sheetIndexStr); + if (sheetIndex >= 0) { + sheetNameTab.setSelectedIndex(sheetIndex); + centerCardPane.editingComponet.navigate(trl); + } + } protected void doBeforeChange(int oldIndex) { if (oldIndex >= 0) { @@ -131,7 +146,7 @@ public class ReportComponentComposite extends JComponent implements RemoveListen } } - private void updateJSlider(){ + private void updateJSlider() { centerCardPane.editingComponet.updateJSliderValue(); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java b/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java index 53f193be74..6cbc0142ed 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/WorkBookModelAdapter.java @@ -2,6 +2,7 @@ package com.fr.design.mainframe; import com.fr.base.Parameter; import com.fr.base.TableData; +import com.fr.base.param.ParameterSource; import com.fr.data.TableDataSource; import com.fr.design.DesignModelAdapter; import com.fr.design.bridge.DesignToolbarProvider; @@ -17,8 +18,8 @@ import com.fr.stable.ParameterProvider; import com.fr.stable.StringUtils; import com.fr.stable.bridge.StableFactory; import com.fr.stable.js.WidgetName; - import com.fr.util.ParameterApplyHelper; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -139,7 +140,7 @@ public class WorkBookModelAdapter extends DesignModelAdapter 10000) { + setSelection(new FloatSelection(TRL.unescape(cellName))); + return; + } + CellSelection cellSelection = new CellSelection(columnRow.getColumn(), columnRow.getRow(), columnRow.getColumnSpan(), columnRow.getRowSpan()); + // 滚动到位 + JScrollBar verticalBar = getVerticalScrollBar(), + horizontalBar = getHorizontalScrollBar(); + int m = columnRow.getColumn(), n = columnRow.getRow(); + verticalBar.setMaximum(n); + verticalBar.setValue(n < 21 ? verticalBar.getValue() : n - 20); + horizontalBar.setMaximum(m); + horizontalBar.setValue(m < 13 ? horizontalBar.getValue() : m - 12); + // 选中 + setSelection(cellSelection); + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java index 0497828c7e..327d0555c2 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java @@ -11,10 +11,14 @@ import com.fr.design.mainframe.alphafine.cell.model.MoreModel; import com.fr.design.mainframe.alphafine.model.SearchResult; import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider; import com.fr.file.filetree.FileNode; +import com.fr.file.filetree.FileNodes; import com.fr.general.ComparatorUtils; import com.fr.json.JSONObject; +import com.fr.rpc.ExceptionHandler; +import com.fr.rpc.RPCInvokerExceptionInfo; import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.WorkContext; /** @@ -74,7 +78,12 @@ public class FileSearchManager implements AlphaFineSearchProvider { return lessModelList; } AlphaFineHelper.checkCancel(); - fileNodes = FRContext.getFileNodes().list(ProjectConstants.REPORTLETS_NAME, AlphaFineConstants.FILE_EXTENSIONS, true); + fileNodes = WorkContext.getCurrent().get(FileNodes.class, new ExceptionHandler() { + @Override + public Object callHandler(RPCInvokerExceptionInfo exceptionInfo) { + return FRContext.getFileNodes().list(ProjectConstants.REPORTLETS_NAME, AlphaFineConstants.FILE_EXTENSIONS, true); + } + }).list(ProjectConstants.REPORTLETS_NAME, AlphaFineConstants.FILE_EXTENSIONS, true, false); isContainCpt = true; isContainFrm = true; doSearch(this.searchText); @@ -128,7 +137,12 @@ public class FileSearchManager implements AlphaFineSearchProvider { */ private void doFileContentSearch(String searchText) { if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isContainFileContent()) { - FileNode[] fileNodes = FRContext.getFileNodes().filterFiles(searchText, ProjectConstants.REPORTLETS_NAME, new FileExtension[]{FileExtension.CPT, FileExtension.FRM}, true); + FileNode[] fileNodes = WorkContext.getCurrent().get(FileNodes.class, new ExceptionHandler() { + @Override + public Object callHandler(RPCInvokerExceptionInfo exceptionInfo) { + return FRContext.getFileNodes().filterFiles(searchText, ProjectConstants.REPORTLETS_NAME, new FileExtension[]{FileExtension.CPT, FileExtension.FRM}, true); + } + }).filterFiles(searchText, ProjectConstants.REPORTLETS_NAME, new FileExtension[]{FileExtension.CPT, FileExtension.FRM}, true, false); for (FileNode node : fileNodes) { FileModel model = new FileModel(node.getName(), node.getEnvPath()); if (!AlphaFineHelper.getFilterResult().contains(model) && !filterModelList.contains(model)) { diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java index 0ea7713ca9..99a0d9bf48 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java @@ -12,7 +12,10 @@ 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.ilable.UILabel; +import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.layout.VerticalFlowLayout; @@ -30,8 +33,7 @@ import com.fr.report.cell.cellattr.CellPageAttr; import com.fr.report.elementcase.TemplateElementCase; import com.fr.stable.Constants; import com.fr.stable.StringUtils; -import com.fr.design.i18n.Toolkit; -import java.awt.Color; + import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JPanel; @@ -40,6 +42,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.BorderLayout; import java.awt.CardLayout; +import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Insets; @@ -57,6 +60,8 @@ public class CellOtherSetPane extends AbstractCellAttrPane { private static final int HEAD_HEIGTH = 24; private static final int COMBO_WIDTH = 154; private static final int BUTTON_GROUP_WIDTH = 140; + private static final double f = TableLayout.FILL; + private static final double p = TableLayout.PREFERRED; // normal private UIButtonGroup autoshrik; @@ -66,8 +71,20 @@ public class CellOtherSetPane extends AbstractCellAttrPane { private UIComboBox showContent; + //内容提示 + private UIButtonGroup tooltipButtonGroup; + private CardLayout tooltipLayout; + private JPanel tooltipPane; private UITextField tooltipTextField; + //文本超出时隐藏 + private UICheckBox textOverflowCheckBox; + private UIComboBox showPartComboBox; + private CardLayout showPartLayout; + private JPanel showPartPane; + private UISpinner showCharNums; + private UIComboBox textOverflowTypeComboBox; + private UITextField fileNameTextField; // 分页 @@ -213,17 +230,16 @@ public class CellOtherSetPane extends AbstractCellAttrPane { private JPanel seniorUpPane() { JPanel pane = new JPanel(new BorderLayout()); // TODO: 方法之间的耦合还比较严重。现在必须先执行 createShowContentPane,再执行 createSeniorCheckPane。否则出现 npe。 + pane.add(createTextOverflowPane(), BorderLayout.SOUTH); pane.add(createShowContentPane(), BorderLayout.CENTER); pane.add(createSeniorCheckPane(), BorderLayout.NORTH); return pane; } private JPanel createShowContentPane() { - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p}; + double[] rowSize = {p, p, p, p}; double[] colSize = {f, COMBO_WIDTH}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}}; JPanel fileNamePane = createNormal(); fileNamePane.setBorder(BorderFactory.createEmptyBorder(0,12,0,0)); @@ -232,21 +248,96 @@ public class CellOtherSetPane extends AbstractCellAttrPane { UIComponentUtils.setLineWrap(showContentLabel); UILabel toolTipLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_ToolTip")); - JPanel toolTipTextFieldWrapper = new JPanel(new BorderLayout()); - toolTipTextFieldWrapper.add(tooltipTextField, BorderLayout.NORTH); + tooltipLayout = new CardLayout(); + tooltipPane = new JPanel(tooltipLayout); + tooltipPane.add(new JPanel(), "none"); + tooltipPane.add(tooltipTextField, "content"); + tooltipPane.setPreferredSize(new Dimension(0, 0)); + tooltipButtonGroup = new UIButtonGroup(new String[]{Toolkit.i18nText("Fine-Design_Report_CellWrite_ToolTip_Custom"), Toolkit.i18nText("Fine-Design_Report_CellWrite_ToolTip_CellValue")}); + tooltipButtonGroup.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (tooltipButtonGroup.getSelectedIndex() == 0) { + tooltipPane.setPreferredSize(new Dimension(154, 20)); + tooltipLayout.show(tooltipPane, "content"); + } else { + tooltipLayout.show(tooltipPane, "none"); + tooltipPane.setPreferredSize(new Dimension(0, 0)); + } + } + }); Component[][] components = new Component[][]{ new Component[]{showContentLabel, UIComponentUtils.wrapWithBorderLayoutPane(showContent)}, new Component[]{fileNamePane, null}, // 选择"用下载连接显示二进制内容"时,会显示这一行的面板 - new Component[]{toolTipLabel, toolTipTextFieldWrapper} + new Component[]{toolTipLabel, tooltipButtonGroup}, // “自定义”or"单元格值" + new Component[]{null, tooltipPane} // 选择“自定义”时显示这一行 }; JPanel showContentPane = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, colSize, rowCount, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); - showContentPane.setBorder(BorderFactory.createEmptyBorder(6, 0, 12, 0)); + showContentPane.setBorder(BorderFactory.createEmptyBorder(6, 0, 6, 0)); return showContentPane; } + private JPanel createTextOverflowPane() { + showPartLayout = new CardLayout(); + showPartPane = new JPanel(showPartLayout); + showCharNums = new UISpinner(0, Integer.MAX_VALUE, 1, 10); + JPanel showPartNumPane = new JPanel(new BorderLayout(4, 0)); + showPartNumPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_Nums")), BorderLayout.WEST); + showPartNumPane.add(showCharNums, BorderLayout.CENTER); + showPartPane.add(new JPanel(), "none"); + showPartPane.add(showPartNumPane, "content"); + showPartComboBox = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_CharNum"), Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_CellWidth")}); + showPartComboBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (showPartComboBox.getSelectedIndex() == 0) { + showPartPane.setPreferredSize(new Dimension(70, 20)); + showPartLayout.show(showPartPane, "content"); + } else { + showPartLayout.show(showPartPane, "none"); + showPartPane.setPreferredSize(new Dimension(0, 0)); + } + } + }); + + textOverflowTypeComboBox = new UIComboBox(new String[]{Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_Ellipsis"), Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_NoneSymbol")}); + UILabel showPartLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_ShowPart") + ":"); + UILabel hideTypeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_HideType") + ":"); + Component[][] textOverflowComponents = new Component[][]{ + new Component[]{showPartLabel, showPartComboBox, showPartPane}, + new Component[]{hideTypeLabel, textOverflowTypeComboBox, null} + }; + JPanel textOverflowComPane = TableLayoutHelper.createTableLayoutPane(textOverflowComponents, new double[]{p, p}, new double[]{p, f, p}); + textOverflowComPane.setVisible(false); + textOverflowCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_HideWhenOverflow")); + textOverflowCheckBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + textOverflowComPane.setVisible(e.getStateChange() == ItemEvent.SELECTED); + if (e.getStateChange() == ItemEvent.SELECTED) { + if (showPartComboBox.getSelectedIndex() == 0) { + showPartPane.setPreferredSize(new Dimension(70, 20)); + showPartLayout.show(showPartPane, "content"); + } else { + showPartLayout.show(showPartPane, "none"); + showPartPane.setPreferredSize(new Dimension(0, 0)); + } + noAutoRadioButton.setSelected(true); + } + } + }); + JPanel dynamicPaneWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); + dynamicPaneWrapper.add(textOverflowComPane); + JPanel textOverflowPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + textOverflowPane.add(textOverflowCheckBox, BorderLayout.NORTH); + textOverflowPane.add(dynamicPaneWrapper, BorderLayout.CENTER); + textOverflowPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + return textOverflowPane; + } + private JPanel createSeniorCheckPane() { previewCellContent.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); printAndExportContent.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); @@ -370,6 +461,11 @@ public class CellOtherSetPane extends AbstractCellAttrPane { insertRowPolicyButtonGroup.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy")); valueEditor.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy")); pageFixedRowDataCheckBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Fixed_Row_Cell")); + tooltipButtonGroup.setGlobalName(Toolkit.i18nText("Fine-Design_Report_CellWrite_ToolTip_Button_Group")); + textOverflowCheckBox.setGlobalName(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_HideWhenOverflow")); + showPartComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_ShowPart")); + showCharNums.setGlobalName(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_Nums")); + textOverflowTypeComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_HideType")); } @@ -428,7 +524,40 @@ public class CellOtherSetPane extends AbstractCellAttrPane { } else { showContent.setSelectedItem(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Default")); } - tooltipTextField.setText(cellGUIAttr.getTooltipText()); + if (cellGUIAttr.isCustomTooltip()) { + tooltipButtonGroup.setSelectedIndex(0); + tooltipTextField.setText(cellGUIAttr.getTooltipText()); + } else { + tooltipButtonGroup.setSelectedIndex(1); + } + if (tooltipButtonGroup.getSelectedIndex() == 0) { + tooltipPane.setPreferredSize(new Dimension(100, 20)); + tooltipLayout.show(tooltipPane, "content"); + } else { + tooltipLayout.show(tooltipPane, "none"); + tooltipPane.setPreferredSize(new Dimension(0, 0)); + } + tooltipPane.setVisible(true); + if (cellGUIAttr.isHideTextWhenOverflow()) { + textOverflowCheckBox.setSelected(true); + if (cellGUIAttr.isShowCharNum()) { + showPartComboBox.setSelectedIndex(0); + showCharNums.setValue(cellGUIAttr.getShowCharNums()); + } else { + showPartComboBox.setSelectedIndex(1); + } + showPartPane.setVisible(true); + if (cellGUIAttr.isTextOverflowEllipsis()) { + textOverflowTypeComboBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_Ellipsis")); + } else { + textOverflowTypeComboBox.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_NoneSymbol")); + } + } else { + showPartComboBox.setSelectedIndex(0); + showCharNums.setValue(cellGUIAttr.getShowCharNums()); + textOverflowTypeComboBox.setSelectedIndex(0); + textOverflowCheckBox.setSelected(false); + } CellPageAttr cellPageAttr = cellElement.getCellPageAttr(); // 分页 if (cellPageAttr == null) { cellPageAttr = new CellPageAttr(); @@ -520,7 +649,18 @@ public class CellOtherSetPane extends AbstractCellAttrPane { cellGUIAttr.setFileName(fileNameTextField.getText()); } } - + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_CellWrite_ToolTip_Button_Group"))) { + cellGUIAttr.setCustomTooltip(tooltipButtonGroup.getSelectedIndex() == 0); + if (tooltipButtonGroup.getSelectedIndex() == 0) { + if (tooltipTextField.getText() == null || tooltipTextField.getText().trim().length() <= 0) { + cellGUIAttr.setTooltipText(fieldName); + } else { + cellGUIAttr.setTooltipText(tooltipTextField.getText()); + } + } else if (tooltipButtonGroup.getSelectedIndex() == 1) { + cellGUIAttr.setTooltipText("=$$$"); + } + } if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_ToolTip"))) { if (tooltipTextField.getText() == null || tooltipTextField.getText().trim().length() <= 0) { cellGUIAttr.setTooltipText(fieldName); @@ -528,6 +668,18 @@ public class CellOtherSetPane extends AbstractCellAttrPane { cellGUIAttr.setTooltipText(tooltipTextField.getText()); } } + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_HideWhenOverflow"))) { + cellGUIAttr.setHideTextWhenOverflow(textOverflowCheckBox.isSelected()); + } + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_ShowPart"))) { + cellGUIAttr.setShowCharNum(showPartComboBox.getSelectedIndex() == 0); + } + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_Nums"))) { + cellGUIAttr.setShowCharNums((int) showCharNums.getValue()); + } + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_CellWrite_TextOverflow_HideType"))) { + cellGUIAttr.setTextOverflowEllipsis(textOverflowTypeComboBox.getSelectedIndex() == 0); + } // 如果与默认的CellGUIAttr相同,就不用保存这个属性了 if (ComparatorUtils.equals(cellGUIAttr, CellGUIAttr.DEFAULT_CELLGUIATTR)) { cellElement.setCellGUIAttr(cellNullGUIAttr); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java index 9d89a7cd33..71d34ff445 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java @@ -3,6 +3,7 @@ */ package com.fr.design.mainframe.form; +import com.fr.base.TRL; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignState; import com.fr.design.actions.AllowAuthorityEditAction; @@ -29,16 +30,20 @@ import com.fr.design.selection.SelectableElement; import com.fr.design.selection.Selectedable; import com.fr.design.selection.SelectionListener; import com.fr.form.FormElementCaseProvider; +import com.fr.form.fit.common.LightTool; import com.fr.form.main.Form; import com.fr.grid.Grid; import com.fr.grid.selection.CellSelection; +import com.fr.grid.selection.FloatSelection; import com.fr.grid.selection.Selection; import com.fr.log.FineLoggerFactory; import com.fr.report.cell.CellElement; import com.fr.report.elementcase.TemplateElementCase; import com.fr.report.worksheet.FormElementCase; import com.fr.report.worksheet.WorkSheet; +import com.fr.stable.ColumnRow; import com.fr.stable.Constants; +import com.fr.stable.StringUtils; import javax.swing.JComponent; import javax.swing.JPanel; @@ -65,8 +70,12 @@ public class FormElementCaseDesigner } public FormElementCaseDesigner(T sheet, Form form) { + this(sheet, form.getFormMobileAttr().isMobileOnly(), LightTool.containNewFormFlag(form)); + } + + public FormElementCaseDesigner(T sheet, boolean isMobileOnly, boolean isNewForm) { super(sheet); - elementCasePane = initElementCasePane(sheet, form); + elementCasePane = initElementCasePane(sheet, isMobileOnly, isNewForm); this.setLayout(FRGUIPaneFactory.createBorderLayout()); elementCasePane.setSelection(getDefaultSelectElement()); this.add(elementCasePane, BorderLayout.CENTER); @@ -80,8 +89,8 @@ public class FormElementCaseDesigner } - protected FormElementCasePaneDelegate initElementCasePane(T sheet, Form form){ - return new FormElementCasePaneDelegate((FormElementCase) sheet, form); + protected FormElementCasePaneDelegate initElementCasePane(T sheet, boolean isMobileOnly, boolean isNewForm){ + return new FormElementCasePaneDelegate((FormElementCase) sheet, isMobileOnly, isNewForm); } @Override @@ -389,4 +398,28 @@ public class FormElementCaseDesigner public FormElementCaseProvider getEditingElementCase() { return this.getEditingElementCasePane().getTarget(); } + + @Override + public void navigate(TRL trl) { + String cellName = trl.next(); + if (StringUtils.isEmpty(cellName)) { + return; + } + ColumnRow columnRow = ColumnRow.valueOf(cellName); + if (!ColumnRow.validate(columnRow) || columnRow.getColumn() > 10000) { + setSelection((S)new FloatSelection(TRL.unescape(cellName))); + return; + } + CellSelection cellSelection = new CellSelection(columnRow.getColumn(), columnRow.getRow(), columnRow.getColumnSpan(), columnRow.getRowSpan()); + // 滚动到位 + JScrollBar verticalBar = getVerticalScrollBar(), + horizontalBar = getHorizontalScrollBar(); + int m = columnRow.getColumn(), n = columnRow.getRow(); + verticalBar.setMaximum(n); + verticalBar.setValue(n < 21 ? verticalBar.getValue() : n - 20); + horizontalBar.setMaximum(m); + horizontalBar.setValue(m < 13 ? horizontalBar.getValue() : m - 12); + // 选中 + setSelection((S)cellSelection); + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java index 5961700e26..cd46f9de1c 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCasePaneDelegate.java @@ -9,6 +9,7 @@ import com.fr.design.actions.form.FormECFrozenAction; import com.fr.design.designer.creator.XElementCase; import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.fit.NewUIModeCellElementPainter; import com.fr.design.fit.common.FormDesignerUtil; import com.fr.design.gui.frpane.HyperlinkGroupPane; @@ -40,13 +41,16 @@ import java.awt.Rectangle; */ public class FormElementCasePaneDelegate extends ElementCasePane{ - public FormElementCasePaneDelegate(FormElementCase sheet, Form form) { + this(sheet, form.getFormMobileAttr().isMobileOnly(), LightTool.containNewFormFlag(form)); + } + + public FormElementCasePaneDelegate(FormElementCase sheet, boolean isMobileOnly, boolean isNewForm) { super(sheet); - this.getGrid().setPaginateLineShowType(form.getFormMobileAttr().isMobileOnly() + this.getGrid().setPaginateLineShowType(isMobileOnly ? Grid.SINGLE_HORIZONTAL_PAGINATE_LINE : Grid.NO_PAGINATE_LINE); - if (LightTool.containNewFormFlag(form)){ + if (isNewForm){ this.getGrid().setCellElementPainter(new NewUIModeCellElementPainter()); } this.addSelectionChangeListener(new SelectionListener() { @@ -68,8 +72,17 @@ public class FormElementCasePaneDelegate extends ElementCasePane template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (!(template instanceof JForm)) { + return rectangle; + } + + FormDesigner designer = ((JForm) template).getFormDesign(); + if (designer == null) { + return rectangle; + } + XElementCase xElementCase = FormDesignerUtil.getXelementCase(designer.getRootComponent(), (FormElementCase) elementCase); if (xElementCase != null) { rectangle.setBounds(xElementCase.getBounds()); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormReportComponentComposite.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormReportComponentComposite.java index 67235ee7b2..5fdc4b011b 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormReportComponentComposite.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormReportComponentComposite.java @@ -2,7 +2,6 @@ package com.fr.design.mainframe.form; import com.fr.base.DynamicUnitList; import com.fr.base.ScreenResolution; -import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.cell.bar.DynamicScrollBar; import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; @@ -11,7 +10,11 @@ import com.fr.design.mainframe.BaseJForm; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerUIModeConfig; import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.mainframe.JDashboard; +import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JFormSliderPane; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.JTemplateProvider; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.form.FormElementCaseContainerProvider; import com.fr.form.FormElementCaseProvider; @@ -22,11 +25,11 @@ import com.fr.report.worksheet.FormElementCase; import com.fr.stable.AssistUtils; import com.fr.stable.Constants; -import javax.swing.*; +import javax.swing.JComponent; +import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.awt.*; -import java.awt.event.*; +import java.awt.BorderLayout; /** * 整个FormElementCase编辑区域 包括滚动条、中间的grid或者聚合块、下面的sheetTab @@ -38,37 +41,29 @@ public class FormReportComponentComposite extends JComponent implements TargetMo private static final int MIN = 10; private static final int DIR = 10; private static final double MIN_TIME = 0.4; - public FormElementCaseDesigner elementCaseDesigner; - private BaseJForm jForm; + public final FormElementCaseDesigner elementCaseDesigner; + private final JTemplateProvider jTemplate; - private FormTabPane sheetNameTab; + private final FormTabPane sheetNameTab; private JPanel hbarContainer; private JFormSliderPane jSliderContainer; - public FormReportComponentComposite(BaseJForm jform, FormElementCaseDesigner elementCaseDesign, FormElementCaseContainerProvider ecContainer) { - this.jForm = jform; + public FormReportComponentComposite(JTemplateProvider jTemplate, JDashboard jDashboard, FormElementCaseDesigner elementCaseDesign, String ecContainerName) { + this.jTemplate = jTemplate; this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.elementCaseDesigner = elementCaseDesign; this.add(elementCaseDesigner, BorderLayout.CENTER); - sheetNameTab = new FormTabPane(ecContainer, jform); + sheetNameTab = new FormTabPane(ecContainerName, jDashboard); this.add(createSouthControlPane(), BorderLayout.SOUTH); jSliderContainer.addValueChangeListener(showValSpinnerChangeListener); - this.elementCaseDesigner.elementCasePane.getGrid().addMouseWheelListener(showValSpinnerMouseWheelListener); + this.elementCaseDesigner.elementCasePane.getGrid().addMouseWheelListener(new FormReportComponentCompositeMouseWheelHandler(this)); elementCaseDesigner.addTargetModifiedListener(this); this.jSliderContainer.setShowValue((ScreenResolution.getScreenResolution() * HUND) / Constants.DEFAULT_WEBWRITE_AND_SCREEN_RESOLUTION); } - MouseWheelListener showValSpinnerMouseWheelListener = new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - if (InputEventBaseOnOS.isControlDown(e)) { - int dir = e.getWheelRotation(); - int old_resolution = jSliderContainer.getShowValue(); - jSliderContainer.setShowValue(old_resolution - (dir * DIR)); - } - } - }; - + public FormReportComponentComposite(BaseJForm jform, FormElementCaseDesigner elementCaseDesign, FormElementCaseContainerProvider ecContainer) { + this(jform, jform, elementCaseDesign, ecContainer.getElementCaseContainerName()); + } ChangeListener showValSpinnerChangeListener = new ChangeListener() { @Override @@ -177,7 +172,7 @@ public class FormReportComponentComposite extends JComponent implements TargetMo } public void setComposite() { - DesignerContext.getDesignerFrame().resetToolkitByPlus((ToolBarMenuDockPlus) jForm); + DesignerContext.getDesignerFrame().resetToolkitByPlus((ToolBarMenuDockPlus) jTemplate); this.validate(); this.repaint(40); } @@ -192,8 +187,11 @@ public class FormReportComponentComposite extends JComponent implements TargetMo * 模板更新 */ public void fireTargetModified() { - jForm.fireTargetModified(); + jTemplate.fireTargetModified(); } + public JFormSliderPane getSliderContainer() { + return this.jSliderContainer; + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormReportComponentCompositeMouseWheelHandler.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormReportComponentCompositeMouseWheelHandler.java new file mode 100644 index 0000000000..7e8da60dc5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormReportComponentCompositeMouseWheelHandler.java @@ -0,0 +1,79 @@ +package com.fr.design.mainframe.form; + +import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.mainframe.DesignerScaleMouseWheelHandler; +import com.fr.design.mainframe.DesignerTranslateMouseWheelHandler; +import com.fr.design.mainframe.JFormSliderPane; +import com.fr.design.mainframe.ReportComponentComposite; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/24 + */ +public class FormReportComponentCompositeMouseWheelHandler implements MouseWheelListener { + private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; + private final DesignerScaleMouseWheelHandler scaleMouseWheelHandler; + + public FormReportComponentCompositeMouseWheelHandler(FormReportComponentComposite componentComposite) { + translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new ScrollPaneAdapter(componentComposite)); + scaleMouseWheelHandler = new DesignerScaleMouseWheelHandler(new ScalePaneAdapter(componentComposite), ReportComponentComposite.DIR); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (InputEventBaseOnOS.isControlDown(e)) { + scaleMouseWheelHandler.mouseWheelMoved(e); + } else { + translateMouseWheelHandler.mouseWheelMoved(e); + } + } + + private static class ScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { + private final FormReportComponentComposite componentComposite; + private JViewport viewport; + + public ScrollPaneAdapter(FormReportComponentComposite componentComposite) { + this.componentComposite = componentComposite; + this.viewport = new JViewport(); + } + + @Override + public boolean isWheelScrollingEnabled() { + return true; + } + + @Override + public JScrollBar getVerticalScrollBar() { + return componentComposite.elementCaseDesigner.getVerticalScrollBar(); + } + + @Override + public JScrollBar getHorizontalScrollBar() { + return componentComposite.elementCaseDesigner.getHorizontalScrollBar(); + } + + @Override + public JViewport getViewport() { + return viewport; + } + } + + private static class ScalePaneAdapter implements DesignerScaleMouseWheelHandler.ScalePane { + private final FormReportComponentComposite componentComposite; + + public ScalePaneAdapter(FormReportComponentComposite componentComposite) { + this.componentComposite = componentComposite; + } + + @Override + public JFormSliderPane getSlidePane() { + return componentComposite.getSliderContainer(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormTabPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormTabPane.java index f158b39360..dca7029047 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormTabPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormTabPane.java @@ -5,6 +5,7 @@ import com.fr.base.GraphHelper; import com.fr.design.constants.UIConstants; import com.fr.design.mainframe.BaseJForm; +import com.fr.design.mainframe.JDashboard; import com.fr.form.FormElementCaseContainerProvider; @@ -27,8 +28,8 @@ public class FormTabPane extends JComponent implements MouseListener, MouseMotio private static final int GAP = 5; //间隔 - private BaseJForm form; - private FormElementCaseContainerProvider elementCase; + private JDashboard jDashboard; + private final String elementCaseContainerName; //选了30度和60度的特殊角度的x,y作为经过的两个点的坐标 private double specialLocation1 = 2.5; @@ -48,8 +49,12 @@ public class FormTabPane extends JComponent implements MouseListener, MouseMotio private int selectedIndex = -1; public FormTabPane(FormElementCaseContainerProvider elementCase, BaseJForm form){ - this.elementCase = elementCase; - this.form = form; + this(elementCase.getElementCaseContainerName(), form); + } + + public FormTabPane(String elementCaseContainerName, JDashboard jDashboard){ + this.elementCaseContainerName = elementCaseContainerName; + this.jDashboard = jDashboard; this.setLayout(new BorderLayout(0, 0)); this.addMouseListener(this); this.addMouseMotionListener(this); @@ -57,12 +62,16 @@ public class FormTabPane extends JComponent implements MouseListener, MouseMotio this.setForeground(new Color(99, 99, 99)); } + public String getElementCaseContainerName() { + return elementCaseContainerName; + } + public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; calculateECWidth(); paintFormTab(g2d, 0, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Form"), POLY_SHEET_ICON); - paintECTab(g2d, formTabWidth, elementCase.getElementCaseContainerName(), WORK_SHEET_ICON); + paintECTab(g2d, formTabWidth, getElementCaseContainerName(), WORK_SHEET_ICON); } /** @@ -165,7 +174,7 @@ public class FormTabPane extends JComponent implements MouseListener, MouseMotio private void calculateECWidth() { FontMetrics fm = GraphHelper.getFontMetrics(this.getFont()); int charWidth = fm.charWidth('M'); - String ECName = elementCase.getElementCaseContainerName(); + String ECName = getElementCaseContainerName(); ecTabWidth = Math.max(ecTabWidth,fm.stringWidth(ECName) + charWidth * 2 + ADD_WIDTH_BY_SHEETNAME) ; } @@ -177,7 +186,7 @@ public class FormTabPane extends JComponent implements MouseListener, MouseMotio public void mouseClicked(MouseEvent e) { selectedIndex = getTabIndex(e.getX()); if (selectedIndex == FORM_INDEX) { - form.tabChanged(FORM_INDEX); + jDashboard.switchToDashBoardEditor(); } repaint(); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/guide/creator/GuideCreateUtils.java b/designer-realize/src/main/java/com/fr/design/mainframe/guide/creator/GuideCreateUtils.java index bb21208740..bb651cce93 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/guide/creator/GuideCreateUtils.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/guide/creator/GuideCreateUtils.java @@ -130,12 +130,13 @@ public class GuideCreateUtils { return; } FormDesigner designer = GuideCreateUtils.getFormDesigner(); - designer.getSelectionModel().selectACreator(xLayoutContainer); if (dragNewComponent) { - designer.addNewWidget(xCreator, xLayoutContainer.getX(), xLayoutContainer.getY()); + designer.instantiateCreator(xCreator); } else { - designer.changeWidgetPlace(xCreator, xLayoutContainer.getX(), xLayoutContainer.getY()); + designer.backUpCreator(xCreator); } + designer.getSelectionModel().selectACreator(xLayoutContainer); + designer.addWidgetToForm(xCreator, xLayoutContainer.getX(), xLayoutContainer.getY()); designer.getSelectionModel().selectACreator(xCreator); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java index e5f44d4e44..d8f7265f7d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java @@ -22,7 +22,6 @@ import com.fr.log.FineLoggerFactory; import com.fr.serialization.SerializerHelper; import com.fr.stable.ArrayUtils; import com.fr.stable.StableUtils; -import com.fr.third.apache.log4j.spi.LoggingEvent; import com.fr.third.apache.logging.log4j.core.LogEvent; import com.fr.third.org.apache.http.client.config.RequestConfig; import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; @@ -33,6 +32,7 @@ import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; import com.fr.workspace.base.WorkspaceConstants; import com.fr.workspace.connect.WorkspaceConnectionInfo; +import com.fr.workspace.server.socket.CustomLogEvent; import com.fr.workspace.server.socket.LogEventConverter; import io.socket.client.IO; import io.socket.client.Socket; @@ -151,14 +151,14 @@ public class DesignerSocketIO { if (ArrayUtils.isNotEmpty(objects)) { try { Object obj = SerializerHelper.deserialize((byte[]) objects[0]); - // 兼容下老版本服务器 + // 完全去除log4j1.x LogEvent event; - if (obj instanceof LoggingEvent) { - event = LogEventConverter.convert((LoggingEvent) obj); + if (obj instanceof CustomLogEvent) { + event = LogEventConverter.convert((CustomLogEvent) obj); + DesignerLogger.log(event); } else { - event = (LogEvent) obj; + FineLoggerFactory.getLogger().warn("Unable to display server push logs, because server and designer versions are inconsistent!"); } - DesignerLogger.log(event); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } diff --git a/designer-realize/src/main/java/com/fr/design/report/NewReportBackgroundPane.java b/designer-realize/src/main/java/com/fr/design/report/NewReportBackgroundPane.java index cf514512da..928d863656 100644 --- a/designer-realize/src/main/java/com/fr/design/report/NewReportBackgroundPane.java +++ b/designer-realize/src/main/java/com/fr/design/report/NewReportBackgroundPane.java @@ -2,7 +2,6 @@ package com.fr.design.report; import com.fr.base.theme.ReportTheme; import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.base.theme.settings.ThemedReportBodyStyle; import com.fr.design.designer.IntervalConstants; import com.fr.design.dialog.BasicPane; @@ -10,21 +9,19 @@ import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; import com.fr.design.gui.frpane.AttributeChangeListener; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.style.ReportBackgroundSpecialPane; import com.fr.design.gui.style.FollowingThemePane; +import com.fr.design.gui.style.ReportBackgroundSpecialPane; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.theme.ui.BorderUtils; -import com.fr.form.ui.PaddingMargin; import com.fr.general.Background; import com.fr.page.ReportSettingsProvider; import com.fr.report.stable.ReportSettings; import javax.swing.BorderFactory; import javax.swing.JPanel; -import javax.swing.SwingConstants; import javax.swing.border.CompoundBorder; import java.awt.BorderLayout; import java.awt.Color; @@ -168,7 +165,7 @@ public class NewReportBackgroundPane extends BasicPane { container.setBorder(BorderFactory.createEmptyBorder()); JPanel titledPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); titledPane.setBorder(new CompoundBorder( - BorderUtils.createTitleBorder("预览", 12), + BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Preview"), 12), BorderFactory.createEmptyBorder(5, 5, 4, 5) )); titledPane.setPreferredSize(new Dimension(377, 502)); diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java index 68cd025e30..a9a7a85124 100644 --- a/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPane.java @@ -70,7 +70,6 @@ public class PreviewPane extends JPanel implements CallbackEvent{ private static final int MAX = 400; private static final int HUND = 100; private static final int MIN = 10; - private static final int DIR = 10; private static final double MIN_TIME = 0.4; private Widget widget; @@ -194,27 +193,7 @@ public class PreviewPane extends JPanel implements CallbackEvent{ grid.removeMouseMotionListener(grid.getGridMouseAdapter()); grid.removeMouseListener(grid.getGridMouseAdapter()); - grid.addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - if (!InputEventBaseOnOS.isControlDown(e)) { - ElementCasePane reportPane = grid.getElementCasePane(); - if (reportPane.isVerticalScrollBarVisible()) { - JScrollBar scrollBar = reportPane.getVerticalScrollBar(); - int maxValue = scrollBar.getModel().getMaximum(); - int newValue = reportPane.getVerticalScrollBar().getValue() + e.getWheelRotation(); - int extendValue = GridUtils.getExtentValue(newValue, elementCase.getRowHeightList_DEC(), grid.getHeight(), getResolution()); - if (extendValue <= maxValue) { - reportPane.getVerticalScrollBar().setValue(newValue); - } - } - } else { - int dir = e.getWheelRotation(); - addScale( - dir * DIR); - grid.setCursor(SCALE_CURSOR); - } - } - }); + grid.addMouseWheelListener(new PreviewPaneMouseWheelHandler(this)); grid.addMouseMotionListener(new MouseMotionAdapter() { @Override @@ -320,7 +299,7 @@ public class PreviewPane extends JPanel implements CallbackEvent{ elementCasePane.repaint(); } - private void addScale(int step) { + public void addScale(int step) { scaleValue += step; scaleValue = fixedScale(scaleValue); plusButton.setEnabled(scaleValue < MAX); diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPaneMouseWheelHandler.java b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPaneMouseWheelHandler.java new file mode 100644 index 0000000000..56e73955d1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/share/ui/effect/PreviewPaneMouseWheelHandler.java @@ -0,0 +1,69 @@ +package com.fr.design.share.ui.effect; + +import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.mainframe.DesignerTranslateMouseWheelHandler; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +import static com.fr.design.share.ui.effect.PreviewPane.SCALE_CURSOR; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/24 + */ +public class PreviewPaneMouseWheelHandler implements MouseWheelListener { + private static final int DIR = 10; + + private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; + private final PreviewPane previewPane; + + public PreviewPaneMouseWheelHandler(PreviewPane previewPane) { + this.translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new PreviewPaneScrollPaneAdapter(previewPane)); + this.previewPane = previewPane; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (InputEventBaseOnOS.isControlDown(e)) { + int dir = e.getWheelRotation(); + previewPane.addScale( - dir * DIR); + previewPane.getElementCasePane().getGrid().setCursor(SCALE_CURSOR); + } else { + translateMouseWheelHandler.mouseWheelMoved(e); + } + } + + private static class PreviewPaneScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { + private final PreviewPane previewPane; + private final JViewport viewport; + + public PreviewPaneScrollPaneAdapter(PreviewPane previewPane) { + this.previewPane = previewPane; + this.viewport = new JViewport(); + } + + @Override + public boolean isWheelScrollingEnabled() { + return true; + } + + @Override + public JScrollBar getVerticalScrollBar() { + return previewPane.getElementCasePane().getVerticalScrollBar(); + } + + @Override + public JScrollBar getHorizontalScrollBar() { + return previewPane.getElementCasePane().getHorizontalScrollBar(); + } + + @Override + public JViewport getViewport() { + return this.viewport; + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortGroupPane.java b/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortGroupPane.java index db6f574bd6..8a90b960e0 100644 --- a/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortGroupPane.java +++ b/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortGroupPane.java @@ -123,11 +123,30 @@ public abstract class AbstractSortGroupPane extends JPanel implements ComponentC } protected void refresh() { + freshAddSortItemBarTip(); + freshSortUIExpandablePaneTip(); validate(); repaint(); revalidate(); } + void freshAddSortItemBarTip() { + if (sortUIExpandablePanes != null) { + int itemCount = sortUIExpandablePanes.size(); + uiButton.setText(itemCount == 0 ? Toolkit.i18nText("Fine-Design_Sort_Add_Main_Sort") : Toolkit.i18nText("Fine-Design_Sort_Add_Second_Sort")); + } + } + + void freshSortUIExpandablePaneTip() { + for (int i = 0; i < sortUIExpandablePanes.size(); i++) { + if (i == 0) { + sortUIExpandablePanes.get(i).freshHeaderPaneTip(Toolkit.i18nText("Fine-Design_Sort_Main_Sort")); + } else { + sortUIExpandablePanes.get(i).freshHeaderPaneTip(Toolkit.i18nText("Fine-Design_Sort_Second_Sort")); + } + } + } + class AddSortItemBar extends JPanel { AbstractSortGroupPane sortGroupPane; diff --git a/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortPane.java b/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortPane.java index 6491d04a8e..227708e7a1 100644 --- a/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortPane.java +++ b/designer-realize/src/main/java/com/fr/design/sort/common/AbstractSortPane.java @@ -65,7 +65,7 @@ public abstract class AbstractSortPane extends JPanel { if (cellSortAttr != null) { sortHeader = cellSortAttr.getSortHeader(); } - sortHeaderPane.populateBean(sortHeader, defaultHeaderArea); + sortHeaderPane.populateBean(sortHeader, defaultHeaderArea, cellElement); } refresh(); } diff --git a/designer-realize/src/main/java/com/fr/design/sort/common/SortColumnRowPane.java b/designer-realize/src/main/java/com/fr/design/sort/common/SortColumnRowPane.java index 653ce86c8c..e9ebbd882c 100644 --- a/designer-realize/src/main/java/com/fr/design/sort/common/SortColumnRowPane.java +++ b/designer-realize/src/main/java/com/fr/design/sort/common/SortColumnRowPane.java @@ -50,6 +50,7 @@ public class SortColumnRowPane extends JPanel implements UIObserver { private final static Icon DISABLED_ICON = IconUtils.readIcon("/com/fr/design/images/buttonicon/select_disabled.svg"); private final static Icon ENABLE_ICON = IconUtils.readIcon("/com/fr/design/images/buttonicon/select_normal.svg"); private boolean enabled; + SelectActionListener selectActionListener; HeaderAreaPane.CellSelectionManager cellSelectionManager; @@ -94,7 +95,8 @@ public class SortColumnRowPane extends JPanel implements UIObserver { void initSelectButton() { selectButton = new UIButton(ENABLE_ICON); - selectButton.addMouseListener(new SelectActionListener(this)); + selectActionListener = new SelectActionListener(this); + selectButton.addMouseListener(selectActionListener); this.add(selectButton); } @@ -147,6 +149,11 @@ public class SortColumnRowPane extends JPanel implements UIObserver { return true; } + + public void cancelSelectState() { + selectActionListener.recoverSelectHeader(SortUtils.getCurrentElementCase()); + } + class SelectActionListener extends MouseAdapter { SortColumnRowPane columnRowPane; ColumnRow oldColumnRow; @@ -161,7 +168,7 @@ public class SortColumnRowPane extends JPanel implements UIObserver { @Override public void mouseClicked(MouseEvent e) { if (enabled) { - ElementCasePane elementCasePane = getCurrentElementCase(); + ElementCasePane elementCasePane = SortUtils.getCurrentElementCase(); if (elementCasePane == null || isAlreadyAddListener) { return; } @@ -201,15 +208,21 @@ public class SortColumnRowPane extends JPanel implements UIObserver { } columnRowPane.setColumnRow(columnRow); } + } + recoverSelectHeader(elementCasePane); + } + + private void recoverSelectHeader(ElementCasePane elementCasePane) { + if (isAlreadyAddListener) { restoreDisableHeaderCellsStyle(elementCasePane.getEditingElementCase()); + elementCasePane.removeSelectionChangeListener(gridSelectionChangeListener); + isAlreadyAddListener = false; + elementCasePane.getGrid().setNotShowingTableSelectPane(true); + elementCasePane.setRepeatSelection(false); + elementCasePane.setEditable(true); + elementCasePane.repaint(); + oldColumnRow = null; } - elementCasePane.removeSelectionChangeListener(gridSelectionChangeListener); - isAlreadyAddListener = false; - elementCasePane.getGrid().setNotShowingTableSelectPane(true); - elementCasePane.setRepeatSelection(false); - elementCasePane.setEditable(true); - elementCasePane.repaint(); - oldColumnRow = null; } private void ashDisableHeaderCellsStyle(TemplateElementCase elementCase) { @@ -263,17 +276,4 @@ public class SortColumnRowPane extends JPanel implements UIObserver { repaint(); revalidate(); } - - public static ElementCasePane getCurrentElementCase() { - try { - TargetComponent targetComponent - = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getCurrentElementCasePane(); - if (targetComponent instanceof ElementCasePane) { - return (ElementCasePane) targetComponent; - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e, e.getMessage()); - } - return null; - } } \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/sort/common/SortUIExpandablePane.java b/designer-realize/src/main/java/com/fr/design/sort/common/SortUIExpandablePane.java index 6de6636f4c..eef21bb060 100644 --- a/designer-realize/src/main/java/com/fr/design/sort/common/SortUIExpandablePane.java +++ b/designer-realize/src/main/java/com/fr/design/sort/common/SortUIExpandablePane.java @@ -63,7 +63,12 @@ public class SortUIExpandablePane extends JPanel { headerPane.setShow(show); } + public void freshHeaderPaneTip(String tip) { + headerPane.tipUILabel.setText(tip); + } + class HeaderPane extends JPanel implements UIObserver { + UILabel tipUILabel; UILabel iconUiLabel; UILabel closeButton; AbstractSortGroupPane sortGroupPane; @@ -78,8 +83,8 @@ public class SortUIExpandablePane extends JPanel { private void initComponents() { iconUiLabel = new UILabel(); this.add(iconUiLabel); - UILabel uiLabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Second_Sort")); - this.add(uiLabel); + tipUILabel = new UILabel(Toolkit.i18nText("Fine-Design_Sort_Second_Sort")); + this.add(tipUILabel); this.add(AbstractSortPane.createIntervalUILabel(108)); closeButton = new UILabel(IconUtils.readIcon("/com/fr/design/images/control/close.png")); diff --git a/designer-realize/src/main/java/com/fr/design/sort/common/SortUtils.java b/designer-realize/src/main/java/com/fr/design/sort/common/SortUtils.java new file mode 100644 index 0000000000..32ee1a764c --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/sort/common/SortUtils.java @@ -0,0 +1,24 @@ +package com.fr.design.sort.common; + +import com.fr.design.designer.TargetComponent; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.mainframe.JTemplate; +import com.fr.log.FineLoggerFactory; + +public class SortUtils { + public static ElementCasePane getCurrentElementCase() { + try { + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jTemplate != null) { + TargetComponent targetComponent = jTemplate.getCurrentElementCasePane(); + if (targetComponent instanceof ElementCasePane) { + return (ElementCasePane) targetComponent; + } + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + return null; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/sort/header/HeaderAreaPane.java b/designer-realize/src/main/java/com/fr/design/sort/header/HeaderAreaPane.java index 4f4617053b..25641340cb 100644 --- a/designer-realize/src/main/java/com/fr/design/sort/header/HeaderAreaPane.java +++ b/designer-realize/src/main/java/com/fr/design/sort/header/HeaderAreaPane.java @@ -8,6 +8,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.sort.common.AbstractSortPane; import com.fr.design.sort.common.SortColumnRowPane; +import com.fr.design.sort.common.SortUtils; import com.fr.log.FineLoggerFactory; import com.fr.report.cell.TemplateCellElement; import com.fr.report.cell.cellattr.CellExpandAttr; @@ -35,6 +36,7 @@ public class HeaderAreaPane extends JPanel { protected int headerAreaPaneWidth; protected int headerAreaPaneRightWidth; private CellSelectionManager cellSelectionManager = new CellSelectionManager(); + TemplateCellElement cellElement; AreaJLayeredPane areaJLayeredPane; @@ -62,9 +64,10 @@ public class HeaderAreaPane extends JPanel { this.add(areaJLayeredPane); } - public void populateBean(ColumnRow columnRow, boolean showHeaderArea) { + public void populateBean(ColumnRow columnRow, boolean showHeaderArea, TemplateCellElement cellElement) { + this.cellElement = cellElement; boolean enabled = true; - ElementCasePane elementCasePane = getCurrentElementCase(); + ElementCasePane elementCasePane = SortUtils.getCurrentElementCase(); if (elementCasePane != null) { enabled = elementCasePane.isSelectedOneCell(); } @@ -72,7 +75,7 @@ public class HeaderAreaPane extends JPanel { } public ColumnRow updateBean(TemplateCellElement cellElement) { - ElementCasePane elementCasePane = getCurrentElementCase(); + ElementCasePane elementCasePane = SortUtils.getCurrentElementCase(); if (elementCasePane != null) { if (!elementCasePane.isSelectedOneCell()) { return getOldColumnRow(cellElement); @@ -96,19 +99,6 @@ public class HeaderAreaPane extends JPanel { } } - private ElementCasePane getCurrentElementCase() { - try { - TargetComponent targetComponent - = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getCurrentElementCasePane(); - if (targetComponent instanceof ElementCasePane) { - return (ElementCasePane) targetComponent; - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e, e.getMessage()); - } - return null; - } - class AreaJLayeredPane extends JPanel { SortColumnRowPane columnRowPane; JLayeredPane jLayeredPane; @@ -151,6 +141,7 @@ public class HeaderAreaPane extends JPanel { } } else { cellSelectionManager.removeNotSelectables(columnRowPane.updateBean()); + columnRowPane.cancelSelectState(); } } @@ -176,7 +167,8 @@ public class HeaderAreaPane extends JPanel { } public void populateBean(ColumnRow columnRow, boolean showHeaderArea, boolean enabled) { - cellSelectionManager.build(); + cellSelectionManager.build(cellElement, columnRow); + columnRow = cellSelectionManager.buildCurrentCell(cellElement, columnRow); columnRowPane.populateBean(columnRow, enabled, cellSelectionManager); setSortColumnRowPaneShow(showHeaderArea); uiComboBox.setSelectedIndex(showHeaderArea ? 1 : 0); @@ -203,15 +195,26 @@ public class HeaderAreaPane extends JPanel { ElementCasePane elementCase; java.util.List notSelectables = new ArrayList<>(); - void build() { - ElementCasePane elementCase = SortColumnRowPane.getCurrentElementCase(); - if (elementCase != null && this.elementCase != elementCase) { + void build(TemplateCellElement templateCellElement, ColumnRow headerColumnRow) { + ElementCasePane elementCase = SortUtils.getCurrentElementCase(); + if (elementCase != null) { this.elementCase = elementCase; notSelectables = new ArrayList<>(); - buildNotSelectables(elementCase.getEditingElementCase()); + buildNotSelectables(elementCase.getEditingElementCase(), templateCellElement); } } + private ColumnRow buildCurrentCell(TemplateCellElement templateCellElement, ColumnRow headerColumnRow) { + if (isNotSelectables(headerColumnRow)) { + SortHeader sortHeader = templateCellElement.getCellExpandAttr().getCellSortAttr().getSortHeader(); + headerColumnRow = ColumnRow.ERROR; + sortHeader.setHeaderArea(headerColumnRow.toString()); + } else { + handleDisableHeaderCell(templateCellElement); + } + return headerColumnRow; + } + public java.util.List getNotSelectables() { return this.notSelectables; } @@ -232,24 +235,20 @@ public class HeaderAreaPane extends JPanel { notSelectables.remove(columnRow); } - private void buildNotSelectables(TemplateElementCase elementCase) { + private void buildNotSelectables(TemplateElementCase elementCase, TemplateCellElement excludeTemplateCellElement) { Iterator iterator = elementCase.cellIterator(); while (iterator.hasNext()) { TemplateCellElement templateCellElement = (TemplateCellElement) iterator.next(); - CellExpandAttr cellExpandAttr = templateCellElement.getCellExpandAttr(); - if (cellExpandAttr != null) { - handleDisableHeaderCell(cellExpandAttr); - } - Object value = templateCellElement.getValue(); - if (value instanceof DSColumn) { - handleDisableHeaderCell((DSColumn) value); + if (templateCellElement != excludeTemplateCellElement) { + handleDisableHeaderCell(templateCellElement); } } } - private void handleDisableHeaderCell(CellSortable cellSortable) { - if (cellSortable.getCellSortAttr() != null) { - SortHeader sortHeader = cellSortable.getCellSortAttr().getSortHeader(); + private void handleDisableHeaderCell(TemplateCellElement templateCellElement) { + CellExpandAttr cellExpandAttr = templateCellElement.getCellExpandAttr(); + if (cellExpandAttr != null && cellExpandAttr.getCellSortAttr() != null) { + SortHeader sortHeader = cellExpandAttr.getCellSortAttr().getSortHeader(); if (sortHeader != null) { String headerArea = sortHeader.getHeaderArea(); if (headerArea != null) { diff --git a/designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java b/designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java index 79f939639e..27c03e9e01 100644 --- a/designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java +++ b/designer-realize/src/main/java/com/fr/design/sort/header/HeaderSortRulePane.java @@ -1,45 +1,37 @@ package com.fr.design.sort.header; +import com.fr.base.FineColor; import com.fr.base.svg.SVGIcon; -import com.fr.base.svg.SVGTranscoder; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ipoppane.PopupHider; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.theme.edit.ui.ColorListPane; -import com.fr.general.IOUtils; -import com.fr.log.FineLoggerFactory; +import com.fr.design.style.color.ColorControlWindow; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.report.core.sort.header.HeaderIconBuilder; import com.fr.report.core.sort.header.SortHeader; import com.fr.report.core.sort.common.SortRule; -import org.apache.batik.transcoder.TranscoderInput; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; public class HeaderSortRulePane extends JPanel { - private static final String ASC_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/asc.svg"; - private static final String DES_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/des.svg"; - private static final String NOSORT_ICON_TEMPLATE_PATH = "/com/fr/design/images/sort/nosort.svg"; - private static final double ICON_SCALE = SVGIcon.SYSTEM_SCALE * 1.25; - private static final int ICON_LENGTH = (int) Math.ceil(16 * ICON_SCALE); IconButton ascIconButton; IconButton desIconButton; IconButton nosortIconButton; UICheckBox ascUICheckBox; UICheckBox desUICheckBox; UICheckBox nosortUICheckBox; - static Map originalSvgTextMap = new HashMap<>(); + Color defaultColor = new Color(33, 33, 34); HeaderSortRulePane() { initComponents(); @@ -61,12 +53,12 @@ public class HeaderSortRulePane extends JPanel { void initSortRuleItem() { Component[][] components = new Component[][]{ - new Component[]{ascUICheckBox = new UICheckBox(SortRule.ASC.getDescription()), ascIconButton = new IconButton(ASC_ICON_TEMPLATE_PATH)}, - new Component[]{desUICheckBox = new UICheckBox(SortRule.DES.getDescription()), desIconButton = new IconButton(DES_ICON_TEMPLATE_PATH)}, - new Component[]{nosortUICheckBox = new UICheckBox(SortRule.NO_SORT.getDescription()), nosortIconButton = new IconButton(NOSORT_ICON_TEMPLATE_PATH)}, + new Component[]{ascUICheckBox = new UICheckBox(SortRule.ASC.getDescription()), ascIconButton = new IconButton(SortRule.ASC)}, + new Component[]{desUICheckBox = new UICheckBox(SortRule.DES.getDescription()), desIconButton = new IconButton(SortRule.DES)}, + new Component[]{nosortUICheckBox = new UICheckBox(SortRule.NO_SORT.getDescription()), nosortIconButton = new IconButton(SortRule.NO_SORT)}, }; - double[] rowSize = {ICON_LENGTH + 10, ICON_LENGTH + 10, ICON_LENGTH + 10}; - double[] columnSize = {80, ICON_LENGTH + 10}; + double[] rowSize = {HeaderIconBuilder.ICON_LENGTH + 10, HeaderIconBuilder.ICON_LENGTH + 10, HeaderIconBuilder.ICON_LENGTH + 10}; + double[] columnSize = {80, HeaderIconBuilder.ICON_LENGTH + 10}; JPanel sortRuleItem = TableLayoutHelper.createCommonTableLayoutPane(components, rowSize, columnSize, 0); this.add(sortRuleItem, BorderLayout.CENTER); initUICheckBoxChange(ascUICheckBox, ascIconButton); @@ -87,24 +79,23 @@ public class HeaderSortRulePane extends JPanel { ascUICheckBox.setSelected(selected); desUICheckBox.setSelected(selected); nosortUICheckBox.setSelected(selected); - ascIconButton.refreshIconLabelColor(new Color(33, 33, 34)); - desIconButton.refreshIconLabelColor(new Color(33, 33, 34)); - nosortIconButton.refreshIconLabelColor(new Color(33, 33, 34)); + ascIconButton.refreshIconLabelColor(new FineColor(defaultColor)); + desIconButton.refreshIconLabelColor(new FineColor(defaultColor)); + nosortIconButton.refreshIconLabelColor(new FineColor(defaultColor)); } - class IconButton extends JPanel implements UIObserver { + class IconButton extends JPanel implements UIObserver, PopupHider { + SortRule sortRule; JLayeredPane jLayeredPane; - String iconTemplatePath; UILabel iconLabel; - ColorListPane.ColorButton colorButton; - Color color; - BufferedImage bufferedImage; + FineColor fineColor = new FineColor(defaultColor); UIObserverListener uiObserverListener; boolean activeState; UILabel borderUiLabel; + private ColorControlWindow colorSelector; - IconButton(String iconTemplatePath) { - this.iconTemplatePath = iconTemplatePath; + IconButton(SortRule sortRule) { + this.sortRule = sortRule; initComponents(); } @@ -115,48 +106,48 @@ public class HeaderSortRulePane extends JPanel { public void setActiveState(boolean activeState) { if (activeState) { borderUiLabel.setBorder(BorderFactory.createLineBorder(Color.gray, 1)); - colorButton.setVisible(true); } else { borderUiLabel.setBorder(null); - colorButton.setVisible(false); } this.activeState = activeState; } void initComponents() { jLayeredPane = new JLayeredPane(); - iconLabel = getIconLabel(iconTemplatePath); + iconLabel = getIconLabel(); borderUiLabel = new UILabel(); - borderUiLabel.setSize(ICON_LENGTH, ICON_LENGTH); + borderUiLabel.setSize(HeaderIconBuilder.ICON_LENGTH, HeaderIconBuilder.ICON_LENGTH); borderUiLabel.setOpaque(true); borderUiLabel.setBackground(Color.WHITE); - iconLabel.setSize(ICON_LENGTH, ICON_LENGTH); - colorButton = new ColorListPane.ColorButton(Color.CYAN); - colorButton.setSize(ICON_LENGTH, ICON_LENGTH); - colorButton.addChangeListener(new ChangeListener() { + iconLabel.setSize(HeaderIconBuilder.ICON_LENGTH, HeaderIconBuilder.ICON_LENGTH); + iconLabel.addMouseListener(new MouseAdapter() { @Override - public void stateChanged(ChangeEvent e) { - color = colorButton.getSelectObject(); - refreshIconLabelColor(color); - uiObserverListener.doChange(); + public void mouseClicked(MouseEvent e) { + if (activeState) { + showPopupMenu(); + } } }); - jLayeredPane.setPreferredSize(new Dimension(ICON_LENGTH, ICON_LENGTH)); - + jLayeredPane.setPreferredSize(new Dimension(HeaderIconBuilder.ICON_LENGTH, HeaderIconBuilder.ICON_LENGTH)); jLayeredPane.add(iconLabel, JLayeredPane.POPUP_LAYER); jLayeredPane.add(borderUiLabel, JLayeredPane.MODAL_LAYER); - jLayeredPane.add(colorButton, JLayeredPane.PALETTE_LAYER); this.add(jLayeredPane); } - void refreshIconLabelColor(Color color) { - Icon icon = getIcon(iconTemplatePath, color); + void refreshIconLabelColor(FineColor fineColor) { + this.fineColor = fineColor; + Icon icon = getIcon(fineColor); refreshIconLabel(icon); } + Icon getIcon(FineColor fineColor) { + BufferedImage bufferedImage = HeaderIconBuilder.getIcon(sortRule, fineColor); + Icon icon = new ImageIcon(bufferedImage); + return icon; + } + void refreshIconLabel(BufferedImage bufferedImage) { if (bufferedImage != null) { - this.bufferedImage = bufferedImage; Icon icon = new SVGIcon(bufferedImage); refreshIconLabel(icon); } @@ -170,64 +161,46 @@ public class HeaderSortRulePane extends JPanel { } } - UILabel getIconLabel(String iconPath) { - return getIconLabel(iconPath, new Color(33, 33, 34)); + UILabel getIconLabel() { + return getIconLabel(new FineColor(defaultColor)); } - UILabel getIconLabel(String iconPath, Color color) { - Icon svgIcon = getIcon(iconPath, color); + UILabel getIconLabel(FineColor fineColor) { + Icon svgIcon = getIcon(fineColor); return new UILabel(svgIcon); } - Icon getIcon(String iconPath, Color color) { - try { - String originalSvgText = getOriginalSvgText(iconPath); - String svgText = originalSvgText.replaceAll("\\{fillColor\\}", shiftColor(color)); - InputStream svgInputStream = new ByteArrayInputStream(svgText.getBytes(StandardCharsets.UTF_8)); - TranscoderInput input = new TranscoderInput(svgInputStream); - bufferedImage = SVGTranscoder.createImage(ICON_SCALE, input).getImage(); - SVGIcon svgIcon = new SVGIcon(bufferedImage); - return svgIcon; - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e, e.getMessage()); - } - return null; + private void showPopupMenu() { + hidePopupMenu(); + colorSelector = this.getColorSelector(); + GUICoreUtils.showPopupMenu(colorSelector, this, 0, this.getSize().height); } - String getOriginalSvgText(String iconPath) throws Exception { - String originalSvgText = originalSvgTextMap.get(iconPath); - if (originalSvgText == null) { - InputStream inputStream = IOUtils.getResourceAsStream(iconPath, HeaderSortRulePane.class); - originalSvgText = getSvgText(inputStream); - originalSvgTextMap.put(iconPath, originalSvgText); + @Override + public void hidePopupMenu() { + if (colorSelector != null) { + colorSelector.setVisible(false); } - return originalSvgText; - } - - String shiftColor(Color color) { - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(shiftValue(color.getRed())); - stringBuilder.append(shiftValue(color.getGreen())); - stringBuilder.append(shiftValue(color.getBlue())); - return stringBuilder.toString(); + colorSelector = null; } - String shiftValue(int value) { - String resultValue = Integer.toHexString(value); - if (resultValue.length() == 1) { - resultValue = "0" + resultValue; - } - return resultValue; + private ColorControlWindow getColorSelector() { + return new ColorControlWindow(false, IconButton.this) { + @Override + protected void colorChanged() { + Color color = this.getColor(); + if (color instanceof FineColor) { + fineColor = (FineColor) color; + } else { + fineColor = new FineColor(color); + } + refreshIconLabelColor(fineColor); + hidePopupMenu(); + uiObserverListener.doChange(); + } + }; } - private String getSvgText(InputStream inputStream) throws Exception { - StringBuffer stringBuffer = new StringBuffer(); - byte[] b = new byte[1024]; - for (int n; (n = inputStream.read(b)) != -1; ) { - stringBuffer.append(new String(b, 0, n)); - } - return stringBuffer.toString(); - } @Override public void registerChangeListener(UIObserverListener uiObserverListener) { @@ -256,7 +229,6 @@ public class HeaderSortRulePane extends JPanel { nosortIconButton.refreshIconLabel(bufferedImage); nosortUICheckBox.setSelected(true); } - } } } @@ -264,13 +236,13 @@ public class HeaderSortRulePane extends JPanel { public SortHeader.SortItem[] updateBean() { java.util.List items = new ArrayList<>(); if (ascUICheckBox.isSelected()) { - items.add(new SortHeader.SortItem(SortRule.ASC, ascIconButton.bufferedImage)); + items.add(new SortHeader.SortItem(SortRule.ASC, ascIconButton.fineColor)); } if (desUICheckBox.isSelected()) { - items.add(new SortHeader.SortItem(SortRule.DES, desIconButton.bufferedImage)); + items.add(new SortHeader.SortItem(SortRule.DES, desIconButton.fineColor)); } if (nosortUICheckBox.isSelected()) { - items.add(new SortHeader.SortItem(SortRule.NO_SORT, nosortIconButton.bufferedImage)); + items.add(new SortHeader.SortItem(SortRule.NO_SORT, nosortIconButton.fineColor)); } SortHeader.SortItem[] resultItems = new SortHeader.SortItem[items.size()]; return items.toArray(resultItems); diff --git a/designer-realize/src/main/java/com/fr/design/sort/header/SortHeaderPane.java b/designer-realize/src/main/java/com/fr/design/sort/header/SortHeaderPane.java index a68d0eebe6..77802429ca 100644 --- a/designer-realize/src/main/java/com/fr/design/sort/header/SortHeaderPane.java +++ b/designer-realize/src/main/java/com/fr/design/sort/header/SortHeaderPane.java @@ -34,7 +34,7 @@ public class SortHeaderPane extends JPanel { this.add(headerSettingPane); } - public void populateBean(SortHeader sortHeader, String defaultHeaderArea) { + public void populateBean(SortHeader sortHeader, String defaultHeaderArea,TemplateCellElement cellElement) { this.sortHeader = sortHeader; boolean showHeaderArea = false; SortHeader.SortItem[] sortItems = null; @@ -48,7 +48,7 @@ public class SortHeaderPane extends JPanel { columnRow = ColumnRow.valueOf(headerArea); } } - headerAreaPane.populateBean(columnRow, showHeaderArea); + headerAreaPane.populateBean(columnRow, showHeaderArea, cellElement); headerSettingPane.populateBean(sortItems); } diff --git a/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java b/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java index 3818f1ac80..193fd4de9a 100644 --- a/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java +++ b/designer-realize/src/main/java/com/fr/design/write/submit/SmartInsertDBManipulationPane.java @@ -291,6 +291,10 @@ public class SmartInsertDBManipulationPane extends DBManipulationPane { @Override public void checkValid() throws Exception { KeyColumnTableModel model = (KeyColumnTableModel) keyColumnValuesTable.getModel(); + checkModelValid(model); + } + + private void checkModelValid(KeyColumnTableModel model) throws Exception { int cnt = model.getRowCount(); int groupLength = -1; for (int i = 0; i < cnt; i++) { @@ -374,7 +378,8 @@ public class SmartInsertDBManipulationPane extends DBManipulationPane { */ @Override public void checkValid() throws Exception { - SmartInsertDBManipulationPane.this.checkValid(); + KeyColumnTableModel model = (KeyColumnTableModel) table.getModel(); + SmartInsertDBManipulationPane.this.checkModelValid(model); } private SelectionListener listener = new SelectionListener() { diff --git a/designer-realize/src/main/java/com/fr/poly/PolyDesigner.java b/designer-realize/src/main/java/com/fr/poly/PolyDesigner.java index 437cb8ea12..494b7e4c60 100644 --- a/designer-realize/src/main/java/com/fr/poly/PolyDesigner.java +++ b/designer-realize/src/main/java/com/fr/poly/PolyDesigner.java @@ -5,6 +5,7 @@ package com.fr.poly; import com.fr.base.GraphHelper; import com.fr.base.ScreenResolution; +import com.fr.base.TRL; import com.fr.base.vcs.DesignerMode; import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.DesignState; @@ -65,6 +66,7 @@ import com.fr.stable.unit.FU; import com.fr.stable.unit.OLDPIX; import com.fr.stable.unit.UNIT; import com.fr.stable.unit.UnitRectangle; +import org.jetbrains.annotations.Nullable; import javax.swing.AbstractAction; import javax.swing.ActionMap; @@ -124,7 +126,7 @@ public class PolyDesigner extends ReportComponent 0 && elementCasePane != null) { + elementCasePane.navigate(trl); + } + + } + + @Nullable + private BlockCreator getBlock(String blockName) { + for (int i = 0; i < addedData.getAddedCount(); i++) { + BlockCreator creator = addedData.getAddedAt(i); + if (ComparatorUtils.equals(blockName, creator.getValue().getBlockName())) { + return creator; + } + } + return null; + } } diff --git a/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java b/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java index 9a584836be..33bcda20a6 100644 --- a/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java +++ b/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java @@ -3,6 +3,7 @@ */ package com.fr.poly.creator; +import com.fr.base.TRL; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignState; import com.fr.design.actions.UpdateAction; @@ -32,11 +33,16 @@ import com.fr.design.menu.MenuDef; import com.fr.design.menu.SeparatorDef; import com.fr.design.selection.SelectionEvent; import com.fr.design.selection.SelectionListener; +import com.fr.grid.selection.CellSelection; +import com.fr.grid.selection.FloatSelection; import com.fr.page.ReportSettingsProvider; import com.fr.poly.PolyDesigner; import com.fr.report.poly.PolyECBlock; import com.fr.stable.ArrayUtils; +import com.fr.stable.ColumnRow; +import com.fr.stable.StringUtils; +import javax.swing.JScrollBar; import java.awt.Dimension; /** @@ -171,4 +177,27 @@ public class ECBlockPane extends PolyElementCasePane { return designer.getTemplateReport().getReportSettings(); } + @Override + public void navigate(TRL trl) { + String cellName = trl.next(); + if (StringUtils.isEmpty(cellName)) { + return; + } + ColumnRow columnRow = ColumnRow.valueOf(cellName); + if (!ColumnRow.validate(columnRow) || columnRow.getColumn() > 10000) { + setSelection(new FloatSelection(TRL.unescape(cellName))); + return; + } + CellSelection cellSelection = new CellSelection(columnRow.getColumn(), columnRow.getRow(), columnRow.getColumnSpan(), columnRow.getRowSpan()); + // 滚动到位 + JScrollBar verticalBar = getVerticalScrollBar(), + horizontalBar = getHorizontalScrollBar(); + int m = columnRow.getColumn(), n = columnRow.getRow(); + verticalBar.setMaximum(n); + verticalBar.setValue(n < 21 ? verticalBar.getValue() : n - 20); + horizontalBar.setMaximum(m); + horizontalBar.setValue(m < 13 ? horizontalBar.getValue() : m - 12); + // 选中 + setSelection(cellSelection); + } } diff --git a/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.java b/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.java index 2a4852ee88..23015e9d09 100644 --- a/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.java +++ b/designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.java @@ -44,7 +44,6 @@ import com.fr.report.cell.cellattr.core.group.DSColumn; import com.fr.report.cell.cellattr.core.group.FilterTypeEnum; import com.fr.report.cell.cellattr.core.group.SelectCount; import com.fr.stable.StringUtils; -import com.fr.third.jodd.util.ArraysUtil; import javax.swing.BorderFactory; import javax.swing.Icon; @@ -622,7 +621,7 @@ public class CellDSColumnEditor extends CellQuickEditor { //显示set和tip setCardPane.setPreferredSize(new Dimension(156, 20)); TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 2, VGAP); - tipCardPane.setPreferredSize(new Dimension(224, 40)); + tipCardPane.setPreferredSize(new Dimension(224, 50)); TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 4, VGAP_INNER); } else { //未定义 @@ -746,7 +745,7 @@ public class CellDSColumnEditor extends CellQuickEditor { //显示set和tip setCardPane.setPreferredSize(new Dimension(156, 20)); TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 2, VGAP); - tipCardPane.setPreferredSize(new Dimension(224, 40)); + tipCardPane.setPreferredSize(new Dimension(224, 50)); TableLayoutHelper.modifyTableLayoutIndexVGap(contentPane, 4, VGAP_INNER); break; case EVEN: 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 f953df4668..e29a4e804a 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -11,6 +11,7 @@ import com.fr.design.actions.server.TemplateThemeManagerAction; import com.fr.design.actions.server.WidgetManagerAction; import com.fr.design.base.mode.DesignModeContext; import com.fr.design.constants.UIConstants; +import com.fr.design.deeplink.DeepLinkManager; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.MutilTempalteTabPane; @@ -106,6 +107,7 @@ public class MainDesigner extends BaseDesigner { */ public static void main(String[] args) { + DeepLinkManager.getInstance().start(args); StopWatch watch = new StopWatch(); watch.start(); DesignerLifecycleMonitorContext.getMonitor().beforeStart(); 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 eea3360bae..be583c7d56 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 @@ -12,6 +12,8 @@ import com.fr.chart.chartattr.ChartCollection; import com.fr.config.MarketConfig; import com.fr.config.ServerPreferenceConfig; import com.fr.decision.update.backup.RecoverManager; +import com.fr.decision.webservice.v10.plugin.helper.category.impl.PluginResourceLoader; +import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.NewFormAction; @@ -180,6 +182,8 @@ public class DesignerActivator extends Activator implements Prepare { AlphaFineHelper.switchConfig4Locale(); RecoverManager.register(new RecoverForDesigner()); pushUpdateTask.run(); + PluginResourceLoader.INSTANCE.checkOldShopFile(); + UpmResourceLoader.INSTANCE.checkOldShopFile(); } @Override