Browse Source

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

* commit '35143aad51b2a7534febcec445255560a87d122b': (68 commits)
  REPORT-98345 版本管理三期 迁移成功后,没刷新工具栏
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭 修改方法名
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭 修改方法名
  REPORT-100458 【版本管理二期】迁移弹窗,保留版本的输入框没有非法值校验
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭
  REPORT-100958 【版本管理三期】还原或者预览版本,弹窗应该关闭
  REPORT-91839 模板版本管理二期 没设置启动页,启动的时候判断有点问题
  REPORT-100518 【版本管理二期】无磁盘写入权限,版本迁移无异常提示
  REPORT-101340 【版本管理二期】自动清理配置灰化时,hover提示没有
  REPORT-101060 【版本管理三期】删除无权限的版本,能删除成功
  REPORT-101166 【版本管理三期】集群环境,版本管理页面所有配置项都不可点
  REPORT-100954 【版本管理三期】版本中心弹窗交互问题
  REPORT-91839 模板版本管理二期 偶遇报错,不确定场景,加一下处理
  REPORT-101167 【版本管理一期】集群环境,保存版本不生效
  REPORT-100162 【版本管理二期】模板不在编辑状态,还是在触发自动保存
  REPORT-100633 【版本管理二期】取消勾选备注的版本不会被清理,备注的版本还是不会被清理
  REPORT-101289 【版本管理二期】数据迁移的提示弹窗位置没有居中
  REPORT-101293 【版本管理二期】模板未打开,点击版本管理点不开
  fix: 只有选择关闭当前分类其它模板时才做类型比较 #REPORT-99959
  fix: 关闭当前类型模板时,不判断其它类型模板是否保存 #REPORT-99959
  ...
feature/x
superman 1 year ago
parent
commit
6cf65843c6
  1. 120
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  2. 6
      designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java
  3. 20
      designer-base/src/main/java/com/fr/design/dialog/BasicPane.java
  4. 10
      designer-base/src/main/java/com/fr/design/editor/editor/NumberEditor.java
  5. 2
      designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java
  6. 19
      designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java
  7. 13
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  8. 15
      designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableModelAdapter.java
  9. 7
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  10. 71
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  11. 6
      designer-base/src/main/java/com/fr/design/mainframe/vcs/RecycleAction.java
  12. 37
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsExceptionUtils.java
  13. 291
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java
  14. 49
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsRecycleSettingHelper.java
  15. 162
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsService.java
  16. 9
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableEntity.java
  17. 31
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java
  18. 41
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/AbstractSupportSelectTablePane.java
  19. 120
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java
  20. 103
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecycleSettingPane.java
  21. 32
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/ToolTipTableCellRenderer.java
  22. 59
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntEditor.java
  23. 39
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntSpinner.java
  24. 156
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsBatchProcessDetailPane.java
  25. 35
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellEditor.java
  26. 29
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellRender.java
  27. 43
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java
  28. 111
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java
  29. 54
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovingExitOption.java
  30. 21
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java
  31. 37
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsOperatorPane.java
  32. 81
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsProgressDialog.java
  33. 4
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_sort_normal.svg
  34. 27
      designer-form/src/main/java/com/fr/design/designer/creator/XEditorHolder.java
  35. 23
      designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java
  36. 2
      designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java

120
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.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.VcsConfigManager; import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.UIPositiveIntEditor;
import com.fr.design.mainframe.vcs.ui.VcsMovePanel; import com.fr.design.mainframe.vcs.ui.VcsMovePanel;
import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.unit.UnitConvertUtil; import com.fr.design.unit.UnitConvertUtil;
@ -50,9 +51,12 @@ import com.fr.io.attr.ImageExportAttr;
import com.fr.locale.InterProviderFactory; import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.report.ReportConfigManager; import com.fr.report.ReportConfigManager;
import com.fr.scheduler.tool.FineScheduler;
import com.fr.stable.Constants; import com.fr.stable.Constants;
import com.fr.stable.os.OperatingSystem; import com.fr.stable.os.OperatingSystem;
import com.fr.third.apache.logging.log4j.Level; import com.fr.third.apache.logging.log4j.Level;
import com.fr.third.guava.collect.BiMap;
import com.fr.third.guava.collect.HashBiMap;
import com.fr.transaction.Configurations; import com.fr.transaction.Configurations;
import com.fr.transaction.Worker; import com.fr.transaction.Worker;
import com.fr.transaction.WorkerAdaptor; import com.fr.transaction.WorkerAdaptor;
@ -61,6 +65,8 @@ import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.VcsOperator; import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.git.config.GcConfig; import com.fr.workspace.server.vcs.git.config.GcConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator; import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanSchedule;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanService;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
@ -92,6 +98,7 @@ import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.io.File; import java.io.File;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
@ -173,6 +180,8 @@ public class PreferencePane extends BasicPane {
private static final int DEFAULT_INDEX = 3; private static final int DEFAULT_INDEX = 3;
private BasicDialog basicDialog;
private boolean languageChanged; // 是否修改了设计器语言设置 private boolean languageChanged; // 是否修改了设计器语言设置
//设置是否支持undo //设置是否支持undo
private UICheckBox supportUndoCheckBox; private UICheckBox supportUndoCheckBox;
@ -217,15 +226,17 @@ public class PreferencePane extends BasicPane {
private UIComboBox autoCleanIntervalComboBox; private UIComboBox autoCleanIntervalComboBox;
private UIComboBox autoCleanRetainIntervalComboBox; private UIComboBox autoCleanRetainIntervalComboBox;
private IntegerEditor autoSaveIntervalEditor; private UIPositiveIntEditor autoSaveIntervalEditor;
private UICheckBox saveCommitCheckBox; private UICheckBox saveCommitCheckBox;
private UICheckBox useIntervalCheckBox; private UICheckBox useIntervalCheckBox;
private VcsMovePanel movePanel; private VcsMovePanel movePanel;
private JPanel saveIntervalPane; private JPanel saveIntervalPane;
private JPanel autoCleanPane; private JPanel autoCleanPane;
private JPanel gcControlPane;
private UICheckBox startupPageEnabledCheckBox; private UICheckBox startupPageEnabledCheckBox;
private IntegerEditor saveIntervalEditor; private UIPositiveIntEditor saveIntervalEditor;
private UICheckBox gcEnableCheckBox; private UICheckBox gcEnableCheckBox;
private UIButton gcButton; private UIButton gcButton;
private UILabel remindVcsLabel; private UILabel remindVcsLabel;
@ -245,7 +256,15 @@ public class PreferencePane extends BasicPane {
private UIRadioButton previewRenderQuality; private UIRadioButton previewRenderQuality;
private static final int DPI_SCALE_S = 1; private static final int DPI_SCALE_S = 1;
private static final int DPI_SCALE_M = 2; private static final int DPI_SCALE_M = 2;
private static final BiMap<Integer, Integer> INDEX_DAY_MAP = HashBiMap.create(new HashMap<Integer, Integer>() {
{
put(ONE_DAY_INDEX, ONE_DAY_INT);
put(ONE_WEEK_INDEX, ONE_WEEK_INT);
put(ONE_MONTH_INDEX, ONE_MONTH_INT);
put(SIX_MONTH_INDEX, SIX_MONTH_INT);
put(THREE_MONTH_INDEX, THREE_MONTH_INT);
}
});
public PreferencePane() { public PreferencePane() {
this.initComponents(); this.initComponents();
} }
@ -412,13 +431,13 @@ public class PreferencePane extends BasicPane {
saveIntervalPane = createSaveIntervalPane(); saveIntervalPane = createSaveIntervalPane();
saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete")); saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete"));
saveIntervalEditor = new IntegerEditor(60); saveIntervalEditor = new UIPositiveIntEditor(60);
useIntervalCheckBox = new UICheckBox(); useIntervalCheckBox = new UICheckBox();
savePane.add(vcsEnableCheckBox); savePane.add(vcsEnableCheckBox);
savePane.add(saveIntervalPane); savePane.add(saveIntervalPane);
//gc面板 //gc面板
JPanel gcControlPane = createGcControlPane(); gcControlPane = createGcControlPane();
JPanel enableVcsPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout()); JPanel enableVcsPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
enableVcsPanel.add(remindVcsLabel); enableVcsPanel.add(remindVcsLabel);
@ -430,6 +449,7 @@ public class PreferencePane extends BasicPane {
intervalPanel.add(saveIntervalEditor); intervalPanel.add(saveIntervalEditor);
intervalPanel.add(delayLabel); intervalPanel.add(delayLabel);
autoCleanPane = createAutoCleanPane(); autoCleanPane = createAutoCleanPane();
checkAutoScheduleStartAndUpdateStatus();
vcsEnableCheckBox.addChangeListener(new ChangeListener() { vcsEnableCheckBox.addChangeListener(new ChangeListener() {
@Override @Override
public void stateChanged(ChangeEvent e) { public void stateChanged(ChangeEvent e) {
@ -451,10 +471,13 @@ public class PreferencePane extends BasicPane {
}); });
vcsPane.add(enableVcsPanel); vcsPane.add(enableVcsPanel);
vcsPane.add(intervalPanel); vcsPane.add(intervalPanel);
if (VcsHelper.getInstance().isLegacyMode()) {
vcsPane.add(saveCommitCheckBox); vcsPane.add(saveCommitCheckBox);
}
vcsPane.add(autoCleanPane); vcsPane.add(autoCleanPane);
saveIntervalPane.setVisible(!VcsHelper.getInstance().isLegacyMode()); boolean support = VcsHelper.getInstance().checkV2FunctionSupport();
autoCleanPane.setVisible(!VcsHelper.getInstance().isLegacyMode()); saveIntervalPane.setVisible(support);
autoCleanPane.setVisible(support);
if (VcsHelper.getInstance().isLegacyMode()) { if (VcsHelper.getInstance().isLegacyMode()) {
// 老版本时才显示gc选项 // 老版本时才显示gc选项
vcsPane.add(gcControlPane); vcsPane.add(gcControlPane);
@ -470,11 +493,17 @@ public class PreferencePane extends BasicPane {
private VcsMovePanel createMovePane(CardLayout cardLayout, JPanel parentPane) { private VcsMovePanel createMovePane(CardLayout cardLayout, JPanel parentPane) {
return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack(){ return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack(){
@Override @Override
public void doCallBack(boolean visible) { public void doCallBack(boolean useV2) {
saveIntervalPane.setVisible(visible); saveIntervalPane.setVisible(useV2);
autoCleanPane.setVisible(visible); autoCleanPane.setVisible(useV2);
} gcControlPane.setVisible(!useV2);
}); saveCommitCheckBox.setVisible(!useV2);
useVcsAutoCleanScheduleCheckBox.setSelected(useV2);
useVcsAutoSaveScheduleCheckBox.setSelected(useV2);
checkAutoScheduleStartAndUpdateStatus();
useVcsAutoSaveScheduleCheckBox.setEnabled(useV2);
}
}, basicDialog);
}; };
private JPanel createAutoCleanPane() { private JPanel createAutoCleanPane() {
@ -490,15 +519,45 @@ public class PreferencePane extends BasicPane {
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Content"))); autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Content")));
autoCleanPane.add(autoCleanRetainIntervalComboBox); autoCleanPane.add(autoCleanRetainIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Last"))); autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Last")));
useVcsAutoCleanScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(false); autoCleanPane.setVisible(false);
return autoCleanPane; return autoCleanPane;
} }
private void checkAutoScheduleStartAndUpdateStatus() {
if (!VcsHelper.getInstance().isLegacyMode()) {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return WorkContext.getCurrent().get(VcsAutoCleanOperator.class).isSupport();
}
@Override
protected void done() {
try {
boolean useAutoClean = get();
updateAutoCleanEnabled(useAutoClean);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
} else {
updateAutoCleanEnabled(false);
}
}
private void updateAutoCleanEnabled(boolean b) {
useVcsAutoCleanScheduleCheckBox.setEnabled(b);
autoCleanIntervalComboBox.setEnabled(b);
autoCleanRetainIntervalComboBox.setEnabled(b);
if (autoCleanPane != null) {
autoCleanPane.setToolTipText(b ? null : Toolkit.i18nText("Fine-Design_Vcs_Server_Start_Hover"));
}
}
private JPanel createSaveIntervalPane() { private JPanel createSaveIntervalPane() {
JPanel saveIntervalPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout()); JPanel saveIntervalPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoSaveScheduleCheckBox = new UICheckBox(); useVcsAutoSaveScheduleCheckBox = new UICheckBox();
autoSaveIntervalEditor = new IntegerEditor(60); autoSaveIntervalEditor = new UIPositiveIntEditor(60);
saveIntervalPane.add(useVcsAutoSaveScheduleCheckBox); saveIntervalPane.add(useVcsAutoSaveScheduleCheckBox);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Every"))); saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Every")));
saveIntervalPane.add(autoSaveIntervalEditor); saveIntervalPane.add(autoSaveIntervalEditor);
@ -890,7 +949,8 @@ public class PreferencePane extends BasicPane {
defaultStringToFormulaBox.setSelected(false); defaultStringToFormulaBox.setSelected(false);
} }
VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager(); VcsConfigManager vcsConfigManager = designerEnvManager.getVcsConfigManager();
if (WorkContext.getCurrent().isCluster()) { //如果是集群并且是老版本则不可用
if (VcsHelper.getInstance().isLegacyMode() && WorkContext.getCurrent().isCluster()) {
vcsEnableCheckBox.setEnabled(false); vcsEnableCheckBox.setEnabled(false);
gcEnableCheckBox.setEnabled(false); gcEnableCheckBox.setEnabled(false);
} }
@ -916,6 +976,8 @@ public class PreferencePane extends BasicPane {
useVcsAutoSaveScheduleCheckBox.setSelected(vcsConfigManager.isUseAutoSave()); useVcsAutoSaveScheduleCheckBox.setSelected(vcsConfigManager.isUseAutoSave());
useVcsAutoCleanScheduleCheckBox.setSelected(VcsConfig.getInstance().isUseV2AutoClean()); useVcsAutoCleanScheduleCheckBox.setSelected(VcsConfig.getInstance().isUseV2AutoClean());
autoSaveIntervalEditor.setValue(vcsConfigManager.getAutoSaveInterval()); autoSaveIntervalEditor.setValue(vcsConfigManager.getAutoSaveInterval());
autoCleanIntervalComboBox.setSelectedIndex(getIndex(VcsConfig.getInstance().getV2CleanInterval()));
autoCleanRetainIntervalComboBox.setSelectedIndex(getIndex(VcsConfig.getInstance().getV2RetainInterval()));
gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor()); gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor());
paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor()); paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor());
@ -1005,18 +1067,11 @@ public class PreferencePane extends BasicPane {
} }
private int getDay(int dateIndex) { private int getDay(int dateIndex) {
switch (dateIndex) { return INDEX_DAY_MAP.getOrDefault(dateIndex, THREE_MONTH_INT);
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;
} }
private int getIndex(int day) {
return INDEX_DAY_MAP.inverse().getOrDefault(day, THREE_MONTH_INDEX);
} }
/** /**
@ -1165,11 +1220,16 @@ public class PreferencePane extends BasicPane {
} else { } else {
VcsHelper.getInstance().stopAutoSave(); VcsHelper.getInstance().stopAutoSave();
} }
if (useVcsAutoCleanScheduleCheckBox.isEnabled()) {
if (useVcsAutoCleanScheduleCheckBox.isSelected()) { if (useVcsAutoCleanScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!"); FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!");
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(getDay(autoCleanIntervalComboBox.getSelectedIndex())); WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(
VcsAutoCleanService.VCS_AUTO_CLEAN_JOB_NAME,
getDay(autoCleanIntervalComboBox.getSelectedIndex()),
VcsAutoCleanSchedule.class);
} else { } else {
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob(); WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob(VcsAutoCleanService.VCS_AUTO_CLEAN_JOB_NAME);
}
} }
} }
return null; return null;
@ -1205,12 +1265,14 @@ public class PreferencePane extends BasicPane {
@Override @Override
public BasicDialog showWindow(Window window) { public BasicDialog showWindow(Window window) {
return showWindow(window, new DialogActionAdapter() { basicDialog = showWindow(window, new DialogActionAdapter() {
@Override @Override
public void doOk() { public void doOk() {
languageChanged = !ComparatorUtils.equals(languageComboBox.getSelectedItem(), DesignerEnvManager.getEnvManager(false).getLanguage()); languageChanged = !ComparatorUtils.equals(languageComboBox.getSelectedItem(), DesignerEnvManager.getEnvManager(false).getLanguage());
} }
}); });
movePanel.setParentDialog(basicDialog);
return basicDialog;
} }
@Override @Override

6
designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java

@ -7,6 +7,7 @@ import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.SaveSomeTemplatePane; import com.fr.design.file.SaveSomeTemplatePane;
import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.vcs.ui.VcsMovingExitOption;
import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.MenuDef; import com.fr.design.menu.MenuDef;
import com.fr.design.menu.SeparatorDef; import com.fr.design.menu.SeparatorDef;
@ -60,6 +61,11 @@ public class SwitchExistEnv extends MenuDef {
* @param e 事件 * @param e 事件
*/ */
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
//检查是否正在迁移,如果正在迁移就弹出弹窗让用户选择
if (!VcsMovingExitOption.ShowDialogAndConfirmSwitch()) {
//如果用户选择取消切换环境则返回,不然说明用户就是想切换,则往下走
return;
}
final String envName = getName(); final String envName = getName();
DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); DesignerEnvManager envManager = DesignerEnvManager.getEnvManager();
DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName);

20
designer-base/src/main/java/com/fr/design/dialog/BasicPane.java

@ -75,6 +75,26 @@ public abstract class BasicPane extends JPanel {
return dg; return dg;
} }
/**
* 显示小窗口并允许自定义需不需要按钮
*
* @param window 窗口
* @param isNeedButtonsPane 是否需要确定删除按钮
* @return 对话框
*/
public BasicDialog showSmallWindow(Window window, boolean isNeedButtonsPane) {
BasicDialog dg;
if (window instanceof Frame) {
dg = new DIALOG((Frame) window, isNeedButtonsPane);
} else {
dg = new DIALOG((Dialog) window, isNeedButtonsPane);
}
dg.setBasicDialogSize(BasicDialog.SMALL);
GUICoreUtils.centerWindow(dg);
dg.setResizable(false);
return dg;
}
/** /**
* 图表类型选择时 弹出的按钮大小, 不适合用最大最小, 因为图表大小 默认是规定好的, 那么界面大小也是必须配合. * 图表类型选择时 弹出的按钮大小, 不适合用最大最小, 因为图表大小 默认是规定好的, 那么界面大小也是必须配合.

10
designer-base/src/main/java/com/fr/design/editor/editor/NumberEditor.java

@ -38,7 +38,7 @@ public abstract class NumberEditor<T extends Number> extends Editor<T> {
*/ */
public NumberEditor(T value, String name) { public NumberEditor(T value, String name) {
this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setLayout(FRGUIPaneFactory.createBorderLayout());
numberField = new UINumberField(); numberField = createNumberField();
this.add(numberField, BorderLayout.CENTER); this.add(numberField, BorderLayout.CENTER);
this.numberField.addKeyListener(textKeyListener); this.numberField.addKeyListener(textKeyListener);
this.numberField.setHorizontalAlignment(UITextField.RIGHT); this.numberField.setHorizontalAlignment(UITextField.RIGHT);
@ -46,6 +46,14 @@ public abstract class NumberEditor<T extends Number> extends Editor<T> {
this.setName(name); this.setName(name);
} }
/**
* 创建NumberField对象
*
*/
protected UINumberField createNumberField() {
return new UINumberField();
}
/** /**
* 给numberField加键盘事件 * 给numberField加键盘事件
* *

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

@ -419,7 +419,7 @@ public class MultiTemplateTabPane extends JComponent {
public void closeOtherByOperatorType(String operatorType){ public void closeOtherByOperatorType(String operatorType){
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false);
if (saveSomeTempaltePane.showSavePane()) { if (saveSomeTempaltePane.showSavePane(null, false, true)) {
List<JTemplate<?, ?>> openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList(); List<JTemplate<?, ?>> openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList();
JTemplate<?, ?>[] templates = new JTemplate<?, ?>[openedTemplate.size()]; JTemplate<?, ?>[] templates = new JTemplate<?, ?>[openedTemplate.size()];

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

@ -183,7 +183,19 @@ public class SaveSomeTemplatePane extends BasicPane {
* @return * @return
*/ */
public boolean showSavePane(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave) { public boolean showSavePane(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave) {
initAndPopulate(option, judgeJTemplateMustSave); return showSavePane(option, judgeJTemplateMustSave, false);
}
/**
* 显示保存模板提醒面板
*
* @param option 具体关闭操作
* @param judgeJTemplateMustSave 模板是否必须保存
* @param judgeSameTabType 是否只包含当前编辑的模板类型
* @return
*/
public boolean showSavePane(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave, boolean judgeSameTabType) {
initAndPopulate(option, judgeJTemplateMustSave, judgeSameTabType);
//如果有未保存的文件 ,则跳出保存对话框,选择要存储的项目 //如果有未保存的文件 ,则跳出保存对话框,选择要存储的项目
if (!unSavedTemplate.isEmpty()) { if (!unSavedTemplate.isEmpty()) {
dialog.setVisible(true); dialog.setVisible(true);
@ -197,13 +209,16 @@ public class SaveSomeTemplatePane extends BasicPane {
return HistoryTemplateListPane.getInstance().getHistoryList(); return HistoryTemplateListPane.getInstance().getHistoryList();
} }
private void initAndPopulate(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave) { private void initAndPopulate(@Nullable MultiTemplateTabPane.CloseCondition option, boolean judgeJTemplateMustSave, boolean judgeSameTabType) {
java.util.List<JTemplate<?, ?>> opendedTemplate = getOpenedTemplatesToProcess(); java.util.List<JTemplate<?, ?>> opendedTemplate = getOpenedTemplatesToProcess();
JTemplate<?, ?> currentTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); JTemplate<?, ?> currentTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
int currentIndex = opendedTemplate.indexOf(currentTemplate); int currentIndex = opendedTemplate.indexOf(currentTemplate);
for (int i = 0; i < opendedTemplate.size(); i++) { for (int i = 0; i < opendedTemplate.size(); i++) {
//满足关闭条件的才继续判断文件是否发生了改动 //满足关闭条件的才继续判断文件是否发生了改动
boolean needClose = option == null || option.shouldClose(opendedTemplate.get(i), currentIndex, i); boolean needClose = option == null || option.shouldClose(opendedTemplate.get(i), currentIndex, i);
if (judgeSameTabType) {
needClose &= ComparatorUtils.equals(opendedTemplate.get(i).getTemplateTabOperatorType(), currentTemplate.getTemplateTabOperatorType());
}
if (needClose && isneedToAdd(opendedTemplate.get(i), currentTemplate)) { if (needClose && isneedToAdd(opendedTemplate.get(i), currentTemplate)) {
unSavedTemplate.add(opendedTemplate.get(i)); unSavedTemplate.add(opendedTemplate.get(i));
} }

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

@ -18,7 +18,6 @@ import com.fr.design.lock.LockInfoDialog;
import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager; import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.mainframe.manager.search.searcher.control.pane.TemplateSearchRemindPane; 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.design.mainframe.vcs.common.VcsHelper;
import com.fr.file.FILE; import com.fr.file.FILE;
import com.fr.file.FileNodeFILE; import com.fr.file.FileNodeFILE;
@ -65,6 +64,7 @@ import java.util.Set;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.fr.workspace.server.vcs.VcsOperator;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -378,8 +378,6 @@ public class TemplateTreePane extends JPanel implements FileOperations {
deleteNodes(deletableNodes); deleteNodes(deletableNodes);
} }
} }
Set<FileNode> deletedFileNode = deletableNodes.stream().map(treeNode -> (FileNode) treeNode.getUserObject()).collect(Collectors.toSet());
refreshAfterDelete(deletedFileNode);
} }
private void refreshAfterDelete(Set<FileNode> deletedPaths) { private void refreshAfterDelete(Set<FileNode> deletedPaths) {
@ -409,7 +407,12 @@ public class TemplateTreePane extends JPanel implements FileOperations {
if (node instanceof FileNode) { if (node instanceof FileNode) {
FileNodeFILE nodeFILE = new FileNodeFILE((FileNode) node); FileNodeFILE nodeFILE = new FileNodeFILE((FileNode) node);
if (nodeFILE.exists()) { if (nodeFILE.exists()) {
VcsService.getInstance().doRecycle(VcsHelper.getInstance().dealWithFilePath(((FileNode) node).getEnvPath())); try {
WorkContext.getCurrent().get(VcsOperator.class).recycleVersion(VcsHelper.getInstance().getCurrentUsername(), VcsHelper.getInstance().dealWithFilePath(((FileNode) node).getEnvPath()));
} catch (Exception e) {
FineLoggerFactory.getLogger().error("[VcsV2] recycle {} failed", nodeFILE.getName());
return false;
}
if (TemplateResourceManager.getResource().delete(nodeFILE)) { if (TemplateResourceManager.getResource().delete(nodeFILE)) {
HistoryTemplateListCache.getInstance().deleteFile(nodeFILE); HistoryTemplateListCache.getInstance().deleteFile(nodeFILE);
} else { } else {
@ -426,6 +429,8 @@ public class TemplateTreePane extends JPanel implements FileOperations {
if (!get()) { if (!get()) {
showErrorDialog(); showErrorDialog();
} }
Set<FileNode> deletedFileNode = nodes.stream().map(treeNode -> (FileNode) treeNode.getUserObject()).collect(Collectors.toSet());
refreshAfterDelete(deletedFileNode);
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

15
designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableModelAdapter.java

@ -4,6 +4,7 @@ import com.fr.base.BaseUtils;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import org.jetbrains.annotations.Nullable;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JTable; import javax.swing.JTable;
@ -64,6 +65,20 @@ public abstract class UITableModelAdapter<T> extends AbstractTableModel implemen
return null; return null;
} }
/**
* 获取映射后的值
*
* @param row
* @return
*/
@Nullable
public T getConvertRowSelectedValue(int row) {
if (table.getSelectedRow() >= 0) {
return list.get(table.convertRowIndexToModel(row));
}
return null;
}
public void setColumnClass(Class<?>[] classes) { public void setColumnClass(Class<?>[] classes) {
this.classes = classes; this.classes = classes;
} }

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

@ -34,6 +34,7 @@ import com.fr.design.mainframe.share.mini.MiniShopDisposingChecker;
import com.fr.design.mainframe.toolbar.ToolBarMenuDock; import com.fr.design.mainframe.toolbar.ToolBarMenuDock;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.VcsMovingExitOption;
import com.fr.design.menu.ShortCut; import com.fr.design.menu.ShortCut;
import com.fr.design.os.impl.MacOsAddListenerAction; import com.fr.design.os.impl.MacOsAddListenerAction;
import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.os.impl.SupportOSImpl;
@ -161,6 +162,12 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
@Override @Override
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
//检查是否正在迁移,如果正在迁移就弹出弹窗让用户选择
if (!VcsMovingExitOption.ShowDialogAndConfirmExit()) {
//如果用户选择取消退出则返回,不然说明用户就是想退出,则往下走
return;
}
// 检查mini商城是否存在未结束的后台任务 // 检查mini商城是否存在未结束的后台任务
if (!MiniShopDisposingChecker.check()) { if (!MiniShopDisposingChecker.check()) {
return; return;

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

@ -46,6 +46,7 @@ import com.fr.design.roleAuthority.RolesAlreadyEditedPane;
import com.fr.design.ui.util.UIUtil; import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.DesignUtils; import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.worker.save.CallbackSaveWorker;
import com.fr.event.Event; import com.fr.event.Event;
import com.fr.file.filetree.FileNode; import com.fr.file.filetree.FileNode;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
@ -337,7 +338,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
} }
toolbarDef.addShortCut(vcsAction); toolbarDef.addShortCut(vcsAction);
//11.0.19及其之后加入回收站逻辑 //11.0.19及其之后加入回收站逻辑
if (!VcsHelper.getInstance().isLegacyMode()) { if (VcsHelper.getInstance().checkV2FunctionSupport()) {
recycleAction = new RecycleAction(); recycleAction = new RecycleAction();
toolbarDef.addShortCut(recycleAction); toolbarDef.addShortCut(recycleAction);
} }
@ -393,9 +394,12 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private boolean isCurrentEditing(String path) { private boolean isCurrentEditing(String path) {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (JTemplate.isValid(jt)) {
String editing = jt.getEditingFILE().getPath(); String editing = jt.getEditingFILE().getPath();
return ComparatorUtils.equals(editing, path); return ComparatorUtils.equals(editing, path);
} }
return false;
}
/** /**
* 按钮状态改变 * 按钮状态改变
@ -501,22 +505,25 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath(); String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path); path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
if (VcsHelper.getInstance().isLegacyMode()) {
boolean currentEditing = isCurrentEditing(path); boolean currentEditing = isCurrentEditing(path);
if (VcsHelper.getInstance().isLegacyMode()) {
// 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本) // 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本)
closeOpenedTemplate(path, currentEditing); closeOpenedTemplate(path, currentEditing);
FileVersionsPanel fileVersionTablePanel = FileVersionsPanel.getInstance(); FileVersionsPanel fileVersionTablePanel = FileVersionsPanel.getInstance();
fileVersionTablePanel.showFileVersionsPane(); fileVersionTablePanel.showFileVersionsPane();
stateChange(); stateChange();
} else { } else {
VcsNewPane panel = new VcsNewPane(path); checkTemplateSavedAndShowVcsNewPane(path, currentEditing);
BasicDialog dialog = panel.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
} }
} }
private void showVcsNewPane(String path) {
VcsNewPane panel = new VcsNewPane(path);
panel.showDialog();
}
/** /**
* 版本管理可用状态的监控 * 版本管理可用状态的监控
*/ */
@ -570,6 +577,60 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
} }
} }
/**
* 如果指定模板已经打开
* <p>1.如果该模板已保存则正常打开新版本管理弹窗
* <p>2.如果该模板未保存触发保存逻辑
* <li>a.如果用户选择保存则保存并不关闭模板弹出新版本管理弹窗
* <li>b.如果用户选择不保存则关闭当前模板弹出新版本管理弹窗
* <li>c.如果用户选择取消, 则啥操作都不做
*
* @param path
* @param isCurrentEditing
*/
private void checkTemplateSavedAndShowVcsNewPane(String path, boolean isCurrentEditing) {
for (JTemplate jTemplate : HistoryTemplateListCache.getInstance().getHistoryList()) {
if (ComparatorUtils.equals(jTemplate.getEditingFILE().getPath(), path)) {
if (!jTemplate.isALLSaved()) {
MultiTemplateTabPane.getInstance().setIsCloseCurrent(isCurrentEditing);
MultiTemplateTabPane.getInstance().closeFormat(jTemplate);
confirmCloseAndShowVcsNewPane(jTemplate, path);
return;
}
}
}
showVcsNewPane(path);
}
private void confirmCloseAndShowVcsNewPane(JTemplate<?, ?> specifiedTemplate, String path) {
if (specifiedTemplate == null) {
return;
}
if (!specifiedTemplate.isALLSaved() && !DesignerMode.isVcsMode()) {
specifiedTemplate.stopEditing();
int returnVal = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Save") + " \"" + specifiedTemplate.getEditingFILE() + "\" ?",
Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (returnVal == JOptionPane.YES_OPTION) {
CallbackSaveWorker worker = specifiedTemplate.save();
worker.addSuccessCallback(() -> {
FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName()));
showVcsNewPane(path);
});
worker.start(specifiedTemplate.getRuntimeId());
} else if (returnVal == JOptionPane.NO_OPTION) {
closeTpl(specifiedTemplate);
showVcsNewPane(path);
}
} else {
showVcsNewPane(path);
}
}
private void closeTpl(JTemplate<?, ?> specifiedTemplate) {
HistoryTemplateListCache.getInstance().closeSelectedReport(specifiedTemplate);
MultiTemplateTabPane.getInstance().closeAndFreeLock(specifiedTemplate);
MultiTemplateTabPane.getInstance().activePrevTemplateAfterClose();
}
} }

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

@ -4,7 +4,7 @@ import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicDialog;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.ui.RecyclePane; import com.fr.design.mainframe.vcs.ui.RecycleSettingPane;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -18,13 +18,13 @@ import java.awt.event.ActionEvent;
public class RecycleAction extends UpdateAction { public class RecycleAction extends UpdateAction {
public RecycleAction() { public RecycleAction() {
this.setSmallIcon("/com/fr/design/standard/vcslist/vcs_recycle"); this.setSmallIcon("/com/fr/design/standard/vcslist/vcs_recycle", false);
this.setName(Toolkit.i18nText("Fine-Design_Vcs_Recycle")); this.setName(Toolkit.i18nText("Fine-Design_Vcs_Recycle"));
} }
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
RecyclePane pane = new RecyclePane(); RecycleSettingPane pane = new RecycleSettingPane();
BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame(), false); BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true); dialog.setVisible(true);
} }

37
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsExceptionUtils.java

@ -0,0 +1,37 @@
package com.fr.design.mainframe.vcs;
import com.fr.design.i18n.Toolkit;
import java.io.IOException;
import java.util.HashMap;
/**
* 版本管理异常处理工具类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/24
*/
public class VcsExceptionUtils {
public static final HashMap<Class, String> EXCEPTION_MAP = new HashMap<Class, String>() {
{
put(IOException.class, Toolkit.i18nText("Fine-Design_Vcs_Exception_IO"));
put(UnsupportedOperationException.class, Toolkit.i18nText("Fine-Design_Vcs_Exception_Un_Support"));
}
};
/**
* 根据异常返回结果描述文案
*/
public static String createDetailByException(Exception e) {
for (Class key : EXCEPTION_MAP.keySet()) {
if (key.isAssignableFrom(e.getClass())) {
return EXCEPTION_MAP.get(key);
}
}
return Toolkit.i18nText("Fine-Design_Vcs_Exception_Unknown");
}
}

291
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsOperatorWorker.java

@ -0,0 +1,291 @@
package com.fr.design.mainframe.vcs;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.ui.VcsBatchProcessDetailPane;
import com.fr.design.mainframe.vcs.ui.VcsProgressDialog;
import com.fr.log.FineLoggerFactory;
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.SwingWorker;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 为版本中心回收站版本详情提供带进度条与结算面板的操作的worker
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/18
*/
public class VcsOperatorWorker {
private int count = 0;
private static final int FREQ = 5;
private String successStr;
private String title;
private String failedStr;
private String everyFailedStr;
private VcsProgressDialog dialog;
private static final String PREFIX = "(v.";
private static final String TAIL = ")";
public VcsOperatorWorker(String title, String dealingStr, String successStr, String failedStr, String everyFailedStr) {
this.title = title;
this.successStr = successStr;
this.failedStr = failedStr;
this.everyFailedStr = everyFailedStr;
dialog = new VcsProgressDialog(title, dealingStr);
}
public VcsOperatorWorker(String everyFailedStr) {
this.title = StringUtils.EMPTY;
this.successStr = StringUtils.EMPTY;
this.failedStr = StringUtils.EMPTY;
this.everyFailedStr = everyFailedStr;
}
/**
* 快速创建用于删除的worker
*
* @return
*/
public static VcsOperatorWorker createDeleteWorker() {
return new VcsOperatorWorker(
Toolkit.i18nText("Fine-Design_Vcs_Delete_Progress_Title"),
Toolkit.i18nText("Fine-Design_Vcs_Delete_Progress_Tips"),
Toolkit.i18nText("Fine-Design_Vcs_Delete_Progress_Success"),
"Fine-Design_Vcs_Delete_Progress_Failed",
Toolkit.i18nText("Fine-Design_Vcs_Delete_Every_Failed"));
}
/**
* 快速创建用于还原的worker
*
* @return
*/
public static VcsOperatorWorker createRestoreWorker() {
return new VcsOperatorWorker(
Toolkit.i18nText("Fine-Design_Vcs_Restore_Progress_Title"),
Toolkit.i18nText("Fine-Design_Vcs_Restore_Progress_Tips"),
Toolkit.i18nText("Fine-Design_Vcs_Restore_Progress_Success"),
"Fine-Design_Vcs_Restore_Progress_Failed",
Toolkit.i18nText("Fine-Design_Vcs_Restore_Every_Failed"));
}
/**
* 快速创建用于还原的worker
*
* @return
*/
public static VcsOperatorWorker createUpdateWorker() {
return new VcsOperatorWorker(Toolkit.i18nText("Fine-Design_Vcs_Update_Every_Failed"));
}
/**
* 批量还原
*
* @param vcsEntities 需要还原的版本
*/
public void batchRestore(List<VcsEntity> vcsEntities) {
List<String> failedList = new ArrayList<>();
startProcess(vcsEntities, failedList, (vcsEntity, operator) -> {
String fileName = vcsEntity.getFilename();
boolean result = true;
try {
operator.restoreVersion(fileName);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
result = false;
}
if (!result) {
failedList.add(fileName+PREFIX+vcsEntity.getVersion()+TAIL);
}
});
}
/**
* 批量删除
*
* @param vcsEntities 需要删除的版本
* @param all 是否需要删除所有版本
*/
public void batchDelete(List<VcsEntity> vcsEntities, boolean all) {
List<String> failedList = new ArrayList<>();
startProcess(vcsEntities, failedList, (vcsEntity, operator) -> {
String fileName = vcsEntity.getFilename();
boolean result = true;
try {
if (all) {
operator.deleteVersionForRecycle(fileName);
} else {
operator.deleteVersion(fileName, vcsEntity.getVersion());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
result = false;
}
if (!result) {
failedList.add(fileName+PREFIX+vcsEntity.getVersion()+TAIL);
}
});
}
/**
* 删除指定模板的全部历史版本
*
* @param entity VcsEntity
*/
public void doDelete(VcsEntity entity) {
String fileName = entity.getFilename();
start4Single(entity, (vcsEntity, operator) -> operator.deleteVersionForRecycle(fileName), fileName + everyFailedStr);
}
/**
* 删除指定模板的指定版本
*
* @param entity 版本
*/
public void deleteTargetVersion(VcsEntity entity) {
String fileName = entity.getFilename();
int version = entity.getVersion();
start4Single(entity, (vcsEntity, operator) -> {
operator.deleteVersion(fileName, version);
}, fileName + everyFailedStr);
}
/**
* 更新版本
*
* @param entity 版本
*/
public void updateEntityAnnotation(VcsEntity entity) {
start4Single(entity, (vcsEntity, operator) -> {
operator.updateVersion(entity);
}, everyFailedStr);
}
private void startProcess(List<VcsEntity> vcsEntities, List<String> failedList, VcsWorkerOperator workerOperator) {
try {
dialog.getProgressBar().setMaximum(vcsEntities.size());
start4Batch(vcsEntities, failedList, workerOperator);
dialog.showDialog();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 控制更新频率
*
* @return 是否需要更新进度
*/
private boolean needPublish() {
return (count > FREQ && count % FREQ == 0) || count < FREQ;
}
private void start4Single(VcsEntity entity, VcsWorkerOperator vcsWorkerOperator, String failedTip) {
new SwingWorker<Boolean, Void>() {
@Override
protected void done() {
try {
if (!get()) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), failedTip);
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
@Override
protected Boolean doInBackground() throws Exception {
try {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
vcsWorkerOperator.process(entity, operator);
} catch (Exception e) {
return false;
}
return true;
}
}.execute();
}
private void start4Batch(List<VcsEntity> vcsEntities, List<String> failedList, VcsWorkerOperator workerOperator) {
new SwingWorker<Boolean, Integer>() {
@Override
protected Boolean doInBackground() throws Exception {
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
for (VcsEntity vcsEntity : vcsEntities) {
workerOperator.process(vcsEntity, operator);
count++;
if (needPublish()) {
publish(count);
}
}
return failedList.isEmpty();
}
@Override
protected void process(List<Integer> chunks) {
dialog.getProgressBar().setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
dialog.closeDialog();
try {
showErrorDetailPane(get(), failedList, failedList.size(), vcsEntities.size() - failedList.size());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
private void showErrorDetailPane(boolean result, List<String> failedList, int failed, int success) {
if (result) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), successStr);
} else {
VcsBatchProcessDetailPane pane = new VcsBatchProcessDetailPane(
DesignerContext.getDesignerFrame(),
title,
Toolkit.i18nText(failedStr, failed, success)
);
for (String msg : failedList) {
pane.updateDetailArea(msg + everyFailedStr);
}
pane.show();
}
}
/**
* Vcs面板操作处理接口
*
*/
private interface VcsWorkerOperator {
/**
* 处理
*
* @param vcsEntity 版本
* @param operator 操作类
*/
void process(VcsEntity vcsEntity, VcsOperator operator) throws Exception;
}
}

49
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsRecycleSettingHelper.java

@ -0,0 +1,49 @@
package com.fr.design.mainframe.vcs;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.transaction.Configurations;
import com.fr.transaction.WorkerAdaptor;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanService;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoRecycleSchedule;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 版本管理界面配置回收事件的处理类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/21
*/
public class VcsRecycleSettingHelper {
private static ExecutorService executorService = Executors.newSingleThreadExecutor(new NamedThreadFactory("VcsRecycle"));
/**
* 更新任务
*
* @param day
*/
public static void updateJob(int day) {
executorService.execute(new Runnable() {
@Override
public void run() {
Configurations.update(new WorkerAdaptor(VcsConfig.class) {
@Override
public void run() {
VcsConfig.getInstance().setV2CleanRecycleInterval(day);
}
});
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(
VcsAutoCleanService.VCS_AUTO_CLEAN_RECYCLE_JOB_NAME,
1,
VcsAutoRecycleSchedule.class);
}
});
}
}

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

@ -1,162 +0,0 @@
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);
}
}
}

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

@ -1,6 +1,7 @@
package com.fr.design.mainframe.vcs; package com.fr.design.mainframe.vcs;
import com.fr.report.entity.VcsEntity; import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
/** /**
* 包装VcsEntity的用于表格展示与处理的类 * 包装VcsEntity的用于表格展示与处理的类
@ -16,7 +17,7 @@ public class VcsTableEntity implements TableEntity{
private static final String MB = "MB"; private static final String MB = "MB";
private static final String VERSION = "V."; private static final String VERSION = "V.";
private static final double MB_SIZE = 1024.0; private static final double MB_SIZE = 1024.0 * 1024;
private VcsEntity entity; private VcsEntity entity;
@ -39,7 +40,11 @@ public class VcsTableEntity implements TableEntity{
* @return 版本大小 * @return 版本大小
*/ */
public String getSize() { public String getSize() {
return String.format("%.2f",entity.getSize()/MB_SIZE) + MB; double size = entity.getSize()/MB_SIZE;
if (size == 0) {
return StringUtils.EMPTY;
}
return String.format("%.3f", size) + MB;
} }
/** /**

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

@ -15,6 +15,7 @@ import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.ui.FileVersionTable; import com.fr.design.mainframe.vcs.ui.FileVersionTable;
import com.fr.event.Event; import com.fr.event.Event;
import com.fr.event.EventDispatcher; import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.ListenerAdaptor; import com.fr.event.ListenerAdaptor;
import com.fr.general.IOUtils; import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
@ -24,6 +25,8 @@ import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants; import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import com.fr.workspace.server.vcs.VcsOperator; import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.filesystem.VcsFileSystem; import com.fr.workspace.server.vcs.filesystem.VcsFileSystem;
import com.fr.workspace.server.vcs.git.config.GcConfig; import com.fr.workspace.server.vcs.git.config.GcConfig;
@ -66,6 +69,8 @@ public class VcsHelper implements JTemplateActionListener {
private volatile boolean legacyMode; private volatile boolean legacyMode;
private volatile boolean root;
public static VcsHelper getInstance() { public static VcsHelper getInstance() {
return INSTANCE; return INSTANCE;
} }
@ -74,7 +79,14 @@ public class VcsHelper implements JTemplateActionListener {
VcsOperator op = WorkContext.getCurrent().get(VcsOperator.class); VcsOperator op = WorkContext.getCurrent().get(VcsOperator.class);
// 开了设计器启动页面时一开始取不到VcsOperator,通过下面的切换环境事件再取,这边判断下 // 开了设计器启动页面时一开始取不到VcsOperator,通过下面的切换环境事件再取,这边判断下
if (op != null) { if (op != null) {
try {
legacyMode = op.isLegacyMode(); legacyMode = op.isLegacyMode();
root = WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot();
} catch (Exception e) {
legacyMode = true;
root = false;
FineLoggerFactory.getLogger().error("[VcsHelper] init first failed ", e.getMessage());
}
} }
EventDispatcher.listen(ConfigEvent.READY, new ListenerAdaptor() { EventDispatcher.listen(ConfigEvent.READY, new ListenerAdaptor() {
@Override @Override
@ -89,6 +101,18 @@ public class VcsHelper implements JTemplateActionListener {
} }
} }
}); });
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
try {
root = WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot() ;
} catch (Exception e) {
root = false;
FineLoggerFactory.getLogger().error("[VcsHelper] get root failed", e.getMessage());
}
}
});
} }
/** /**
@ -327,7 +351,7 @@ public class VcsHelper implements JTemplateActionListener {
private void autoSave(JTemplate jt, String currentUsername, String fileName, int nowVersion, boolean replace, VcsOperator operator) { private void autoSave(JTemplate jt, String currentUsername, String fileName, int nowVersion, boolean replace, VcsOperator operator) {
try { try {
if (JTemplate.isValid(jt)) { if (JTemplate.isValid(jt) && !jt.isALLSaved()) {
operator.autoSave(currentUsername, fileName, StringUtils.EMPTY, nowVersion, jt.exportData(), replace); operator.autoSave(currentUsername, fileName, StringUtils.EMPTY, nowVersion, jt.exportData(), replace);
} }
} catch (Exception e) { } catch (Exception e) {
@ -347,7 +371,8 @@ public class VcsHelper implements JTemplateActionListener {
public void templateSaved(JTemplate<?, ?> jt) { public void templateSaved(JTemplate<?, ?> jt) {
if (needInit() if (needInit()
&& DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable() && DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable()
&& !WorkContext.getCurrent().isCluster()) { // 如果是集群,在新版本下才生效
&& (!WorkContext.getCurrent().isCluster() || !VcsHelper.getInstance().isLegacyMode())) {
fireVcs(jt); fireVcs(jt);
} }
} }
@ -370,7 +395,7 @@ public class VcsHelper implements JTemplateActionListener {
* @return 支持返回true * @return 支持返回true
*/ */
public boolean checkV2FunctionSupport() { public boolean checkV2FunctionSupport() {
return !VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot()); return !VcsHelper.getInstance().isLegacyMode() && root;
} }
/** /**

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

@ -1,5 +1,6 @@
package com.fr.design.mainframe.vcs.ui; package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane; import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane;
import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icheckbox.UICheckBox;
@ -19,6 +20,7 @@ import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.SwingWorker; import javax.swing.SwingWorker;
import javax.swing.UIManager; import javax.swing.UIManager;
@ -26,6 +28,7 @@ import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.UIResource; import javax.swing.plaf.UIResource;
import javax.swing.table.JTableHeader; import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer; import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableRowSorter;
import java.awt.*; import java.awt.*;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
@ -151,6 +154,13 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
tablePane.add(tableTopPane, BorderLayout.NORTH); tablePane.add(tableTopPane, BorderLayout.NORTH);
tablePane.add(tableContentPane, BorderLayout.CENTER); tablePane.add(tableContentPane, BorderLayout.CENTER);
tableContentPane.getEditTable().getColumnModel().getColumn(0).setMaxWidth(50); tableContentPane.getEditTable().getColumnModel().getColumn(0).setMaxWidth(50);
RowSorter<UITableModelAdapter<T>> sorter = new TableRowSorter<UITableModelAdapter<T>>(model) {
@Override
public boolean isSortable(int column) {
return column != 0;
}
};
tableContentPane.getEditTable().setRowSorter(sorter);
return tablePane; return tablePane;
} }
@ -171,7 +181,7 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
int row = ((JTable) e.getSource()).rowAtPoint(e.getPoint()); int row = ((JTable) e.getSource()).rowAtPoint(e.getPoint());
int col = ((JTable) e.getSource()).columnAtPoint(e.getPoint()); int col = ((JTable) e.getSource()).columnAtPoint(e.getPoint());
if (col == 0) { if (col == 0) {
T entity = model.getSelectedValue(); T entity = model.getConvertRowSelectedValue(row);
//改变面板的各个状态 //改变面板的各个状态
changeComponentStatus(entity, row, col, table); changeComponentStatus(entity, row, col, table);
} }
@ -210,6 +220,17 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
//更新表头的勾选框状态 //更新表头的勾选框状态
HeaderRenderer renderer = (HeaderRenderer) table.getTableHeader().getDefaultRenderer(); HeaderRenderer renderer = (HeaderRenderer) table.getTableHeader().getDefaultRenderer();
renderer.refreshHeader(table, selectCount >= table.getRowCount()); renderer.refreshHeader(table, selectCount >= table.getRowCount());
changeExtraComponentStatus();
}
/**
* 更新额外组件的状态
*/
protected void changeExtraComponentStatus() {
}
public int getSelectCount() {
return selectCount;
} }
@ -233,6 +254,7 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
public HeaderRenderer(JTable table) { public HeaderRenderer(JTable table) {
this.tableHeader = table.getTableHeader(); this.tableHeader = table.getTableHeader();
tableHeader.setCursor(new Cursor(Cursor.HAND_CURSOR));
selectBox = new UICheckBox(); selectBox = new UICheckBox();
selectBox.setSelected(false); selectBox.setSelected(false);
tableHeader.addMouseListener(new MouseAdapter() { tableHeader.addMouseListener(new MouseAdapter() {
@ -245,6 +267,7 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
selectBox.setSelected(value); selectBox.setSelected(value);
selectAllOrNull(value); selectAllOrNull(value);
selectCount = value ? table.getRowCount() : 0; selectCount = value ? table.getRowCount() : 0;
changeExtraComponentStatus();
tableHeader.repaint(); tableHeader.repaint();
model.fireTableDataChanged(); model.fireTableDataChanged();
} }
@ -281,8 +304,12 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
tableHeader = table.getTableHeader(); tableHeader = table.getTableHeader();
tableHeader.setReorderingAllowed(false); tableHeader.setReorderingAllowed(false);
String valueStr = (String) value; String valueStr = (String) value;
JLabel label = new JLabel(valueStr); UILabel label = new UILabel(valueStr);
if (needIcon4Head(column)) {
label.setIcon(IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_sort"));
label.setHorizontalTextPosition(JLabel.LEFT);
label.setHorizontalAlignment(SwingConstants.LEFT); label.setHorizontalAlignment(SwingConstants.LEFT);
}
selectBox.setHorizontalAlignment(SwingConstants.CENTER); selectBox.setHorizontalAlignment(SwingConstants.CENTER);
selectBox.setBorderPainted(true); selectBox.setBorderPainted(true);
JComponent component = (column == 0) ? selectBox : label; JComponent component = (column == 0) ? selectBox : label;
@ -311,6 +338,7 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
setColumnClass(classes); setColumnClass(classes);
this.setDefaultEditor(Boolean.class, new BooleanEditor()); this.setDefaultEditor(Boolean.class, new BooleanEditor());
this.setDefaultRenderer(Boolean.class, new BooleanRenderer()); this.setDefaultRenderer(Boolean.class, new BooleanRenderer());
this.setDefaultRenderer(UILabel.class, new ToolTipTableCellRenderer());
} }
@Override @Override
@ -366,5 +394,14 @@ public abstract class AbstractSupportSelectTablePane<T extends TableEntity> exte
} }
/**
* 表头的某列是否需要icon
*
* @param col
* @return
*/
protected boolean needIcon4Head(int col) {
return col != 0;
}
} }

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

@ -1,11 +1,13 @@
package com.fr.design.mainframe.vcs.ui; package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils; import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.vcs.VcsService; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.VcsOperatorWorker;
import com.fr.design.mainframe.vcs.TableEntity; import com.fr.design.mainframe.vcs.TableEntity;
import com.fr.design.mainframe.vcs.TableValueOperator; import com.fr.design.mainframe.vcs.TableValueOperator;
import com.fr.design.mainframe.vcs.VcsTableEntity; import com.fr.design.mainframe.vcs.VcsTableEntity;
@ -37,8 +39,10 @@ import static com.fr.design.i18n.Toolkit.i18nText;
*/ */
public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity> { 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_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_REFRESH = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_restore", IconUtils.ICON_TYPE_NORMAL);
public static final Icon ICON_DELETE = IconUtils.readIcon("/com/fr/design/standard/vcslist/vcs_recycle_delete"); public static final Icon ICON_REFRESH_DISABLE = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_restore", IconUtils.ICON_TYPE_DISABLED);
public static final Icon ICON_DELETE = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_delete", IconUtils.ICON_TYPE_NORMAL);
public static final Icon ICON_DELETE_DISABLE = IconUtils.readSVGIcon("/com/fr/design/standard/vcslist/vcs_recycle_delete", IconUtils.ICON_TYPE_DISABLED);
protected UITextField searchTextField; protected UITextField searchTextField;
@ -47,6 +51,10 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
protected UILabel restoreLabel; protected UILabel restoreLabel;
private static final int COLUMNS_COUNT = 15; private static final int COLUMNS_COUNT = 15;
private BasicDialog dialog;
private BasicDialog parentDialog;
private List<VcsTableEntity> tableEntities;
public RecyclePane() { public RecyclePane() {
super(i18nText("Fine-Design_Vcs_Recycle"), (o, columnIndex) -> { super(i18nText("Fine-Design_Vcs_Recycle"), (o, columnIndex) -> {
@ -71,7 +79,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
Toolkit.i18nText("Fine-Design_Vcs_Recycle_Size"), Toolkit.i18nText("Fine-Design_Vcs_Recycle_Size"),
Toolkit.i18nText("Fine-Design_Vcs_Delete_Time"), Toolkit.i18nText("Fine-Design_Vcs_Delete_Time"),
Toolkit.i18nText("Fine-Design_Vcs_Time") Toolkit.i18nText("Fine-Design_Vcs_Time")
}, true); }, false);
} }
public RecyclePane(String title, TableValueOperator<VcsTableEntity> operators, boolean needBorder) { public RecyclePane(String title, TableValueOperator<VcsTableEntity> operators, boolean needBorder) {
@ -86,6 +94,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
for (VcsEntity entity : entityList) { for (VcsEntity entity : entityList) {
tableEntities.add(new VcsTableEntity(entity)); tableEntities.add(new VcsTableEntity(entity));
} }
updateTableList(tableEntities);
return tableEntities; return tableEntities;
} }
@ -108,17 +117,33 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
if (isNeedRestore()) { if (isNeedRestore()) {
restoreLabel = new UILabel(ICON_REFRESH); restoreLabel = new UILabel(ICON_REFRESH);
restoreLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); restoreLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
restoreLabel.setDisabledIcon(ICON_REFRESH_DISABLE);
restoreLabel.setEnabled(false);
rightPane.add(restoreLabel); rightPane.add(restoreLabel);
} }
if (isNeedDelete()) { if (isNeedDelete()) {
deleteLabel = new UILabel(ICON_DELETE); deleteLabel = new UILabel(ICON_DELETE);
deleteLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); deleteLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
deleteLabel.setDisabledIcon(ICON_DELETE_DISABLE);
deleteLabel.setEnabled(false);
rightPane.add(deleteLabel); rightPane.add(deleteLabel);
} }
tableTopPane.add(leftPane, BorderLayout.EAST); tableTopPane.add(leftPane, BorderLayout.EAST);
tableTopPane.add(rightPane, BorderLayout.WEST); tableTopPane.add(rightPane, BorderLayout.WEST);
} }
@Override
protected void changeExtraComponentStatus() {
boolean canUseLabel = getSelectCount() > 0;
if (restoreLabel != null) {
restoreLabel.setEnabled(canUseLabel);
}
if (deleteLabel != null) {
deleteLabel.setEnabled(canUseLabel);
}
}
@Override @Override
protected void initTopPaneListener() { protected void initTopPaneListener() {
initSearchTextFiledListener(); initSearchTextFiledListener();
@ -128,13 +153,14 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
private void initDeleteLabelListener() { private void initDeleteLabelListener() {
if (isNeedDelete()) { if (isNeedDelete()) {
deleteLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Delete"));
deleteLabel.addMouseListener(new MouseAdapter() { deleteLabel.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
fireListener(new VcsResponseListener() { fireListener(new VcsResponseListener() {
@Override @Override
public void doAfterChooseYes(List<VcsEntity> selectList) { public void doAfterChooseYes(List<VcsEntity> selectList) {
VcsService.getInstance().doDelete(selectList, isNeedDeleteAllVersion()); VcsOperatorWorker.createDeleteWorker().batchDelete(selectList, isNeedDeleteAllVersion());
} }
}, true); }, true);
} }
@ -144,13 +170,14 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
private void initRestoreListener() { private void initRestoreListener() {
if (isNeedRestore()) { if (isNeedRestore()) {
restoreLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Restore"));
restoreLabel.addMouseListener(new MouseAdapter() { restoreLabel.addMouseListener(new MouseAdapter() {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
fireListener(new VcsResponseListener() { fireListener(new VcsResponseListener() {
@Override @Override
public void doAfterChooseYes(List<VcsEntity> selectList) { public void doAfterChooseYes(List<VcsEntity> selectList) {
VcsService.getInstance().doRestore(selectList); VcsOperatorWorker.createRestoreWorker().batchRestore(selectList);
} }
}, false); }, false);
} }
@ -164,8 +191,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String str = searchTextField.getText(); String str = searchTextField.getText();
List<VcsTableEntity> entityList = model.getList(); model.setList(tableEntities.stream().filter(entity -> entity.getEntity().getFilename().contains(str)).collect(Collectors.toList()));
model.setList(entityList.stream().filter(entity -> entity.getEntity().getFilename().contains(str)).collect(Collectors.toList()));
model.fireTableDataChanged(); model.fireTableDataChanged();
} }
}); });
@ -173,6 +199,7 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
} }
private void fireListener(VcsResponseListener listener, boolean isDelete) { private void fireListener(VcsResponseListener listener, boolean isDelete) {
List<VcsEntity> selectList = model.getList().stream().filter(TableEntity::isSelect).map(VcsTableEntity::getEntity).collect(Collectors.toList()); List<VcsEntity> selectList = model.getList().stream().filter(TableEntity::isSelect).map(VcsTableEntity::getEntity).collect(Collectors.toList());
if (selectList.size() > 0) { if (selectList.size() > 0) {
@ -183,7 +210,8 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
JOptionPane.OK_CANCEL_OPTION, JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE); JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) { if (selVal == JOptionPane.YES_OPTION) {
model.setList(model.getList().stream().filter(tableEntity -> !tableEntity.isSelect()).collect(Collectors.toList())); tableEntities = model.getList().stream().filter(tableEntity -> !tableEntity.isSelect()).collect(Collectors.toList());
model.setList(tableEntities);
model.fireTableDataChanged(); model.fireTableDataChanged();
listener.doAfterChooseYes(selectList); listener.doAfterChooseYes(selectList);
} }
@ -191,6 +219,61 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
} }
/**
* 显示弹窗
*
*/
public void showDialog() {
dialog = this.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
/**
* 依据父弹窗显示弹窗
*
* @param parent 父弹窗
*/
public void showDialog(BasicDialog parent) {
this.parentDialog = parent;
dialog = this.showWindow(parent, false);
initDialogListener(dialog);
dialog.setVisible(true);
}
protected void initDialogListener(BasicDialog dialog) {
}
/**
* 关闭弹窗,如果有父弹窗,则一起关闭,如果有属性配置的弹窗面板要保存再关闭
*
*/
public void saveSettingAndCloseDialog() {
if (dialog != null) {
dialog.doOK();
dialog.dispose();
}
if (parentDialog != null) {
parentDialog.doOK();
parentDialog.dispose();
}
}
public BasicDialog getDialog() {
return dialog;
}
public void setDialog(BasicDialog dialog) {
this.dialog = dialog;
}
public BasicDialog getParentDialog() {
return parentDialog;
}
public void setParentDialog(BasicDialog parentDialog) {
this.parentDialog = parentDialog;
}
/** /**
* 删除范围 * 删除范围
* *
@ -250,6 +333,25 @@ public class RecyclePane extends AbstractSupportSelectTablePane<VcsTableEntity>
return true; return true;
} }
/**
* 更新数据列表
*
* @param entities
*/
public void updateTableList(List<VcsTableEntity> entities) {
tableEntities = entities;
}
/**
* 移除指定元素
*
* @param entity
*/
public void removeTarget(VcsTableEntity entity) {
tableEntities.remove(entity);
}
/** /**
* 版本管理按钮事件响应 * 版本管理按钮事件响应
*/ */

103
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecycleSettingPane.java

@ -0,0 +1,103 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.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.vcs.VcsRecycleSettingHelper;
import com.fr.workspace.server.vcs.VcsConfig;
import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 回收站配置面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/21
*/
public class RecycleSettingPane extends BasicPane {
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 = 30;
private UISpinner spinner;
private UIButton button;
public RecycleSettingPane() {
init();
}
private void init() {
this.setLayout(new BorderLayout());
UITabbedPane tabbedPane = new UITabbedPane();
//回收站内容
JPanel recyclePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
UIScrollPane recycleScrollPane = patchScroll(recyclePane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Vcs_Recycle_Content"), recycleScrollPane);
recyclePane.add(new RecyclePane());
//通用设置
JPanel settingPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
UIScrollPane settingScrollPane = patchScroll(settingPane);
tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Carton_General_Settings"), settingScrollPane);
settingPane.add(createSchedulePane());
this.add(tabbedPane, BorderLayout.CENTER);
}
private JPanel createSchedulePane() {
JPanel schedulePane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 0);
JPanel spinnerPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
JPanel buttonPane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane_First0();
spinnerPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Recycle_Schedule")));
spinner = new UISpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
spinner.setValue(VcsConfig.getInstance().getV2CleanRecycleInterval());
spinnerPane.add(spinner);
spinnerPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Recycle_Schedule_Day")));
schedulePane.add(spinnerPane);
button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Save"));
initButtonListener();
buttonPane.add(button);
schedulePane.add(buttonPane);
return schedulePane;
}
private void initButtonListener() {
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
VcsRecycleSettingHelper.updateJob((int) spinner.getValue());
}
});
}
private UIScrollPane patchScroll(JPanel generalPane) {
UIScrollPane generalPanelWithScroll = new UIScrollPane(generalPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
generalPanelWithScroll.setBorder(new EmptyBorder(0, 0, 0, 0));
return generalPanelWithScroll;
}
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Vcs_Recycle");
}
}

32
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/ToolTipTableCellRenderer.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.general.GeneralUtils;
import com.fr.stable.StringUtils;
import javax.swing.JTable;
import javax.swing.JLabel;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.*;
/**
* 带ToolTip的UILabel的表格渲染类
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/21
*/
public class ToolTipTableCellRenderer extends DefaultTableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if(component instanceof JLabel) {
String toolTipText = GeneralUtils.objectToString(value);
if (StringUtils.isNotEmpty(toolTipText)) {
((JLabel) component).setToolTipText(toolTipText);
}
}
return component;
}
}

59
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntEditor.java

@ -0,0 +1,59 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.editor.editor.IntegerEditor;
import com.fr.design.gui.itextfield.UIIntNumberField;
import com.fr.design.gui.itextfield.UINumberField;
import com.fr.stable.StringUtils;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
/**
* 正整数输入框
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/25
*/
public class UIPositiveIntEditor extends IntegerEditor {
private static final int DEFAULT_COLUMNS = 4;
private static final int MIN = 1;
private static final int MAX = 99999;
private static final int DEFAULT_VALUE = 60;
public UIPositiveIntEditor(Integer value) {
super(value);
numberField.setMaxValue(MAX);
numberField.setMinValue(MIN);
initNumberFieldListener();
}
public UIPositiveIntEditor(Integer value, Integer min, Integer max) {
super(value);
numberField.setMaxValue(max);
numberField.setMinValue(min);
initNumberFieldListener();
}
private void initNumberFieldListener() {
numberField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
if (StringUtils.isEmpty(numberField.getTextValue())) {
numberField.setValue(DEFAULT_VALUE);
}
}
});
}
@Override
protected UINumberField createNumberField() {
UIIntNumberField field = new UIIntNumberField();
field.setColumns(DEFAULT_COLUMNS);
return field;
}
}

39
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/UIPositiveIntSpinner.java

@ -0,0 +1,39 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.itextfield.UIIntNumberField;
import com.fr.design.gui.itextfield.UINumberField;
/**
* 只允许输入正整数的Spinner
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/25
*/
public class UIPositiveIntSpinner extends UISpinner {
private static final int DEFAULT_COLUMNS = 5;
public UIPositiveIntSpinner() {
}
public UIPositiveIntSpinner(double minValue, double maxValue, double dierta) {
super(minValue, maxValue, dierta);
}
public UIPositiveIntSpinner(double minValue, double maxValue, double dierta, double defaultValue) {
super(minValue, maxValue, dierta, defaultValue);
}
public UIPositiveIntSpinner(double minValue, double maxValue, double dierta, double defaultValue, boolean fillNegativeNumber) {
super(minValue, maxValue, dierta, defaultValue, fillNegativeNumber);
}
@Override
protected UINumberField initNumberField() {
UIIntNumberField field = new UIIntNumberField();
field.setColumns(DEFAULT_COLUMNS);
return field;
}
}

156
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsBatchProcessDetailPane.java

@ -0,0 +1,156 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 处理结果详细面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/19
*/
public class VcsBatchProcessDetailPane {
private UILabel message = new UILabel();
private UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK"));
private UILabel uiLabel = new UILabel();
private UILabel directUiLabel = new UILabel();
private UILabel detailLabel = new UILabel();
private JPanel upPane;
private JPanel midPane;
private JPanel downPane;
private JPanel hiddenPanel;
private JTextArea jta;
private JDialog dialog;
public static final Dimension DEFAULT = new Dimension(380, 150);
public static final Dimension DEFAULT_PRO = new Dimension(380, 270);
public VcsBatchProcessDetailPane(Frame parent, String title, String msg) {
init(parent, title, msg);
}
private void init(Frame parent, String title, String msg) {
message.setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 0));
message.setText(msg);
dialog = new JDialog(parent, title, true);
dialog.setSize(DEFAULT);
JPanel jp = new JPanel();
initUpPane();
initDownPane();
initMidPane();
initHiddenPanel();
initListener();
jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
jp.add(upPane);
jp.add(midPane);
jp.add(hiddenPanel);
jp.add(downPane);
hiddenPanel.setVisible(false);
dialog.add(jp);
dialog.setResizable(false);
dialog.setLocationRelativeTo(SwingUtilities.getWindowAncestor(parent));
}
private void initDownPane() {
downPane = new JPanel();
downPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 9));
downPane.add(cancelButton);
}
private void initUpPane() {
upPane = new JPanel();
uiLabel = new UILabel(UIManager.getIcon("OptionPane.errorIcon"));
upPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
upPane.add(uiLabel);
upPane.add(message);
}
private void initMidPane() {
midPane = new JPanel();
midPane.add(directUiLabel);
midPane.add(detailLabel);
midPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
detailLabel.setForeground(Color.BLUE);
detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
}
private void initHiddenPanel() {
hiddenPanel = new JPanel();
hiddenPanel.setLayout(new BorderLayout(2, 0));
hiddenPanel.add(new JPanel(), BorderLayout.WEST);
hiddenPanel.add(new JPanel(), BorderLayout.EAST);
JPanel borderPanel = new JPanel();
borderPanel.setLayout(new BorderLayout());
jta = new JTextArea();
JScrollPane jsp = new JScrollPane(jta);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jta.setEditable(false);
borderPanel.add(jsp, BorderLayout.CENTER);
hiddenPanel.add(borderPanel);
}
/**
* 补充更详细的报错信息
*
* @param message 信息
*/
public void updateDetailArea(String message) {
jta.append(message + "\n");
}
private void initListener() {
detailLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (hiddenPanel.isVisible()) {
hiddenPanel.setVisible(false);
dialog.setSize(DEFAULT);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
} else {
dialog.setSize(DEFAULT_PRO);
hiddenPanel.setVisible(true);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down"));
}
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hiddenPanel.removeAll();
dialog.dispose();
}
});
}
/**
* 显示面板
*/
public void show() {
dialog.setVisible(true);
}
}

35
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellEditor.java

@ -0,0 +1,35 @@
package com.fr.design.mainframe.vcs.ui;
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import java.awt.*;
import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFAULT_SELECT_TABLE_ROW_COLOR;
/**
* Vcs的表格Editor
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/20
*/
public class VcsCellEditor extends AbstractCellEditor implements TableCellEditor {
private final VcsOperatorPane vcsPanel;
public VcsCellEditor(VcsOperatorPane vcsPanel) {
this.vcsPanel = vcsPanel;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
vcsPanel.setBackground(isSelected ? DEFAULT_SELECT_TABLE_ROW_COLOR : Color.WHITE);
return vcsPanel;
}
@Override
public Object getCellEditorValue() {
return vcsPanel;
}
}

29
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCellRender.java

@ -0,0 +1,29 @@
package com.fr.design.mainframe.vcs.ui;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFAULT_SELECT_TABLE_ROW_COLOR;
/**
* Vcs的表格Render
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/20
*/
public class VcsCellRender implements TableCellRenderer {
private final VcsOperatorPane vcsPanel;
public VcsCellRender(VcsOperatorPane vcsPanel) {
this.vcsPanel = vcsPanel;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
vcsPanel.setBackground(isSelected ? DEFAULT_SELECT_TABLE_ROW_COLOR : Color.WHITE);
return vcsPanel;
}
}

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

@ -2,11 +2,12 @@ package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils; import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane; import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.VcsService; import com.fr.design.mainframe.vcs.VcsOperatorWorker;
import com.fr.design.mainframe.vcs.VcsTableEntity; import com.fr.design.mainframe.vcs.VcsTableEntity;
import com.fr.file.FileNodeFILE; import com.fr.file.FileNodeFILE;
@ -83,8 +84,11 @@ public class VcsCenterPane extends VcsNewPane {
@Override @Override
public VcsOperatorPane createOperatorPane() { public VcsOperatorPane createOperatorPane() {
manager = new UILabel(MANAGER_ICON); manager = new UILabel(MANAGER_ICON);
manager.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Manager"));
open = new UILabel(OPEN_ICON); open = new UILabel(OPEN_ICON);
open.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Open"));
delete = new UILabel(DELETE_ICON); delete = new UILabel(DELETE_ICON);
delete.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Delete"));
initManagerListener(); initManagerListener();
initOpenListener(); initOpenListener();
initDeleteListener(); initDeleteListener();
@ -111,7 +115,10 @@ public class VcsCenterPane extends VcsNewPane {
JOptionPane.OK_CANCEL_OPTION, JOptionPane.OK_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE); JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) { if (selVal == JOptionPane.YES_OPTION) {
VcsService.getInstance().deleteEntity(entity); VcsOperatorWorker.createDeleteWorker().doDelete(entity);
removeTarget((VcsTableEntity) o);
model.getList().remove(o);
model.fireTableDataChanged();
} }
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(fileName), false))); DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(fileName), false)));
} }
@ -119,6 +126,12 @@ public class VcsCenterPane extends VcsNewPane {
}); });
} }
@Override
protected boolean needIcon4Head(int col) {
return col != 0 && col != OPERATOR_COL;
}
private void initOpenListener() { private void initOpenListener() {
open.addMouseListener(new MouseAdapter() { open.addMouseListener(new MouseAdapter() {
@Override @Override
@ -127,6 +140,7 @@ public class VcsCenterPane extends VcsNewPane {
Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn()); Object o = table.getValueAt(table.getEditingRow(), table.getEditingColumn());
if (o instanceof VcsTableEntity) { if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity(); VcsEntity entity = ((VcsTableEntity) o).getEntity();
saveSettingAndCloseDialog();
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(entity.getFilename()), false))); DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(getTemplateTruePath(entity.getFilename()), false)));
} }
} }
@ -147,8 +161,7 @@ public class VcsCenterPane extends VcsNewPane {
return entity.getFilename()+Toolkit.i18nText("Fine-Design_Vcs_Version_Tips"); return entity.getFilename()+Toolkit.i18nText("Fine-Design_Vcs_Version_Tips");
} }
}; };
BasicDialog dialog = pane.showWindow(DesignerContext.getDesignerFrame(), false); pane.showDialog(getDialog());
dialog.setVisible(true);
} }
} }
}); });
@ -161,9 +174,21 @@ public class VcsCenterPane extends VcsNewPane {
for (VcsEntity entity : entities) { for (VcsEntity entity : entities) {
tableEntities.add(new VcsTableEntity(entity)); tableEntities.add(new VcsTableEntity(entity));
} }
updateTableList(tableEntities);
return tableEntities; return tableEntities;
} }
@Override
protected void initDialogListener(BasicDialog dialog) {
dialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
getParentDialog().doOK();
getParentDialog().dispose();
}
});
}
@Override @Override
protected String title4PopupWindow() { protected String title4PopupWindow() {
return TITLE; return TITLE;
@ -189,4 +214,14 @@ public class VcsCenterPane extends VcsNewPane {
protected boolean isNeedRestore() { protected boolean isNeedRestore() {
return false; return false;
} }
@Override
protected boolean isNeedSearch() {
return true;
}
@Override
protected boolean isNeedDeleteAllVersion() {
return true;
}
} }

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

@ -5,6 +5,7 @@ import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
@ -14,8 +15,11 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.vcs.VcsExceptionUtils;
import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.utils.DesignUtils; import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.ThemeUtils;
import com.fr.design.widget.FRWidgetFactory; import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.FRFont; import com.fr.general.FRFont;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
@ -25,6 +29,7 @@ import com.fr.workspace.server.vcs.v2.move.VcsMoveStrategy;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.ButtonGroup; import javax.swing.ButtonGroup;
import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JProgressBar; import javax.swing.JProgressBar;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
@ -37,6 +42,9 @@ import java.awt.event.MouseEvent;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import static javax.swing.JOptionPane.YES_NO_CANCEL_OPTION;
import static javax.swing.JOptionPane.YES_OPTION;
/** /**
* 迁移面板 * 迁移面板
@ -75,6 +83,8 @@ public class VcsMovePanel extends BasicPane {
public static final String FAILED = "FAILED"; public static final String FAILED = "FAILED";
public static boolean moving = false; public static boolean moving = false;
private BasicDialog parentDialog;
private UILabel vcsUpdateExistLabel = new UILabel(); private UILabel vcsUpdateExistLabel = new UILabel();
private UILabel vcsUpdateFireLabel = new UILabel(); private UILabel vcsUpdateFireLabel = new UILabel();
@ -103,7 +113,7 @@ public class VcsMovePanel extends BasicPane {
//全部放弃 //全部放弃
private UIRadioButton moveNothingButton; private UIRadioButton moveNothingButton;
private UISpinner spinner; private UIPositiveIntSpinner spinner;
private MoveCallBack callBack; private MoveCallBack callBack;
@ -112,11 +122,12 @@ public class VcsMovePanel extends BasicPane {
private boolean visible = false; private boolean visible = false;
public VcsMovePanel(CardLayout cardLayout, JPanel parentPane, MoveCallBack callBack) { public VcsMovePanel(CardLayout cardLayout, JPanel parentPane, MoveCallBack callBack, BasicDialog parentDialog) {
this.parentCard = cardLayout; this.parentCard = cardLayout;
this.parentPane = parentPane; this.parentPane = parentPane;
this.callBack = callBack; this.callBack = callBack;
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
this.parentDialog = parentDialog;
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0)); updatePane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));
//初始化顶部的面板 //初始化顶部的面板
@ -197,8 +208,14 @@ public class VcsMovePanel extends BasicPane {
private void initTipDesc() { private void initTipDesc() {
UILabel descLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Desc")); UILabel descLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Desc"));
UILabel firstLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tips_First"));
UILabel secondLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tips_Second"));
descLabel.setForeground(TIP_COLOR); descLabel.setForeground(TIP_COLOR);
firstLabel.setForeground(TIP_COLOR);
secondLabel.setForeground(TIP_COLOR);
choosePane.add(descLabel); choosePane.add(descLabel);
choosePane.add(firstLabel);
choosePane.add(secondLabel);
} }
private void initRadioButton() { private void initRadioButton() {
@ -222,7 +239,7 @@ public class VcsMovePanel extends BasicPane {
moveAllPane.add(moveAllButton); moveAllPane.add(moveAllButton);
moveDefaultPanel.add(moveDefaultButton); moveDefaultPanel.add(moveDefaultButton);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Left"))); moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Left")));
spinner = new UISpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE); spinner = new UIPositiveIntSpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
moveDefaultPanel.add(spinner); moveDefaultPanel.add(spinner);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Right"))); moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Right")));
moveNothingPane.add(moveNothingButton); moveNothingPane.add(moveNothingButton);
@ -232,7 +249,9 @@ public class VcsMovePanel extends BasicPane {
} }
private void initVcsLabel(JPanel parent) { private void initVcsLabel(JPanel parent) {
parent.removeAll();
if (!VcsHelper.getInstance().isLegacyMode()) { if (!VcsHelper.getInstance().isLegacyMode()) {
parent.setBackground(ThemeUtils.BACK_COLOR);
centerButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center")); centerButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center"));
parent.add(centerButton); parent.add(centerButton);
initVcsCenterListener(); initVcsCenterListener();
@ -253,9 +272,7 @@ public class VcsMovePanel extends BasicPane {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
VcsCenterPane vcsCenterPane = new VcsCenterPane(); VcsCenterPane vcsCenterPane = new VcsCenterPane();
BasicDialog dialog = vcsCenterPane.showWindow(DesignerContext.getDesignerFrame(), false); vcsCenterPane.showDialog(parentDialog);
dialog.setVisible(true);
} }
}); });
} }
@ -267,23 +284,48 @@ public class VcsMovePanel extends BasicPane {
BasicDialog dlg = choosePane.showMediumWindow(SwingUtilities.getWindowAncestor(VcsMovePanel.this), new DialogActionAdapter() { BasicDialog dlg = choosePane.showMediumWindow(SwingUtilities.getWindowAncestor(VcsMovePanel.this), new DialogActionAdapter() {
@Override @Override
public void doOk() { public void doOk() {
createConfirmPane();
}
});
dlg.setVisible(true);
}
});
}
private void createConfirmPane() {
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP);
layout.setAlignLeft(true);
JPanel panel = new JPanel();
panel.setLayout(layout);
UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tip_Title"));
UILabel firstLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tip_First"));
UILabel secondLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Tip_Second"));
titleLabel.setForeground(TIP_COLOR);
firstLabel.setForeground(TIP_COLOR);
secondLabel.setForeground(TIP_COLOR);
panel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Right_Now")));
panel.add(titleLabel);
panel.add(firstLabel);
panel.add(secondLabel);
int value = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), panel, Toolkit.i18nText("Fine-Design_Vcs_Move_Title"), JOptionPane.YES_NO_OPTION);
processMove(value);
}
private void processMove(int value) {
if (value == YES_OPTION) {
//进度条面板 //进度条面板
initProcessPane(); initProcessPane();
VcsMovePanel.this.getParentCard().next(getParentPane()); VcsMovePanel.this.getParentCard().next(getParentPane());
VcsMoveStrategy strategy; VcsMoveStrategy strategy;
if (moveDefaultButton.isSelected()) { if (moveDefaultButton.isSelected()) {
strategy = VcsMoveStrategy.createNumStrategy((int) spinner.getValue()); strategy = VcsMoveStrategy.createStrategy((int) spinner.getValue());
} else if (moveNothingButton.isSelected()) { } else if (moveNothingButton.isSelected()) {
strategy = VcsMoveStrategy.ALL_GIVE_UP; strategy = VcsMoveStrategy.createStrategy(0);
} else { } else {
strategy = VcsMoveStrategy.ALL_RETAIN; strategy = VcsMoveStrategy.createStrategy(Integer.MAX_VALUE);
} }
new MoveWorker(strategy).execute(); new MoveWorker(strategy).execute();
} }
});
dlg.setVisible(true);
}
});
} }
private void initSuccessPane() { private void initSuccessPane() {
@ -318,15 +360,19 @@ public class VcsMovePanel extends BasicPane {
private void doAfterMove() { private void doAfterMove() {
visible = !VcsHelper.getInstance().isLegacyMode(); visible = !VcsHelper.getInstance().isLegacyMode();
if (visible) { initVcsLabel(updatePane);
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(); updatePane.setVisible(visible);
updatePane.add(new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center")));
}
updatePane.setVisible(!visible);
callBack.doCallBack(visible); callBack.doCallBack(visible);
parentCard.show(parentPane, SETTING); parentCard.show(parentPane, SETTING);
} }
public BasicDialog getParentDialog() {
return parentDialog;
}
public void setParentDialog(BasicDialog parentDialog) {
this.parentDialog = parentDialog;
}
@Override @Override
protected String title4PopupWindow() { protected String title4PopupWindow() {
@ -341,7 +387,7 @@ public class VcsMovePanel extends BasicPane {
return parentPane; return parentPane;
} }
private void initFailedPane() { private void initFailedPane(String detail) {
JPanel failedPane = new JPanel(); JPanel failedPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane(); JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
failedButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Go")); failedButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Go"));
@ -349,7 +395,7 @@ public class VcsMovePanel extends BasicPane {
failedIconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_failed.svg")); failedIconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_failed.svg"));
failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed")); failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed"));
failedLabel.setFont(FONT); failedLabel.setFont(FONT);
failedTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Tip")); failedTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Tip", detail));
initStatusPane(failedTipLabel, failedIconLabel, failedLabel, failedButton, body, FAILED, failedPane); initStatusPane(failedTipLabel, failedIconLabel, failedLabel, failedButton, body, FAILED, failedPane);
} }
@ -372,16 +418,17 @@ public class VcsMovePanel extends BasicPane {
} }
private class MoveWorker extends SwingWorker<Void, Integer> { private class MoveWorker extends SwingWorker<Boolean, Integer> {
private VcsMoveStrategy strategy; private VcsMoveStrategy strategy;
private String detail = StringUtils.EMPTY;
public MoveWorker(VcsMoveStrategy strategy) { public MoveWorker(VcsMoveStrategy strategy) {
this.strategy = strategy; this.strategy = strategy;
} }
@Override @Override
protected Void doInBackground() throws Exception { protected Boolean doInBackground() throws Exception {
try { try {
//开始迁移 //开始迁移
VcsMoveService.getInstance().startMove(new VcsMoveService.BaseMoveServiceWhileMoving() { VcsMoveService.getInstance().startMove(new VcsMoveService.BaseMoveServiceWhileMoving() {
@ -396,13 +443,11 @@ public class VcsMovePanel extends BasicPane {
} }
}, strategy); }, strategy);
} catch (Exception e) { } catch (Exception e) {
this.cancel(true);
VcsMoveService.getInstance().stopMoving(); VcsMoveService.getInstance().stopMoving();
initFailedPane(); detail = VcsExceptionUtils.createDetailByException(e);
VcsMovePanel.this.getParentCard().show(getParentPane(), FAILED); return false;
FineLoggerFactory.getLogger().error("[VcsV2] Vcs move failed!");
} }
return null; return true;
} }
@Override @Override
@ -413,12 +458,22 @@ public class VcsMovePanel extends BasicPane {
@Override @Override
protected void done() { protected void done() {
VcsMoveService.getInstance().stopMoving(); VcsMoveService.getInstance().stopMoving();
try {
if (get()) {
initSuccessPane(); initSuccessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), SUCCESS); VcsMovePanel.this.getParentCard().show(getParentPane(), SUCCESS);
VcsHelper.getInstance().updateLegacyMode(); VcsHelper.getInstance().updateLegacyMode();
DesignerFrameFileDealerPane.getInstance().refreshDockingView();
} else {
initFailedPane(detail);
VcsMovePanel.this.getParentCard().show(getParentPane(), FAILED);
FineLoggerFactory.getLogger().error("[VcsV2] Vcs move failed!");
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
} }
} }
/** /**
* 迁移回调事件 * 迁移回调事件

54
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovingExitOption.java

@ -0,0 +1,54 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.workspace.server.vcs.v2.move.VcsMoveService;
import javax.swing.JOptionPane;
/**
* 版本管理迁移检查
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/18
*/
public class VcsMovingExitOption {
/**
* 关闭前的检查
*
* @return
*/
public static boolean ShowDialogAndConfirmExit() {
return showDialogAndChoose(Toolkit.i18nText("Fine-Design_Vcs_Close_Tips"));
}
/**
* 切换环境前的检查
*
* @return
*/
public static boolean ShowDialogAndConfirmSwitch() {
return showDialogAndChoose(Toolkit.i18nText("Fine-Design_Vcs_Switch_Tips"));
}
private static boolean showDialogAndChoose(String msg) {
if (VcsMoveService.getInstance().isMoving()) {
int result = FineJOptionPane.showConfirmDialog(
DesignerContext.getDesignerFrame(),
msg,
Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
FineJOptionPane.YES_NO_OPTION
);
return result == JOptionPane.YES_OPTION;
}
return true;
}
}

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

@ -9,7 +9,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.vcs.TableValueOperator; import com.fr.design.mainframe.vcs.TableValueOperator;
import com.fr.design.mainframe.vcs.VcsService; import com.fr.design.mainframe.vcs.VcsOperatorWorker;
import com.fr.design.mainframe.vcs.VcsTableEntity; import com.fr.design.mainframe.vcs.VcsTableEntity;
import com.fr.design.mainframe.vcs.common.VcsCacheFileNodeFile; import com.fr.design.mainframe.vcs.common.VcsCacheFileNodeFile;
import com.fr.design.mainframe.vcs.common.VcsHelper; import com.fr.design.mainframe.vcs.common.VcsHelper;
@ -111,8 +111,9 @@ public class VcsNewPane extends RecyclePane {
} }
}; };
this.operatorPane = createOperatorPane(); this.operatorPane = createOperatorPane();
this.model.setDefaultEditor(VcsOperatorPane.class, operatorPane); this.model.setDefaultEditor(VcsOperatorPane.class, new VcsCellEditor(createOperatorPane()));
this.model.setDefaultRenderer(VcsOperatorPane.class, operatorPane); this.model.setDefaultRenderer(VcsOperatorPane.class, new VcsCellRender(createOperatorPane()));
this.model.setDefaultRenderer(UILabel.class, new ToolTipTableCellRenderer());
} }
@ -128,8 +129,11 @@ public class VcsNewPane extends RecyclePane {
*/ */
public VcsOperatorPane createOperatorPane() { public VcsOperatorPane createOperatorPane() {
restore = new UILabel(RESTORE_ICON); restore = new UILabel(RESTORE_ICON);
restore.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Restore"));
delete = new UILabel(DELETE_ICON); delete = new UILabel(DELETE_ICON);
delete.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Delete"));
preview = new UILabel(PREVIEW_ICON); preview = new UILabel(PREVIEW_ICON);
preview.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_ToolTip_Preview"));
initPreviewListener(); initPreviewListener();
initDeleteListener(); initDeleteListener();
initRestoreListener(); initRestoreListener();
@ -156,6 +160,7 @@ public class VcsNewPane extends RecyclePane {
JOptionPane.QUESTION_MESSAGE); JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) { if (selVal == JOptionPane.YES_OPTION) {
restoreEntity(entity); restoreEntity(entity);
VcsNewPane.this.saveSettingAndCloseDialog();
} }
} }
} }
@ -209,7 +214,7 @@ public class VcsNewPane extends RecyclePane {
if (selVal == JOptionPane.YES_OPTION) { if (selVal == JOptionPane.YES_OPTION) {
model.getList().remove(o); model.getList().remove(o);
model.fireTableDataChanged(); model.fireTableDataChanged();
VcsService.getInstance().deleteEntity(entity.getFilename(), entity.getVersion()); VcsOperatorWorker.createDeleteWorker().deleteTargetVersion(entity);
} }
} }
} }
@ -225,6 +230,7 @@ public class VcsNewPane extends RecyclePane {
if (o instanceof VcsTableEntity) { if (o instanceof VcsTableEntity) {
VcsEntity entity = ((VcsTableEntity) o).getEntity(); VcsEntity entity = ((VcsTableEntity) o).getEntity();
previewEntity(entity); previewEntity(entity);
VcsNewPane.this.saveSettingAndCloseDialog();
} }
} }
}); });
@ -329,11 +335,16 @@ public class VcsNewPane extends RecyclePane {
@Override @Override
public void doOK() { public void doOK() {
entity.setCommitMsg(getMsgTestArea().getText()); entity.setCommitMsg(getMsgTestArea().getText());
VcsService.getInstance().updateEntityAnnotation(entity); VcsOperatorWorker.createUpdateWorker().updateEntityAnnotation(entity);
setVisible(false); setVisible(false);
model.fireTableDataChanged(); model.fireTableDataChanged();
} }
}; };
dialog.setVisible(true); dialog.setVisible(true);
} }
@Override
protected boolean needIcon4Head(int col) {
return col != 0 && col != OPERATOR_COL;
}
} }

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

@ -3,20 +3,15 @@ package com.fr.design.mainframe.vcs.ui;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.AbstractCellEditor;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.*; import java.awt.*;
import java.util.List;
import java.util.List;
import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFAULT_SELECT_TABLE_ROW_COLOR;
/** /**
* 操作面板用于置放常用的操作label * 操作面板用于置放常用的操作label
@ -27,37 +22,19 @@ import static com.fr.design.mainframe.vcs.ui.AbstractSupportSelectTablePane.DEFA
* @since 11.0 * @since 11.0
* Created on 2023/7/13 * Created on 2023/7/13
*/ */
public class VcsOperatorPane extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { public class VcsOperatorPane extends JPanel {
private JPanel contentPane;
private static final Color DETAIL_FONT_COLOR = new Color(65, 155, 249);
public VcsOperatorPane(List<JComponent> iconJComponentMap) { public VcsOperatorPane(List<JComponent> iconJComponentMap) {
init(iconJComponentMap); init(iconJComponentMap);
} }
private void init(List<JComponent> iconJComponentMap) { private void init(List<JComponent> iconJComponentMap) {
contentPane = new JPanel(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout()); this.setLayout(FRGUIPaneFactory.createLeftZeroVgapNormalHgapLayout());
for (JComponent value : iconJComponentMap) { for (JComponent value : iconJComponentMap) {
value.setForeground(DETAIL_FONT_COLOR);
value.setCursor(new Cursor(Cursor.HAND_CURSOR)); value.setCursor(new Cursor(Cursor.HAND_CURSOR));
contentPane.add(value); this.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;
}
} }

81
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsProgressDialog.java

@ -0,0 +1,81 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.iprogressbar.ModernUIProgressBarUI;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.stable.StringUtils;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import static java.awt.Component.CENTER_ALIGNMENT;
/**
* Vcs操作进度条面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/7/18
*/
public class VcsProgressDialog{
private JProgressBar progressBar = new JProgressBar();
private UILabel tipLabel;
private BasicPane processPane;
private BasicDialog dialog;
public VcsProgressDialog(String title, String dealingStr) {
processPane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return title;
}
};
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
progressBar.setStringPainted(true);
progressBar.setUI(new ModernUIProgressBarUI());
progressBar.setBorderPainted(false);
progressBar.setOpaque(false);
progressBar.setBorder(null);
progressBar.setSize(BasicDialog.MEDIUM);
progressBar.setValue(0);
body.add(progressBar);
body.add(new UILabel(StringUtils.BLANK));
tipLabel = new UILabel(dealingStr);
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
body.add(tipLabel);
processPane.add(body);
processPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
}
/**
* 展示面板
*
*/
public void showDialog() {
dialog = processPane.showSmallWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
/**
* 关闭面板
*
*/
public void closeDialog() {
dialog.setVisible(false);
}
public JProgressBar getProgressBar() {
return progressBar;
}
public void setProgressBar(JProgressBar progressBar) {
this.progressBar = progressBar;
}
}

4
designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_sort_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 fill-rule="evenodd" clip-rule="evenodd" d="M14.2462 6.17654C14.3492 6.30778 14.2557 6.5 14.0889 6.5H11.9999V13.9768C11.9999 14.0873 11.9104 14.1768 11.7999 14.1768H11.1999C11.0895 14.1768 10.9999 14.0873 10.9999 13.9768V6.5H8.91119C8.74436 6.5 8.65086 6.30779 8.75384 6.17654L11.3426 2.87732C11.4227 2.77527 11.5772 2.77527 11.6573 2.87731L14.2462 6.17654Z" fill="#333334"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.04297 10.801C2.93999 10.6698 3.03349 10.4775 3.20032 10.4775H5.28927V3.00074C5.28927 2.89028 5.37881 2.80074 5.48927 2.80074H6.08927C6.19972 2.80074 6.28927 2.89028 6.28927 3.00074V10.4775H8.378C8.54482 10.4775 8.63832 10.6698 8.53534 10.801L5.94661 14.1002C5.86653 14.2023 5.712 14.2023 5.63192 14.1002L3.04297 10.801Z" fill="#333334"/>
</svg>

After

Width:  |  Height:  |  Size: 874 B

27
designer-form/src/main/java/com/fr/design/designer/creator/XEditorHolder.java

@ -44,9 +44,7 @@ public class XEditorHolder extends XWidgetCreator {
ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this);
editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter);
Rectangle rect = this.getBounds(); Rectangle rect = this.getBounds();
int min = rect.x + rect.width / 2 - editingMouseListener.getMinMoveSize(); if (checkMouseEditRangeValid(e, rect, editingMouseListener)) {
int max = rect.x + rect.width / 2 + editingMouseListener.getMinMoveSize();
if (e.getX() > min && e.getX() < max) {
ToolTipEditor.getInstance().showToolTip((XEditorHolder) this, e.getXOnScreen(), ToolTipEditor.getInstance().showToolTip((XEditorHolder) this, e.getXOnScreen(),
e.getYOnScreen()); e.getYOnScreen());
} }
@ -54,6 +52,29 @@ public class XEditorHolder extends XWidgetCreator {
} }
} }
/**
* 判断当前鼠标事件是否在可编辑区域内
*
* @param e 鼠标事件
* @param rect 区域
* @param editingMouseListener 位置处理器
* @return 是否位于可编辑区
*/
private boolean checkMouseEditRangeValid(MouseEvent e, Rectangle rect, EditingMouseListener editingMouseListener) {
int horizontalValue = editingMouseListener.getDesigner().getHorizontalScaleValue();
int verticalValue = editingMouseListener.getDesigner().getVerticalScaleValue();
int minMoveSize = editingMouseListener.getMinMoveSize();
int minHorizontal = rect.x + rect.width / 2 - minMoveSize - horizontalValue;
int maxHorizontal = rect.x + rect.width / 2 + minMoveSize - horizontalValue;
int minVertical = rect.y + rect.height / 2 - minMoveSize - verticalValue;
int maxVertical = rect.y + rect.height / 2 + minMoveSize - verticalValue;
boolean xRangeValid = e.getX() > minHorizontal && e.getX() < maxHorizontal;
boolean yRangeValid = e.getY() > minVertical && e.getY() < maxVertical;
return xRangeValid && yRangeValid;
}
@Override @Override
protected String getIconName() { protected String getIconName() {
return "text_field_16.png"; return "text_field_16.png";

23
designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java

@ -279,9 +279,7 @@ public class EditingMouseListener extends MouseInputAdapter {
if (component instanceof XEditorHolder) { if (component instanceof XEditorHolder) {
XEditorHolder xcreator = (XEditorHolder) component; XEditorHolder xcreator = (XEditorHolder) component;
Rectangle rect = xcreator.getBounds(); Rectangle rect = xcreator.getBounds();
int min = rect.x + rect.width / 2 - minMoveSize; if (checkCreatorRangeValid(e, rect)) {
int max = rect.x + rect.width / 2 + minMoveSize;
if (e.getX() > min && e.getX() < max) {
if (designer.getCursor().getType() != Cursor.HAND_CURSOR) { if (designer.getCursor().getType() != Cursor.HAND_CURSOR) {
designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
} }
@ -673,8 +671,8 @@ public class EditingMouseListener extends MouseInputAdapter {
currentEditor = designerEditor; currentEditor = designerEditor;
currentXCreator = creator; currentXCreator = creator;
Rectangle bounds = new Rectangle(1, 1, creator.getWidth() - 2, creator.getHeight() - 2); Rectangle bounds = new Rectangle(1, 1, creator.getWidth() - 2, creator.getHeight() - 2);
bounds.x += (rect.x - designer.getArea().getHorizontalValue()); bounds.x += (rect.x - designer.getHorizontalScaleValue());
bounds.y += (rect.y - designer.getArea().getVerticalValue()); bounds.y += (rect.y - designer.getVerticalScaleValue());
designerEditor.getEditorTarget().setBounds(bounds); designerEditor.getEditorTarget().setBounds(bounds);
designer.add(designerEditor.getEditorTarget()); designer.add(designerEditor.getEditorTarget());
designer.invalidate(); designer.invalidate();
@ -747,4 +745,19 @@ public class EditingMouseListener extends MouseInputAdapter {
refreshTopXCreator(false); refreshTopXCreator(false);
} }
/**
* 判断当前鼠标移动事件是否在Creator有效范围内
*/
private boolean checkCreatorRangeValid(MouseEvent e, Rectangle rect) {
int horizontalValue = designer.getHorizontalScaleValue();
int verticalValue = designer.getVerticalScaleValue();
int minHorizontal = rect.x + rect.width / 2 - minMoveSize - horizontalValue;
int maxHorizontal = rect.x + rect.width / 2 + minMoveSize - horizontalValue;
int minVertical = rect.y + rect.height / 2 - minMoveSize - verticalValue;
int maxVertical = rect.y + rect.height / 2 + minMoveSize - verticalValue;
boolean xRangeValid = e.getX() > minHorizontal && e.getX() < maxHorizontal;
boolean yRangeValid = e.getY() > minVertical && e.getY() < maxVertical;
return xRangeValid && yRangeValid;
}
} }

2
designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java

@ -1208,7 +1208,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
} }
public XLayoutContainer getRootContainer(int y) { public XLayoutContainer getRootContainer(int y) {
XLayoutContainer container = y < paraHeight - formArea.getVerticalValue() ? paraComponent : rootComponent; XLayoutContainer container = y < paraHeight - formArea.getVerticalValue() / scale ? paraComponent : rootComponent;
if (container == null) { if (container == null) {
container = rootComponent; container = rootComponent;
} }

Loading…
Cancel
Save