Browse Source

Merge remote-tracking branch 'origin/feature/x' into feature/x

feature/x
Destiny.Lin 1 year ago
parent
commit
b8cb0684bb
  1. 2
      designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
  2. 20
      designer-base/src/main/java/com/fr/design/actions/help/SystemInfoPane.java
  3. 14
      designer-base/src/main/java/com/fr/design/components/table/TablePanel.java
  4. 10
      designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java
  5. 6
      designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java
  6. 24
      designer-base/src/main/java/com/fr/design/file/DefaultTemplateTreeDefineProcessor.java
  7. 46
      designer-base/src/main/java/com/fr/design/file/FileOperationHelper.java
  8. 8
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java
  9. 124
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  10. 59
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabUtils.java
  11. 31
      designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java
  12. 12
      designer-base/src/main/java/com/fr/design/javascript/JSContentWithDescriptionPane.java
  13. 8
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  14. 4
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  15. 11
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  16. 23
      designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/AbstractMobileStyleDefinePaneCreator.java
  17. 40
      designer-base/src/main/java/com/fr/design/mainframe/mobile/processor/MobileStyleDefinePaneCreator.java
  18. 11
      designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java
  19. 69
      designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStylePane.java
  20. 19
      designer-base/src/main/java/com/fr/design/utils/DesignUtils.java
  21. 4
      designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java
  22. 1
      designer-base/src/main/resources/com/fr/design/config/default
  23. BIN
      designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png
  24. BIN
      designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_en.png
  25. BIN
      designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh.png
  26. BIN
      designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh_TW.png
  27. 49
      designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java
  28. 289
      designer-base/src/test/java/com/fr/design/file/MultiTemplateTabPaneTest.java
  29. 6
      designer-chart/src/main/java/com/fr/van/chart/multilayer/data/MultiPiePlotTableDataContentPane.java
  30. 26
      designer-form/src/main/java/com/fr/design/designer/creator/XNumberEditor.java
  31. 10
      designer-form/src/main/java/com/fr/design/designer/creator/XPassword.java
  32. 3
      designer-form/src/main/java/com/fr/design/designer/creator/XPicture.java
  33. 10
      designer-form/src/main/java/com/fr/design/designer/creator/XTextArea.java
  34. 110
      designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java
  35. 37
      designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java
  36. 6
      designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java
  37. 2
      designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetCardTagBoundPane.java
  38. 6
      designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/WCardMainLayoutDefinePane.java
  39. 6
      designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/WCardTagLayoutDefinePane.java
  40. 11
      designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ElementCaseDefinePane.java
  41. 9
      designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/TextEditorMobileDefinePane.java
  42. 5
      designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobilePasswordEditSettingPane.java
  43. 5
      designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextAreaSettingPane.java
  44. 4
      designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextEditSettingPane.java
  45. 13
      designer-realize/src/main/java/com/fr/design/widget/WidgetMobilePaneFactory.java
  46. 2
      designer-realize/src/main/java/com/fr/design/widget/ui/mobile/TextEditorMobilePane.java
  47. 24
      designer-realize/src/main/java/com/fr/grid/GridKeyAction.java

2
designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java

@ -437,7 +437,7 @@ public class EnvChangeEntrance {
@Override
public void doOk() {
SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(true, SwingUtilities.getWindowAncestor(envListPane));
if (!saveSomeTemplatePane.showSavePane()) {
if (!saveSomeTemplatePane.showSavePane(true)) {
// 用户取消保存时,取消切换目录操作
return;
}

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

14
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) {

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

@ -572,7 +572,7 @@ public abstract class DesignTableDataManager {
parameter.setValue(parameterMap.get(parameter.getName()));
}
}
parameterMap.put(SqlNoteConstants.SQL_NOTE_TEMPLATE, HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getEditingFILE().getPath());
addTemplateInfoIfNeed(parameterMap);
return DataOperator.getInstance().previewTableData(TableDataSourceTailor.extractTableData(tableDataSource), tabledata, parameterMap, rowCount);
} catch (Exception e) {
throw new TableDataException(e.getMessage(), e);
@ -592,6 +592,12 @@ public abstract class DesignTableDataManager {
}
}
private static void addTemplateInfoIfNeed(Map<String, Object> parameterMap) {
if (JTemplate.isValid(HistoryTemplateListCache.getInstance().getCurrentEditingTemplate())) {
parameterMap.put(SqlNoteConstants.SQL_NOTE_TEMPLATE, HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getEditingFILE().getPath());
}
}
private static boolean needInputParams(boolean mustInputParameters, ParameterProvider[] parameters) {
if (mustInputParameters && ArrayUtils.isNotEmpty(parameters)) {
return true;
@ -669,7 +675,7 @@ public abstract class DesignTableDataManager {
if (needLoadingBar) {
MultiResultTableDataWrapper.loadingBar.start();
}
parameterMap.put(SqlNoteConstants.SQL_NOTE_TEMPLATE, HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().getEditingFILE().getPath());
addTemplateInfoIfNeed(parameterMap);
return DataOperator.getInstance().previewMultiResultTableData(tableData, parameterMap, 0);
}

6
designer-base/src/main/java/com/fr/design/data/datapane/connect/DatabaseConnectionPane.java

@ -589,7 +589,7 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
} else {
path = driverPath;
}
if(JarFileParseUtil.hasDuplicateDriver(con.getDriver(), path)) {
if(hasDuplicateDriver(con.getDriver(), path)) {
testResult.setForeground(Color.RED);
testResult.setText(Toolkit.i18nText("Fine_Designer_Driver_Conflict"));
} else {
@ -605,7 +605,9 @@ public abstract class DatabaseConnectionPane<E extends com.fr.data.impl.Connecti
return xBorderPanel;
}
private boolean hasDuplicateDriver(String driver, String folder) {
return JarFileParseUtil.hasDuplicateDriver(driver, folder);
}
}
}

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

46
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);

8
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java

@ -1,5 +1,6 @@
package com.fr.design.file;
import com.fr.base.svg.IconUtils;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.imenu.UIMenuItem;
@ -7,7 +8,6 @@ import com.fr.design.gui.imenu.UIScrollPopUpMenu;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.TemplateUtils;
import com.fr.general.IOUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.collections.CollectionUtils;
@ -34,9 +34,9 @@ import java.util.Map;
**/
public class MultiTemplateTabMenuFactory {
private static final Icon CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png");
private static final Icon MOUSE_OVER_CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/mouseoverclose icon.png");
private static final Icon MOUSE_PRESS_CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/pressclose icon.png");
private static final Icon CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close");
private static final Icon MOUSE_OVER_CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close_mouseover.svg");
private static final Icon MOUSE_PRESS_CLOSE = IconUtils.readIcon("/com/fr/design/standard/close/close_press.svg");
private static final int ITEM_SIZE = 25;

124
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java

@ -44,6 +44,7 @@ import javax.swing.JSeparator;
import javax.swing.MenuElement;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.plaf.basic.BasicMenuItemUI;
import java.awt.AWTEvent;
import java.awt.AlphaComposite;
@ -212,6 +213,35 @@ public class MultiTemplateTabPane extends JComponent {
});
}
/**
* 模板可以关闭的条件
*/
class CloseCondition {
private CloseOption closeOption;
public CloseCondition(CloseOption closeOption) {
this.closeOption = closeOption;
}
/**
* 判断模板是否可以关闭两个条件1是否满足CloseOption里面的条件在左侧在右侧等2是否和当前正在编辑模板属于同一种模板tab操作类型
* @param closeJTemplate
* @param tplIndex
* @param i
* @return
*/
public boolean shouldClose(JTemplate closeJTemplate, int tplIndex, int i) {
boolean matchOption = this.closeOption.shouldClose(tplIndex, i);
JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (!JTemplate.isValid(currentTemplate)) {
return matchOption;
}
return matchOption && ComparatorUtils.equals(closeJTemplate.getTemplateTabOperatorType(),
currentTemplate.getTemplateTabOperatorType());
}
}
enum CloseOption {
Left(Toolkit.i18nText("Fine-Design_Close_templates_To_The_Left")) {
@Override
@ -322,32 +352,34 @@ public class MultiTemplateTabPane extends JComponent {
@Override
public void actionPerformed(ActionEvent e) {
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false);
if (saveSomeTempaltePane.showSavePane()) {
//只有关闭所有模板才需要判断当前模板,关闭左侧、右侧、其他都不需要
SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(option == CloseOption.All);
CloseCondition closeCondition = new CloseCondition(option);
if (saveSomeTemplatePane.showSavePane(closeCondition, false)) {
JTemplate<?, ?>[] templates = new JTemplate<?, ?>[openedTemplate.size()];
for (int i = 0; i < openedTemplate.size(); i++) {
templates[i] = openedTemplate.get(i);
}
JTemplate<?, ?> currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
closeTemplate(templates, currentTemplate);
closeTemplate(closeCondition, templates, currentTemplate);
if (openedTemplate.size() == 0) {
DesignerContext.getDesignerFrame().addAndActivateJTemplate();
} else if (option == CloseOption.All){
DesignerContext.getDesignerFrame().activateJTemplate(openedTemplate.get(0));
//openedTemplate(0)是JVirtualTemplate时需重新打开
openedTemplate.get(0).activeOldJTemplate();
} else {
DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate);
currentTemplate.activeOldJTemplate();
}
MultiTemplateTabPane.getInstance().repaint();
}
}
private void closeTemplate(JTemplate<?, ?>[] templates, JTemplate<?, ?> currentTemplate) {
String operator = currentTemplate.getTemplateTabOperatorType();
private void closeTemplate(CloseCondition closeCondition, JTemplate<?, ?>[] templates, JTemplate<?, ?> currentTemplate) {
for (int i = 0; i < templates.length; i++) {
if (option.shouldClose(tplIndex, i) && ComparatorUtils.equals(operator, templates[i].getTemplateTabOperatorType())) {
if (closeCondition.shouldClose(templates[i], tplIndex, i)) {
JTemplate<?, ?> jTemplate = templates[i];
if (jTemplate == currentTemplate) {
currentTemplate = option == CloseOption.All ? null : templates[tplIndex];
@ -725,6 +757,58 @@ public class MultiTemplateTabPane extends JComponent {
minPaintIndex = 0;
maxPaintIndex = openedTemplate.size() - 1;
}
//需要根据每个tab的宽度重新check下实际的maxPaintIndex和minPaintIndex
checkActualPaintIndex();
}
/**
* 先计算出需要补充的tab个数
* @return
*/
private int calTabCountComplemented(){
int a = 0;
for (int i = minPaintIndex; i <= maxPaintIndex; i++) {
JTemplate template = openedTemplate.get(i);
if (!showJTemplateTab(template)) {
a++;
}
}
return a;
}
/**
* 由于可能存在宽度为0的tab所以这边需要重新check下先往后补再往前补
*/
private void checkActualPaintIndex(){
int tabCount = calTabCountComplemented();
if (tabCount == 0){
return;
}
if (maxPaintIndex < openedTemplate.size() - 1) {
for (int i = maxPaintIndex + 1; i < openedTemplate.size(); i++) {
JTemplate template = openedTemplate.get(i);
if (showJTemplateTab(template)) {
tabCount--;
}
maxPaintIndex++;
if (tabCount == 0){
return;
}
}
}
if (minPaintIndex > 0){
for (int i = minPaintIndex - 1; i >= 0; i--) {
JTemplate template = openedTemplate.get(i);
if (showJTemplateTab(template)) {
tabCount--;
}
minPaintIndex--;
if (tabCount == 0){
return;
}
}
}
}
@ -996,9 +1080,12 @@ public class MultiTemplateTabPane extends JComponent {
// selectIndex 没有变化,但是对应的模板已经变成了前一张模板
if (closeIconIndex == selectedIndex || isCloseCurrent) {
// 如果当前关闭的模板在最右侧,那么预览上一个,防止数组越界
// 关闭的模板是当前选中的模板时,需要重新计算下一个待展示的模板的index
if (selectedIndex >= maxPaintIndex) {
// selectIndex 不会 <0 因为如果关闭的是打开的最后一个模板,那么关闭之后 openedTemplate.isEmpty() = true
selectedIndex = calNextShowJTemplateIndex(selectedIndex - 1);
} else {
selectedIndex = calNextShowJTemplateIndex(selectedIndex);
}
isCloseCurrent = false;
}
@ -1021,18 +1108,8 @@ public class MultiTemplateTabPane extends JComponent {
* @return
*/
public int calNextShowJTemplateIndex(int currentIndex) {
//先看是否有可以展示的模板
for (int i = currentIndex; i >= 0; i--) {
if (showJTemplateTab(openedTemplate.get(i))) {
return i;
}
}
for (int i = currentIndex; i >= 0; i--) {
if (!showJTemplateTab(openedTemplate.get(i))) {
return i;
}
}
return -1;
JTemplate jTemplate= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return MultiTemplateTabUtils.calShowTemplateIndex(currentIndex, openedTemplate, jTemplate.getTemplateTabOperatorType());
}
@ -1119,6 +1196,7 @@ public class MultiTemplateTabPane extends JComponent {
private class MultiTemplateTabMouseListener implements MouseListener {
private boolean oldLightWeightPopupEnabled;
/**
* 鼠标进入
@ -1127,7 +1205,8 @@ public class MultiTemplateTabPane extends JComponent {
*/
@Override
public void mouseEntered(MouseEvent e) {
// do nothing
this.oldLightWeightPopupEnabled = ToolTipManager.sharedInstance().isLightWeightPopupEnabled();
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(false);
}
/**
@ -1137,6 +1216,9 @@ public class MultiTemplateTabPane extends JComponent {
*/
@Override
public void mouseExited(MouseEvent e) {
ToolTipManager.sharedInstance().setEnabled(false);
ToolTipManager.sharedInstance().setEnabled(true);
ToolTipManager.sharedInstance().setLightWeightPopupEnabled(this.oldLightWeightPopupEnabled);
listDownMode = LIST_DOWN;
closeIconIndex = -1;
mouseOveredIndex = -1;

59
designer-base/src/main/java/com/fr/design/file/MultiTemplateTabUtils.java

@ -0,0 +1,59 @@
package com.fr.design.file;
import com.fr.design.mainframe.JTemplate;
import com.fr.general.ComparatorUtils;
import java.util.List;
import java.util.function.Predicate;
public class MultiTemplateTabUtils {
/**
* 计算离currentIndex最近的相同模式的模板index值优先左边
*
* @param currentIndex 当前index
* @param openedTemplate 模板list
* @param type 当前显示模式
* @return
*/
public static int calShowTemplateIndex(int currentIndex, List<JTemplate<?, ?>> openedTemplate, String type) {
if (currentIndex < 0 || currentIndex > openedTemplate.size() - 1) {
return -1;
}
int result = getShowJTemplateTab(currentIndex, openedTemplate, template -> showJTemplateTab(type, template));
if (result != -1) return result;
return getShowJTemplateTab(currentIndex, openedTemplate, template -> !showJTemplateTab(type, template));
}
/**
* 先从左找再从右找离得最近的满足条件的模板
*
* @param currentIndex 当前index
* @param openedTemplate 模板list
* @param predicate
* @return
*/
private static int getShowJTemplateTab(int currentIndex, List<JTemplate<?, ?>> openedTemplate, Predicate<JTemplate<?, ?>> predicate) {
for (int i = currentIndex; i >= 0; i--) {
if (predicate.test(openedTemplate.get(i))) {
return i;
}
}
for (int i = currentIndex + 1; i < openedTemplate.size(); i++) {
if (predicate.test(openedTemplate.get(i))) {
return i;
}
}
return -1;
}
/**
* 是否显示模板
*
* @param type 模板类型
* @param jTemplate 模板
* @return
*/
private static boolean showJTemplateTab(String type, JTemplate<?, ?> jTemplate) {
return ComparatorUtils.equals(type, jTemplate.getTemplateTabOperatorType());
}
}

31
designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java

@ -17,6 +17,7 @@ import com.fr.design.mainframe.JTemplate;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
@ -123,8 +124,10 @@ public class SaveSomeTemplatePane extends BasicPane {
if (index < 0) {
return;
}
boolean mustSaveBeforeSwitchEnv = judgeJTemplateMustSave
&& unSavedTemplate.get(index).needSaveBeforeSwitchEnv();
UICheckBox checkBox = (UICheckBox) templatesList.getModel().getElementAt(index);
checkBox.setSelected(!checkBox.isSelected());
checkBox.setSelected(mustSaveBeforeSwitchEnv ||!checkBox.isSelected());
//根据templateCheckBoxes中的选择情况来更新全选框的状态
int selectedCount = calculateSelectedNum();
@ -162,8 +165,25 @@ public class SaveSomeTemplatePane extends BasicPane {
return showSavePane(false);
}
/**
* 显示保存模板提醒面板
*
* @param judgeJTemplateMustSave 模板是否必须保存
* @return
*/
public boolean showSavePane(boolean judgeJTemplateMustSave) {
populate(judgeJTemplateMustSave);
return showSavePane(null, judgeJTemplateMustSave);
}
/**
* 显示保存模板提醒面板
*
* @param option 具体关闭操作
* @param judgeJTemplateMustSave 模板是否必须保存
* @return
*/
public boolean showSavePane(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave) {
initAndPopulate(option, judgeJTemplateMustSave);
//如果有未保存的文件 ,则跳出保存对话框,选择要存储的项目
if (!unSavedTemplate.isEmpty()) {
dialog.setVisible(true);
@ -177,11 +197,14 @@ public class SaveSomeTemplatePane extends BasicPane {
return HistoryTemplateListPane.getInstance().getHistoryList();
}
public void populate(boolean judgeJTemplateMustSave) {
private void initAndPopulate(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave) {
java.util.List<JTemplate<?, ?>> opendedTemplate = getOpenedTemplatesToProcess();
JTemplate<?, ?> currentTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
int currentIndex = opendedTemplate.indexOf(currentTemplate);
for (int i = 0; i < opendedTemplate.size(); i++) {
if (isneedToAdd(opendedTemplate.get(i), currentTemplate)) {
//满足关闭条件的才继续判断文件是否发生了改动
boolean needClose = option == null || option.shouldClose(opendedTemplate.get(i), currentIndex, i);
if (needClose && isneedToAdd(opendedTemplate.get(i), currentTemplate)) {
unSavedTemplate.add(opendedTemplate.get(i));
}
}

12
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<HelpDocument> 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);

8
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java

@ -852,7 +852,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
if (jt == null || jt.getEditingFILE() == null) {
return;
}
if (currentTemplateDeactivateFail()) {
if (currentTemplateDeactivateFail(jt)) {
return;
}
jt.addJTemplateActionListener(this);
@ -877,7 +877,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
if (jt == null || jt.getEditingFILE() == null) {
return;
}
if (currentTemplateDeactivateFail()) {
if (currentTemplateDeactivateFail(jt)) {
return;
}
getCenterTemplateCardPane().showJTemplate(jt);
@ -939,9 +939,9 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
*
* @return 是否停用失败
*/
private boolean currentTemplateDeactivateFail() {
private boolean currentTemplateDeactivateFail(JTemplate jt) {
JTemplate currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
return currentEditingTemplate != null && !currentEditingTemplate.deactivateTemplate();
return currentEditingTemplate != null && !currentEditingTemplate.deactivateTemplate(jt);
}

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

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

@ -1373,6 +1373,17 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
/**
* 将要激活打开其他模板使当前模板灭活
* 默认 do nothing 返回true
*
* @return true成功停用当前模板
*/
public boolean deactivateTemplate(JTemplate jTemplate) {
//兼容调用老的接口
return deactivateTemplate();
}
/**
* 返回当前支持的超链界面pane
*

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

40
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;
/**
* <p> 创建通用属性样式界面可替换{@link com.fr.design.mainframe.mobile.ui.MobileStyleDefinePane}
* <p> 每种样式的通用属性面板是一样的
*
* @param widget 控件
* @param customDefinePane 自定义面板
* @param mobileStyle 移动端样式
* @return
*/
@Nullable BasicBeanPane<MobileStyle> createBaseBeanPane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customDefinePane, Class<? extends MobileStyle> mobileStyle);
/**
* 替换通用属性面板注册额外属性
*
* @return 属性类
*/
@Nullable Class<? extends MobileCommonExtraStyle> classForCommonExtraStyle(Widget widget);
}

11
designer-base/src/main/java/com/fr/design/mainframe/mobile/ui/MobileStyleDefinePane.java

@ -53,22 +53,28 @@ public class MobileStyleDefinePane extends BasicBeanPane<MobileStyle> {
private UISpinner borderRadius;
private NewColorSelectBox iconColor;
private MobileStyleFontConfigPane fontConfigPane;
private MobileStyle mobileStyle;
MobileStyleDefinePane(Widget widget, Class<? extends MobileStyleCustomDefinePane> customBeanPaneClass,
Class<? extends MobileStyle> 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<MobileStyle> {
@Override
public MobileStyle updateBean() {
MobileStyle mobileStyle = Reflect.on(mobileStyleClazz).create().get();
this.widget.setMobileStyle(mobileStyle);
this.customBeanPane.updateBean();
mobileStyle.setCommonCustom(customCombo.getSelectedIndex() == 1);

69
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<String, BasicBeanPane<MobileStyle>> 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<MobileStyle> mobileStyleBasicBeanPane = new MobileStyleDefinePane(widget, appearanceClazz, mobileStyleClazz);
if (checkFlag && processor != null && processor.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz) != null) {
mobileStyleBasicBeanPane = processor.createBaseBeanPane(widget, appearanceClazz, mobileStyleClazz);
Class<? extends MobileCommonExtraStyle> 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<PluginContext>() {
@Override
public void on(Event event, PluginContext pluginContext) {
if (pluginContext.getRuntime().contain(MobileStyleDefinePaneCreator.XML_TAG)) {
checkFlag = true;
refreshDockingView();
}
}
});
EventDispatcher.listen(PluginEventType.BeforeStop, new Listener<PluginContext>() {
@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();
}
}

19
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<String> 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() {

4
designer-base/src/main/java/com/fr/env/detect/ui/EnvDetectorDialog.java vendored

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

1
designer-base/src/main/resources/com/fr/design/config/default

@ -1 +1,2 @@
Fine-Designer_Login=i7hP48WAcuTrmxfN
Fine-Designer_Reu_Share_CERTIFICATE_PUBLIC_KEY=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtsz62CPSWXZE/IYZRiAuTSZkw1WOwer8+JFktK0uKLAUuQoBr+UjAMFtRA8W7JgKMDwZy/2liEAiXEOSPU/hrdV8DtT541LnGi1X/hXiRwuttPWYN3L2GYm/d5blU+FBNwghBIrdAxXTzYBc6P4KL/oYXnMdTIrkz8tYkG3QoFQIDAQAB

BIN
designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_en.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
designer-base/src/main/resources/com/fr/design/images/form/designer/widget/picture_widget_designer_bg_zh_TW.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

49
designer-base/src/test/java/com/fr/design/file/FileOperationHelperTest.java

@ -0,0 +1,49 @@
package com.fr.design.file;
import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode;
import com.fr.file.filetree.FileNode;
import org.junit.Assert;
import org.junit.Test;
/**
*
* @author Levy.Xie
* @version 11.0
* Created by Levy.Xie on 2023/05/23
*/
public class FileOperationHelperTest {
@Test
public void testIsSubDirectory() {
FileNode sourceNode1 = new FileNode("/usr/local/webroot/reportlets", true);
FileNode sourceNode2 = new FileNode("/usr/local/webroot/reportlets/demo", true);
FileNode sourceNode3 = new FileNode("/usr/local/webroot/reportlets/doc", true);
FileNode sourceNode4 = new FileNode("/usr/local/webroot/reportlets/doc/1.cpt", false);
FileNode sourceNode5 = new FileNode("/usr/local/webroot/reportlets/demo/test", true);
FileNode sourceNode6 = new FileNode("/usr/local/webroot/reportlets/demo/test", false);
FileNode sourceNode7 = new FileNode("/usr/local/webroot/reportlets/demo/test123", true);
FileNode sourceNode8 = new FileNode("/usr/local/webroot/reportlets/../reportlets/demo/test", true);
FileNode sourceNode9 = new FileNode("/usr/local/webroot/reportlets/../reportlets/demo/test/c", true);
FileNode targetNode = new FileNode("/usr/local/webroot/reportlets/demo/test", true);
Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode1, targetNode));
Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode2, targetNode));
Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode3, targetNode));
Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode4, targetNode));
Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode5, targetNode));
Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode6, targetNode));
Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode7, targetNode));
Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode8, targetNode));
Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(sourceNode9, targetNode));
ExpandMutableTreeNode treeNode1 = new ExpandMutableTreeNode(sourceNode1);
ExpandMutableTreeNode treeNode2 = new ExpandMutableTreeNode(sourceNode2);
ExpandMutableTreeNode treeNode3 = new ExpandMutableTreeNode(sourceNode3);
ExpandMutableTreeNode treeNode4 = new ExpandMutableTreeNode(sourceNode4);
Assert.assertTrue(FileOperationHelper.getInstance().isSubDirectoryOrSame(new ExpandMutableTreeNode[]{treeNode1, treeNode2, treeNode3}, targetNode));
Assert.assertFalse(FileOperationHelper.getInstance().isSubDirectoryOrSame(new ExpandMutableTreeNode[]{treeNode3, treeNode4}, targetNode));
}
}

289
designer-base/src/test/java/com/fr/design/file/MultiTemplateTabPaneTest.java

@ -0,0 +1,289 @@
package com.fr.design.file;
import com.fr.design.DesignModelAdapter;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.designer.TargetComponent;
import com.fr.design.gui.frpane.HyperlinkGroupPane;
import com.fr.design.gui.frpane.HyperlinkGroupPaneActionProvider;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.mainframe.AuthorityEditPane;
import com.fr.design.mainframe.BaseUndoState;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef;
import com.fr.plugin.injectable.PluginModule;
import junit.framework.TestCase;
import org.junit.Assert;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import java.util.ArrayList;
import java.util.List;
public class MultiTemplateTabPaneTest extends TestCase {
@Override
protected void setUp() throws Exception {
PluginModule.registerAgent(PluginModule.ExtraDesign, new ExtraDesignClassManager());
}
/**
* 当前显示模式A传入index左边(含当前)或右边有模式A的模板返回最近的模式A模板index优先左边
*/
public void test_index_left_has_same_mode_temp() {
//当前显示模式A,传入index左边(含当前)有模式A的模板,返回左边最近的模式A模板index
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
openedTemplateList.add(new A_Mode());
Assert.assertEquals(0, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new A_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
openedTemplateList.add(new B_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
}
public void test_index_left_has_not_but_right_has_same_mode_temp() {
//当前显示模式A,传入index左边没有但是右边有模式A的模板,返回右边最近的模式A模板index
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
openedTemplateList.add(new B_Mode());
openedTemplateList.add(new A_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(1, new B_Mode());
openedTemplateList.add(new A_Mode());
Assert.assertEquals(2, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new A_Mode());
Assert.assertEquals(2, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
}
/**
* 当前显示模式A没有模式A的模板左边(含当前)或者右边有其他模式的模板返回最近的其他模式模式模板index优先左边
*/
public void test_no_same_mode_temp_but_index_left_has_other_mode_temp() {
//当前显示模式A,没有模式A的模板,左边(含当前)有其他模式模板,返回左边最近的其他模式模板index
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
openedTemplateList.add(new B_Mode());
Assert.assertEquals(0, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new B_Mode());
Assert.assertEquals(1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
}
public void test_has_no_temp() {
//当前显示模式A,没有模式A的模板,也没有其他模式的模板,返回-1
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
}
public void test_if_index_less_than_zero_or_more_than_open_temp_size() {
//index<0 或者超出openTemplateList.size时,返回-1
List<JTemplate<?, ?>> openedTemplateList = new ArrayList<>();
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(-1, openedTemplateList, "A_Mode"));
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(0, openedTemplateList, "A_Mode"));
openedTemplateList.add(new A_Mode());
Assert.assertEquals(-1, MultiTemplateTabUtils.calShowTemplateIndex(1, openedTemplateList, "A_Mode"));
}
private class A_Mode extends AbstractTestMode {
public String getTemplateTabOperatorType() {
return "A_Mode";
}
}
private class B_Mode extends AbstractTestMode {
public String getTemplateTabOperatorType() {
return "B_Mode";
}
}
private abstract class AbstractTestMode extends JTemplate {
public AbstractTestMode() {
}
@Override
public void copy() {
}
@Override
public boolean paste() {
return false;
}
@Override
public boolean cut() {
return false;
}
@Override
public AuthorityEditPane createAuthorityEditPane() {
return null;
}
@Override
public JPanel getEastUpPane() {
return null;
}
@Override
public JPanel getEastDownPane() {
return null;
}
@Override
public ToolBarDef[] toolbars4Target() {
return new ToolBarDef[0];
}
@Override
public JPanel[] toolbarPanes4Form() {
return new JPanel[0];
}
@Override
public JComponent[] toolBarButton4Form() {
return new JComponent[0];
}
@Override
public JComponent toolBar4Authority() {
return null;
}
@Override
public int getToolBarHeight() {
return 0;
}
@Override
public void refreshEastPropertiesPane() {
}
@Override
public TargetComponent getCurrentElementCasePane() {
return null;
}
@Override
public JComponent getCurrentReportComponentPane() {
return null;
}
@Override
public TemplateProcessInfo getProcessInfo() {
return null;
}
@Override
public void setJTemplateResolution(int resolution) {
}
@Override
public int getJTemplateResolution() {
return 0;
}
@Override
protected JComponent createCenterPane() {
return null;
}
@Override
public void removeTemplateSelection() {
}
@Override
public void refreshContainer() {
}
@Override
public void removeParameterPaneSelection() {
}
@Override
public void setScale(int resolution) {
}
@Override
public int getScale() {
return 0;
}
@Override
public int selfAdaptUpdate() {
return 0;
}
@Override
protected DesignModelAdapter createDesignModel() {
return null;
}
@Override
public UIMenuItem[] createMenuItem4Preview() {
return new UIMenuItem[0];
}
@Override
protected BaseUndoState<?> createUndoState() {
return null;
}
@Override
public String suffix() {
return null;
}
@Override
public ShortCut[] shortcut4TemplateMenu() {
return new ShortCut[0];
}
@Override
public ShortCut[] shortCuts4Authority() {
return new ShortCut[0];
}
@Override
public boolean isJWorkBook() {
return false;
}
@Override
public HyperlinkGroupPane getHyperLinkPane(HyperlinkGroupPaneActionProvider hyperlinkGroupPaneActionProvider) {
return null;
}
@Override
public HyperlinkGroupPane getHyperLinkPaneNoPop(HyperlinkGroupPaneActionProvider hyperlinkGroupPaneActionProvider) {
return null;
}
@Override
public void setAuthorityMode(boolean isUpMode) {
}
@Override
public Icon getIcon() {
return null;
}
@Override
public String route() {
return null;
}
@Override
protected void applyUndoState(BaseUndoState baseUndoState) {
}
}
}

6
designer-chart/src/main/java/com/fr/van/chart/multilayer/data/MultiPiePlotTableDataContentPane.java

@ -58,6 +58,9 @@ public class MultiPiePlotTableDataContentPane extends AbstractTableDataContentPa
//将数据列名保存下来,在update时会删除层级名列表,需要用保存的list重新初始化新的层级名列表
private List columnNameList;
//汇总方式求和的索引
public static final int SUM_INDEX = 2;
public MultiPiePlotTableDataContentPane() {
}
@ -241,7 +244,8 @@ public class MultiPiePlotTableDataContentPane extends AbstractTableDataContentPa
for (UIComboBox uiComboBox : levelNameList) {
clearBoxItems(uiComboBox);
}
clearBoxItems(calculateCombox);
//默认选求和
calculateCombox.setSelectedIndex(SUM_INDEX);
refreshCenterPane();
}

26
designer-form/src/main/java/com/fr/design/designer/creator/XNumberEditor.java

@ -6,9 +6,7 @@ package com.fr.design.designer.creator;
import com.fr.base.BaseUtils;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
import com.fr.design.designer.properties.mobile.NumberEditorMobilePropertyUI;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.design.mainframe.widget.editors.InChangeBooleanEditor;
import com.fr.design.mainframe.widget.editors.SpinnerMaxNumberEditor;
import com.fr.design.mainframe.widget.editors.SpinnerMinNumberEditor;
@ -94,18 +92,18 @@ public class XNumberEditor extends XWrapperedFieldEditor {
}
@Override
protected JComponent initEditor() {
setBorder(FIELDBORDER);
return this;
}
protected JComponent initEditor() {
setBorder(FIELDBORDER);
return this;
}
@Override
protected String getIconName() {
return "number_field_16.png";
}
@Override
protected String getIconName() {
return "number_field_16.png";
}
@Override
public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() {
return new WidgetPropertyUIProvider[]{new NumberEditorMobilePropertyUI(this)};
}
// @Override
// public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() {
// return new WidgetPropertyUIProvider[]{new NumberEditorMobilePropertyUI(this)};
// }
}

10
designer-form/src/main/java/com/fr/design/designer/creator/XPassword.java

@ -3,9 +3,7 @@
*/
package com.fr.design.designer.creator;
import com.fr.design.designer.properties.mobile.PasswordMobilePropertyUI;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.design.gui.ibutton.UIPasswordField;
import com.fr.design.mainframe.widget.editors.RegexEditor;
import com.fr.design.mainframe.widget.editors.WidgetValueEditor;
@ -70,8 +68,8 @@ public class XPassword extends XWrapperedFieldEditor {
(CRPropertyDescriptor[]) ArrayUtils.addAll(sup, new CRPropertyDescriptor[]{regex, waterMark});
}
@Override
public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() {
return new WidgetPropertyUIProvider[]{new PasswordMobilePropertyUI(this)};
}
// @Override
// public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() {
// return new WidgetPropertyUIProvider[]{new PasswordMobilePropertyUI(this)};
// }
}

3
designer-form/src/main/java/com/fr/design/designer/creator/XPicture.java

@ -9,6 +9,7 @@ import com.fr.design.mainframe.widget.renderer.PictureRenderer;
import com.fr.design.mainframe.widget.renderer.UrlLinkRenderer;
import com.fr.form.ui.PictureWidget;
import com.fr.general.IOUtils;
import com.fr.general.locale.image.I18nImage;
import com.fr.stable.ArrayUtils;
import java.awt.Dimension;
import java.awt.Image;
@ -59,7 +60,7 @@ public class XPicture extends XWidgetCreator {
imgPanel.setBackgroundImage((Image) value);
imgPanel.setImageDisplayMode(pictureWidget.getShowType());
} else {
imgPanel.setBackgroundImage(IOUtils.readImage("com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png"));
imgPanel.setBackgroundImage(I18nImage.getImage("/com/fr/design/images/form/designer/widget/picture_widget_designer_bg.png"));
imgPanel.setImageDisplayMode(0);
}
this.editor.add(imgPanel, "Center");

10
designer-form/src/main/java/com/fr/design/designer/creator/XTextArea.java

@ -6,9 +6,7 @@ package com.fr.design.designer.creator;
import com.fr.base.BaseUtils;
import com.fr.base.ScreenResolution;
import com.fr.base.Style;
import com.fr.design.designer.properties.mobile.TextAreaMobilePropertyUI;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.design.mainframe.widget.editors.RegexEditor;
import com.fr.design.mainframe.widget.editors.WidgetValueEditor;
import com.fr.design.mainframe.widget.renderer.RegexCellRencerer;
@ -85,9 +83,9 @@ public class XTextArea extends XWrapperedFieldEditor {
return "text_area_16.png";
}
@Override
public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() {
return new WidgetPropertyUIProvider[]{new TextAreaMobilePropertyUI(this)};
}
// @Override
// public WidgetPropertyUIProvider[] getWidgetPropertyUIProviders() {
// return new WidgetPropertyUIProvider[]{new TextAreaMobilePropertyUI(this)};
// }
}

110
designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java

@ -10,6 +10,7 @@ import com.fr.design.designer.beans.models.SelectionModel;
import com.fr.design.designer.creator.XButton;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.gui.ilable.UILabel;
@ -25,16 +26,27 @@ import com.fr.form.ui.container.WTabTextDirection;
import com.fr.form.ui.container.cardlayout.WCardTagLayout;
import com.fr.form.ui.container.cardlayout.WTabFitLayout;
import com.fr.general.Background;
import com.fr.general.act.BorderPacker;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
import com.fr.general.act.BorderPacker;
import com.fr.general.act.TitlePacker;
import com.fr.general.cardtag.TemplateStyle;
import com.fr.stable.unit.PT;
import javax.swing.*;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicLabelUI;
import java.awt.*;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
@ -236,52 +248,43 @@ public class XCardSwitchButton extends XButton {
//SwitchButton对应的XWCardLayout和XWCardTagLayout暂未存到xml中,重新打开时根据父子层关系获取
private void initRelateLayout(){
this.tagLayout = (XWCardTagLayout)this.getBackupParent();
private void initRelateLayout() {
this.tagLayout = (XWCardTagLayout) this.getBackupParent();
XWCardTitleLayout titleLayout = (XWCardTitleLayout) this.tagLayout.getBackupParent();
XWCardMainBorderLayout borderLayout = (XWCardMainBorderLayout)titleLayout.getBackupParent();
XWCardMainBorderLayout borderLayout = (XWCardMainBorderLayout) titleLayout.getBackupParent();
this.cardLayout = borderLayout.getCardPart();
}
//是否进入点击关闭按钮区域
private boolean isSelectedClose(MouseEvent e, FormDesigner designer){
/**
* <p> 是否进入点击关闭按钮区域
* <p> 计算逻辑
* <p> 先得到鼠标的绝对坐标 -> tab布局的绝对坐标 -> 得到鼠标相对tab的坐标有参数面板时要减去参数面板的高度
* <p> 再计算删除区域位置的相对坐标通过对比判定鼠标是否在点击关闭按钮区域内鼠标的位置(ex,ey)
* <li> 当前点击tag删除区域的x坐标 < ex < 当前点击tag删除区域的x坐标 + 偏移量</li>
* <li> 当前点击tag删除区域的y坐标 < ey < 当前点击tag删除区域的y坐标 + 偏移量</li>
*
* @param e 鼠标事件
* @param designer 表单编辑对象
* @return true/false 在内/不在
*/
private boolean isSelectedClose(MouseEvent e, FormDesigner designer) {
int diff = designer.getHorizontalScaleValue();
// mouse position
// 这里是鼠标的绝对位置
int ex = e.getX() + diff;
int ey = e.getY();
//获取tab布局的位置,鼠标相对于tab按钮的位置
Container mainLayout = cardLayout.getBackupParent();
Point point = mainLayout.getLocation();
int y = 0;
int x = 0;
//遍历一下,不然是相对位置,嵌套后位置不对
while (mainLayout.getParent() != null){
if(mainLayout instanceof XWCardLayout){
y += mainLayout.getY();
}
mainLayout = mainLayout.getParent();
if(mainLayout instanceof XWCardMainBorderLayout){
x += mainLayout.getX();
y += mainLayout.getY();
}
}
double mainX = point.getX() + x;
double mainY = point.getY() + y;
// 获取tab布局的位置,鼠标相对于tab按钮的位置
double[] tabPositionInBody = getTabAbsolutePositionInBody();
// 参数界面对坐标的影响
JForm jform = (JForm) HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
if(jform.getFormDesign().getParaComponent() != null){
if (jform.getFormDesign().getParaComponent() != null) {
ey -= jform.getFormDesign().getParaHeight();
}
//减掉tab布局的相对位置
ex -= mainX;
ey -= mainY;
ex -= tabPositionInBody[0];
ey -= tabPositionInBody[1];
XLayoutContainer titleLayout = tagLayout.getBackupParent();
Point titlePoint = titleLayout.getLocation();
@ -291,10 +294,43 @@ public class XCardSwitchButton extends XButton {
int width = button.getWidth();
// 鼠标进入按钮右侧删除图标区域
double recX = position.getX() + titlePoint.getX() + (width - CLOSE_ICON_RIGHT_OFFSET);
double recX = position.getX() + titlePoint.getX() + (width - CLOSE_ICON_RIGHT_OFFSET);
double recY = position.getY() + titlePoint.getY() + CLOSE_ICON_TOP_OFFSET;
// 比较的是相对位置的偏移量是否在一定距离内
// 所以要得到鼠标相对于当前tab块的坐标
return (recX < ex && ex < recX + CLOSE_ICON_RIGHT_OFFSET && ey < recY && ey > position.getY());
}
/**
* 获取tab布局在body内的绝对位置
*
* @return
*/
private double[] getTabAbsolutePositionInBody() {
// 获取tab布局的位置,鼠标相对于tab按钮的位置
Container mainLayout = cardLayout.getBackupParent();
// 这个point是当前tab布局的相对坐标,是相对于父容器的坐标
// 比如父级是一个absolute块,放在左上角,现在得到的point就是(0,0)
Point point = mainLayout.getLocation();
int y = 0;
int x = 0;
// 遍历一下,不然是相对位置,嵌套后位置不对
// 这里是要得到tab布局的绝对位置,所以要加上父组件的位置
while (mainLayout.getParent() != null) {
if (mainLayout instanceof XWCardLayout) {
y += mainLayout.getY();
}
mainLayout = mainLayout.getParent();
return (recX < ex && ex < recX + CLOSE_ICON_RIGHT_OFFSET && ey < recY && ey > position.getY());
if ((mainLayout instanceof XWCardMainBorderLayout) || (mainLayout instanceof XWAbsoluteLayout)) {
x += mainLayout.getX();
y += mainLayout.getY();
}
}
double mainX = point.getX() + x;
double mainY = point.getY() + y;
return new double[]{mainX, mainY};
}
//将当前switchButton改为选中状态
@ -306,7 +342,7 @@ public class XCardSwitchButton extends XButton {
}
}
@Override
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;

37
designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java

@ -24,21 +24,25 @@ import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.imenu.UIPopupMenu;
import com.fr.design.mainframe.EditingMouseListener;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormHierarchyTreePane;
import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.CardSwitchButton;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WCardLayout;
import com.fr.form.ui.container.WTabDisplayPosition;
import com.fr.form.ui.container.cardlayout.WCardTagLayout;
import com.fr.form.ui.container.cardlayout.WTabFitLayout;
import com.fr.general.act.BorderPacker;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
import com.fr.general.act.BorderPacker;
import com.fr.general.cardtag.DefaultTemplateStyle;
import com.fr.stable.StringUtils;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Rectangle;
import java.awt.event.ContainerEvent;
import java.awt.event.MouseEvent;
import java.util.HashMap;
@ -434,7 +438,7 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout {
}
private void fixTitleLayout(XLayoutContainer parent){
private void fixTitleLayout(XLayoutContainer parent) {
FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner();
LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(formDesigner, parent);
if (layoutAdapter != null) {
@ -443,4 +447,31 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout {
}
}
/**
* <p> 对于tab组件WCardMainBorderLayout里面有两个子容器:
* <li> WCardTitleLayout里面包含两个部分一个是CardAddButton另一个是WCardTagLayout - tabpane0 </li>
* <li> WCardLayout里面放的是WTabFitLayout - tab00tab10</li>
* <p> 在右侧组件树选择删除WCardTagLayout时tabpane0按照现在的产品逻辑应该删除整个tab组件
*
* @param creator 组件
* @param designer 表单设计器
*/
@Override
public void deleteRelatedComponent(XCreator creator, FormDesigner designer) {
XWCardTagLayout tagLayout = (XWCardTagLayout) creator;
// 先删除所有tab按钮
tagLayout.removeAll();
//逐层回溯找出最外层的XWCardMainBorderLayout
XWCardTitleLayout cardTitleLayout = (XWCardTitleLayout) tagLayout.getBackupParent();
XWCardMainBorderLayout mainLayout = (XWCardMainBorderLayout) cardTitleLayout.getBackupParent();
// 删除tab布局
SelectionModel selectionModel = designer.getSelectionModel();
if (mainLayout != null) {
selectionModel.setSelectedCreator(mainLayout);
selectionModel.deleteSelection();
}
LayoutUtils.layoutRootContainer(designer.getRootComponent());
FormHierarchyTreePane.getInstance().refreshRoot();
selectionModel.setSelectedCreator(designer.getRootComponent());
}
}

6
designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java

@ -3,6 +3,7 @@ package com.fr.design.mainframe.share.util;
import com.fr.base.theme.FormTheme;
import com.fr.design.DesignerEnvManager;
import com.fr.design.extra.PluginConstants;
import com.fr.design.login.config.DefaultLoginKeys;
import com.fr.form.share.base.CancelCheck;
import com.fr.form.share.constants.ShareComponentConstants;
import com.fr.ftp.util.Base64;
@ -45,10 +46,7 @@ import java.util.Set;
* created by Harrison on 2020/05/27
**/
public class DownloadUtils {
private static final String CERTIFICATE_PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtsz62CPSWXZE/IYZRiAuTSZkw\n" +
"1WOwer8+JFktK0uKLAUuQoBr+UjAMFtRA8W7JgKMDwZy/2liEAiXEOSPU/hrdV8D\n" +
"tT541LnGi1X/hXiRwuttPWYN3L2GYm/d5blU+FBNwghBIrdAxXTzYBc6P4KL/oYX\n" +
"nMdTIrkz8tYkG3QoFQIDAQAB";
private static final String CERTIFICATE_PUBLIC_KEY = DefaultLoginKeys.getInstance().getKey("Fine-Designer_Reu_Share_CERTIFICATE_PUBLIC_KEY");
private static String getReusesUrl() {
return StableUtils.pathJoin(OnlineShopUtils.getReuInfoPath(), "file/download");

2
designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetCardTagBoundPane.java

@ -29,7 +29,7 @@ public class WidgetCardTagBoundPane extends WidgetBoundPane {
@Override
public void initBoundPane() {
cardTagWidth = new UIBoundSpinner(0, Integer.MAX_VALUE, 1);
cardTagWidth = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0);
cardTagWidth.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"));
this.add(WidgetBoundsPaneFactory.createCardTagBoundPane(cardTagWidth));
}

6
designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/WCardMainLayoutDefinePane.java

@ -7,16 +7,13 @@ import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.xpane.CardTagLayoutStylePane;
import com.fr.design.gui.xpane.LayoutStylePane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.widget.accessibles.AccessibleCardTagWLayoutBorderStyleEditor;
import com.fr.design.widget.ui.designer.AbstractDataModify;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.container.WCardLayout;
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import java.awt.BorderLayout;
@ -72,6 +69,9 @@ public class WCardMainLayoutDefinePane extends AbstractDataModify<WCardMainBorde
@Override
public void populateBean(WCardMainBorderLayout ob) {
WCardLayout cardLayout = ob.getCardPart();
if (cardLayout == null) {
return;
}
stylePane.populateBean((LayoutBorderStyle) cardLayout.getBorderStyle());
setCarousel.setSelected(cardLayout.isCarousel());
IntervalPane.setVisible(cardLayout.isCarousel());

6
designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/WCardTagLayoutDefinePane.java

@ -24,7 +24,6 @@ import com.fr.form.ui.container.cardlayout.WCardTagLayout;
import com.fr.general.Background;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
import com.fr.general.cardtag.TemplateStyle;
import javax.swing.BorderFactory;
@ -107,8 +106,11 @@ public class WCardTagLayoutDefinePane extends AbstractDataModify<WCardTagLayout>
public void populateBean(WCardTagLayout ob) {
//标题背景和字体属性设置在WCardLayout上做兼容
XLayoutContainer topLayout = creator.getTopLayout();
if (topLayout.getComponentCount() == 0) {
// 没有子组件,不用做处理
return;
}
LayoutBorderStyle layoutBorderStyle = (LayoutBorderStyle) ((XWCardMainBorderLayout) topLayout).getCardPart().toData().getBorderStyle();
displayPositionGroup.setSelectedIndex(ob.getDisplayPosition().getType());
textDirectionGroup.setSelectedIndex(ob.getTextDirection().getType());
backgroundEditor.setValue(layoutBorderStyle.getTitle().getBackground());

11
designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/ElementCaseDefinePane.java

@ -22,7 +22,6 @@ import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.mainframe.mobile.ui.MobileCollapsedStyleExpandPane;
import com.fr.design.mainframe.mobile.ui.MobileComboBoxDialogEditor;
import com.fr.form.ui.ElementCaseEditor;
import com.fr.form.ui.mobile.MobileCollapsedStyle;
import com.fr.stable.StringUtils;
@ -30,7 +29,9 @@ import javax.swing.BorderFactory;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
/**
* 报表块-移动端属性面板
@ -123,7 +124,6 @@ public class ElementCaseDefinePane extends MobileWidgetDefinePane {
panelWrapper.add(panel, BorderLayout.NORTH);
UIExpandablePane folderPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Fit"), 280, 20, panelWrapper);
this.add(folderPane, BorderLayout.NORTH);
this.bingListeners2Widgets();
this.setGlobalNames();
this.repaint();
}
@ -165,7 +165,6 @@ public class ElementCaseDefinePane extends MobileWidgetDefinePane {
@Override
public void populate(FormDesigner designer) {
this.designer = designer;
this.addAttributeChangeListener(changeListener);
ElementCaseEditor elementCaseEditor = (ElementCaseEditor) xCreator.toData();
this.hComboBox.setSelectedItem(new Item(elementCaseEditor.getHorziontalAttr().description(), elementCaseEditor.getHorziontalAttr()));
this.vComboBox.setSelectedItem(new Item(elementCaseEditor.getVerticalAttr().description(), elementCaseEditor.getVerticalAttr()));
@ -178,6 +177,8 @@ public class ElementCaseDefinePane extends MobileWidgetDefinePane {
this.mobileCollapsedStyleEditor.setStyle(elementCaseEditor.getMobileCollapsedStyle());
fix(elementCaseEditor.getMobileCollapsedStyle());
this.mobileCollapsedStyleEditor.setSelected(elementCaseEditor.getMobileCollapsedStyle().isCollapsedWork());
this.bingListeners2Widgets();
this.addAttributeChangeListener(changeListener);
}
/**
@ -191,7 +192,6 @@ public class ElementCaseDefinePane extends MobileWidgetDefinePane {
@Override
public void update() {
DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified(); // 触发设计器保存按钮亮起来
String globalName = this.getGlobalName();
switch (globalName) {
case "hComboBox":
@ -220,6 +220,7 @@ public class ElementCaseDefinePane extends MobileWidgetDefinePane {
style.setCollapsedWork(this.mobileCollapsedStyleEditor.isSelectedCustom() && !FormDesignerUtils.isInAbsoluteLayout(xCreator));
((ElementCaseEditor) xCreator.toData()).setMobileCollapsedStyle(style);
}
DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified(); // 触发设计器保存按钮亮起来
}
private void setGlobalNames() {

9
designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/TextEditorMobileDefinePane.java

@ -3,7 +3,6 @@ package com.fr.design.widget.ui.designer.mobile;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.widget.ui.designer.mobile.component.MobileTextEditSettingPane;
import com.fr.design.widget.ui.designer.mobile.component.MobileTextFieldInputSettingPane;
import com.fr.form.ui.TextEditor;
@ -31,25 +30,25 @@ public class TextEditorMobileDefinePane extends BaseTextEditorMobileDefinePane {
@Override
protected void initSettingPane(JPanel container) {
inputSettingPane = new MobileTextFieldInputSettingPane();
textSettingPane = new MobileTextEditSettingPane();
// textSettingPane = new MobileTextEditSettingPane();
container.add(inputSettingPane);
container.add(textSettingPane);
// container.add(textSettingPane);
}
@Override
public void populate(FormDesigner designer) {
super.populate(designer);
TextEditor textEditor = (TextEditor) getxCreator().toData();
inputSettingPane.populateBean(textEditor.getMobileScanCodeAttr());
// textSettingPane.populateBean(textEditor.getMobileTextEditAttr());
this.bindListeners2Widgets();
}
@Override
public void update() {
super.update();
TextEditor textEditor = (TextEditor) getxCreator().toData();
inputSettingPane.updateBean(textEditor.getMobileScanCodeAttr());
// textSettingPane.updateBean(textEditor.getMobileTextEditAttr());
DesignerContext.getDesignerFrame().getSelectedJTemplate().fireTargetModified();
}

5
designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobilePasswordEditSettingPane.java

@ -23,11 +23,6 @@ public class MobilePasswordEditSettingPane extends MobileTextEditSettingPane {
this.add(showPassword, BorderLayout.NORTH);
}
@Override
protected boolean getClearDefaultState() {
return true;
}
@Override
public void populateBean(MobileTextEditAttr ob) {
super.populateBean(ob);

5
designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextAreaSettingPane.java

@ -23,6 +23,11 @@ public class MobileTextAreaSettingPane extends MobileTextEditSettingPane {
this.add(showWordCount, BorderLayout.NORTH);
}
@Override
protected boolean getClearDefaultState() {
return false;
}
@Override
public void populateBean(MobileTextEditAttr ob) {
super.populateBean(ob);

4
designer-form/src/main/java/com/fr/design/widget/ui/designer/mobile/component/MobileTextEditSettingPane.java

@ -27,7 +27,7 @@ public class MobileTextEditSettingPane extends BasicBeanPane<MobileTextEditAttr>
}
protected boolean getClearDefaultState() {
return false;
return true;
}
protected void initLayout() {
@ -38,7 +38,7 @@ public class MobileTextEditSettingPane extends BasicBeanPane<MobileTextEditAttr>
@Override
public void populateBean(MobileTextEditAttr ob) {
allowOneClickClear.setSelected(ob.isAllowOneClickClear() != null && ob.isAllowOneClickClear());
allowOneClickClear.setSelected(ob.isAllowOneClickClear() == null || ob.isAllowOneClickClear());
}
@Override

13
designer-realize/src/main/java/com/fr/design/widget/WidgetMobilePaneFactory.java

@ -4,14 +4,8 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.fun.CellWidgetOptionProvider;
import com.fr.design.widget.mobile.WidgetMobilePane;
import com.fr.design.widget.ui.mobile.MultiFileEditorMobilePane;
import com.fr.design.widget.ui.mobile.NumberEditorMobilePane;
import com.fr.design.widget.ui.mobile.PasswordMobilePane;
import com.fr.design.widget.ui.mobile.TextAreaMobilePane;
import com.fr.design.widget.ui.mobile.TextEditorMobilePane;
import com.fr.form.ui.MultiFileEditor;
import com.fr.form.ui.NumberEditor;
import com.fr.form.ui.Password;
import com.fr.form.ui.TextArea;
import com.fr.form.ui.TextEditor;
import com.fr.form.ui.Widget;
import com.fr.general.GeneralContext;
@ -35,9 +29,10 @@ public class WidgetMobilePaneFactory {
static {
mobilePaneMap.put(MultiFileEditor.class, MultiFileEditorMobilePane.class);
mobilePaneMap.put(TextEditor.class, TextEditorMobilePane.class);
mobilePaneMap.put(TextArea.class, TextAreaMobilePane.class);
mobilePaneMap.put(NumberEditor.class, NumberEditorMobilePane.class);
mobilePaneMap.put(Password.class, PasswordMobilePane.class);
// 此版本不发布,先屏蔽入口
// mobilePaneMap.put(TextArea.class, TextAreaMobilePane.class);
// mobilePaneMap.put(NumberEditor.class, NumberEditorMobilePane.class);
// mobilePaneMap.put(Password.class, PasswordMobilePane.class);
mobilePluginPaneMap.putAll(ExtraDesignClassManager.getInstance().getCellWidgetMobileOptionsMap());
GeneralContext.listenPluginRunningChanged(new PluginEventListener() {

2
designer-realize/src/main/java/com/fr/design/widget/ui/mobile/TextEditorMobilePane.java

@ -37,7 +37,7 @@ public class TextEditorMobilePane extends WidgetMobilePane {
settingPane = new MobileTextFieldInputSettingPane();
textSettingPane = new MobileTextEditSettingPane();
container.add(settingPane);
container.add(textSettingPane);
// container.add(textSettingPane);
this.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, container), BorderLayout.NORTH);
}

24
designer-realize/src/main/java/com/fr/grid/GridKeyAction.java

@ -69,28 +69,26 @@ public class GridKeyAction extends AbstractAction {
} else if ("right".equals(actionKey)) {
selectionMove(ReportConstants.MOVE_DIRECTION_RIGHT);
} else if ("up".equals(actionKey)) {
selectionMove(ReportConstants.MOVE_DIRECTION_UP);
directKeyPressed(ReportConstants.MOVE_DIRECTION_UP);
} else if ("down".equals(actionKey)) {
selectionMove(ReportConstants.MOVE_DIRECTION_DOWN);
directKeyPressed(ReportConstants.MOVE_DIRECTION_DOWN);
} else if ("enter".equals(actionKey)) {
enterKeyPressed();
directKeyPressed(ReportConstants.MOVE_DIRECTION_DOWN);
} else if ("tab".equals(actionKey)) {
tabKeyPressed();
directKeyPressed(ReportConstants.MOVE_DIRECTION_RIGHT);
}
}
private void enterKeyPressed() {
if (grid.isCellEditing()) {
grid.stopEditing();
}
selectionMove(ReportConstants.MOVE_DIRECTION_DOWN);
}
private void tabKeyPressed() {
/**
* 传入方向进行单元格的方向移动
*
* @param direction 方向
*/
private void directKeyPressed(int direction) {
if (grid.isCellEditing()) {
grid.stopEditing();
}
selectionMove(ReportConstants.MOVE_DIRECTION_RIGHT);
selectionMove(direction);
}
/**

Loading…
Cancel
Save