From 526a43c7c6ba0bad42a3611795516cb54370b19d Mon Sep 17 00:00:00 2001 From: kerry Date: Tue, 15 Oct 2019 11:42:44 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-21017=E3=80=90=E6=96=B0=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E3=80=91=E5=A2=9E=E5=8A=A0cptx=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=8F=8A=E7=9B=B8=E5=85=B3=E9=80=82=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gui/itree/filetree/FileNodeConstants.java | 4 +- .../gui/itree/filetree/FileTreeIcon.java | 29 ++++++++++-- .../AbstractNewTemplateFileProvider.java | 20 ++++++++ .../com/fr/design/mainframe/JTemplate.java | 32 +++++++++++-- .../mainframe/NewTemplateFileProvider.java | 46 +++++++++++++++++++ .../java/com/fr/file/FILEChooserPane.java | 25 +++++----- .../itree/filetree/FileNodeConstantsTest.java | 39 ++++++++++++---- .../java/com/fr/file/FILEChooserPaneTest.java | 38 +++++++++++++++ .../java/com/fr/design/mainframe/JForm.java | 14 ++++++ .../com/fr/design/mainframe/JWorkBook.java | 9 ++++ 10 files changed, 226 insertions(+), 30 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/AbstractNewTemplateFileProvider.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/NewTemplateFileProvider.java create mode 100644 designer-base/src/test/java/com/fr/file/FILEChooserPaneTest.java diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java index 8c5f0e154..256fee21b 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java +++ b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileNodeConstants.java @@ -55,12 +55,14 @@ public class FileNodeConstants { private static void initSupportedTypes() { try { rwl.writeLock().lock(); - supportFileType = new ArrayList<>(Arrays.asList(FRContext.getFileNodes().getSupportedTypes())); + supportFileType = new ArrayList(); //通过插件扩展的 Set apps = ExtraDesignClassManager.getInstance().getArray(App.MARK_STRING); for (App app : apps) { addAppExtensions(app.defaultExtensions()); } + supportFileType.addAll(Arrays.asList(FRContext.getFileNodes().getSupportedTypes())); + } finally { rwl.writeLock().unlock(); } diff --git a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java index b0e26cc80..1a84fa169 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java +++ b/designer-base/src/main/java/com/fr/design/gui/itree/filetree/FileTreeIcon.java @@ -1,7 +1,9 @@ package com.fr.design.gui.itree.filetree; import com.fr.base.BaseUtils; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.icon.LockIcon; +import com.fr.design.mainframe.NewTemplateFileProvider; import com.fr.file.filetree.FileNode; import com.fr.general.ComparatorUtils; import com.fr.stable.StableUtils; @@ -11,6 +13,7 @@ import javax.swing.Icon; import javax.swing.UIManager; import javax.swing.filechooser.FileSystemView; import java.io.File; +import java.util.Set; public class FileTreeIcon { private FileTreeIcon() { @@ -146,16 +149,36 @@ public class FileTreeIcon { if (node.isDirectory()) { return FileTreeIcon.FOLDER_IMAGE_ICON; } - return FileSystemView.getFileSystemView().getSystemIcon(new File(path)); + return getLocalFileIcon(path); } } if (node.isDirectory()) { return FileTreeIcon.FOLDER_IMAGE_ICON; } else { - return FileTreeIcon.getIcon(FileTreeIcon.getFileType(node.getName()), isShowLock); + return getRemoteFileIcon(node, isShowLock); } } + private static Icon getLocalFileIcon(String path) { + Set providers = ExtraDesignClassManager.getInstance().getArray(NewTemplateFileProvider.XML_TAG); + for (NewTemplateFileProvider provider : providers) { + if (provider.getLocalFileIcon(path) != null) { + return provider.getLocalFileIcon(path); + } + } + return FileSystemView.getFileSystemView().getSystemIcon(new File(path)); + } + + private static Icon getRemoteFileIcon(FileNode node, boolean isShowLock){ + Set providers = ExtraDesignClassManager.getInstance().getArray(NewTemplateFileProvider.XML_TAG); + for (NewTemplateFileProvider provider : providers) { + if (provider.getRemoteFileIcon(node, isShowLock) != null) { + return provider.getRemoteFileIcon(node, isShowLock); + } + } + return FileTreeIcon.getIcon(FileTreeIcon.getFileType(node.getName()), isShowLock); + } + private static Icon getIcon(int fileType, boolean isLocked) { if (fileType == JAVA_FILE) { if (isLocked) { @@ -293,4 +316,4 @@ public class FileTreeIcon { return TEXT_FILE; } } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/AbstractNewTemplateFileProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/AbstractNewTemplateFileProvider.java new file mode 100644 index 000000000..64a6f480f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/AbstractNewTemplateFileProvider.java @@ -0,0 +1,20 @@ +package com.fr.design.mainframe; + +import com.fr.stable.fun.mark.API; + +/** + * Created by kerry on 2019-10-14 + */ +@API(level = NewTemplateFileProvider.CURRENT_LEVEL) +public abstract class AbstractNewTemplateFileProvider implements NewTemplateFileProvider { + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public String mark4Provider() { + return getClass().getName(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 852130c1e..1daeb4d81 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -4,6 +4,7 @@ import com.fr.base.BaseUtils; import com.fr.base.FRContext; import com.fr.base.Parameter; import com.fr.base.ScreenResolution; +import com.fr.base.extension.FileExtension; import com.fr.base.io.BaseBook; import com.fr.base.iofile.attr.DesignBanCopyAttrMark; import com.fr.base.iofile.attr.TemplateIdAttrMark; @@ -12,7 +13,6 @@ import com.fr.design.DesignModelAdapter; import com.fr.design.DesignState; import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; -import com.fr.design.actions.AllowAuthorityEditAction; import com.fr.design.actions.TableDataSourceAction; import com.fr.design.actions.edit.RedoAction; import com.fr.design.actions.edit.UndoAction; @@ -49,6 +49,7 @@ import com.fr.design.write.submit.DBManipulationPane; import com.fr.file.FILE; import com.fr.file.FILEChooserPane; import com.fr.file.MemFILE; +import com.fr.file.filter.ChooseFileFilter; import com.fr.form.ui.NoneWidget; import com.fr.form.ui.Widget; import com.fr.general.ComparatorUtils; @@ -575,6 +576,7 @@ public abstract class JTemplate> String oldName = this.getPath(); // alex:如果是SaveAs的话需要让用户来选择路径了 FILEChooserPane fileChooser = getFILEChooserPane(isShowLoc); + addChooseFILEFilter(fileChooser); fileChooser.setFileNameTextField(fileName, this.suffix()); int chooseResult = fileChooser.showSaveDialog(DesignerContext.getDesignerFrame(), this.suffix()); @@ -625,6 +627,16 @@ public abstract class JTemplate> } } + protected void addChooseFILEFilter(FILEChooserPane fileChooser){ + String appName = ProductConstants.APP_NAME; + fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPT, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); + if (FileExtension.FRM.matchExtension(this.suffix())) { + // richer:form文件 daniel 改成三个字 + fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.FRM, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); + } + + } + // 保存新模板时会进入此方法(新建模板直接保存,或者另存为) protected boolean saveNewFile(FILE editingFILE, String oldName) { String originID = StringUtils.EMPTY; @@ -635,13 +647,25 @@ public abstract class JTemplate> initForCollect(); this.editingFILE = editingFILE; - boolean result = this.saveFile(); + boolean result = this.saveToNewFile(oldName); if (result) { DesignerFrameFileDealerPane.getInstance().refresh(); collectInfo(originID); } - //更换最近打开 - DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getPath()); + return result; + } + + protected boolean saveToNewFile(String oldName){ + boolean result = false; + Set providers = ExtraDesignClassManager.getInstance().getArray(NewTemplateFileProvider.XML_TAG); + for (NewTemplateFileProvider provider : providers) { + result = result || provider.saveToNewFile(this.editingFILE.getPath(), this); + } + if(!result && FileExtension.CPT.matchExtension(this.editingFILE.getPath())){ + result = result || this.saveFile(); + //更换最近打开 + DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getPath()); + } return result; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/NewTemplateFileProvider.java b/designer-base/src/main/java/com/fr/design/mainframe/NewTemplateFileProvider.java new file mode 100644 index 000000000..e14a54d7b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/NewTemplateFileProvider.java @@ -0,0 +1,46 @@ +package com.fr.design.mainframe; + +import com.fr.file.FILEChooserPane; +import com.fr.file.filetree.FileNode; +import com.fr.stable.fun.mark.Mutable; + +import javax.swing.Icon; + +/** + * Created by kerry on 2019-10-11 + */ +public interface NewTemplateFileProvider extends Mutable { + + int CURRENT_LEVEL = 1; + + String XML_TAG = "NewFileTypeProvider"; + + /** + * 向文件选择器中添加指定文件类型过滤器 + * @param fileChooser 文件选择器 + * @param suffix 文件后缀 + */ + void addChooseFileFilter(FILEChooserPane fileChooser, String suffix); + + /** + * 获取本地目录文件关联的icon + * @param path 文件路径 + * @return 对应的图标 + */ + Icon getLocalFileIcon(String path); + + /** + * 获取远程目录文件关联的icon + * @param node 文件节点 + * @param isShowLock 是否显示被锁住 + * @return 对应的图标 + */ + Icon getRemoteFileIcon(FileNode node, boolean isShowLock); + + /** + * 保存为新类型文件 + * @param targetPath 目标路径 + * @param jTemplate 模板对象 + */ + boolean saveToNewFile(String targetPath, JTemplate jTemplate); +} 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 fc4a5dfea..7c6e56bb7 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -782,12 +782,7 @@ public class FILEChooserPane extends BasicPane { } } //jerry 26216 只保留.cpt .frm有用的格式,并且不可编辑 - if (type == JFileChooser.OPEN_DIALOG) { - postfixComboBox.setEnabled(true); - } else { - postfixComboBox.setEnabled(false); - } - + postfixComboBox.setEnabled(true); //只有一个类型时不可下拉 if (filterList.size() == 1) { postfixComboBox.setEnabled(false); @@ -841,14 +836,7 @@ public class FILEChooserPane extends BasicPane { private void saveDialog() { String filename = fileNameTextField.getText(); - if (!filename.endsWith(suffix)) { - ChooseFileFilter chooseFileFilter = (ChooseFileFilter) (postfixComboBox.getSelectedItem()); - if (chooseFileFilter != null && StringUtils.isNotEmpty(chooseFileFilter.getExtensionString())) { - fileNameTextField.setText(filename + chooseFileFilter.getExtensionString()); - } else { - fileNameTextField.setText(filename + this.suffix); - } - } + fileNameTextField.setText(calFileNameText(filename, (ChooseFileFilter) (postfixComboBox.getSelectedItem()))); option = OK_OPTION; FILE selectedFile = this.getSelectedFILE(); @@ -874,6 +862,15 @@ public class FILEChooserPane extends BasicPane { } } + private String calFileNameText(String currentValue, ChooseFileFilter selectFileFilter) { + if (selectFileFilter == null || StringUtils.isEmpty(selectFileFilter.getExtensionString())) { + return currentValue + this.suffix; + } else if (!currentValue.endsWith(selectFileFilter.getExtensionString())) { + return currentValue + selectFileFilter.getExtensionString(); + } + return currentValue; + } + private boolean access(FILE selectedFile) { boolean access = false; try { diff --git a/designer-base/src/test/java/com/fr/design/gui/itree/filetree/FileNodeConstantsTest.java b/designer-base/src/test/java/com/fr/design/gui/itree/filetree/FileNodeConstantsTest.java index 67f082456..a12ae6c14 100644 --- a/designer-base/src/test/java/com/fr/design/gui/itree/filetree/FileNodeConstantsTest.java +++ b/designer-base/src/test/java/com/fr/design/gui/itree/filetree/FileNodeConstantsTest.java @@ -11,6 +11,10 @@ import com.fr.stable.fun.mark.Mutable; import org.easymock.EasyMock; import org.junit.Assert; import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.api.easymock.PowerMock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; import java.util.HashSet; import java.util.Set; @@ -18,23 +22,42 @@ import java.util.Set; /** * Created by alex sung on 2019/7/25. */ +@RunWith(PowerMockRunner.class) +@PrepareForTest(ExtraDesignClassManager.class) public class FileNodeConstantsTest { @Test - public void supportFileTypesTest(){ - ExtraDesignClassManager extra = EasyMock.mock(ExtraDesignClassManager.class); - Set apps = new HashSet(){{add(new MockCptxApp());}}; - EasyMock.expect(extra.getArray(App.MARK_STRING)).andReturn(apps).anyTimes(); - EasyMock.replay(extra); - + public void supportFileTypesTest() { + ExtraDesignClassManager extra = mockExtraDesignClassManager(); Assert.assertEquals(1, extra.getArray(App.MARK_STRING).size()); App app = (App) extra.getArray(App.MARK_STRING).iterator().next(); Assert.assertEquals("cptx", app.defaultExtensions()[0]); } - private class MockCptxApp extends AbstractAppProvider{ + @Test + public void testSupportFileTypesOrder() { + ExtraDesignClassManager extra = mockExtraDesignClassManager(); + PowerMock.mockStatic(ExtraDesignClassManager.class); + EasyMock.expect(ExtraDesignClassManager.getInstance()).andReturn(extra).once(); + PowerMock.replayAll(); + String[] fileTypes = FileNodeConstants.getSupportFileTypes(); + Assert.assertEquals("cptx", fileTypes[0]); + Assert.assertEquals("cpt", fileTypes[1]); + } + + private ExtraDesignClassManager mockExtraDesignClassManager() { + ExtraDesignClassManager extra = EasyMock.mock(ExtraDesignClassManager.class); + Set apps = new HashSet() {{ + add(new MockCptxApp()); + }}; + EasyMock.expect(extra.getArray(App.MARK_STRING)).andReturn(apps).anyTimes(); + EasyMock.replay(extra); + return extra; + } + + private class MockCptxApp extends AbstractAppProvider { @Override public String[] defaultExtensions() { - return new String[] {FileExtension.CPTX.getExtension()}; + return new String[]{FileExtension.CPTX.getExtension()}; } @Override diff --git a/designer-base/src/test/java/com/fr/file/FILEChooserPaneTest.java b/designer-base/src/test/java/com/fr/file/FILEChooserPaneTest.java new file mode 100644 index 000000000..d3d601c28 --- /dev/null +++ b/designer-base/src/test/java/com/fr/file/FILEChooserPaneTest.java @@ -0,0 +1,38 @@ +package com.fr.file; + +import com.fr.base.extension.FileExtension; +import com.fr.file.filter.ChooseFileFilter; +import com.fr.invoke.Reflect; +import com.fr.stable.StringUtils; +import org.junit.Assert; +import org.junit.Test; + +/** + * Created by kerry on 2019-10-15 + */ + +public class FILEChooserPaneTest { + @Test + public void testAddChooseFileFilter() { + FILEChooserPane chooserPane = Reflect.on(FILEChooserPane.class).field("INSTANCE").get(); + String result1 = Reflect.on(chooserPane).call("calFileNameText", "WorkBook1.cpt", null).get(); + Assert.assertEquals("WorkBook1.cptnull", result1); + + ChooseFileFilter chooseFileFilter1 = new ChooseFileFilter(FileExtension.CPT, StringUtils.EMPTY); + String result2 = Reflect.on(chooserPane).call("calFileNameText", "WorkBook1.cpt", chooseFileFilter1).get(); + Assert.assertEquals("WorkBook1.cpt", result2); + + ChooseFileFilter chooseFileFilter2 = new ChooseFileFilter(FileExtension.CPTX, StringUtils.EMPTY); + String result3 = Reflect.on(chooserPane).call("calFileNameText", "WorkBook1.cpt", chooseFileFilter2).get(); + Assert.assertEquals("WorkBook1.cpt.cptx", result3); + + ChooseFileFilter chooseFileFilter3 = new ChooseFileFilter(FileExtension.CPT, StringUtils.EMPTY); + String result4 = Reflect.on(chooserPane).call("calFileNameText", "WorkBook1.cptx", chooseFileFilter3).get(); + Assert.assertEquals("WorkBook1.cptx.cpt", result4); + + ChooseFileFilter chooseFileFilter5 = new ChooseFileFilter(FileExtension.CPTX, StringUtils.EMPTY); + String result5 = Reflect.on(chooserPane).call("calFileNameText", "WorkBook1.cptx", chooseFileFilter5).get(); + Assert.assertEquals("WorkBook1.cptx", result5); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index 6b8cbbe5d..0abafdabd 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.PaperSize; import com.fr.base.Parameter; +import com.fr.base.extension.FileExtension; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignState; import com.fr.design.actions.FormMobileAttrAction; @@ -34,6 +35,7 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.imenu.UIMenuItem; import com.fr.design.gui.xpane.FormHyperlinkGroupPane; import com.fr.design.gui.xpane.FormHyperlinkGroupPaneNoPop; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.form.FormECCompositeProvider; import com.fr.design.mainframe.form.FormECDesignerProvider; @@ -52,6 +54,8 @@ import com.fr.design.report.fit.menupane.ReportFitAttrAction; import com.fr.design.roleAuthority.RolesAlreadyEditedPane; import com.fr.design.utils.gui.LayoutUtils; import com.fr.file.FILE; +import com.fr.file.FILEChooserPane; +import com.fr.file.filter.ChooseFileFilter; import com.fr.form.FormElementCaseContainerProvider; import com.fr.form.FormElementCaseProvider; import com.fr.form.main.Form; @@ -66,6 +70,7 @@ import com.fr.report.cell.cellattr.CellImage; import com.fr.report.worksheet.FormElementCase; import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; +import com.fr.stable.ProductConstants; import com.fr.stable.bridge.StableFactory; import com.fr.web.controller.ViewRequestConstants; @@ -949,4 +954,13 @@ public class JForm extends JTemplate implements BaseJForm { public String route() { return ViewRequestConstants.REPORT_VIEW_PATH; } + + protected void addChooseFILEFilter(FILEChooserPane fileChooser){ + super.addChooseFILEFilter(fileChooser); + Set providers = ExtraDesignClassManager.getInstance().getArray(NewTemplateFileProvider.XML_TAG); + for (NewTemplateFileProvider provider : providers) { + provider.addChooseFileFilter(fileChooser, this.suffix()); + } + } }