Browse Source

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

research/10.0
1 6 years ago
parent
commit
778263e10b
  1. 36
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  2. 49
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  3. 96
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  4. 4
      designer-base/src/main/java/com/fr/design/mainframe/template/info/TemplateInfo.java
  5. 5
      designer-base/src/main/java/com/fr/design/mainframe/template/info/TemplateInfoCollector.java
  6. 71
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsCacheFileNodeFile.java
  7. 100
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java
  8. 99
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/EditFileVersionDialog.java
  9. 74
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java
  10. 43
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellRender.java
  11. 92
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionDialog.java
  12. 21
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionFirstRowPanel.java
  13. 149
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionRowPanel.java
  14. 79
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionTable.java
  15. 200
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java
  16. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_back_normal@2x.png
  17. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete.png
  18. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete@2x.png
  19. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit.png
  20. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit@2x.png
  21. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@1x.png
  22. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@2x.png
  23. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled.png
  24. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled@2x.png
  25. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_normal@2x.png
  26. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert.png
  27. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert@2x.png
  28. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled.png
  29. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled@2x.png
  30. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_normal@2x.png
  31. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@1x.png
  32. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@2x.png
  33. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/vcs_back.png
  34. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/vcs_list.png
  35. BIN
      designer-base/src/main/resources/com/fr/design/images/vcs/vcs_save.png
  36. 28
      designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoCollectorTest.java
  37. 4
      designer-base/src/test/resources/com/fr/design/mainframe/template/info/tpl.info
  38. 45
      designer-realize/src/main/java/com/fr/start/Designer.java

36
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -130,6 +130,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private int westRegionContainerWidth = 240; private int westRegionContainerWidth = 240;
private String encryptionKey; private String encryptionKey;
private String jdkHome; private String jdkHome;
private boolean vcsEnable;
private boolean saveCommit;
private int saveInterval;
//上一次登录弹窗的时间, 为了控制一天只弹一次窗口 //上一次登录弹窗的时间, 为了控制一天只弹一次窗口
private String lastShowBBSTime; private String lastShowBBSTime;
@ -1341,6 +1346,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
} }
} }
private void readJettyPort(XMLableReader reader) { private void readJettyPort(XMLableReader reader) {
String tmpVal; String tmpVal;
if ((tmpVal = reader.getElementValue()) != null) { if ((tmpVal = reader.getElementValue()) != null) {
@ -1601,6 +1607,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.setDragPermited(reader.getAttrAsBoolean("isDragPermited", false)); this.setDragPermited(reader.getAttrAsBoolean("isDragPermited", false));
this.setUndoLimit(reader.getAttrAsInt("undoLimit", 5)); this.setUndoLimit(reader.getAttrAsInt("undoLimit", 5));
this.setDefaultStringToFormula(reader.getAttrAsBoolean("defaultStringToFormula", false)); this.setDefaultStringToFormula(reader.getAttrAsBoolean("defaultStringToFormula", false));
this.setVcsEnable(reader.getAttrAsBoolean("supportVcs", true));
this.setSaveCommit(reader.getAttrAsBoolean("saveCommit", false));
this.setSaveInterval(reader.getAttrAsInt("saveInterval", 60));
if ((tmpVal = reader.getAttrAsString("gridLineColor", null)) != null) { if ((tmpVal = reader.getAttrAsString("gridLineColor", null)) != null) {
this.setGridLineColor(new Color(Integer.parseInt(tmpVal))); this.setGridLineColor(new Color(Integer.parseInt(tmpVal)));
} }
@ -1936,6 +1945,9 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
.attr("verticalScrollBarVisible", this.isVerticalScrollBarVisible()) .attr("verticalScrollBarVisible", this.isVerticalScrollBarVisible())
.attr("horizontalScrollBarVisible", this.isHorizontalScrollBarVisible()) .attr("horizontalScrollBarVisible", this.isHorizontalScrollBarVisible())
.attr("supportCellEditorDef", this.isSupportCellEditorDef()) .attr("supportCellEditorDef", this.isSupportCellEditorDef())
.attr("supportVcs", this.isVcsEnable())
.attr("saveInterval", this.getSaveInterval())
.attr("saveCommit", this.isSaveCommit())
.attr("isDragPermited", this.isDragPermited()) .attr("isDragPermited", this.isDragPermited())
.attr("gridLineColor", this.getGridLineColor().getRGB()) .attr("gridLineColor", this.getGridLineColor().getRGB())
.attr("paginationLineColor", this.getPaginationLineColor().getRGB()) .attr("paginationLineColor", this.getPaginationLineColor().getRGB())
@ -1946,4 +1958,28 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
private void writeDesignerPushUpdateAttr(XMLPrintWriter writer) { private void writeDesignerPushUpdateAttr(XMLPrintWriter writer) {
this.designerPushUpdateConfigManager.writeXML(writer); this.designerPushUpdateConfigManager.writeXML(writer);
} }
public boolean isVcsEnable() {
return vcsEnable;
}
public void setVcsEnable(boolean vcsEnable) {
this.vcsEnable = vcsEnable;
}
public boolean isSaveCommit() {
return saveCommit;
}
public void setSaveCommit(boolean saveCommit) {
this.saveCommit = saveCommit;
}
public int getSaveInterval() {
return saveInterval;
}
public void setSaveInterval(int saveInterval) {
this.saveInterval = saveInterval;
}
} }

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

@ -41,6 +41,8 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
@ -135,6 +137,12 @@ public class PreferencePane extends BasicPane {
private UICheckBox joinProductImproveCheckBox; private UICheckBox joinProductImproveCheckBox;
private UICheckBox autoPushUpdateCheckBox; private UICheckBox autoPushUpdateCheckBox;
private UICheckBox vcsEnableCheckBox;
private UICheckBox saveCommitCheckBox;
private IntegerEditor saveIntervalEditor;
public PreferencePane() { public PreferencePane() {
this.initComponents(); this.initComponents();
} }
@ -155,6 +163,7 @@ public class PreferencePane extends BasicPane {
createEditPane(generalPane); createEditPane(generalPane);
createGuiOfGridPane(generalPane); createGuiOfGridPane(generalPane);
createColorSettingPane(generalPane); createColorSettingPane(generalPane);
createVcsSettingPane(generalPane);
// ConfPane // ConfPane
JPanel confLocationPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane(); JPanel confLocationPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane();
@ -193,6 +202,36 @@ public class PreferencePane extends BasicPane {
advancePane.add(spaceUpPane); advancePane.add(spaceUpPane);
} }
private void createVcsSettingPane(JPanel generalPane) {
JPanel vcsPane = FRGUIPaneFactory.createVerticalTitledBorderPane(Toolkit.i18nText("Fine-Design_Vcs_Title"));
generalPane.add(vcsPane);
vcsEnableCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Vcs_SaveAuto"));
saveCommitCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Vcs_No_Delete"));
saveIntervalEditor = new IntegerEditor(30);
JPanel memorySpace = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
UILabel everyLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Every"));
UILabel delayLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Delay"));
memorySpace.add(everyLabel);
memorySpace.add(saveIntervalEditor);
memorySpace.add(delayLabel);
vcsEnableCheckBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
boolean selected = vcsEnableCheckBox.isSelected();
if (selected) {
saveCommitCheckBox.setEnabled(true);
saveIntervalEditor.setEnabled(true);
} else {
saveCommitCheckBox.setEnabled(false);
saveIntervalEditor.setEnabled(false);
}
}
});
vcsPane.add(vcsEnableCheckBox);
vcsPane.add(memorySpace);
vcsPane.add(saveCommitCheckBox);
}
private void createFunctionPane(JPanel generalPane) { private void createFunctionPane(JPanel generalPane) {
JPanel functionPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Function")); JPanel functionPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preference_Function"));
generalPane.add(functionPane); generalPane.add(functionPane);
@ -542,6 +581,13 @@ public class PreferencePane extends BasicPane {
defaultStringToFormulaBox.setEnabled(false); defaultStringToFormulaBox.setEnabled(false);
defaultStringToFormulaBox.setSelected(false); defaultStringToFormulaBox.setSelected(false);
} }
vcsEnableCheckBox.setSelected(designerEnvManager.isVcsEnable());
if (!vcsEnableCheckBox.isSelected()) {
saveIntervalEditor.setEnabled(false);
saveCommitCheckBox.setEnabled(false);
}
saveIntervalEditor.setValue(designerEnvManager.getSaveInterval());
saveCommitCheckBox.setSelected(designerEnvManager.isSaveCommit());
supportCellEditorDefCheckBox.setSelected(designerEnvManager.isSupportCellEditorDef()); supportCellEditorDefCheckBox.setSelected(designerEnvManager.isSupportCellEditorDef());
@ -631,6 +677,9 @@ public class PreferencePane extends BasicPane {
designerEnvManager.setOracleSystemSpace(this.oracleSpace.isSelected()); designerEnvManager.setOracleSystemSpace(this.oracleSpace.isSelected());
designerEnvManager.setCachingTemplateLimit((int) this.cachingTemplateSpinner.getValue()); designerEnvManager.setCachingTemplateLimit((int) this.cachingTemplateSpinner.getValue());
designerEnvManager.setJoinProductImprove(this.joinProductImproveCheckBox.isSelected()); designerEnvManager.setJoinProductImprove(this.joinProductImproveCheckBox.isSelected());
designerEnvManager.setSaveInterval(this.saveIntervalEditor.getValue());
designerEnvManager.setVcsEnable(this.vcsEnableCheckBox.isSelected());
designerEnvManager.setSaveCommit(this.saveCommitCheckBox.isSelected());
if (this.autoPushUpdateCheckBox != null) { if (this.autoPushUpdateCheckBox != null) {
designerEnvManager.setAutoPushUpdateEnabled(this.autoPushUpdateCheckBox.isSelected()); designerEnvManager.setAutoPushUpdateEnabled(this.autoPushUpdateCheckBox.isSelected());
} }

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

@ -26,6 +26,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper; import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.vcs.ui.FileVersionsPanel;
import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.KeySetUtils;
import com.fr.design.menu.ShortCut; import com.fr.design.menu.ShortCut;
import com.fr.design.menu.ToolBarDef; import com.fr.design.menu.ToolBarDef;
@ -43,9 +44,12 @@ import com.fr.plugin.manage.PluginFilter;
import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEvent;
import com.fr.plugin.observer.PluginEventListener; import com.fr.plugin.observer.PluginEventListener;
import com.fr.stable.CoreConstants; import com.fr.stable.CoreConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.third.org.apache.commons.io.FilenameUtils; import com.fr.third.org.apache.commons.io.FilenameUtils;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.JDialog; import javax.swing.JDialog;
@ -111,6 +115,8 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private DelFileAction delFileAction = new DelFileAction(); private DelFileAction delFileAction = new DelFileAction();
private VcsAction vcsAction = new VcsAction();
/** /**
* 刷新 * 刷新
@ -191,7 +197,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
if (WorkContext.getCurrent().isLocal()) { if (WorkContext.getCurrent().isLocal()) {
toolbarDef.addShortCut(showInExplorerAction); toolbarDef.addShortCut(showInExplorerAction);
} }
toolbarDef.addShortCut(renameAction, delFileAction); toolbarDef.addShortCut(renameAction, delFileAction, vcsAction);
Set<ShortCut> extraShortCuts = ExtraDesignClassManager.getInstance().getExtraShortCuts(); Set<ShortCut> extraShortCuts = ExtraDesignClassManager.getInstance().getExtraShortCuts();
for (ShortCut shortCut : extraShortCuts) { for (ShortCut shortCut : extraShortCuts) {
toolbarDef.addShortCut(shortCut); toolbarDef.addShortCut(shortCut);
@ -209,6 +215,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
showInExplorerAction.setEnabled(false); showInExplorerAction.setEnabled(false);
renameAction.setEnabled(false); renameAction.setEnabled(false);
delFileAction.setEnabled(false); delFileAction.setEnabled(false);
vcsAction.setEnabled(false);
this.repaint(); this.repaint();
} }
@ -273,6 +280,62 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
} }
/**
* 版本管理
*/
private class VcsAction extends UpdateAction {
public VcsAction() {
this.setName(Toolkit.i18nText("Fine-Design_Vcs_Title"));
this.setSmallIcon(VcsHelper.VCS_LIST_PNG);
}
@Override
public void actionPerformed(ActionEvent e) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
boolean isCurrentEditing = isCurrentEditing(path);
// 如果模板正在编辑,保存后再打开版本管理
if (isCurrentEditing) {
saveCurrentEditingTemplate();
}
// 如果模板已经打开了,关掉,避免出现2个同名tab(1个是模板,1个是版本)
closeOpenedTemplate(path, isCurrentEditing);
FileVersionsPanel fileVersionTablePanel = FileVersionsPanel.getInstance();
fileVersionTablePanel.showFileVersionsPane();
}
private void closeOpenedTemplate(String path, boolean isCurrentEditing) {
for (JTemplate jTemplate : HistoryTemplateListCache.getInstance().getHistoryList()) {
if (ComparatorUtils.equals(jTemplate.getEditingFILE().getPath(), path)) {
if (isCurrentEditing) {
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
}
MutilTempalteTabPane.getInstance().closeFormat(jTemplate);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jTemplate);
return;
}
}
}
}
private void saveCurrentEditingTemplate() {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
jt.stopEditing();
jt.saveTemplate();
jt.requestFocus();
}
private boolean isCurrentEditing(String path) {
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
String editing = jt.getEditingFILE().getPath();
return ComparatorUtils.equals(editing, path);
}
/** /**
* 在系统资源管理器中打开 * 在系统资源管理器中打开
*/ */
@ -386,18 +449,45 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
newFolderAction.setEnabled(singleSelected); newFolderAction.setEnabled(singleSelected);
renameAction.setEnabled(singleSelected); renameAction.setEnabled(singleSelected);
showInExplorerAction.setEnabled(singleSelected); showInExplorerAction.setEnabled(singleSelected);
// 删除操作在至少选中一个时可用 // 删除操作在至少选中一个时可用
boolean selected = selectedPathNum > 0; boolean selected = selectedPathNum > 0;
delFileAction.setEnabled(selected); delFileAction.setEnabled(selected);
// 刷新操作始终可用 // 刷新操作始终可用
refreshTreeAction.setEnabled(true); refreshTreeAction.setEnabled(true);
handleVcsAction();
// 其他状态 // 其他状态
otherStateChange(); otherStateChange();
} }
private void handleVcsAction() {
if (!DesignerEnvManager.getEnvManager().isVcsEnable() || VcsHelper.isUnSelectedTemplate()) {
vcsAction.setEnabled(false);
return;
}
if (WorkContext.getCurrent() != null) {
if (!WorkContext.getCurrent().isLocal()) {
//当前环境为远程环境时
FileNode node = TemplateTreePane.getInstance().getTemplateFileTree().getSelectedFileNode();
if (selectedOperation.getFilePath() != null) {
if (node.getLock() != null && !ComparatorUtils.equals(node.getUserID(), node.getLock())) {
vcsAction.setEnabled(false);
} else {
vcsAction.setEnabled(true);
}
} else {
vcsAction.setEnabled(false);
}
} else {
//当前环境为本地环境时
vcsAction.setEnabled(selectedOperation.getFilePath() != null);
}
}
}
public FileOperations getSelectedOperation() { public FileOperations getSelectedOperation() {
return selectedOperation; return selectedOperation;
} }

4
designer-base/src/main/java/com/fr/design/mainframe/template/info/TemplateInfo.java

@ -102,6 +102,10 @@ class TemplateInfo implements XMLReadable, XMLWriter {
return templateID; return templateID;
} }
String getOriginID() {
return originID;
}
int getTimeConsume() { int getTimeConsume() {
return (int)consumingMap.get(ATTR_TIME_CONSUME); return (int)consumingMap.get(ATTR_TIME_CONSUME);
} }

5
designer-base/src/main/java/com/fr/design/mainframe/template/info/TemplateInfoCollector.java

@ -75,11 +75,8 @@ public class TemplateInfoCollector implements XMLReadable, XMLWriter {
TemplateInfo templateInfo; TemplateInfo templateInfo;
if (this.contains(templateID)) { if (this.contains(templateID)) {
templateInfo = templateInfoMap.get(templateID); templateInfo = templateInfoMap.get(templateID);
} else if (!this.contains(originID)) {
templateInfo = TemplateInfo.newInstance(templateID);
templateInfoMap.put(templateID, templateInfo);
} else { } else {
int originTime = templateInfoMap.get(originID).getTimeConsume(); int originTime = this.contains(originID) ? templateInfoMap.get(originID).getTimeConsume() : 0;
templateInfo = TemplateInfo.newInstance(templateID, originID, originTime); templateInfo = TemplateInfo.newInstance(templateID, originID, originTime);
templateInfoMap.put(templateID, templateInfo); templateInfoMap.put(templateID, templateInfo);
} }

71
designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsCacheFileNodeFile.java

@ -0,0 +1,71 @@
package com.fr.design.mainframe.vcs.common;
import com.fr.base.io.XMLEncryptUtils;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StableUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.resource.WorkResource;
import com.fr.workspace.resource.WorkResourceOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class VcsCacheFileNodeFile extends FileNodeFILE {
private final FileNode node;
public VcsCacheFileNodeFile(FileNode node) {
super(node);
this.node = node;
}
/**
* 和FileNodeFILE中一样只是去掉了必须以reportlets开头的限制改为vcs开头
*
* @return
* @throws Exception
*/
@Override
public InputStream asInputStream() {
if (node == null) {
return null;
}
String envPath = node.getEnvPath();
// envPath必须以vcs开头
if (!envPath.startsWith(VcsHelper.VCS_CACHE_DIR)) {
return null;
}
InputStream in = WorkContext.getCurrent().get(WorkResource.class)
.openStream(StableUtils.pathJoin(VcsHelper.VCS_CACHE_DIR, envPath.substring(VcsHelper.VCS_CACHE_DIR.length() + 1)));
return envPath.endsWith(".cpt") || envPath.endsWith(".frm")
? XMLEncryptUtils.decodeInputStream(in) : in;
}
/**
* 和FileNodeFILE中一样只是去掉了必须以reportlets开头的限制改为vcs开头
*
* @return
* @throws Exception
*/
@Override
public OutputStream asOutputStream() {
if (ComparatorUtils.equals(node, null)) {
return null;
}
String envPath = node.getEnvPath();
// envPath必须以reportLets开头
if (!envPath.startsWith(VcsHelper.VCS_CACHE_DIR)) {
return null;
}
return new WorkResourceOutputStream(StableUtils.pathJoin(VcsHelper.VCS_CACHE_DIR, envPath.substring(VcsHelper.VCS_CACHE_DIR.length() + 1)));
}
}

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

@ -0,0 +1,100 @@
package com.fr.design.mainframe.vcs.common;
import com.fr.design.DesignerEnvManager;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane;
import com.fr.design.gui.itree.filetree.TemplateFileTree;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.JTemplate;
import com.fr.general.IOUtils;
import com.fr.report.entity.VcsEntity;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import javax.swing.Icon;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.util.Date;
import static com.fr.stable.StableUtils.pathJoin;
/**
* Created by XiaXiang on 2019/4/17.
*/
public class VcsHelper {
private final static String VCS_DIR = "vcs";
public final static String VCS_CACHE_DIR = pathJoin(VCS_DIR, "cache");
private static final int MINUTE = 60 * 1000;
public final static String CURRENT_USERNAME = WorkContext.getCurrent().isLocal()
? Toolkit.i18nText("Fine-Design_Vcs_Local_User")
: WorkContext.getCurrent().getConnection().getUserName();
public final static Color TABLE_SELECT_BACKGROUND = new Color(0xD8F2FD);
public final static EmptyBorder EMPTY_BORDER = new EmptyBorder(5, 10, 0, 10);
public final static EmptyBorder EMPTY_BORDER_BOTTOM = new EmptyBorder(10, 10, 10, 10);
public final static Icon VCS_LIST_PNG = IOUtils.readIcon("/com/fr/design/images/vcs/vcs_list.png");
public final static Icon VCS_BACK_PNG = IOUtils.readIcon("/com/fr/design/images/vcs/vcs_back.png");
public final static Icon VCS_FILTER_PNG = IOUtils.readIcon("/com/fr/design/images/vcs/icon_filter@1x.png");
public final static Icon VCS_EDIT_PNG = IOUtils.readIcon("/com/fr/design/images/vcs/icon_edit.png");
public final static Icon VCS_DELETE_PNG = IOUtils.readIcon("/com/fr/design/images/vcs/icon_delete.png");
public final static Icon VCS_USER_PNG = IOUtils.readIcon("/com/fr/design/images/vcs/icon_user@1x.png");
public final static Icon VCS_REVERT = IOUtils.readIcon("/com/fr/design/images/vcs/icon_revert.png");
private static int containsFolderCounts() {
TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree();
if (fileTree.getSelectionPaths() == null) {
return 0;
}
//选择的包含文件和文件夹的数目
if (fileTree.getSelectionPaths().length == 0) {
return 0;
}
//所有的num减去模板的count,得到文件夹的count
return fileTree.getSelectionPaths().length - fileTree.getSelectedTemplatePaths().length;
}
private static int selectedTemplateCounts() {
TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree();
if (fileTree.getSelectionPaths() == null) {
return 0;
}
return fileTree.getSelectedTemplatePaths().length;
}
public static boolean isUnSelectedTemplate() {
return VcsHelper.containsFolderCounts() + VcsHelper.selectedTemplateCounts() != 1;
}
public static String getEditingFilename() {
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(VcsHelper.VCS_CACHE_DIR)) {
editingFilePath = editingFilePath.replaceFirst(VcsHelper.VCS_CACHE_DIR, StringUtils.EMPTY);
}
if (editingFilePath.startsWith("/")) {
editingFilePath = editingFilePath.substring(1);
}
return editingFilePath;
}
public static boolean needDeleteVersion(VcsEntity entity) {
if (entity == null) {
return false;
}
return new Date().getTime() - entity.getTime().getTime() < DesignerEnvManager.getEnvManager().getSaveInterval() * MINUTE && StringUtils.isBlank(entity.getCommitMsg());
}
}

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

@ -0,0 +1,99 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.UIDialog;
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.itextarea.UITextArea;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.locale.InterProviderFactory;
import com.fr.report.ReportContext;
import com.fr.report.entity.VcsEntity;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* 编辑版本信息面板
*/
public class EditFileVersionDialog extends UIDialog {
private final UITextArea msgTestArea = new UITextArea();
private final UILabel versionLabel = new UILabel();
private VcsEntity entity;
public EditFileVersionDialog(VcsEntity entity) {
this(DesignerContext.getDesignerFrame());
this.entity = entity;
msgTestArea.setText(entity.getCommitMsg());
versionLabel.setText(String.valueOf(entity.getVersion()));
}
private EditFileVersionDialog(Frame parent) {
super(parent);
initComponents();
setModal(true);
setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Vcs_Save_Version"));
setSize(300, 220);
setResizable(false);
GUICoreUtils.centerWindow(this);
}
private void initComponents() {
JPanel fontPane = new JPanel(new BorderLayout());
fontPane.add(new UILabel(" " + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Vcs_Version_Message") + ":"), BorderLayout.NORTH);
msgTestArea.setBorder(null);
UIScrollPane scrollPane = new UIScrollPane(msgTestArea);
Component[][] components = new Component[][]{
new Component[]{new UILabel(" " + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Vcs_Version_Number") + ":"), versionLabel},
new Component[]{fontPane, scrollPane}
};
double[] rowSizes = new double[]{25, 100};
double[] columnSizes = new double[]{70, 200};
add(TableLayoutHelper.createTableLayoutPane(components, rowSizes, columnSizes), BorderLayout.CENTER);
JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT));
add(buttonPane, BorderLayout.SOUTH);
UIButton ok = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_OK"));
UIButton cancel = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Design_Action_Cancel"));
buttonPane.add(ok);
buttonPane.add(cancel);
ok.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
entity.setCommitMsg(msgTestArea.getText());
ReportContext.getInstance().getVcsController().saveOrUpdateFileVersion(entity);
setVisible(false);
}
});
cancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doCancel();
}
});
}
@Override
public void checkValid() throws Exception {
}
}

74
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionCellEditor.java

@ -0,0 +1,74 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.common.VcsCacheFileNodeFile;
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.AbstractCellEditor;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellEditor;
import java.awt.Component;
public class FileVersionCellEditor extends AbstractCellEditor implements TableCellEditor {
private static final long serialVersionUID = -7299526575184810693L;
//第一行
private final JPanel firstRowPanel;
//其余行
private final FileVersionRowPanel renderAndEditor;
public FileVersionCellEditor() {
this.firstRowPanel = new FileVersionFirstRowPanel();
this.renderAndEditor = new FileVersionRowPanel();
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
String fileOfVersion;
Component editor = row == 0 ? firstRowPanel : renderAndEditor;
if (isSelected) {
return editor;
} else if (row == 0) {
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
fileOfVersion = WorkContext.getCurrent().get(VcsOperator.class).getFileOfCurrent(path.replaceFirst("/", ""));
} else {
renderAndEditor.update((VcsEntity) value);
fileOfVersion = WorkContext.getCurrent().get(VcsOperator.class).getFileOfFileVersion(((VcsEntity) value).getFilename(), ((VcsEntity) value).getVersion());
}
editor.setBackground(VcsHelper.TABLE_SELECT_BACKGROUND);
if (StringUtils.isNotEmpty(fileOfVersion)) {
//先关闭当前打开的模板版本
JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
jt.stopEditing();
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(jt);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt);
//再打开cache中的模板
DesignerContext.getDesignerFrame().openTemplate(new VcsCacheFileNodeFile(new FileNode(fileOfVersion, false)));
}
double height = editor.getPreferredSize().getHeight();
if (table.getRowHeight(row) != height) {
table.setRowHeight(row, (int) height);
}
return editor;
}
@Override
public Object getCellEditorValue() {
return renderAndEditor.getVcsEntity();
}
}

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

@ -0,0 +1,43 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.report.entity.VcsEntity;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import java.awt.Component;
import static com.fr.design.constants.UIConstants.TREE_BACKGROUND;
import static com.fr.design.mainframe.vcs.common.VcsHelper.TABLE_SELECT_BACKGROUND;
public class FileVersionCellRender implements TableCellRenderer {
//第一行
private final JPanel firstRowPanel;
//其余行
private final FileVersionRowPanel render;
public FileVersionCellRender() {
this.render = new FileVersionRowPanel();
this.firstRowPanel = new FileVersionFirstRowPanel();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
Component editor = row == 0 ? firstRowPanel : render;
// https://stackoverflow.com/questions/3054775/jtable-strange-behavior-from-getaccessiblechild-method-resulting-in-null-point
if (value != null) {
render.update((VcsEntity) value);
}
editor.setBackground(isSelected ? TABLE_SELECT_BACKGROUND : TREE_BACKGROUND);
double height = editor.getPreferredSize().getHeight();
if (table.getRowHeight(row) != height) {
table.setRowHeight(row, (int) height);
}
return editor;
}
}

92
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionDialog.java

@ -0,0 +1,92 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.dialog.UIDialog;
import com.fr.design.editor.editor.DateEditor;
import com.fr.design.gui.date.UIDatePicker;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
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.AbstractAction;
import javax.swing.Box;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.List;
import static com.fr.design.mainframe.vcs.common.VcsHelper.EMPTY_BORDER;
import static com.fr.design.mainframe.vcs.common.VcsHelper.EMPTY_BORDER_BOTTOM;
public class FileVersionDialog extends UIDialog {
public static final long DELAY = 24 * 60 * 60 * 1000;
private UIButton okBtn = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK"));
private UIButton cancelBtn = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Utils_Design_Action_Cancel"));
private DateEditor dateEditor;
private UITextField textField;
public FileVersionDialog(Frame frame) {
super(frame);
setUndecorated(true);
JPanel panel = new JPanel(new BorderLayout());
Box upBox = Box.createHorizontalBox();
upBox.setBorder(EMPTY_BORDER_BOTTOM);
upBox.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_buildTime")));
upBox.add(Box.createHorizontalGlue());
dateEditor = new DateEditor(new Date(), true, StringUtils.EMPTY, UIDatePicker.STYLE_CN_DATE1);
upBox.add(dateEditor);
Box downBox = Box.createHorizontalBox();
downBox.setBorder(EMPTY_BORDER_BOTTOM);
downBox.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_CommitMsg")));
textField = new UITextField();
downBox.add(textField);
Box box2 = Box.createHorizontalBox();
box2.add(Box.createHorizontalGlue());
box2.setBorder(EMPTY_BORDER);
box2.add(okBtn);
box2.add(cancelBtn);
okBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
FileVersionDialog.this.setVisible(false);
Date date = dateEditor.getValue();
List<VcsEntity> vcsEntities = WorkContext.getCurrent().get(VcsOperator.class).getFilterVersions(date, new Date(date.getTime() + DELAY), textField.getText());
FileVersionTable.getInstance().updateModel(1, vcsEntities);
}
});
cancelBtn.addActionListener(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
FileVersionDialog.this.setVisible(false);
}
});
panel.add(upBox, BorderLayout.NORTH);
panel.add(downBox, BorderLayout.CENTER);
panel.add(box2, BorderLayout.SOUTH);
add(panel);
setSize(new Dimension(220, 100));
centerWindow(this);
}
private void centerWindow(Window window) {
window.setLocation(0, 95);
}
@Override
public void checkValid() throws Exception {
}
}

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

@ -0,0 +1,21 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import javax.swing.Box;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.BorderLayout;
public class FileVersionFirstRowPanel extends JPanel {
public FileVersionFirstRowPanel() {
super(new BorderLayout());
Box upPane = Box.createVerticalBox();
upPane.setBorder(new EmptyBorder(5, 10, 5, 10));
upPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Local_User")));
add(upPane, BorderLayout.CENTER);
}
}

149
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionRowPanel.java

@ -0,0 +1,149 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.design.gui.frpane.UITextPane;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.vcs.common.VcsHelper;
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.Box;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.SimpleDateFormat;
import java.util.Date;
public class FileVersionRowPanel extends JPanel {
private VcsEntity vcsEntity;
private UILabel versionLabel = new UILabel();
private UILabel usernameLabel = new UILabel(StringUtils.EMPTY, VcsHelper.VCS_USER_PNG, SwingConstants.LEFT);
private UITextPane timeAndMsgLabel = new UITextPane();
private UILabel timeLabel = new UILabel();
private EditFileVersionDialog editDialog;
public FileVersionRowPanel() {
setLayout(new BorderLayout());
// version + username
Box upPane = Box.createHorizontalBox();
upPane.setBorder(VcsHelper.EMPTY_BORDER);
upPane.add(versionLabel);
upPane.add(Box.createHorizontalGlue());
// msg
timeAndMsgLabel.setBorder(VcsHelper.EMPTY_BORDER);
timeAndMsgLabel.setOpaque(false);
timeAndMsgLabel.setBackground(new Color(0, 0, 0, 0));
timeAndMsgLabel.setEditable(false);
// confirm + delete
UIButton confirmBtn = new UIButton(VcsHelper.VCS_REVERT);
confirmBtn.set4ToolbarButton();
confirmBtn.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_Revert"));
confirmBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if (JOptionPane.showConfirmDialog(null, Toolkit.i18nText("Fine-Design_Vcs_Version_Revert_Confirm"), Toolkit.i18nText("Fine-Design_Vcs_Version_Revert_Title"),
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
WorkContext.getCurrent().get(VcsOperator.class).rollbackTo(vcsEntity);
FileVersionsPanel.getInstance().exitVcs(vcsEntity.getFilename());
}
}
});
UIButton deleteBtn = new UIButton(VcsHelper.VCS_DELETE_PNG);
deleteBtn.set4ToolbarButton();
deleteBtn.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_Delete"));
deleteBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if (JOptionPane.showConfirmDialog(null, Toolkit.i18nText("Fine-Design_Vcs_Delete-Confirm"), Toolkit.i18nText("Fine-Design_Vcs_Remove"),
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
try {
WorkContext.getCurrent().get(VcsOperator.class).deleteVersion(vcsEntity.getFilename(), vcsEntity.getVersion());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
FileVersionTable table = (FileVersionTable) (FileVersionRowPanel.this.getParent());
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
try {
table.updateModel(table.getSelectedRow() - 1, WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst("/", "")));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
}
});
UIButton editBtn = new UIButton(VcsHelper.VCS_EDIT_PNG);
editBtn.set4ToolbarButton();
editBtn.setToolTipText(Toolkit.i18nText("Fine-Design_Vcs_Edit"));
editBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showEditDialog();
}
});
upPane.add(editBtn);
upPane.add(confirmBtn);
upPane.add(deleteBtn);
Box downPane = Box.createHorizontalBox();
downPane.add(usernameLabel);
downPane.setBorder(VcsHelper.EMPTY_BORDER_BOTTOM);
downPane.add(Box.createHorizontalGlue());
downPane.add(timeLabel);
add(upPane, BorderLayout.NORTH);
add(timeAndMsgLabel, BorderLayout.CENTER);
add(downPane, BorderLayout.SOUTH);
}
private void showEditDialog() {
this.editDialog = new EditFileVersionDialog(vcsEntity);
editDialog.setVisible(true);
update(vcsEntity);
}
public void update(final VcsEntity fileVersion) {
this.vcsEntity = fileVersion;
versionLabel.setText(String.format("V.%s", fileVersion.getVersion()));
usernameLabel.setText(fileVersion.getUsername());
timeAndMsgLabel.setText(StringUtils.EMPTY);
timeLabel.setText(timeStr(fileVersion.getTime()));
try {
StyledDocument doc = timeAndMsgLabel.getStyledDocument();
Style style = timeAndMsgLabel.getLogicalStyle();
StyleConstants.setForeground(style, Color.BLACK);
doc.insertString(doc.getLength(), " " + fileVersion.getCommitMsg(), style);
} catch (BadLocationException e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
private String timeStr(Date time) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return simpleDateFormat.format(time);
}
public VcsEntity getVcsEntity() {
return vcsEntity;
}
}

79
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionTable.java

@ -0,0 +1,79 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.report.entity.VcsEntity;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
import java.util.List;
public class FileVersionTable extends JTable {
private static volatile FileVersionTable instance;
private FileVersionTable() {
super(new CellModel(new ArrayList<VcsEntity>()));
setDefaultRenderer(VcsEntity.class, new FileVersionCellRender());
setDefaultEditor(VcsEntity.class, new FileVersionCellEditor());
setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setTableHeader(null);
setRowHeight(30);
}
public static FileVersionTable getInstance() {
if (instance == null) {
synchronized (FileVersionTable.class) {
if (instance == null) {
instance = new FileVersionTable();
}
}
}
return instance;
}
public void updateModel(int selectedRow, List<VcsEntity> entities) {
if (selectedRow > entities.size()) {
selectedRow = entities.size();
}
setModel(new CellModel(entities));
editCellAt(selectedRow, 0);
setRowSelectionInterval(selectedRow, selectedRow);
}
private static class CellModel extends AbstractTableModel {
private static final long serialVersionUID = -6078568799037607690L;
private List<VcsEntity> vcsEntities;
CellModel(List<VcsEntity> vcsEntities) {
this.vcsEntities = vcsEntities;
}
public Class getColumnClass(int columnIndex) {
return VcsEntity.class;
}
public int getColumnCount() {
return 1;
}
public int getRowCount() {
return (vcsEntities == null) ? 0 : vcsEntities.size() + 1;
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (rowIndex == 0) {
return null;
}
return (vcsEntities == null) ? null : vcsEntities.get(rowIndex - 1);
}
public boolean isCellEditable(int columnIndex, int rowIndex) {
return true;
}
}
}

200
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/FileVersionsPanel.java

@ -0,0 +1,200 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.GraphHelper;
import com.fr.design.base.mode.DesignModeContext;
import com.fr.design.dialog.BasicPane;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.MutilTempalteTabPane;
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.itoolbar.UIToolbar;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.ToolBarNewTemplatePane;
import com.fr.design.mainframe.WestRegionContainerPane;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.menu.ToolBarDef;
import com.fr.file.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StableUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.SwingConstants;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class FileVersionsPanel extends BasicPane {
private static final String ELLIPSIS = "...";
private static volatile FileVersionsPanel instance;
private UILabel titleLabel;
private String templatePath;
private UIButton filterBtn;
private FileVersionDialog versionDialog;
private FileVersionsPanel() {
initComponents();
}
public static FileVersionsPanel getInstance() {
if (instance == null) {
synchronized (FileVersionsPanel.class) {
if (instance == null) {
instance = new FileVersionsPanel();
}
}
}
return instance;
}
private void initComponents() {
setLayout(new BorderLayout());
UIToolbar toolbar = ToolBarDef.createJToolBar();
toolbar.setBorder(BorderFactory.createEmptyBorder(2, 0, 2, 0));
toolbar.setBorderPainted(true);
Box upPane = Box.createHorizontalBox();
UIButton backBtn = new UIButton(VcsHelper.VCS_BACK_PNG);
backBtn.set4ToolbarButton();
backBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
exitVcs(templatePath);
}
});
toolbar.add(backBtn);
filterBtn = new UIButton(VcsHelper.VCS_FILTER_PNG);
filterBtn.set4ToolbarButton();
filterBtn.setHorizontalAlignment(SwingConstants.RIGHT);
filterBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showFilterPane();
}
});
titleLabel = new UILabel() {
@Override
public Dimension getMaximumSize() {
return new Dimension(257, 21);
}
};
upPane.add(titleLabel);
upPane.add(Box.createHorizontalGlue());
upPane.add(filterBtn);
toolbar.add(Box.createHorizontalGlue());
toolbar.add(upPane);
add(toolbar, BorderLayout.NORTH);
UIScrollPane jScrollPane = new UIScrollPane(FileVersionTable.getInstance());
add(jScrollPane, BorderLayout.CENTER);
}
private void showFilterPane() {
versionDialog = new FileVersionDialog(DesignerContext.getDesignerFrame());
versionDialog.setVisible(true);
}
/**
* 退出版本管理并且打开模板
*
* @param path 被管理的模板的名字
*/
public void exitVcs(String path) {
// 关闭当前打开的版本
JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
MutilTempalteTabPane.getInstance().setIsCloseCurrent(true);
MutilTempalteTabPane.getInstance().closeFormat(jt);
MutilTempalteTabPane.getInstance().closeSpecifiedTemplate(jt);
updateDesignerFrame(true);
final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, path);
DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(selectedFilePath, false)));
}
private void refreshVersionTablePane() {
templatePath = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
String[] paths = StableUtils.pathSplit(templatePath);
String filename = paths[paths.length - 1];
int width = FileVersionTable.getInstance().getWidth() - 40;
if (getStringWidth(filename) > width) {
filename = getEllipsisName(filename, width);
}
titleLabel.setText(filename);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
FileVersionTable.getInstance().updateModel(1, WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst("/", "")));
}
public void showFileVersionsPane() {
updateDesignerFrame(false);
refreshVersionTablePane();
}
@Override
protected String title4PopupWindow() {
return null;
}
private void updateDesignerFrame(boolean isExit) {
// 左上侧面板
WestRegionContainerPane.getInstance().replaceUpPane(
isExit ? DesignerFrameFileDealerPane.getInstance() : this);
DesignModeContext.switchTo(isExit ? com.fr.design.base.mode.DesignerMode.NORMAL : com.fr.design.base.mode.DesignerMode.VCS);
// MutilTempalteTabPane & NewTemplatePane 是否可点
ToolBarNewTemplatePane.getInstance().setButtonGray(!isExit);
JTemplate<?, ?> currentEditingTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (currentEditingTemplate.isJWorkBook()) {
DesignerContext.getDesignerFrame().resetToolkitByPlus(currentEditingTemplate);
}
}
private int getStringWidth(String str) {
return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str);
}
private String getEllipsisName(String name, int maxStringlength) {
//若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度
// int maxellipsislength = maxStringlength - ELLIPSIS.length();
int ellipsisWidth = getStringWidth(ELLIPSIS);
int leftkeyPoint = 0;
int rightKeyPoint = name.length() - 1;
int leftStrWidth = 0;
int rightStrWidth = 0;
while (leftStrWidth + rightStrWidth + ellipsisWidth < maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
leftkeyPoint++;
} else {
rightKeyPoint--;
}
leftStrWidth = getStringWidth(name.substring(0, leftkeyPoint));
rightStrWidth = getStringWidth(name.substring(rightKeyPoint));
if (leftStrWidth + rightStrWidth + ellipsisWidth > maxStringlength) {
if (leftStrWidth <= rightStrWidth) {
rightKeyPoint++;
}
break;
}
}
return name.substring(0, leftkeyPoint) + ELLIPSIS + name.substring(rightKeyPoint);
}
}

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_back_normal@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 398 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 605 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_normal@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_normal@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 908 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@1x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 668 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/vcs_back.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/vcs_list.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

BIN
designer-base/src/main/resources/com/fr/design/images/vcs/vcs_save.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 453 B

28
designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoCollectorTest.java

@ -66,9 +66,12 @@ public class TemplateInfoCollectorTest {
@Test @Test
public void testReadXML() { public void testReadXML() {
assertEquals(",,", DesignerOpenHistory.getInstance().toString());
TemplateInfoCollector collector = TemplateInfoCollector.getInstance(); TemplateInfoCollector collector = TemplateInfoCollector.getInstance();
assertEquals("2019-04-18", Reflect.on(collector).field("designerOpenDate").get());
assertEquals(7, ((Map) Reflect.on(collector).field("templateInfoMap").get()).size()); assertEquals(7, ((Map) Reflect.on(collector).field("templateInfoMap").get()).size());
assertEquals("2019-04-08,2019-04-03,2019-03-29", DesignerOpenHistory.getInstance().toString());
} }
@Test @Test
@ -151,6 +154,29 @@ public class TemplateInfoCollectorTest {
assertEquals(129, consumingMap.get("originTime")); assertEquals(129, consumingMap.get("originTime"));
} }
@Test
public void testCollectInfoWhenSaveAsWithNoTrackOriginID() throws Exception {
setUpMockForNewInstance();
TemplateInfoCollector collector = TemplateInfoCollector.getInstance();
String templateID = "423238d4-5223-22vj-vlsj-42jc49245iw3";
String originID = "3kha8jcs-31xw-42f5-h2ww-2ee84935312z";
int timeConsume = 200;
collector.collectInfo(templateID, originID, mockProcessInfo, timeConsume);
TemplateInfo templateInfo = collector.getOrCreateTemplateInfoByID(templateID);
assertEquals(templateID, templateInfo.getTemplateID());
assertEquals(originID, templateInfo.getOriginID());
Map<String, Object> consumingMap = Reflect.on(templateInfo).field("consumingMap").get();
assertEquals(templateID, consumingMap.get("templateID"));
assertEquals(originID, consumingMap.get("originID"));
assertEquals(200, consumingMap.get("time_consume"));
assertEquals(0, consumingMap.get("originTime"));
}
@Test @Test
public void testAddIdleDateCount() { public void testAddIdleDateCount() {
String templateID = "16a988ce-8529-42f5-b17c-2ee849355071"; String templateID = "16a988ce-8529-42f5-b17c-2ee849355071";

4
designer-base/src/test/resources/com/fr/design/mainframe/template/info/tpl.info

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<TplInfo xmlVersion="20170720" releaseVersion="10.0.0"> <TplInfo xmlVersion="20170720" releaseVersion="10.0.0">
<DesignerOpenDate> <DesignerOpenHistory>
<![CDATA[2019-04-18]]></DesignerOpenDate> <![CDATA[2019-04-08,2019-04-03,2019-03-29]]></DesignerOpenHistory>
<TemplateInfoList> <TemplateInfoList>
<TemplateInfo templateID="16a988ce-8529-42f5-b17c-2ee849355071" day_count="9"> <TemplateInfo templateID="16a988ce-8529-42f5-b17c-2ee849355071" day_count="9">
<processMap process="" float_count="0" widget_count="0" cell_count="1" block_count="0" report_type="0"/> <processMap process="" float_count="0" widget_count="0" cell_count="1" block_count="0" report_type="0"/>

45
designer-realize/src/main/java/com/fr/start/Designer.java

@ -12,6 +12,7 @@ import com.fr.design.actions.server.ServerConfigManagerAction;
import com.fr.design.actions.server.StyleListAction; import com.fr.design.actions.server.StyleListAction;
import com.fr.design.actions.server.WidgetManagerAction; import com.fr.design.actions.server.WidgetManagerAction;
import com.fr.design.constants.UIConstants; import com.fr.design.constants.UIConstants;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.MutilTempalteTabPane; import com.fr.design.file.MutilTempalteTabPane;
import com.fr.design.fun.MenuHandler; import com.fr.design.fun.MenuHandler;
@ -22,6 +23,7 @@ import com.fr.design.gui.imenu.UIPopupMenu;
import com.fr.design.gui.itoolbar.UILargeToolbar; import com.fr.design.gui.itoolbar.UILargeToolbar;
import com.fr.design.mainframe.ActiveKeyGenerator; import com.fr.design.mainframe.ActiveKeyGenerator;
import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.InformationCollector; import com.fr.design.mainframe.InformationCollector;
import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.JWorkBook; import com.fr.design.mainframe.JWorkBook;
@ -30,6 +32,8 @@ import com.fr.design.mainframe.bbs.UserInfoLabel;
import com.fr.design.mainframe.bbs.UserInfoPane; import com.fr.design.mainframe.bbs.UserInfoPane;
import com.fr.design.mainframe.template.info.TemplateInfoCollector; import com.fr.design.mainframe.template.info.TemplateInfoCollector;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.mainframe.vcs.common.VcsCacheFileNodeFile;
import com.fr.design.mainframe.vcs.ui.FileVersionTable;
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;
@ -42,6 +46,7 @@ import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory; import com.fr.log.FineLoggerFactory;
import com.fr.module.Module; import com.fr.module.Module;
import com.fr.module.ModuleContext; import com.fr.module.ModuleContext;
import com.fr.report.entity.VcsEntity;
import com.fr.runtime.FineRuntime; import com.fr.runtime.FineRuntime;
import com.fr.stable.BuildContext; import com.fr.stable.BuildContext;
import com.fr.stable.OperatingSystem; import com.fr.stable.OperatingSystem;
@ -56,6 +61,8 @@ import com.fr.start.module.StartupArgs;
import com.fr.start.preload.ImagePreLoader; import com.fr.start.preload.ImagePreLoader;
import com.fr.start.server.ServerTray; import com.fr.start.server.ServerTray;
import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
@ -107,7 +114,6 @@ public class Designer extends BaseDesigner {
System.exit(0); System.exit(0);
return; return;
} }
RestartHelper.deleteRecordFilesWhenStart(); RestartHelper.deleteRecordFilesWhenStart();
preloadResource(); preloadResource();
@ -270,15 +276,50 @@ public class Designer extends BaseDesigner {
saveButton.addActionListener(new ActionListener() { saveButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
JTemplate<?, ?> jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); JTemplate<?, ?> jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
jt.stopEditing(); jt.stopEditing();
jt.saveTemplate(); jt.saveTemplate();
jt.requestFocus(); jt.requestFocus();
if (DesignerEnvManager.getEnvManager().isVcsEnable()) {
dealWithVcs(jt);
}
} }
}); });
return saveButton; return saveButton;
} }
/**
* 版本控制
* @param jt
*/
private void dealWithVcs(final JTemplate jt) {
new Thread(new Runnable() {
@Override
public void run() {
String fileName = VcsHelper.getEditingFilename();
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
VcsEntity entity = operator.getFileVersionByIndex(fileName, 0);
int latestFileVersion = 0;
if (entity != null) {
latestFileVersion = entity.getVersion();
}
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) {
operator.saveVersionFromCache(VcsHelper.CURRENT_USERNAME, fileName, StringUtils.EMPTY, latestFileVersion + 1);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
FileVersionTable.getInstance().updateModel(1, WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst("/", "")));
} else {
operator.saveVersion(VcsHelper.CURRENT_USERNAME, fileName, StringUtils.EMPTY, latestFileVersion + 1);
}
VcsEntity oldEntity = WorkContext.getCurrent().get(VcsOperator.class).getFileVersionByIndex(fileName, 1);
if (VcsHelper.needDeleteVersion(oldEntity)) {
operator.deleteVersion(oldEntity.getFilename(), oldEntity.getVersion());
}
}
}).start();
}
private UIButton createUndoButton() { private UIButton createUndoButton() {
undo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/undo.png")); undo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/undo.png"));
undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName()); undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName());

Loading…
Cancel
Save