You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
346 lines
13 KiB
346 lines
13 KiB
package com.fr.design.actions.file; |
|
|
|
import com.fr.base.BaseUtils; |
|
import com.fr.chartx.TwoTuple; |
|
import com.fr.design.DesignerEnvManager; |
|
import com.fr.design.actions.UpdateAction; |
|
import com.fr.design.dialog.FineJOptionPane; |
|
import com.fr.design.file.FileOperations; |
|
import com.fr.design.file.HistoryTemplateListCache; |
|
import com.fr.design.file.MultiTemplateTabPane; |
|
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.design.layout.TableLayout; |
|
import com.fr.design.layout.TableLayoutHelper; |
|
import com.fr.design.mainframe.DesignerContext; |
|
import com.fr.design.mainframe.DesignerFrameFileDealerPane; |
|
import com.fr.design.mainframe.vcs.common.VcsHelper; |
|
import com.fr.design.utils.TemplateUtils; |
|
import com.fr.design.utils.gui.GUICoreUtils; |
|
import com.fr.event.EventDispatcher; |
|
import com.fr.file.FileNodeFILE; |
|
import com.fr.file.filetree.FileNode; |
|
import com.fr.general.ComparatorUtils; |
|
import com.fr.stable.CoreConstants; |
|
import com.fr.stable.StringUtils; |
|
import com.fr.stable.project.ProjectConstants; |
|
import com.fr.third.org.apache.commons.io.FilenameUtils; |
|
|
|
import javax.swing.BorderFactory; |
|
import javax.swing.JDialog; |
|
import javax.swing.JPanel; |
|
import javax.swing.JOptionPane; |
|
import javax.swing.SwingConstants; |
|
import javax.swing.event.DocumentEvent; |
|
import javax.swing.event.DocumentListener; |
|
import java.awt.BorderLayout; |
|
import java.awt.Color; |
|
import java.awt.Component; |
|
import java.awt.Dimension; |
|
import java.awt.FlowLayout; |
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
import java.awt.event.KeyAdapter; |
|
import java.awt.event.KeyEvent; |
|
import java.awt.event.KeyListener; |
|
import java.util.regex.Pattern; |
|
|
|
import static javax.swing.JOptionPane.DEFAULT_OPTION; |
|
import static javax.swing.JOptionPane.ERROR_MESSAGE; |
|
import static javax.swing.JOptionPane.WARNING_MESSAGE; |
|
import static javax.swing.JOptionPane.YES_NO_OPTION; |
|
|
|
/** |
|
* 模板/目录重命名操作 |
|
*/ |
|
public class RenameAction extends UpdateAction { |
|
|
|
private FileOperations selectedOperation; |
|
|
|
public RenameAction() { |
|
|
|
this.setName(Toolkit.i18nText("Fine-Design_Basic_Rename")); |
|
this.setSmallIcon("/com/fr/design/standard/rename/rename"); |
|
} |
|
|
|
@Override |
|
public void actionPerformed(ActionEvent evt) { |
|
selectedOperation = DesignerFrameFileDealerPane.getInstance().getSelectedOperation(); |
|
if (!selectedOperation.access()) { |
|
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), |
|
Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied"), |
|
Toolkit.i18nText("Fine-Design_Basic_Alert"), |
|
WARNING_MESSAGE); |
|
return; |
|
} |
|
|
|
FileNode node = selectedOperation.getFileNode(); |
|
String lock = node.getLock(); |
|
if (lock != null && !lock.equals(node.getUserID())) { |
|
// 提醒被锁定模板无法重命名 |
|
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), |
|
Toolkit.i18nText("Fine-Design_Basic_Unable_Rename_Locked_File"), |
|
Toolkit.i18nText("Fine-Design_Basic_Alert"), |
|
WARNING_MESSAGE); |
|
return; |
|
} |
|
|
|
new FileRenameDialog(node); |
|
MultiTemplateTabPane.getInstance().repaint(); |
|
DesignerFrameFileDealerPane.getInstance().stateChange(); |
|
} |
|
|
|
/** |
|
* 重命名对话框 |
|
* 支持快捷键Enter,ESC |
|
*/ |
|
private class FileRenameDialog extends JDialog { |
|
|
|
private UITextField nameField; |
|
|
|
private UILabel warnLabel; |
|
|
|
private UIButton confirmButton; |
|
|
|
/** |
|
* 操作的节点 |
|
*/ |
|
private FileNodeFILE fnf; |
|
|
|
private KeyListener keyListener = new KeyAdapter() { |
|
@Override |
|
public void keyPressed(KeyEvent e) { |
|
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { |
|
dispose(); |
|
} else if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
|
if (confirmButton.isEnabled()) { |
|
confirmClose(); |
|
} |
|
} |
|
} |
|
}; |
|
|
|
|
|
private FileRenameDialog(FileNode node) { |
|
super(DesignerContext.getDesignerFrame(), true); |
|
if (node == null) { |
|
return; |
|
} |
|
fnf = new FileNodeFILE(node); |
|
String oldName = fnf.getName(); |
|
String suffix = fnf.isDirectory() ? StringUtils.EMPTY : oldName.substring(oldName.lastIndexOf(CoreConstants.DOT), oldName.length()); |
|
oldName = StringUtils.replaceLast(oldName, suffix, StringUtils.EMPTY); |
|
|
|
initPane(oldName); |
|
} |
|
|
|
private void initPane(String oldName) { |
|
this.setLayout(new BorderLayout()); |
|
|
|
// 输入框前提示 |
|
UILabel newNameLabel = new UILabel(Toolkit.i18nText( |
|
fnf.isDirectory() ? |
|
"Fine-Design_Basic_Enter_New_Folder_Name" : "Fine-Design_Basic_Enter_New_File_Name") |
|
); |
|
newNameLabel.setHorizontalAlignment(SwingConstants.TRAILING); |
|
newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); |
|
//newNameLabel.setPreferredSize(new Dimension(118, 15)); |
|
|
|
// 重命名输入框 |
|
nameField = new UITextField(oldName); |
|
nameField.getDocument().addDocumentListener(new DocumentListener() { |
|
|
|
@Override |
|
public void changedUpdate(DocumentEvent e) { |
|
validInput(); |
|
} |
|
|
|
@Override |
|
public void insertUpdate(DocumentEvent e) { |
|
validInput(); |
|
} |
|
|
|
@Override |
|
public void removeUpdate(DocumentEvent e) { |
|
validInput(); |
|
} |
|
}); |
|
nameField.selectAll(); |
|
nameField.setPreferredSize(new Dimension(170, 20)); |
|
|
|
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 5)); |
|
topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); |
|
topPanel.add(newNameLabel); |
|
topPanel.add(nameField); |
|
|
|
// 增加enter以及esc快捷键的支持 |
|
nameField.addKeyListener(keyListener); |
|
// 重名提示 |
|
warnLabel = new UILabel(); |
|
warnLabel.setPreferredSize(new Dimension(300, 50)); |
|
warnLabel.setHorizontalAlignment(SwingConstants.LEADING); |
|
warnLabel.setVerticalAlignment(SwingConstants.TOP); |
|
warnLabel.setForeground(Color.RED); |
|
warnLabel.setVisible(false); |
|
|
|
JPanel midPanel = new JPanel(new BorderLayout()); |
|
midPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); |
|
midPanel.add(warnLabel, BorderLayout.LINE_START); |
|
|
|
// 确认按钮 |
|
confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm")); |
|
confirmButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
confirmClose(); |
|
} |
|
}); |
|
|
|
// 取消按钮 |
|
UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")); |
|
|
|
cancelButton.addActionListener(new ActionListener() { |
|
|
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
dispose(); |
|
} |
|
}); |
|
|
|
|
|
JPanel buttonsPane = new JPanel(new FlowLayout(FlowLayout.TRAILING, 10, 0)); |
|
buttonsPane.setBorder(BorderFactory.createEmptyBorder(10, 15, 10, 10)); |
|
buttonsPane.add(confirmButton); |
|
buttonsPane.add(cancelButton); |
|
|
|
this.add( |
|
TableLayoutHelper.createTableLayoutPane( |
|
new Component[][]{ |
|
new Component[]{topPanel}, |
|
new Component[]{midPanel}, |
|
new Component[]{buttonsPane} |
|
}, |
|
new double[]{TableLayout.FILL, TableLayout.PREFERRED, TableLayout.PREFERRED}, |
|
new double[]{TableLayout.FILL} |
|
), |
|
BorderLayout.CENTER); |
|
|
|
this.setSize(340, 200); |
|
this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Rename")); |
|
this.setResizable(false); |
|
this.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); |
|
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); |
|
GUICoreUtils.centerWindow(this); |
|
this.setVisible(true); |
|
} |
|
|
|
private void confirmClose() { |
|
|
|
if (TemplateUtils.checkSelectedTemplateIsEditing()) { |
|
if (FineJOptionPane.showConfirmDialog(this, |
|
Toolkit.i18nText("Fine-Design_Basic_Template_Is_Editing"), |
|
Toolkit.i18nText("Fine-Design_Basic_Alert"), |
|
YES_NO_OPTION) != JOptionPane.YES_OPTION) { |
|
return; |
|
} |
|
} |
|
|
|
String userInput = nameField.getText().trim(); |
|
|
|
String path = FilenameUtils.standard(fnf.getPath()); |
|
|
|
String oldName = fnf.getName(); |
|
String suffix = fnf.isDirectory() ? StringUtils.EMPTY : oldName.substring(oldName.lastIndexOf(CoreConstants.DOT), oldName.length()); |
|
oldName = StringUtils.replaceLast(oldName, suffix, StringUtils.EMPTY); |
|
|
|
// 输入为空或者没有修改 |
|
if (ComparatorUtils.equals(userInput, oldName)) { |
|
this.dispose(); |
|
return; |
|
} |
|
|
|
String parentPath = FilenameUtils.standard(fnf.getParent().getPath()); |
|
|
|
// 简单执行old new 替换是不可行的,例如 /abc/abc/abc/abc/ |
|
String newPath = parentPath + CoreConstants.SEPARATOR + userInput + suffix; |
|
this.dispose(); |
|
|
|
//模版重命名 |
|
boolean success = selectedOperation.rename(fnf, path, newPath); |
|
|
|
if (success) { |
|
afterRename(path, newPath); |
|
} else { |
|
FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), |
|
Toolkit.i18nText("Fine-Design_Basic_Rename_Failure"), |
|
Toolkit.i18nText("Fine-Design_Basic_Error"), |
|
DEFAULT_OPTION, |
|
ERROR_MESSAGE); |
|
} |
|
} |
|
|
|
private void afterRename(String path, String newPath) { |
|
EventDispatcher.fire(DesignerFrameFileDealerPane.TEMPLATE_RENAME, new TwoTuple<>(path, newPath)); |
|
HistoryTemplateListCache.getInstance().rename(fnf, path, newPath); |
|
DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(fnf.isDirectory(), path, newPath); |
|
selectedOperation.refreshParent(); |
|
if (!fnf.isDirectory()) { |
|
//版本控制:未打开模板时重命名,是个纯文件操作 |
|
//不借助JTemplate的事件触发机制实现(需要新创建JTemplate,并添加监听,不确定会不会有问题) |
|
path = path.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY); |
|
VcsHelper.getInstance().moveVcs(path, newPath.replaceFirst(ProjectConstants.REPORTLETS_NAME, StringUtils.EMPTY)); |
|
} |
|
DesignerContext.getDesignerFrame().setTitle(); |
|
LocateAction.gotoEditingTemplateLeaf(newPath); |
|
} |
|
|
|
|
|
private void validInput() { |
|
|
|
String userInput = nameField.getText().trim(); |
|
|
|
String oldName = fnf.getName(); |
|
String suffix = fnf.isDirectory() ? StringUtils.EMPTY : oldName.substring(oldName.lastIndexOf(CoreConstants.DOT), oldName.length()); |
|
oldName = oldName.replaceAll(suffix, StringUtils.EMPTY); |
|
|
|
if (StringUtils.isEmpty(userInput)) { |
|
confirmButton.setEnabled(false); |
|
return; |
|
} |
|
|
|
if (ComparatorUtils.equals(userInput, oldName)) { |
|
warnLabel.setVisible(false); |
|
confirmButton.setEnabled(true); |
|
return; |
|
} |
|
|
|
String errorMsg = doCheck(userInput, suffix, fnf.isDirectory()); |
|
if (StringUtils.isNotEmpty(errorMsg)) { |
|
nameField.selectAll(); |
|
// 如果文件名已存在,则灰掉确认按钮 |
|
warnLabel.setText(errorMsg); |
|
warnLabel.setVisible(true); |
|
confirmButton.setEnabled(false); |
|
} else { |
|
warnLabel.setVisible(false); |
|
confirmButton.setEnabled(true); |
|
} |
|
} |
|
|
|
private String doCheck (String userInput, String suffix, boolean isDirectory) { |
|
String errorMsg = StringUtils.EMPTY; |
|
if (selectedOperation.duplicated(userInput, suffix, false)) { |
|
errorMsg = Toolkit.i18nText(isDirectory ? |
|
"Fine-Design_Basic_Folder_Name_Duplicate" : |
|
"Fine-Design_Basic_Template_File_Name_Duplicate", |
|
userInput); |
|
} |
|
if (!Pattern.compile(DesignerFrameFileDealerPane.FILE_NAME_LIMIT).matcher(userInput).matches()) { |
|
errorMsg = Toolkit.i18nText("Fine-Design_Basic_Template_Name_Illegal"); |
|
} |
|
return errorMsg; |
|
} |
|
} |
|
}
|
|
|