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 6881c8445..cd9c835f3 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -8,6 +8,7 @@ import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.env.DesignerWorkspaceGenerator; import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.DesignerWorkspaceInfoContext; import com.fr.design.env.DesignerWorkspaceType; import com.fr.design.env.RemoteDesignerWorkspaceInfo; import com.fr.design.env.RemoteWorkspace; @@ -105,6 +106,7 @@ public class EnvChangeEntrance { private boolean switch2Env(final String envName, PopTipStrategy strategy) { DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); + DesignerWorkspaceInfoContext.setWorkspaceInfo(selectedEnv); WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); try { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java index f1f1c6c75..175ddbfda 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TreeTableDataDictPane.java @@ -64,7 +64,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable { tableFlowPane.add(tableDataNameComboBox); tableDataNameComboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { - tdChange(); + tdChange(true); } }); tableFlowPane.add(new PreviewLabel(this)); @@ -73,19 +73,21 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable { this.add(centerPane, BorderLayout.CENTER); parentMarkRadio = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Tree_Accord_Parent_Marked_Filed"), true); lengthMarkRadio = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Build_Tree_Accord_Marked_Filed_Length")); - parentMarkRadio.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { + parentMarkRadio.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { if (isBuildByParentFiled()) { makeParentEnable(); - tdChange(); + tdChange(false); } } }); - lengthMarkRadio.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { + lengthMarkRadio.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { if (!isBuildByParentFiled()) { makeLengthEnable(); - tdChange(); + tdChange(false); } } }); @@ -169,7 +171,7 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable { } - private void tdChange() { + private void tdChange(boolean isChangeDS) { TableDataWrapper tableDataWrappe = this.tableDataNameComboBox.getSelectedItem(); if (tableDataWrappe == null) { return; @@ -186,7 +188,9 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable { String[] columnNames = new String[len]; namelist.toArray(columnNames); for (int i = 0; i < valueEditorPanes.length; i++) { - valueEditorPanes[i].setEditors(new Editor[]{new ColumnNameEditor(columnNames), new ColumnIndexEditor(len)}, columnNames[0]); + if (isChangeDS || isNoSelectedColumnName(valueEditorPanes[i])) { + valueEditorPanes[i].setEditors(new Editor[]{new ColumnNameEditor(columnNames), new ColumnIndexEditor(len)}, columnNames[0]); + } } } catch (Exception e) { for (int i = 0; i < valueEditorPanes.length; i++) { @@ -197,6 +201,10 @@ public class TreeTableDataDictPane extends BasicPane implements Previewable { } } + private boolean isNoSelectedColumnName(ValueEditorPane valueEditorPane) { + return (Integer) valueEditorPane.update() == -1; + } + @Override protected String title4PopupWindow() { return "TreeTableDataDictionay"; diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java index aaa02f9af..5a8c13889 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/JDBCDefPane.java @@ -511,7 +511,6 @@ public class JDBCDefPane extends JPanel { this.dbtypeComboBox.setSelectedItem(OTHER_DB); } } - this.jdbcDatabase.setIdentity(jdbcDatabase.getIdentity()); // jdbcDatabase.getDriverSource() 只会是空或者是有值,但是为了保险起见,还是应该做个处理 String driverSource = jdbcDatabase.getDriverSource(); if (driverSource == null) { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java b/designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java index 7baf51ddd..eb8d188a1 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/preview/CopyableJTable.java @@ -48,9 +48,17 @@ public class CopyableJTable extends SortableJTable { boolean mouseDrag = false; boolean headerSelect = false; - DefaultTableCellRenderer tableHeaderCellRenderer = new DefaultTableCellRenderer() { + + class CopyableTableHeaderCellRenderer implements TableCellRenderer { + TableCellRenderer tableCellRenderer; + + CopyableTableHeaderCellRenderer(TableCellRenderer tableCellRenderer) { + this.tableCellRenderer = tableCellRenderer; + } + + @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - JComponent comp = (JComponent) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + JComponent comp = (JComponent) this.tableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (isChoose(row, column)) { comp.setBackground(selectBackGround); } else { @@ -58,13 +66,13 @@ public class CopyableJTable extends SortableJTable { } return comp; } - }; + } public CopyableJTable(TableSorter tableModel) { super(tableModel); initListener(); - this.getTableHeader().setDefaultRenderer(tableHeaderCellRenderer); + this.getTableHeader().setDefaultRenderer(new CopyableTableHeaderCellRenderer(this.getTableHeader().getDefaultRenderer())); } private void initListener() { diff --git a/designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceInfoContext.java b/designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceInfoContext.java new file mode 100644 index 000000000..ba8a5b09f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/env/DesignerWorkspaceInfoContext.java @@ -0,0 +1,20 @@ +package com.fr.design.env; + +/** + * + * @author hades + * @version 10.0 + * Created by hades on 2021/8/24 + */ +public class DesignerWorkspaceInfoContext { + + private static DesignerWorkspaceInfo workspaceInfo; + + public static DesignerWorkspaceInfo getWorkspaceInfo() { + return workspaceInfo; + } + + public static void setWorkspaceInfo(DesignerWorkspaceInfo workspaceInfo) { + DesignerWorkspaceInfoContext.workspaceInfo = workspaceInfo; + } +} diff --git a/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java b/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java index 6bb8ec37a..a7d6eb6c1 100644 --- a/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java +++ b/designer-base/src/main/java/com/fr/design/env/LocalDesignerWorkspaceInfo.java @@ -3,6 +3,7 @@ package com.fr.design.env; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralUtils; import com.fr.locale.InterProviderFactory; +import com.fr.stable.CoreConstants; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; @@ -107,7 +108,7 @@ public class LocalDesignerWorkspaceInfo implements DesignerWorkspaceInfo { File engineLib = new File(StableUtils.pathJoin(this.path, ProjectConstants.LIB_NAME, REPORT_ENGINE_JAR)); // 非安装版本允许自由切换 - boolean notExistLib = !ComparatorUtils.equals(GeneralUtils.readFullBuildNO(), InterProviderFactory.getProvider().getLocText("Fine-Core_Basic_About_No_Build")) + boolean notExistLib = !CoreConstants.DOT.equals(StableUtils.getInstallHome()) && !engineLib.exists(); if (notExistLib) { throw new MainVersionNotMatchException(); diff --git a/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java b/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java index f3c85f6fb..363eb1ab0 100644 --- a/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java +++ b/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java @@ -93,7 +93,7 @@ public class TemplateTreePane extends JPanel implements FileOperations { @Override public void mousePressed(MouseEvent evt) { - if (evt.getClickCount() == 2) { + if (reportletsTree.getPathForLocation(evt.getX(), evt.getY()) != null && evt.getClickCount() == 2) { openFile(); } } diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java index b15b9eab9..648cb03f3 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java @@ -3,6 +3,7 @@ package com.fr.design.gui.controlpane; import com.fr.design.constants.UIConstants; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.controlpane.shortcutfactory.ShortCutFactory; +import com.fr.design.gui.ifilechooser.JavaFxNativeFileChooser; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itoolbar.UIToolBarUI; import com.fr.design.gui.itoolbar.UIToolbar; @@ -277,6 +278,10 @@ public abstract class UIControlPane extends JControlPane { this.requestFocus(); return; } + if (JavaFxNativeFileChooser.isShowDialogState()) { + JavaFxNativeFileChooser.setShowDialogState(false); + return; + } saveSettings(); setVisible(false); PopupDialogSaveAction saveAction = OSSupportCenter.getAction(PopupDialogSaveAction.class); diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java index bab3e8851..5769fdacf 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/UnitInputPane.java @@ -10,6 +10,7 @@ import com.fr.design.gui.ispinner.UIBasicSpinner; import com.fr.design.gui.itextfield.UINumberField; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.GeneralUtils; import com.fr.stable.AssistUtils; import com.fr.stable.StringUtils; @@ -27,7 +28,8 @@ import java.math.BigDecimal; * For input Number. */ public abstract class UnitInputPane extends BasicPane { - private static final double NUM_POINT = 0.000001; + private static final double MAX_NUM = 3000.0D; + private static final double NUM_POINT = 0.000001; private int scale = -1; String title; @@ -46,7 +48,7 @@ public abstract class UnitInputPane extends BasicPane { centerPane.add(titleLabel); // Denny:在对话框中加入JSpinner对象 - numberFieldSpinner = new UIBasicSpinner(new SpinnerNumberModel(0, 0, 999, 1)); + numberFieldSpinner = new UIBasicSpinner(new SpinnerNumberModel(0, 0, MAX_NUM, 1)); GUICoreUtils.setColumnForSpinner(numberFieldSpinner, 24); numberFieldSpinner.setPreferredSize(new Dimension(60, 20)); numberFieldSpinner.setMinimumSize(new Dimension(60, 20)); @@ -71,17 +73,17 @@ public abstract class UnitInputPane extends BasicPane { public void populate(float floatValue) { popValue = floatValue; - numberFieldSpinner.setModel(new SpinnerNumberModel(0.00, 0.00, 999.00, 0.01)); + numberFieldSpinner.setModel(new SpinnerNumberModel(0.00, 0.00, MAX_NUM, 0.01)); JFormattedTextField temp = GUICoreUtils.getSpinnerTextField(numberFieldSpinner); addChangeListener(temp); - BigDecimal de = new BigDecimal(floatValue + ""); + BigDecimal de = new BigDecimal(GeneralUtils.objectToString(floatValue)); if (scale > 0) { floatValue = de.setScale(scale, BigDecimal.ROUND_DOWN).floatValue(); } else { floatValue = de.floatValue(); } - //选中多列, 并且列宽不完全一致的话, 就不显示值了. + //选中多列, 并且列宽不完全一致的话, 就不显示值了. temp.setText(AssistUtils.equals(floatValue, 0) ? StringUtils.EMPTY : Utils.convertNumberStringToString(new Float(floatValue))); // denny:默认应该为选中,方便用户修改 @@ -99,8 +101,8 @@ public abstract class UnitInputPane extends BasicPane { public double update() throws ValueNotChangeException { // 值没变就不改 if (!changed) { - throw vncExp; - } + throw vncExp; + } // Denny: get numberFieldSpinner 的 TextField JFormattedTextField temp = GUICoreUtils.getSpinnerTextField(numberFieldSpinner); @@ -108,7 +110,8 @@ public abstract class UnitInputPane extends BasicPane { if (temp.getText().length() == 0) { return 0; } - BigDecimal de = new BigDecimal(temp.getText()); + + BigDecimal de = new BigDecimal(GeneralUtils.objectToString(temp.getValue())); if (scale > 0) { return de.setScale(scale, BigDecimal.ROUND_DOWN).floatValue(); } else { @@ -176,4 +179,4 @@ public abstract class UnitInputPane extends BasicPane { // 鼠标按键在组件上单击时 } }; -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java b/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java index 038212bfd..8be467810 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java +++ b/designer-base/src/main/java/com/fr/design/gui/ifilechooser/JavaFxNativeFileChooser.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.concurrent.CountDownLatch; public class JavaFxNativeFileChooser implements FileChooserProvider { + private static boolean showDialogState = false; private File[] selectedFiles = new File[0]; private FileSelectionMode fileSelectionMode = FileSelectionMode.FILE; private String title = Toolkit.i18nText("Fine-Design_Basic_Open"); @@ -43,8 +44,17 @@ public class JavaFxNativeFileChooser implements FileChooserProvider { return null; } + public static boolean isShowDialogState() { + return showDialogState; + } + + public static void setShowDialogState(boolean showDialogState) { + JavaFxNativeFileChooser.showDialogState = showDialogState; + } + @Override public int showDialog(Component parent) { + setShowDialogState(true); final CountDownLatch latch = new CountDownLatch(1); PlatformImpl.startup(() -> { }); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CopyAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CopyAction.java index c577a8693..b71def807 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CopyAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CopyAction.java @@ -1,8 +1,7 @@ package com.fr.design.designer.beans.actions; - import com.fr.design.base.mode.DesignModeContext; -import com.fr.design.designer.beans.actions.behavior.ComponentEnable; +import com.fr.design.designer.beans.actions.behavior.CopyableEnable; import com.fr.design.mainframe.FormDesigner; import javax.swing.KeyStroke; @@ -18,7 +17,7 @@ public class CopyAction extends FormWidgetEditAction { this.setMnemonic('C'); this.setSmallIcon("/com/fr/design/images/m_edit/copy"); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, DEFAULT_MODIFIER)); - setUpdateBehavior(new ComponentEnable()); + setUpdateBehavior(new CopyableEnable()); this.setEnabled(!DesignModeContext.isBanCopyAndCut()); } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java index e93eebd72..94c84a87d 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java @@ -3,6 +3,7 @@ package com.fr.design.designer.beans.actions; import com.fr.design.base.mode.DesignModeContext; import com.fr.design.designer.beans.actions.behavior.ComponentEnable; +import com.fr.design.designer.beans.actions.behavior.CutableEnable; import com.fr.design.mainframe.FormDesigner; import javax.swing.KeyStroke; @@ -18,7 +19,7 @@ public class CutAction extends FormWidgetEditAction { this.setMnemonic('T'); this.setSmallIcon("/com/fr/design/images/m_edit/cut"); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, DEFAULT_MODIFIER)); - this.setUpdateBehavior(new ComponentEnable()); + this.setUpdateBehavior(new CutableEnable()); this.setEnabled(!DesignModeContext.isBanCopyAndCut()); } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java index 5f9a59de5..c2fec8f39 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java @@ -7,9 +7,7 @@ import java.awt.event.KeyEvent; import javax.swing.*; - -import com.fr.design.designer.beans.actions.behavior.ComponentEnable; - +import com.fr.design.designer.beans.actions.behavior.DeletableEnable; import com.fr.design.mainframe.FormDesigner; /** @@ -26,7 +24,7 @@ public class FormDeleteAction extends FormWidgetEditAction { // Richie:删除菜单图标 this.setSmallIcon("/com/fr/design/images/m_report/delete"); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, 0)); - this.setUpdateBehavior(new ComponentEnable()); + this.setUpdateBehavior(new DeletableEnable()); } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CopyableEnable.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CopyableEnable.java new file mode 100644 index 000000000..ce3254ea8 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CopyableEnable.java @@ -0,0 +1,16 @@ +package com.fr.design.designer.beans.actions.behavior; + +import com.fr.design.designer.beans.actions.FormWidgetEditAction; +import com.fr.design.mainframe.FormDesigner; + +public class CopyableEnable implements UpdateBehavior { + @Override + public void doUpdate(FormWidgetEditAction action) { + FormDesigner designer = action.getEditingComponent(); + if (designer == null) { + action.setEnabled(false); + return; + } + action.setEnabled(designer.isCurrentComponentCopyable()); + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CutableEnable.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CutableEnable.java new file mode 100644 index 000000000..7a6320227 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/CutableEnable.java @@ -0,0 +1,16 @@ +package com.fr.design.designer.beans.actions.behavior; + +import com.fr.design.designer.beans.actions.FormWidgetEditAction; +import com.fr.design.mainframe.FormDesigner; + +public class CutableEnable implements UpdateBehavior { + @Override + public void doUpdate(FormWidgetEditAction action) { + FormDesigner designer = action.getEditingComponent(); + if (designer == null) { + action.setEnabled(false); + return; + } + action.setEnabled(designer.isCurrentComponentCutable()); + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/DeletableEnable.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/DeletableEnable.java new file mode 100644 index 000000000..669582676 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/DeletableEnable.java @@ -0,0 +1,16 @@ +package com.fr.design.designer.beans.actions.behavior; + +import com.fr.design.designer.beans.actions.FormWidgetEditAction; +import com.fr.design.mainframe.FormDesigner; + +public class DeletableEnable implements UpdateBehavior { + @Override + public void doUpdate(FormWidgetEditAction action) { + FormDesigner designer = action.getEditingComponent(); + if (designer == null) { + action.setEnabled(false); + return; + } + action.setEnabled(designer.isCurrentComponentDeletable()); + } +} diff --git a/designer-form/src/main/java/com/fr/design/fit/JFormType.java b/designer-form/src/main/java/com/fr/design/fit/JFormType.java index 7fe795c6f..f2d1c4ad9 100644 --- a/designer-form/src/main/java/com/fr/design/fit/JFormType.java +++ b/designer-form/src/main/java/com/fr/design/fit/JFormType.java @@ -69,12 +69,12 @@ public enum JFormType { }; private int type; private boolean newType; - private PreviewProvider previewType; + private PreviewProvider defaultPreviewType; - JFormType(int type, PreviewProvider previewType) { + JFormType(int type, PreviewProvider defaultPreviewType) { this.type = type; this.newType = (type == 1); - this.previewType = previewType; + this.defaultPreviewType = defaultPreviewType; } public int getType() { @@ -85,8 +85,8 @@ public enum JFormType { return newType; } - public PreviewProvider getPreviewType() { - return previewType; + public PreviewProvider getDefaultPreviewType() { + return defaultPreviewType; } public abstract void switchUI(); @@ -128,6 +128,14 @@ public enum JFormType { * @date: 2020/12/17 16:17 */ public void updatePreviewType(JTemplate jTemplate) { - jTemplate.setPreviewType(this.getPreviewType()); + if (jTemplate.getPreviewType() != null) { + PreviewProvider[] previewProviders = jTemplate.supportPreview(); + for (PreviewProvider previewProvider : previewProviders) { + if (previewProvider.getClass() == jTemplate.getPreviewType().getClass()) { + return; + } + } + } + jTemplate.setPreviewType(this.getDefaultPreviewType()); } } diff --git a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java b/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java index 0d8696ba3..323a28ad0 100644 --- a/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java +++ b/designer-form/src/main/java/com/fr/design/fit/common/TemplateTool.java @@ -39,6 +39,7 @@ public class TemplateTool { @Override public void on(Event event, JTemplate jTemplate) { if (!(jTemplate instanceof JForm)) { + JFormType.OLD_TYPE.switchUIMode(); return; } JFormType currentType = JFormType.OLD_TYPE; diff --git a/designer-form/src/main/java/com/fr/design/form/parameter/FormParaDesigner.java b/designer-form/src/main/java/com/fr/design/form/parameter/FormParaDesigner.java index 0ac74e5b5..20f8203ac 100644 --- a/designer-form/src/main/java/com/fr/design/form/parameter/FormParaDesigner.java +++ b/designer-form/src/main/java/com/fr/design/form/parameter/FormParaDesigner.java @@ -745,5 +745,13 @@ public class FormParaDesigner extends FormDesigner implements ParameterDesignerP return false; } + @Override + public boolean isCurrentComponentCutable() { + return !isRootSelected(); + } + @Override + public boolean isCurrentComponentCopyable() { + return !isRootSelected(); + } } diff --git a/designer-form/src/main/java/com/fr/design/form/util/FormDesignerUtils.java b/designer-form/src/main/java/com/fr/design/form/util/FormDesignerUtils.java index ded4e7c99..4c1f9304b 100644 --- a/designer-form/src/main/java/com/fr/design/form/util/FormDesignerUtils.java +++ b/designer-form/src/main/java/com/fr/design/form/util/FormDesignerUtils.java @@ -36,6 +36,9 @@ public class FormDesignerUtils { * @return */ public static boolean isBodyAbsolute(FormDesigner designer) { + if (!designer.getRootComponent().acceptType(XWFitLayout.class)) { + return false; + } WFitLayout root = ((WFitLayout) designer.getRootComponent().toData()); return root.getBodyLayoutType() == com.fr.form.ui.container.WBodyLayoutType.ABSOLUTE; } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java index 4b7fc8eb9..92127c5a8 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java @@ -110,6 +110,10 @@ public class FormDesigner extends TargetComponent
implements TreeSelection Arrays.asList(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_M_Edit_Delete")}) ); + protected static final ArrayList PARAMETER_TOOLAR_BAN_LIST = new ArrayList( + Arrays.asList(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Cut"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_M_Edit_Copy")}) + ); + private double scale = 1.0D; //底层容器的默认大小 @@ -1267,6 +1271,11 @@ public class FormDesigner extends TargetComponent implements TreeSelection return isForm || isRoot(getSelectionModel().getSelection().getSelectedCreator()); } + public boolean isParameterSelected() { + XCreator xCreator = getSelectionModel().getSelection().getSelectedCreator(); + return xCreator != null && xCreator.acceptType(XWParameterLayout.class); + } + /** * 显示权限编辑界面 */ @@ -1300,6 +1309,10 @@ public class FormDesigner extends TargetComponent implements TreeSelection protected void setToolbarButtons() { //自适应布局和底层都不能删除 DesignerContext.getDesignerFrame().checkCombineUp(!isRootSelected(), NAME_ARRAY_LIST); + + if (isParameterSelected()) { + DesignerContext.getDesignerFrame().checkCombineUp(false, PARAMETER_TOOLAR_BAN_LIST); + } } private void invalidateLayout() { @@ -1385,6 +1398,18 @@ public class FormDesigner extends TargetComponent implements TreeSelection } } + public boolean isCurrentComponentCutable() { + return !(isRootSelected() || isParameterSelected()); + } + + public boolean isCurrentComponentCopyable() { + return !(isRootSelected() || isParameterSelected()); + } + + public boolean isCurrentComponentDeletable() { + return !isRootSelected(); + } + // 当前选中控件可以上移一层吗? public boolean isCurrentComponentMovableUp() { XCreator creator = getSelectionModel().getSelection().getSelectedCreator(); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java index 157ce6f98..782c7f35d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java @@ -5,29 +5,40 @@ import com.fr.decision.webservice.utils.DecisionServiceConstants; import com.fr.design.DesignerEnvManager; import com.fr.design.EnvChangeEntrance; import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.env.DesignerWorkspaceInfo; +import com.fr.design.env.DesignerWorkspaceInfoContext; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.loghandler.DesignerLogger; import com.fr.design.ui.util.UIUtil; -import com.fr.event.Event; import com.fr.event.EventDispatcher; -import com.fr.event.Listener; +import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.report.RemoteDesignConstants; import com.fr.serialization.SerializerHelper; import com.fr.stable.ArrayUtils; +import com.fr.stable.StringUtils; import com.fr.third.apache.log4j.spi.LoggingEvent; +import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier; +import com.fr.third.org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import com.fr.third.org.apache.http.ssl.SSLContexts; +import com.fr.web.WebSocketConfig; +import com.fr.web.socketio.WebSocketProtocol; import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; -import com.fr.workspace.WorkspaceEvent; import com.fr.workspace.base.WorkspaceConstants; import com.fr.workspace.connect.WorkspaceConnection; +import com.fr.workspace.connect.WorkspaceConnectionInfo; import com.fr.workspace.server.socket.SocketInfoOperator; import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyStore; import java.util.Arrays; +import javax.net.ssl.SSLContext; import javax.swing.*; import java.io.IOException; import java.net.URI; @@ -37,26 +48,14 @@ import java.util.TimerTask; public class DesignerSocketIO { - - static { - EventDispatcher.listen(WorkspaceEvent.LostConnect, new Listener() { - @Override - public void on(Event event, Workspace param) { - // 远程设计websocket不支持wss 所以断开无法提醒 - // 使用远程设计的心跳断开来提醒断开 - if (DesignerEnvManager.getEnvManager().isHttps()) { - showConnectionLostDialog(); - } - } - }); - } - enum Status { Connected, Disconnected, Disconnecting } + private static final String HTTPS = "https"; + private static final String HTTP = "http"; private static Socket socket = null; private static Status status = Status.Disconnected; private static Timer disConnectHintTimer = null; @@ -65,6 +64,8 @@ public class DesignerSocketIO { private static String[] uri; //维护一个关于uri列表的计数器 private static int count; + // 当前webSocket选择的协议 + private static String currentProtocol; public static void close() { @@ -95,7 +96,7 @@ public class DesignerSocketIO { //根据uri和计数器建立连接,并注册监听 try { if (count < uri.length) { - socket = IO.socket(new URI(uri[count])); + socket = IO.socket(new URI(uri[count]), createOptions()); socket.on(WorkspaceConstants.WS_LOGRECORD, printLog); socket.on(WorkspaceConstants.CONFIG_MODIFY, modifyConfig); socket.on(Socket.EVENT_CONNECT_ERROR, failRetry); @@ -112,15 +113,58 @@ public class DesignerSocketIO { } } + private static IO.Options createOptions() { + IO.Options options = new IO.Options(); + try { + if (ComparatorUtils.equals(currentProtocol, HTTPS)) { + options.sslContext = getSSLContext(); + options.hostnameVerifier = NoopHostnameVerifier.INSTANCE; + options.secure = true; + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return options; + } + + private static SSLContext getSSLContext() throws Exception { + WorkspaceConnectionInfo connection = getConnectionInfo(); + String certPath = connection.getCertPath(); + String certSecretKey = connection.getCertSecretKey(); + if (StringUtils.isBlank(certPath) || StringUtils.isBlank(certSecretKey)) { + return SSLContexts.createDefault(); + } + KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); + try (FileInputStream keystore = new FileInputStream(new File(certPath))) { + trustStore.load(keystore, certSecretKey.toCharArray()); + } + return SSLContexts.custom() + .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) + .build(); + } + + private static WorkspaceConnectionInfo getConnectionInfo() { + if (DesignerWorkspaceInfoContext.getWorkspaceInfo() == null) { + String currentName = DesignerEnvManager.getEnvManager().getCurEnvName(); + DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(currentName); + return info.getConnection(); + } else { + return DesignerWorkspaceInfoContext.getWorkspaceInfo().getConnection(); + } + } + private static String[] getSocketUri() throws IOException { Workspace current = WorkContext.getCurrent(); URL url = new URL(current.getPath()); Integer[] ports = current.get(SocketInfoOperator.class).getPort(); WorkspaceConnection connection = current.getConnection(); + // 服务器配置https webSocket可能是wss也可能是ws webSocket的协议可以单独配置 + WebSocketProtocol webSocketProtocol = WebSocketConfig.getInstance().getProtocol(); + currentProtocol = webSocketProtocol == WebSocketProtocol.PLAIN ? HTTP : HTTPS; String[] result = new String[ports.length]; for (int i = 0; i < ports.length; i++) { result[i] = String.format("%s://%s:%s%s?%s=%s&%s=%s", - url.getProtocol(), + currentProtocol, url.getHost(), ports[i], WorkspaceConstants.WS_NAMESPACE, @@ -129,6 +173,7 @@ public class DesignerSocketIO { RemoteDesignConstants.USER_LOCK_ID, connection.getId()); } + FineLoggerFactory.getLogger().error("Available ports: {}, current Protocol: {}", Arrays.toString(ports), currentProtocol); return result; } @@ -136,7 +181,7 @@ public class DesignerSocketIO { private static final Emitter.Listener failRetry = new Emitter.Listener() { @Override public void call(Object... args) { - FineLoggerFactory.getLogger().warn("failed args: {}", Arrays.toString(args)); + printLog(args, PrintEventLogImpl.WARN, "failed args: {}"); status = Status.Disconnecting; socket.close(); count++; @@ -183,7 +228,7 @@ public class DesignerSocketIO { * todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上,切换成心跳断开之后进行提醒, * socket 只用推日志和通知配置变更 */ - FineLoggerFactory.getLogger().error("disConnected args: {}", Arrays.toString(objects)); + printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}"); if (status != Status.Disconnecting) { showConnectionLostDialog(); } @@ -199,7 +244,7 @@ public class DesignerSocketIO { private static void showConnectionLostDialog() { try { - UIUtil.invokeAndWaitIfNeeded(new Runnable() { + UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { FineJOptionPane.showMessageDialog( @@ -226,4 +271,46 @@ public class DesignerSocketIO { } }; + private static void printLog(Object[] objects, PrintEventLog printEventLog, String prefix) { + for (Object object : objects) { + if (object instanceof Throwable) { + Throwable throwable = (Throwable) object; + printEventLog.printThrowable(throwable); + } else { + printEventLog.print(prefix, object); + } + } + } + + interface PrintEventLog { + void printThrowable(Throwable throwable); + void print(String s, Object ...object); + } + + enum PrintEventLogImpl implements PrintEventLog { + ERROR { + @Override + public void printThrowable(Throwable throwable) { + FineLoggerFactory.getLogger().error(throwable.getMessage(), throwable); + } + + @Override + public void print(String s, Object... object) { + FineLoggerFactory.getLogger().error(s, object); + } + }, + + WARN { + @Override + public void printThrowable(Throwable throwable) { + FineLoggerFactory.getLogger().warn(throwable.getMessage(), throwable); + } + + @Override + public void print(String s, Object... object) { + FineLoggerFactory.getLogger().warn(s, object); + } + }; + } + } diff --git a/designer-realize/src/main/java/com/fr/grid/AbstractGridHeaderMouseHandler.java b/designer-realize/src/main/java/com/fr/grid/AbstractGridHeaderMouseHandler.java index b04e4ad1e..044f0a458 100644 --- a/designer-realize/src/main/java/com/fr/grid/AbstractGridHeaderMouseHandler.java +++ b/designer-realize/src/main/java/com/fr/grid/AbstractGridHeaderMouseHandler.java @@ -157,7 +157,7 @@ public abstract class AbstractGridHeaderMouseHandler extends MouseInputAdapter { dragType = GridUtils.DRAG_CELL_SIZE; isDragPermited = true; dragIndex = index; - showToolTip(evt, createToolTipString(sizeList.get(dragIndex).toPixD(resolution), sizeList.getRangeValue(0, dragIndex + 1).toPixD(resolution))); + showToolTip(evt, createToolTipString(sizeList.get(dragIndex), sizeList.getRangeValue(0, dragIndex + 1))); return true; } if (between(evt, tmpSize1, tmpSize2)) { @@ -301,21 +301,18 @@ public abstract class AbstractGridHeaderMouseHandler extends MouseInputAdapter { protected abstract void resetGridSelectionBySelect(int index, ElementCasePane ePane); - private String createToolTipString(double doubleValue, double totalDoubleValue) { + private String createToolTipString(UNIT unitValue, UNIT totalUnitValue) { int unitType = DesignerEnvManager.getEnvManager().getReportLengthUnit(); -// int resolution = ScreenResolution.getScreenResolution(); - FU ulen = FU.valueOfPix((int) doubleValue, resolution); - FU tulen = FU.valueOfPix((int) totalDoubleValue, resolution); ReportLengthUNITProvider lengthUNIT = DesignerUIModeConfig.getInstance().parseLengthUNIT(unitType); String unit = lengthUNIT.unitText(); - double len = lengthUNIT.unit2Value4Scale(ulen); - double tlen = lengthUNIT.unit2Value4Scale(tulen); + double len = lengthUNIT.unit2Value4Scale(unitValue); + double tlen = lengthUNIT.unit2Value4Scale(totalUnitValue); StringBuilder sb = new StringBuilder(); sb.append(String.format("%.2f", new Double(len))) .append('/').append(String.format("%.2f", new Double(tlen))) .append(unit).append('(') - .append((int)(doubleValue)).append('/') - .append((int)(totalDoubleValue)) + .append((int)(unitValue.toPixD(resolution))).append('/') + .append((int)(totalUnitValue.toPixD(resolution))) .append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Px")) .append(')'); return sb.toString(); @@ -416,7 +413,7 @@ public abstract class AbstractGridHeaderMouseHandler extends MouseInputAdapter { DynamicUnitList sizeList = getSizeList(report); // int resolution = ScreenResolution.getScreenResolution(); - this.setToolTipText2(this.createToolTipString(sizeList.get(dragIndex).toPixD(resolution), sizeList.getRangeValue(0, dragIndex + 1).toPixD(resolution))); + this.setToolTipText2(this.createToolTipString(sizeList.get(dragIndex), sizeList.getRangeValue(0, dragIndex + 1))); } ePane.repaint(); diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java index 0035e1e60..724f947c9 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java @@ -62,12 +62,12 @@ public class DesignerWorkspaceProvider extends Activator { } else { WorkContext.switchTo(workspace); //在设计器完全启动完成后,对初始环境进行一次服务检测,对主要功能无影响,异常仅做日志提示即可 - final DesignerWorkspaceInfo selectEnv = workspaceInfo; + final String selectEnv = current; EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { @Override public void on(Event event, Null aNull) { try { - VersionCheckUtils.showVersionCheckDialog(selectEnv.getName()); + VersionCheckUtils.showVersionCheckDialog(selectEnv); } catch (Exception e) { FineLoggerFactory.getLogger().warn("Check Service Failed"); }