@ -0,0 +1,74 @@ |
|||||||
|
package com.fr.design.mainframe.toolbar; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.vcs.ui.FileVersionCellEditor; |
||||||
|
import com.fr.design.mainframe.vcs.ui.FileVersionCellRender; |
||||||
|
import com.fr.design.mainframe.vcs.ui.FileVersionFirstRowPanel; |
||||||
|
import com.fr.design.mainframe.vcs.ui.FileVersionRowPanel; |
||||||
|
import com.fr.design.mainframe.vcs.ui.FileVersionTablePanel; |
||||||
|
import com.fr.design.mainframe.vcs.ui.FileVersionsPanel; |
||||||
|
import com.fr.third.javax.inject.Singleton; |
||||||
|
import com.fr.third.springframework.context.annotation.Bean; |
||||||
|
import com.fr.third.springframework.context.annotation.ComponentScan; |
||||||
|
import com.fr.third.springframework.context.annotation.Configuration; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
import com.fr.workspace.server.vcs.VcsOperator; |
||||||
|
import com.fr.workspace.server.vcs.VcsOperatorImpl; |
||||||
|
import com.fr.workspace.server.vcs.filesystem.VcsFileSystem; |
||||||
|
import com.fr.workspace.server.vcs.git.FineGit; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XiaXiang on 2019/4/16. |
||||||
|
*/ |
||||||
|
@Configuration |
||||||
|
@ComponentScan({"com.fr.workspace.server.vcs", "com.fr.design.mainframe.vcs"}) |
||||||
|
public class VcsConfig { |
||||||
|
@Bean |
||||||
|
@Singleton |
||||||
|
public FileVersionsPanel fileVersionsPanel() { |
||||||
|
return new FileVersionsPanel(fileVersionTablePanel()); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
@Singleton |
||||||
|
public FileVersionTablePanel fileVersionTablePanel() { |
||||||
|
return new FileVersionTablePanel(vcsOperator(), fileVersionCellEditor(), fileVersionCellRender()); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
@Singleton |
||||||
|
public FileVersionCellEditor fileVersionCellEditor() { |
||||||
|
return new FileVersionCellEditor(fileVersionFirstRowPanel(), fileVersionRowPanel(), vcsOperator()); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
@Singleton |
||||||
|
public FileVersionFirstRowPanel fileVersionFirstRowPanel() { |
||||||
|
return new FileVersionFirstRowPanel(); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
public FileVersionRowPanel fileVersionRowPanel() { |
||||||
|
return new FileVersionRowPanel(vcsOperator()); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
@Singleton |
||||||
|
public FileVersionCellRender fileVersionCellRender() { |
||||||
|
return new FileVersionCellRender(fileVersionFirstRowPanel(), fileVersionRowPanel()); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
@Singleton |
||||||
|
public VcsOperator vcsOperator() { |
||||||
|
return new VcsOperatorImpl(vcsFileSystem(), new FineGit(vcsFileSystem().getVcsHistoryPath())); |
||||||
|
} |
||||||
|
|
||||||
|
@Bean |
||||||
|
@Singleton |
||||||
|
public VcsFileSystem vcsFileSystem() { |
||||||
|
return new VcsFileSystem(WorkContext.getCurrent()); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package com.fr.design.mainframe.toolbar; |
||||||
|
|
||||||
|
import com.fr.third.springframework.context.annotation.AnnotationConfigApplicationContext; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by XiaXiang on 2019/4/20. |
||||||
|
*/ |
||||||
|
public class VcsContext extends AnnotationConfigApplicationContext { |
||||||
|
public static final VcsContext INSTANCE = new VcsContext(); |
||||||
|
|
||||||
|
public static VcsContext get() { |
||||||
|
|
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
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 |
@ -0,0 +1,74 @@ |
|||||||
|
package com.fr.design.mainframe.vcs.proxy; |
||||||
|
|
||||||
|
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 com.fr.workspace.server.vcs.common.Constants; |
||||||
|
|
||||||
|
import java.io.InputStream; |
||||||
|
import java.io.OutputStream; |
||||||
|
|
||||||
|
/** |
||||||
|
* Created by hzzz on 2017/12/21. |
||||||
|
*/ |
||||||
|
public class VcsCacheFileNodeFileProxy extends FileNodeFILE { |
||||||
|
|
||||||
|
private final FileNode node; |
||||||
|
|
||||||
|
public VcsCacheFileNodeFileProxy(FileNode node) { |
||||||
|
super(node); |
||||||
|
this.node = node; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 和FileNodeFILE中一样,只是去掉了必须以reportlets开头的限制,改为vcs开头 |
||||||
|
* |
||||||
|
* @return |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public InputStream asInputStream() throws Exception { |
||||||
|
if (node == null) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
String envPath = node.getEnvPath(); |
||||||
|
// envPath必须以vcs开头
|
||||||
|
if (!envPath.startsWith(Constants.VCS_CACHE_DIR)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
InputStream in = WorkContext.getCurrent().get(WorkResource.class) |
||||||
|
.openStream(StableUtils.pathJoin(Constants.VCS_CACHE_DIR, envPath.substring(Constants.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() throws Exception { |
||||||
|
if (ComparatorUtils.equals(node, null)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
String envPath = node.getEnvPath(); |
||||||
|
// envPath必须以reportlets开头
|
||||||
|
if (!envPath.startsWith(Constants.VCS_CACHE_DIR)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return new WorkResourceOutputStream(StableUtils.pathJoin(Constants.VCS_CACHE_DIR, envPath.substring(Constants.VCS_CACHE_DIR.length() + 1))); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,83 @@ |
|||||||
|
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.proxy.VcsCacheFileNodeFileProxy; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.entity.VcsEntity; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.workspace.server.vcs.VcsOperator; |
||||||
|
import com.fr.workspace.server.vcs.common.Constants; |
||||||
|
|
||||||
|
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 final VcsOperator vcs; |
||||||
|
//第一行
|
||||||
|
private final JPanel firstRowPanel; |
||||||
|
//其余行
|
||||||
|
private final FileVersionRowPanel renderAndEditor; |
||||||
|
|
||||||
|
public FileVersionCellEditor(FileVersionFirstRowPanel firstRowPanel, FileVersionRowPanel renderAndEditor, VcsOperator vcs) { |
||||||
|
this.vcs = vcs; |
||||||
|
this.firstRowPanel = firstRowPanel; |
||||||
|
this.renderAndEditor = renderAndEditor; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { |
||||||
|
String fileOfVersion = null; |
||||||
|
Component editor = row == 0 ? firstRowPanel : renderAndEditor; |
||||||
|
if (isSelected) { |
||||||
|
return editor; |
||||||
|
} else if (row == 0) { |
||||||
|
//TODO path "/"
|
||||||
|
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath(); |
||||||
|
try { |
||||||
|
fileOfVersion = vcs.getFileOfCurrent(path.replaceFirst("/", "")); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} else { |
||||||
|
renderAndEditor.update((VcsEntity) value); |
||||||
|
try { |
||||||
|
fileOfVersion = vcs.getFileOfFileVersion(((VcsEntity) value).getFilename(), ((VcsEntity) value).getVersion()); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
editor.setBackground(Constants.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 VcsCacheFileNodeFileProxy(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.getFileVersion(); |
||||||
|
} |
||||||
|
} |
@ -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.workspace.server.vcs.common.Constants.TABLE_SELECT_BACKGROUND; |
||||||
|
|
||||||
|
|
||||||
|
public class FileVersionCellRender implements TableCellRenderer { |
||||||
|
|
||||||
|
//第一行
|
||||||
|
private final JPanel firstRowPanel; |
||||||
|
//其余行
|
||||||
|
private final FileVersionRowPanel render; |
||||||
|
|
||||||
|
public FileVersionCellRender(FileVersionFirstRowPanel firstRowPanel, FileVersionRowPanel render) { |
||||||
|
this.render = render; |
||||||
|
this.firstRowPanel = firstRowPanel; |
||||||
|
} |
||||||
|
|
||||||
|
@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,77 @@ |
|||||||
|
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 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 static com.fr.workspace.server.vcs.common.Constants.EMPTY_BORDER; |
||||||
|
import static com.fr.workspace.server.vcs.common.Constants.EMPTY_BORDER_BOTTOM; |
||||||
|
|
||||||
|
|
||||||
|
public class FileVersionDialog extends UIDialog { |
||||||
|
private UIButton okBtn = new UIButton("确定"); |
||||||
|
private UIButton cancelBtn = new UIButton("取消"); |
||||||
|
|
||||||
|
|
||||||
|
public FileVersionDialog(Frame frame) { |
||||||
|
super(frame); |
||||||
|
setUndecorated(true); |
||||||
|
JPanel panel = new JPanel(new BorderLayout()); |
||||||
|
Box box0 = Box.createHorizontalBox(); |
||||||
|
box0.setBorder(EMPTY_BORDER_BOTTOM); |
||||||
|
box0.add(new UILabel("生成日期")); |
||||||
|
box0.add(Box.createHorizontalGlue()); |
||||||
|
box0.add(new DateEditor(new Date(), true, "生成日期", UIDatePicker.STYLE_CN_DATE1)); |
||||||
|
Box box1 = Box.createHorizontalBox(); |
||||||
|
box1.setBorder(EMPTY_BORDER_BOTTOM); |
||||||
|
box1.add(new UILabel("备注关键词 ")); |
||||||
|
box1.add(new UITextField()); |
||||||
|
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); |
||||||
|
} |
||||||
|
}); |
||||||
|
cancelBtn.addActionListener(new AbstractAction() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
FileVersionDialog.this.setVisible(false); |
||||||
|
} |
||||||
|
}); |
||||||
|
panel.add(box0, BorderLayout.NORTH); |
||||||
|
panel.add(box1, 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,20 @@ |
|||||||
|
package com.fr.design.mainframe.vcs.ui; |
||||||
|
|
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
|
||||||
|
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("本地用户")); |
||||||
|
add(upPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,148 @@ |
|||||||
|
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.toolbar.VcsConfig; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.entity.VcsEntity; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.third.springframework.context.annotation.AnnotationConfigApplicationContext; |
||||||
|
import com.fr.workspace.server.vcs.VcsOperator; |
||||||
|
import com.fr.workspace.server.vcs.common.Constants; |
||||||
|
|
||||||
|
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 final VcsOperator<VcsEntity> vcs; |
||||||
|
private VcsEntity fileVersion; |
||||||
|
private UILabel versionLabel = new UILabel(); |
||||||
|
private UILabel usernameLabel = new UILabel("", Constants.VCS_USER_PNG, SwingConstants.LEFT); |
||||||
|
private UITextPane timeAndMsgLabel = new UITextPane(); |
||||||
|
private UILabel timeLabel = new UILabel(); |
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
public FileVersionRowPanel(final VcsOperator vcsOperator) { |
||||||
|
this.vcs = vcsOperator; |
||||||
|
setLayout(new BorderLayout()); |
||||||
|
|
||||||
|
// version + username
|
||||||
|
Box upPane = Box.createHorizontalBox(); |
||||||
|
upPane.setBorder(Constants.EMPTY_BORDER); |
||||||
|
upPane.add(versionLabel); |
||||||
|
upPane.add(Box.createHorizontalGlue()); |
||||||
|
|
||||||
|
|
||||||
|
// msg
|
||||||
|
timeAndMsgLabel.setBorder(Constants.EMPTY_BORDER); |
||||||
|
timeAndMsgLabel.setOpaque(false); |
||||||
|
timeAndMsgLabel.setBackground(new Color(0, 0, 0, 0)); |
||||||
|
timeAndMsgLabel.setEditable(false); |
||||||
|
|
||||||
|
// confirm + delete
|
||||||
|
UIButton confirmBtn = new UIButton(Constants.VCS_REVERT); |
||||||
|
confirmBtn.set4ToolbarButton(); |
||||||
|
confirmBtn.setToolTipText(Toolkit.i18nText("Plugin-VCS_Version_Revert")); |
||||||
|
confirmBtn.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent evt) { |
||||||
|
if (JOptionPane.showConfirmDialog(null, Toolkit.i18nText("Plugin-VCS_Version_Revert_Confirm"), Toolkit.i18nText("Plugin-VCS_Version_Revert_Title"), |
||||||
|
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { |
||||||
|
try { |
||||||
|
vcs.rollbackTo(fileVersion); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(VcsConfig.class); |
||||||
|
context.getBean(FileVersionsPanel.class).exitVcs(fileVersion.getFilename()); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
UIButton deleteBtn = new UIButton(Constants.VCS_DELETE_PNG); |
||||||
|
deleteBtn.set4ToolbarButton(); |
||||||
|
deleteBtn.setToolTipText(Toolkit.i18nText("Plugin-VCS_Version_Delete")); |
||||||
|
deleteBtn.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent evt) { |
||||||
|
if (JOptionPane.showConfirmDialog(null, Toolkit.i18nText("Plugin-VCS_Version_Delete_Confirm"), Toolkit.i18nText("FR-Designer_Remove"), |
||||||
|
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { |
||||||
|
//TODO refactor
|
||||||
|
try { |
||||||
|
vcs.deleteVersion(fileVersion.getFilename(), fileVersion.getVersion()); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
FileVersionTablePanel table = (FileVersionTablePanel) (FileVersionRowPanel.this.getParent()); |
||||||
|
table.updateModel(table.getSelectedRow() - 1); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
UIButton editBtn = new UIButton(Constants.VCS_EDIT_PNG); |
||||||
|
editBtn.set4ToolbarButton(); |
||||||
|
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(Constants.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() { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void update(final VcsEntity fileVersion) { |
||||||
|
this.fileVersion = 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 getFileVersion() { |
||||||
|
return fileVersion; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
package com.fr.design.mainframe.vcs.ui; |
||||||
|
|
||||||
|
import com.fr.design.mainframe.DesignerFrameFileDealerPane; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.report.entity.VcsEntity; |
||||||
|
import com.fr.workspace.server.vcs.VcsOperator; |
||||||
|
|
||||||
|
import javax.swing.JTable; |
||||||
|
import javax.swing.ListSelectionModel; |
||||||
|
import javax.swing.table.AbstractTableModel; |
||||||
|
import javax.swing.table.TableCellEditor; |
||||||
|
import javax.swing.table.TableCellRenderer; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
|
||||||
|
public class FileVersionTablePanel extends JTable { |
||||||
|
|
||||||
|
private final VcsOperator vcs; |
||||||
|
|
||||||
|
public FileVersionTablePanel(VcsOperator vcs, TableCellEditor tableCellEditor, TableCellRenderer tableCellRenderer) { |
||||||
|
super(new Model(new ArrayList<VcsEntity>())); |
||||||
|
this.vcs = vcs; |
||||||
|
setDefaultRenderer(VcsEntity.class, tableCellRenderer); |
||||||
|
setDefaultEditor(VcsEntity.class, tableCellEditor); |
||||||
|
setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
||||||
|
setTableHeader(null); |
||||||
|
setRowHeight(30); |
||||||
|
} |
||||||
|
|
||||||
|
public void updateModel(int selectedRow) { |
||||||
|
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath(); |
||||||
|
//TODO path "/"
|
||||||
|
List<VcsEntity> vcsEntities = null; |
||||||
|
try { |
||||||
|
vcsEntities = vcs.getVersions(path.replaceFirst("/", "")); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage()); |
||||||
|
} |
||||||
|
if (selectedRow > vcsEntities.size()) { |
||||||
|
selectedRow = vcsEntities.size(); |
||||||
|
} |
||||||
|
setModel(new Model(vcsEntities)); |
||||||
|
editCellAt(selectedRow, 0); |
||||||
|
setRowSelectionInterval(selectedRow, selectedRow); |
||||||
|
} |
||||||
|
|
||||||
|
private static class Model extends AbstractTableModel { |
||||||
|
private List<VcsEntity> vcsEntities; |
||||||
|
|
||||||
|
|
||||||
|
Model(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; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public List<VcsEntity> getVcsEntities() { |
||||||
|
return vcsEntities; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,187 @@ |
|||||||
|
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.HistoryTemplateListPane; |
||||||
|
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.menu.ToolBarDef; |
||||||
|
import com.fr.file.FileNodeFILE; |
||||||
|
import com.fr.file.filetree.FileNode; |
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
import com.fr.stable.project.ProjectConstants; |
||||||
|
import com.fr.workspace.server.vcs.common.Constants; |
||||||
|
|
||||||
|
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 final FileVersionTablePanel fileVersionsTablePane; |
||||||
|
private UILabel titleLabel; |
||||||
|
private String templatePath; |
||||||
|
private UIButton filterBtn; |
||||||
|
private FileVersionDialog versionDialog; |
||||||
|
|
||||||
|
|
||||||
|
public FileVersionsPanel(FileVersionTablePanel fileVersionTablePanel) { |
||||||
|
this.fileVersionsTablePane = fileVersionTablePanel; |
||||||
|
initComponents(); |
||||||
|
} |
||||||
|
|
||||||
|
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(Constants.VCS_BACK_PNG); |
||||||
|
backBtn.set4ToolbarButton(); |
||||||
|
backBtn.addActionListener(new ActionListener() { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
exitVcs(templatePath); |
||||||
|
} |
||||||
|
}); |
||||||
|
toolbar.add(backBtn); |
||||||
|
filterBtn = new UIButton(Constants.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(fileVersionsTablePane); |
||||||
|
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); |
||||||
|
|
||||||
|
udpateDesignerFrame(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 = fileVersionsTablePane.getWidth() - 40; |
||||||
|
if (getStringWidth(filename) > width) { |
||||||
|
filename = getEllipsisName(filename, width); |
||||||
|
} |
||||||
|
titleLabel.setText(filename); |
||||||
|
fileVersionsTablePane.updateModel(1); |
||||||
|
} |
||||||
|
|
||||||
|
public void showFileVersionsPane() { |
||||||
|
udpateDesignerFrame(false); |
||||||
|
refreshVersionTablePane(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void udpateDesignerFrame(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 = HistoryTemplateListPane.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); |
||||||
|
} |
||||||
|
} |