Browse Source

Merge pull request #12475 in DESIGN/design from feature/x to bugfix/11.0

* commit '8b605c399b38c057efae2ad41e9e4c1c49936f4c':
  REPORT-98345 版本管理三期 修改代码规范
  REPORT-98345 版本管理三期 修改代码规范
  REPORT-98345 版本管理三期 修改线程池,修改代码规范,添加部分注释
  REPORT-98345 版本管理三期 提交总体代码
  Revert "Revert "REPORT-91839 模板版本管理二期 修复bug""
  Revert "Revert "REPORT-91839 模板版本管理二期 多删了一部分""
  Revert "Revert "REPORT-91839 模板版本管理二期 补充按钮交互,消除冗余代码""
  Revert "Revert "REPORT-91839 模板版本管理二期 优化判断新老模式的逻辑,事件响应改为Config准备后进行""
  Revert "Revert "REPORT-91839 模板版本管理二期 完善一下判断逻辑,增加自动保存标签设置""
  Revert "Revert "REPORT-91839 模板版本管理二期 修复规范问题""
  Revert "Revert "REPORT-91839 模板版本管理二期""
  Revert "Revert "REPORT-80651 模板版本管理重构一期补交""
  REPORT-98536 fvs替换frm-设计器变更 - 去掉新建决策报表快捷键
  REPORT-98536 fvs替换frm-设计器变更
bugfix/11.0
superman 1 year ago
parent
commit
d1795e972f
  1. 198
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  2. 47
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  3. 33
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  4. 31
      designer-base/src/main/java/com/fr/design/mainframe/vcs/RecycleAction.java
  5. 25
      designer-base/src/main/java/com/fr/design/mainframe/vcs/TableEntity.java
  6. 21
      designer-base/src/main/java/com/fr/design/mainframe/vcs/TableValueOperator.java
  7. 25
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsConfigManager.java
  8. 162
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsService.java
  9. 108
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableEntity.java
  10. 210
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java
  11. 370
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/AbstractSupportSelectTablePane.java
  12. 26
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/EditFileVersionDialog.java
  13. 266
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java
  14. 192
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java
  15. 434
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java
  16. 339
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java
  17. 63
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsOperatorPane.java
  18. 4
      designer-base/src/main/resources/com/fr/design/images/buttonicon/new_other_normal.svg
  19. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_center_manager_normal.svg
  20. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_center_open_normal.svg
  21. 7
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_delete_normal.svg
  22. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_preview_normal.svg
  23. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_restore_normal.svg
  24. 7
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_delete_disabled.svg
  25. 7
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_delete_normal.svg
  26. 8
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_normal.svg
  27. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_restore_disabled.svg
  28. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_restore_normal.svg
  29. 3
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_search_normal.svg
  30. 5
      designer-base/src/main/resources/com/fr/design/vcs/move_failed.svg
  31. 5
      designer-base/src/main/resources/com/fr/design/vcs/move_success.svg
  32. 3
      designer-base/src/main/resources/com/fr/design/vcs/vcs_move_icon.svg
  33. 8
      designer-form/src/main/java/com/fr/design/actions/NewFormAction.java
  34. 8
      designer-realize/src/main/java/com/fr/start/MainDesigner.java
  35. BIN
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs1.png
  36. BIN
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs2.png
  37. BIN
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs3.png
  38. BIN
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs4.png
  39. 160
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/template_resource/local_templates.json

198
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -36,6 +36,7 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.VcsMovePanel;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.unit.UnitConvertUtil;
import com.fr.design.utils.gui.GUICoreUtils;
@ -54,9 +55,12 @@ import com.fr.stable.os.OperatingSystem;
import com.fr.third.apache.logging.log4j.Level;
import com.fr.transaction.Configurations;
import com.fr.transaction.Worker;
import com.fr.transaction.WorkerAdaptor;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.git.config.GcConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
@ -77,14 +81,7 @@ import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Window;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
@ -122,6 +119,7 @@ public class PreferencePane extends BasicPane {
private static final int PREFERENCE_LABEL_MAX_WIDTH = 460;
private static final int OFFSET_HEIGHT = 60;
private static final int VCS_FILL_TOTAL = 5;
private static final String TYPE = "pressed";
private static final String DISPLAY_TYPE = "+";
private static final String BACK_SLASH = "BACK_SLASH";
@ -149,6 +147,32 @@ public class PreferencePane extends BasicPane {
private static final Level[] LOG = {Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG};
private static final int ONE_DAY_INT = 1;
private static final int ONE_WEEK_INT = 7;
private static final int ONE_MONTH_INT = 30;
private static final int THREE_MONTH_INT = 90;
private static final int SIX_MONTH_INT = 180;
private static final int ONE_DAY_INDEX = 0;
private static final int ONE_WEEK_INDEX = 1;
private static final int ONE_MONTH_INDEX = 2;
private static final int THREE_MONTH_INDEX = 3;
private static final int SIX_MONTH_INDEX = 4;
private static final String ONE_DAY = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_DAY");
private static final String ONE_WEEK = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_WEEK");
private static final String ONE_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_MONTH");
private static final String THREE_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_THREE_MONTH");
private static final String SIX_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_SIX_MONTH");
private static final String[] INTERVAL = {
ONE_DAY,
ONE_WEEK,
ONE_MONTH,
THREE_MONTH,
SIX_MONTH
};
private static final int DEFAULT_INDEX = 3;
private boolean languageChanged; // 是否修改了设计器语言设置
//设置是否支持undo
private UICheckBox supportUndoCheckBox;
@ -186,8 +210,20 @@ public class PreferencePane extends BasicPane {
private UICheckBox cloudAnalyticsDelayCheckBox;
private UICheckBox vcsEnableCheckBox;
private UICheckBox useVcsAutoSaveScheduleCheckBox;
private UICheckBox useVcsAutoCleanScheduleCheckBox;
private UIComboBox autoCleanIntervalComboBox;
private UIComboBox autoCleanRetainIntervalComboBox;
private IntegerEditor autoSaveIntervalEditor;
private UICheckBox saveCommitCheckBox;
private UICheckBox useIntervalCheckBox;
private VcsMovePanel movePanel;
private JPanel saveIntervalPane;
private JPanel autoCleanPane;
private UICheckBox startupPageEnabledCheckBox;
private IntegerEditor saveIntervalEditor;
private UICheckBox gcEnableCheckBox;
@ -227,13 +263,26 @@ public class PreferencePane extends BasicPane {
JPanel advancePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
UIScrollPane adviceScrollPane = patchScroll(advancePane);
jtabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), adviceScrollPane);
//初始化vcs总面板
JPanel vcsParentPane = new JPanel();
CardLayout cardLayout = new CardLayout();
vcsParentPane.setLayout(cardLayout);
//vcs配置面板
JPanel vcsPane = new JPanel(new BorderLayout());
//添加滚动条
UIScrollPane vcsScrollPane = patchScroll(vcsPane);
//配置面板作为vcs总面板的一张卡片
vcsParentPane.add(vcsScrollPane, VcsMovePanel.SETTING);
jtabPane.addTab(i18nText("Fine-Design_Vcs_Title"), vcsParentPane);
contentPane.add(jtabPane, BorderLayout.NORTH);
createFunctionPane(generalPane);
createEditPane(generalPane);
createColorSettingPane(generalPane);
createVcsSettingPane(generalPane);
// vcsPane
createVcsSettingPane(vcsPane, vcsParentPane, cardLayout);
// ConfPane
JPanel confLocationPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane();
@ -345,21 +394,33 @@ public class PreferencePane extends BasicPane {
return generalPanelWithScroll;
}
private void createVcsSettingPane(JPanel generalPane) {
JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Title"));
generalPane.add(vcsPane);
private void createVcsSettingPane(JPanel generalPane,JPanel parentPane, CardLayout cardLayout) {
//迁移面板
movePanel = createMovePane(cardLayout, parentPane);
generalPane.add(movePanel, BorderLayout.NORTH);
JPanel savePane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Save_Setting"));
JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Clean_Setting"));
JPanel containPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
containPane.add(savePane);
containPane.add(vcsPane);
//填充一下面板
fillPane(containPane, VCS_FILL_TOTAL);
generalPane.add(containPane, BorderLayout.CENTER);
remindVcsLabel = new UILabel(i18nText("Fine-Design_Vcs_Remind"));
remindVcsLabel.setVisible(!VcsHelper.getInstance().needInit());
vcsEnableCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_SaveAuto"));
saveIntervalPane = createSaveIntervalPane();
saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete"));
saveIntervalEditor = new IntegerEditor(60);
useIntervalCheckBox = new UICheckBox();
savePane.add(vcsEnableCheckBox);
savePane.add(saveIntervalPane);
//gc面板
JPanel gcControlPane = createGcControlPane();
JPanel enableVcsPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
enableVcsPanel.add(vcsEnableCheckBox);
enableVcsPanel.add(remindVcsLabel);
JPanel intervalPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
final UILabel everyLabel = new UILabel(i18nText("Fine-Design_Vcs_Every"));
@ -368,6 +429,7 @@ public class PreferencePane extends BasicPane {
intervalPanel.add(everyLabel);
intervalPanel.add(saveIntervalEditor);
intervalPanel.add(delayLabel);
autoCleanPane = createAutoCleanPane();
vcsEnableCheckBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
@ -390,8 +452,63 @@ public class PreferencePane extends BasicPane {
vcsPane.add(enableVcsPanel);
vcsPane.add(intervalPanel);
vcsPane.add(saveCommitCheckBox);
vcsPane.add(autoCleanPane);
saveIntervalPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
if (VcsHelper.getInstance().isLegacyMode()) {
// 老版本时才显示gc选项
vcsPane.add(gcControlPane);
}
}
private void fillPane(JPanel containPane, int total) {
for (int i = 0; i < total; i++) {
containPane.add(new JPanel());
}
}
private VcsMovePanel createMovePane(CardLayout cardLayout, JPanel parentPane) {
return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack(){
@Override
public void doCallBack(boolean visible) {
saveIntervalPane.setVisible(visible);
autoCleanPane.setVisible(visible);
}
});
};
private JPanel createAutoCleanPane() {
JPanel autoCleanPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoCleanScheduleCheckBox = new UICheckBox();
autoCleanIntervalComboBox = new UIComboBox(INTERVAL);
autoCleanIntervalComboBox.setSelectedIndex(DEFAULT_INDEX);
autoCleanRetainIntervalComboBox = new UIComboBox(INTERVAL);
autoCleanRetainIntervalComboBox.setSelectedIndex(DEFAULT_INDEX);
autoCleanPane.add(useVcsAutoCleanScheduleCheckBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Every")));
autoCleanPane.add(autoCleanIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Content")));
autoCleanPane.add(autoCleanRetainIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Last")));
useVcsAutoCleanScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(false);
return autoCleanPane;
}
private JPanel createSaveIntervalPane() {
JPanel saveIntervalPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoSaveScheduleCheckBox = new UICheckBox();
autoSaveIntervalEditor = new IntegerEditor(60);
saveIntervalPane.add(useVcsAutoSaveScheduleCheckBox);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Every")));
saveIntervalPane.add(autoSaveIntervalEditor);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Save_Delay")));
useVcsAutoSaveScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode());
saveIntervalPane.setVisible(false);
return saveIntervalPane;
}
/**
* 模创建板版本gc 配置操作面板
@ -796,6 +913,10 @@ public class PreferencePane extends BasicPane {
gcEnableCheckBox.setSelected(GcConfig.getInstance().isGcEnable());
gcButton.setEnabled(gcEnableCheckBox.isSelected());
useVcsAutoSaveScheduleCheckBox.setSelected(vcsConfigManager.isUseAutoSave());
useVcsAutoCleanScheduleCheckBox.setSelected(VcsConfig.getInstance().isUseV2AutoClean());
autoSaveIntervalEditor.setValue(vcsConfigManager.getAutoSaveInterval());
gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor());
paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor());
@ -883,6 +1004,21 @@ public class PreferencePane extends BasicPane {
}
}
private int getDay(int dateIndex) {
switch (dateIndex) {
case ONE_DAY_INDEX:
return ONE_DAY_INT;
case ONE_WEEK_INDEX:
return ONE_WEEK_INT;
case ONE_MONTH_INDEX:
return ONE_MONTH_INT;
case SIX_MONTH_INDEX:
return SIX_MONTH_INT;
default:
return THREE_MONTH_INT;
}
}
/**
* The method of update.
*/
@ -931,6 +1067,17 @@ public class PreferencePane extends BasicPane {
vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected());
vcsConfigManager.setSaveCommit(this.saveCommitCheckBox.isSelected());
vcsConfigManager.setUseInterval(this.useIntervalCheckBox.isSelected());
vcsConfigManager.setUseAutoSave(this.useVcsAutoSaveScheduleCheckBox.isSelected());
vcsConfigManager.setAutoSaveInterval(this.autoSaveIntervalEditor.getValue());
Configurations.update(new WorkerAdaptor(VcsConfig.class) {
@Override
public void run() {
VcsConfig.getInstance().setUseV2AutoClean(useVcsAutoCleanScheduleCheckBox.isSelected());
VcsConfig.getInstance().setV2CleanInterval(getDay(autoCleanIntervalComboBox.getSelectedIndex()));
VcsConfig.getInstance().setV2RetainInterval(getDay(autoCleanRetainIntervalComboBox.getSelectedIndex()));
}
});
dealWithSchedule();
designerEnvManager.setStartupPageEnabled(this.startupPageEnabledCheckBox.isSelected());
Configurations.update(new Worker() {
@Override
@ -1005,6 +1152,31 @@ public class PreferencePane extends BasicPane {
}
private void dealWithSchedule() {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
boolean v2FunctionSupport = VcsHelper.getInstance().checkV2FunctionSupport();
if (v2FunctionSupport) {
//如果支持V2
if (useVcsAutoSaveScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto save!");
VcsHelper.getInstance().startAutoSave(autoSaveIntervalEditor.getValue());
} else {
VcsHelper.getInstance().stopAutoSave();
}
if (useVcsAutoCleanScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!");
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(getDay(autoCleanIntervalComboBox.getSelectedIndex()));
} else {
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob();
}
}
return null;
}
}.execute();
}
// 如果语言设置改变了,则显示重启对话框
public void showRestartDialog() {
if (!languageChanged) {

47
designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java

@ -18,6 +18,8 @@ import com.fr.design.lock.LockInfoDialog;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.mainframe.manager.search.searcher.control.pane.TemplateSearchRemindPane;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.file.FILE;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
@ -38,6 +40,7 @@ import java.util.UUID;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
@ -59,6 +62,7 @@ import java.util.Objects;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.jetbrains.annotations.Nullable;
@ -346,13 +350,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
YES_NO_OPTION)
== JOptionPane.YES_OPTION) {
// 删除所有选中的即可
if (!deleteNodes(Arrays.asList(treeNodes))) {
FineJOptionPane.showConfirmDialog(null,
Toolkit.i18nText("Fine-Design_Basic_Delete_Failure"),
Toolkit.i18nText("Fine-Design_Basic_Error"),
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE);
}
deleteNodes(Arrays.asList(treeNodes));
}
} else {
@ -377,13 +375,7 @@ public class TemplateTreePane extends JPanel implements FileOperations {
YES_NO_OPTION)
== JOptionPane.YES_OPTION) {
// 删除其他
if (!deleteNodes(deletableNodes)) {
FineJOptionPane.showConfirmDialog(null,
Toolkit.i18nText("Fine-Design_Basic_Delete_Failure"),
Toolkit.i18nText("Fine-Design_Basic_Error"),
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE);
}
deleteNodes(deletableNodes);
}
}
Set<FileNode> deletedFileNode = deletableNodes.stream().map(treeNode -> (FileNode) treeNode.getUserObject()).collect(Collectors.toSet());
@ -407,14 +399,17 @@ public class TemplateTreePane extends JPanel implements FileOperations {
}
}
private boolean deleteNodes(Collection<ExpandMutableTreeNode> nodes) {
private void deleteNodes(Collection<ExpandMutableTreeNode> nodes) {
new SwingWorker<Boolean,Void>(){
@Override
protected Boolean doInBackground() throws Exception {
boolean success = true;
for (ExpandMutableTreeNode treeNode : nodes) {
Object node = treeNode.getUserObject();
if (node instanceof FileNode) {
FileNodeFILE nodeFILE = new FileNodeFILE((FileNode) node);
if (nodeFILE.exists()) {
VcsService.getInstance().doRecycle(VcsHelper.getInstance().dealWithFilePath(((FileNode) node).getEnvPath()));
if (TemplateResourceManager.getResource().delete(nodeFILE)) {
HistoryTemplateListCache.getInstance().deleteFile(nodeFILE);
} else {
@ -425,6 +420,26 @@ public class TemplateTreePane extends JPanel implements FileOperations {
}
return success;
}
@Override
protected void done() {
try {
if (!get()) {
showErrorDialog();
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
private void showErrorDialog() {
FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(),
Toolkit.i18nText("Fine-Design_Basic_Delete_Failure"),
Toolkit.i18nText("Fine-Design_Basic_Error"),
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE);
}
@Override

33
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java

@ -16,6 +16,7 @@ import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.datapane.management.search.TableDataTreeSearchManager;
import com.fr.design.data.tabledata.ResponseDataSourceChange;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.FileOperations;
import com.fr.design.file.FileToolbarStateChangeListener;
@ -34,8 +35,10 @@ import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.mainframe.manager.search.searcher.control.pane.TemplateTreeSearchToolbarPane;
import com.fr.design.mainframe.vcs.RecycleAction;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.FileVersionsPanel;
import com.fr.design.mainframe.vcs.ui.VcsNewPane;
import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef;
@ -150,6 +153,8 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private VcsAction vcsAction = new VcsAction();
private RecycleAction recycleAction = new RecycleAction();
//搜索
private SwitchAction switchAction = new SwitchAction();
private TemplateTreeSearchToolbarPane searchToolbarPane;
@ -325,13 +330,17 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
if (VcsHelper.getInstance().needInit()) {
vcsAction = new VcsAction();
if (!WorkContext.getCurrent().isCluster()) {
if (!isLegacyOnCluster()) {
vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_Title"));
} else {
vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_NotSupportRemote"));
}
toolbarDef.addShortCut(vcsAction);
//11.0.19及其之后加入回收站逻辑
if (!VcsHelper.getInstance().isLegacyMode()) {
recycleAction = new RecycleAction();
toolbarDef.addShortCut(recycleAction);
}
}
}
@ -492,14 +501,19 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
public void actionPerformed(ActionEvent e) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
boolean isCurrentEditing = isCurrentEditing(path);
if (VcsHelper.getInstance().isLegacyMode()) {
boolean currentEditing = isCurrentEditing(path);
// 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本)
closeOpenedTemplate(path, isCurrentEditing);
closeOpenedTemplate(path, currentEditing);
FileVersionsPanel fileVersionTablePanel = FileVersionsPanel.getInstance();
fileVersionTablePanel.showFileVersionsPane();
stateChange();
} else {
VcsNewPane panel = new VcsNewPane(path);
BasicDialog dialog = panel.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
}
@ -509,7 +523,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private void fireVcsActionChange(boolean enable) {
if (!DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable()
|| VcsHelper.getInstance().isUnSelectedTemplate()
|| WorkContext.getCurrent().isCluster()) {
|| isLegacyOnCluster()) {
setEnabled(false);
return;
}
@ -810,6 +824,11 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
}
}
private boolean isLegacyOnCluster() {
// 老模式且为集群,用于代替之前的只判断集群逻辑
return WorkContext.getCurrent().isCluster() && VcsHelper.getInstance().isLegacyMode();
}
private String doCheck (String userInput, String suffix) {
String errorMsg = StringUtils.EMPTY;
if (selectedOperation.duplicated(userInput, suffix, true)) {

31
designer-base/src/main/java/com/fr/design/mainframe/vcs/RecycleAction.java

@ -0,0 +1,31 @@
package com.fr.design.mainframe.vcs;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.ui.RecyclePane;
import java.awt.event.ActionEvent;
/**
* 回收站
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/4
*/
public class RecycleAction extends UpdateAction {
public RecycleAction() {
this.setSmallIcon("/com/fr/design/standard/vcslist/vcs_recycle");
this.setName(Toolkit.i18nText("Fine-Design_Vcs_Recycle"));
}
@Override
public void actionPerformed(ActionEvent e) {
RecyclePane pane = new RecyclePane();
BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
}

25
designer-base/src/main/java/com/fr/design/mainframe/vcs/TableEntity.java

@ -0,0 +1,25 @@
package com.fr.design.mainframe.vcs;
/**
* 表格选中包装类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/11
*/
public interface TableEntity {
/**
* 是否选中
*
* @return
*/
boolean isSelect();
/**
* 设置选中属性
*
* @param select
*/
void setSelect(boolean select);
}

21
designer-base/src/main/java/com/fr/design/mainframe/vcs/TableValueOperator.java

@ -0,0 +1,21 @@
package com.fr.design.mainframe.vcs;
/**
* 表格操作
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/11
*/
public interface TableValueOperator<T> {
/**
* 获取对应列的值
*
* @param o 表格内容
* @param columnIndex 列数
* @return 对应列的值
*/
Object getValue(T o, int columnIndex);
}

25
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsConfigManager.java

@ -16,6 +16,10 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
private boolean useInterval = true;
private int saveInterval = 60;
private boolean useAutoSave = false;
private int autoSaveInterval = 15;
public static VcsConfigManager getInstance() {
return instance;
}
@ -48,6 +52,23 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
return saveInterval;
}
public int getAutoSaveInterval() {
return autoSaveInterval;
}
public void setAutoSaveInterval(int autoSaveInterval) {
this.autoSaveInterval = autoSaveInterval;
}
public boolean isUseAutoSave() {
return useAutoSave;
}
public void setUseAutoSave(boolean useAutoSave) {
this.useAutoSave = useAutoSave;
}
public void setSaveInterval(int saveInterval) {
this.saveInterval = saveInterval;
}
@ -59,6 +80,8 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
this.setSaveInterval(reader.getAttrAsInt("saveInterval", 60));
this.setUseInterval(reader.getAttrAsBoolean("useInterval", true));
this.setVcsEnable(reader.getAttrAsBoolean("vcsEnable", true));
this.setAutoSaveInterval(reader.getAttrAsInt("autoSaveInterval", 15));
this.setUseAutoSave(reader.getAttrAsBoolean("useAutoSave", false));
}
}
@ -69,6 +92,8 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
writer.attr("saveInterval", this.getSaveInterval());
writer.attr("useInterval", this.isUseInterval());
writer.attr("vcsEnable", this.isVcsEnable());
writer.attr("autoSaveInterval", this.getAutoSaveInterval());
writer.attr("useAutoSave", this.isUseAutoSave());
writer.end();
}
}

162
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsService.java

@ -0,0 +1,162 @@
package com.fr.design.mainframe.vcs;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.log.FineLoggerFactory;
import com.fr.report.entity.VcsEntity;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 版本管理常用操作
* <p>便于版本管理面板快捷实现版本管理相关操作
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/10
*/
public class VcsService {
private static final String SERVICE = "VcsService";
private static final VcsService INSTANCE = new VcsService();
private static final ExecutorService executorService = Executors.newFixedThreadPool(5, new NamedThreadFactory(SERVICE));
/**
* 获取单例
*
* @return
*/
public static VcsService getInstance() {
return INSTANCE;
}
private VcsService() {
}
/**
* 回收模板
*
* @param filename
*/
public void doRecycle(String filename) {
try {
WorkContext.getCurrent().get(VcsOperator.class).recycleVersion(VcsHelper.getInstance().getCurrentUsername(), filename);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 从回收站还原版本
*
* @param vcsEntities
*/
public void doRestore(List<VcsEntity> vcsEntities) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
for (VcsEntity vcsEntity : vcsEntities) {
String fileName = vcsEntity.getFilename();
operator.restoreVersion(fileName);
}
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除对应列表中所有模板的指定的历史版本
*
* @param vcsEntities
*/
public void doDelete(List<VcsEntity> vcsEntities, boolean all) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
for (VcsEntity vcsEntity : vcsEntities) {
String fileName = vcsEntity.getFilename();
if (all) {
operator.deleteVersionForRecycle(fileName);
} else {
operator.deleteVersion(fileName, vcsEntity.getVersion());
}
}
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除指定模板的全部历史版本
*
* @param entity VcsEntity
*/
public void deleteEntity(VcsEntity entity) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator vcsOperator = WorkContext.getCurrent().get(VcsOperator.class);
String fileName = entity.getFilename();
vcsOperator.deleteVersionForRecycle(fileName);
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 删除指定模板的指定版本
*
* @param fileName 文件名
* @param version 版本号
*/
public void deleteEntity(String fileName, int version) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator vcsOperator = WorkContext.getCurrent().get(VcsOperator.class);
vcsOperator.deleteVersion(fileName, version);
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 更新版本
*
* @param entity 版本
*/
public void updateEntityAnnotation(VcsEntity entity) {
try {
executorService.execute(new Runnable() {
@Override
public void run() {
VcsOperator vcsOperator = WorkContext.getCurrent().get(VcsOperator.class);
vcsOperator.updateVersion(entity);
}
});
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}

108
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableEntity.java

@ -0,0 +1,108 @@
package com.fr.design.mainframe.vcs;
import com.fr.report.entity.VcsEntity;
/**
* 包装VcsEntity的用于表格展示与处理的类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/10
*/
public class VcsTableEntity implements TableEntity{
private boolean select = false;
private static final String MB = "MB";
private static final String VERSION = "V.";
private static final double MB_SIZE = 1024.0;
private VcsEntity entity;
public VcsTableEntity(VcsEntity entity) {
this.entity = entity;
}
/**
* 获取模板名
*
* @return 模板名
*/
public String getFilename() {
return entity.getFilename();
}
/**
* 获取版本大小
*
* @return 版本大小
*/
public String getSize() {
return String.format("%.2f",entity.getSize()/MB_SIZE) + MB;
}
/**
* 获取修改时间
*
* @return 修改时间
*/
public String getTime() {
return entity.getTime().toLocaleString();
}
/**
* 获取用户名
*
* @return 用户名
*/
public String getUserName() {
return entity.getUsername();
}
/**
* 获取备注
*
* @return 备注
*/
public String getCommitMsg() {
return entity.getCommitMsg();
}
/**
* 获取版本号
*
* @return 版本号
*/
public String getVersion() {
return VERSION + entity.getVersion();
}
/**
* 获取删除时间
*
* @return 删除时间
*/
public String getDeleteTime() {
return entity.getDeleteTime().toLocaleString();
}
@Override
public boolean isSelect() {
return select;
}
@Override
public void setSelect(boolean select) {
this.select = select;
}
public VcsEntity getEntity() {
return entity;
}
public void setEntity(VcsEntity entity) {
this.entity = entity;
}
}

210
designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java

@ -2,6 +2,7 @@ package com.fr.design.mainframe.vcs.common;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.config.ConfigEvent;
import com.fr.design.DesignerEnvManager;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane;
@ -12,6 +13,9 @@ import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.JTemplateActionListener;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.ui.FileVersionTable;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.ListenerAdaptor;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext;
@ -25,11 +29,14 @@ import com.fr.workspace.server.vcs.filesystem.VcsFileSystem;
import com.fr.workspace.server.vcs.git.config.GcConfig;
import javax.swing.Icon;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Created by XiaXiang on 2019/4/17.
@ -55,10 +62,65 @@ public class VcsHelper implements JTemplateActionListener {
private final static String SERVICE_NAME_MOVE = "moveVcs";
private static final VcsHelper INSTANCE = new VcsHelper();
private static ScheduledExecutorService saveSchedule;
private volatile boolean legacyMode;
public static VcsHelper getInstance() {
return INSTANCE;
}
private VcsHelper() {
VcsOperator op = WorkContext.getCurrent().get(VcsOperator.class);
// 开了设计器启动页面时一开始取不到VcsOperator,通过下面的切换环境事件再取,这边判断下
if (op != null) {
legacyMode = op.isLegacyMode();
}
EventDispatcher.listen(ConfigEvent.READY, new ListenerAdaptor() {
@Override
protected void on(Event event) {
try {
legacyMode = WorkContext.getCurrent().get(VcsOperator.class).isLegacyMode();
FineLoggerFactory.getLogger().info("[VcsHelper] legacyMode:{}", legacyMode);
} catch (Exception e) {
//保险起见走老逻辑
legacyMode = true;
FineLoggerFactory.getLogger().error("[VcsHelper] get legacy failed", e.getMessage());
}
}
});
}
/**
* 开始自动保存任务
*
* @param interval 时间间隔
*/
public void startAutoSave(int interval) {
stopAutoSave();
saveSchedule = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("VcsAutoSaveSchedule"));
saveSchedule.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
FineLoggerFactory.getLogger().info("[VcsV2] start to run auto save schedule");
JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable() && JTemplate.isValid(template)) {
fireAutoSaveVcs(template);
}
}
}, interval, interval, TimeUnit.MINUTES);
}
/**
* 停止任务
*/
public void stopAutoSave() {
if (saveSchedule != null && !saveSchedule.isShutdown()) {
saveSchedule.shutdown();
}
}
private int containsFolderCounts() {
TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree();
if (fileTree.getSelectionPaths() == null) {
@ -93,18 +155,28 @@ public class VcsHelper implements JTemplateActionListener {
}
private String getEditingFilename() {
String vcsCacheDir = VcsFileSystem.getInstance().getVcsCacheRelativePath();
JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String editingFilePath = jt.getEditingFILE().getPath();
if (editingFilePath.startsWith(ProjectConstants.REPORTLETS_NAME)) {
editingFilePath = editingFilePath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY);
} else if (editingFilePath.startsWith(vcsCacheDir)) {
editingFilePath = editingFilePath.replaceFirst(vcsCacheDir, StringUtils.EMPTY);
return dealWithFilePath(editingFilePath);
}
/**
* 处理传入的文件名使其符合Vcs规范
*
* @param filePath 文件路径
* @return 处理完的文件
*/
public String dealWithFilePath(String filePath) {
String vcsCacheDir = VcsFileSystem.getInstance().getVcsCacheRelativePath();
if (filePath.startsWith(ProjectConstants.REPORTLETS_NAME)) {
filePath = filePath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY);
} else if (filePath.startsWith(vcsCacheDir)) {
filePath = filePath.replaceFirst(vcsCacheDir, StringUtils.EMPTY);
}
if (editingFilePath.startsWith(VCS_FILE_SLASH)) {
editingFilePath = editingFilePath.substring(1);
if (filePath.startsWith(VCS_FILE_SLASH)) {
filePath = filePath.substring(1);
}
return editingFilePath;
return filePath;
}
private boolean needDeleteVersion(VcsEntity entity) {
@ -133,24 +205,21 @@ public class VcsHelper implements JTemplateActionListener {
fireVcs.execute(new Runnable() {
@Override
public void run() {
String fileName = getEditingFilename();
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
VcsEntity entity = operator.getFileVersionByIndex(fileName, 0);
boolean replace = needDeleteVersion(entity);
int latestFileVersion = 0;
if (entity != null) {
latestFileVersion = entity.getVersion();
}
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) {
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1);
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
FileVersionTable.getInstance().updateModel(1, WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY)));
List<VcsEntity> updatedList = WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY));
SwingUtilities.invokeLater(() -> FileVersionTable.getInstance().updateModel(1, updatedList));
} else {
operator.saveVersion(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1);
}
VcsEntity oldEntity = WorkContext.getCurrent().get(VcsOperator.class).getFileVersionByIndexAndUsername(fileName, getCurrentUsername(), 1);
if (needDeleteVersion(oldEntity)) {
operator.deleteVersion(oldEntity.getFilename(), oldEntity.getVersion());
operator.saveVersion(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace);
}
if (GcConfig.getInstance().isGcEnable()) {
operator.gc();
@ -158,8 +227,10 @@ public class VcsHelper implements JTemplateActionListener {
}
});
if (!fireVcs.isShutdown()) {
fireVcs.shutdown();
}
}
/**
* 移动Vcs
@ -188,12 +259,85 @@ public class VcsHelper implements JTemplateActionListener {
moveVcs.shutdown();
}
/**
* 判断是否为老模式
* @return 是否为老模式
*/
public boolean isLegacyMode() {
return legacyMode;
}
/**
* 更新当前的legacyMode状态
* <li>目前用在迁移结束后更新模式为新模式</li>
*
*/
public void updateLegacyMode() {
this.legacyMode = !legacyMode;
}
@Override
public void templateOpened(JTemplate<?, ?> jt) {
try {
if (checkAutoSaveSupport()) {
startAutoSave(VcsConfigManager.getInstance().getAutoSaveInterval());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/**
* 响应版本管理自动保存
*
* <li>直接用template的file来保存的话相当于拿源文件来保存模板这样用户做的改动会丢失</li>
* <li>因此需要自己实现一下自动保存的逻辑将当前模板的数据导出,再拿这个Byte[]去做我们需要的保存处理</li>
* <li>保存后需要触发清理逻辑</li>
*
* @param jt 模板
*/
public void fireAutoSaveVcs(final JTemplate jt) {
String fileName = getEditingFilename();
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
VcsEntity entity = operator.getFileVersionByIndex(fileName, 0);
boolean replace = needDeleteVersion(entity);
int latestFileVersion = 0;
if (entity != null) {
latestFileVersion = entity.getVersion();
}
if (JTemplate.isValid(jt)) {
doSave(jt, fileName, latestFileVersion, replace, operator);
}
}
private void doSave(JTemplate jt, String fileName, int latestFileVersion, boolean replace, VcsOperator operator) {
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) {
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
List<VcsEntity> updatedList = WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY));
SwingUtilities.invokeLater(() -> FileVersionTable.getInstance().updateModel(1, updatedList));
} else {
autoSave(jt, getCurrentUsername(), fileName, latestFileVersion + 1, replace, operator);
}
if (GcConfig.getInstance().isGcEnable()) {
operator.gc();
}
}
private void autoSave(JTemplate jt, String currentUsername, String fileName, int nowVersion, boolean replace, VcsOperator operator) {
try {
if (JTemplate.isValid(jt)) {
operator.autoSave(currentUsername, fileName, StringUtils.EMPTY, nowVersion, jt.exportData(), replace);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/**
* 模板保存时 处理.
*
@ -210,6 +354,40 @@ public class VcsHelper implements JTemplateActionListener {
@Override
public void templateClosed(JTemplate<?, ?> jt) {
try {
if (checkAutoSaveSupport()) {
stopAutoSave();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/**
* 判断是否支持V2功能
*
* @return 支持返回true
*/
public boolean checkV2FunctionSupport() {
return !VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot());
}
/**
* 判断是否支持迁移功能
*
* @return 支持返回true
*/
public boolean checkMoveFunctionSupport() {
return WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot();
}
/**
* 是否支持自动保存
*
* @return 支持返回true
*/
public boolean checkAutoSaveSupport() {
return VcsConfigManager.getInstance().isUseAutoSave() && !VcsHelper.getInstance().isLegacyMode();
}
}

370
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/AbstractSupportSelectTablePane.java

@ -0,0 +1,370 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.vcs.TableEntity;
import com.fr.design.mainframe.vcs.TableValueOperator;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.UIResource;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 比较通用的带全选功能的表格面板
*
* <p>整体划分为north与center两个面板参考BorderLayout的布局,center部分用于置放表格表格部分支持全选north部分支持自定义用于展示各种标签按钮输入框</p>
* <p>获取数据的时候不需要用SwingWorker(内部已经实现)考虑到大部分表格内容的展现需要去获取数据而获取数据大部分都需要一定时间因此为了防止UI冻结在加载数据结束之前先展示进度条面板</p>
* <p>使用该面板你可能需要:</p>
* <li>自己封装一个实现TableEntity接口(该接口用于提供(选中/全选)功能)内部存放你要放入表格的类例如VcsEntity,参考VcsTableEntity</li>
* <li>初始化的时候赋予变量model值(如果有需要的话)该变量用于控制表格的数据类型,默认DefaultModel分为5列第一列为勾选框</li>
* <li>(一定要干的)初始化的时候赋予变量model内operators值,用于确认表格每一列getValueAt返回的值</li>
* <li>上面板也允许自定义重写initTableTopPane即可</li>
* <li>要使用该面板可以参考:RecyclePane</li>
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/11
*/
public abstract class AbstractSupportSelectTablePane<T extends TableEntity> extends BasicPane {
public static final Color DEFAULT_HEADER_COLOR = new Color(232, 232, 233);
public static final Color DEFAULT_SELECT_TABLE_ROW_COLOR = new ColorUIResource(200, 221, 233);
private CardLayout layout;
protected JPanel contentPane;
protected UITextField searchTextField = new UITextField();;
protected UILabel deleteLabel = new UILabel();
/**
* 整体面板的center部分,用来放表格
*/
protected UITableEditorPane<T> tableContentPane;
protected UITableModelAdapter<T> model;
/**
* 整体面板的north部分
*/
protected JPanel tableTopPane = new JPanel();
/**
* 整体面板
*/
protected JPanel tablePane = new JPanel();
private int selectCount = 0;
private static final String LOADING = "loading";
private static final String TABLE ="table";
protected List<T> entities;
protected TableValueOperator<T> operator;
public AbstractSupportSelectTablePane(String title, TableValueOperator<T> operators, String[] tableNames, boolean needBorder) {
this.operator = operators;
this.model = new DefaultModel(tableNames, new Class[]{
Boolean.class,
UILabel.class,
UILabel.class,
UILabel.class,
UILabel.class
});
init(title, needBorder);
}
public AbstractSupportSelectTablePane(String title, TableValueOperator<T> operators, boolean needBorder) {
this.operator = operators;
init(title, needBorder);
}
/**
* 初始化
*
*/
private void init(String title, boolean needBorder) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
contentPane = new JPanel();
layout = new CardLayout();
contentPane.setLayout(layout);
contentPane.add(new TipsPane(true), LOADING);
this.add(contentPane);
new SwingWorker<List<T>, Void>(){
@Override
protected List<T> doInBackground() {
return getTableList();
}
@Override
protected void done() {
try {
entities = get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
contentPane.add(createTablePane(title, needBorder), TABLE);
layout.show(contentPane, TABLE);
}
}.execute();
}
/**
* 获取表格数据
*
* @return 表格数据
*/
abstract protected List<T> getTableList();
private JPanel createTablePane(String title, boolean needBorder) {
tablePane = needBorder ? FRGUIPaneFactory.createTopVerticalTitledBorderPane(title) : new JPanel();
if (isNeedTopPane()) {
initTableTopPane();
initTopPaneListener();
}
initTableContentPane(entities);
tablePane.setLayout(new BorderLayout());
tablePane.add(tableTopPane, BorderLayout.NORTH);
tablePane.add(tableContentPane, BorderLayout.CENTER);
tableContentPane.getEditTable().getColumnModel().getColumn(0).setMaxWidth(50);
return tablePane;
}
/**
* 初始化表格面板
*
* @param entities 表格数据
*/
protected void initTableContentPane(List<T> entities) {
tableContentPane = new UITableEditorPane<>(model);
model.setList(entities);
JTable table = tableContentPane.getEditTable();
table.getTableHeader().setBackground(DEFAULT_HEADER_COLOR);
table.getTableHeader().setDefaultRenderer(new HeaderRenderer(tableContentPane.getEditTable()));
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int row = ((JTable) e.getSource()).rowAtPoint(e.getPoint());
int col = ((JTable) e.getSource()).columnAtPoint(e.getPoint());
if (col == 0) {
T entity = model.getSelectedValue();
//改变面板的各个状态
changeComponentStatus(entity, row, col, table);
}
}
});
initExtraListener4Table(table);
}
/**
* 设定额外的表格事件
*
* @param table 表格
*/
protected void initExtraListener4Table(JTable table) {
//do nothing
}
/**
* 是否需要上面板
*
* @return
*/
protected boolean isNeedTopPane() {
return true;
}
private void changeComponentStatus(T entity, int row, int col, JTable table) {
boolean select = entity.isSelect();
entity.setSelect(!select);
table.setValueAt(entity.isSelect(), row, col);
if (select) {
selectCount--;
} else {
selectCount++;
}
//更新表头的勾选框状态
HeaderRenderer renderer = (HeaderRenderer) table.getTableHeader().getDefaultRenderer();
renderer.refreshHeader(table, selectCount >= table.getRowCount());
}
/**
* 初始化上面板
*/
abstract protected void initTableTopPane();
/**
* 初始化上面板事件
*/
abstract protected void initTopPaneListener();
/**
* 表头渲染
*/
public class HeaderRenderer implements TableCellRenderer {
JTableHeader tableHeader;
final UICheckBox selectBox;
public HeaderRenderer(JTable table) {
this.tableHeader = table.getTableHeader();
selectBox = new UICheckBox();
selectBox.setSelected(false);
tableHeader.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 0) {
//获得选中列
int selectColumn = tableHeader.columnAtPoint(e.getPoint());
if (selectColumn == 0) {
boolean value = !selectBox.isSelected();
selectBox.setSelected(value);
selectAllOrNull(value);
selectCount = value ? table.getRowCount() : 0;
tableHeader.repaint();
model.fireTableDataChanged();
}
}
}
private void selectAllOrNull(boolean value) {
int len = table.getRowCount();
for (T entity : model.getList()) {
entity.setSelect(value);
}
}
});
}
/**
* 刷新表头
*
* @param table
*/
public void refreshHeader(JTable table, boolean value) {
selectBox.setSelected(value);
int rowHeight = table.getRowHeight();
table.updateUI();
table.setRowHeight(rowHeight);
}
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row, int column) {
tableHeader = table.getTableHeader();
tableHeader.setReorderingAllowed(false);
String valueStr = (String) value;
JLabel label = new JLabel(valueStr);
label.setHorizontalAlignment(SwingConstants.LEFT);
selectBox.setHorizontalAlignment(SwingConstants.CENTER);
selectBox.setBorderPainted(true);
JComponent component = (column == 0) ? selectBox : label;
component.setForeground(tableHeader.getForeground());
component.setBackground(tableHeader.getBackground());
component.setFont(tableHeader.getFont());
component.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
return component;
}
}
@Override
protected String title4PopupWindow() {
return StringUtils.EMPTY;
}
/**
* 默认的数据model
*/
public class DefaultModel extends UITableModelAdapter<T> {
public DefaultModel(String[] tableNames, Class[] classes) {
super(tableNames);
setColumnClass(classes);
this.setDefaultEditor(Boolean.class, new BooleanEditor());
this.setDefaultRenderer(Boolean.class, new BooleanRenderer());
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
T vcsEntity = this.getList().get(rowIndex);
return operator.getValue(vcsEntity, columnIndex);
}
@Override
public boolean isCellEditable(int row, int col) {
return col == 0;
}
@Override
public UITableEditAction[] createAction() {
return new UITableEditAction[0];
}
}
/**
* 用于展示指定风格的checkbox的Editor
*/
public class BooleanEditor extends DefaultCellEditor {
public BooleanEditor() {
super(new UICheckBox());
UICheckBox checkBox = (UICheckBox) getComponent();
checkBox.setHorizontalAlignment(UICheckBox.CENTER);
}
}
/**
* 用于展示指定风格的checkbox的渲染器
*/
public class BooleanRenderer extends UICheckBox implements TableCellRenderer, UIResource {
public BooleanRenderer() {
super();
setHorizontalAlignment(JLabel.CENTER);
setBorderPainted(true);
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
setSelected((Boolean) table.getValueAt(row, 0));
setUI(getUICheckBoxUI());
setBorder(BorderFactory.createEmptyBorder());
setBackground(isSelected ? DEFAULT_SELECT_TABLE_ROW_COLOR : Color.WHITE);
return this;
}
}
}

26
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/EditFileVersionDialog.java

@ -81,12 +81,7 @@ public class EditFileVersionDialog extends UIDialog {
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
entity.setCommitMsg(msgTestArea.getText());
WorkContext.getCurrent().get(VcsOperator.class).updateVersion(entity);
setVisible(false);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
FileVersionTable table = FileVersionTable.getInstance();
table.updateModel(table.getSelectedRow(), WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst("/", StringUtils.EMPTY)));
doOK();
}
});
@ -101,4 +96,23 @@ public class EditFileVersionDialog extends UIDialog {
public void checkValid() throws Exception {
}
/**
* 确定事件
*
*/
public void doOK() {
entity.setCommitMsg(msgTestArea.getText());
WorkContext.getCurrent().get(VcsOperator.class).updateVersion(entity);
setVisible(false);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
FileVersionTable table = FileVersionTable.getInstance();
table.updateModel(table.getSelectedRow(), WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst("/", StringUtils.EMPTY)));
}
public UITextArea getMsgTestArea() {
return msgTestArea;
}
}

266
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java

@ -0,0 +1,266 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.vcs.TableEntity;
import com.fr.design.mainframe.vcs.TableValueOperator;
import com.fr.design.mainframe.vcs.VcsTableEntity;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import javax.swing.Icon;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static com.fr.design.i18n.Toolkit.i18nText;
/**
* 回收面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/5
*/
public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity> {
public static final Icon ICON_SEARCH = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_recycle_search");
public static final Icon ICON_REFRESH = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_recycle_restore");
public static final Icon ICON_DELETE = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_recycle_delete");
protected UITextField searchTextField;
protected UILabel deleteLabel;
protected UILabel restoreLabel;
private static final int COLUMNS_COUNT = 15;
public RecyclePane() {
super(i18nText("Fine-Design_Vcs_Recycle"), (o, columnIndex) -> {
switch (columnIndex) {
case 0:
return o.isSelect();
case 1:
return o.getFilename();
case 2:
return o.getSize();
case 3:
return o.getDeleteTime();
case 4:
return o.getTime();
default:
return o;
}
}, new String[]{
StringUtils.EMPTY,
Toolkit.i18nText("Fine-Design_Vcs_Template"),
Toolkit.i18nText("Fine-Design_Vcs_Recycle_Size"),
Toolkit.i18nText("Fine-Design_Vcs_Delete_Time"),
Toolkit.i18nText("Fine-Design_Vcs_Time")
}, true);
}
public RecyclePane(String title, TableValueOperator<VcsTableEntity> operators, boolean needBorder) {
super(title, operators, needBorder);
}
@Override
protected List<VcsTableEntity> getTableList() {
List<VcsEntity> entityList = WorkContext.getCurrent().get(VcsOperator.class).getRecycleEntities();
List<VcsTableEntity> tableEntities = new ArrayList<>();
for (VcsEntity entity : entityList) {
tableEntities.add(new VcsTableEntity(entity));
}
return tableEntities;
}
@Override
protected void initTableTopPane() {
tableTopPane = new JPanel();
tableTopPane.setLayout(new BorderLayout());
JPanel leftPane = new JPanel();
JPanel rightPane = new JPanel();
//左边面板,包含搜索icon+搜索框
if (isNeedSearch()) {
searchTextField = new UITextField();
searchTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Vcs_Start_Search"));
searchTextField.setColumns(COLUMNS_COUNT);
leftPane.add(new UILabel(ICON_SEARCH));
leftPane.add(searchTextField);
}
//右边面板,包括还原按钮+删除按钮
if (isNeedRestore()) {
restoreLabel = new UILabel(ICON_REFRESH);
restoreLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
rightPane.add(restoreLabel);
}
if (isNeedDelete()) {
deleteLabel = new UILabel(ICON_DELETE);
deleteLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
rightPane.add(deleteLabel);
}
tableTopPane.add(leftPane, BorderLayout.EAST);
tableTopPane.add(rightPane, BorderLayout.WEST);
}
@Override
protected void initTopPaneListener() {
initSearchTextFiledListener();
initRestoreListener();
initDeleteLabelListener();
}
private void initDeleteLabelListener() {
if (isNeedDelete()) {
deleteLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
fireListener(new VcsResponseListener() {
@Override
public void doAfterChooseYes(List<VcsEntity> selectList) {
VcsService.getInstance().doDelete(selectList, isNeedDeleteAllVersion());
}
}, true);
}
});
}
}
private void initRestoreListener() {
if (isNeedRestore()) {
restoreLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
fireListener(new VcsResponseListener() {
@Override
public void doAfterChooseYes(List<VcsEntity> selectList) {
VcsService.getInstance().doRestore(selectList);
}
}, false);
}
});
}
}
private void initSearchTextFiledListener() {
if (isNeedSearch()) {
searchTextField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String str = searchTextField.getText();
List<VcsTableEntity> entityList = model.getList();
model.setList(entityList.stream().filter(entity -> entity.getEntity().getFilename().contains(str)).collect(Collectors.toList()));
model.fireTableDataChanged();
}
});
}
}
private void fireListener(VcsResponseListener listener, boolean isDelete) {
List<VcsEntity> selectList = model.getList().stream().filter(TableEntity::isSelect).map(VcsTableEntity::getEntity).collect(Collectors.toList());
if (selectList.size() > 0) {
int selVal = FineJOptionPane.showConfirmDialog(
RecyclePane.this,
isDelete ? getDeleteTip(selectList.size()) : getRestoreTip(selectList.size()),
Toolkit.i18nText("Fine-Design_Basic_Confirm"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
model.setList(model.getList().stream().filter(tableEntity -> !tableEntity.isSelect()).collect(Collectors.toList()));
model.fireTableDataChanged();
listener.doAfterChooseYes(selectList);
}
}
}
/**
* 删除范围
*
* @return 默认删除全部版本
*/
protected boolean isNeedDeleteAllVersion() {
return true;
}
@Override
protected String title4PopupWindow() {
return i18nText("Fine-Design_Vcs_Recycle");
}
/**
* 删除提示
*
* @return 默认需要
*/
protected String getDeleteTip(int size) {
return Toolkit.i18nText("Fine-Design_Vcs_Delete_Select_All_Version_Forever", size);
}
/**
* 还原提示
*
* @return 默认需要
*/
protected String getRestoreTip(int size) {
return Toolkit.i18nText("Fine-Design_Vcs_Restore_Select_All_Version", size);
}
/**
* 是否需要还原功能
*
* @return 默认需要
*/
protected boolean isNeedRestore() {
return true;
}
/**
* 是否需要搜索功能
*
* @return 默认需要
*/
protected boolean isNeedSearch() {
return true;
}
/**
* 是否需要删除功能
*
* @return 默认需要
*/
protected boolean isNeedDelete() {
return true;
}
/**
* 版本管理按钮事件响应
*/
public interface VcsResponseListener {
/**
* 选择确认之后要做的事情
*
* @param selectList 所选上的内容
*/
void doAfterChooseYes(List<VcsEntity> selectList);
}
}

192
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java

@ -0,0 +1,192 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.vcs.VcsTableEntity;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
/**
* 版本中心面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/13
*/
public class VcsCenterPane extends VcsNewPane {
private UILabel manager;
private UILabel open;
private UILabel delete;
private static final Icon MANAGER_ICON = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_center_manager");
private static final Icon DELETE_ICON = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_operator_delete");
private static final Icon OPEN_ICON = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_center_open");
private static final Class[] CLASSES = new Class[]{
Boolean.class,
UILabel.class,
UILabel.class,
UILabel.class,
VcsOperatorPane.class
};
private static final int OPERATOR_COL = 4;
private static final String[] COLUMN_NAMES = new String[]{
StringUtils.EMPTY,
Toolkit.i18nText("Fine-Design_Vcs_Template"),
Toolkit.i18nText("Fine-Design_Vcs_Time"),
Toolkit.i18nText("Fine-Design_Vcs_Size"),
Toolkit.i18nText("Fine-Design_Vcs_Operator")
};
private static final String TITLE = Toolkit.i18nText("Fine-Design_Vcs_Center");
public VcsCenterPane() {
super(TITLE, (o, columnIndex) -> {
switch (columnIndex) {
case 0:
return o.isSelect();
case 1:
return o.getFilename();
case 2:
return o.getTime();
case 3:
return o.getSize();
default:
return o;
}
}, false, COLUMN_NAMES, CLASSES, OPERATOR_COL);
}
@Override
public VcsOperatorPane createOperatorPane() {
manager = new UILabel(MANAGER_ICON);
open = new UILabel(OPEN_ICON);
delete = new UILabel(DELETE_ICON);
initManagerListener();
initOpenListener();
initDeleteListener();
List<JComponent> components = new ArrayList<>();
components.add(manager);
components.add(open);
components.add(delete);
return new VcsOperatorPane(components);
}
private void initDeleteListener() {
delete.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JTable table = tableContentPane.getEditTable();
Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn());
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
String fileName = entity.getFilename();
int selVal = FineJOptionPane.showConfirmDialog(
VcsCenterPane.this,
Toolkit.i18nText("Fine-Design_Vcs_Center_Delete", fileName),
Toolkit.i18nText("Fine-Design_Basic_Confirm"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
VcsService.getInstance().deleteEntity(entity);
}
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(fileName), false)));
}
}
});
}
private void initOpenListener() {
open.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JTable table = tableContentPane.getEditTable();
Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn());
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(entity.getFilename()), false)));
}
}
});
}
private void initManagerListener() {
manager.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JTable table = tableContentPane.getEditTable();
Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn());
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
VcsNewPane pane = new VcsNewPane(getTemplateTruePath(entity.getFilename())) {
@Override
protected String title4PopupWindow() {
return entity.getFilename()+Toolkit.i18nText("Fine-Design_Vcs_Version_Tips");
}
};
BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
}
});
}
@Override
protected List<VcsTableEntity> getTableList() {
List<VcsEntity> entities = WorkContext.getCurrent().get(VcsOperator.class).getEveryVersion();
List<VcsTableEntity> tableEntities = new ArrayList<>();
for (VcsEntity entity : entities) {
tableEntities.add(new VcsTableEntity(entity));
}
return tableEntities;
}
@Override
protected String title4PopupWindow() {
return TITLE;
}
private String getTemplateTruePath(String filename) {
return StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, filename);
}
@Override
protected String getDeleteTip(int size) {
return Toolkit.i18nText("Fine-Design_Vcs_Delete_Select_All_Version");
}
@Override
protected boolean isNeedTopPane() {
return true;
}
@Override
protected boolean isNeedRestore() {
return false;
}
}

434
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java

@ -0,0 +1,434 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.iprogressbar.ModernUIProgressBarUI;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.FRFont;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.vcs.v2.move.VcsMoveService;
import com.fr.workspace.server.vcs.v2.move.VcsMoveStrategy;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 迁移面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/6/13
*/
public class VcsMovePanel extends BasicPane {
private static final FRFont FONT = DesignUtils
.getDefaultGUIFont()
.applySize(14)
.applyStyle(FRFont.BOLD);
private static final Color BACK_GROUND_COLOR = new Color(202,232,255);
//提示字体的颜色,直接模仿其他面板的写法
private static final Color TIP_COLOR = new Color(51, 51, 52, (int)Math.round(0.5 * 255));
private static final Color LABEL_COLOR = new Color(34,149,233);
private static final int MIN_VALUE = 1;
private static final int MAX_VALUE = 999;
private static final int STEP = 1;
private static final int DEFAULT_VALUE = 5;
public static final String SETTING = "SETTING";
public static final String PROCESS = "PROCESS";
public static final String SUCCESS = "SUCCESS";
public static final String FAILED = "FAILED";
public static boolean moving = false;
private UILabel vcsUpdateExistLabel = new UILabel();
private UILabel vcsUpdateFireLabel = new UILabel();
private UIButton centerButton;
private BasicPane choosePane;
private CardLayout parentCard;
private JPanel parentPane;
private static final JProgressBar PROGRESS_BAR = new JProgressBar();
private JPanel progressPanel;
private UILabel tipLabel;
private UIButton successButton;
private UILabel iconLabel;
private UILabel successLabel;
private UILabel successTipLabel;
private UIButton failedButton;
private UILabel failedIconLabel;
private UILabel failedLabel;
private UILabel failedTipLabel;
//保留全部
private UIRadioButton moveAllButton;
//默认选项,保留部分
private UIRadioButton moveDefaultButton;
//全部放弃
private UIRadioButton moveNothingButton;
private UISpinner spinner;
private MoveCallBack callBack;
private JPanel updatePane;
private boolean visible = false;
public VcsMovePanel(CardLayout cardLayout, JPanel parentPane, MoveCallBack callBack) {
this.parentCard = cardLayout;
this.parentPane = parentPane;
this.callBack = callBack;
this.setLayout(new BorderLayout());
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));
//初始化顶部的面板
initVcsLabel(updatePane);
//initVcsChoosePane
initVcsChoosePane();
//初始化listener
initListener();
this.add(updatePane);
checkVisible();
//如果已经在迁移
if (VcsMoveService.getInstance().isMoving()) {
initProcessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), PROCESS);
}
}
private void checkVisible() {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return VcsHelper.getInstance().checkMoveFunctionSupport();
}
@Override
protected void done() {
try {
boolean useMove = get();
VcsMovePanel.this.setVisible(useMove);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
private void initProcessPane() {
JPanel processPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
PROGRESS_BAR.setStringPainted(true);
PROGRESS_BAR.setUI(new ModernUIProgressBarUI());
PROGRESS_BAR.setBorderPainted(false);
PROGRESS_BAR.setOpaque(false);
PROGRESS_BAR.setBorder(null);
PROGRESS_BAR.setSize(BasicDialog.MEDIUM);
body.add(PROGRESS_BAR);
body.add(new UILabel(StringUtils.BLANK));
tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_While_Moving"));
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
body.add(tipLabel);
processPane.add(body);
processPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
parentPane.add(processPane, PROCESS);
}
private void initVcsChoosePane() {
choosePane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Vcs_Deal_With_Entry");
}
};
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP);
layout.setAlignLeft(true);
choosePane.setLayout(layout);
//初始化上方的文字板块
initTopDesc();
//初始化中间区域的单选框
initRadioButton();
//初始化下方的Tip描述
initTipDesc();
}
private void initTopDesc() {
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_How_To_Deal_With_Entry"));
choosePane.add(label);
}
private void initTipDesc() {
UILabel descLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Desc"));
descLabel.setForeground(TIP_COLOR);
choosePane.add(descLabel);
}
private void initRadioButton() {
//保留全部
moveAllButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_All"));
//默认选项,保留部分
moveDefaultButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Default"));
//全部放弃
moveNothingButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Nothing"));
// 将按钮"保留部分"设置为选中状态
moveDefaultButton.setSelected(true);
// 创建一个按钮组,添加三个按钮
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(moveAllButton);
buttonGroup.add(moveDefaultButton);
buttonGroup.add(moveNothingButton);
JPanel moveDefaultPanel = new JPanel();
JPanel moveAllPane = new JPanel();
JPanel moveNothingPane = new JPanel();
moveAllPane.add(moveAllButton);
moveDefaultPanel.add(moveDefaultButton);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Left")));
spinner = new UISpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
moveDefaultPanel.add(spinner);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Right")));
moveNothingPane.add(moveNothingButton);
choosePane.add(moveAllPane);
choosePane.add(moveDefaultPanel);
choosePane.add(moveNothingPane);
}
private void initVcsLabel(JPanel parent) {
if (!VcsHelper.getInstance().isLegacyMode()) {
centerButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center"));
parent.add(centerButton);
initVcsCenterListener();
} else {
parent.setBackground(BACK_GROUND_COLOR);
vcsUpdateExistLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/vcs_move_icon.svg"));
vcsUpdateExistLabel.setText(Toolkit.i18nText("Fine-Design_Vcs_Can_Update"));
vcsUpdateFireLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Update"));
vcsUpdateFireLabel.setForeground(LABEL_COLOR);
vcsUpdateFireLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
parent.add(vcsUpdateExistLabel);
parent.add(vcsUpdateFireLabel);
}
}
private void initVcsCenterListener() {
centerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
VcsCenterPane vcsCenterPane = new VcsCenterPane();
BasicDialog dialog = vcsCenterPane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
});
}
private void initListener() {
vcsUpdateFireLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
BasicDialog dlg = choosePane.showMediumWindow(SwingUtilities.getWindowAncestor(VcsMovePanel.this), new DialogActionAdapter() {
@Override
public void doOk() {
//进度条面板
initProcessPane();
VcsMovePanel.this.getParentCard().next(getParentPane());
VcsMoveStrategy strategy;
if (moveDefaultButton.isSelected()) {
strategy = VcsMoveStrategy.createNumStrategy((int) spinner.getValue());
} else if (moveNothingButton.isSelected()) {
strategy = VcsMoveStrategy.ALL_GIVE_UP;
} else {
strategy = VcsMoveStrategy.ALL_RETAIN;
}
new MoveWorker(strategy).execute();
}
});
dlg.setVisible(true);
}
});
}
private void initSuccessPane() {
JPanel successPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
successButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Success_Go"));
initSuccessButtonListener();
iconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_success.svg"));
successLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Success"));
successLabel.setFont(FONT);
successTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Success_Tip"));
initStatusPane(successTipLabel, iconLabel, successLabel, successButton, body, SUCCESS, successPane);
}
private void initSuccessButtonListener() {
successButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAfterMove();
}
});
}
private void initFailedButtonListener() {
failedButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAfterMove();
}
});
}
private void doAfterMove() {
visible = !VcsHelper.getInstance().isLegacyMode();
if (visible) {
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.add(new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center")));
}
updatePane.setVisible(!visible);
callBack.doCallBack(visible);
parentCard.show(parentPane, SETTING);
}
@Override
protected String title4PopupWindow() {
return StringUtils.EMPTY;
}
public CardLayout getParentCard() {
return parentCard;
}
public JPanel getParentPane() {
return parentPane;
}
private void initFailedPane() {
JPanel failedPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
failedButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Go"));
initFailedButtonListener();
failedIconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_failed.svg"));
failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed"));
failedLabel.setFont(FONT);
failedTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Tip"));
initStatusPane(failedTipLabel, failedIconLabel, failedLabel, failedButton, body, FAILED, failedPane);
}
private void initStatusPane(UILabel tipLabel, UILabel iconLabel, UILabel label, UIButton button, JPanel body, String tag,JPanel statusPane) {
tipLabel.setForeground(TIP_COLOR);
body.add(iconLabel);
body.add(new UILabel(StringUtils.BLANK));
body.add(label);
body.add(new UILabel(StringUtils.BLANK));
body.add(tipLabel);
body.add(new UILabel(StringUtils.BLANK));
body.add(button);
statusPane.add(body);
statusPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
parentPane.add(statusPane, tag);
iconLabel.setAlignmentX(CENTER_ALIGNMENT);
label.setAlignmentX(CENTER_ALIGNMENT);
button.setAlignmentX(CENTER_ALIGNMENT);
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
}
private class MoveWorker extends SwingWorker<Void, Integer> {
private VcsMoveStrategy strategy;
public MoveWorker(VcsMoveStrategy strategy) {
this.strategy = strategy;
}
@Override
protected Void doInBackground() throws Exception {
try {
//开始迁移
VcsMoveService.getInstance().startMove(new VcsMoveService.BaseMoveServiceWhileMoving() {
@Override
public void publishProgress() {
int num = VcsMoveService.getInstance().getCurrentMove();
publish(num);
}
@Override
public void prepare4Move() {
PROGRESS_BAR.setMaximum(VcsMoveService.getInstance().getTotal());
}
}, strategy);
} catch (Exception e) {
this.cancel(true);
VcsMoveService.getInstance().stopMoving();
initFailedPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), FAILED);
FineLoggerFactory.getLogger().error("[VcsV2] Vcs move failed!");
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
PROGRESS_BAR.setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
VcsMoveService.getInstance().stopMoving();
initSuccessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), SUCCESS);
VcsHelper.getInstance().updateLegacyMode();
}
}
/**
* 迁移回调事件
*
*/
public static class MoveCallBack {
/**
* 处理回调
*/
public void doCallBack(boolean visible){}
}
}

339
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java

@ -0,0 +1,339 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MultiTemplateTabPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.vcs.TableValueOperator;
import com.fr.design.mainframe.vcs.VcsService;
import com.fr.design.mainframe.vcs.VcsTableEntity;
import com.fr.design.mainframe.vcs.common.VcsCacheFileNodeFile;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 版本管理交互优化新面板
* <li>采用表格的形式展现</li>
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/11
*/
public class VcsNewPane extends RecyclePane {
private String filePath = StringUtils.EMPTY;
protected static int OPERATOR_COL = 5;
protected static int EDIT_COL = 4;
private static final int DOUBLE_CLICK_COUNT = 2;
protected VcsOperatorPane operatorPane;
private static final Icon PREVIEW_ICON = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_operator_preview");
private static final Icon DELETE_ICON = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_operator_delete");
private static final Icon RESTORE_ICON = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_operator_restore");
private UILabel restore;
private UILabel delete;
private UILabel preview;
private static final String TITLE = Toolkit.i18nText("Fine-Design_Vcs_Title");
private static final String[] COLUMN_NAMES = new String[]{
StringUtils.EMPTY,
Toolkit.i18nText("Fine-Design_Vcs_Version"),
Toolkit.i18nText("Fine-Design_Vcs_Time"),
Toolkit.i18nText("Fine-Design_Vcs_User"),
Toolkit.i18nText("Fine-Design_Vcs_Annotation"),
Toolkit.i18nText("Fine-Design_Vcs_Operator")
};
private static final Class[] CLASSES = new Class[]{
Boolean.class,
UILabel.class,
UILabel.class,
UILabel.class,
UILabel.class,
VcsOperatorPane.class
};
public VcsNewPane(String filePath) {
super(TITLE, (o, columnIndex) -> {
switch (columnIndex) {
case 0:
return o.isSelect();
case 1:
return o.getVersion();
case 2:
return o.getTime();
case 3:
return o.getUserName();
case 4:
return o.getCommitMsg();
default:
return o;
}
}, false);
this.filePath = filePath;
initModel(COLUMN_NAMES, CLASSES, OPERATOR_COL);
}
private void initModel(String[] columns, Class[] classes, int operatorCol) {
this.model = new DefaultModel(columns, classes) {
@Override
public boolean isCellEditable(int row, int col) {
return col == 0 || col == operatorCol;
}
};
this.operatorPane = createOperatorPane();
this.model.setDefaultEditor(VcsOperatorPane.class, operatorPane);
this.model.setDefaultRenderer(VcsOperatorPane.class, operatorPane);
}
public VcsNewPane(String title, TableValueOperator<VcsTableEntity> operators, boolean needBorder, String[] columns, Class[] classes, int operatorCol) {
super(title, operators, needBorder);
initModel(columns, classes, operatorCol);
}
/**
* 创建操作面板
*
* @return 操作面板
*/
public VcsOperatorPane createOperatorPane() {
restore = new UILabel(RESTORE_ICON);
delete = new UILabel(DELETE_ICON);
preview = new UILabel(PREVIEW_ICON);
initPreviewListener();
initDeleteListener();
initRestoreListener();
List<JComponent> list = new ArrayList<>();
list.add(restore);
list.add(delete);
list.add(preview);
return new VcsOperatorPane(list);
}
private void initRestoreListener() {
restore.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JTable table = tableContentPane.getEditTable();
Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn());
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
int selVal = FineJOptionPane.showConfirmDialog(
VcsNewPane.this,
Toolkit.i18nText("Fine-Design_Vcs_Restore_This_Version_Tips"),
Toolkit.i18nText("Fine-Design_Basic_Confirm"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
restoreEntity(entity);
}
}
}
});
}
private void restoreEntity(VcsEntity entity) {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
//step1.设置还原的用户名
entity.setUsername(VcsHelper.getInstance().getCurrentUsername());
//step2.rollback到指定版本
WorkContext.getCurrent().get(VcsOperator.class).rollbackTo(entity);
return null;
}
@Override
protected void done() {
//step3.如果原来原模板已经打开则关闭原模板,打开rollback后的新模板
List<JTemplate<?, ?>> templateList = HistoryTemplateListCache.getInstance().getHistoryList();
for (JTemplate<?, ?> template : templateList) {
if (StringUtils.equals(filePath, template.getPath())) {
MultiTemplateTabPane.getInstance().setIsCloseCurrent(HistoryTemplateListCache.getInstance().isCurrentEditingFile(filePath));
MultiTemplateTabPane.getInstance().closeFormat(template);
MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(template);
break;
}
}
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(filePath, false)));
}
}.execute();
}
private void initDeleteListener() {
delete.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JTable table = tableContentPane.getEditTable();
int row = table.getEditingColumn();
Object o = table.getValueAt(table.getEditingRow(), row);
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
int selVal = FineJOptionPane.showConfirmDialog(
VcsNewPane.this,
Toolkit.i18nText("Fine-Design_Vcs_Delete_This_Version_Tips"),
Toolkit.i18nText("Fine-Design_Basic_Confirm"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
model.getList().remove(o);
model.fireTableDataChanged();
VcsService.getInstance().deleteEntity(entity.getFilename(), entity.getVersion());
}
}
}
});
}
private void initPreviewListener() {
preview.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
JTable table = tableContentPane.getEditTable();
Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn());
if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity();
previewEntity(entity);
}
}
});
}
private void previewEntity(VcsEntity entity) {
new SwingWorker<String, Void>() {
@Override
protected String doInBackground() throws Exception {
//step1.将指定版本的历史文件读取出来,加上前缀放到cache中
VcsOperator vcsOperator = WorkContext.getCurrent().get(VcsOperator.class);
String fileOfVersion = vcsOperator.getFileOfFileVersion(
entity.getFilename(),
entity.getVersion(),
Toolkit.i18nText("Fine-Design_Vcs_Prefix", entity.getVersion()));
return fileOfVersion;
}
@Override
protected void done() {
try {
//step2.再打开cache中的模板
DesignerContext.getDesignerFrame().openTemplate(new VcsCacheFileNodeFile(new FileNode(get(), false)));
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
@Override
protected boolean isNeedDeleteAllVersion() {
return false;
}
@Override
protected List<VcsTableEntity> getTableList() {
List<VcsEntity> entityList = WorkContext.getCurrent().get(VcsOperator.class).getVersions(VcsHelper.getInstance().dealWithFilePath(filePath));
List<VcsTableEntity> tableEntities = new ArrayList<>();
for (VcsEntity entity : entityList) {
tableEntities.add(new VcsTableEntity(entity));
}
return tableEntities;
}
@Override
protected String title4PopupWindow() {
return TITLE;
}
@Override
protected String getDeleteTip(int size) {
return Toolkit.i18nText("Fine-Design_Vcs_Delete_Versions_Tips", size);
}
@Override
protected boolean isNeedRestore() {
return false;
}
@Override
protected boolean isNeedSearch() {
return false;
}
@Override
protected void initExtraListener4Table(JTable table) {
table.addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
Point point = e.getPoint();
int row = table.rowAtPoint(point);
int col = table.columnAtPoint(point);
if (col != 0) {
table.editCellAt(row, col);
}
}
});
initEditListener(table);
}
private void initEditListener(JTable table) {
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == DOUBLE_CLICK_COUNT) {
Point point = e.getPoint();
int row = table.rowAtPoint(point);
int col = table.columnAtPoint(point);
if (col == EDIT_COL) {
Object o = table.getValueAt(row, OPERATOR_COL);
if (o instanceof VcsTableEntity) {
showDialog(((VcsTableEntity) o).getEntity());
}
}
}
}
});
}
private void showDialog(VcsEntity entity) {
EditFileVersionDialog dialog = new EditFileVersionDialog(entity) {
@Override
public void doOK() {
entity.setCommitMsg(getMsgTestArea().getText());
VcsService.getInstance().updateEntityAnnotation(entity);
setVisible(false);
model.fireTableDataChanged();
}
};
dialog.setVisible(true);
}
}

63
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsOperatorPane.java

@ -0,0 +1,63 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.AbstractCellEditor;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.util.List;
import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFAULT_SELECT_TABLE_ROW_COLOR;
/**
* 操作面板用于置放常用的操作label
* <p>例如 删除还原预览打开模板等</p>
* <li>负责表格渲染 操作按钮置蓝+设定cursor</li>
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/13
*/
public class VcsOperatorPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
private JPanel contentPane;
private static final Color DETAIL_FONT_COLOR = new Color(65, 155, 249);
public VcsOperatorPane(List<JComponent> iconJComponentMap) {
init(iconJComponentMap);
}
private void init(List<JComponent> iconJComponentMap) {
contentPane = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
for (JComponent value : iconJComponentMap) {
value.setForeground(DETAIL_FONT_COLOR);
value.setCursor(new Cursor(Cursor.HAND_CURSOR));
contentPane.add(value);
}
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
return contentPane;
}
@Override
public Object getCellEditorValue() {
return contentPane;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
contentPane.setBackground(isSelected ? DEFAULT_SELECT_TABLE_ROW_COLOR : Color.WHITE);
return contentPane;
}
}

4
designer-base/src/main/resources/com/fr/design/images/buttonicon/new_other_normal.svg

@ -0,0 +1,4 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0.5 15.6727V0.672668H11.2731L14.5 4.36054V15.6727H0.5Z" stroke="#333334"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 5.17267H6V7.17267H4V5.17267ZM3 4.17267H4H6H7V5.17267V7.17267V8.17267H6H4H3V7.17267V5.17267V4.17267ZM4 10.1727H6V12.1727H4V10.1727ZM3 9.17267H4H6H7V10.1727V12.1727V13.1727H6H4H3V12.1727V10.1727V9.17267ZM9 6.17267C9 6.72495 9.44772 7.17267 10 7.17267C10.5523 7.17267 11 6.72495 11 6.17267C11 5.62038 10.5523 5.17267 10 5.17267C9.44772 5.17267 9 5.62038 9 6.17267ZM10 4.17267C8.89543 4.17267 8 5.0681 8 6.17267C8 7.27724 8.89543 8.17267 10 8.17267C11.1046 8.17267 12 7.27724 12 6.17267C12 5.0681 11.1046 4.17267 10 4.17267ZM9 12.1727V10.1727H11V12.1727H9ZM8 9.17267H9H11H12V10.1727V12.1727V13.1727H11H9H8V12.1727V10.1727V9.17267Z" fill="#333334"/>
</svg>

After

Width:  |  Height:  |  Size: 885 B

5
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_center_manager_normal.svg

@ -0,0 +1,5 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#231;&#137;&#136;&#230;&#156;&#172;&#231;&#174;&#161;&#231;&#144;&#134;">
<path id="Union" fill-rule="evenodd" clip-rule="evenodd" d="M2 2.5H14V14.5H2V2.5ZM1 15.5V1.5H15V15.5H1ZM5.75 4.5H4.25L7.25 10.5H8.75L11.75 4.5H10.25L8 9L5.75 4.5ZM12 11.5V12.5H4V11.5H12Z" fill="#333334"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 400 B

5
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_center_open_normal.svg

@ -0,0 +1,5 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="&#230;&#137;&#147;&#229;&#188;&#128;&#230;&#168;&#161;&#230;&#157;&#191;">
<path id="Union" fill-rule="evenodd" clip-rule="evenodd" d="M8.55349 5.73077L8.25543 5.39831L6.55349 3.5H2V11.2333L2.875 7.5H9.90625H13V5.73077H9H8.55349ZM14 7.5H14.9729H16L15.7656 8.5L14.125 15.5H2.0271H1V14.5V3.5V2.5H2H7L9 4.73077H13H14V5.73077V7.5ZM2.26147 14.5L3.66772 8.5H9.90625H14.7385L13.3323 14.5H2.26147Z" fill="#333334"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 523 B

7
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_delete_normal.svg

@ -0,0 +1,7 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#229;&#136;&#160;&#233;&#153;&#164;">
<g id="icon/delete">
<path id="Combined-Shape" d="M11 1.5V3.5H15V4.5H13V15.5H3V4.5H1V3.5H5V1.5H11ZM12 4.5H4V14.5H12V4.5ZM7 6.5V12.5H6V6.5H7ZM10 6.5V12.5H9V6.5H10ZM10 2.5H6V3.5H10V2.5Z" fill="#333334"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 366 B

5
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_preview_normal.svg

@ -0,0 +1,5 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#233;&#162;&#132;&#232;&#167;&#136;">
<path id="Combined Shape" fill-rule="evenodd" clip-rule="evenodd" d="M3 14.5H7V15.5H2V1.5H9H10L14 5.5V8.5H13V6.5H10H9V5.5V2.5H3V14.5ZM10 2.914V5.5H12.586L10 2.914ZM9.5 7.5C11.4329 7.5 13 9.06712 13 11C13 11.6067 12.8456 12.1774 12.5739 12.6749C12.6206 12.7078 12.6651 12.7452 12.7069 12.787L13.7129 13.793C14.1039 14.184 14.1039 14.816 13.7129 15.207C13.5179 15.402 13.2619 15.5 13.0059 15.5C12.7499 15.5 12.4939 15.402 12.2989 15.207L11.2929 14.201C11.2516 14.1599 11.2147 14.116 11.1821 14.07C10.6829 14.3441 10.1097 14.5 9.5 14.5C7.56712 14.5 6 12.9329 6 11C6 9.06712 7.56712 7.5 9.5 7.5ZM7 11.0006C7 9.62232 8.12167 8.50065 9.5 8.50065C10.8783 8.50065 12 9.62232 12 11.0006C12 12.379 10.8783 13.5006 9.5 13.5006C8.12167 13.5006 7 12.379 7 11.0006Z" fill="#333334"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 929 B

5
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_restore_normal.svg

@ -0,0 +1,5 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#229;&#136;&#183;&#230;&#150;&#176;">
<path id="Union" fill-rule="evenodd" clip-rule="evenodd" d="M13.924 2.15774C13.924 1.82637 13.6553 1.55774 13.324 1.55774C12.9926 1.55774 12.724 1.82637 12.724 2.15774V4.59914C11.6284 3.54744 10.1397 2.90004 8.50002 2.90004C5.13109 2.90004 2.40002 5.6311 2.40002 9.00004C2.40002 12.369 5.13109 15.1 8.50002 15.1C11.1941 15.1 13.4787 13.354 14.2871 10.9335C14.3921 10.6191 14.2223 10.2793 13.908 10.1743C13.5937 10.0693 13.2538 10.239 13.1489 10.5533C12.4991 12.4989 10.6624 13.9 8.50002 13.9C5.79383 13.9 3.60002 11.7062 3.60002 9.00004C3.60002 6.29384 5.79383 4.10004 8.50002 4.10004C9.8643 4.10004 11.0983 4.65709 11.9873 5.55774H9.32397C8.9926 5.55774 8.72397 5.82637 8.72397 6.15774C8.72397 6.48911 8.9926 6.75774 9.32397 6.75774H13.324C13.6553 6.75774 13.924 6.48911 13.924 6.15774V2.15774Z" fill="#333334"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 973 B

7
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_delete_disabled.svg

@ -0,0 +1,7 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#229;&#136;&#160;&#233;&#153;&#164;" opacity="0.3">
<g id="icon/delete">
<path id="Combined-Shape" d="M11 1V3H15V4H13V15H3V4H1V3H5V1H11ZM12 4H4V14H12V4ZM7 6V12H6V6H7ZM10 6V12H9V6H10ZM10 2H6V3H10V2Z" fill="#333334"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 342 B

7
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_delete_normal.svg

@ -0,0 +1,7 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="&#231;&#138;&#182;&#230;&#128;&#129;=&#230;&#173;&#163;&#229;&#184;&#184;">
<g id="icon/delete">
<path id="Combined-Shape" d="M11 1V3H15V4H13V15H3V4H1V3H5V1H11ZM12 4H4V14H12V4ZM7 6V12H6V6H7ZM10 6V12H9V6H10ZM10 2H6V3H10V2Z" fill="#333334"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 360 B

8
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_normal.svg

@ -0,0 +1,8 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#229;&#155;&#158;&#230;&#148;&#182;&#231;&#171;&#153;">
<g id="icon/delete">
<path id="Combined-Shape" d="M11 1V3H15V4H13V15H3V4H1V3H5V1H11ZM12 4H4V14H12V4ZM10 2H6V3H10V2Z" fill="#333334"/>
</g>
<path id="Subtract" fill-rule="evenodd" clip-rule="evenodd" d="M9.4255 7.5425L8.5 6H7.5L5.93265 8.61225L6.79415 8.84308L8 6.83333L8.8005 8.1675L9.4255 7.5425ZM9.95583 8.42638L9.33083 9.05138L10.5 11H8.86391L9.09598 11.8661L11 11.8661L11.5 11L9.95583 8.42638ZM8.06071 11.8661L7.82864 11H5.5L6.25902 9.73497L5.39752 9.50413L4.5 11L5 11.8672L5.00064 11.8661L8.06071 11.8661Z" fill="#333334"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 706 B

5
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_restore_disabled.svg

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#232;&#191;&#152;&#229;&#142;&#159;" opacity="0.3">
<path id="Union" d="M2.39418 1.6C2.39418 1.26863 2.66281 1 2.99418 1C3.32555 1 3.59418 1.26863 3.59418 1.6V4.0414C4.68979 2.9897 6.17846 2.3423 7.81813 2.3423C11.1871 2.3423 13.9181 5.07336 13.9181 8.4423C13.9181 11.8112 11.1871 14.5423 7.81813 14.5423C5.12408 14.5423 2.83941 12.7962 2.03106 10.3757C1.92609 10.0614 2.0958 9.72152 2.41011 9.61655C2.72441 9.51159 3.0643 9.68129 3.16927 9.9956C3.81901 11.9412 5.65572 13.3423 7.81813 13.3423C10.5243 13.3423 12.7181 11.1485 12.7181 8.4423C12.7181 5.7361 10.5243 3.5423 7.81813 3.5423C6.45385 3.5423 5.2199 4.09935 4.33089 5H6.99418C7.32555 5 7.59418 5.26863 7.59418 5.6C7.59418 5.93137 7.32555 6.2 6.99418 6.2H2.99418C2.66281 6.2 2.39418 5.93137 2.39418 5.6V1.6Z" fill="#333334"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 904 B

5
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_restore_normal.svg

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="icon &#232;&#191;&#152;&#229;&#142;&#159;">
<path id="Union" d="M2.39418 1.6C2.39418 1.26863 2.66281 1 2.99418 1C3.32555 1 3.59418 1.26863 3.59418 1.6V4.0414C4.68979 2.9897 6.17846 2.3423 7.81813 2.3423C11.1871 2.3423 13.9181 5.07336 13.9181 8.4423C13.9181 11.8112 11.1871 14.5423 7.81813 14.5423C5.12408 14.5423 2.83941 12.7962 2.03106 10.3757C1.92609 10.0614 2.0958 9.72152 2.41011 9.61655C2.72441 9.51159 3.0643 9.68129 3.16927 9.9956C3.81901 11.9412 5.65572 13.3423 7.81813 13.3423C10.5243 13.3423 12.7181 11.1485 12.7181 8.4423C12.7181 5.7361 10.5243 3.5423 7.81813 3.5423C6.45385 3.5423 5.2199 4.09935 4.33089 5H6.99418C7.32555 5 7.59418 5.26863 7.59418 5.6C7.59418 5.93137 7.32555 6.2 6.99418 6.2H2.99418C2.66281 6.2 2.39418 5.93137 2.39418 5.6V1.6Z" fill="#333334"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 890 B

3
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_search_normal.svg

@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="Combined Shape" fill-rule="evenodd" clip-rule="evenodd" d="M5.5 11C2.46243 11 0 8.53757 0 5.5C0 2.46243 2.46243 0 5.5 0C8.53757 0 11 2.46243 11 5.5C11 6.75785 10.5778 7.91707 9.86726 8.84367L13.7881 12.7645C14.0707 13.0471 14.0707 13.5054 13.7881 13.7881C13.5054 14.0707 13.0471 14.0707 12.7645 13.7881L8.84367 9.86726C7.91707 10.5778 6.75785 11 5.5 11ZM10 5.5C10 7.98528 7.98528 10 5.5 10C3.01472 10 1 7.98528 1 5.5C1 3.01472 3.01472 1 5.5 1C7.98528 1 10 3.01472 10 5.5Z" fill="#333334"/>
</svg>

After

Width:  |  Height:  |  Size: 603 B

5
designer-base/src/main/resources/com/fr/design/vcs/move_failed.svg

@ -0,0 +1,5 @@
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M32 60.5C16.536 60.5 4 47.964 4 32.5C4 17.036 16.536 4.5 32 4.5C47.464 4.5 60 17.036 60 32.5C60 47.964 47.464 60.5 32 60.5Z" fill="#EB1D1F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M44 24.1928L23.692 44.4995L20 40.8075L40.308 20.4995L44 24.1928Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.308 44.5L20 24.1933L23.692 20.5L44 40.8067L40.308 44.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 549 B

5
designer-base/src/main/resources/com/fr/design/vcs/move_success.svg

@ -0,0 +1,5 @@
<svg width="58" height="59" viewBox="0 0 58 59" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M29 58.5C12.9837 58.5 0 45.5163 0 29.5C0 13.4837 12.9837 0.5 29 0.5C45.0163 0.5 58 13.4837 58 29.5C58 45.5163 45.0163 58.5 29 58.5Z" fill="#16C153"/>
<rect x="20.66" y="39.8213" width="32.1738" height="5.52381" transform="rotate(-45 20.66 39.8213)" fill="white"/>
<rect x="14.9535" y="26.7378" width="18.7954" height="5.52381" transform="rotate(45 14.9535 26.7378)" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 533 B

3
designer-base/src/main/resources/com/fr/design/vcs/vcs_move_icon.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 8C15 4.13435 11.8656 1 8 1C4.13435 1 1 4.13435 1 8C1 11.8656 4.13435 15 8 15C11.8656 15 15 11.8656 15 8ZM7.43333 5.70798C7.27778 5.55242 7.2 5.36353 7.2 5.14131C7.2 4.91909 7.27778 4.7302 7.43333 4.57464C7.58889 4.41909 7.77778 4.34131 8 4.34131C8.22222 4.34131 8.41111 4.41909 8.56667 4.57464C8.72222 4.7302 8.8 4.91909 8.8 5.14131C8.8 5.36353 8.72222 5.55242 8.56667 5.70798C8.41111 5.86353 8.22222 5.94131 8 5.94131C7.77778 5.94131 7.58889 5.86353 7.43333 5.70798ZM8 11.7787C7.6134 11.7787 7.3 11.4653 7.3 11.0787V7.47868C7.3 7.09208 7.6134 6.77868 8 6.77868C8.3866 6.77868 8.7 7.09208 8.7 7.47868V11.0787C8.7 11.4653 8.3866 11.7787 8 11.7787Z" fill="#419BF9"/>
</svg>

After

Width:  |  Height:  |  Size: 821 B

8
designer-form/src/main/java/com/fr/design/actions/NewFormAction.java

@ -6,16 +6,12 @@ import com.fr.design.widget.ui.designer.NewFormPane;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER;
public class NewFormAction extends UpdateAction {
public NewFormAction() {
this.setMenuKeySet(NEW_FORM);
this.setName(getMenuKeySet().getMenuKeySetName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setName(getMenuKeySet().getMenuName());
this.setSmallIcon("/com/fr/design/images/buttonicon/new_form3");
this.setAccelerator(getMenuKeySet().getKeyStroke());
}
@ -33,7 +29,7 @@ public class NewFormAction extends UpdateAction {
public static final MenuKeySet NEW_FORM = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'F';
return 0;
}
@Override

8
designer-realize/src/main/java/com/fr/start/MainDesigner.java

@ -213,14 +213,18 @@ public class MainDesigner extends BaseDesigner {
ArrayList<ShortCut> shortCuts = new ArrayList<ShortCut>();
// shortCuts.add(new NewWorkBookXAction());
shortCuts.add(new NewWorkBookAction());
// 决策报表、聚合报表归入其他
MenuDef newOtherFileMenuDef = new MenuDef(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_M_New_Other_Template"));
newOtherFileMenuDef.setIconPath("/com/fr/design/images/buttonicon/new_other");
try {
if (DesignModuleFactory.getNewFormAction() != null) {
shortCuts.add((ShortCut) DesignModuleFactory.getNewFormAction().newInstance());
newOtherFileMenuDef.addShortCut((ShortCut) DesignModuleFactory.getNewFormAction().newInstance());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
shortCuts.add(new NewPolyReportAction());
newOtherFileMenuDef.addShortCut(new NewPolyReportAction());
shortCuts.add(newOtherFileMenuDef);
return shortCuts.toArray(new ShortCut[0]);
}

BIN
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 802 KiB

BIN
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

BIN
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

BIN
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_fvs4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

160
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/template_resource/local_templates.json

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save