@ -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))); |
||||
} |
||||
} |
@ -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()); |
||||
} |
||||
|
||||
|
||||
} |
@ -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 { |
||||
|
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
|
||||
} |
@ -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 { |
||||
|
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
|
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
After Width: | Height: | Size: 804 B |
After Width: | Height: | Size: 167 B |
After Width: | Height: | Size: 211 B |
After Width: | Height: | Size: 398 B |
After Width: | Height: | Size: 730 B |
After Width: | Height: | Size: 317 B |
After Width: | Height: | Size: 537 B |
After Width: | Height: | Size: 289 B |
After Width: | Height: | Size: 605 B |
After Width: | Height: | Size: 586 B |
After Width: | Height: | Size: 512 B |
After Width: | Height: | Size: 971 B |
After Width: | Height: | Size: 467 B |
After Width: | Height: | Size: 926 B |
After Width: | Height: | Size: 908 B |
After Width: | Height: | Size: 376 B |
After Width: | Height: | Size: 668 B |
After Width: | Height: | Size: 310 B |
After Width: | Height: | Size: 286 B |
After Width: | Height: | Size: 453 B |