diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index cd9c835f39..60554ef7dc 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -13,6 +13,7 @@ import com.fr.design.env.DesignerWorkspaceType; import com.fr.design.env.RemoteDesignerWorkspaceInfo; import com.fr.design.env.RemoteWorkspace; import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.file.SaveSomeTemplatePane; import com.fr.design.file.TemplateTreePane; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; @@ -82,6 +83,8 @@ public class EnvChangeEntrance { private boolean envListOkAction(EnvListPane envListPane, PopTipStrategy strategy) { final String selectedName = envListPane.updateEnvManager(); + SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(true, SwingUtilities.getWindowAncestor(envListPane)); + saveSomeTemplatePane.showSavePane(); return switch2Env(selectedName, strategy); } diff --git a/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java b/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java index 1ca29a0425..5925e250f4 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/ExitDesignerAction.java @@ -3,6 +3,7 @@ */ package com.fr.design.actions.file; +import com.fr.design.file.SaveSomeTemplatePane; import com.fr.design.mainframe.TemplateSavingChecker; import java.awt.event.ActionEvent; @@ -28,9 +29,14 @@ public class ExitDesignerAction extends UpdateAction { * @param e 事件 */ public void actionPerformed(ActionEvent e) { + // 检查是否有正在保存的模板 if (!TemplateSavingChecker.check()) { return; } - DesignerContext.getDesignerFrame().exit(); + // 提示用户保存模板 + SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(true); + if (saveSomeTemplatePane.showSavePane()) { + DesignerContext.getDesignerFrame().exit(); + } } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java index 9c12c491cb..100bd59657 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java @@ -9,6 +9,7 @@ import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.dialog.DialogActionListener; import com.fr.design.editor.editor.IntegerEditor; +import com.fr.design.file.SaveSomeTemplatePane; import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIColorButton; @@ -889,6 +890,9 @@ public class PreferencePane extends BasicPane { if (!languageChanged) { return; } + // 重启弹窗出现之前提示用户保存模板 + SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(true, SwingUtilities.getWindowAncestor(this)); + saveSomeTempaltePane.showSavePane(); int rv = JOptionPane.showOptionDialog( null, i18nText("Fine-Design_Basic_Language_Change_Successful"), diff --git a/designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java b/designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java index c59a92b975..b47d5ef1ec 100644 --- a/designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java +++ b/designer-base/src/main/java/com/fr/design/actions/file/SwitchExistEnv.java @@ -5,6 +5,7 @@ import com.fr.design.EnvChangeEntrance; import com.fr.design.actions.UpdateAction; import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.file.SaveSomeTemplatePane; import com.fr.design.mainframe.JTemplate; import com.fr.design.menu.KeySetUtils; import com.fr.design.menu.MenuDef; @@ -66,6 +67,8 @@ public class SwitchExistEnv extends MenuDef { // 打开配置目录面板 EnvChangeEntrance.getInstance().chooseEnv(envName); } else { + SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(true); + saveSomeTemplatePane.showSavePane(); EnvChangeEntrance.getInstance().switch2Env(envName); } } 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 index d6b12efa62..cb38ea8bd9 100644 --- a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java +++ b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java @@ -353,7 +353,7 @@ public class HistoryTemplateListCache implements CallbackEvent { int size = historyList.size(); for (int i = 0; i < size; i++) { JTemplate template = historyList.get(i); - FILE file = template.templateToStashFile(); + FILE file = template.templateToStashFile4Envchange(); if (file != null) { stashFILEMap.put(i, file); } @@ -382,7 +382,8 @@ public class HistoryTemplateListCache implements CallbackEvent { } FineLoggerFactory.getLogger().info("{} is being reloaded", stashedFile.getName()); JTemplate template = historyList.get(i); - template.refreshResource(stashedFile); + // 切换环境后,刷新资源并且将暂存的FILE替换到template中 + template.refreshResourceAndEditingFILE(stashedFile); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } diff --git a/designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java b/designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java index 7fef2e379b..af2d1d2a12 100644 --- a/designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java +++ b/designer-base/src/main/java/com/fr/design/file/SaveSomeTemplatePane.java @@ -17,7 +17,6 @@ import com.fr.design.mainframe.JTemplate; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; -import com.fr.stable.ProductConstants; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -43,9 +42,18 @@ public class SaveSomeTemplatePane extends BasicPane { private boolean isJudgeCurrentEditingTemplate = true; public SaveSomeTemplatePane(boolean isNeedTojudgeCurrent) { + this(isNeedTojudgeCurrent, DesignerContext.getDesignerFrame()); + } + + /** + * 支持自定义设置 dialog的父窗口 + * @param isNeedTojudgeCurrent + * @param parent + */ + public SaveSomeTemplatePane(boolean isNeedTojudgeCurrent, Window parent) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); if (this.dialog == null) { - this.dialog = this.showSmallWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { + this.dialog = this.showSmallWindow(parent, new DialogActionAdapter() { @Override public void doOk() { for (int i = 0; i < templateCheckBoxes.length; i++) { diff --git a/designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java b/designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java index a0fd544d53..003215ca6c 100644 --- a/designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java +++ b/designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java @@ -99,7 +99,11 @@ public class LockInfoDialog extends JDialog { return; } final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, TemplateTreePane.getInstance().getFilePath()); - TemplateUtils.createAndOpenTemplate(Toolkit.i18nText("Fine_Design_Template_Lock_Copy"), new FileNodeFILE(new FileNode(selectedFilePath, false)), true); + TemplateUtils.createAndOpenTemplate( + Toolkit.i18nText("Fine_Design_Template_Lock_Copy"), + new FileNodeFILE(new FileNode(selectedFilePath, false)), + false, + true); } }); cancelButton.addActionListener(new ActionListener() { 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 aacbd2fbfd..b8e5468dbc 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 @@ -442,20 +442,40 @@ public abstract class JTemplate> stopListenThemeConfig(); } + /** + * 用于 切换工作目录 时的模板资源暂存 + * @return + */ + public FILE templateToStashFile4Envchange() { + FILE file = this.getEditingFILE(); + if (file.isEnvFile() && !isSaved()) { + // 切换工作目录时,存在未保存的环境文件时,将其转化为与环境无关的内存文件,再创建暂存文件 + return new StashedFILE(new MemFILE(file.getName()), exportBaseBook2ByteArray(), template.suffix()); + } else { + // 其它情况下,直接创建暂存文件 + return templateToStashFile(); + } + } + public FILE templateToStashFile() { FILE file = this.getEditingFILE(); + return new StashedFILE(file, exportBaseBook2ByteArray(), template.suffix()); + } + + private byte[] exportBaseBook2ByteArray() { try { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); BaseBook target = this.getTarget(); if (target != null) { target.export(outputStream); - return new StashedFILE(file, outputStream.toByteArray(), template.suffix()); + return outputStream.toByteArray(); } // 如果 target == null 那么这个模板是被模板内存优化功能处理过的,不用处理 } catch (Exception e) { + FineLoggerFactory.getLogger().error("Export BaseBook to Byte Array Failed"); FineLoggerFactory.getLogger().error(e.getMessage(), e); } - return null; + return new byte[0]; } @@ -492,6 +512,17 @@ public abstract class JTemplate> } + /** + * 刷新 模板资源 和 EditingFILE + * 仅在切换工作目录,reload模板时使用 + * @param file + */ + public void refreshResourceAndEditingFILE(FILE file) { + // 这里替换EditingFILE是为了在切换工作目录后,将模板文件对象设置成环境无关文件对象 + this.editingFILE = file instanceof StashedFILE ? ((StashedFILE) file).getInsideFILE() : file; + refreshResource(file); + } + private void setTargetByFile(FILE file) { T newTemplate = JTemplateFactory.asIOFile(file, this.suffix()); if (newTemplate != null) { @@ -1921,4 +1952,4 @@ public abstract class JTemplate> DesignerUIModeConfig.getInstance().setAbsoluteMeasureUIMode(); } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java b/designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java index a84c260c36..c4cb64db09 100644 --- a/designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java @@ -27,7 +27,16 @@ import java.io.OutputStream; */ public class TemplateUtils { - public static void createAndOpenTemplate(String prefix, FILE file, boolean needOpen) { + /** + * 创建新的模板文件并打开模板 + * @param prefix 模板文件名称前缀 + * @param file 模板文件 + * @param createByEditingTemplate 是否根据 当前编辑模板 来创建新模板 + * 为true时以CurrentEditingTemplate为准创建新模板 + * 为false时以传入的File文件为准创建新模板,此文件可以不是编辑状态 + * @param openNewTemplate 是否需要在创建后打开模板 + */ + public static void createAndOpenTemplate(String prefix, FILE file, boolean createByEditingTemplate, boolean openNewTemplate) { String fileName = file.getName(); String oldPath = file.getPath(); int indexOfLastDot = fileName.lastIndexOf(CoreConstants.DOT); @@ -49,19 +58,18 @@ public class TemplateUtils { if (isOk(result)) { file = fileChooserPane.getSelectedFILE(); - _createAndOpenTemplate(file, oldPath, needOpen); + _createAndOpenTemplate(file, oldPath, createByEditingTemplate, openNewTemplate); } - } - private static void _createAndOpenTemplate(FILE file, String oldPath, boolean needOpen){ + private static void _createAndOpenTemplate(FILE file, String oldPath, boolean createByEditingTemplate, boolean openNewTemplate){ new SwingWorker() { @Override protected Void doInBackground() throws Exception { byte[] content = new byte[0]; - if (!needOpen) { + if (createByEditingTemplate) { // 从当前编辑模板中生成备份文件 JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); content = template.exportData(); @@ -95,7 +103,7 @@ public class TemplateUtils { protected void done() { try { get(); - if (needOpen) { + if (openNewTemplate) { DesignerContext.getDesignerFrame().openTemplate(file); } // 备份成功刷新下目录树 展示出来备份的模板 diff --git a/designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java b/designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java index 5d7beb36ae..080b9ddbcd 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java @@ -22,6 +22,7 @@ import javax.swing.JOptionPane; * @version 11.0 * Created by hades on 2021/12/7 */ +@SuppressWarnings("all") public class SaveFailureHandler implements ThrowableHandler { private static final SaveFailureHandler INSTANCE = new SaveFailureHandler(); @@ -70,7 +71,7 @@ public class SaveFailureHandler implements ThrowableHandler { @Override public boolean process(Throwable e) { if (e.getCause() instanceof UnLockedException || e instanceof UnLockedException) { - processByBack(Toolkit.i18nText("Fine_Design_Template_Has_Been_UnLocked")); + processUnLocked(Toolkit.i18nText("Fine_Design_Template_Has_Been_UnLocked")); return true; } return false; @@ -81,7 +82,7 @@ public class SaveFailureHandler implements ThrowableHandler { @Override public boolean process(Throwable e) { if (e.getCause() instanceof InconsistentLockException || e instanceof InconsistentLockException) { - processByBack(Toolkit.i18nText("Fine_Design_Template_Save_Failed_By_Lock_Inconsistency")); + processInconsistentLock(Toolkit.i18nText("Fine_Design_Template_Save_Failed_By_Lock_Inconsistency")); return true; } return false; @@ -102,7 +103,7 @@ public class SaveFailureHandler implements ThrowableHandler { }; - protected void processByBack(String tip) { + protected void processUnLocked(String tip) { int option = FineJOptionPane.showOptionDialog(DesignerContext.getDesignerFrame(), tip, Toolkit.i18nText("Fine-Design_Basic_Alert"), @@ -113,10 +114,36 @@ public class SaveFailureHandler implements ThrowableHandler { if (option == JOptionPane.YES_OPTION) { JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); if (template != null) { - TemplateUtils.createAndOpenTemplate(Toolkit.i18nText("Fine_Design_Template_Backup"), new FileNodeFILE(new FileNode(template.getPath(), false)), false); + TemplateUtils.createAndOpenTemplate( + Toolkit.i18nText("Fine_Design_Template_Backup"), + new FileNodeFILE(new FileNode(template.getPath(), false)), + true, + false); + } + } + } + + protected void processInconsistentLock(String tip) { + int option = FineJOptionPane.showOptionDialog(DesignerContext.getDesignerFrame(), + tip, + Toolkit.i18nText("Fine-Design_Basic_Alert"), + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE, + IOUtils.readIcon("/com/fr/design/images/warnings/warning32.png"), + new Object[] {Toolkit.i18nText("Fine_Design_Template_SaveAs_Backup"), Toolkit.i18nText("Fine-Design_Basic_Button_Cancel")}, null); + if (option == JOptionPane.YES_OPTION) { + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template != null) { + TemplateUtils.createAndOpenTemplate( + Toolkit.i18nText("Fine_Design_Template_Backup"), + new FileNodeFILE(new FileNode(template.getPath(), false)), + true, + true); + // 创建并打开备份模板后,关闭原模板 + HistoryTemplateListCache.getInstance().closeSelectedReport(template); } } } } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/file/StashedFILE.java b/designer-base/src/main/java/com/fr/file/StashedFILE.java index 48f00f95b2..a73dd612d0 100644 --- a/designer-base/src/main/java/com/fr/file/StashedFILE.java +++ b/designer-base/src/main/java/com/fr/file/StashedFILE.java @@ -87,6 +87,14 @@ public class StashedFILE extends AbstractFILE { return false; } + /** + * 获取内部FILE对象 + * @return + */ + public FILE getInsideFILE() { + return file; + } + @Override public String toString() { return FILEFactory.MEM_PREFIX + getName();