From 3752c38f176805e9c3c4defed6b3b5310b7a7a7a Mon Sep 17 00:00:00 2001 From: "yaoh.wu" Date: Tue, 28 Aug 2018 15:04:24 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-10689=20=E8=BF=9C=E7=A8=8B=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=96=B0=E5=BB=BA=E5=88=A0=E9=99=A4=E5=92=8C=E9=87=8D?= =?UTF-8?q?=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/DesignerEnvManager.java | 38 +- .../com/fr/design/file/FileOperations.java | 77 +- .../design/file/HistoryTemplateListCache.java | 291 ++++++ .../design/file/HistoryTemplateListPane.java | 451 +--------- .../com/fr/design/file/NodeAuthProcessor.java | 225 +++++ .../com/fr/design/file/TemplateTreePane.java | 340 +++++-- .../gui/itree/filetree/TemplateFileTree.java | 136 +-- .../DesignerFrameFileDealerPane.java | 670 ++++++++------ .../java/com/fr/design/menu/KeySetUtils.java | 68 +- .../src/main/java/com/fr/file/FILE.java | 71 +- .../java/com/fr/file/FILEChooserPane.java | 831 +++++++++++------- .../main/java/com/fr/file/FILEFactory.java | 6 +- .../src/main/java/com/fr/file/FileFILE.java | 65 +- .../main/java/com/fr/file/FileNodeFILE.java | 239 +++-- .../src/main/java/com/fr/file/MemFILE.java | 7 +- .../images/icon_NewFolderIcon_normal.png | Bin 0 -> 288 bytes 16 files changed, 2057 insertions(+), 1458 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java create mode 100644 designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java create mode 100644 designer-base/src/main/resources/com/fr/design/images/icon_NewFolderIcon_normal.png diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index 8e6b1e26e..16d00156b 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -41,9 +41,10 @@ import com.fr.stable.xml.XMLableReader; import com.fr.workspace.WorkContext; import com.fr.workspace.WorkContextCallback; -import javax.swing.*; +import javax.swing.SwingWorker; import javax.swing.SwingWorker.StateValue; -import java.awt.*; +import java.awt.Color; +import java.awt.Rectangle; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; @@ -57,6 +58,7 @@ import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; @@ -482,7 +484,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { public void setLastEastRegionContainerWidth(int eastRegionContainerWidth) { this.eastRegionContainerWidth = eastRegionContainerWidth; } - + /** * 返回默认环境 */ @@ -544,7 +546,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { DesignerEnvManager.getEnvManager().setCurEnvName(envName); DesignUtils.refreshDesignerFrame(); - if(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate() != null) { + if (HistoryTemplateListPane.getInstance().getCurrentEditingTemplate() != null) { HistoryTemplateListPane.getInstance().getCurrentEditingTemplate().refreshToolArea(); } DesignTableDataManager.fireDSChanged(new HashMap()); @@ -866,12 +868,38 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { public void replaceRecentOpenedFilePath(String oldPath, String newPath) { List list = getRecentOpenedFilePathList(); if (list.contains(oldPath)) { - int index = getRecentOpenedFilePathList().indexOf(oldPath); + int index = list.indexOf(oldPath); + list.remove(oldPath); + list.add(index, newPath); + } + oldPath = oldPath.replaceAll("\\\\", "/"); + if (list.contains(oldPath)) { + int index = list.indexOf(oldPath); list.remove(oldPath); list.add(index, newPath); } } + /** + * 替换近期打开的文件路径 + * + * @param type 文件类型,文件夹true,文件false + * @param oldPath 旧的路径 使用反斜杠分割 + * @param newPath 新的路径 使用反斜杠分割 + */ + public void replaceRecentOpenedFilePath(boolean type, String oldPath, String newPath) { + List list = getRecentOpenedFilePathList(); + ListIterator iterator = list.listIterator(); + + while (iterator.hasNext()) { + String s = iterator.next().replaceAll("/", "\\\\"); + if (type ? s.contains(oldPath + "\\") : s.equals(oldPath)) { + s = s.replace(oldPath, newPath); + iterator.set(s); + } + } + } + private void checkRecentOpenedFileNum() { List list = getRecentOpenedFilePathList(); if (list == null) { diff --git a/designer-base/src/main/java/com/fr/design/file/FileOperations.java b/designer-base/src/main/java/com/fr/design/file/FileOperations.java index 34b86cbc6..6509142a4 100644 --- a/designer-base/src/main/java/com/fr/design/file/FileOperations.java +++ b/designer-base/src/main/java/com/fr/design/file/FileOperations.java @@ -1,45 +1,88 @@ package com.fr.design.file; +import com.fr.file.FILE; +import com.fr.file.filetree.FileNode; + public interface FileOperations { + + /** + * 新建文件夹 + * + * @param name 文件夹名称 + * @return 是否成功 + */ + boolean mkdir(String name); + + /** + * 打开报表文件 + */ + void openFile(); + + /** + * 打开文件夹 + */ + void showInExplorer(); + + /** + * 刷新 + */ + void refresh(); + /** - *打开选中的报表文件 + * 删除文件 */ - public void openSelectedReport(); + void deleteFile(); /** - *打开文件夹 + * 加上文件锁 */ - public void openContainerFolder(); + void lockFile(); /** - *刷新 + * 文件解锁 */ - public void refresh(); + void unlockFile(); + + /** + * 选中的模板路径 + * + * @return 选中的模板路径 + */ + String getFilePath(); + /** - *删除文件 + * 选中的文件节点 + * + * @return 文件节点 */ - public void deleteFile(); + FileNode getFileNode(); /** - *加上文件锁 + * 是否有完整权限 + * + * @return 是否有完整权限 */ - public void lockFile(); + boolean access(); /** - *文件解锁 + * 重命名 + * + * @param tplFile 旧文件 + * @param to 新文件名 + * @param from 旧文件名 + * @return 是否成功 */ - public void unLockFile(); + boolean rename(FILE tplFile, String from, String to); - public String getSelectedTemplatePath(); /** - *文件名是否存在 + * 文件名是否存在 + * * @param newName 原名 - * @param oldName 新的文件名 - * @param suffix 后缀名 + * @param suffix 后缀名 * @return 是否存在 */ - public boolean isNameAlreadyExist(String newName, String oldName, String suffix); + boolean duplicated(String newName, String suffix); } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java new file mode 100644 index 000000000..13fd85955 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java @@ -0,0 +1,291 @@ +package com.fr.design.file; + +import com.fr.base.chart.chartdata.CallbackEvent; +import com.fr.design.DesignerEnvManager; +import com.fr.design.data.DesignTableDataManager; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.module.DesignModuleFactory; +import com.fr.file.FILE; +import com.fr.file.FileNodeFILE; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; + +/** + * 历史模板缓存 + * + * @see HistoryTemplateListPane + */ +public class HistoryTemplateListCache implements CallbackEvent { + + //最大保存内存中面板数,为0时关闭优化内存 + private static final int DEAD_LINE = DesignerEnvManager.getEnvManager().getCachingTemplateLimit(); + private List> historyList; + private JTemplate editingTemplate; + + private static volatile HistoryTemplateListCache THIS; + + public static HistoryTemplateListCache getInstance() { + if (THIS == null) { + synchronized (HistoryTemplateListCache.class) { + if (THIS == null) { + THIS = new HistoryTemplateListCache(); + } + } + } + return THIS; + } + + private HistoryTemplateListCache() { + historyList = new ArrayList<>(); + } + + /** + * 关闭选择的文件 + * + * @param selected 选择的 + */ + public void closeSelectedReport(JTemplate selected) { + DesignModuleFactory.clearChartPropertyPane(); + DesignTableDataManager.closeTemplate(selected); + if (contains(selected) == -1) { + return; + } + selected.fireJTemplateClosed(); + selected.stopEditing(); + try { + historyList.remove(contains(selected)); + selected.getEditingFILE().closeTemplate(); + FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_Closed_Warn_Text", selected.getEditingFILE().getName())); + MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + } + + /** + * 临时关闭选择的文件 + * + * @param selected 选择的 + */ + public void closeVirtualSelectedReport(JTemplate selected) { + DesignModuleFactory.clearChartPropertyPane(); + DesignTableDataManager.closeTemplate(selected); + if (contains(selected) == -1) { + return; + } + selected.fireJTemplateClosed(); + selected.stopEditing(); + try { + selected.getEditingFILE().closeTemplate(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + + public JTemplate getCurrentEditingTemplate() { + return this.editingTemplate; + } + + public void setCurrentEditingTemplate(JTemplate jt) { + this.editingTemplate = jt; + //如果当前历史面板中没有 + + if (contains(jt) == -1) { + addHistory(); + } + MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); + //设置tab栏为当前选中的那一栏 + if (editingTemplate != null) { + MutilTempalteTabPane.getInstance().setSelectedIndex(contains(jt)); + } + + } + + /** + * 添加历史记录 + */ + public void addHistory() { + if (editingTemplate == null) { + return; + } + DesignerEnvManager.getEnvManager().addRecentOpenedFilePath(editingTemplate.getPath()); + historyList.add(editingTemplate); + closeOverLineTemplate(); + } + + + public List> getHistoryList() { + return historyList; + } + + + /** + * 清空历史记录 + */ + public void removeAllHistory() { + historyList.clear(); + this.editingTemplate = null; + } + + public int getHistoryCount() { + return historyList.size(); + } + + + public JTemplate get(int index) { + if (index > historyList.size() - 1 || index < 0) { + return null; + } + Collections.reverse(historyList); + JTemplate select = historyList.get(index); + Collections.reverse(historyList); + return select; + } + + + public JTemplate getTemplate(int index) { + return historyList.get(index); + } + + /** + * 获取模板的index + * + * @param jt 模板 + * @return 位置 + */ + public int contains(JTemplate jt) { + for (int i = 0; i < historyList.size(); i++) { + if (ComparatorUtils.equals(historyList.get(i).getEditingFILE(), jt.getEditingFILE())) { + return i; + } + } + return -1; + } + + + /** + * 判断是否打开过该模板 + * + * @param filename 文件名 + * @return 文件位置 + */ + public int contains(String filename) { + for (int i = 0; i < historyList.size(); i++) { + String historyPath = historyList.get(i).getPath().replaceAll("/", "\\\\"); + //文件路径是全路径,历史路径是reportlets/模板名 + if (filename.endsWith(historyPath)) { + return i; + } + } + return -1; + } + + /** + * 是否是当前编辑的文件 + * + * @param filename 文件名 + * @return 是则返回TRUE + */ + public boolean isCurrentEditingFile(String filename) { + String editingFileName = editingTemplate.getPath(); + return ComparatorUtils.equals(filename, editingFileName); + } + + @Override + public void callback() { + getCurrentEditingTemplate().repaint(); + } + + /** + * 打开new模板的同时关闭old模板,优先关已保存的、先打开的 + */ + public void closeOverLineTemplate() { + int size = historyList.size(); + int vCount = size - DEAD_LINE; + if (DEAD_LINE == 0 || vCount <= 0) { + return; + } + for (int i = 0; i < vCount; i++) { + JTemplate overTemplate = historyList.get(i); + + if (overTemplate.getEditingFILE().exists() && overTemplate.isALLSaved() && overTemplate != editingTemplate) { + historyList.get(i).closeOverLineTemplate(i); + } + } + MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); + } + + + public void deleteFile(FileNodeFILE file) { + boolean isDir = file.isDirectory(); + + String suffix = isDir ? "\\" : StringUtils.EMPTY; + + // path like reportlets/xx/xxx/xxx + String path = file.getPath().replaceAll("/", "\\\\") + suffix; + + ListIterator> iterator = historyList.listIterator(); + + while (iterator.hasNext()) { + JTemplate template = iterator.next(); + String tPath = template.getPath().replaceAll("/", "\\\\"); + if (isDir ? tPath.startsWith(path) : tPath.equals(path)) { + iterator.remove(); + int index = iterator.nextIndex(); + int size = getHistoryCount(); + if (size == index + 1 && index > 0) { + //如果删除的是后一个Tab,则定位到前一个 + MutilTempalteTabPane.getInstance().setSelectedIndex(index - 1); + JTemplate selectedFile = MutilTempalteTabPane.getInstance().getSelectedFile(); + if (!isCurrentEditingFile(selectedFile.getPath())) { + //如果此时面板上的实时刷新的selectedIndex得到的和历史的不一样 + DesignerContext.getDesignerFrame().activateJTemplate(selectedFile); + } + } + } + } + //如果打开过,则删除,实时刷新多tab面板 + int openFileCount = getHistoryCount(); + if (openFileCount == 0) { + DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + } + MutilTempalteTabPane.getInstance().repaint(); + } + + + public boolean rename(FILE tplFile, String from, String to) { + boolean isDir = tplFile.isDirectory(); + + JTemplate template; + + template = this.getCurrentEditingTemplate(); + if (template != null) { + String editingPath = template.getEditingFILE().getPath().replaceAll("/", "\\\\"); + if (isDir ? editingPath.contains(from + "\\") : editingPath.equals(from)) { + FILE renameFile = template.getEditingFILE(); + renameFile.setPath(editingPath.replace(from, to)); + } + } + + for (int i = 0; i < this.getHistoryCount(); i++) { + template = this.get(i); + String editingPath = template.getEditingFILE().getPath().replaceAll("/", "\\\\"); + if (isDir ? editingPath.contains(from + "\\") : editingPath.equals(from)) { + FILE renameFile = template.getEditingFILE(); + renameFile.setPath(editingPath.replace(from, to)); + } + + } + return true; + } +} diff --git a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListPane.java b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListPane.java index eff4291e4..073c4fd1d 100644 --- a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListPane.java +++ b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListPane.java @@ -1,443 +1,16 @@ package com.fr.design.file; -import com.fr.base.FRContext; -import com.fr.base.chart.chartdata.CallbackEvent; -import com.fr.design.DesignModelAdapter; -import com.fr.design.DesignerEnvManager; -import com.fr.design.constants.UIConstants; -import com.fr.design.data.DesignTableDataManager; -import com.fr.design.data.datapane.TableDataTreePane; -import com.fr.design.gui.icontainer.UIScrollPane; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.ilist.UIList; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.module.DesignModuleFactory; -import com.fr.design.utils.gui.GUIPaintUtils; -import com.fr.file.filetree.FileNode; -import com.fr.general.ComparatorUtils; -import com.fr.general.IOUtils; - -import com.fr.log.FineLoggerFactory; -import com.fr.stable.Constants; -import com.fr.stable.StableUtils; -import com.fr.stable.project.ProjectConstants; -import com.fr.workspace.WorkContext; - -import javax.swing.*; -import javax.swing.event.ListSelectionEvent; -import javax.swing.event.ListSelectionListener; -import java.awt.*; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class HistoryTemplateListPane extends JPanel implements FileOperations, CallbackEvent { - //最大保存内存中面板数,为0时关闭优化内存 - private static final int DEAD_LINE = DesignerEnvManager.getEnvManager().getCachingTemplateLimit();; - private static final int LIST_BORDER = 4; - private List> historyList; - private JTemplate editingTemplate; - private FileToolbarStateChangeListener toobarStateChangeListener; - - private static volatile HistoryTemplateListPane THIS; - - private UIList list; - - public static final HistoryTemplateListPane getInstance() { - if (THIS == null) { - synchronized (HistoryTemplateListPane.class) { - if (THIS == null) { - THIS = new HistoryTemplateListPane(); - } - } - } - return THIS; - } - - private HistoryTemplateListPane() { - setLayout(new BorderLayout()); - historyList = new ArrayList>(); - list = new UIList(new HistoryListDataMode()) { - public int locationToIndex(Point location) { - int rowCount = getModel().getSize(); - int height = getPreferredSize().height - 2 * LIST_BORDER; - int rowHeight = height / rowCount; - int index = (location.y - LIST_BORDER) / rowHeight; - if (location.y < LIST_BORDER || index > rowCount - 1) { - return -1; - } else { - return index; - } - } - }; - ToolTipManager.sharedInstance().registerComponent(list); - list.setBackground(UIConstants.NORMAL_BACKGROUND); - list.setCellRenderer(new HistoryListCellRender()); - list.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() < 2) { - return; - } - openSelectedReport(); - } - }); - - - list.addListSelectionListener(new ListSelectionListener() { - - @Override - public void valueChanged(ListSelectionEvent e) { - if (toobarStateChangeListener != null) { - toobarStateChangeListener.stateChange(); - } - - } - }); - list.setBorder(BorderFactory.createEmptyBorder(LIST_BORDER, LIST_BORDER, LIST_BORDER, LIST_BORDER)); - UIScrollPane scrollPane = new UIScrollPane(list); - scrollPane.setBorder(null); - - this.add(scrollPane, BorderLayout.CENTER); - - } - - /** - * 关闭选择的文件 - * - * @param selected 选择的 - */ - public void closeSelectedReport(JTemplate selected) { - DesignModuleFactory.clearChartPropertyPane(); - DesignTableDataManager.closeTemplate(selected); - if (contains(selected) == -1) { - return; - } - selected.fireJTemplateClosed(); - selected.stopEditing(); - try { - historyList.remove(contains(selected)); - selected.getEditingFILE().closeTemplate(); - FineLoggerFactory.getLogger().info(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Template_Closed_Warn_Text", selected.getEditingFILE().getName())); - MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); - } catch (Exception e) { - FRContext.getLogger().error(e.getMessage(), e); - } - - } - - /** - * 临时关闭选择的文件 - * - * @param selected 选择的 - */ - public void closeVirtualSelectedReport(JTemplate selected) { - DesignModuleFactory.clearChartPropertyPane(); - DesignTableDataManager.closeTemplate(selected); - if (contains(selected) == -1) { - return; - } - selected.fireJTemplateClosed(); - selected.stopEditing(); - try { - selected.getEditingFILE().closeTemplate(); - } catch (Exception e) { - FRContext.getLogger().error(e.getMessage(), e); - } - } - - /** - * 关闭选择的文件 - */ - public void selectedReportToVirtual(int i) { - closeOverLineTemplate(); - } - - public JTemplate getCurrentEditingTemplate() { - return this.editingTemplate; - } - - public void setCurrentEditingTemplate(JTemplate jt) { - this.editingTemplate = jt; - //如果当前历史面板中没有 - - if (contains(jt) == -1) { - addHistory(); - } - MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); - //设置tab栏为当前选中的那一栏 - if (editingTemplate != null) { - MutilTempalteTabPane.getInstance().setSelectedIndex(contains(jt)); - } - - } - - /** - * 添加历史记录 - */ - public void addHistory() { - if (editingTemplate == null) { - return; - } - DesignerEnvManager.getEnvManager().addRecentOpenedFilePath(editingTemplate.getPath()); - ((HistoryListDataMode) list.getModel()).add(editingTemplate); - } - - - public List> getHistoryList() { - return historyList; - } - - - /** - * 清空历史记录 - */ - public void removeAllHistory() { - historyList.clear(); - this.editingTemplate = null; - } - - public int getHistoryCount() { - return list.getModel().getSize(); - } - - - public UIList getList() { - return list; - } - - - public JTemplate get(int index) { - return (JTemplate) list.getModel().getElementAt(index); - } - - - public JTemplate getTemplate(int index) { - return historyList.get(index); - } - - /** - * 获取模板的index - * - * @param jt 模板 - * @return 位置 - */ - public int contains(JTemplate jt) { - for (int i = 0; i < historyList.size(); i++) { - if (ComparatorUtils.equals(historyList.get(i).getEditingFILE(), jt.getEditingFILE())) { - return i; - } - } - return -1; - } - - - /** - * 判断是否打开过该模板 - * - * @param filename 文件名 - * @return 文件位置 - */ - public int contains(String filename) { - for (int i = 0; i < historyList.size(); i++) { - String historyPath = historyList.get(i).getPath().replaceAll("/", "\\\\"); - //文件路径是全路径,历史路径是reportlets/模板名 - if (filename.endsWith(historyPath)) { - return i; - } - } - return -1; - } - - /** - * 是否是当前编辑的文件 - * - * @param filename 文件名 - * @return 是则返回TRUE - */ - public boolean isCurrentEditingFile(String filename) { - String editingFileName = editingTemplate.getPath(); - return ComparatorUtils.equals(filename, editingFileName); - } - - @Override - public void callback() { - getCurrentEditingTemplate().repaint(); - } - - private class HistoryListCellRender extends DefaultListCellRenderer { - - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, final boolean isSelected, boolean cellHasFocus) { - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - JTemplate jt = (JTemplate) value; - UILabel nameLabel = new UILabel(jt.getEditingFILE().getName()); - final int nameWidth = nameLabel.getPreferredSize().width; - UILabel uiLabel = new UILabel() { - public void paint(Graphics g) { - GUIPaintUtils.fillPaint((Graphics2D) g, 18, 0, nameWidth + 2, getHeight(), true, Constants.NULL, isSelected ? UIConstants.FLESH_BLUE : UIConstants.NORMAL_BACKGROUND, UIConstants.ARC); - super.paint(g); - } - - }; - uiLabel.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0)); - uiLabel.setIcon(jt.getIcon()); - uiLabel.setText(jt.getEditingFILE().getName()); - return uiLabel; - } - - } - - - private class HistoryListDataMode extends AbstractListModel { - - @Override - public int getSize() { - return historyList.size(); - } - - @Override - public JTemplate getElementAt(int index) { - if (index > getSize() - 1 || index < 0) { - return null; - } - Collections.reverse(historyList); - JTemplate select = historyList.get(index); - Collections.reverse(historyList); - return select; - } - - public void remove(int index) { - boolean outofindex = index >= historyList.size() || index < 0; - if (historyList.isEmpty() || outofindex) { - return; - } - historyList.remove(index); - } - - public void add(JTemplate jt) { - historyList.add(jt); - closeOverLineTemplate(); - refresh(); - } - } - - /** - * 打开new模板的同时关闭old模板,优先关已保存的、先打开的 - */ - public void closeOverLineTemplate() { - int size = historyList.size(); - int vCount = size - DEAD_LINE; - if (DEAD_LINE == 0 || vCount <= 0) { - return; - } - for (int i = 0; i < vCount; i++) { - JTemplate overTemplate = historyList.get(i); - - if (overTemplate.getEditingFILE().exists() && overTemplate.isALLSaved() && overTemplate != editingTemplate) { - historyList.get(i).closeOverLineTemplate(i); - } - } - MutilTempalteTabPane.getInstance().refreshOpenedTemplate(historyList); - } - - /** - * 刷新 - */ - public void refresh() { - list.removeAll(); - list.setModel(new HistoryListDataMode()); - list.setSelectedIndex(list.getSelectedIndex()); - } - - /** - * 打开选择的文件 - */ - public void openSelectedReport() { - DesignerContext.getDesignerFrame().addAndActivateJTemplate((JTemplate) list.getSelectedValue()); - TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); - refresh(); - } - - /** - * 打开文件所在文件夹 - */ - public void openContainerFolder() { - FileNode fileNode = new FileNode(((JTemplate) list.getSelectedValue()).getEditingFILE().getPath(), false); - if (WorkContext.getCurrent().isLocal()) { - IOUtils.openWindowsFolder(StableUtils.pathJoin(WorkContext.getCurrent().getPath(), fileNode.getEnvPath())); - } - } - - /** - * 删除文件 - */ - public void deleteFile() { -// TODO Auto-generated method stub - - } - - /*** - * 琐文件 - */ - public void lockFile() { -// TODO Auto-generated method stub - - } - - /** - * 解锁 - */ - public void unLockFile() { -// TODO Auto-generated method stub - - } - - /** - * 路径 - * - * @return 路径 - */ - public String getSelectedTemplatePath() { - if (list.getSelectedIndex() < 0 || list.getSelectedIndex() > list.getModel().getSize() - 1) { - return null; - } - ; - String path = ((HistoryListDataMode) list.getModel()).getElementAt(list.getSelectedIndex()).getEditingFILE().getPath(); - if (path.startsWith(ProjectConstants.REPORTLETS_NAME)) { - return path.substring(ProjectConstants.REPORTLETS_NAME.length()); - } - return path; - } - - public void setToobarStateChangeListener(FileToolbarStateChangeListener toobarStateChangeListener) { - this.toobarStateChangeListener = toobarStateChangeListener; - } - - /** - * 文件是否存在 - * - * @param newName 文件名 - * @param oldName 原名 - * @param suffix 后缀名 - * @return 文件是否存在 - */ - public boolean isNameAlreadyExist(String newName, String oldName, String suffix) { - boolean isNameAreadyExist = false; - for (int i = 0; i < getHistoryCount(); i++) { - JTemplate jt = ((HistoryListDataMode) list.getModel()).getElementAt(i); - if (ComparatorUtils.equals(jt.getEditingFILE().getName(), newName + suffix)) { - isNameAreadyExist = true; - break; - } - } - if (ComparatorUtils.equals(newName, oldName)) { - isNameAreadyExist = false; - } - - return isNameAreadyExist; +/** + * 历史模板缓存 + * + * 为可能存在的插件做兼容处理 + * + * @see HistoryTemplateListCache + * @deprecated use HistoryTemplateListCache instead + */ +@Deprecated +public class HistoryTemplateListPane { + public static HistoryTemplateListCache getInstance() { + return HistoryTemplateListCache.getInstance(); } } diff --git a/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java b/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java new file mode 100644 index 000000000..3625a7d4d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java @@ -0,0 +1,225 @@ +package com.fr.design.file; + +import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.file.FILE; +import com.fr.file.FileNodeFILE; +import com.fr.file.filetree.FileNode; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.report.DesignAuthority; +import com.fr.stable.CoreConstants; +import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.authority.AuthorityOperator; + +import java.util.ArrayList; + +public class NodeAuthProcessor { + + public static NodeAuthProcessor getInstance() { + return NodeAuthProcessor.HOLDER.singleton; + } + + private static class HOLDER { + private static NodeAuthProcessor singleton = new NodeAuthProcessor(); + } + + /** + * 远程设计拥有全部权限的文件夹路径 + */ + private ArrayList authPaths = new ArrayList<>(); + + + private NodeAuthProcessor() { + + } + + public void refresh() { + + authPaths.clear(); + if (!WorkContext.getCurrent().isLocal()) { + try { + String username = WorkContext.getConnector().currentUser(); + // 远程设计获取全部设计成员的权限列表 + DesignAuthority[] authorities = WorkContext.getCurrent().get(AuthorityOperator.class).getAuthorities(); + DesignAuthority authority = null; + + if (authorities != null) { + for (DesignAuthority designAuthority : authorities) { + if (ComparatorUtils.equals(designAuthority.getUsername(), username)) { + authority = designAuthority; + } + } + } + if (authority != null) { + for (DesignAuthority.Item item : authority.getItems()) { + if (item.getType()) { + authPaths.add(item.getPath()); + } + } + } + } catch (Exception exception) { + FineLoggerFactory.getLogger().error(exception.getMessage(), exception); + } + } + } + + public void clear() { + authPaths.clear(); + } + + + /** + * 生成带权限信息的文件节点,供另存对话框使用 + * + * @param fileNodes file nodes + * @return 带权限信息的文件节点 + */ + public FILE[] parser2FILEArray(FileNode[] fileNodes, String envPath) { + + boolean isLocal = WorkContext.getCurrent().isLocal(); + boolean isRoot = WorkContext.getCurrent().isRoot(); + FILE[] res = new FILE[fileNodes.length]; + for (int i = 0; i < res.length; i++) { + FileNode fn = fileNodes[i]; + + if (fn.isDirectory()) { + if (isLocal || isRoot) { + res[i] = new FileNodeFILE(fileNodes[i], envPath); + } else { + boolean hasFullAuthority = isContained(fn); + res[i] = new FileNodeFILE(fileNodes[i], envPath, hasFullAuthority); + } + } else { + res[i] = new FileNodeFILE(fileNodes[i], envPath); + } + } + return res; + } + + /** + * 生成带权限信息的文件节点,供另存对话框使用 + * + * @param fileNode file nodes + * @return 带权限信息的文件节点 + */ + public FILE fixFILENodeAuth(FileNode fileNode) { + + boolean isLocal = WorkContext.getCurrent().isLocal(); + boolean isRoot = WorkContext.getCurrent().isRoot(); + + if (fileNode.isDirectory()) { + if (isLocal || isRoot) { + return new FileNodeFILE(fileNode); + } else { + boolean hasFullAuthority = isContained(fileNode); + return new FileNodeFILE(fileNode, hasFullAuthority); + } + } else { + return new FileNodeFILE(fileNode); + } + } + + /** + * 生成带权限信息的文件节点,供另存对话框使用 + * + * @param fileNode file nodes + * @return 带权限信息的文件节点 + */ + public boolean fixFileNodeAuth(FileNode fileNode) { + + boolean isLocal = WorkContext.getCurrent().isLocal(); + boolean isRoot = WorkContext.getCurrent().isRoot(); + + if (fileNode.isDirectory()) { + if (isLocal || isRoot) { + return true; + } else { + return isContained(fileNode); + } + } else { + return true; + } + } + + /** + * 生成带权限信息的目录树节点, + * 提供给目录树使用 + * + * @param fileNodes file nodes + * @return 带权限信息的目录树节点 + */ + public ExpandMutableTreeNode[] parser2TreeNodeArray(FileNode[] fileNodes) { + boolean isLocal = WorkContext.getCurrent().isLocal(); + boolean isRoot = WorkContext.getCurrent().isRoot(); + ExpandMutableTreeNode[] res = new ExpandMutableTreeNode[fileNodes.length]; + for (int i = 0; i < res.length; i++) { + FileNode fn = fileNodes[i]; + res[i] = new ExpandMutableTreeNode(fn); + if (fn.isDirectory()) { + res[i].add(new ExpandMutableTreeNode()); + if (isLocal || isRoot) { + res[i].setFullAuthority(true); + } else { + boolean hasFullAuthority = isContained(fn); + res[i].setFullAuthority(hasFullAuthority); + } + } + } + return res; + } + + public void fixTreeNodeAuth(ExpandMutableTreeNode treeNode) { + if (treeNode == null) { + return; + } + + Object object = treeNode.getUserObject(); + if (object instanceof FileNode) { + boolean isLocal = WorkContext.getCurrent().isLocal(); + boolean isRoot = WorkContext.getCurrent().isRoot(); + if (((FileNode) object).isDirectory()) { + if (isLocal || isRoot) { + treeNode.setFullAuthority(true); + } else { + boolean hasFullAuthority = isContained((FileNode) object); + treeNode.setFullAuthority(hasFullAuthority); + } + } + } + + + } + + private boolean isContained(FileNode fileNode) { + + for (String auPath : authPaths) { + if (isContained(auPath, fileNode)) { + return true; + } + } + return false; + } + + private boolean isContained(String auPath, FileNode fileNode) { + auPath = ProjectConstants.REPORTLETS_NAME + CoreConstants.SEPARATOR + auPath; + String fileName = fileNode.getEnvPath(); + String[] auPaths = auPath.split(CoreConstants.SEPARATOR); + String[] nodePaths = fileName.split(CoreConstants.SEPARATOR); + // 待判断目录是有权限目录或者有权限目录的子目录,全部权限 + if (auPaths.length <= nodePaths.length) { + for (int i = 0; i < auPaths.length; i++) { + if (!auPaths[i].equals(nodePaths[i])) { + return false; + } + } + return fileNode.isDirectory(); + } + // 其他情况半权限 + else { + return false; + } + } + + +} diff --git a/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java b/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java index e3d12da1a..3344d69f2 100644 --- a/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java +++ b/designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java @@ -7,18 +7,18 @@ import com.fr.base.FRContext; import com.fr.base.io.FileAssistUtilsOperator; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.itree.filetree.TemplateFileTree; +import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.JTemplate; +import com.fr.file.FILE; import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNode; import com.fr.file.filetree.IOFileNodeFilter; import com.fr.general.ComparatorUtils; import com.fr.general.IOUtils; - import com.fr.log.FineLoggerFactory; import com.fr.stable.CoreConstants; -import com.fr.stable.ProductConstants; import com.fr.stable.StableUtils; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; @@ -26,7 +26,10 @@ import com.fr.workspace.WorkContext; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.ToolTipManager; +import javax.swing.UIManager; import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; import java.awt.BorderLayout; import java.awt.Desktop; import java.awt.Dimension; @@ -37,6 +40,11 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Enumeration; + +import static javax.swing.JOptionPane.YES_NO_OPTION; public class TemplateTreePane extends JPanel implements FileOperations { @@ -49,7 +57,7 @@ public class TemplateTreePane extends JPanel implements FileOperations { } private TemplateFileTree reportletsTree; - private FileToolbarStateChangeListener toobarStateChangeListener; + private FileToolbarStateChangeListener toolBarStateChangeListener; private TemplateTreePane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); @@ -71,14 +79,14 @@ public class TemplateTreePane extends JPanel implements FileOperations { @Override public void mousePressed(MouseEvent evt) { if (evt.getClickCount() == 2) { - openSelectedReport(); + openFile(); } } @Override public void mouseReleased(MouseEvent e) { - if (toobarStateChangeListener != null) { - toobarStateChangeListener.stateChange(); + if (toolBarStateChangeListener != null) { + toolBarStateChangeListener.stateChange(); } } }; @@ -89,24 +97,24 @@ public class TemplateTreePane extends JPanel implements FileOperations { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { - openSelectedReport(); + openFile(); } } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { - openSelectedReport(); + openFile(); } - if (toobarStateChangeListener != null) { - toobarStateChangeListener.stateChange(); + if (toolBarStateChangeListener != null) { + toolBarStateChangeListener.stateChange(); } } @Override public void keyTyped(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { - openSelectedReport(); + openFile(); } } }); @@ -116,6 +124,49 @@ public class TemplateTreePane extends JPanel implements FileOperations { return this.reportletsTree; } + + /** + * 选中的路径数 + * + * @return 选中的路径数 + */ + public int countSelectedPath() { + TreePath[] treePaths = reportletsTree.getSelectionPaths(); + if (treePaths == null) { + return 0; + } + return treePaths.length; + } + + /** + * 选中的文件夹个数 + * + * @return 选中的文件夹个数 + */ + + public int countSelectedFolder() { + + if (reportletsTree.getSelectedFolderPaths() == null) { + return 0; + } + + return reportletsTree.getSelectedFolderPaths().length; + } + + /** + * 选中的文件个数 + * + * @return 选中的文件 + */ + public int countSelectedFile() { + + if (reportletsTree.getSelectionPaths() == null) { + return 0; + } + + return reportletsTree.getSelectedTemplatePaths().length; + } + /** * 刷新 */ @@ -125,11 +176,16 @@ public class TemplateTreePane extends JPanel implements FileOperations { } + @Override + public boolean mkdir(String path) { + return WorkContext.getWorkResource().createDirectory(path); + } + /** * 打开选中的报表文件 */ @Override - public void openSelectedReport() { + public void openFile() { String reportPath = reportletsTree.getSelectedTemplatePath(); final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath); DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(selectedFilePath, false))); @@ -139,7 +195,7 @@ public class TemplateTreePane extends JPanel implements FileOperations { * 打开文件夹 */ @Override - public void openContainerFolder() { + public void showInExplorer() { FileNode fn = TemplateTreePane.this.reportletsTree.getSelectedFileNode(); String filePath = StableUtils.pathJoin(WorkContext.getCurrent().getPath(), fn.getEnvPath()); filePath = filePath.substring(0, filePath.lastIndexOf(CoreConstants.SEPARATOR)); @@ -156,134 +212,232 @@ public class TemplateTreePane extends JPanel implements FileOperations { @Override public void refresh() { reportletsTree.refresh(); - FineLoggerFactory.getLogger().info(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Template_File_Tree_Refresh_Successfully") + "!"); + FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Template_File_Tree_Refresh_Successfully") + "!"); } /** * 删除文件 + * 文件夹和文件均可删除 + *

+ * 当文件被锁时不能删除 + * 当文件夹中包含被锁文件时不能删除 */ @Override public void deleteFile() { - String[] reportPaths = reportletsTree.getSelectedTemplatePaths(); - if (reportPaths.length == 0) { - return; + + + String tipContent = + countSelectedFolder() > 0 + ? Toolkit.i18nText("Fine-Design_Basic_Confirm_Delete_Folder") + : Toolkit.i18nText("Fine-Design_Basic_Confirm_Delete_File"); + + ExpandMutableTreeNode[] treeNodes = reportletsTree.getSelectedTreeNodes(); + // 筛选可以删除的文件 + ArrayList deletableNodes = new ArrayList<>(); + ArrayList lockedNodes = new ArrayList<>(); + for (ExpandMutableTreeNode treeNode : treeNodes) { + checkFreeOrLock(treeNode, deletableNodes, lockedNodes); + } + + boolean success = false; + + if (lockedNodes.isEmpty()) { + + if (JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), + tipContent, + UIManager.getString("OptionPane.titleText"), + YES_NO_OPTION) + == JOptionPane.OK_OPTION) { + // 删除所有选中的即可 + success = deleteNodes(Arrays.asList(treeNodes)); + } + + } else { + + if (JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Confirm_Delete_Unlock_File"), + UIManager.getString("OptionPane.titleText"), + YES_NO_OPTION) + == JOptionPane.YES_OPTION) { + // 删除其他 + success = deleteNodes(deletableNodes); + } } - if (JOptionPane.showConfirmDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Confirm_Delete_File")) != JOptionPane.OK_OPTION) { - return; + + if (!success) { + JOptionPane.showConfirmDialog(null, + Toolkit.i18nText("Fine-Design_Basic_Delete_Failure"), + UIManager.getString("OptionPane.titleText"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.ERROR_MESSAGE); } - for (String reportPath : reportPaths) { - FileNodeFILE nodeFile = new FileNodeFILE(new FileNode(StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath), false)); - if (nodeFile.isLocked()) { - if (JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_FileLocked_Undeleted"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.YES_OPTION, JOptionPane.ERROR_MESSAGE) == JOptionPane.YES_OPTION) { - refreshDockingView(); + reportletsTree.refresh(); + } + + private boolean deleteNodes(Collection nodes) { + boolean success = true; + for (ExpandMutableTreeNode treeNode : nodes) { + Object node = treeNode.getUserObject(); + if (node instanceof FileNode) { + FileNodeFILE nodeFILE = new FileNodeFILE((FileNode) node); + if (nodeFILE.exists()) { + FileAssistUtilsOperator fileAssistUtils = WorkContext.getCurrent().get(FileAssistUtilsOperator.class); + success = fileAssistUtils.moveToTrash(nodeFILE.getPath()) && success; + HistoryTemplateListCache.getInstance().deleteFile(nodeFILE); } - break; } - if (nodeFile.exists()) { - String path = StableUtils.pathJoin(nodeFile.getEnvPath(), nodeFile.getPath()); - FileAssistUtilsOperator fileAssistUtils = WorkContext.getCurrent().get(FileAssistUtilsOperator.class); - fileAssistUtils.moveToTrash(nodeFile.getPath()); - deleteHistory(path.replaceAll("/", "\\\\")); + } + return success; + } + + private boolean checkFreeOrLock(ExpandMutableTreeNode node, ArrayList dNodes, ArrayList lNodes) { + // 自己没锁 + boolean selfEmptyLock = false; + Object userObj = node.getUserObject(); + if (userObj instanceof FileNode) { + String lock = ((FileNode) userObj).getLock(); + selfEmptyLock = lock == null || ((FileNode) userObj).getUserID().equals(lock); + } + + if (node.isLeaf()) { + if (selfEmptyLock) { + dNodes.add(node); + } else { + lNodes.add(node); + } + return selfEmptyLock; + } + + ExpandMutableTreeNode[] children = reportletsTree.loadChildTreeNodes(node); + + boolean childrenEmptyLock = true; + + for (ExpandMutableTreeNode child : children) { + + boolean childEmptyLock = checkFreeOrLock(child, dNodes, lNodes); + if (childEmptyLock) { + dNodes.add(child); } else { - JOptionPane.showMessageDialog(this, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Warning_Template_Do_Not_Exsit"), ProductConstants.PRODUCT_NAME, - JOptionPane.INFORMATION_MESSAGE); + lNodes.add(child); } + + childrenEmptyLock = childrenEmptyLock && childEmptyLock; } - reportletsTree.refresh(); + + boolean emptyLock = childrenEmptyLock && selfEmptyLock; + if (emptyLock) { + dNodes.add(node); + } else { + lNodes.add(node); + } + return emptyLock; } + @Override public void lockFile() { throw new UnsupportedOperationException("unsupport now"); } @Override - public void unLockFile() { + public void unlockFile() { throw new UnsupportedOperationException("unsupport now"); } - private void deleteHistory(String fileName) { - int index = HistoryTemplateListPane.getInstance().contains(fileName); - int size = HistoryTemplateListPane.getInstance().getHistoryCount(); - if (index == -1) { - return; + + @Override + public String getFilePath() { + return reportletsTree.getSelectedTemplatePath(); + } + + @Override + public boolean access() { + + TreePath[] selectedTreePaths = reportletsTree.getSelectionPaths(); + + if (selectedTreePaths == null || selectedTreePaths.length != 1) { + return false; } - //如果打开过,则删除,实时刷新多tab面板 - HistoryTemplateListPane.getInstance().getHistoryList().remove(index); - int openfileCount = HistoryTemplateListPane.getInstance().getHistoryCount(); - if (openfileCount == 0) { - DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + // 选中的是文件夹 + TreePath treePath = selectedTreePaths[0]; + ExpandMutableTreeNode currentTreeNode = (ExpandMutableTreeNode) treePath.getLastPathComponent(); + + ExpandMutableTreeNode parentTreeNode = (ExpandMutableTreeNode) currentTreeNode.getParent(); + + return parentTreeNode != null && parentTreeNode.hasFullAuthority(); + } + + @Override + public boolean rename(FILE tplFile, String from, String to) { + + // 多人协作时判断是否有锁定的文件 + ExpandMutableTreeNode[] treeNodes = reportletsTree.getSelectedTreeNodes(); + // 筛选可以重命名的文件 + ArrayList unlockedNodes = new ArrayList<>(); + ArrayList lockedNodes = new ArrayList<>(); + for (ExpandMutableTreeNode treeNode : treeNodes) { + checkFreeOrLock(treeNode, unlockedNodes, lockedNodes); } - MutilTempalteTabPane.getInstance().repaint(); - if (size == index + 1 && index != 0) { - //如果删除的是最后一个Tab,则定位到前一个 - MutilTempalteTabPane.getInstance().setSelectedIndex(index - 1); + + if (!lockedNodes.isEmpty()) { + JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Warn_Rename_Lock_File"), + UIManager.getString("OptionPane.titleText"), + JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE); + return true; } - JTemplate selectedfile = MutilTempalteTabPane.getInstance().getSelectedFile(); - if (!HistoryTemplateListPane.getInstance().isCurrentEditingFile(selectedfile.getPath())) { - //如果此时面板上的实时刷新的selectedIndex得到的和历史的不一样 - DesignerContext.getDesignerFrame().activateJTemplate(selectedfile); + + try { + // com.fr.io.utils.ResourceIOUtils 接收的是WEB-INF下的路径 + return WorkContext.getWorkResource().rename(from, to); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; } - MutilTempalteTabPane.getInstance().repaint(); } - @Override - public String getSelectedTemplatePath() { - return reportletsTree.getSelectedTemplatePath(); + public FileNode getFileNode() { + return reportletsTree.getSelectedFileNode(); } - public void setToobarStateChangeListener(FileToolbarStateChangeListener toobarStateChangeListener) { - this.toobarStateChangeListener = toobarStateChangeListener; + public void setToolbarStateChangeListener(FileToolbarStateChangeListener listener) { + this.toolBarStateChangeListener = listener; } + /** - * 文件名是否存在 + * 仅支持在拥有完整权限的文件夹下进行新建和重命名操作,那么是可以看到改文件夹下所有文件的。 * * @param newName 原名 - * @param oldName 新的文件名 * @param suffix 后缀名 - * @return 是否存在 + * @return 是否有重名的 */ @Override - public boolean isNameAlreadyExist(String newName, String oldName, String suffix) { - boolean isNameAlreadyExist = false; - - TemplateFileTree tt = reportletsTree; - DefaultMutableTreeNode gen = (DefaultMutableTreeNode) tt.getModel().getRoot(); - ArrayList al = new ArrayList(); + public boolean duplicated(String newName, String suffix) { - findFiles(gen, al); - - for (int i = 0; i < al.size(); i++) { - if (ComparatorUtils.equals(al.get(i), newName + suffix)) { - isNameAlreadyExist = true; - break; - } + // 选中的节点 + TreePath treePath = reportletsTree.getSelectionPath(); + if (treePath == null) { + return false; } + DefaultMutableTreeNode currentTreeNode = (DefaultMutableTreeNode) treePath.getLastPathComponent(); + TreeNode parentTreeNode = currentTreeNode.getParent(); - if (ComparatorUtils.equals(newName, oldName)) { - isNameAlreadyExist = false; - } + Enumeration children = parentTreeNode.children(); - return isNameAlreadyExist; - } - - - private void findFiles(DefaultMutableTreeNode node, ArrayList al) { - String[] str = new String[node.getChildCount()]; - for (int j = 0; j < node.getChildCount(); j++) { - DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) node.getChildAt(j); - if (childNode.getChildCount() > 0) { - findFiles(childNode, al); - } else { - str[j] = node.getChildAt(j).toString(); - if (str[j].contains(".")) { - al.add(str[j]); + while (children.hasMoreElements()) { + DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) children.nextElement(); + Object object = childNode.getUserObject(); + if (object instanceof FileNode) { + if (ComparatorUtils.equals(((FileNode) object).getName(), newName + suffix)) { + return true; } + } else { + return false; } } + return false; } } diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java index 862aff379..0a13dd1bd 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java +++ b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/TemplateFileTree.java @@ -2,17 +2,13 @@ package com.fr.design.gui.itree.filetree; import com.fr.base.FRContext; import com.fr.base.extension.FileExtension; +import com.fr.design.file.NodeAuthProcessor; import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; import com.fr.file.filetree.FileNode; -import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; -import com.fr.report.DesignAuthority; import com.fr.stable.ArrayUtils; -import com.fr.stable.CoreConstants; import com.fr.stable.StableUtils; import com.fr.stable.project.ProjectConstants; -import com.fr.workspace.WorkContext; -import com.fr.workspace.server.authority.AuthorityOperator; import javax.swing.text.Position; import javax.swing.tree.DefaultTreeModel; @@ -26,12 +22,6 @@ import java.util.List; */ public class TemplateFileTree extends EnvFileTree { - - /** - * 远程设计拥有全部权限的文件夹路径 - */ - private ArrayList paths = new ArrayList<>(); - public TemplateFileTree() { super(ProjectConstants.REPORTLETS_NAME, null, null); } @@ -79,10 +69,32 @@ public class TemplateFileTree extends EnvFileTree { } } + return selectedPathList.toArray(new String[0]); + } + public String[] getSelectedFolderPaths() { + TreePath[] selectedTreePaths = this.getSelectionPaths(); + if (ArrayUtils.isEmpty(selectedTreePaths)) { + return ArrayUtils.EMPTY_STRING_ARRAY; + } + List selectedPathList = new ArrayList(); + for (TreePath treepath : selectedTreePaths) { + ExpandMutableTreeNode currentTreeNode = (ExpandMutableTreeNode) treepath.getLastPathComponent(); + Object userObject = currentTreeNode.getUserObject(); + if (userObject instanceof FileNode) { + FileNode fn = (FileNode) userObject; + if (fn.isDirectory()) { + String envPath = fn.getEnvPath(); + if (envPath.startsWith(ProjectConstants.REPORTLETS_NAME)) { + selectedPathList.add(envPath.substring(ProjectConstants.REPORTLETS_NAME.length())); + } + } + } + } return selectedPathList.toArray(new String[0]); } + @Override public TreePath getNextMatch(String prefix, int startingRow, Position.Bias bias) { @@ -122,37 +134,11 @@ public class TemplateFileTree extends EnvFileTree { */ @Override public void refreshEnv() { - paths.clear(); - - if (!WorkContext.getCurrent().isLocal()) { - try { - String username = WorkContext.getConnector().currentUser(); - // 远程设计获取全部设计成员的权限列表 - DesignAuthority[] authorities = WorkContext.getCurrent().get(AuthorityOperator.class).getAuthorities(); - DesignAuthority authority = null; - - if (authorities != null) { - for (DesignAuthority designAuthority : authorities) { - if (ComparatorUtils.equals(designAuthority.getUsername(), username)) { - authority = designAuthority; - } - } - } - if (authority != null) { - for (DesignAuthority.Item item : authority.getItems()) { - if (item.getType()) { - paths.add(item.getPath()); - } - } - } - } catch (Exception exception) { - FineLoggerFactory.getLogger().error(exception.getMessage(), exception); - } - } - + NodeAuthProcessor.getInstance().refresh(); DefaultTreeModel defaultTreeModel = (DefaultTreeModel) this.getModel(); ExpandMutableTreeNode rootTreeNode = (ExpandMutableTreeNode) defaultTreeModel.getRoot(); + NodeAuthProcessor.getInstance().fixTreeNodeAuth(rootTreeNode); rootTreeNode.removeAllChildren(); FileNode[] fns; @@ -178,64 +164,34 @@ public class TemplateFileTree extends EnvFileTree { } @Override - protected ExpandMutableTreeNode[] loadChildTreeNodes(ExpandMutableTreeNode treeNode) { - + public ExpandMutableTreeNode[] loadChildTreeNodes(ExpandMutableTreeNode treeNode) { + FileNode[] fnArray = listFileNodes(treeNode); - + return fileNodeArray2TreeNodeArray(fnArray); } - /* - * 把FileNode[]转成ExpandMutableTreeNode[] - */ - private ExpandMutableTreeNode[] fileNodeArray2TreeNodeArray(FileNode[] fileNodes) { - boolean isLocal = WorkContext.getCurrent().isLocal(); - boolean isRoot = WorkContext.getCurrent().isRoot(); - ExpandMutableTreeNode[] res = new ExpandMutableTreeNode[fileNodes.length]; - for (int i = 0; i < res.length; i++) { - FileNode fn = fileNodes[i]; - res[i] = new ExpandMutableTreeNode(fn); - if (fn.isDirectory()) { - res[i].add(new ExpandMutableTreeNode()); - if (isLocal || isRoot) { - res[i].setFullAuthority(true); - } else { - boolean hasFullAuthority = isContained(fn); - res[i].setFullAuthority(hasFullAuthority); - } - } + + public ExpandMutableTreeNode[] getSelectedTreeNodes() { + TreePath[] paths = this.getSelectionPaths(); + + if (paths == null) { + return new ExpandMutableTreeNode[0]; } - return res; - } - private boolean isContained(FileNode fileNode) { + ArrayList res = new ArrayList<>(); - for (String auPath : paths) { - if (isContained(auPath, fileNode)) { - return true; - } + for (TreePath path : paths) { + res.add((ExpandMutableTreeNode) path.getLastPathComponent()); } - return false; + return res.toArray(new ExpandMutableTreeNode[res.size()]); } - private boolean isContained(String auPath, FileNode fileNode) { - auPath = ProjectConstants.REPORTLETS_NAME + CoreConstants.SEPARATOR + auPath; - String fileName = fileNode.getEnvPath(); - String[] auPaths = auPath.split(CoreConstants.SEPARATOR); - String[] nodePaths = fileName.split(CoreConstants.SEPARATOR); - // 待判断目录是有权限目录或者有权限目录的子目录,全部权限 - if (auPaths.length <= nodePaths.length) { - for (int i = 0; i < auPaths.length; i++) { - if (!auPaths[i].equals(nodePaths[i])) { - return false; - } - } - return fileNode.isDirectory(); - } - // 其他情况半权限 - else { - return false; - } + /* + * 把FileNode[]转成ExpandMutableTreeNode[] + */ + private ExpandMutableTreeNode[] fileNodeArray2TreeNodeArray(FileNode[] fileNodes) { + return NodeAuthProcessor.getInstance().parser2TreeNodeArray(fileNodes); } @@ -270,7 +226,7 @@ public class TemplateFileTree extends EnvFileTree { * 求当前TreeNode下所有的FileNode. */ private FileNode[] listFileNodes(ExpandMutableTreeNode currentTreeNode) { - + if (currentTreeNode == null) { return new FileNode[0]; } @@ -278,12 +234,10 @@ public class TemplateFileTree extends EnvFileTree { Object object = currentTreeNode.getUserObject(); if (object instanceof FileNode) { - + return this.listFileNodes(((FileNode) object).getEnvPath()); } return new FileNode[0]; } - - } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java index ec27d1f73..83e30eecf 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java @@ -1,7 +1,6 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; -import com.fr.base.FRContext; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignerEnvManager; @@ -13,6 +12,7 @@ import com.fr.design.data.datapane.TableDataTreePane; import com.fr.design.data.tabledata.ResponseDataSourceChange; import com.fr.design.file.FileOperations; import com.fr.design.file.FileToolbarStateChangeListener; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.MutilTempalteTabPane; import com.fr.design.file.TemplateTreePane; @@ -21,66 +21,66 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.imenu.UIMenuHighLight; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itoolbar.UIToolbar; -import com.fr.design.gui.itree.filetree.TemplateFileTree; +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.menu.KeySetUtils; import com.fr.design.menu.ShortCut; import com.fr.design.menu.ToolBarDef; import com.fr.design.roleAuthority.RolesAlreadyEditedPane; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.file.FILE; import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNode; import com.fr.general.ComparatorUtils; -import com.fr.io.utils.ResourceIOUtils; +import com.fr.log.FineLoggerFactory; import com.fr.stable.CoreConstants; -import com.fr.stable.StableUtils; -import com.fr.stable.project.ProjectConstants; +import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; import javax.swing.JDialog; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingConstants; +import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; +import java.awt.Component; import java.awt.Dimension; -import java.awt.GridLayout; +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.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; +import static javax.swing.JOptionPane.WARNING_MESSAGE; + public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarStateChangeListener, ResponseDataSourceChange { private static final String FILE = "file"; private static volatile DesignerFrameFileDealerPane THIS; - private CardLayout card; - - private JPanel cardPane; - - private java.util.List otherToobarStateChangeListeners = new ArrayList<>(); + private List otherToolbarStateChangeListeners = new ArrayList<>(); private FileOperations selectedOperation; private UIToolbar toolBar; - private OpenReportAction openReportAction = new OpenReportAction(); + private NewFolderAction newFolderAction = new NewFolderAction(); private RefreshTreeAction refreshTreeAction = new RefreshTreeAction(); - private OpenFolderAction openFolderAction = new OpenFolderAction(); + private ShowInExplorerAction showInExplorerAction = new ShowInExplorerAction(); private RenameAction renameAction = new RenameAction(); @@ -91,11 +91,10 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt * 刷新 */ public void refresh() { - selectedOperation.refresh(); } - public static final DesignerFrameFileDealerPane getInstance() { + public static DesignerFrameFileDealerPane getInstance() { if (THIS == null) { synchronized (DesignerFrameFileDealerPane.class) { @@ -121,13 +120,14 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt tooBarPane.add(new UIMenuHighLight(), BorderLayout.SOUTH); add(tooBarPane, BorderLayout.NORTH); - cardPane = new JPanel(card = new CardLayout()); + CardLayout card; + JPanel cardPane = new JPanel(card = new CardLayout()); cardPane.add(TemplateTreePane.getInstance(), FILE); selectedOperation = TemplateTreePane.getInstance(); card.show(cardPane, FILE); - TemplateTreePane.getInstance().setToobarStateChangeListener(this); + TemplateTreePane.getInstance().setToolbarStateChangeListener(this); add(cardPane, BorderLayout.CENTER); stateChange(); @@ -136,7 +136,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt public final void setCurrentEditingTemplate(JTemplate jt) { - DesignModelAdapter.setCurrentModelAdapter(jt == null ? null : jt.getModel()); + DesignModelAdapter.setCurrentModelAdapter(jt.getModel()); fireDSChanged(); TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); HistoryTemplateListPane.getInstance().setCurrentEditingTemplate(jt); @@ -152,7 +152,9 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt jt.requestFocus(); jt.revert(); - FRContext.getLogger().info("\"" + jt.getEditingFILE().getName() + "\"" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_LOG_Has_Been_Openned") + "!"); + FineLoggerFactory.getLogger().info( + "\"" + jt.getEditingFILE().getName() + "\"" + + Toolkit.i18nText("Fine-Design_Basic_LOG_Has_Been_Openned") + "!"); } /** @@ -161,27 +163,26 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt public void refreshDockingView() { ToolBarDef toolbarDef = new ToolBarDef(); - toolbarDef.addShortCut(openReportAction, refreshTreeAction); + toolbarDef.addShortCut(newFolderAction, refreshTreeAction); if (WorkContext.getCurrent().isLocal()) { - toolbarDef.addShortCut(openFolderAction, renameAction); + toolbarDef.addShortCut(showInExplorerAction); } - toolbarDef.addShortCut(delFileAction); + toolbarDef.addShortCut(renameAction, delFileAction); Set extraShortCuts = ExtraDesignClassManager.getInstance().getExtraShortCuts(); for (ShortCut shortCut : extraShortCuts) { toolbarDef.addShortCut(shortCut); } - toolbarDef.updateToolBar(toolBar); - refreshActions(); + resetActionStatus(); refresh(); } - private void refreshActions() { + private void resetActionStatus() { - openReportAction.setEnabled(false); + newFolderAction.setEnabled(false); refreshTreeAction.setEnabled(true); - openFolderAction.setEnabled(false); + showInExplorerAction.setEnabled(false); renameAction.setEnabled(false); delFileAction.setEnabled(false); this.repaint(); @@ -206,28 +207,53 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt } + public void addToolbarStateChangeListener(FileToolbarStateChangeListener listener) { + this.otherToolbarStateChangeListeners.add(listener); + } + + public void removeToolbarStateChangeListener(FileToolbarStateChangeListener listener) { + this.otherToolbarStateChangeListeners.remove(listener); + } + + private void otherStateChange() { + for (FileToolbarStateChangeListener listener : otherToolbarStateChangeListeners) { + listener.stateChange(); + } + } + /* - * Open Report Action + * 新建文件夹 */ - private class OpenReportAction extends UpdateAction { + private class NewFolderAction extends UpdateAction { - public OpenReportAction() { + public NewFolderAction() { - this.setName(KeySetUtils.OPEN_TEMPLATE.getMenuKeySetName()); - this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/buttonicon/open.png")); + this.setName(KeySetUtils.NEW_FOLDER.getMenuKeySetName()); + this.setSmallIcon(BaseUtils.readIcon("com/fr/design/images/icon_NewFolderIcon_normal.png")); } @Override public void actionPerformed(ActionEvent evt) { - selectedOperation.openSelectedReport(); + if (!selectedOperation.access()) { + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + WARNING_MESSAGE); + return; + } + + new MkdirDialog(); } } - private class OpenFolderAction extends UpdateAction { + /** + * 在系统资源管理器中打开 + */ + private class ShowInExplorerAction extends UpdateAction { - public OpenFolderAction() { + public ShowInExplorerAction() { this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Show_In_Containing_Folder")); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/view_folder.png")); @@ -236,7 +262,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt @Override public void actionPerformed(ActionEvent evt) { - selectedOperation.openContainerFolder(); + selectedOperation.showInExplorer(); } } @@ -247,7 +273,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt public RefreshTreeAction() { - this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh")); + this.setName(Toolkit.i18nText("Fine-Design_Basic_Refresh")); this.setSmallIcon(UIConstants.REFRESH_ICON); } @@ -260,20 +286,6 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt } } - public void addToobarStateChangeListener(FileToolbarStateChangeListener toobarStateChangeListener) { - this.otherToobarStateChangeListeners.add(toobarStateChangeListener); - } - - public void removeToobarStateChangeListener(FileToolbarStateChangeListener toobarStateChangeListener) { - this.otherToobarStateChangeListeners.remove(toobarStateChangeListener); - } - - private void otherStateChange() { - for (FileToolbarStateChangeListener toobarStateChangeListener : otherToobarStateChangeListeners) { - toobarStateChangeListener.stateChange(); - } - } - /* * 重命名文件 */ @@ -281,14 +293,22 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt public RenameAction() { - this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Rename")); + this.setName(Toolkit.i18nText("Fine-Design_Basic_Rename")); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/data/source/rename.png")); } @Override public void actionPerformed(ActionEvent evt) { + if (!selectedOperation.access()) { + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + WARNING_MESSAGE); + return; + } - new RenameDialog(); + FileNode node = selectedOperation.getFileNode(); + new FileRenameDialog(node); MutilTempalteTabPane.getInstance().repaint(); } @@ -301,13 +321,21 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt public DelFileAction() { - this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove")); + this.setName(Toolkit.i18nText("Fine-Design_Basic_Remove")); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/data/source/delete.png")); } @Override public void actionPerformed(ActionEvent evt) { + if (!selectedOperation.access()) { + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + WARNING_MESSAGE); + return; + } + selectedOperation.deleteFile(); } } @@ -318,295 +346,411 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt @Override public void stateChange() { - if (selectedOperation.getSelectedTemplatePath() != null) { - openReportAction.setEnabled(true); - renameAction.setEnabled(true); - delFileAction.setEnabled(true); - } else { - openReportAction.setEnabled(false); - renameAction.setEnabled(false); - delFileAction.setEnabled(false); - } - openFolderAction.setEnabled(containsFolderNums() + seletedTemplateNums() != 0); + int selectedPathNum = TemplateTreePane.getInstance().countSelectedPath(); + + // 新建文件夹,重命名操作,在explorer中打开三个操作在选中单个文件夹或者文件时可用,其他情况不可用 + boolean singleSelected = selectedPathNum == 1; + newFolderAction.setEnabled(singleSelected); + renameAction.setEnabled(singleSelected); + showInExplorerAction.setEnabled(singleSelected); + // 删除操作在至少选中一个时可用 + boolean selected = selectedPathNum > 0; + delFileAction.setEnabled(selected); + + // 刷新操作始终可用 refreshTreeAction.setEnabled(true); - if (containsFolderNums() > 0 && (containsFolderNums() + seletedTemplateNums() > 1)) { - refreshActions(); - } else if (containsFolderNums() == 0 && seletedTemplateNums() > 1) { - openReportAction.setEnabled(false); - refreshTreeAction.setEnabled(true); - openFolderAction.setEnabled(false); - renameAction.setEnabled(false); - delFileAction.setEnabled(true); - } + // 其他状态 otherStateChange(); } - /** - * 是否包含文件夹 - * - * @return - */ - - private int containsFolderNums() { - - TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree(); - if (fileTree.getSelectionPaths() == null) { - return 0; - } - - //选择的包含文件和文件夹的数目 - if (fileTree.getSelectionPaths().length == 0) { - return 0; - } - //所有的num减去模板的num,得到文件夹的num - return fileTree.getSelectionPaths().length - fileTree.getSelectedTemplatePaths().length; + public FileOperations getSelectedOperation() { + return selectedOperation; } /** - * 是否选择了多个模板 - * - * @return + * 重命名对话框 + * 支持快捷键Enter,ESC */ - private int seletedTemplateNums() { + private class FileRenameDialog extends JDialog { - TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree(); - if (fileTree.getSelectionPaths() == null) { - return 0; - } + private UITextField nameField; - return fileTree.getSelectedTemplatePaths().length; - } + private UILabel warnLabel; + private UIButton confirmButton; - // js: 重命名对话框,模仿Eclipse的重命名,支持快捷键F2,Enter,ESC - private class RenameDialog { + /** + * 操作的节点 + */ + private FileNodeFILE fnf; - private UITextField jt; - private String userInput; + private FileRenameDialog(FileNode node) { + if (node == null) { + return; + } + fnf = new FileNodeFILE(node); - private String oldName; + String oldName = fnf.getName(); + String suffix = fnf.isDirectory() ? "" : oldName.substring(oldName.lastIndexOf(CoreConstants.DOT), oldName.length()); + oldName = oldName.replaceAll(suffix, ""); - private UILabel hintsLabel; + this.setLayout(new BorderLayout()); + this.setModal(true); - private UIButton confirmButton; + // 输入框前提示 + 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.RIGHT); + newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + newNameLabel.setPreferredSize(new Dimension(118, 15)); - private JDialog jd; + // 重命名输入框 + nameField = new UITextField(oldName); + nameField.getDocument().addDocumentListener(new DocumentListener() { - private String suffix; + public void changedUpdate(DocumentEvent e) { + validInput(); + } - public RenameDialog() { + public void insertUpdate(DocumentEvent e) { + validInput(); + } - final String reportPath = selectedOperation.getSelectedTemplatePath(); - if (reportPath == null) { - return; - } + public void removeUpdate(DocumentEvent e) { + validInput(); + } + }); + nameField.selectAll(); + nameField.setPreferredSize(new Dimension(180, 20)); - final FileNodeFILE nodeFile = new FileNodeFILE(new FileNode(StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath), false)); - final String path = nodeFile.getPath(); - oldName = nodeFile.getName(); - suffix = oldName.substring(oldName.lastIndexOf(CoreConstants.DOT), oldName.length()); - oldName = oldName.replaceAll(suffix, ""); + JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); + topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15)); + topPanel.add(newNameLabel); + topPanel.add(nameField); - jd = new JDialog(); - jd.setLayout(new GridLayout(2, 2)); - jd.setModal(true); - UILabel newNameLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Enter_New_File_Name")); - newNameLabel.setMinimumSize(new Dimension(150, 27)); - newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT); - jt = new UITextField(oldName); - jt.getDocument().addDocumentListener(getdoDocumentListener()); - jt.selectAll(); - jt.setPreferredSize(new Dimension(150, 20)); - - JPanel newNamePanel = new JPanel(); - newNamePanel.setLayout(new BoxLayout(newNamePanel, BoxLayout.X_AXIS)); - newNamePanel.add(Box.createHorizontalGlue()); - newNamePanel.add(newNameLabel); - newNamePanel.add(Box.createHorizontalStrut(5)); - jd.add(newNamePanel); - - JPanel jtPanel = new JPanel(); - jtPanel.setLayout(new BoxLayout(jtPanel, BoxLayout.Y_AXIS)); - JPanel containJt = new JPanel(new BorderLayout()); - containJt.add(jt, BorderLayout.WEST); - containJt.setMaximumSize(new Dimension(200, 20)); - jtPanel.add(Box.createVerticalGlue()); - jtPanel.add(containJt); - jtPanel.add(Box.createVerticalGlue()); - jd.add(jtPanel); - - addUITextFieldListener(nodeFile, path); - - hintsLabel = new UILabel(); - hintsLabel.setBounds(20, 50, 250, 30); - hintsLabel.setMaximumSize(new Dimension(200, 30)); - hintsLabel.setHorizontalAlignment(SwingConstants.RIGHT); - hintsLabel.setForeground(Color.RED); - hintsLabel.setVisible(false); - - confirmButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Confirm")); - confirmButton.setPreferredSize(new Dimension(80, 25)); - confirmButton.setMinimumSize(new Dimension(80, 25)); - confirmButton.setMaximumSize(new Dimension(80, 25)); + // 增加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(nodeFile, path); + confirmClose(); } }); - UIButton cancelButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Cancel")); - cancelButton.setPreferredSize(new Dimension(80, 25)); - cancelButton.setMinimumSize(new Dimension(80, 25)); - cancelButton.setMaximumSize(new Dimension(80, 25)); + // 取消按钮 + 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) { - - jd.dispose(); + dispose(); } }); - JPanel hintsPanel = new JPanel(); - hintsPanel.setLayout(new BorderLayout()); - hintsPanel.add(hintsLabel, BorderLayout.EAST); - jd.add(hintsLabel); - - JPanel btPanel = new JPanel(new BorderLayout()); - btPanel.setLayout(new BoxLayout(btPanel, BoxLayout.X_AXIS)); - btPanel.add(Box.createHorizontalGlue()); - btPanel.add(confirmButton); - btPanel.add(Box.createHorizontalStrut(5)); - btPanel.add(cancelButton); - btPanel.add(Box.createHorizontalStrut(20)); - jd.add(btPanel); - - jd.setSize(380, 200); - jd.setTitle(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Rename")); - jd.setResizable(false); - jd.setAlwaysOnTop(true); - jd.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png")); - jd.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); - GUICoreUtils.centerWindow(jd); - jd.setVisible(true); + 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_Rename")); + 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); } - public void confirmClose(FileNodeFILE nodeFile, String path) { + private void confirmClose() { + + String userInput = nameField.getText().trim(); + + String path = fnf.getPath(); + + String oldName = fnf.getName(); + String suffix = fnf.isDirectory() ? "" : oldName.substring(oldName.lastIndexOf(CoreConstants.DOT), oldName.length()); + oldName = oldName.replaceAll(suffix, ""); + + // 输入为空或者没有修改 + if (ComparatorUtils.equals(userInput, oldName)) { + this.dispose(); + return; + } + + String oldPath = path.replaceAll(CoreConstants.SEPARATOR, "\\\\"); + + String parentPath = fnf.getParent().getPath().replaceAll(CoreConstants.SEPARATOR, "\\\\"); - userInput = userInput == null ? oldName : userInput; - String oldPath = path.replaceAll("/", "\\\\"); - String newPath = path.replace(nodeFile.getName(), userInput + suffix); - renameTemplateInMemory(nodeFile, userInput + suffix, oldName + suffix); - DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldPath, newPath.replaceAll("/", "\\\\")); + // 简单执行old new 替换是不可行的,例如 /abc/abc/abc/abc/ + String newPath = parentPath + "\\" + userInput + suffix; + + HistoryTemplateListCache.getInstance().rename(fnf, oldPath, newPath); + DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(fnf.isDirectory(), oldPath, newPath); //模版重命名 - ResourceIOUtils.renameTo(path, newPath); + boolean success = selectedOperation.rename(fnf, oldPath, newPath); selectedOperation.refresh(); DesignerContext.getDesignerFrame().setTitle(); - jd.dispose(); + this.dispose(); + + if (!success) { + JOptionPane.showConfirmDialog(null, + Toolkit.i18nText("Fine-Design_Basic_Rename_Failure"), + UIManager.getString("OptionPane.titleText"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.ERROR_MESSAGE); + } } - private void renameTemplateInMemory(FILE tplFile, String newName, String oldName) { - JTemplate dPane = getSpecialTemplateByFILE(tplFile); - if (dPane == null) { + private void validInput() { + + String userInput = nameField.getText().trim(); + + String oldName = fnf.getName(); + String suffix = fnf.isDirectory() ? "" : oldName.substring(oldName.lastIndexOf(CoreConstants.DOT), oldName.length()); + oldName = oldName.replaceAll(suffix, ""); + + if (StringUtils.isEmpty(userInput)) { + confirmButton.setEnabled(false); + } + + if (ComparatorUtils.equals(userInput, oldName)) { + warnLabel.setVisible(false); + confirmButton.setEnabled(true); return; } - FILE renameFile = dPane.getEditingFILE(); - renameFile.setPath(renameFile.getPath().replace(oldName, newName)); + + if (selectedOperation.duplicated(userInput, suffix)) { + nameField.selectAll(); + // 如果文件名已存在,则灰掉确认按钮 + warnLabel.setText( + Toolkit.i18nText(fnf.isDirectory() ? + "Fine-Design_Basic_Folder_Name_Duplicate" : + "Fine-Design_Basic_Template_File_Name_Duplicate", + userInput)); + warnLabel.setVisible(true); + confirmButton.setEnabled(false); + } else { + warnLabel.setVisible(false); + confirmButton.setEnabled(true); + } } + } - // 增加enter以及esc快捷键的支持 - public void addUITextFieldListener(final FileNodeFILE nodeFile, final String path) { - jt.addKeyListener(new KeyAdapter() { + /** + * 新建文件夹对话框 + * 支持快捷键Enter,ESC + */ + private class MkdirDialog extends JDialog { - public void keyPressed(KeyEvent e) { + private UITextField nameField; - if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { - jd.dispose(); - } + 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)); - jt.addKeyListener(new KeyAdapter() { + 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_ENTER) { + if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + dispose(); + } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { if (confirmButton.isEnabled()) { - confirmClose(nodeFile, path); + 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)); - // UITextField的输入监听 - public DocumentListener getdoDocumentListener() { + cancelButton.addActionListener(new ActionListener() { - DocumentListener dl = new DocumentListener() { + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); - public void changedUpdate(DocumentEvent e) { + 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); + } - isNameAlreadyExist(); - } + private void confirmClose() { + String userInput = nameField.getText().trim(); - public void insertUpdate(DocumentEvent e) { + if (StringUtils.isEmpty(userInput)) { + return; + } - isNameAlreadyExist(); - } + //新建文件夹 + boolean success = selectedOperation.mkdir( + selectedOperation.getFileNode().getParent() + CoreConstants.SEPARATOR + userInput + ); + selectedOperation.refresh(); + this.dispose(); + if (!success) { + JOptionPane.showConfirmDialog(null, + Toolkit.i18nText("Fine-Design_Basic_Make_Failure"), + UIManager.getString("OptionPane.titleText"), + JOptionPane.DEFAULT_OPTION, + JOptionPane.ERROR_MESSAGE); + } + } - public void removeUpdate(DocumentEvent e) { - isNameAlreadyExist(); - } - }; + private void validInput() { + String userInput = nameField.getText().trim(); - return dl; - } - private void isNameAlreadyExist() { + if (StringUtils.isEmpty(userInput)) { + confirmButton.setEnabled(false); + } - userInput = jt.getText().trim(); - if (selectedOperation.isNameAlreadyExist(userInput, oldName, suffix)) { - jt.selectAll(); + if (selectedOperation.duplicated(userInput, StringUtils.EMPTY)) { + nameField.selectAll(); // 如果文件名已存在,则灰掉确认按钮 - hintsLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Template_File_Name_Duplicate", userInput)); - hintsLabel.setVisible(true); + warnLabel.setText( + Toolkit.i18nText( + "Fine-Design_Basic_Folder_Name_Duplicate", + userInput)); + warnLabel.setVisible(true); confirmButton.setEnabled(false); } else { - hintsLabel.setVisible(false); + warnLabel.setVisible(false); confirmButton.setEnabled(true); } } } - /** - * @param tplFile - * @return 内存中的template重命名一下 - */ - private JTemplate getSpecialTemplateByFILE(FILE tplFile) { - HistoryTemplateListPane historyHandle = HistoryTemplateListPane.getInstance(); - if (ComparatorUtils.equals(historyHandle.getCurrentEditingTemplate().getEditingFILE(), tplFile)) { - return historyHandle.getCurrentEditingTemplate(); - } - for (int i = 0; i < historyHandle.getHistoryCount(); i++) { - if (ComparatorUtils.equals(historyHandle.get(i).getEditingFILE(), tplFile)) { - return historyHandle.get(i); - } - } - return null; - } - - public FileOperations getSelectedOperation() { - return selectedOperation; - } } diff --git a/designer-base/src/main/java/com/fr/design/menu/KeySetUtils.java b/designer-base/src/main/java/com/fr/design/menu/KeySetUtils.java index f220b46a0..3ecda64c4 100644 --- a/designer-base/src/main/java/com/fr/design/menu/KeySetUtils.java +++ b/designer-base/src/main/java/com/fr/design/menu/KeySetUtils.java @@ -5,7 +5,7 @@ package com.fr.design.menu; -import javax.swing.*; +import javax.swing.KeyStroke; import java.awt.event.KeyEvent; import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_MODIFIER; @@ -20,6 +20,23 @@ import static com.fr.design.gui.syntax.ui.rtextarea.RTADefaultInputMap.DEFAULT_M public class KeySetUtils { + public static final MenuKeySet NEW_FOLDER = new MenuKeySet() { + @Override + public char getMnemonic() { + return 'I'; + } + + @Override + public String getMenuName() { + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_New_Folder"); + } + + @Override + public KeyStroke getKeyStroke() { + return KeyStroke.getKeyStroke(KeyEvent.VK_I, DEFAULT_MODIFIER); + } + }; + public static final MenuKeySet OPEN_TEMPLATE = new MenuKeySet() { @Override @@ -547,7 +564,9 @@ public class KeySetUtils { public static final MenuKeySet REPORT_WATERMARK = new MenuKeySet() { @Override - public char getMnemonic() { return 'M'; } + public char getMnemonic() { + return 'M'; + } @Override public String getMenuName() { @@ -974,14 +993,6 @@ public class KeySetUtils { }; - - - - - - - - public static final MenuKeySet INSERT_FLOAT = new MenuKeySet() { @Override public char getMnemonic() { @@ -1000,41 +1011,4 @@ public class KeySetUtils { }; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } diff --git a/designer-base/src/main/java/com/fr/file/FILE.java b/designer-base/src/main/java/com/fr/file/FILE.java index 3977ee87e..8c1f734cf 100644 --- a/designer-base/src/main/java/com/fr/file/FILE.java +++ b/designer-base/src/main/java/com/fr/file/FILE.java @@ -1,93 +1,106 @@ package com.fr.file; import javax.swing.Icon; +import java.io.InputStream; +import java.io.OutputStream; public interface FILE { /** - * 后缀 - * @return 后缀 + * 前缀 + * + * @return 前缀 */ - public String prefix(); + String prefix(); /** * 是否是目录 + * * @return 是则返回true */ - public boolean isDirectory(); - - // Name - public String getName(); - - // Icon - public Icon getIcon(); - - // 当前目录的Path - public String getPath(); - - public void setPath(String path); - - // 取当前目录的上级目录 - public FILE getParent(); + boolean isDirectory(); + + // Name + String getName(); + + // Icon + Icon getIcon(); + + // 当前目录的Path + String getPath(); + + void setPath(String path); + + // 取当前目录的上级目录 + FILE getParent(); /** * 列出当前目录下所有的文件及文件夹 + * * @return 文件 */ - public FILE[] listFiles(); + FILE[] listFiles(); /** * 新建一个目录 + * * @param name 名字 * @return 新建目录 */ - public boolean createFolder(String name); + boolean createFolder(String name); /** * 新建文件 + * * @return 是否新建成功 * @throws Exception 异常 */ - public boolean mkfile() throws Exception; + boolean mkfile() throws Exception; /** * 是否存在 + * * @return 是否存在 */ - public boolean exists(); + boolean exists(); /** * 关闭文件 + * * @throws Exception 异常 */ - public void closeTemplate() throws Exception; + void closeTemplate() throws Exception; /** * 作为输入流 + * * @return 输入流 * @throws Exception 异常 */ - public java.io.InputStream asInputStream() throws Exception; + InputStream asInputStream() throws Exception; /** * 作为输出流 + * * @return 输出流 * @throws Exception 异常 */ - public java.io.OutputStream asOutputStream() throws Exception; - - public String getEnvFullName(); + OutputStream asOutputStream() throws Exception; + + String getEnvFullName(); /** * 是否是内存文件 + * * @return 是则返回true */ - public boolean isMemFile(); + boolean isMemFile(); /** * 是否是环境文件 + * * @return 是则返回true */ - public boolean isEnvFile(); + boolean isEnvFile(); } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index 3629dfdf9..447ebc367 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -3,17 +3,19 @@ package com.fr.file; import com.fr.base.BaseUtils; import com.fr.base.FRContext; import com.fr.base.extension.FileExtension; -import com.fr.file.filetree.LocalFileNodes; import com.fr.design.DesignerEnvManager; import com.fr.design.actions.UpdateAction; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.UIDialog; import com.fr.design.file.HistoryTemplateListPane; 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.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; @@ -21,37 +23,63 @@ import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.file.filetree.FileNode; +import com.fr.file.filetree.LocalFileNodes; 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.stable.CoreConstants; -import com.fr.stable.OperatingSystem; 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 javax.swing.*; +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.*; +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.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; @@ -68,6 +96,7 @@ import java.util.regex.Pattern; * 该文件选择器,整理行为如下: */ public class FILEChooserPane extends BasicPane { + /** * Return value if OK is chosen. */ @@ -81,17 +110,22 @@ public class FILEChooserPane extends BasicPane { 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(); - public FILE currentDirectory; // 当前路径,在subFileList中显示这个路径下所有的文件 + private FILE currentDirectory; // 当前路径,在subFileList中显示这个路径下所有的文件 - private List filterList = new ArrayList(); + private List filterList = new ArrayList<>(); private FILEFilter filter; private LocationButtonPane locationBtnPane; // 显示location的Panel - private UIButton createFolderButton; + private UIButton mkdirButton; - private PlaceListModel model; private JList placesList; // File.listRoots() + Env + Favourite private JList subFileList; // 当前选中目录下的文件夹及文件 @@ -100,7 +134,6 @@ public class FILEChooserPane extends BasicPane { private UIComboBox postfixComboBox; // 文件后缀名的下拉列表框 private UIButton okButton; - private UIButton cancelButton; protected int type; @@ -110,7 +143,7 @@ public class FILEChooserPane extends BasicPane { private UIDialog dialog; - private int returnValue = CANCEL_OPTION; + private int option = CANCEL_OPTION; protected String suffix; @@ -138,7 +171,7 @@ public class FILEChooserPane extends BasicPane { INSTANCE.showEnv = showEnv; INSTANCE.showLoc = showLoc; INSTANCE.showWebReport = false; - INSTANCE.setModelOfPlaceList(); + INSTANCE.setPlaceListModel(); INSTANCE.removeAllFilter(); return INSTANCE; } @@ -150,7 +183,7 @@ public class FILEChooserPane extends BasicPane { */ public static FILEChooserPane getInstance(boolean showEnv, FILEFilter filter) { INSTANCE.showEnv = showEnv; - INSTANCE.setModelOfPlaceList(); + INSTANCE.setPlaceListModel(); INSTANCE.removeAllFilter(); INSTANCE.addChooseFILEFilter(filter, 0); return INSTANCE; @@ -166,7 +199,7 @@ public class FILEChooserPane extends BasicPane { INSTANCE.showEnv = showEnv; INSTANCE.showLoc = showLoc; INSTANCE.showWebReport = false; - INSTANCE.setModelOfPlaceList(); + INSTANCE.setPlaceListModel(); INSTANCE.removeAllFilter(); INSTANCE.addChooseFILEFilter(filter, 0); return INSTANCE; @@ -183,7 +216,7 @@ public class FILEChooserPane extends BasicPane { INSTANCE.showEnv = showEnv; INSTANCE.showLoc = showLoc; INSTANCE.showWebReport = showWebReport; - INSTANCE.setModelOfPlaceList(); + INSTANCE.setPlaceListModel(); INSTANCE.removeAllFilter(); INSTANCE.addChooseFILEFilterToFist(filter, 0); return INSTANCE; @@ -202,7 +235,7 @@ public class FILEChooserPane extends BasicPane { actionMap.put("dialogExit", new AbstractAction() { @Override public void actionPerformed(ActionEvent evt) { - returnValue = CANCEL_OPTION; + option = CANCEL_OPTION; dialogExit(); } }); @@ -211,8 +244,8 @@ public class FILEChooserPane extends BasicPane { // locationPane.setLayout(FRGUIPaneFactory.createBorderLayout()); locationPane.add(locationBtnPane = new LocationButtonPane(), BorderLayout.CENTER); - createFolderButton = createFolderButton(); - locationPane.add(createFolderButton, BorderLayout.EAST); + mkdirButton = initMkdirButton(); + locationPane.add(mkdirButton, BorderLayout.EAST); JPanel centerLeftPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); // centerLeftPanel.setLayout(FRGUIPaneFactory.createBorderLayout()); @@ -222,32 +255,161 @@ public class FILEChooserPane extends BasicPane { centerLeftPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY)); centerLeftPanel.setPreferredSize(new Dimension(120, 1)); placesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - placesList.setCellRenderer(placelistRenderer); - placesList.addListSelectionListener(placeListener); - placesList.addMouseListener(placeMouseListener); + 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(); - // subFilePanel.setLayout(FRGUIPaneFactory.createBorderLayout()); // - // TODO alex_GUI // 以后rightPanel要用JTable - subFileList = new JList(new DefaultListModel()); - subFileList.setCellRenderer(listRenderer); - subFileList.addMouseListener(subFileListMouseListener); - subFileList.addKeyListener(subFileListKeyListener); + 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(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_File_Name") + ":"), BorderLayout.WEST), - fileNameTextField = new UIAutoCompletionField(), okButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Design_File_Open")) + 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(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Utils_File_Type") + ":"), BorderLayout.WEST), - postfixComboBox = new UIComboBox(), cancelButton = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Design_Action_Cancel")) + 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, @@ -255,7 +417,7 @@ public class FILEChooserPane extends BasicPane { centerRightPane.add(fileNamePane, BorderLayout.SOUTH); Component[][] outComponents = new Component[][]{ - new Component[]{GUICoreUtils.createBorderPane(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_File_Lookup_range") + ":"), BorderLayout.WEST), locationPane}, + 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}); @@ -269,7 +431,7 @@ public class FILEChooserPane extends BasicPane { cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { - returnValue = CANCEL_OPTION; + option = CANCEL_OPTION; doCancel(); } }); @@ -277,7 +439,7 @@ public class FILEChooserPane extends BasicPane { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { - returnValue = CANCEL_OPTION; + option = CANCEL_OPTION; doOK(); } } @@ -309,7 +471,7 @@ public class FILEChooserPane extends BasicPane { this(); this.showEnv = showEnv; this.showLoc = showLoc; - this.setModelOfPlaceList(); + this.setPlaceListModel(); } @@ -320,7 +482,7 @@ public class FILEChooserPane extends BasicPane { */ public FILE getSelectedFILE() { String fileName = fileNameTextField.getText().trim(); - if (!fileName.endsWith(suffix) && fileName.indexOf(CoreConstants.DOT) == -1) { + if (!fileName.endsWith(suffix) && !fileName.contains(CoreConstants.DOT)) { fileName += this.suffix; } if (currentDirectory == null) { @@ -334,7 +496,7 @@ public class FILEChooserPane extends BasicPane { } protected String getEnvProjectName() { - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Env_Directory"); + return Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Env_Directory"); } /** @@ -360,9 +522,6 @@ public class FILEChooserPane extends BasicPane { this.filterList.add(index, filter); } - // August:上面的方法在包含时直接return了,应该把改filter放在第一个 - // 不然在多次打开两个FILEchooserpane时,filter会出错 - /** * 若是已经存在,则将之删去之后,在指定的位置增加 * @@ -427,22 +586,15 @@ public class FILEChooserPane extends BasicPane { fileNameTextField.removeDocumentListener(); fileNameTextField.setText(text); fileNameTextField.addDocumentListener(); - if (currentDirectory != null) { + if (currentDirectory == null) { return; } - FILE[] res_array = currentDirectory.listFiles(); - String[] name_array = new String[res_array.length]; - for (int i = 0; i < res_array.length; i++) { - name_array[i] = res_array[i].getName(); + 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(name_array)); - } - - /** - * @return - */ - public String getFileNameTextField() { - return this.fileNameTextField.getText(); + fileNameTextField.setFilter(new DefaultCompletionFilter(names)); } @@ -514,7 +666,7 @@ public class FILEChooserPane extends BasicPane { @Override public void windowClosing(WindowEvent e) { - returnValue = CANCEL_OPTION; + option = CANCEL_OPTION; dialogExit(); } }); @@ -527,15 +679,13 @@ public class FILEChooserPane extends BasicPane { chooseType(); // richer:当文件类型被选定时,显示的文件就仅仅显示被选定的类型 // 如果是保存对话框,给个默认名字 - if (type == JFileChooser.SAVE_DIALOG) { - this.getFileNameTextField(); - } else { + if (type != JFileChooser.SAVE_DIALOG) { fileNameTextField.removeDocumentListener(); fileNameTextField.setText(""); fileNameTextField.addDocumentListener(); } dialog.setVisible(true); - return returnValue; + return option; } protected void fileType() { @@ -546,39 +696,39 @@ public class FILEChooserPane extends BasicPane { EnumSet fileExtensions = EnumSet.of(FileExtension.CPT, FileExtension.CPTX, FileExtension.FRM, FileExtension.FRMX, FileExtension.CHT); if (type == JFileChooser.OPEN_DIALOG) { if (WorkContext.getCurrent().isLocal()) { //本地连接 - this.addChooseFILEFilter(new ChooseFileFilter(fileSuffix_local, appName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_File"))); + this.addChooseFILEFilter(new ChooseFileFilter(fileSuffix_local, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); } else { - this.addChooseFILEFilter(new ChooseFileFilter(fileExtensions, appName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_File"))); + this.addChooseFILEFilter(new ChooseFileFilter(fileExtensions, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); } } // ben:filefilter设置初值为cpt过滤 - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPT, appName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_File"))); - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPTX, appName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_File"))); + 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 + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_File"))); - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.FRMX, appName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_File"))); + this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.FRM, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); + this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.FRMX, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); } else { if (type == JFileChooser.OPEN_DIALOG) { - this.addChooseFILEFilter(new ChooseFileFilter(EnumSet.of(FileExtension.XLS, FileExtension.XLSX), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Excel_Source"))); + 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, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Excel_Source"))); - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.XLSX, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Excel2007_Source"))); + 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, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_Export_png"))); + 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, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Export_PDF"))); - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.SVG, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Export_SVG"))); - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CSV, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Export_CSV"))); - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.DOC, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Export_Word"))); - this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.TXT, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Import_Export_Text"))); + 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"))); } } @@ -586,12 +736,12 @@ public class FILEChooserPane extends BasicPane { private void chooseType() { DefaultComboBoxModel defaultComboBoxModel = (DefaultComboBoxModel) postfixComboBox.getModel(); defaultComboBoxModel.removeAllElements(); - for (FILEFilter aFilterList : filterList) { - defaultComboBoxModel.addElement(aFilterList); + for (FILEFilter filter : filterList) { + defaultComboBoxModel.addElement(filter); } if (WorkContext.getCurrent().isLocal()) { //本地连接 if (!showWebReport) { - defaultComboBoxModel.addElement(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_App_AllFiles") + "(*.*)"); + defaultComboBoxModel.addElement(Toolkit.i18nText("Fine-Design_Basic_Utils_App_AllFiles") + "(*.*)"); } } // 默认选取的文件类型(.cpt)类型 @@ -643,11 +793,11 @@ public class FILEChooserPane extends BasicPane { if (this.subFileList.getSelectedValue() == null) { FILE file = this.getSelectedFILE(); if (file.exists()) { - returnValue = OK_OPTION; + option = OK_OPTION; saveDictionary(); dialogExit(); } else { - JOptionPane.showMessageDialog(this, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_Template_Report_Not_Exist")); + JOptionPane.showMessageDialog(this, Toolkit.i18nText("Fine-Design_Basic_App_Template_Report_Not_Exist")); return; } } @@ -657,7 +807,7 @@ public class FILEChooserPane extends BasicPane { if (selectedSubFile != null && selectedSubFile.isDirectory()) { setSelectedDirectory((FILE) this.subFileList.getSelectedValue()); } else { - returnValue = OK_OPTION; + option = OK_OPTION; saveDictionary(); dialogExit(); } @@ -678,34 +828,42 @@ public class FILEChooserPane extends BasicPane { fileNameTextField.setText(filename + this.suffix); } } - returnValue = OK_OPTION; + option = OK_OPTION; FILE selectedFile = this.getSelectedFILE(); - boolean access = false; + if (access(selectedFile) && access(currentDirectory)) { + if (selectedFile.exists()) { + int selVal = JOptionPane.showConfirmDialog(dialog, Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Cover_The_Current_File") + " ?", + ProductConstants.PRODUCT_NAME, JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE); + if (selVal == JOptionPane.YES_OPTION) { + option = JOPTIONPANE_OK_OPTION; + saveDictionary(); + dialogExit(); + } else { + option = JOPTIONPANE_CANCEL_OPTION; + } + + } else { + dialogExit(); + saveDictionary(); + } + } else { + JOptionPane.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 = false; try { access = FRContext.getOrganizationOperator().canAccess(selectedFile.getPath()); + if (selectedFile.isEnvFile() && selectedFile instanceof FileNodeFILE) { + access = access && ((FileNodeFILE) selectedFile).hasFullAuth(); + } } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } - if (!access) { - JOptionPane.showMessageDialog(FILEChooserPane.this, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_Privilege_No") + "!", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_File_Message"), JOptionPane.WARNING_MESSAGE); - return; - } - if (selectedFile.exists()) { - int selVal = JOptionPane.showConfirmDialog(dialog, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Cover_The_Current_File") + " ?", - ProductConstants.PRODUCT_NAME, JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE); - if (selVal == JOptionPane.YES_OPTION) { - returnValue = JOPTIONPANE_OK_OPTION; - saveDictionary(); - dialogExit(); - } else { - returnValue = JOPTIONPANE_CANCEL_OPTION; - } - - } else { - dialogExit(); - saveDictionary(); - } + return access; } private void saveDictionary() { @@ -730,18 +888,11 @@ public class FILEChooserPane extends BasicPane { dialog = null; } - /** - * @return - */ - public int getReturnValue() { - return this.returnValue; - } - /* * dialog的名字 */ private String dialogName() { - return type == JFileChooser.OPEN_DIALOG ? com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Design_File_Open") : com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_Template_Save"); + return type == JFileChooser.OPEN_DIALOG ? Toolkit.i18nText("Fine-Design_Basic_Utils_Design_File_Open") : Toolkit.i18nText("Fine-Design_Basic_App_Template_Save"); } /* @@ -756,7 +907,6 @@ public class FILEChooserPane extends BasicPane { for (int i = 0, len = model.getSize(); i < len; i++) { if (ComparatorUtils.equals(name, ((FILE) model.getElementAt(i)).getName())) { subFileList.setSelectedIndex(i); - // TODO alex_GUI 怎么ScrollIntoView? break; } } @@ -782,20 +932,12 @@ public class FILEChooserPane extends BasicPane { }; } if (FILEChooserPane.this.showWebReport) { - // webReportFILE = new FileFILE(new - // File(FRContext.getCommonOperator().getWebReportPath())); webReportFILE = new FileNodeFILE(FRContext.getCommonOperator().getWebRootPath()); - // String webReportPath = - // FRContext.getCommonOperator().getWebReportPath(); - // String webReportParentPath = new - // File(webReportPath).getParent(); - // webReportFILE = new FileNodeFILE(new FileNode("WebReport", - // true),webReportParentPath); } if (FILEChooserPane.this.showLoc) { - if (OperatingSystem.isWindows()) { + if (WindowsDetector.detect(true)) { // windows下展示桌面 File[] desktop = FileSystemView.getFileSystemView().getRoots(); if (desktop != null) { @@ -805,7 +947,8 @@ public class FILEChooserPane extends BasicPane { } } } - } else { // *nix下展示家目录 + } else { + // *nix下展示家目录 filesOfSystem.add(new FileFILE(FileSystemView.getFileSystemView().getDefaultDirectory())); } @@ -847,11 +990,11 @@ public class FILEChooserPane extends BasicPane { } } - private void setCD(final FILE lastdirctory) { + private void setCD(final FILE lastDirectory) { for (int i = 0; i < this.getSize(); i++) { FILE file = this.getElementAt(i); - if (ComparatorUtils.equals(lastdirctory.prefix(), file.prefix())) { - setCurrentDirectory(lastdirctory); + if (ComparatorUtils.equals(lastDirectory.prefix(), file.prefix())) { + setCurrentDirectory(lastDirectory); return; } } @@ -859,16 +1002,17 @@ public class FILEChooserPane extends BasicPane { } } - protected void setModelOfPlaceList() { + private void setPlaceListModel() { if (placesList == null) { return; } - model = new PlaceListModel(); + PlaceListModel model = new PlaceListModel(); placesList.setModel(model); - String lastdirctorypath = DesignerEnvManager.getEnvManager().getDialogCurrentDirectory(); + String lastDirectoryPath = DesignerEnvManager.getEnvManager().getDialogCurrentDirectory(); String prefix = DesignerEnvManager.getEnvManager().getCurrentDirectoryPrefix(); - FILE lastdirctory = FILEFactory.createFolder(prefix + lastdirctorypath); - model.setCD(lastdirctory); + FILE lastDirectory = FILEFactory.createFolder(prefix + lastDirectoryPath); + + model.setCD(lastDirectory); if (currentDirectory != null) { return; @@ -884,159 +1028,10 @@ public class FILEChooserPane extends BasicPane { } } - private ListCellRenderer placelistRenderer = 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; - } - - }; - /* - * JList的CellRenderer - */ - private ListCellRenderer listRenderer = 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; - } - - }; - // placeList listener - ListSelectionListener placeListener = new ListSelectionListener() { - @Override - public void valueChanged(ListSelectionEvent e) { - Object selValue = placesList.getSelectedValue(); - if (selValue instanceof FILE) { - setSelectedDirectory((FILE) selValue); - } - } - }; - - /** - * placeList mouseListener - */ - private MouseListener placeMouseListener = new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - Object selValue = placesList.getSelectedValue(); - if (selValue instanceof FILE) { - setSelectedDirectory((FILE) selValue); - } - } - }; - - /** - * right list. - */ - private KeyListener subFileListKeyListener = 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(); - } - } - } - - } - }; - /* - * 鼠标点击JList时的listener - */ - private MouseListener subFileListMouseListener = 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(); - } - } - } - } - }; - /* * 选中文件 */ private void setFileTextField(FILE file) { - // clickedFILE = file; - - // String okButtonText; - // if (file != null && file.isDirectory() - // && this.fileNameTextField.getText().length() == 0) { - // okButtonText = com.fr.design.i18n.Toolkit.i18nText("Open");// + "(O)"; - // } else { - // okButtonText = dialogName(); - // } - // okButton.setText(okButtonText); - if (file != null && !file.isDirectory()) { fileNameTextField.setText(file.getName()); if (file instanceof FileFILE) { @@ -1066,7 +1061,7 @@ public class FILEChooserPane extends BasicPane { for (int i = 0; i < defaultListModel.getSize(); i++) { if (defaultListModel.getElementAt(i) instanceof FileFILE) { FileFILE popDir = (FileFILE) defaultListModel.getElementAt(i); - if (popDir != null && dir != null && dir.getPath().indexOf(popDir.getPath()) == 0) { + if (popDir != null && dir.getPath().indexOf(popDir.getPath()) == 0) { placesList.setSelectedIndex(i); break; } @@ -1089,7 +1084,7 @@ public class FILEChooserPane extends BasicPane { currentDirectory = dir; this.locationBtnPane.populate(currentDirectory); - this.createFolderButton.setEnabled(currentDirectory != null); + this.mkdirButton.setEnabled(currentDirectory != null); refreshSubFileListModel(); } @@ -1127,7 +1122,7 @@ public class FILEChooserPane extends BasicPane { private BasicArrowButton leftArrowButton; private BasicArrowButton rightArrowButton; - private List buttonList = new ArrayList(); + private List buttonList = new ArrayList<>(); private int pathIndex = 0; private int maxPathIndex = 0; @@ -1198,7 +1193,6 @@ public class FILEChooserPane extends BasicPane { if (dir == null) { return; } - String path = dir.getPath(); isWebAppNamePath = ComparatorUtils.equals(dir.prefix(), FILEFactory.WEBREPORT_PREFIX); // 确保最后一个字符是分隔符 @@ -1209,9 +1203,7 @@ public class FILEChooserPane extends BasicPane { if (StringUtils.isBlank(path) && isWebAppNamePath) { this.buttonList.add(createBlankButton(new SetDirectoryAction(webAppName + '/'))); } - - Pattern seperatorPattern = Pattern.compile("[/\\\\]+"); // alex:之所以在Pattern那里加个+,是因为有些路径会有两个甚至多个分隔符放在一起 - Matcher matcher = seperatorPattern.matcher(path); + Matcher matcher = SEPARATOR_PATTERN.matcher(path); int node_start = 0; while (matcher.find()) { int start = matcher.start(); @@ -1223,7 +1215,7 @@ public class FILEChooserPane extends BasicPane { 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(new String[]{btn_path, "/"})))))); + FILEFactory.createFolder(dir.prefix() + StableUtils.pathJoin(btn_path, "/")))))); node_start = matcher.end(); } maxPathIndex = calculateMaxPathIndex(); @@ -1350,40 +1342,44 @@ public class FILEChooserPane extends BasicPane { 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(FILEChooserPane.this.getBackground().darker()); + blankButton.setBackground(darker); blankButton.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { - blankButton.setBackground(FILEChooserPane.this.getBackground().brighter()); + blankButton.setBackground(brighter); blankButton.setBorderPainted(true); - repaint(); + blankButton.repaint(); } @Override public void mouseExited(MouseEvent e) { - blankButton.setBackground(FILEChooserPane.this.getBackground().darker()); + blankButton.setBackground(darker); blankButton.setBorderPainted(false); - repaint(); + blankButton.repaint(); } @Override public void mousePressed(MouseEvent e) { - blankButton.setBackground(FILEChooserPane.this.getBackground().brighter()); + blankButton.setBackground(brighter); blankButton.setBorderPainted(false); - repaint(); + blankButton.repaint(); } @Override public void mouseReleased(MouseEvent e) { - blankButton.setBackground(FILEChooserPane.this.getBackground().brighter()); + blankButton.setBackground(darker); blankButton.setBorderPainted(true); - repaint(); + blankButton.repaint(); } @@ -1391,61 +1387,218 @@ public class FILEChooserPane extends BasicPane { 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 { + JOptionPane.showMessageDialog( + FILEChooserPane.this, + Toolkit.i18nText("Fine-Design_Basic_App_Privilege_No") + "!", + Toolkit.i18nText("Fine-Design_Basic_App_File_Message"), + JOptionPane.WARNING_MESSAGE); + } - private ActionListener createFolderActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent evt) { - if (currentDirectory == null) { - return; - } - boolean access = false; - try { - access = FRContext.getOrganizationOperator().canAccess(currentDirectory.getPath()); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - if (!access) { - JOptionPane.showMessageDialog(FILEChooserPane.this, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_Privilege_No") + "!", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_App_File_Message"), JOptionPane.WARNING_MESSAGE); - return; } + }); + return folderButton; + } - String res = JOptionPane.showInputDialog(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Please_Input_A_New_Name")); - if (res != null) { - currentDirectory.createFolder(res); - refreshSubFileListModel(); + /** + * 新建文件夹对话框 + * 支持快捷键Enter,ESC + */ + private class MkdirDialog extends JDialog { - setSelectedFileName(res); - // 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(), res) && allFiles[i].isDirectory()) { - place = i; - break; + 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(); + } } } - scrollPane.validate(); - int total = scrollPane.getVerticalScrollBar().getMaximum(); - int value = total * place / subFileList.getModel().getSize(); - scrollPane.getVerticalScrollBar().setValue(value); + }); + // 重名提示 + 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(); + + 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); + this.dispose(); } - }; - /* - * 新建文件夹的Button - */ - private UIButton createFolderButton() { - UIButton folderButton = new UIButton(); - folderButton.setIcon(BaseUtils.readIcon("/com/fr/design/images/file/newfolder.png")); - folderButton.setEnabled(false); - folderButton.setMargin(new Insets(0, 0, 0, 0)); - folderButton.setUI(new BasicButtonUI()); - folderButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_New_Folder")); - folderButton.addActionListener(createFolderActionListener); - return folderButton; + 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); + } + } } } diff --git a/designer-base/src/main/java/com/fr/file/FILEFactory.java b/designer-base/src/main/java/com/fr/file/FILEFactory.java index f5d690b21..5a19108ee 100644 --- a/designer-base/src/main/java/com/fr/file/FILEFactory.java +++ b/designer-base/src/main/java/com/fr/file/FILEFactory.java @@ -1,6 +1,7 @@ package com.fr.file; import com.fr.base.FRContext; +import com.fr.design.file.NodeAuthProcessor; import com.fr.file.filetree.FileNode; import com.fr.workspace.WorkContext; @@ -19,7 +20,7 @@ public class FILEFactory { * 也有可能就是一个普通的路径d:/foo/bar */ public static FILE createFILE(String path) { - + String envPath = WorkContext.getCurrent().getPath().replaceAll("/", "\\\\"); if (path == null) { return null; @@ -45,7 +46,8 @@ public class FILEFactory { } else if (path.startsWith(MEM_PREFIX)) { return new MemFILE(path.substring(MEM_PREFIX.length())); } else if (path.startsWith(ENV_PREFIX)) { - return new FileNodeFILE(new FileNode(path.substring(ENV_PREFIX.length()), true)); + return NodeAuthProcessor.getInstance(). + fixFILENodeAuth(new FileNode(path.substring(ENV_PREFIX.length()), true)); } else if (path.startsWith(WEBREPORT_PREFIX)) { return new FileNodeFILE(new FileNode(path.substring(WEBREPORT_PREFIX.length()), true), FRContext.getCommonOperator().getWebRootPath()); diff --git a/designer-base/src/main/java/com/fr/file/FileFILE.java b/designer-base/src/main/java/com/fr/file/FileFILE.java index 5242495be..b9c4f7bb0 100644 --- a/designer-base/src/main/java/com/fr/file/FileFILE.java +++ b/designer-base/src/main/java/com/fr/file/FileFILE.java @@ -4,11 +4,11 @@ import com.fr.base.io.XMLEncryptUtils; import com.fr.design.gui.itree.filetree.FileComparator; import com.fr.design.gui.itree.filetree.FileTreeIcon; import com.fr.general.ComparatorUtils; -import com.fr.web.session.SessionLocalManager; import com.fr.stable.StableUtils; import com.fr.stable.project.ProjectConstants; +import com.fr.web.session.SessionLocalManager; -import javax.swing.*; +import javax.swing.Icon; import javax.swing.filechooser.FileSystemView; import java.io.File; import java.io.FileOutputStream; @@ -16,6 +16,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class FileFILE implements FILE { @@ -30,9 +32,9 @@ public class FileFILE implements FILE { } /** - * 后缀 + * 前缀 * - * @return 后缀 + * @return 前缀 */ public String prefix() { return FILEFactory.FILE_PREFIX; @@ -44,7 +46,7 @@ public class FileFILE implements FILE { * @returns 是则返回true */ public boolean isDirectory() { - return file == null ? false : file.isDirectory(); + return file != null && file.isDirectory(); } @Override @@ -118,22 +120,22 @@ public class FileFILE implements FILE { return new FILE[]{this}; } - File[] file_array = file.listFiles(); - if (file_array == null) { + File[] fileArray = file.listFiles(); + if (fileArray == null) { return new FILE[0]; } - java.util.Arrays.sort(file_array, new FileComparator()); + Arrays.sort(fileArray, new FileComparator()); - java.util.List res_list = new ArrayList(file_array.length); + List resList = new ArrayList(fileArray.length); - for (int i = 0; i < file_array.length; i++) { + for (int i = 0; i < fileArray.length; i++) { // 因为有一些系统文件,比如虚拟内存等,会在listFiles的时候出现,但却not exists - if (file_array[i].exists()) { - res_list.add(new FileFILE(file_array[i])); + if (fileArray[i].exists()) { + resList.add(new FileFILE(fileArray[i])); } } - return res_list.toArray(new FILE[res_list.size()]); + return resList.toArray(new FILE[resList.size()]); } /** @@ -147,9 +149,7 @@ public class FileFILE implements FILE { return false; } - File new_file = new File(StableUtils.pathJoin(new String[]{ - file.getAbsolutePath(), name - })); + File new_file = new File(StableUtils.pathJoin(file.getAbsolutePath(), name)); if (new_file.exists()) { return false; @@ -164,7 +164,7 @@ public class FileFILE implements FILE { * @return 是否存在 */ public boolean exists() { - return file == null ? false : file.exists(); + return file != null && file.exists(); } /** @@ -192,13 +192,12 @@ public class FileFILE implements FILE { * 作为输出流 * * @return 输出流 - * @throws Exception 异常 */ - public OutputStream asOutputStream() throws Exception { + public OutputStream asOutputStream() { if (file == null || !file.exists()) { return null; } - java.io.OutputStream out = null; + OutputStream out; try { out = new FileOutputStream(file); } catch (Exception e) { @@ -209,10 +208,8 @@ public class FileFILE implements FILE { /** * 关闭文件 - * - * @throws Exception 异常 */ - public void closeTemplate() throws Exception { + public void closeTemplate() { } @Override @@ -225,10 +222,10 @@ public class FileFILE implements FILE { } /** - * 返回hash码 - * - * @return 返回hash码 - */ + * 返回hash码 + * + * @return 返回hash码 + */ public int hashCode() { int hash = 7; hash = 97 * hash + (this.file != null ? this.file.hashCode() : 0); @@ -251,17 +248,19 @@ public class FileFILE implements FILE { } /** - * 是否是内存文件 - * @return 是则返回true - */ + * 是否是内存文件 + * + * @return 是则返回true + */ public boolean isMemFile() { return false; } /** - * 是否是环境文件 - * @return 是则返回true - */ + * 是否是环境文件 + * + * @return 是则返回true + */ public boolean isEnvFile() { return false; } diff --git a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java index f64f961cb..04016c503 100644 --- a/designer-base/src/main/java/com/fr/file/FileNodeFILE.java +++ b/designer-base/src/main/java/com/fr/file/FileNodeFILE.java @@ -3,32 +3,39 @@ package com.fr.file; import com.fr.base.BaseUtils; import com.fr.base.FRContext; import com.fr.base.io.XMLEncryptUtils; +import com.fr.design.file.NodeAuthProcessor; import com.fr.design.gui.itree.filetree.FileNodeComparator; import com.fr.design.gui.itree.filetree.FileTreeIcon; +import com.fr.design.i18n.Toolkit; import com.fr.file.filetree.FileNode; import com.fr.general.ComparatorUtils; - -import com.fr.workspace.resource.WorkResourceOutputStream; import com.fr.log.FineLoggerFactory; import com.fr.stable.CoreConstants; import com.fr.stable.StableUtils; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; +import com.fr.workspace.resource.WorkResourceOutputStream; -import javax.swing.*; +import javax.swing.Icon; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.OutputStream; +import java.util.Arrays; public class FileNodeFILE implements FILE { - + private FileNode node; - - // carl:记录下FILE对应的运行环境,每次创建都设置下当前的运行环境 + + //记录下FILE对应的运行环境,每次创建都设置下当前的运行环境 private String envPath; - + + /** + * 是否有全部权限 + */ + private boolean hasFullAuth = true; + public FileNodeFILE(FileNodeFILE parent, String name, boolean isDir) { - + FileNode fn = parent.node; String parentDir; if (fn.isDirectory()) { @@ -36,156 +43,187 @@ public class FileNodeFILE implements FILE { } else { parentDir = fn.getParent(); } - + this.node = new FileNode(StableUtils.pathJoin(parentDir, name), isDir); this.envPath = WorkContext.getCurrent().getPath(); + this.hasFullAuth = NodeAuthProcessor.getInstance().fixFileNodeAuth(node); } - + + public FileNodeFILE(FileNode node) { - this.node = node; this.envPath = WorkContext.getCurrent().getPath(); + this.hasFullAuth = NodeAuthProcessor.getInstance().fixFileNodeAuth(node); + } + + public FileNodeFILE(FileNode node, boolean hasFullAuth) { + this(node); + this.hasFullAuth = hasFullAuth; } - + public FileNodeFILE(String envPath) { - this.node = null; this.envPath = envPath; } - + public FileNodeFILE(FileNode node, String envPath) { - this.node = node; this.envPath = envPath; + this.hasFullAuth = NodeAuthProcessor.getInstance().fixFileNodeAuth(node); + } + + public FileNodeFILE(FileNode node, String envPath, boolean hasFullAuth) { + this(node, envPath); + this.hasFullAuth = hasFullAuth; + } + + + /** + * @return 是否有完整权限 + */ + public boolean hasFullAuth() { + return hasFullAuth; } - + /** - * prefix 后缀 + * 前缀 * - * @return 返回后缀 + * @return 前缀 */ + @Override public String prefix() { - + if (ComparatorUtils.equals(getEnvPath(), FRContext.getCommonOperator().getWebRootPath())) { return FILEFactory.WEBREPORT_PREFIX; } return FILEFactory.ENV_PREFIX; } - + /** * @return */ public String getEnvPath() { - + return this.envPath; } - + /** * 是否是目录 * * @return 是则返回true */ + @Override public boolean isDirectory() { - - return ComparatorUtils.equals(node, null) ? true : node.isDirectory(); + + return ComparatorUtils.equals(node, null) || node.isDirectory(); } - + /** * @return */ + @Override public String getName() { - + if (node == null) { return null; } - + if (ComparatorUtils.equals(node.getEnvPath(), ProjectConstants.REPORTLETS_NAME)) { - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Runtime_Env"); + return Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Runtime_Env"); } else { return node.getName(); } } - + /** * @return */ + @Override public Icon getIcon() { - + if (node == null) { return null; } - + if (ComparatorUtils.equals(node.getEnvPath(), ProjectConstants.REPORTLETS_NAME)) { return BaseUtils.readIcon("/com/fr/base/images/oem/logo.png"); } else { + + if (!hasFullAuth) { + return FileTreeIcon.getFolderHalfImageIcon(); + } + return FileTreeIcon.getIcon(node); } } - + /** * @return */ + @Override public String getPath() { - + if (node == null) { return ""; } - + return node.getEnvPath(); } - + /** * @param path */ + @Override public void setPath(String path) { - + node.setEnvPath(path); } - + /** * @return */ + @Override public FILE getParent() { - + if (node == null) { return null; } - + return new FileNodeFILE(new FileNode(node.getParent(), true)); } - + /** * 文件 * * @return 文件组 */ + @Override public FILE[] listFiles() { - + if (ComparatorUtils.equals(node, null)) { node = new FileNode(CoreConstants.SEPARATOR, true); - //return new FILE[0]; } if (!node.isDirectory()) { return new FILE[]{this}; } - + try { - FileNode[] node_array; - node_array = listFile(node.getEnvPath()); - java.util.Arrays.sort(node_array, new FileNodeComparator()); - - FILE[] res_array = new FILE[node_array.length]; - for (int i = 0; i < node_array.length; i++) { - res_array[i] = new FileNodeFILE(node_array[i], envPath); - } - - return res_array; + FileNode[] nodeArray; + nodeArray = listFile(node.getEnvPath()); + Arrays.sort(nodeArray, new FileNodeComparator()); + + return fileNodeArray2FILEArray(nodeArray, envPath); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); return new FILE[0]; } } - + + private FILE[] fileNodeArray2FILEArray(FileNode[] nodeArray, String envPath) { + return NodeAuthProcessor.getInstance().parser2FILEArray(nodeArray, envPath); + } + + /** * 根目录文件地址 * @@ -193,7 +231,7 @@ public class FileNodeFILE implements FILE { * @return 返回文件节点 */ private FileNode[] listFile(String rootFilePath) { - + try { if (ComparatorUtils.equals(envPath, FRContext.getCommonOperator().getWebRootPath())) { return FRContext.getFileNodes().listWebRootFile(rootFilePath); @@ -205,19 +243,20 @@ public class FileNodeFILE implements FILE { } return new FileNode[0]; } - + /** * 创建文件夹 * * @param name 文件夹名字 * @return 创建成功返回true */ + @Override public boolean createFolder(String name) { - + if (ComparatorUtils.equals(node, null) || !node.isDirectory()) { return false; } - + try { return WorkContext.getWorkResource().createDirectory(StableUtils.pathJoin(node.getEnvPath(), name)); } catch (Exception e) { @@ -225,18 +264,18 @@ public class FileNodeFILE implements FILE { return false; } } - + /** * 是否锁住 * * @return 文件被锁返回true */ public boolean isLocked() { - + if (node == null) { return false; } - + try { return FRContext.getCommonOperator().fileLocked(node.getEnvPath()); } catch (Exception e) { @@ -244,14 +283,15 @@ public class FileNodeFILE implements FILE { return false; } } - + /** * 是否存在 * * @return 文件存在返回 true */ + @Override public boolean exists() { - + if (node == null) { return false; } @@ -259,7 +299,7 @@ public class FileNodeFILE implements FILE { if (!isCurrentEnv()) { return false; } - + try { return WorkContext.getWorkResource().exist(node.getEnvPath()); } catch (Exception e) { @@ -267,28 +307,29 @@ public class FileNodeFILE implements FILE { return false; } } - + /** * 是否是当前环境 * * @return 是报表当前环境返回true */ public boolean isCurrentEnv() { - + return ComparatorUtils.equals(WorkContext.getCurrent().getPath(), envPath); } - + /** * 创建文件 * * @return 成功返回true */ + @Override public boolean mkfile() { - + if (node == null) { return false; } - + try { return WorkContext.getWorkResource().createFile(node.getEnvPath()); } catch (Exception e) { @@ -296,43 +337,45 @@ public class FileNodeFILE implements FILE { return false; } } - + /** * 作为输入流 * * @return 输入流 * @throws Exception */ + @Override public InputStream asInputStream() throws Exception { - + if (node == null) { return null; } - + String envPath = node.getEnvPath(); // envPath必须以reportlets开头 if (!envPath.startsWith(ProjectConstants.REPORTLETS_NAME)) { return null; } - + InputStream in = new ByteArrayInputStream(WorkContext.getWorkResource().readFully(StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, envPath.substring(ProjectConstants.REPORTLETS_NAME.length() + 1)))); - + return envPath.endsWith(".cpt") || envPath.endsWith(".frm") - ? XMLEncryptUtils.decodeInputStream(in) : in; + ? XMLEncryptUtils.decodeInputStream(in) : in; } - + /** * 作为输出流 * * @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(ProjectConstants.REPORTLETS_NAME)) { @@ -340,58 +383,62 @@ public class FileNodeFILE implements FILE { } return new WorkResourceOutputStream(envPath); } - + /** * 关闭模板 * * @throws Exception */ + @Override public void closeTemplate() throws Exception { - + if (node == null) { return; } - + String envPath = node.getEnvPath(); // envPath必须以reportlets开头 if (!envPath.startsWith(ProjectConstants.REPORTLETS_NAME)) { return; } - + FRContext.getCommonOperator().unlockTemplate( - envPath.substring(ProjectConstants.REPORTLETS_NAME.length() + 1)); + envPath.substring(ProjectConstants.REPORTLETS_NAME.length() + 1)); } - + /** * 得到环境的全名 * * @return */ + @Override public String getEnvFullName() { - + return this.node.getEnvPath().substring(ProjectConstants.REPORTLETS_NAME.length() + 1); } - + /** * 是否是内存文件 * * @return 是则返回true */ + @Override public boolean isMemFile() { - + return false; } - + /** * 是否是环境文件 * * @return 是则返回true */ + @Override public boolean isEnvFile() { - + return true; } - + /** * 是佛相同 * @@ -399,34 +446,34 @@ public class FileNodeFILE implements FILE { * @return */ public boolean equals(Object obj) { - + if (!(obj instanceof FileNodeFILE)) { return false; } - + return ComparatorUtils.equals(this.envPath, ((FileNodeFILE) obj).envPath) && ComparatorUtils.equals(this.node, ((FileNodeFILE) obj).node); } - + /** * 返回hash码 * * @return 返回hash码 */ public int hashCode() { - + int hash = 5; hash = 61 * hash + (this.node != null ? this.node.hashCode() : 0); hash = 61 * hash + (this.envPath != null ? this.envPath.hashCode() : 0); return hash; } - + /** * 作为字符串返回 * * @return String 字符串 */ public String toString() { - + return prefix() + (this.node != null ? this.node.getEnvPath() : ""); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/file/MemFILE.java b/designer-base/src/main/java/com/fr/file/MemFILE.java index fa76ab047..f35151eb9 100644 --- a/designer-base/src/main/java/com/fr/file/MemFILE.java +++ b/designer-base/src/main/java/com/fr/file/MemFILE.java @@ -1,10 +1,9 @@ package com.fr.file; +import javax.swing.Icon; import java.io.InputStream; import java.io.OutputStream; -import javax.swing.Icon; - public class MemFILE implements FILE { private String name; @@ -103,9 +102,9 @@ public class MemFILE implements FILE { } /** - * 后缀 + * 前缀 * - * @return 后缀 + * @return 前缀 */ public String prefix() { return FILEFactory.MEM_PREFIX; diff --git a/designer-base/src/main/resources/com/fr/design/images/icon_NewFolderIcon_normal.png b/designer-base/src/main/resources/com/fr/design/images/icon_NewFolderIcon_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..9ea75fc6d857fef4e30a72519a4afd56ac7d0759 GIT binary patch literal 288 zcmV+*0pI?KP)Px#+DSw~R5%gEQZWv~Fbs4MVnN~&NHDM_p?`o*d;oU-!9REbQ$B&n3KD#!jd9YZ zL{^Iw7P8d7JD;680RKK>Xn>+9W_9gOhd_UWW_n3Ypv)08z%4pKh|E)B%07QE@ZUiymM#>D+As)0WaWr ztQm14H_tYZQa{rs*#@+cg*TuTh9~fYLE8Vz7E)O=cGKD8@dwfyc?I1ENXz