Browse Source

Pull request #12457: REPORT-98345 版本管理三期 提交总体代码

Merge in DESIGN/design from ~DESTINY.LIN/design:feature/x to feature/x

* commit 'bfb3f7f31214c0ebc333a37736244d15be515a50':
  REPORT-98345 版本管理三期 修改代码规范
  REPORT-98345 版本管理三期 修改代码规范
  REPORT-98345 版本管理三期 修改线程池,修改代码规范,添加部分注释
  REPORT-98345 版本管理三期 提交总体代码
feature/x
Destiny.Lin-林锦龙 12 months ago
parent
commit
91565399b6
  1. 11
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  2. 71
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  3. 30
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  4. 31
      designer-base/src/main/java/com/fr/design/mainframe/vcs/RecycleAction.java
  5. 25
      designer-base/src/main/java/com/fr/design/mainframe/vcs/TableEntity.java
  6. 21
      designer-base/src/main/java/com/fr/design/mainframe/vcs/TableValueOperator.java
  7. 162
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsService.java
  8. 108
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsTableEntity.java
  9. 28
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java
  10. 370
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/AbstractSupportSelectTablePane.java
  11. 26
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/EditFileVersionDialog.java
  12. 266
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/RecyclePane.java
  13. 192
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsCenterPane.java
  14. 50
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java
  15. 339
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsNewPane.java
  16. 63
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsOperatorPane.java
  17. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_center_manager_normal.svg
  18. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_center_open_normal.svg
  19. 7
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_delete_normal.svg
  20. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_preview_normal.svg
  21. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_operator_restore_normal.svg
  22. 7
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_delete_disabled.svg
  23. 7
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_delete_normal.svg
  24. 8
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_normal.svg
  25. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_restore_disabled.svg
  26. 5
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_restore_normal.svg
  27. 3
      designer-base/src/main/resources/com/fr/design/standard/vcslist/vcs_recycle_search_normal.svg

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

@ -119,6 +119,7 @@ public class PreferencePane extends BasicPane {
private static final int PREFERENCE_LABEL_MAX_WIDTH = 460;
private static final int OFFSET_HEIGHT = 60;
private static final int VCS_FILL_TOTAL = 5;
private static final String TYPE = "pressed";
private static final String DISPLAY_TYPE = "+";
private static final String BACK_SLASH = "BACK_SLASH";
@ -399,9 +400,11 @@ public class PreferencePane extends BasicPane {
generalPane.add(movePanel, BorderLayout.NORTH);
JPanel savePane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Save_Setting"));
JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Clean_Setting"));
JPanel containPane = new JPanel(new GridLayout(10,1,0,8));
JPanel containPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
containPane.add(savePane);
containPane.add(vcsPane);
//填充一下面板
fillPane(containPane, VCS_FILL_TOTAL);
generalPane.add(containPane, BorderLayout.CENTER);
remindVcsLabel = new UILabel(i18nText("Fine-Design_Vcs_Remind"));
remindVcsLabel.setVisible(!VcsHelper.getInstance().needInit());
@ -458,6 +461,12 @@ public class PreferencePane extends BasicPane {
}
}
private void fillPane(JPanel containPane, int total) {
for (int i = 0; i < total; i++) {
containPane.add(new JPanel());
}
}
private VcsMovePanel createMovePane(CardLayout cardLayout, JPanel parentPane) {
return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack(){
@Override

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

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

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

@ -16,6 +16,7 @@ import com.fr.design.data.DesignTableDataManager;
import com.fr.design.data.datapane.TableDataTreePane;
import com.fr.design.data.datapane.management.search.TableDataTreeSearchManager;
import com.fr.design.data.tabledata.ResponseDataSourceChange;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.file.FileOperations;
import com.fr.design.file.FileToolbarStateChangeListener;
@ -34,8 +35,10 @@ import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager;
import com.fr.design.mainframe.manager.search.searcher.control.pane.TemplateTreeSearchToolbarPane;
import com.fr.design.mainframe.vcs.RecycleAction;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.FileVersionsPanel;
import com.fr.design.mainframe.vcs.ui.VcsNewPane;
import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef;
@ -150,6 +153,8 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private VcsAction vcsAction = new VcsAction();
private RecycleAction recycleAction = new RecycleAction();
//搜索
private SwitchAction switchAction = new SwitchAction();
private TemplateTreeSearchToolbarPane searchToolbarPane;
@ -331,7 +336,11 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_NotSupportRemote"));
}
toolbarDef.addShortCut(vcsAction);
//11.0.19及其之后加入回收站逻辑
if (!VcsHelper.getInstance().isLegacyMode()) {
recycleAction = new RecycleAction();
toolbarDef.addShortCut(recycleAction);
}
}
}
@ -492,14 +501,19 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
public void actionPerformed(ActionEvent e) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
if (VcsHelper.getInstance().isLegacyMode()) {
boolean currentEditing = isCurrentEditing(path);
// 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本)
closeOpenedTemplate(path, currentEditing);
FileVersionsPanel fileVersionTablePanel = FileVersionsPanel.getInstance();
fileVersionTablePanel.showFileVersionsPane();
stateChange();
} else {
VcsNewPane panel = new VcsNewPane(path);
BasicDialog dialog = panel.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
boolean isCurrentEditing = isCurrentEditing(path);
// 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本)
closeOpenedTemplate(path, isCurrentEditing);
FileVersionsPanel fileVersionTablePanel = FileVersionsPanel.getInstance();
fileVersionTablePanel.showFileVersionsPane();
stateChange();
}

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

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

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

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

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

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

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

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

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

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

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

@ -155,18 +155,28 @@ public class VcsHelper implements JTemplateActionListener {
}
private String getEditingFilename() {
String vcsCacheDir = VcsFileSystem.getInstance().getVcsCacheRelativePath();
JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String editingFilePath = jt.getEditingFILE().getPath();
if (editingFilePath.startsWith(ProjectConstants.REPORTLETS_NAME)) {
editingFilePath = editingFilePath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY);
} else if (editingFilePath.startsWith(vcsCacheDir)) {
editingFilePath = editingFilePath.replaceFirst(vcsCacheDir, StringUtils.EMPTY);
return dealWithFilePath(editingFilePath);
}
/**
* 处理传入的文件名使其符合Vcs规范
*
* @param filePath 文件路径
* @return 处理完的文件
*/
public String dealWithFilePath(String filePath) {
String vcsCacheDir = VcsFileSystem.getInstance().getVcsCacheRelativePath();
if (filePath.startsWith(ProjectConstants.REPORTLETS_NAME)) {
filePath = filePath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY);
} else if (filePath.startsWith(vcsCacheDir)) {
filePath = filePath.replaceFirst(vcsCacheDir, StringUtils.EMPTY);
}
if (editingFilePath.startsWith(VCS_FILE_SLASH)) {
editingFilePath = editingFilePath.substring(1);
if (filePath.startsWith(VCS_FILE_SLASH)) {
filePath = filePath.substring(1);
}
return editingFilePath;
return filePath;
}
private boolean needDeleteVersion(VcsEntity entity) {
@ -369,7 +379,7 @@ public class VcsHelper implements JTemplateActionListener {
* @return 支持返回true
*/
public boolean checkMoveFunctionSupport() {
return VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot());
return WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot();
}
/**

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

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

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

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

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

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

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

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

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

@ -13,6 +13,7 @@ import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.widget.FRWidgetFactory;
@ -22,6 +23,7 @@ import com.fr.stable.StringUtils;
import com.fr.workspace.server.vcs.v2.move.VcsMoveService;
import com.fr.workspace.server.vcs.v2.move.VcsMoveStrategy;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
@ -73,8 +75,11 @@ public class VcsMovePanel extends BasicPane {
public static final String FAILED = "FAILED";
public static boolean moving = false;
private UILabel vcsUpdateExistLabel;
private UILabel vcsUpdateFireLabel;
private UILabel vcsUpdateExistLabel = new UILabel();
private UILabel vcsUpdateFireLabel = new UILabel();
private UIButton centerButton;
private BasicPane choosePane;
private CardLayout parentCard;
private JPanel parentPane;
@ -113,8 +118,8 @@ public class VcsMovePanel extends BasicPane {
this.callBack = callBack;
this.setLayout(new BorderLayout());
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.setBackground(BACK_GROUND_COLOR);
//初始化迁移的面板
updatePane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));
//初始化顶部的面板
initVcsLabel(updatePane);
//initVcsChoosePane
initVcsChoosePane();
@ -227,13 +232,32 @@ public class VcsMovePanel extends BasicPane {
}
private void initVcsLabel(JPanel parent) {
vcsUpdateExistLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/vcs_move_icon.svg"));
vcsUpdateExistLabel.setText(Toolkit.i18nText("Fine-Design_Vcs_Can_Update"));
vcsUpdateFireLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Update"));
vcsUpdateFireLabel.setForeground(LABEL_COLOR);
vcsUpdateFireLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
parent.add(vcsUpdateExistLabel);
parent.add(vcsUpdateFireLabel);
if (!VcsHelper.getInstance().isLegacyMode()) {
centerButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center"));
parent.add(centerButton);
initVcsCenterListener();
} else {
parent.setBackground(BACK_GROUND_COLOR);
vcsUpdateExistLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/vcs_move_icon.svg"));
vcsUpdateExistLabel.setText(Toolkit.i18nText("Fine-Design_Vcs_Can_Update"));
vcsUpdateFireLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Update"));
vcsUpdateFireLabel.setForeground(LABEL_COLOR);
vcsUpdateFireLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
parent.add(vcsUpdateExistLabel);
parent.add(vcsUpdateFireLabel);
}
}
private void initVcsCenterListener() {
centerButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
VcsCenterPane vcsCenterPane = new VcsCenterPane();
BasicDialog dialog = vcsCenterPane.showWindow(DesignerContext.getDesignerFrame(), false);
dialog.setVisible(true);
}
});
}
private void initListener() {
@ -294,6 +318,10 @@ public class VcsMovePanel extends BasicPane {
private void doAfterMove() {
visible = !VcsHelper.getInstance().isLegacyMode();
if (visible) {
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.add(new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Center")));
}
updatePane.setVisible(!visible);
callBack.doCallBack(visible);
parentCard.show(parentPane, SETTING);

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

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

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

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

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

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

After

Width:  |  Height:  |  Size: 400 B

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

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

After

Width:  |  Height:  |  Size: 523 B

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

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

After

Width:  |  Height:  |  Size: 366 B

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

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

After

Width:  |  Height:  |  Size: 929 B

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

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

After

Width:  |  Height:  |  Size: 973 B

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

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

After

Width:  |  Height:  |  Size: 342 B

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

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

After

Width:  |  Height:  |  Size: 360 B

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

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

After

Width:  |  Height:  |  Size: 706 B

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

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

After

Width:  |  Height:  |  Size: 904 B

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

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

After

Width:  |  Height:  |  Size: 890 B

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

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

After

Width:  |  Height:  |  Size: 603 B

Loading…
Cancel
Save