diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index 16c1a7e8a..1f3055d40 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -1,6 +1,7 @@ package com.fr.design; import com.fr.common.report.ReportState; +import com.fr.design.env.processor.RemoteDesignerWorkspaceInfoProcessor; import com.fr.design.mainframe.manager.clip.TemplateTreeClipboard; import com.fr.design.plugin.remind.PluginErrorDesignReminder; import com.fr.design.data.DesignTableDataManager; @@ -101,6 +102,29 @@ public class EnvChangeEntrance { } } + /** + * 插件进行用户名转换 + * + * @param workspaceInfo 环境信息 + */ + private DesignerWorkspaceInfo customUserName(DesignerWorkspaceInfo workspaceInfo) { + //本地环境直接返回 + if (workspaceInfo == null || workspaceInfo.getType() == DesignerWorkspaceType.Local) { + return workspaceInfo; + } + RemoteDesignerWorkspaceInfoProcessor processor = ExtraDesignClassManager.getInstance().getSingle(RemoteDesignerWorkspaceInfoProcessor.XML_TAG); + if (processor == null) { + return workspaceInfo; + } + try { + WorkspaceConnectionInfo workspaceConnectionInfo = processor.customUserName(workspaceInfo.getConnection()); + return (RemoteDesignerWorkspaceInfo) ((RemoteDesignerWorkspaceInfo) workspaceInfo).cloneWithConnectionInfo(workspaceConnectionInfo); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return workspaceInfo; + } + } + /** * 切换到新环境 * @@ -109,7 +133,7 @@ public class EnvChangeEntrance { */ private boolean switch2Env(final String envName, PopTipStrategy strategy) { DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); - DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + DesignerWorkspaceInfo selectedEnv = customUserName(envManager.getWorkspaceInfo(envName)); DesignerWorkspaceInfoContext.setWorkspaceInfo(selectedEnv); WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); diff --git a/designer-base/src/main/java/com/fr/design/actions/help/SystemInfoPane.java b/designer-base/src/main/java/com/fr/design/actions/help/SystemInfoPane.java index 7fe26054f..db5c21e69 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/SystemInfoPane.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/SystemInfoPane.java @@ -41,16 +41,12 @@ public class SystemInfoPane extends JPanel { for (int i = 0; i < keys.length; i++) { Object[] tableRowData = new Object[2]; String keyValue = keys[i].toString(); - // james:屏蔽掉exe4j的内容 - if (keyValue.indexOf("exe4j") != -1) { - continue; - } - // james:这个也是exe4j的东东 - if ("install4j.exeDir".equals(keyValue)) { + + if (needToShield(keyValue)) { continue; } - if(keyValue.indexOf("FineReport") != -1){ + if(keyValue.contains("FineReport")){ keys[i] = keyValue.replaceAll("FineReport", ProductConstants.APP_NAME); } @@ -66,4 +62,14 @@ public class SystemInfoPane extends JPanel { add(new JScrollPane(table), BorderLayout.CENTER); } + + /** + * 是否属于需要屏蔽的内容(当前屏蔽掉exe4j与jxbrowser的内容) + * + * @param keyValue 对应的key值 + * @return 需要屏蔽则返回true + */ + private boolean needToShield(String keyValue) { + return keyValue.contains("exe4j") || keyValue.contains("jxbrowser") || "install4j.exeDir".equals(keyValue); + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/RemindPane.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/RemindPane.java index 1d8d99266..aeab19aca 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/RemindPane.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/RemindPane.java @@ -4,10 +4,21 @@ import com.fr.design.dialog.UIDialog; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.general.IOUtils; - - -import javax.swing.*; -import java.awt.*; +import com.fr.general.locale.image.I18nImage; + +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.LayoutManager; +import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -23,8 +34,10 @@ public class RemindPane extends JPanel { private Icon checkIcon = IOUtils.readIcon("/com/fr/design/mainframe/alphafine/images/check.png"); private Icon unCheckIcon = IOUtils.readIcon("/com/fr/design/mainframe/alphafine/images/uncheck.png"); private Icon closeIcon = IOUtils.readIcon("/com/fr/design/mainframe/alphafine/images/remind_close.png"); - private Icon labelIcon = IOUtils.readIcon("/com/fr/design/mainframe/alphafine/images/remind.png"); - private Icon openIcon = IOUtils.readIcon("com/fr/design/mainframe/alphafine/images/open.png"); + private static final String REMIND_IMAGE_URL = "/com/fr/design/mainframe/alphafine/images/open/open.png"; + private Icon labelIcon = new ImageIcon(I18nImage.getImage(REMIND_IMAGE_URL)); + private static final String OPEN_IMAGE_URL = "/com/fr/design/mainframe/alphafine/images/open/open.png"; + private final Icon openIcon = new ImageIcon(I18nImage.getImage(OPEN_IMAGE_URL)); private static final int WIDTH = 600; private static final int HEIGHT = 400; diff --git a/designer-base/src/main/java/com/fr/design/components/table/TablePanel.java b/designer-base/src/main/java/com/fr/design/components/table/TablePanel.java index 317a17195..b2e8ceb35 100644 --- a/designer-base/src/main/java/com/fr/design/components/table/TablePanel.java +++ b/designer-base/src/main/java/com/fr/design/components/table/TablePanel.java @@ -161,6 +161,20 @@ public class TablePanel extends JPanel { } cellPanel.add(component); } + + /** + * 为单元格Panel更新tooltip + * + * @param row 行数 + * @param column 列数 + * @param value tooltip值 + */ + public void updateCellToolTip(int row, int column, String value) { + int x = row - 1; + int y = column - 1; + JPanel cellPanel = this.cellPanels[x][y]; + cellPanel.setToolTipText(value); + } public void updateCell(int row, int column, String value) { diff --git a/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java b/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java index 920a13dbf..39abe75cf 100644 --- a/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java +++ b/designer-base/src/main/java/com/fr/design/env/RemoteDesignerWorkspaceInfo.java @@ -6,6 +6,7 @@ import com.fr.log.FineLoggerFactory; import com.fr.security.SecurityToolbox; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; +import com.fr.stable.fun.mark.Immutable; import com.fr.stable.project.ProjectConstants; import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.XMLableReader; @@ -166,6 +167,15 @@ public class RemoteDesignerWorkspaceInfo implements DesignerWorkspaceInfo { return object; } + /** + * clone一个自定义连接信息的RemoteDesignerWorkspaceInfo + */ + public Object cloneWithConnectionInfo(WorkspaceConnectionInfo workspaceConnectionInfo) throws CloneNotSupportedException { + RemoteDesignerWorkspaceInfo object = (RemoteDesignerWorkspaceInfo) super.clone(); + object.connection = workspaceConnectionInfo; + return object; + } + @Override public boolean checkValid() throws Exception { diff --git a/designer-base/src/main/java/com/fr/design/env/processor/AbstractRemoteDesignerWorkspaceInfoProcessor.java b/designer-base/src/main/java/com/fr/design/env/processor/AbstractRemoteDesignerWorkspaceInfoProcessor.java new file mode 100644 index 000000000..6917f1745 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/env/processor/AbstractRemoteDesignerWorkspaceInfoProcessor.java @@ -0,0 +1,24 @@ +package com.fr.design.env.processor; + +import com.fr.stable.fun.mark.API; + + +/** + * 远程设计自定义用户名接口实现抽象类 + * + * @author John.Ying + * @since 11.0 + * Created on 2023/5/17 + */ +@API(level = RemoteDesignerWorkspaceInfoProcessor.CURRENT_LEVEL) +public abstract class AbstractRemoteDesignerWorkspaceInfoProcessor implements RemoteDesignerWorkspaceInfoProcessor { + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} diff --git a/designer-base/src/main/java/com/fr/design/env/processor/RemoteDesignerWorkspaceInfoProcessor.java b/designer-base/src/main/java/com/fr/design/env/processor/RemoteDesignerWorkspaceInfoProcessor.java new file mode 100644 index 000000000..b74d21159 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/env/processor/RemoteDesignerWorkspaceInfoProcessor.java @@ -0,0 +1,25 @@ +package com.fr.design.env.processor; + +import com.fr.stable.fun.mark.Immutable; +import com.fr.workspace.connect.WorkspaceConnectionInfo; + +/** + * 远程设计自定义用户名接口 + * px:为了二开插件开的接口,不建议实现,后面可能会变动 + * + * @author John.Ying + * @since 11.0 + * Created on 2023/5/17 + */ +public interface RemoteDesignerWorkspaceInfoProcessor extends Immutable { + + String XML_TAG = "RemoteDesignerWorkspaceInfoProcessor"; + + int CURRENT_LEVEL = 1; + + /** + * 根据链接信息自定义用户名 + */ + WorkspaceConnectionInfo customUserName(WorkspaceConnectionInfo workspaceInfo); + +} diff --git a/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java b/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java index 1bcfe3c62..1d2048fa2 100644 --- a/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java +++ b/designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java @@ -28,7 +28,6 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.collections.CollectionUtils; import com.fr.stable.project.ProjectConstants; -import com.fr.workspace.WorkContext; import javax.swing.BorderFactory; import javax.swing.JDialog; @@ -221,6 +220,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi /** * 检测是否能够黏贴 + * * @param treeNodeList * @return */ @@ -271,7 +271,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi } } } catch (Exception e) { - FineLoggerFactory.getLogger().error(e,"Template paste failed.", e.getMessage()); + FineLoggerFactory.getLogger().error(e, "Template paste failed.", e.getMessage()); FineJOptionPane.showConfirmDialog(null, Toolkit.i18nText("Fine-Design_Basic_Paste_Failure"), Toolkit.i18nText("Fine-Design_Basic_Error"), @@ -286,7 +286,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi /** * 确认粘贴的目标目录是否是复制文件的子目录,并确认是否继续执行粘贴任务 * - * @param targetDir 目标文件夹 + * @param targetDir 目标文件夹 * @param pasteNodes 待粘贴的文件 * @return 是否继续 */ @@ -433,6 +433,14 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi WARNING_MESSAGE); return false; } + // 检查移动的源文件夹是否为目标文件夹相同文件夹或子文件夹 + if (FileOperationHelper.getInstance().isSubDirectoryOrSame(getFileTree().getSelectedTreeNodes(), getTargetFileNode())) { + FineJOptionPane.showMessageDialog(this, + Toolkit.i18nText("Fine-Design_Basic_Move_To_SubDirectory"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + WARNING_MESSAGE); + return false; + } if (TemplateUtils.checkSelectedTemplateIsEditing()) { return FineJOptionPane.showConfirmDialog(this, Toolkit.i18nText("Fine-Design_Basic_Template_Is_Editing"), @@ -443,9 +451,7 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi } private boolean doMove() { - FileNode fileNode = getDirTree().getSelectedFileNode(); - ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) getDirTree().getModel().getRoot(); - fileNode = fileNode == null ? (FileNode) rootTreeNode.getUserObject() : fileNode; + FileNode fileNode = getTargetFileNode(); boolean moveSuccess = true; try { //待移动的文件可以有多个 @@ -465,6 +471,12 @@ public class DefaultTemplateTreeDefineProcessor extends AbstractTemplateTreeDefi return moveSuccess; } + private FileNode getTargetFileNode() { + FileNode fileNode = getDirTree().getSelectedFileNode(); + ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) getDirTree().getModel().getRoot(); + return fileNode == null ? (FileNode) rootTreeNode.getUserObject() : fileNode; + } + @Override public void dispose() { TemplateDirTreeSearchManager.getInstance().outOfSearchMode(); diff --git a/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java b/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java index a3abaf460..8bf57ae4e 100644 --- a/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java +++ b/designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java @@ -16,7 +16,10 @@ import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; import com.fr.workspace.resource.ResourceIOException; +import org.jetbrains.annotations.NotNull; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import static javax.swing.JOptionPane.WARNING_MESSAGE; @@ -32,6 +35,38 @@ public class FileOperationHelper { return INSTANCE; } + /** + * 检查目标文件夹是否为多个源文件夹中的任一文件夹,或者任一文件夹的子文件夹 + * + * @param fileNodes 需移动的源文件 + * @param targetNode 移动后的目标文件夹 + * @return + */ + public boolean isSubDirectoryOrSame(@NotNull ExpandMutableTreeNode[] fileNodes, @NotNull FileNode targetNode) { + for (ExpandMutableTreeNode treeNode : fileNodes) { + FileNode sourceFileNode = (FileNode) treeNode.getUserObject(); + if (isSubDirectoryOrSame(sourceFileNode, targetNode)) { + return true; + } + } + return false; + } + + /** + * 检查目标文件夹是否为源文件夹,或源文件夹的子文件夹 + * + * @param sourceFileNode 需移动的源文件 + * @param targetNode 移动后的目标文件夹 + */ + public boolean isSubDirectoryOrSame(@NotNull FileNode sourceFileNode, @NotNull FileNode targetNode) { + if (!sourceFileNode.isDirectory() || !targetNode.isDirectory()) { + return false; + } + Path sourceDir = Paths.get(sourceFileNode.getEnvPath()).normalize(); + Path targetDir = Paths.get(targetNode.getEnvPath()).normalize(); + return targetDir.startsWith(sourceDir); + } + public String moveFile(FileNode sourceFileNode, String targetDir) { String targetPath = copyFileAndVcs(sourceFileNode, targetDir); FileNodeFILE nodeFILE = new FileNodeFILE(sourceFileNode); @@ -51,8 +86,9 @@ public class FileOperationHelper { /** * 拷贝文件的同时拷贝对应的版本控制文件 + * * @param sourceFile 源文件或目录 - * @param targetDir 目标目录 + * @param targetDir 目标目录 * @return 复制后的目标文件的路径 */ public String copyFileAndVcs(FileNode sourceFile, String targetDir) { @@ -61,8 +97,9 @@ public class FileOperationHelper { /** * 只拷贝文件, 不拷贝对应的版本控制文件 + * * @param sourceFile 源文件或目录 - * @param targetDir 目标目录 + * @param targetDir 目标目录 * @return 复制后的目标文件的路径 */ public String copyFile(FileNode sourceFile, String targetDir) { @@ -71,7 +108,8 @@ public class FileOperationHelper { /** * 检测节点是否被锁住了 - * @param node 待检测节点 + * + * @param node 待检测节点 * @param dNodes 没有锁住的节点集合 * @param lNodes 锁住的节点集合 * @return 是否存在被锁住的文件 @@ -165,7 +203,7 @@ public class FileOperationHelper { } else { if (!TemplateResourceManager.getResource().copy(sourcePath, targetPath)) { throw new ResourceIOException(String.format("copy file failed, from %s to %s", sourcePath, targetPath)); - } else if (withCopyVcs){ + } else if (withCopyVcs) { sourcePath = sourcePath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY); targetPath = targetPath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY); VcsHelper.getInstance().moveVcs(sourcePath, targetPath); 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 74b159620..4116f4f1d 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 @@ -20,6 +20,7 @@ import com.fr.design.javascript.jsapi.JSAPITreeHelper; import com.fr.design.javascript.jsapi.JSAPIUserObject; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.general.ComparatorUtils; +import com.fr.general.GeneralContext; import com.fr.general.http.HttpToolbox; import com.fr.json.JSONArray; import com.fr.json.JSONException; @@ -70,6 +71,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; import java.util.concurrent.ExecutionException; public class JSContentWithDescriptionPane extends JSContentPane implements KeyListener { @@ -393,9 +395,13 @@ public class JSContentWithDescriptionPane extends JSContentPane implements KeyLi private void updateHelpDocuments(Object value, List helpDocuments) { String url = LocaleLinkProvider.getInstance().getLink(PROPS_LINK_KEY, PROPS_LINK_KEY_DEFAULT) + value.toString(); try { - String result = HttpToolbox.get(url); - JSONObject jsonObject = new JSONObject(result); - JSONArray jsonArray = jsonObject.optJSONArray("list"); + JSONArray jsonArray = null; + //目前简中繁中之外的语言高级编辑器功能及文档不完善,右侧展示的文档链接列表暂时为空白 + if(GeneralContext.isChineseEnv()) { + String result = HttpToolbox.get(url); + JSONObject jsonObject = new JSONObject(result); + jsonArray = jsonObject.optJSONArray("list"); + } if (jsonArray != null) { for (int i = 0; i < jsonArray.length(); i++) { JSONObject resultJSONObject = jsonArray.optJSONObject(i); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java index 8cfd26342..fc2f9c658 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java @@ -54,6 +54,7 @@ import com.fr.plugin.injectable.PluginModule; import com.fr.plugin.manage.PluginFilter; import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEventListener; +import com.fr.report.lock.LockInfoOperator; import com.fr.stable.CoreConstants; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; @@ -61,7 +62,6 @@ import com.fr.stable.project.ProjectConstants; import com.fr.third.org.apache.commons.io.FilenameUtils; import com.fr.workspace.WorkContext; -import com.fr.report.lock.LockInfoOperator; import javax.swing.BorderFactory; import javax.swing.JDialog; import javax.swing.JOptionPane; @@ -537,7 +537,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt } private boolean pathSupportVcsAction(String path) { - if (FileExtension.CPT.matchExtension(path) || FileExtension.FRM.matchExtension(path)) { + if (FileExtension.CPT.matchExtension(path) || FileExtension.FRM.matchExtension(path) || FileExtension.VIS.matchExtension(path)) { return true; } return false; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java index fcfa4292f..d850e8e81 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java @@ -157,7 +157,8 @@ public class NorthRegionContainerPane extends JPanel { if (!DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) { ad.createAlphaFinePane().setVisible(false); } - northEastPane.add(ad.createGuideEntryPane()); + /// 新手引导功能,暂时屏蔽 + // northEastPane.add(ad.createGuideEntryPane()); northEastPane.add(ad.createNotificationCenterPane()); OSSupportCenter.buildAction(new OSBasedAction() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/AbstractMobileStyleDefinePaneCreator.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/AbstractMobileStyleDefinePaneCreator.java new file mode 100644 index 000000000..203a83f13 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/AbstractMobileStyleDefinePaneCreator.java @@ -0,0 +1,23 @@ +package com.fr.design.mainframe.mobile.processor; + +import com.fr.stable.fun.mark.API; + +/** + * 移动端Form控件,样式模板,通用属性替换接口 + * + * @author Coral.Chen + * @since 11.0 + * Created on 2023/4/11 + */ +@API(level = MobileStyleDefinePaneCreator.CURRENT_LEVEL) +public abstract class AbstractMobileStyleDefinePaneCreator implements MobileStyleDefinePaneCreator { + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/MobileStyleDefinePaneCreator.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/MobileStyleDefinePaneCreator.java new file mode 100644 index 000000000..3b5e2cb86 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/MobileStyleDefinePaneCreator.java @@ -0,0 +1,40 @@ +package com.fr.design.mainframe.mobile.processor; + +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.mainframe.mobile.ui.MobileStyleCustomDefinePane; +import com.fr.form.ui.Widget; +import com.fr.form.ui.mobile.MobileCommonExtraStyle; +import com.fr.form.ui.mobile.MobileStyle; +import com.fr.stable.fun.mark.Immutable; +import org.jetbrains.annotations.Nullable; + +/** + * 移动端Form控件,样式模板,通用属性替换接口 + * + * @author Coral.Chen + * @since 11.0 + * Created on 2023/4/11 + */ +public interface MobileStyleDefinePaneCreator extends Immutable { + String XML_TAG = "MobileStyleDefinePaneCreator"; + + int CURRENT_LEVEL = 1; + + /** + *

创建通用属性样式界面,可替换{@link com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane} + *

每种样式的通用属性面板是一样的 + * + * @param widget 控件 + * @param customDefinePane 自定义面板 + * @param mobileStyle 移动端样式 + * @return + */ + @Nullable BasicBeanPane createBaseBeanPane(Widget widget, Class customDefinePane, Class mobileStyle); + + /** + * 替换通用属性面板,注册额外属性 + * + * @return 属性类 + */ + @Nullable Class classForCommonExtraStyle(Widget widget); +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java index 6c03df00d..268672fb3 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java @@ -53,22 +53,28 @@ public class MobileStyleDefinePane extends BasicBeanPane { private UISpinner borderRadius; private NewColorSelectBox iconColor; private MobileStyleFontConfigPane fontConfigPane; + private MobileStyle mobileStyle; MobileStyleDefinePane(Widget widget, Class customBeanPaneClass, Class mobileStyleClazz) { this.widget = widget; this.customBeanPane = Reflect.on(customBeanPaneClass).create(widget).get(); this.mobileStyleClazz = mobileStyleClazz; + initMobileStyle(widget); init(); } + private void initMobileStyle(Widget widget) { + mobileStyle = widget.getMobileStyle() != null ? widget.getMobileStyle() : Reflect.on(mobileStyleClazz).create().get(); + } + @Override public void populateBean(MobileStyle ob) { this.customBeanPane.populateBean(ob); customCombo.setSelectedIndex(ob.isCommonCustom() ? 1 : 0); - if(ob.getCommonBackground() != null) { - colorSelectBox.setSelectObject(((ColorBackground)ob.getCommonBackground()).getColor()); + if (ob.getCommonBackground() != null) { + colorSelectBox.setSelectObject(((ColorBackground) ob.getCommonBackground()).getColor()); } borderType.setSelectedLineStyle(ob.getCommonBorderType()); if (ob.getCommonBorderColor() != null) { @@ -85,7 +91,6 @@ public class MobileStyleDefinePane extends BasicBeanPane { @Override public MobileStyle updateBean() { - MobileStyle mobileStyle = Reflect.on(mobileStyleClazz).create().get(); this.widget.setMobileStyle(mobileStyle); this.customBeanPane.updateBean(); mobileStyle.setCommonCustom(customCombo.getSelectedIndex() == 1); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStylePane.java b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStylePane.java index 3573427ca..aafc5d4e2 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStylePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStylePane.java @@ -5,17 +5,32 @@ import com.fr.design.beans.BasicBeanPane; import com.fr.design.dialog.BasicPane; import com.fr.design.fun.MobileWidgetStyleProvider; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.mobile.processor.MobileStyleDefinePaneCreator; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WScaleLayout; +import com.fr.form.ui.mobile.MobileCommonExtraStyle; import com.fr.form.ui.mobile.MobileStyle; +import com.fr.form.ui.mobile.StyleClassMap; import com.fr.form.ui.widget.CRBoundsWidget; import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.PluginEventType; import com.fr.stable.ArrayUtils; -import javax.swing.*; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Dimension; import java.util.HashMap; import java.util.Map; @@ -28,9 +43,11 @@ public class MobileStylePane extends BasicPane { private JList styleList; private Map> map = new HashMap<>(); + private boolean checkFlag = true; + public MobileStylePane(Widget widget) { - if(widget instanceof WScaleLayout) { - this.widget = ((CRBoundsWidget)((WScaleLayout) widget).getBoundsWidget()).getWidget(); + if (widget instanceof WScaleLayout) { + this.widget = ((CRBoundsWidget) ((WScaleLayout) widget).getBoundsWidget()).getWidget(); } else { this.widget = widget; } @@ -63,13 +80,18 @@ public class MobileStylePane extends BasicPane { } private void init() { + initComponent(); + initPluginListener(); + } + + private void initComponent() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); listModel = new DefaultListModel<>(); card = new CardLayout(); right = FRGUIPaneFactory.createCardLayout_S_Pane(); right.setLayout(card); MobileWidgetStyleProvider[] styleProviders = getMobileWidgetStyleProviders(); - for(MobileWidgetStyleProvider styleProvider: styleProviders) { + for (MobileWidgetStyleProvider styleProvider : styleProviders) { this.addProvider2View(styleProvider); } this.addWestList(); @@ -107,7 +129,15 @@ public class MobileStylePane extends BasicPane { listModel.addElement(displayName); try { + MobileStyleDefinePaneCreator processor = ExtraDesignClassManager.getInstance().getSingle(MobileStyleDefinePaneCreator.XML_TAG); BasicBeanPane mobileStyleBasicBeanPane = new MobileStyleDefinePane(widget, appearanceClazz, mobileStyleClazz); + if (checkFlag && processor != null && processor.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz) != null) { + mobileStyleBasicBeanPane = processor.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz); + Class extraStyle = processor.classForCommonExtraStyle(widget); + if (extraStyle != null) { + StyleClassMap.putCommonStyle(extraStyle.getName(), extraStyle.getName()); + } + } right.add(displayName, mobileStyleBasicBeanPane); map.put(displayName, mobileStyleBasicBeanPane); } catch (Exception e) { @@ -133,4 +163,33 @@ public class MobileStylePane extends BasicPane { styleProviders = ArrayUtils.insert(0, styleProviders, defaultMobileWidgetStyleProvider); return styleProviders; } + + private void initPluginListener() { + EventDispatcher.listen(PluginEventType.AfterRun, new Listener() { + @Override + public void on(Event event, PluginContext pluginContext) { + if (pluginContext.getRuntime().contain(MobileStyleDefinePaneCreator.XML_TAG)) { + checkFlag = true; + refreshDockingView(); + } + } + }); + EventDispatcher.listen(PluginEventType.BeforeStop, new Listener() { + @Override + public void on(Event event, PluginContext pluginContext) { + if (pluginContext.getRuntime().contain(MobileStyleDefinePaneCreator.XML_TAG)) { + checkFlag = false; + refreshDockingView(); + } + } + }); + } + + private void refreshDockingView() { + removeAll(); + initComponent(); + populate(widget.getMobileStyle()); + this.updateUI(); + this.repaint(); + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java index ea649033e..7ff83c7b1 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java @@ -11,6 +11,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog; import com.fr.general.IOUtils; +import com.fr.general.locale.image.I18nImage; import com.fr.stable.Constants; import com.fr.stable.StringUtils; @@ -26,7 +27,6 @@ import java.awt.Graphics2D; import java.awt.Image; import java.awt.Rectangle; import java.awt.RenderingHints; -import java.awt.Toolkit; import java.awt.Window; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -209,7 +209,8 @@ public class TemplateThemeBlock extends JPanel { } private static class ThumbnailPane extends JPanel { - private static final Image LOADING_IMAGE = Toolkit.getDefaultToolkit().createImage(ThumbnailPane.class.getResource("/com/fr/design/images/mainframe/loading.gif")); + private static final String LOADING_IMAGE_URL = "/com/fr/design/images/mainframe/loading/loading.gif"; + private static final Image LOADING_IMAGE = I18nImage.getImage(LOADING_IMAGE_URL); private Image thumbnail = null; @Override 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 4779f9191..bfba512a2 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 @@ -66,8 +66,8 @@ import java.util.concurrent.TimeoutException; * Some util method of Designer */ public class DesignUtils { - private static int port = DesignerPort.getInstance().getMessagePort(); + private static Integer port; private static boolean started = false; @@ -80,6 +80,9 @@ public class DesignUtils { } public synchronized static int getPort() { + if (port == null) { + setPort(DesignerPort.getInstance().getMessagePort()); + } return port; } @@ -93,7 +96,6 @@ public class DesignUtils { return started; } - /** * 判断设计器端口是否被其他程序占用 * 尝试去通信,无回应就是其他程序占用端口,否则需要继续判断是否为设计器进程未关闭 @@ -103,7 +105,7 @@ public class DesignUtils { public static boolean isPortOccupied() { ExecutorService executor = null; Future future = null; - try (Socket socket = new Socket("localhost", port); + try (Socket socket = new Socket("localhost", getPort()); BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8)))) { writer.println("check"); @@ -167,7 +169,7 @@ public class DesignUtils { if (lines == null || lines.length == 0) { return; } - try (Socket socket = new Socket("localhost", port)) { + try (Socket socket = new Socket("localhost", getPort())) { clientSend(lines, socket); } catch (Exception ignore) { @@ -190,7 +192,7 @@ public class DesignUtils { try { serverSocket = new ServerSocket(startPort); } catch (IOException e1) { - FineLoggerFactory.getLogger().error("Cannot create server socket on " + port); + FineLoggerFactory.getLogger().error("Cannot create server socket on " + getPort()); } while (true) { try { @@ -221,7 +223,7 @@ public class DesignUtils { @Override public void run() { DesignerStartupContext context = DesignerStartupContext.getInstance(); - + // 如果在启动页展示中 if (DesignerStartupUtil.openTemplateIfOnWaiting(f)) { return; @@ -231,7 +233,7 @@ public class DesignUtils { // 之前就有这样的问题 return; } - + // 打开模板 DesignerContext.getDesignerFrame().openTemplate(new FileFILE(f)); } @@ -250,7 +252,7 @@ public class DesignUtils { reader.close(); socket.close(); } else { - FineLoggerFactory.getLogger().error("Cannot create server socket on " + port); + FineLoggerFactory.getLogger().error("Cannot create server socket on " + getPort()); break; } } catch (IOException ignored) { @@ -484,6 +486,7 @@ public class DesignUtils { /** * 获取设计器可用字体 + * * @return */ public static String[] getAvailableFontFamilyNames4Report() { diff --git a/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java b/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java index 31bdaa979..7be733b2b 100644 --- a/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java +++ b/designer-base/src/main/java/com/fr/env/RemoteEnvPane.java @@ -5,6 +5,7 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.beans.BasicBeanPane; import com.fr.design.border.UITitledBorder; import com.fr.design.env.RemoteDesignerWorkspaceInfo; +import com.fr.design.env.processor.RemoteDesignerWorkspaceInfoProcessor; import com.fr.design.fun.DesignerEnvProcessor; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icheckbox.UICheckBox; @@ -579,8 +580,14 @@ public class RemoteEnvPane extends BasicBeanPane { private void tryConnectRemoteEnv() { final RemoteDesignerWorkspaceInfo remoteEnv = updateBean(); - final WorkspaceConnectionInfo connection = remoteEnv.getConnection(); - + WorkspaceConnectionInfo originalConnection = remoteEnv.getConnection(); + final WorkspaceConnectionInfo connection; + RemoteDesignerWorkspaceInfoProcessor processor = ExtraDesignClassManager.getInstance().getSingle(RemoteDesignerWorkspaceInfoProcessor.XML_TAG); + if (processor != null) { + connection = processor.customUserName(originalConnection); + } else { + connection = originalConnection; + } final SwingWorker worker = new SwingWorker() { @Override diff --git a/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java b/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java index 48dfecd7b..f7ede9f1a 100644 --- a/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java +++ b/designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java @@ -163,6 +163,7 @@ public class EnvDetectorDialog extends JDialog { } }; detectButton.setForeground(Color.WHITE); + detectButton.setToolTipText(buttonStatus.getDesc()); detectButton.addActionListener(event -> { if (buttonStatus.isNotExecuting()) { startDetecting(); @@ -284,6 +285,7 @@ public class EnvDetectorDialog extends JDialog { UIUtil.invokeLaterIfNeeded(() -> { // 刷新按钮 detectButton.setText(buttonStatus.getDesc()); + detectButton.setToolTipText(detectButton.getText()); // 刷新面板 refreshBody(); }); @@ -293,6 +295,7 @@ public class EnvDetectorDialog extends JDialog { // 刷新按钮 detectButton.setText(buttonStatus.getDesc()); + detectButton.setToolTipText(detectButton.getText()); if (buttonStatus == EnvDetectorButtonStatus.A_NEW) { this.resultSummaryPane = new JPanel(); this.resultSummaryPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); @@ -358,6 +361,7 @@ public class EnvDetectorDialog extends JDialog { } EnvDetectorItem item = items.get(i); tablePanel.updateCell(row, 2, new UILabel(item.getDescription())); + tablePanel.updateCellToolTip(row, 2, item.getDescription()); DetectorResult result = item.getResult(); int detectRow = currentDetectIndex + 1; diff --git a/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png index 9e731c557..a302e257b 100644 Binary files a/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png and b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_en.png b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_en.png new file mode 100644 index 000000000..a302e257b Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_en.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh.png b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh.png new file mode 100644 index 000000000..55419d0a6 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh_TW.png b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh_TW.png new file mode 100644 index 000000000..6f9aa1036 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh_TW.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading.gif b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading.gif new file mode 100644 index 000000000..ce2172ba4 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_en.gif b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_en.gif new file mode 100644 index 000000000..26870d749 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_en.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_zh.gif b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_zh.gif new file mode 100644 index 000000000..c77b4fe10 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_zh.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_zh_TW.gif b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_zh_TW.gif new file mode 100644 index 000000000..c78edd7a9 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/mainframe/loading/loading_zh_TW.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/login/guide.css b/designer-base/src/main/resources/com/fr/design/login/guide.css deleted file mode 100644 index 12af5f6c3..000000000 --- a/designer-base/src/main/resources/com/fr/design/login/guide.css +++ /dev/null @@ -1,57 +0,0 @@ -.background-login-close { - color: white !important; - font-weight: bold; - font-size: 14px; -} -.background-guide-close { - background: url(./img/icon_install_normal.png) no-repeat center center; - background-size: cover; - width: 20px; - height: 20px; - cursor: pointer; -} -.background-guide-close:hover { - background-color: #E8E8E9; -} -.background-login-loading { - background: url(./img/login_loading.gif) no-repeat center center; -} -.background-plugin-need-update { - background: url(./img/icon_new.png) no-repeat center center; -} -.background-plugin-cant-use { - background: url(./img/icon_cantuse.png) no-repeat center center; -} -.background-plugin-is-disable { - background: url(./img/icon_disable.png) no-repeat center center; -} -.background-plugin-is-disable-new { - background: url(./img/icon_disable-new.png) no-repeat center center; -} -.background-plugin-selected { - background: url(./img/icon_marked.png) no-repeat center center; -} -.background-shop-title-close { - background: url(./img/icon_close40x40_normal.svg) no-repeat center center; -} -.background-dialog-confirm { - background: url(./img/warning.png) no-repeat center center; - background-size: contain; -} -.background-close-button { - background: url(./img/icon_close9x9_normal.png) no-repeat center center; -} -.background-close-button:hover { - background: url(./img/icon_close9x9_hover.png) no-repeat center center; -} -.designer-login-guide { - background: url(./img/login_guide.png) no-repeat center center; - background-size: cover; -} -.designer-guide-login-button { - font-size: 14px; - color: white; - border-radius: 4px; - background-color: #3685F2; -} - diff --git a/designer-base/src/main/resources/com/fr/design/login/guide.html b/designer-base/src/main/resources/com/fr/design/login/guide.html index aada842a1..bafec74c3 100644 --- a/designer-base/src/main/resources/com/fr/design/login/guide.html +++ b/designer-base/src/main/resources/com/fr/design/login/guide.html @@ -15,7 +15,7 @@ - +