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.
1805 lines
66 KiB
1805 lines
66 KiB
package com.fr.file; |
|
|
|
import com.fr.base.BaseUtils; |
|
import com.fr.base.FRContext; |
|
import com.fr.base.extension.FileExtension; |
|
import com.fr.design.DesignerEnvManager; |
|
import com.fr.design.ExtraDesignClassManager; |
|
import com.fr.design.actions.UpdateAction; |
|
import com.fr.design.dialog.BasicPane; |
|
import com.fr.design.dialog.FineJOptionPane; |
|
import com.fr.design.dialog.UIDialog; |
|
import com.fr.design.env.DesignerWorkspaceInfo; |
|
import com.fr.design.env.DesignerWorkspaceType; |
|
import com.fr.design.file.HistoryTemplateListPane; |
|
import com.fr.design.file.NodeAuthProcessor; |
|
import com.fr.design.fun.ReportSupportedFileUIProvider; |
|
import com.fr.design.gui.ibutton.UIButton; |
|
import com.fr.design.gui.ibutton.UIButtonUI; |
|
import com.fr.design.gui.icombobox.UIComboBox; |
|
import com.fr.design.gui.ilable.UILabel; |
|
import com.fr.design.gui.itextfield.DefaultCompletionFilter; |
|
import com.fr.design.gui.itextfield.UIAutoCompletionField; |
|
import com.fr.design.gui.itextfield.UITextField; |
|
import com.fr.design.gui.itree.filetree.FileTreeIcon; |
|
import com.fr.design.i18n.Toolkit; |
|
import com.fr.design.layout.FRGUIPaneFactory; |
|
import com.fr.design.layout.TableLayout; |
|
import com.fr.design.layout.TableLayoutHelper; |
|
import com.fr.design.mainframe.DesignerFrame; |
|
import com.fr.design.mainframe.JTemplate; |
|
import com.fr.design.utils.gui.GUICoreUtils; |
|
import com.fr.event.Event; |
|
import com.fr.event.EventDispatcher; |
|
import com.fr.event.Listener; |
|
import com.fr.file.filetree.FileNode; |
|
import com.fr.file.filter.ChooseFileFilter; |
|
import com.fr.file.filter.FILEFilter; |
|
import com.fr.general.ComparatorUtils; |
|
import com.fr.general.GeneralContext; |
|
import com.fr.log.FineLoggerFactory; |
|
import com.fr.report.ExtraReportClassManager; |
|
import com.fr.report.fun.ReportSupportedFileProvider; |
|
import com.fr.stable.CoreConstants; |
|
import com.fr.stable.ProductConstants; |
|
import com.fr.stable.StableUtils; |
|
import com.fr.stable.StringUtils; |
|
import com.fr.stable.os.windows.WindowsDetector; |
|
import com.fr.stable.project.ProjectConstants; |
|
import com.fr.workspace.WorkContext; |
|
|
|
import com.fr.workspace.Workspace; |
|
import com.fr.workspace.WorkspaceEvent; |
|
import javax.swing.AbstractAction; |
|
import javax.swing.AbstractListModel; |
|
import javax.swing.ActionMap; |
|
import javax.swing.BorderFactory; |
|
import javax.swing.DefaultComboBoxModel; |
|
import javax.swing.DefaultListCellRenderer; |
|
import javax.swing.DefaultListModel; |
|
import javax.swing.Icon; |
|
import javax.swing.InputMap; |
|
import javax.swing.JComponent; |
|
import javax.swing.JDialog; |
|
import javax.swing.JFileChooser; |
|
import javax.swing.JList; |
|
import javax.swing.JOptionPane; |
|
import javax.swing.JPanel; |
|
import javax.swing.JScrollPane; |
|
import javax.swing.KeyStroke; |
|
import javax.swing.ListModel; |
|
import javax.swing.ListSelectionModel; |
|
import javax.swing.SwingConstants; |
|
import javax.swing.SwingUtilities; |
|
import javax.swing.event.DocumentEvent; |
|
import javax.swing.event.DocumentListener; |
|
import javax.swing.event.ListSelectionEvent; |
|
import javax.swing.event.ListSelectionListener; |
|
import javax.swing.filechooser.FileSystemView; |
|
import javax.swing.plaf.basic.BasicArrowButton; |
|
import javax.swing.plaf.basic.BasicButtonUI; |
|
import java.awt.BorderLayout; |
|
import java.awt.Color; |
|
import java.awt.Component; |
|
import java.awt.Dimension; |
|
import java.awt.FlowLayout; |
|
import java.awt.Insets; |
|
import java.awt.Window; |
|
import java.awt.event.ActionEvent; |
|
import java.awt.event.ActionListener; |
|
import java.awt.event.ItemEvent; |
|
import java.awt.event.ItemListener; |
|
import java.awt.event.KeyAdapter; |
|
import java.awt.event.KeyEvent; |
|
import java.awt.event.MouseAdapter; |
|
import java.awt.event.MouseEvent; |
|
import java.awt.event.WindowAdapter; |
|
import java.awt.event.WindowEvent; |
|
import java.io.File; |
|
import java.util.ArrayList; |
|
import java.util.EnumSet; |
|
import java.util.Iterator; |
|
import java.util.List; |
|
import java.util.Set; |
|
import java.util.regex.Matcher; |
|
import java.util.regex.Pattern; |
|
|
|
/* |
|
* FileChooserPane要高亮显示某Button,以显示当前路径 |
|
* 边距要调整 |
|
* postfix还没有处理 |
|
* 该文件选择器,整理行为如下: |
|
*/ |
|
public class FILEChooserPane extends BasicPane { |
|
|
|
/** |
|
* Return value if OK is chosen. |
|
*/ |
|
public static final int OK_OPTION = 0; |
|
/** |
|
* Return value if CANCEL is chosen. |
|
*/ |
|
public static final int CANCEL_OPTION = 1; |
|
|
|
public static final int JOPTIONPANE_OK_OPTION = 2; |
|
|
|
public static final int JOPTIONPANE_CANCEL_OPTION = 3; |
|
|
|
|
|
/** |
|
* alex:之所以在Pattern那里加个+,是因为有些路径会有两个甚至多个分隔符放在一起 |
|
*/ |
|
private static final Pattern SEPARATOR_PATTERN = Pattern.compile("[/\\\\]+"); |
|
|
|
private static final FILEChooserPane INSTANCE = new FILEChooserPane(); |
|
|
|
private FILE currentDirectory; // 当前路径,在subFileList中显示这个路径下所有的文件 |
|
|
|
private List<FILEFilter> filterList = new ArrayList<>(); |
|
private FILEFilter filter; |
|
|
|
private LocationButtonPane locationBtnPane; // 显示location的Panel |
|
private UIButton mkdirButton; |
|
|
|
private JList placesList; // File.listRoots() + Env + Favourite |
|
private JList subFileList; // 当前选中目录下的文件夹及文件 |
|
|
|
private JScrollPane scrollPane; |
|
private UIAutoCompletionField fileNameTextField; // 文件名的文本框 |
|
private UIComboBox postfixComboBox; // 文件后缀名的下拉列表框 |
|
|
|
private UIButton okButton; |
|
|
|
|
|
protected int type; |
|
protected boolean showEnv; |
|
protected boolean showLoc; |
|
protected boolean showWebReport = false; |
|
|
|
private UIDialog dialog; |
|
|
|
private int option = CANCEL_OPTION; |
|
|
|
protected String suffix; |
|
|
|
/** |
|
* @return |
|
*/ |
|
public static FILEChooserPane getInstance() { |
|
return getInstance(true, true); |
|
} |
|
|
|
/** |
|
* @param showEnv |
|
* @return |
|
*/ |
|
public static FILEChooserPane getInstance(boolean showEnv) { |
|
return getInstance(showEnv, true); |
|
} |
|
|
|
/** |
|
* @param showEnv |
|
* @param showLoc |
|
* @return |
|
*/ |
|
public static FILEChooserPane getInstance(boolean showEnv, boolean showLoc) { |
|
INSTANCE.showEnv = showEnv; |
|
INSTANCE.showLoc = showLoc; |
|
INSTANCE.showWebReport = false; |
|
INSTANCE.setPlaceListModel(); |
|
INSTANCE.removeAllFilter(); |
|
return INSTANCE; |
|
} |
|
|
|
public static FILEChooserPane getMultiEnvInstance(boolean showLoc, boolean showWebReport, FILEFilter filter) { |
|
INSTANCE.showEnv = true; |
|
INSTANCE.showLoc = showLoc; |
|
INSTANCE.showWebReport = showWebReport; |
|
// 替换掉 PlaceListModel |
|
INSTANCE.setMultiPlaceListModel(); |
|
INSTANCE.removeAllFilter(); |
|
INSTANCE.addChooseFILEFilter(filter, 0); |
|
return INSTANCE; |
|
} |
|
|
|
public static FILEChooserPane getMultiEnvInstance(boolean showLoc, boolean showWebReport) { |
|
INSTANCE.showEnv = true; |
|
INSTANCE.showLoc = showLoc; |
|
INSTANCE.showWebReport = showWebReport; |
|
// 替换掉 PlaceListModel |
|
INSTANCE.setMultiPlaceListModel(); |
|
INSTANCE.removeAllFilter(); |
|
return INSTANCE; |
|
} |
|
|
|
|
|
/** |
|
* @param showEnv |
|
* @param filter |
|
* @return |
|
*/ |
|
public static FILEChooserPane getInstance(boolean showEnv, FILEFilter filter) { |
|
INSTANCE.showEnv = showEnv; |
|
INSTANCE.setPlaceListModel(); |
|
INSTANCE.removeAllFilter(); |
|
INSTANCE.addChooseFILEFilter(filter, 0); |
|
return INSTANCE; |
|
} |
|
|
|
/** |
|
* @param showEnv |
|
* @param showLoc |
|
* @param filter |
|
* @return |
|
*/ |
|
public static FILEChooserPane getInstance(boolean showEnv, boolean showLoc, FILEFilter filter) { |
|
INSTANCE.showEnv = showEnv; |
|
INSTANCE.showLoc = showLoc; |
|
INSTANCE.showWebReport = false; |
|
INSTANCE.setPlaceListModel(); |
|
INSTANCE.removeAllFilter(); |
|
INSTANCE.addChooseFILEFilter(filter, 0); |
|
return INSTANCE; |
|
} |
|
|
|
/** |
|
* @param showEnv |
|
* @param showLoc |
|
* @param showWebReport |
|
* @param filter |
|
* @return |
|
*/ |
|
public static FILEChooserPane getInstance(boolean showEnv, boolean showLoc, boolean showWebReport, FILEFilter filter) { |
|
INSTANCE.showEnv = showEnv; |
|
INSTANCE.showLoc = showLoc; |
|
INSTANCE.showWebReport = showWebReport; |
|
INSTANCE.setPlaceListModel(); |
|
INSTANCE.removeAllFilter(); |
|
INSTANCE.addChooseFILEFilterToFist(filter, 0); |
|
return INSTANCE; |
|
} |
|
|
|
private FILEChooserPane() { |
|
this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4)); |
|
this.setLayout(FRGUIPaneFactory.createBorderLayout()); |
|
|
|
// kel:support Esc key. |
|
InputMap inputMapAncestor = this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); |
|
ActionMap actionMap = this.getActionMap(); |
|
|
|
// transfer focus to CurrentEditor |
|
inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dialogExit"); |
|
actionMap.put("dialogExit", new AbstractAction() { |
|
@Override |
|
public void actionPerformed(ActionEvent evt) { |
|
option = CANCEL_OPTION; |
|
dialogExit(); |
|
} |
|
}); |
|
|
|
JPanel locationPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
// locationPane.setLayout(FRGUIPaneFactory.createBorderLayout()); |
|
locationPane.add(locationBtnPane = new LocationButtonPane(), BorderLayout.CENTER); |
|
|
|
mkdirButton = initMkdirButton(); |
|
locationPane.add(mkdirButton, BorderLayout.EAST); |
|
|
|
JPanel centerLeftPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
// centerLeftPanel.setLayout(FRGUIPaneFactory.createBorderLayout()); |
|
// Richie:placesList includes C,D,E,F and DeskTop etc. |
|
placesList = new JList(); |
|
centerLeftPanel.add(placesList, BorderLayout.CENTER); |
|
centerLeftPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY)); |
|
centerLeftPanel.setPreferredSize(new Dimension(120, 1)); |
|
placesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); |
|
placesList.setCellRenderer(new DefaultListCellRenderer() { |
|
|
|
@Override |
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
|
|
|
if (value instanceof FILE) { |
|
FILE dir = (FILE) value; |
|
|
|
String name = dir.getName(); |
|
if (name != null && !StringUtils.isBlank(name)) { |
|
this.setText(name); |
|
} else { |
|
this.setText(GeneralContext.getCurrentAppNameOfEnv()); |
|
} |
|
Icon icon = dir.getIcon(); |
|
if (icon != null) { |
|
this.setIcon(icon); |
|
} |
|
} |
|
|
|
return this; |
|
} |
|
|
|
}); |
|
// placeList listener |
|
placesList.addListSelectionListener(new ListSelectionListener() { |
|
@Override |
|
public void valueChanged(ListSelectionEvent e) { |
|
Object selValue = placesList.getSelectedValue(); |
|
if (selValue instanceof FILE) { |
|
setSelectedDirectory((FILE) selValue); |
|
} |
|
} |
|
}); |
|
/* |
|
* placeList mouseListener |
|
*/ |
|
placesList.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
Object selValue = placesList.getSelectedValue(); |
|
if (selValue instanceof FILE) { |
|
setSelectedDirectory((FILE) selValue); |
|
} |
|
} |
|
}); |
|
|
|
// centerRightPane |
|
JPanel centerRightPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
|
|
JPanel subFilePanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
|
// 以后rightPanel要用JTable |
|
subFileList = new JList(new DefaultListModel<>()); |
|
/* |
|
* JList的CellRenderer |
|
*/ |
|
subFileList.setCellRenderer(new DefaultListCellRenderer() { |
|
|
|
@Override |
|
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
|
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
|
|
|
if (value instanceof FILE) { |
|
FILE dir = (FILE) value; |
|
|
|
String name = dir.getName(); |
|
if (name != null) { |
|
this.setText(name); |
|
} |
|
Icon icon = dir.getIcon(); |
|
if (icon != null) { |
|
this.setIcon(icon); |
|
} |
|
} |
|
|
|
return this; |
|
} |
|
|
|
}); |
|
/* |
|
* 鼠标点击JList时的listener |
|
*/ |
|
subFileList.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
Object source = e.getSource(); |
|
if (!(source instanceof JList)) { |
|
return; |
|
} |
|
|
|
if (e.getClickCount() < 1) { |
|
return; |
|
} |
|
|
|
JList list = (JList) source; |
|
|
|
Object selValue = list.getSelectedValue(); |
|
if (selValue instanceof FILE) { |
|
if (e.getClickCount() == 1) { |
|
fileNameTextField.removeDocumentListener(); |
|
setFileTextField((FILE) selValue); |
|
fileNameTextField.addDocumentListener(); |
|
} else { |
|
setSelectedDirectory((FILE) selValue); |
|
if (!((FILE) selValue).isDirectory()) { |
|
doOK(); |
|
} |
|
} |
|
} |
|
} |
|
}); |
|
/* |
|
* right list. |
|
*/ |
|
// Richie:按下Enter的时候打开文件夹或者打开文件 |
|
subFileList.addKeyListener(new KeyAdapter() { |
|
@Override |
|
public void keyReleased(KeyEvent e) { |
|
Object source = e.getSource(); |
|
if (!(source instanceof JList)) { |
|
return; |
|
} |
|
|
|
JList list = (JList) source; |
|
|
|
Object selValue = list.getSelectedValue(); |
|
if (selValue instanceof FILE) { |
|
setFileTextField((FILE) selValue); |
|
// if (((FILE)selValue).isDirectory()) { |
|
// fileNameTextField.setText(""); |
|
// } |
|
// Richie:按下Enter的时候打开文件夹或者打开文件 |
|
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
|
setSelectedDirectory((FILE) selValue); |
|
if (!((FILE) selValue).isDirectory()) { |
|
doOK(); |
|
} |
|
} |
|
} |
|
|
|
} |
|
}); |
|
scrollPane = new JScrollPane(subFileList); |
|
subFilePanel.add(scrollPane, BorderLayout.CENTER); |
|
centerRightPane.add(subFilePanel, BorderLayout.CENTER); |
|
|
|
// 用createTableLayoutPane布局下fileNamePane |
|
UIButton cancelButton; |
|
Component[][] coms = new Component[][]{ |
|
new Component[]{GUICoreUtils.createBorderPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Utils_File_Name") + ":"), BorderLayout.WEST), |
|
fileNameTextField = new UIAutoCompletionField(), okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Utils_Design_File_Open")) |
|
}, |
|
new Component[]{GUICoreUtils.createBorderPane(new UILabel(Toolkit.i18nText("Fine-Design_Report_Utils_File_Type") + ":"), BorderLayout.WEST), |
|
postfixComboBox = new UIComboBox(), cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Utils_Design_Action_Cancel")) |
|
}}; |
|
|
|
JPanel fileNamePane = TableLayoutHelper.createGapTableLayoutPane(coms, new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED, |
|
TableLayout.PREFERRED}, new double[]{TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}, 24, 4); |
|
centerRightPane.add(fileNamePane, BorderLayout.SOUTH); |
|
|
|
Component[][] outComponents = new Component[][]{ |
|
new Component[]{GUICoreUtils.createBorderPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_App_File_Lookup_range") + ":"), BorderLayout.WEST), locationPane}, |
|
new Component[]{centerLeftPanel, centerRightPane}}; |
|
JPanel contentPane = TableLayoutHelper.createTableLayoutPane(outComponents, new double[]{TableLayout.PREFERRED, TableLayout.FILL}, |
|
new double[]{TableLayout.PREFERRED, TableLayout.FILL}); |
|
this.add(contentPane, BorderLayout.CENTER); |
|
okButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent evt) { |
|
doOK(); |
|
} |
|
}); |
|
cancelButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent evt) { |
|
option = CANCEL_OPTION; |
|
doCancel(); |
|
} |
|
}); |
|
fileNameTextField.addKeyListener(new KeyAdapter() { |
|
@Override |
|
public void keyPressed(KeyEvent e) { |
|
if (e.getKeyCode() == KeyEvent.VK_ENTER) { |
|
option = CANCEL_OPTION; |
|
doOK(); |
|
} |
|
} |
|
}); |
|
postfixComboBox.addItemListener(new ItemListener() { |
|
|
|
@Override |
|
public void itemStateChanged(ItemEvent e) { |
|
Object ss = postfixComboBox.getSelectedItem(); |
|
if (ss instanceof ChooseFileFilter) { |
|
setFILEFilter((ChooseFileFilter) ss); |
|
if (fileNameTextField.isShowing()) { |
|
fileNameTextField.setText(calProperFileName(fileNameTextField.getText(), (ChooseFileFilter) ss)); |
|
} |
|
} else { |
|
setFILEFilter(null); |
|
} |
|
} |
|
}); |
|
} |
|
|
|
private String calProperFileName(String fileName, ChooseFileFilter fileFilter) { |
|
if(fileFilter == null){ |
|
return fileName; |
|
} |
|
String filterExtension = fileFilter.getExtensionString(); |
|
int lastDotIndex = fileName.lastIndexOf(".") != -1 ? fileName.lastIndexOf(".") : fileName.length(); |
|
String fileNameWithOutExtension = fileName.substring(0, lastDotIndex); |
|
String fileNameExtension = fileName.substring(lastDotIndex); |
|
FileExtension fileExtension = FileExtension.parse(fileNameExtension); |
|
if (StringUtils.isEmpty(fileName) || StringUtils.isEmpty(filterExtension) || fileFilter.containsExtension(fileExtension.getExtension())) { |
|
return fileName; |
|
} |
|
if (!ComparatorUtils.equals(fileNameExtension, filterExtension) && !isMapping(fileNameExtension, filterExtension)) { |
|
return fileName + filterExtension; |
|
} |
|
return fileNameWithOutExtension + filterExtension; |
|
} |
|
|
|
private boolean isMapping(String fromExtension, String toExtension){ |
|
if(FileExtension.CPTX.matchExtension(fromExtension)){ |
|
return FileExtension.CPT.matchExtension(toExtension); |
|
}else if(FileExtension.CPT.matchExtension(fromExtension)){ |
|
return FileExtension.CPTX.matchExtension(toExtension); |
|
} |
|
return false; |
|
} |
|
|
|
private void doCancel() { |
|
this.locationBtnPane.setPopDir(null); |
|
dialogExit(); |
|
} |
|
|
|
/** |
|
* @param showEnv |
|
* @param showLoc |
|
*/ |
|
public FILEChooserPane(boolean showEnv, boolean showLoc) { |
|
this(); |
|
this.showEnv = showEnv; |
|
this.showLoc = showLoc; |
|
this.setPlaceListModel(); |
|
} |
|
|
|
|
|
/** |
|
* 返回选中的FILE |
|
* |
|
* @return |
|
*/ |
|
public FILE getSelectedFILE() { |
|
String fileName = fileNameTextField.getText().trim(); |
|
if (!fileName.endsWith(suffix) && !fileName.contains(CoreConstants.DOT)) { |
|
fileName += this.suffix; |
|
} |
|
if (currentDirectory == null) { |
|
return null; |
|
} |
|
if (currentDirectory instanceof FileFILE) { |
|
return new FileFILE((FileFILE) currentDirectory, fileName); |
|
} else { |
|
return new FileNodeFILE((FileNodeFILE) currentDirectory, fileName, false); |
|
} |
|
} |
|
|
|
protected String getEnvProjectName() { |
|
return Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Env_Directory"); |
|
} |
|
|
|
/** |
|
* 增加文件过滤器 |
|
* |
|
* @param filter 过滤器 |
|
*/ |
|
public void addChooseFILEFilter(FILEFilter filter) { |
|
addChooseFILEFilter(filter, filterList.size()); |
|
} |
|
|
|
|
|
/** |
|
* 在指定index增加过滤器 |
|
* |
|
* @param filter 过滤器 |
|
* @param index 序号 |
|
*/ |
|
public void addChooseFILEFilter(FILEFilter filter, int index) { |
|
if (filterList.contains(filter)) { |
|
return; |
|
} |
|
this.filterList.add(index, filter); |
|
} |
|
|
|
/** |
|
* 若是已经存在,则将之删去之后,在指定的位置增加 |
|
* |
|
* @param filter 过滤 |
|
* @param index 序号 |
|
*/ |
|
public void addChooseFILEFilterToFist(FILEFilter filter, int index) { |
|
if (filterList.contains(filter)) { |
|
filterList.remove(filter); |
|
filterList.add(index, filter); |
|
return; |
|
} |
|
this.filterList.add(index, filter); |
|
} |
|
|
|
/** |
|
* 删除文件过滤器 |
|
* 这命名太乱了,完全是误导 |
|
* |
|
* @param filter 过滤 |
|
*/ |
|
public void removeFILEFilter(FILEFilter filter) { |
|
if (filterList.contains(filter)) { |
|
this.filterList.remove(filter); |
|
} |
|
} |
|
|
|
/** |
|
* 删掉全部的过滤器 |
|
*/ |
|
public void removeAllFilter() { |
|
this.filterList.clear(); |
|
} |
|
|
|
|
|
/** |
|
* 设置filter,刷新右侧subFileList中的items |
|
* |
|
* @param filter 过滤 |
|
*/ |
|
public void setFILEFilter(FILEFilter filter) { |
|
this.filter = filter; |
|
|
|
refreshSubFileListModel(); |
|
} |
|
|
|
/** |
|
* richer:默认的话就使用.cpt作为后缀名 |
|
* |
|
* @param text 文本 |
|
* @param suffix 后缀 |
|
*/ |
|
public void setFileNameTextField(String text, String suffix) { |
|
if (StringUtils.isEmpty(suffix)) { |
|
suffix = FileExtension.CPT.getSuffix(); |
|
} |
|
this.suffix = suffix; |
|
|
|
if (!text.endsWith(suffix)) { |
|
text = removeSuffix(text) + suffix; |
|
} |
|
fileNameTextField.removeDocumentListener(); |
|
fileNameTextField.setText(text); |
|
fileNameTextField.addDocumentListener(); |
|
if (currentDirectory == null) { |
|
return; |
|
} |
|
FILE[] files = currentDirectory.listFiles(); |
|
String[] names = new String[files.length]; |
|
for (int i = 0; i < files.length; i++) { |
|
names[i] = files[i].getName(); |
|
} |
|
fileNameTextField.setFilter(new DefaultCompletionFilter(names)); |
|
} |
|
|
|
public void disableFileNameTextFiled() { |
|
fileNameTextField.setEditable(false); |
|
fileNameTextField.setEnabled(false); |
|
} |
|
|
|
public void enableFileNameTextFiled() { |
|
fileNameTextField.setEditable(true); |
|
fileNameTextField.setEnabled(true); |
|
} |
|
|
|
/** |
|
* 移除文件后缀的方法 |
|
* 解决cptx文件的另存为操作默认会出现双后缀的bug(xxx.cptx.cpt) |
|
**/ |
|
private String removeSuffix(String text){ |
|
return FileExtension.CPTX.matchExtension(text) ? text.substring(0, text.length() - FileExtension.CPTX.getSuffix().length()) : text; |
|
} |
|
|
|
|
|
/** |
|
* 打开对话框 |
|
* |
|
* @param parent 父类 |
|
* @return 类型 |
|
*/ |
|
public int showOpenDialog(Component parent) { |
|
return showOpenDialog(parent, FileExtension.CPT.getSuffix()); |
|
} |
|
|
|
/** |
|
* 打开对话框 |
|
* |
|
* @param parent 父类 |
|
* @param suffix 后缀 |
|
* @return 类型 |
|
*/ |
|
public int showOpenDialog(Component parent, String suffix) { |
|
return showDialog(parent, JFileChooser.OPEN_DIALOG, suffix); |
|
} |
|
|
|
/** |
|
* 打开对话框 |
|
* |
|
* @param parent 父类 |
|
* @return 类型 |
|
*/ |
|
public int showSaveDialog(Component parent) { |
|
return showSaveDialog(parent, FileExtension.CPT.getSuffix()); |
|
} |
|
|
|
/** |
|
* 打开对话框 |
|
* |
|
* @param parent 父类 |
|
* @param suffix 后缀 |
|
* @return 类型 |
|
*/ |
|
public int showSaveDialog(Component parent, String suffix) { |
|
return showDialog(parent, JFileChooser.SAVE_DIALOG, suffix); |
|
} |
|
|
|
/** |
|
* august:控件的事件都在这里面添加的 那么我每次showDialog,不都要重复添加一次事件吗?无语了 |
|
* |
|
* @param parent 父类 |
|
* @param type 类型 |
|
* @param suffix 后缀 |
|
* @return 类型 |
|
*/ |
|
public int showDialog(Component parent, int type, String suffix) { |
|
this.type = type; |
|
this.suffix = suffix; |
|
|
|
dialog = showWindow(parent instanceof DesignerFrame ? (Window) parent : SwingUtilities.getWindowAncestor(parent), false); |
|
JPanel contentPane = (JPanel) dialog.getContentPane(); |
|
contentPane.setLayout(FRGUIPaneFactory.createM_BorderLayout()); |
|
contentPane.add(this, BorderLayout.CENTER); |
|
okButton.setText(dialogName()); |
|
// kel:打开界面的时候让文本域获得焦点,支持enter打开或保存。 |
|
dialog.addWindowListener(new WindowAdapter() { |
|
@Override |
|
public void windowActivated(WindowEvent e) { |
|
fileNameTextField.requestFocusInWindow(); |
|
} |
|
|
|
@Override |
|
public void windowClosing(WindowEvent e) { |
|
option = CANCEL_OPTION; |
|
dialogExit(); |
|
} |
|
}); |
|
|
|
// neil:默认打开pane里显示所有支持的格式 |
|
// daniel 从templateFileTree中取 |
|
if (!showWebReport && filterList.isEmpty()) { |
|
fileType(); |
|
} |
|
chooseType(); |
|
// richer:当文件类型被选定时,显示的文件就仅仅显示被选定的类型 |
|
// 如果是保存对话框,给个默认名字 |
|
if (type != JFileChooser.SAVE_DIALOG) { |
|
fileNameTextField.removeDocumentListener(); |
|
fileNameTextField.setText(""); |
|
fileNameTextField.addDocumentListener(); |
|
} |
|
dialog.setAlwaysOnTop(true); |
|
dialog.setVisible(true); |
|
return option; |
|
} |
|
|
|
protected void fileType() { |
|
String appName = ProductConstants.APP_NAME; |
|
JTemplate editing = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); |
|
if (editing == null || !editing.isChartBook()) { |
|
|
|
if (type == JFileChooser.OPEN_DIALOG) { |
|
ChooseFileFilter supportedTypes = new ChooseFileFilter(FRContext.getFileNodes().getSupportedTypes(), appName + Toolkit.i18nText("Fine-Design_Report_Template_File")); |
|
Set<ReportSupportedFileProvider> providers = ExtraReportClassManager.getInstance().getArray(ReportSupportedFileProvider.XML_TAG); |
|
for (ReportSupportedFileProvider provider : providers) { |
|
for (FileExtension fileExtension : provider.getFileExtensions()){ |
|
supportedTypes.addExtension(fileExtension.getExtension()); |
|
} |
|
} |
|
this.addChooseFILEFilter(supportedTypes); |
|
} |
|
|
|
// ben:filefilter设置初值为cpt过滤 |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPT, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPTX, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); |
|
|
|
// richer:form文件 daniel 改成三个字 |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.FRM, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); |
|
|
|
Set<ReportSupportedFileUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ReportSupportedFileUIProvider.XML_TAG); |
|
for (ReportSupportedFileUIProvider provider : providers) { |
|
provider.addChooseFileFilter(this, StringUtils.EMPTY); |
|
} |
|
} else { |
|
if (type == JFileChooser.OPEN_DIALOG) { |
|
this.addChooseFILEFilter(new ChooseFileFilter(EnumSet.of(FileExtension.XLS, FileExtension.XLSX), Toolkit.i18nText("Fine-Design_Basic_Import_Excel_Source"))); |
|
} |
|
} |
|
|
|
// 添加 xls 文件类型过滤 kt |
|
if (WorkContext.getCurrent().isLocal()) { //本地连接 |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.XLS, Toolkit.i18nText("Fine-Design_Basic_Import_Excel_Source"))); |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.XLSX, Toolkit.i18nText("Fine-Design_Basic_Import_Excel2007_Source"))); |
|
} |
|
if (FileExtension.PNG.matchExtension(suffix)) { |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.PNG, Toolkit.i18nText("Fine-Design_Basic_App_Export_png"))); |
|
} |
|
if (type == JFileChooser.SAVE_DIALOG) { |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.PDF, Toolkit.i18nText("Fine-Design_Basic_Import_Export_PDF"))); |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.SVG, Toolkit.i18nText("Fine-Design_Basic_Import_Export_SVG"))); |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CSV, Toolkit.i18nText("Fine-Design_Basic_Import_Export_CSV"))); |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.DOC, Toolkit.i18nText("Fine-Design_Basic_Import_Export_Word"))); |
|
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.TXT, Toolkit.i18nText("Fine-Design_Basic_Import_Export_Text"))); |
|
} |
|
|
|
} |
|
|
|
private void chooseType() { |
|
DefaultComboBoxModel defaultComboBoxModel = (DefaultComboBoxModel) postfixComboBox.getModel(); |
|
defaultComboBoxModel.removeAllElements(); |
|
for (FILEFilter filter : filterList) { |
|
defaultComboBoxModel.addElement(filter); |
|
} |
|
if (WorkContext.getCurrent().isLocal()) { //本地连接 |
|
if (!showWebReport) { |
|
defaultComboBoxModel.addElement(Toolkit.i18nText("Fine-Design_Basic_Utils_App_AllFiles") + "(*.*)"); |
|
} |
|
} |
|
// 默认选取的文件类型(.cpt)类型 |
|
if (!filterList.isEmpty()) { |
|
setFILEFilter(filterList.get(0)); |
|
defaultComboBoxModel.setSelectedItem(filterList.get(0)); |
|
} |
|
// richer:根据不同的文件类型显示不同的后缀名 |
|
EnumSet<FileExtension> fileExtensions = EnumSet.of( |
|
FileExtension.CPT, FileExtension.CPTX, FileExtension.FRM, FileExtension.FRMX, |
|
FileExtension.XLS, FileExtension.XLSX, FileExtension.PDF, FileExtension.SVG, |
|
FileExtension.CSV, FileExtension.DOC, FileExtension.TXT, FileExtension.PNG); |
|
for (FileExtension fileExtension : fileExtensions) { |
|
if (fileExtension.matchExtension(suffix)) { |
|
postfixComboBox.setSelectedIndex(suffixIndex(fileExtension.getExtension())); |
|
break; |
|
} |
|
} |
|
//jerry 26216 只保留.cpt .frm有用的格式,并且不可编辑 |
|
postfixComboBox.setEnabled(true); |
|
//只有一个类型时不可下拉 |
|
if (filterList.size() == 1) { |
|
postfixComboBox.setEnabled(false); |
|
} |
|
} |
|
|
|
private int suffixIndex(String extension) { |
|
for (int i = 0; i < filterList.size(); i++) { |
|
FILEFilter fileFilter = filterList.get(i); |
|
if (fileFilter.containsExtension(extension)) { |
|
return i; |
|
} |
|
} |
|
return 0; |
|
} |
|
|
|
|
|
private void doOK() { |
|
// 如果没有写文件名,不允许打开 or save |
|
if (fileNameTextField.getText().length() == 0) { |
|
return; |
|
} |
|
if (type == JFileChooser.OPEN_DIALOG) { |
|
if (this.subFileList.getSelectedValue() == null) { |
|
FILE file = this.getSelectedFILE(); |
|
if (file.exists()) { |
|
option = OK_OPTION; |
|
saveDictionary(); |
|
dialogExit(); |
|
} else { |
|
FineJOptionPane.showMessageDialog(this, Toolkit.i18nText("Fine-Design_Basic_App_Template_Report_Not_Exist")); |
|
return; |
|
} |
|
} |
|
|
|
// alex:NPE判断,因为可能没有选中子目录,直接在文本框中输入文件名 |
|
FILE selectedSubFile = (FILE) this.subFileList.getSelectedValue(); |
|
if (selectedSubFile != null && selectedSubFile.isDirectory()) { |
|
setSelectedDirectory((FILE) this.subFileList.getSelectedValue()); |
|
} else { |
|
option = OK_OPTION; |
|
saveDictionary(); |
|
dialogExit(); |
|
} |
|
} else if (type == JFileChooser.SAVE_DIALOG) { |
|
saveDialog(); |
|
|
|
} |
|
} |
|
|
|
|
|
private void saveDialog() { |
|
String filename = fileNameTextField.getText(); |
|
filename = calProperFileName(filename, (ChooseFileFilter) (postfixComboBox.getSelectedItem())); |
|
fileNameTextField.setText(filename); |
|
option = OK_OPTION; |
|
FILE selectedFile = this.getSelectedFILE(); |
|
|
|
if (access(selectedFile) && access(currentDirectory)) { |
|
if (selectedFile.exists()) { |
|
int selVal = FineJOptionPane.showConfirmDialog(dialog, Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Cover_The_Current_File") + " ?", |
|
Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); |
|
if (selVal == JOptionPane.YES_OPTION) { |
|
option = JOPTIONPANE_OK_OPTION; |
|
saveDictionary(); |
|
dialogExit(); |
|
} else { |
|
option = JOPTIONPANE_CANCEL_OPTION; |
|
} |
|
|
|
} else { |
|
dialogExit(); |
|
saveDictionary(); |
|
} |
|
} else { |
|
FineJOptionPane.showMessageDialog(FILEChooserPane.this, Toolkit.i18nText("Fine-Design_Basic_App_Privilege_No") + "!", Toolkit.i18nText("Fine-Design_Basic_App_File_Message"), JOptionPane.WARNING_MESSAGE); |
|
|
|
} |
|
} |
|
|
|
|
|
private boolean access(FILE selectedFile) { |
|
boolean access = true; |
|
try { |
|
if (selectedFile.isEnvFile() && selectedFile instanceof FileNodeFILE) { |
|
FileNodeFILE fileNodeFILE = ((FileNodeFILE) selectedFile); |
|
access = access && fileNodeFILE.hasFullAuth() && NodeAuthProcessor.getInstance().checkFileNodeAuth(new FileNode(fileNodeFILE.getPath(), fileNodeFILE.isDirectory())); |
|
} |
|
} catch (Exception e) { |
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
|
} |
|
return access; |
|
} |
|
|
|
private void saveDictionary() { |
|
FILE selectedFile = this.getSelectedFILE(); |
|
if (selectedFile != null) { |
|
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager(); |
|
String prefix = currentDirectory.prefix(); |
|
String path = currentDirectory.getPath(); |
|
designerEnvManager.setCurrentDirectoryPrefix(prefix); |
|
designerEnvManager.setDialogCurrentDirectory(path); |
|
designerEnvManager.saveXMLFile(); |
|
} |
|
} |
|
|
|
private void dialogExit() { |
|
|
|
if (dialog == null) { |
|
return; |
|
} |
|
dialog.setVisible(false); |
|
dialog.dispose(); |
|
dialog = null; |
|
} |
|
|
|
/* |
|
* dialog的名字 |
|
*/ |
|
private String dialogName() { |
|
return type == JFileChooser.OPEN_DIALOG ? Toolkit.i18nText("Fine-Design_Basic_Utils_Design_File_Open") : Toolkit.i18nText("Fine-Design_Basic_App_Template_Save"); |
|
} |
|
|
|
/* |
|
* 在subFileList中选中文件 |
|
*/ |
|
private void setSelectedFileName(String name) { |
|
if (name == null) { |
|
return; |
|
} |
|
|
|
ListModel model = subFileList.getModel(); |
|
for (int i = 0, len = model.getSize(); i < len; i++) { |
|
if (ComparatorUtils.equals(name, ((FILE) model.getElementAt(i)).getName())) { |
|
subFileList.setSelectedIndex(i); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
@Override |
|
protected String title4PopupWindow() { |
|
return dialogName(); |
|
} |
|
|
|
private void setPlaceListModel(AbstractPlaceListModel model) { |
|
if (placesList == null) { |
|
return; |
|
} |
|
placesList.setModel(model); |
|
String lastDirectoryPath = DesignerEnvManager.getEnvManager().getDialogCurrentDirectory(); |
|
String prefix = DesignerEnvManager.getEnvManager().getCurrentDirectoryPrefix(); |
|
FILE lastDirectory = FILEFactory.createFolder(prefix + lastDirectoryPath); |
|
|
|
model.setCD(lastDirectory); |
|
|
|
if (currentDirectory != null) { |
|
return; |
|
} |
|
// b:这里应该是currentDirectory为空时尝试从envmanager取,最后FileSystemView,和this.env有啥关系 |
|
if (StringUtils.isNotBlank(DesignerEnvManager.getEnvManager().getDialogCurrentDirectory())) { |
|
currentDirectory = FILEFactory.createFolder(DesignerEnvManager.getEnvManager().getDialogCurrentDirectory()); |
|
} else { |
|
currentDirectory = FILEFactory.createFolder(FileSystemView.getFileSystemView().getHomeDirectory().getPath()); |
|
} |
|
if (currentDirectory != null && currentDirectory.exists()) { |
|
this.setCurrentDirectory(currentDirectory); |
|
} |
|
} |
|
|
|
private void setPlaceListModel() { |
|
if (placesList == null) { |
|
return; |
|
} |
|
setPlaceListModel(new PlaceListModel()); |
|
} |
|
|
|
private void setMultiPlaceListModel() { |
|
if (placesList == null) { |
|
return; |
|
} |
|
setPlaceListModel(new MultiLocalEnvPlaceListModel()); |
|
} |
|
|
|
/* |
|
* 选中文件 |
|
*/ |
|
private void setFileTextField(FILE file) { |
|
if (file != null && !file.isDirectory()) { |
|
fileNameTextField.setText(file.getName()); |
|
if (file instanceof FileFILE) { |
|
fileNameTextField.setText(((FileFILE) file).getTotalName()); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* Sets the current directory. Passing in <code>null</code> sets the file |
|
* chooser to point to the user's default directory. |
|
* |
|
* @param dir the current directory to point to |
|
* @see #setSelectedDirectory |
|
*/ |
|
public void setCurrentDirectory(FILE dir) { |
|
if (dir == null && placesList != null) { |
|
dir = (FILE) placesList.getModel().getElementAt(0); |
|
placesList.setSelectedIndex(0); |
|
} |
|
|
|
if (placesList != null) { |
|
if (ComparatorUtils.equals(dir.prefix(), FILEFactory.ENV_PREFIX) || dir.prefix().endsWith(FILEFactory.WEBREPORT_PREFIX)) { |
|
placesList.setSelectedIndex(0); |
|
} else if (ComparatorUtils.equals(dir.prefix(), FILEFactory.FILE_PREFIX)) { |
|
AbstractPlaceListModel defaultListModel = (AbstractPlaceListModel) placesList.getModel(); |
|
for (int i = 0; i < defaultListModel.getSize(); i++) { |
|
if (defaultListModel.getElementAt(i) instanceof FileFILE) { |
|
FileFILE popDir = (FileFILE) defaultListModel.getElementAt(i); |
|
if (popDir != null && dir.getPath().indexOf(popDir.getPath()) == 0) { |
|
placesList.setSelectedIndex(i); |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
setSelectedDirectory(dir); |
|
} |
|
|
|
/* |
|
* Set Selected Directory 在右侧的subFileList中显示dir下面的所有文件和文件夹 |
|
*/ |
|
private void setSelectedDirectory(FILE dir) { |
|
if (ComparatorUtils.equals(currentDirectory, dir) || dir == null || !dir.isDirectory()) { |
|
return; |
|
} |
|
|
|
currentDirectory = dir; |
|
|
|
this.locationBtnPane.populate(currentDirectory); |
|
this.mkdirButton.setEnabled(currentDirectory != null); |
|
|
|
refreshSubFileListModel(); |
|
} |
|
|
|
/* |
|
* 刷新右侧的SubFileList |
|
*/ |
|
private void refreshSubFileListModel() { |
|
if (currentDirectory != null) { |
|
((DefaultListModel) subFileList.getModel()).removeAllElements(); |
|
|
|
FILE[] res_array = currentDirectory.listFiles(); |
|
((DefaultListModel) subFileList.getModel()).removeAllElements(); |
|
for (int i = 0; i < res_array.length; i++) { |
|
if (filter == null || filter.accept(res_array[i])) { |
|
((DefaultListModel) subFileList.getModel()).addElement(res_array[i]); |
|
} |
|
} |
|
String[] name_array = new String[res_array.length]; |
|
for (int i = 0; i < res_array.length; i++) { |
|
name_array[i] = res_array[i].getName(); |
|
} |
|
fileNameTextField.setFilter(new DefaultCompletionFilter(name_array)); |
|
subFileList.validate(); |
|
subFileList.repaint(10); |
|
} |
|
} |
|
|
|
private abstract class AbstractPlaceListModel extends AbstractListModel<FILE> { |
|
|
|
protected List<FileFILE> filesOfSystem = new ArrayList<FileFILE>(); |
|
|
|
protected void processSystemFile() { |
|
if (WindowsDetector.detect(true)) { |
|
// windows下展示桌面 |
|
File[] desktop = FileSystemView.getFileSystemView().getRoots(); |
|
if (desktop != null) { |
|
for (int i = 0; i < desktop.length; i++) { |
|
if (desktop[i].exists()) { |
|
filesOfSystem.add(new FileFILE(desktop[i])); |
|
} |
|
} |
|
} |
|
} else { |
|
// *nix下展示家目录 |
|
filesOfSystem.add(new FileFILE(FileSystemView.getFileSystemView().getDefaultDirectory())); |
|
} |
|
|
|
// C, D, E等盘符 |
|
File[] roots = File.listRoots(); |
|
if (roots != null) { |
|
for (int i = 0; i < roots.length; i++) { |
|
if (roots[i].exists()) { |
|
filesOfSystem.add(new FileFILE(roots[i])); |
|
} |
|
} |
|
} |
|
} |
|
|
|
protected void setCD(final FILE lastDirectory) { |
|
for (int i = 0; i < this.getSize(); i++) { |
|
FILE file = this.getElementAt(i); |
|
if (ComparatorUtils.equals(lastDirectory.prefix(), file.prefix())) { |
|
setCurrentDirectory(lastDirectory); |
|
return; |
|
} |
|
} |
|
setCurrentDirectory(this.getElementAt(0)); |
|
} |
|
} |
|
|
|
private class PlaceListModel extends AbstractPlaceListModel { |
|
private FileNodeFILE envFILE; |
|
private FileNodeFILE webReportFILE; |
|
|
|
PlaceListModel() { |
|
if (FILEChooserPane.this.showEnv) { |
|
envFILE = new FileNodeFILE(new FileNode(ProjectConstants.REPORTLETS_NAME, true)) { |
|
@Override |
|
public String getName() { |
|
return getEnvProjectName(); |
|
} |
|
}; |
|
} |
|
if (FILEChooserPane.this.showWebReport) { |
|
webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath); |
|
} |
|
if (FILEChooserPane.this.showLoc) { |
|
processSystemFile(); |
|
} |
|
} |
|
|
|
@Override |
|
public FILE getElementAt(int index) { |
|
int n = FILEChooserPane.this.showEnv ? 1 : 0; |
|
int n2 = FILEChooserPane.this.showWebReport ? 1 : 0; |
|
|
|
if (index < n) { |
|
return envFILE; |
|
} else if (index < n + n2) { |
|
return webReportFILE; |
|
} else if (index < n + n2 + filesOfSystem.size()) { |
|
return filesOfSystem.get(index - n - n2); |
|
} |
|
throw new IndexOutOfBoundsException(); |
|
} |
|
|
|
@Override |
|
public int getSize() { |
|
if (FILEChooserPane.this.showEnv && FILEChooserPane.this.showWebReport) { |
|
return 2 + filesOfSystem.size(); |
|
} else if (FILEChooserPane.this.showEnv || FILEChooserPane.this.showWebReport) { |
|
return 1 + filesOfSystem.size(); |
|
} else { |
|
return filesOfSystem.size(); |
|
} |
|
} |
|
|
|
} |
|
|
|
private class MultiLocalEnvPlaceListModel extends AbstractPlaceListModel { |
|
|
|
private List<FileFILE> envFiles = new ArrayList<FileFILE>(); |
|
private FileNodeFILE webReportFILE; |
|
|
|
MultiLocalEnvPlaceListModel() { |
|
Iterator<String> iterator = DesignerEnvManager.getEnvManager().getEnvNameIterator(); |
|
|
|
while (iterator.hasNext()) { |
|
final String envName = iterator.next(); |
|
DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(envName); |
|
if (info.getType() == DesignerWorkspaceType.Local) { |
|
FileFILE fileFILE = |
|
new FileFILE(new File(info.getPath() + CoreConstants.SEPARATOR + ProjectConstants.REPORTLETS_NAME)) { |
|
@Override |
|
public String getName() { |
|
return envName; |
|
} |
|
}; |
|
if (fileFILE.exists() && fileFILE.isDirectory()) { |
|
envFiles.add(fileFILE); |
|
} |
|
} |
|
} |
|
|
|
if (FILEChooserPane.this.showWebReport) { |
|
webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath); |
|
} |
|
if (FILEChooserPane.this.showLoc) { |
|
processSystemFile(); |
|
} |
|
} |
|
|
|
@Override |
|
public FILE getElementAt(int index) { |
|
int envCount = envFiles.size(); |
|
int webReportCount = FILEChooserPane.this.showWebReport ? 1 : 0; |
|
|
|
if (index < envCount) { |
|
return envFiles.get(index); |
|
} else if (index < envCount + webReportCount) { |
|
return webReportFILE; |
|
} else if (index < envCount + webReportCount + filesOfSystem.size()) { |
|
return filesOfSystem.get(index - envCount - webReportCount); |
|
} |
|
throw new IndexOutOfBoundsException(); |
|
} |
|
|
|
@Override |
|
public int getSize() { |
|
int webReportCount = FILEChooserPane.this.showWebReport ? 1 : 0; |
|
return envFiles.size() + filesOfSystem.size() + webReportCount; |
|
} |
|
|
|
private class FileFILE extends com.fr.file.FileFILE { |
|
|
|
public FileFILE(File file) { |
|
super(file); |
|
} |
|
|
|
@Override |
|
public Icon getIcon() { |
|
if (ComparatorUtils.equals(getTotalName(), ProjectConstants.REPORTLETS_NAME)) { |
|
return BaseUtils.readIcon("/com/fr/base/images/oem/logo.png"); |
|
} else { |
|
return FileTreeIcon.getIcon(new File(this.getPath()), false); |
|
} |
|
} |
|
|
|
@Override |
|
public FILE[] listFiles() { |
|
FILE[] fileFILES = super.listFiles(); |
|
|
|
List<FileFILE> results = new ArrayList<>(); |
|
|
|
for (FILE fileFILE : fileFILES) { |
|
results.add(new FileFILE(new File(fileFILE.getPath()))); |
|
} |
|
|
|
return results.toArray(new FILE[results.size()]); |
|
} |
|
} |
|
} |
|
|
|
/* |
|
* 上面的LocationButtonPane |
|
*/ |
|
private class LocationButtonPane extends JPanel { |
|
private FILE popDir; |
|
|
|
private BasicArrowButton leftArrowButton; |
|
private BasicArrowButton rightArrowButton; |
|
|
|
private List<UIButton> buttonList = new ArrayList<>(); |
|
private int pathIndex = 0; |
|
private int maxPathIndex = 0; |
|
|
|
public LocationButtonPane() { |
|
this.setLayout(FRGUIPaneFactory.createBoxFlowLayout()); |
|
|
|
leftArrowButton = new BasicArrowButton(BasicArrowButton.WEST) { |
|
@Override |
|
public Dimension getPreferredSize() { |
|
return new Dimension(21, 21); |
|
} |
|
}; |
|
leftArrowButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
if (pathIndex > 0) { |
|
pathIndex--; |
|
} |
|
LocationButtonPane.this.doLayout(); |
|
LocationButtonPane.this.repaint(10); |
|
} |
|
}); |
|
|
|
rightArrowButton = new BasicArrowButton(BasicArrowButton.EAST) { |
|
@Override |
|
public Dimension getPreferredSize() { |
|
return new Dimension(21, 21); |
|
} |
|
}; |
|
rightArrowButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent e) { |
|
if (pathIndex < maxPathIndex) { |
|
pathIndex++; |
|
} |
|
LocationButtonPane.this.doLayout(); |
|
LocationButtonPane.this.repaint(10); |
|
} |
|
}); |
|
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener<Workspace>() { |
|
@Override |
|
public void on(Event event, Workspace param) { |
|
setPopDir(null); |
|
} |
|
}); |
|
} |
|
|
|
public void highLightButton(FILE dir) { |
|
for (int i = 0; i < this.buttonList.size(); i++) { |
|
this.buttonList.get(i).setForeground(null); |
|
if (((SetDirectoryAction) this.buttonList.get(i).getAction()).getDir() != null |
|
&& this.buttonList.get(i).getAction() instanceof SetDirectoryAction |
|
&& (ComparatorUtils.equals(((SetDirectoryAction) this.buttonList.get(i).getAction()).getDir().getPath(), dir.getPath()))) { |
|
|
|
this.buttonList.get(i).setForeground(Color.BLUE); |
|
} |
|
} |
|
} |
|
|
|
public void setPopDir(FILE file) { |
|
popDir = file; |
|
} |
|
|
|
public void populate(FILE dir) { |
|
if (popDir != null && dir != null && popDir.toString().indexOf(dir.toString()) == 0) { |
|
highLightButton(dir); |
|
return; |
|
} |
|
|
|
boolean isWebAppNamePath; |
|
popDir = dir; |
|
this.buttonList.clear(); |
|
|
|
if (dir == null) { |
|
return; |
|
} |
|
String path = dir.getPath(); |
|
isWebAppNamePath = ComparatorUtils.equals(dir.prefix(), FILEFactory.WEBREPORT_PREFIX); |
|
// 确保最后一个字符是分隔符 |
|
if (!path.endsWith("/") && !path.endsWith("\\") && !StringUtils.isBlank(path)) { |
|
path = path + "/"; |
|
} |
|
String webAppName = GeneralContext.getCurrentAppNameOfEnv(); |
|
if (StringUtils.isBlank(path) && isWebAppNamePath) { |
|
this.buttonList.add(createBlankButton(new SetDirectoryAction(webAppName + '/'))); |
|
} |
|
Matcher matcher = SEPARATOR_PATTERN.matcher(path); |
|
int node_start = 0; |
|
while (matcher.find()) { |
|
int start = matcher.start(); |
|
String btn_text = path.substring(node_start, start); |
|
String btn_path = path.substring(0, start); |
|
if (StringUtils.isBlank(btn_text) && isWebAppNamePath) { |
|
btn_text = webAppName; |
|
} |
|
this.buttonList.add(createBlankButton((new SetDirectoryAction(btn_text + '/', |
|
// alex:dir.prefix不和btn_path一起参与pathJoin,因为btn_path是否以/打头在unix,linux |
|
// OS中意义很不一样 |
|
FILEFactory.createFolder(dir.prefix() + StableUtils.pathJoin(btn_path, "/")))))); |
|
node_start = matcher.end(); |
|
} |
|
maxPathIndex = calculateMaxPathIndex(); |
|
|
|
pathIndex = maxPathIndex; |
|
this.doLayout(); |
|
this.repaint(10); |
|
|
|
// 高亮显示当前目录 |
|
highLightButton(dir); |
|
} |
|
|
|
// doLayout |
|
@Override |
|
public void doLayout() { |
|
this.removeAll(); |
|
|
|
if (popDir == null) { |
|
return; |
|
} |
|
|
|
int pathWidth = 0; |
|
// 前缀 |
|
// UILabel prefixLabel = new UILabel(popDir.prefix()); |
|
// this.add(prefixLabel); |
|
// pathWidth += prefixLabel.getPreferredSize().width; |
|
|
|
// pathWidth |
|
for (int i = 0; i < buttonList.size(); i++) { |
|
pathWidth += buttonList.get(i).getPreferredSize().width; |
|
} |
|
|
|
// 当path按钮的长度超出显示范围时,隐藏 |
|
if (this.getWidth() < pathWidth) { |
|
int tmpWidth = leftArrowButton.getPreferredSize().width + leftArrowButton.getPreferredSize().width; |
|
int oldTmpWidth = tmpWidth; |
|
for (int i = pathIndex; i < buttonList.size(); i++) { |
|
tmpWidth += buttonList.get(i).getPreferredSize().width; |
|
if (tmpWidth > this.getWidth()) { |
|
break; |
|
} |
|
|
|
|
|
this.add(buttonList.get(i)); |
|
oldTmpWidth = tmpWidth; |
|
} |
|
UILabel blankLabel = new UILabel(""); |
|
blankLabel.setPreferredSize(new Dimension(this.getWidth() - oldTmpWidth - 1, blankLabel.getPreferredSize().height)); |
|
this.add(blankLabel); |
|
// leftArrowButton |
|
this.add(leftArrowButton, 1); |
|
// rightArrowButton |
|
this.add(rightArrowButton); |
|
} else { |
|
pathIndex = 0; |
|
for (int i = 0; i < buttonList.size(); i++) { |
|
this.add(buttonList.get(i)); |
|
} |
|
} |
|
|
|
super.doLayout(); |
|
} |
|
|
|
private int calculateMaxPathIndex() { |
|
if (popDir == null) { |
|
return 0; |
|
} |
|
|
|
int pathWidth = 0; |
|
// 前缀 |
|
UILabel prefixLabel = new UILabel(popDir.prefix()); |
|
pathWidth += prefixLabel.getPreferredSize().width; |
|
|
|
for (int i = 0; i < buttonList.size(); i++) { |
|
pathWidth += buttonList.get(i).getPreferredSize().width; |
|
} |
|
|
|
if (this.getWidth() < pathWidth) { |
|
int index = 0; |
|
|
|
int tmpWidth = prefixLabel.getPreferredSize().width + leftArrowButton.getPreferredSize().width |
|
+ leftArrowButton.getPreferredSize().width; |
|
for (int i = buttonList.size() - 1; i >= 0; i--) { |
|
tmpWidth += buttonList.get(i).getPreferredSize().width; |
|
if (tmpWidth > this.getWidth()) { |
|
break; |
|
} |
|
index = i; |
|
} |
|
|
|
return index; |
|
} |
|
// 当长度足够时,不出现左右的按钮,皆从0开始显示 |
|
else { |
|
return 0; |
|
} |
|
} |
|
} |
|
|
|
private class SetDirectoryAction extends UpdateAction { |
|
private FILE dir; |
|
|
|
public SetDirectoryAction(String name) { |
|
this.setName(name); |
|
// this.dir = file; |
|
} |
|
|
|
public SetDirectoryAction(String name, FILE file) { |
|
this.setName(name); |
|
this.dir = file; |
|
} |
|
|
|
@Override |
|
public void actionPerformed(ActionEvent evt) { |
|
if (dir != null) { |
|
setSelectedDirectory(dir); |
|
} |
|
} |
|
|
|
public FILE getDir() { |
|
return dir; |
|
} |
|
} |
|
|
|
|
|
private UIButton createBlankButton(SetDirectoryAction setDirectoryAction) { |
|
|
|
final Color brighter = this.getBackground().brighter(); |
|
final Color darker = this.getBackground().darker(); |
|
|
|
final UIButton blankButton = new UIButton(setDirectoryAction); |
|
blankButton.setMargin(new Insets(0, 0, 0, 0)); |
|
blankButton.setUI(new BasicButtonUI()); |
|
blankButton.setHorizontalTextPosition(SwingConstants.CENTER); |
|
blankButton.setBorderPainted(false); |
|
blankButton.setBorder(BorderFactory.createRaisedBevelBorder()); |
|
blankButton.setBackground(darker); |
|
blankButton.addMouseListener(new MouseAdapter() { |
|
@Override |
|
public void mouseEntered(MouseEvent e) { |
|
blankButton.setBackground(brighter); |
|
blankButton.setBorderPainted(true); |
|
blankButton.repaint(); |
|
} |
|
|
|
@Override |
|
public void mouseExited(MouseEvent e) { |
|
blankButton.setBackground(darker); |
|
blankButton.setBorderPainted(false); |
|
blankButton.repaint(); |
|
} |
|
|
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
blankButton.setBackground(brighter); |
|
blankButton.setBorderPainted(false); |
|
blankButton.repaint(); |
|
} |
|
|
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
blankButton.setBackground(darker); |
|
blankButton.setBorderPainted(true); |
|
blankButton.repaint(); |
|
} |
|
|
|
|
|
}); |
|
return blankButton; |
|
} |
|
|
|
/* |
|
* 新建文件夹的Button |
|
*/ |
|
private UIButton initMkdirButton() { |
|
UIButton folderButton = new UIButton(); |
|
folderButton.setIcon(BaseUtils.readIcon("com/fr/design/images/icon_NewFolderIcon_normal.png")); |
|
folderButton.setUI(new UIButtonUI()); |
|
folderButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Utils_New_Folder")); |
|
folderButton.addActionListener(new ActionListener() { |
|
@Override |
|
public void actionPerformed(ActionEvent evt) { |
|
if (currentDirectory == null) { |
|
return; |
|
} |
|
|
|
if (access(currentDirectory)) { |
|
new MkdirDialog(); |
|
} else { |
|
FineJOptionPane.showMessageDialog( |
|
FILEChooserPane.this, |
|
Toolkit.i18nText("Fine-Design_Basic_App_Privilege_No") + "!", |
|
Toolkit.i18nText("Fine-Design_Basic_App_File_Message"), |
|
JOptionPane.WARNING_MESSAGE); |
|
} |
|
|
|
|
|
} |
|
}); |
|
return folderButton; |
|
} |
|
|
|
|
|
/** |
|
* 新建文件夹对话框 |
|
* 支持快捷键Enter,ESC |
|
*/ |
|
private class MkdirDialog extends JDialog { |
|
|
|
private UITextField nameField; |
|
|
|
private UILabel warnLabel; |
|
|
|
private UIButton confirmButton; |
|
|
|
|
|
private MkdirDialog() { |
|
|
|
this.setLayout(new BorderLayout()); |
|
this.setModal(true); |
|
|
|
// 输入框前提示 |
|
UILabel newNameLabel = new UILabel(Toolkit.i18nText( |
|
"Fine-Design_Basic_Enter_New_Folder_Name") |
|
); |
|
newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); |
|
newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); |
|
newNameLabel.setPreferredSize(new Dimension(118, 15)); |
|
|
|
// 文件名输入框 |
|
nameField = new UITextField(); |
|
nameField.getDocument().addDocumentListener(new DocumentListener() { |
|
|
|
public void changedUpdate(DocumentEvent e) { |
|
validInput(); |
|
} |
|
|
|
public void insertUpdate(DocumentEvent e) { |
|
validInput(); |
|
} |
|
|
|
public void removeUpdate(DocumentEvent e) { |
|
validInput(); |
|
} |
|
}); |
|
nameField.selectAll(); |
|
nameField.setPreferredSize(new Dimension(180, 20)); |
|
|
|
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); |
|
topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); |
|
topPanel.add(newNameLabel); |
|
topPanel.add(nameField); |
|
|
|
// 增加enter以及esc快捷键的支持 |
|
nameField.addKeyListener(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(); |
|
} |
|
} |
|
} |
|
}); |
|
// 重名提示 |
|
warnLabel = new UILabel(); |
|
warnLabel.setPreferredSize(new Dimension(300, 30)); |
|
warnLabel.setHorizontalAlignment(SwingConstants.LEFT); |
|
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.WEST); |
|
|
|
// 确认按钮 |
|
confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm")); |
|
confirmButton.setPreferredSize(new Dimension(60, 25)); |
|
confirmButton.addActionListener(new ActionListener() { |
|
public void actionPerformed(ActionEvent e) { |
|
confirmClose(); |
|
} |
|
}); |
|
|
|
// 取消按钮 |
|
UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")); |
|
cancelButton.setPreferredSize(new Dimension(60, 25)); |
|
|
|
cancelButton.addActionListener(new ActionListener() { |
|
|
|
public void actionPerformed(ActionEvent e) { |
|
dispose(); |
|
} |
|
}); |
|
|
|
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); |
|
bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); |
|
bottomPanel.add(confirmButton); |
|
bottomPanel.add(cancelButton); |
|
|
|
this.add( |
|
TableLayoutHelper.createTableLayoutPane( |
|
new Component[][]{ |
|
new Component[]{topPanel}, |
|
new Component[]{midPanel}, |
|
new Component[]{bottomPanel} |
|
}, |
|
new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL}, |
|
new double[]{TableLayout.FILL} |
|
), |
|
BorderLayout.CENTER); |
|
|
|
|
|
this.setSize(340, 180); |
|
this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Mkdir")); |
|
this.setResizable(false); |
|
this.setAlwaysOnTop(true); |
|
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() { |
|
|
|
String userInput = nameField.getText().trim(); |
|
|
|
// 处理不合法的文件夹名称 |
|
userInput = userInput.replaceAll("[\\\\/:*?\"<>|]", StringUtils.EMPTY); |
|
|
|
if (currentDirectory.createFolder(userInput)) { |
|
refreshSubFileListModel(); |
|
setSelectedFileName(userInput); |
|
// ben:这里处理有些不妥,取文件时没有考虑filefilter,不过效果一样,取的时候应该用subfilelist得data |
|
FILE[] allFiles = currentDirectory.listFiles(); |
|
int place = 0; |
|
for (int i = 0; i < allFiles.length; i++) { |
|
if (ComparatorUtils.equals(allFiles[i].getName(), userInput) && allFiles[i].isDirectory()) { |
|
place = i; |
|
break; |
|
} |
|
} |
|
scrollPane.revalidate(); |
|
scrollPane.repaint(); |
|
int total = scrollPane.getVerticalScrollBar().getMaximum(); |
|
int value = total * place / subFileList.getModel().getSize(); |
|
scrollPane.getVerticalScrollBar().setValue(value); |
|
|
|
} else { |
|
FineJOptionPane.showConfirmDialog(FILEChooserPane.this, |
|
Toolkit.i18nText("Fine-Design_Basic_Make_Failure"), |
|
Toolkit.i18nText("Fine-Design_Basic_Error"), |
|
JOptionPane.DEFAULT_OPTION, |
|
JOptionPane.ERROR_MESSAGE); |
|
} |
|
this.dispose(); |
|
} |
|
|
|
|
|
private void validInput() { |
|
|
|
String userInput = nameField.getText().trim(); |
|
|
|
if (StringUtils.isEmpty(userInput)) { |
|
confirmButton.setEnabled(false); |
|
} |
|
|
|
boolean duplicate = false; |
|
// ben:这里处理有些不妥,取文件时没有考虑filefilter,不过效果一样,取的时候应该用subfilelist得data |
|
FILE[] allFiles = currentDirectory.listFiles(); |
|
for (int i = 0; i < allFiles.length; i++) { |
|
if (ComparatorUtils.equals(allFiles[i].getName(), userInput) && allFiles[i].isDirectory()) { |
|
duplicate = true; |
|
break; |
|
} |
|
} |
|
|
|
if (duplicate) { |
|
nameField.selectAll(); |
|
// 如果文件名已存在,则灰掉确认按钮 |
|
warnLabel.setText( |
|
Toolkit.i18nText( |
|
"Fine-Design_Basic_Folder_Name_Duplicate", |
|
userInput)); |
|
warnLabel.setVisible(true); |
|
confirmButton.setEnabled(false); |
|
} else { |
|
warnLabel.setVisible(false); |
|
confirmButton.setEnabled(true); |
|
} |
|
} |
|
} |
|
}
|
|
|