From d8650de421d7351000953cd74475eeff8e6efaf6 Mon Sep 17 00:00:00 2001 From: hades Date: Tue, 7 Dec 2021 23:35:30 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-62438=20=E8=BF=9C=E7=A8=8B=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E9=94=81=E5=AE=9A=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/common/exception/ThrowableHandler.java | 12 ++ .../fr/design/file/MutilTempalteTabPane.java | 4 +- .../com/fr/design/file/TemplateTreePane.java | 17 +- .../gui/itextfield/UIAutoCompletionField.java | 7 +- .../com/fr/design/lock/LockInfoDialog.java | 111 +++++++++++ .../fr/design/mainframe/DesignerFrame.java | 11 +- .../DesignerFrameFileDealerPane.java | 61 +++++- .../fr/design/mainframe/DesktopCardPane.java | 12 ++ .../fr/design/mainframe/ForbiddenPane.java | 181 ++++++++++++++++++ .../com/fr/design/mainframe/JTemplate.java | 31 ++- .../com/fr/design/utils/TemplateUtils.java | 117 +++++++++++ .../com/fr/design/worker/open/OpenWorker.java | 10 + .../worker/save/SaveFailureHandler.java | 112 +++++++++++ .../com/fr/design/worker/save/SaveWorker.java | 11 +- .../java/com/fr/file/FILEChooserPane.java | 10 + .../design/images/mainframe/lock_template.png | Bin 0 -> 4804 bytes .../design/images/mainframe/refreh_icon.png | Bin 0 -> 1539 bytes .../com/fr/design/images/toolbarbtn/lock.png | Bin 0 -> 210 bytes .../fr/design/images/toolbarbtn/unlock.png | Bin 0 -> 208 bytes .../java/com/fr/design/mainframe/JForm.java | 11 ++ .../fr/design/preview/DeveloperPreview.java | 1 + .../com/fr/design/mainframe/app/CptApp.java | 3 +- .../com/fr/design/mainframe/app/FormApp.java | 3 +- .../java/com/fr/nx/app/designer/CptxApp.java | 3 + .../main/java/com/fr/start/MainDesigner.java | 2 +- 25 files changed, 702 insertions(+), 28 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/common/exception/ThrowableHandler.java create mode 100644 designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java create mode 100644 designer-base/src/main/java/com/fr/design/mainframe/ForbiddenPane.java create mode 100644 designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java create mode 100644 designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java create mode 100644 designer-base/src/main/resources/com/fr/design/images/mainframe/lock_template.png create mode 100644 designer-base/src/main/resources/com/fr/design/images/mainframe/refreh_icon.png create mode 100644 designer-base/src/main/resources/com/fr/design/images/toolbarbtn/lock.png create mode 100644 designer-base/src/main/resources/com/fr/design/images/toolbarbtn/unlock.png diff --git a/designer-base/src/main/java/com/fr/common/exception/ThrowableHandler.java b/designer-base/src/main/java/com/fr/common/exception/ThrowableHandler.java new file mode 100644 index 000000000..14d2dcc81 --- /dev/null +++ b/designer-base/src/main/java/com/fr/common/exception/ThrowableHandler.java @@ -0,0 +1,12 @@ +package com.fr.common.exception; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2021/12/7 + */ +public interface ThrowableHandler { + + boolean process(Throwable e); + +} diff --git a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java index b7a564713..1920212f4 100644 --- a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java +++ b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java @@ -4,7 +4,6 @@ package com.fr.design.file; import com.fr.base.BaseUtils; import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; -import com.fr.design.base.mode.DesignModeContext; import com.fr.design.constants.UIConstants; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.imenu.UIMenuItem; @@ -17,6 +16,7 @@ import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUIPaintUtils; import com.fr.design.worker.WorkerManager; +import com.fr.design.utils.TemplateUtils; import com.fr.design.worker.save.CallbackSaveWorker; import com.fr.file.FILE; import com.fr.general.ComparatorUtils; @@ -269,7 +269,7 @@ public class MutilTempalteTabPane extends JComponent { private String tempalteShowName(JTemplate template) { - String name = template.getTemplateName(); + String name = TemplateUtils.createLockeTemplatedName(template, template.getTemplateName()); if (!template.isSaved() && !name.endsWith(" *")) { name += " *"; } 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 363eb1ab0..5e5999fd3 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 @@ -13,6 +13,8 @@ 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.DesignerFrameFileDealerPane; +import com.fr.design.lock.LockInfoDialog; import com.fr.file.FILE; import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNode; @@ -21,12 +23,15 @@ import com.fr.form.fit.web.editpreview.FileLockStateObservable; import com.fr.general.ComparatorUtils; import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; +import com.fr.workspace.base.UserInfo; 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.report.lock.LockInfoOperator; +import java.util.UUID; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; @@ -96,6 +101,7 @@ public class TemplateTreePane extends JPanel implements FileOperations { if (reportletsTree.getPathForLocation(evt.getX(), evt.getY()) != null && evt.getClickCount() == 2) { openFile(); } + DesignerFrameFileDealerPane.getInstance().refreshRightToolBarBy(reportletsTree.getSelectedFileNode()); } @Override @@ -216,12 +222,17 @@ public class TemplateTreePane extends JPanel implements FileOperations { if (node == null) { return; } + String reportPath = reportletsTree.getSelectedTemplatePath(); + final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath); String lock = node.getLock(); - if (lock != null && !lock.equals(node.getUserID())) { + boolean showLockInfo = (lock != null && !lock.equals(node.getUserID())) + || WorkContext.getCurrent().get(LockInfoOperator.class).isTplLocked(selectedFilePath); + if (showLockInfo) { + UserInfo userInfo = WorkContext.getCurrent().get(LockInfoOperator.class).getUserInfo(selectedFilePath); + node.setLock(UUID.randomUUID().toString()); + LockInfoDialog.show(userInfo); return; } - String reportPath = reportletsTree.getSelectedTemplatePath(); - final String selectedFilePath = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, reportPath); DesignerContext.getDesignerFrame().openTemplate(new FileNodeFILE(new FileNode(selectedFilePath, false))); } diff --git a/designer-base/src/main/java/com/fr/design/gui/itextfield/UIAutoCompletionField.java b/designer-base/src/main/java/com/fr/design/gui/itextfield/UIAutoCompletionField.java index 967aeddbb..f976f3471 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itextfield/UIAutoCompletionField.java +++ b/designer-base/src/main/java/com/fr/design/gui/itextfield/UIAutoCompletionField.java @@ -256,10 +256,9 @@ public class UIAutoCompletionField extends UITextField implements DocumentListen * */ public void setText(String t) { - if (this.isOpen == true) { - if (!UIAutoCompletionField.this.isShowing()) { - return; - } + boolean unavailable = !this.isEnabled() && !this.isEditable(); + if (unavailable) { + return; } try { Document doc = getDocument(); 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 new file mode 100644 index 000000000..b1c58ebe8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java @@ -0,0 +1,111 @@ +package com.fr.design.lock; + +import com.fr.design.file.TemplateTreePane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.TemplateUtils; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.file.FileNodeFILE; +import com.fr.file.filetree.FileNode; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.base.UserInfo; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.UIManager; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2021/12/2 + */ +public class LockInfoDialog extends JDialog { + + private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm"); + + public LockInfoDialog(UserInfo userInfo) { + super(DesignerContext.getDesignerFrame()); + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + UILabel iconLabel = new UILabel(UIManager.getIcon("OptionPane.warningIcon")); + panel.add(iconLabel, BorderLayout.WEST); + panel.add(createContentPane(userInfo), BorderLayout.CENTER); + panel.add(createControlPane(), BorderLayout.SOUTH); + this.getContentPane().add(panel); + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Alert")); + this.setSize(400, 180); + this.setResizable(false); + this.setModal(true); + GUICoreUtils.centerWindow(this); + this.setVisible(true); + } + + private JPanel createContentPane(UserInfo userInfo) { + JPanel contentPanel = new JPanel(new BorderLayout()); + contentPanel.setBorder(BorderFactory.createEmptyBorder(15, 0, 0, 0)); + contentPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Template_Lock_And_SaveAs_Tip")), BorderLayout.NORTH); + JPanel detailInfoPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane(); + detailInfoPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0,0)); + if (userInfo != null && StringUtils.isNotEmpty(userInfo.getUserName())) { + detailInfoPane.add(createLabel(Toolkit.i18nText("Fine-Design_Template_Lock_Holder", userInfo.getUserName()))); + } + if (userInfo != null && StringUtils.isNotEmpty(userInfo.getIp())) { + detailInfoPane.add(createLabel(Toolkit.i18nText("Fine-Design_Template_Lock_Holder_Ip", userInfo.getIp()) )); + } + detailInfoPane.add(createLabel(Toolkit.i18nText("Fine-Design_Template_Lock_Get_Time", FORMATTER.format(LocalDateTime.now())))); + contentPanel.add(detailInfoPane, BorderLayout.CENTER); + return contentPanel; + } + + private UILabel createLabel(String text) { + UILabel label = new UILabel(text); + label.setForeground(Color.GRAY); + label.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + return label; + } + + private JPanel createControlPane() { + JPanel controlPane = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + UIButton saveAsButton = new UIButton(Toolkit.i18nText("Fine_Design_Template_Lock_Save_As")); + UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Button_Cancel")); + saveAsButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + FileNode node = TemplateTreePane.getInstance().getFileNode(); + if (node == null) { + 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))); + } + }); + cancelButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + controlPane.add(saveAsButton); + controlPane.add(cancelButton); + return controlPane; + } + + + public static void show(UserInfo userInfo) { + new LockInfoDialog(userInfo); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index 6270413f5..be841f79a 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java @@ -35,8 +35,11 @@ import com.fr.design.menu.ShortCut; import com.fr.design.os.impl.MacOsAddListenerAction; import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.design.utils.TemplateUtils; +import com.fr.design.lock.LockInfoDialog; import com.fr.event.EventDispatcher; import com.fr.exception.DecryptTemplateException; +import com.fr.exception.TplLockedException; import com.fr.exit.DesignerExiter; import com.fr.file.FILE; import com.fr.file.FILEFactory; @@ -57,6 +60,7 @@ import com.fr.workspace.WorkContext; import com.fr.workspace.Workspace; import com.fr.workspace.connect.WorkspaceConnectionInfo; +import java.util.UUID; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JFrame; @@ -678,7 +682,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta if (!editingTemplate.getEditingFILE().exists()) { path = FILEFactory.MEM_PREFIX + path; } else if (path.startsWith(ProjectConstants.REPORTLETS_NAME)) { - path = workspace.getPath() + File.separator + path; + path = workspace.getPath() + File.separator + TemplateUtils.createLockeTemplatedName(editingTemplate, path); } defaultTitleSB.append(" ").append(path); } @@ -962,6 +966,11 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta } } catch (Throwable t) { FineLoggerFactory.getLogger().error(t.getMessage(), t); + if (t.getCause() instanceof TplLockedException) { + TemplateTreePane.getInstance().getFileNode().setLock(UUID.randomUUID().toString()); + LockInfoDialog.show(null); + return; + } addAndActivateJTemplate(); } 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 a33aa91d5..7e428612f 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 @@ -43,6 +43,7 @@ import com.fr.file.FileNodeFILE; import com.fr.file.filetree.FileNode; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralContext; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; import com.fr.plugin.context.PluginContext; import com.fr.plugin.injectable.PluginModule; @@ -56,11 +57,13 @@ import com.fr.stable.project.ProjectConstants; import com.fr.third.org.apache.commons.io.FilenameUtils; import com.fr.workspace.WorkContext; +import com.fr.report.lock.LockInfoOperator; import javax.swing.BorderFactory; 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; @@ -127,6 +130,8 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt private UIToolbar toolBar; + private UIToolbar rightToolBar; + private NewFolderAction newFolderAction = new NewFolderAction(); private RefreshTreeAction refreshTreeAction = new RefreshTreeAction(); @@ -148,7 +153,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt toolBar.setBorderPainted(true); JPanel tooBarPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel parent = new JPanel(new BorderLayout()); - parent.add(toolBar, BorderLayout.CENTER); + parent.add(createUpToolBarPane(), BorderLayout.CENTER); parent.setBorder(BorderFactory.createEmptyBorder(3, 0, 4, 0)); tooBarPane.add(parent, BorderLayout.CENTER); tooBarPane.add(new UIMenuHighLight(), BorderLayout.SOUTH); @@ -186,6 +191,50 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt selectedOperation.refresh(); } + private JPanel createUpToolBarPane() { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(toolBar, BorderLayout.CENTER); + if (WorkContext.getCurrent().isRoot()) { + rightToolBar = new UIToolbar(FlowLayout.RIGHT); + rightToolBar.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIConstants.TOOLBAR_BORDER_COLOR)); + rightToolBar.setBorderPainted(true); + rightToolBar.add(new UILabel(Toolkit.i18nText("Fine_Design_Template_Lock_Status"))); + UIButton button = new UIButton(IOUtils.readIcon("/com/fr/design/images/toolbarbtn/lock.png")); + button.setRolloverIcon(IOUtils.readIcon("/com/fr/design/images/toolbarbtn/unlock.png")); + button.setBorderPainted(false); + button.setContentAreaFilled(false); + button.set4ToolbarButton(); + button.setToolTipText(Toolkit.i18nText("Fine_Design_Template_Lock_Status")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + int option = FineJOptionPane.showOptionDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine_Design_Template_UnLock_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE, + UIManager.getIcon("OptionPane.warningIcon"), + new Object[] {Toolkit.i18nText("Fine_Design_Template_UnLock_I_Known"), Toolkit.i18nText("Fine-Design_Basic_Button_Cancel")}, null); + if (option == JOptionPane.YES_OPTION) { + String path = StableUtils.pathJoin(ProjectConstants.REPORTLETS_NAME, TemplateTreePane.getInstance().getTemplateFileTree().getSelectedTemplatePath()); + boolean success = WorkContext.getCurrent().get(LockInfoOperator.class).unLockTpl(path); + if (success) { + FileNode fileNode = TemplateTreePane.getInstance().getFileNode(); + refreshRightToolBarBy(fileNode); + TemplateTreePane.getInstance().refresh(); + } else { + FineLoggerFactory.getLogger().error("Unlock {} failed", path); + } + } + } + }); + rightToolBar.add(button); + refreshRightToolBarBy(TemplateTreePane.getInstance().getFileNode()); + panel.add(rightToolBar, BorderLayout.EAST); + } + return panel; + } + public final void setCurrentEditingTemplate(JTemplate jt) { DesignModelAdapter.setCurrentModelAdapter(jt.getModel()); @@ -545,6 +594,16 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt } } + public void refreshRightToolBarBy(FileNode fileNode) { + if (rightToolBar != null) { + boolean visible = fileNode != null + && StringUtils.isNotEmpty(fileNode.getLock()) + && WorkContext.getCurrent().isRoot() + && WorkContext.getCurrent().get(LockInfoOperator.class).isUnLockable(); + rightToolBar.setVisible(visible); + } + } + /** * 重命名对话框 * 支持快捷键Enter,ESC diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java index 65a9a47d6..94ded5b2b 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java @@ -30,12 +30,14 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener private static final int TRANSPARENT_LAYER = 1; private static final int LOADING_LAYER = 2; private static final int FAILED_LAYER = 3; + private static final int FORBIDDEN_LAYER = 4; private static final long serialVersionUID = 1L; private JTemplate component; private TransparentPane transparentPane = new TransparentPane(); private OpenLoadingPane loadingPane = new OpenLoadingPane(); private OpenFailedPane failedPane = new OpenFailedPane(); + private ForbiddenPane forbiddenPane = new ForbiddenPane(); Map backUpToolbarComponentState = new HashMap<>(); @@ -52,6 +54,7 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener setLayout(new BorderLayout()); layeredPane.add(transparentPane, TRANSPARENT_LAYER); layeredPane.add(failedPane, FAILED_LAYER); + layeredPane.add(forbiddenPane, FORBIDDEN_LAYER); add(layeredPane, BorderLayout.CENTER); } @@ -93,6 +96,8 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener showOpenStatus(); } else if (jt.isOpenFailed()) { showOpenFailedCover(jt.getTemplateOpenFailedTip()); + } else if (jt.isForbidden()) { + showForbiddenStatus(); } else { hideCover(); } @@ -138,6 +143,13 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener } } + public void showForbiddenStatus() { + component.setVisible(false); + layeredPane.moveToFront(forbiddenPane); + forbidToolBar(); + EastRegionContainerPane.getInstance().updateAllPropertyPane(); + } + public void hideCover() { recoverToolBar(); transparentPane.stop(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/ForbiddenPane.java b/designer-base/src/main/java/com/fr/design/mainframe/ForbiddenPane.java new file mode 100644 index 000000000..37f074503 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/ForbiddenPane.java @@ -0,0 +1,181 @@ +package com.fr.design.mainframe; + +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.guide.base.GuideView; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.workspace.WorkContext; +import com.fr.report.lock.LockInfoOperator; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.LayoutManager; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingWorker; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2021/12/6 + */ +public class ForbiddenPane extends JPanel { + + private static final ImageIcon LOCK_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/mainframe/lock_template.png")); + private static final Color TIP_COLOR = new Color(108, 174, 235); + private static final Color BUTTON_COLOR = new Color(63, 155, 249); + private static final int Y_GAP = 10; + private static final int X_GAP = 10; + + private final UILabel lockLabel; + private final UILabel tipLabel; + private final JButton refreshButton; + + public ForbiddenPane() { + + setLayout(new LayoutManager() { + + @Override + public void removeLayoutComponent(Component comp) { + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + int width = parent.getParent().getWidth(); + int height = parent.getParent().getHeight(); + int lockLabelWidth = lockLabel.getPreferredSize().width; + int lockLabelHeight = lockLabel.getPreferredSize().height; + int lockLabelX = (width - lockLabelWidth) / 2; + int lockLabelY = (height - lockLabelHeight) / 2; + int tipLabelWidth = tipLabel.getPreferredSize().width; + int tipLabelHeight = tipLabel.getPreferredSize().height; + int tipLabelX = (width - tipLabelWidth) / 2 + X_GAP; + int tipLabelY = lockLabelY + lockLabelHeight - Y_GAP; + int refreshButtonWidth = refreshButton.getPreferredSize().width; + int refreshButtonHeight = refreshButton.getPreferredSize().height; + int refreshButtonX = (width - refreshButtonWidth) / 2 + X_GAP; + int refreshButtonY = tipLabelY + refreshButtonHeight; + lockLabel.setBounds(lockLabelX, lockLabelY, lockLabelWidth, lockLabelHeight); + tipLabel.setBounds(tipLabelX, tipLabelY, tipLabelWidth, tipLabelHeight); + refreshButton.setBounds(refreshButtonX, refreshButtonY, refreshButtonWidth, refreshButtonHeight); + } + + @Override + public void addLayoutComponent(String name, Component comp) { + } + }); + setBackground(Color.WHITE); + lockLabel = new UILabel(LOCK_ICON); + tipLabel = new UILabel(Toolkit.i18nText("Fine_Design_Template_Has_Been_Locked_Tip")); + tipLabel.setForeground(TIP_COLOR); + refreshButton = new JButton(Toolkit.i18nText("Fine-Design_Basic_Refresh")) { + @Override + public void paintComponent(Graphics g) + { + g.setColor(BUTTON_COLOR); + g.fillRect(0, 0, getSize().width, getSize().height); + super.paintComponent(g); + } + }; + refreshButton.setForeground(Color.WHITE); + refreshButton.setBorderPainted(false); + refreshButton.setContentAreaFilled(false); + refreshButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + final JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (template == null) { + return; + } + // 展示下画面 + LoadingDialog loadingDialog = new LoadingDialog(); + loadingDialog.showDialog(); + new SwingWorker(){ + + @Override + protected Boolean doInBackground() throws Exception { + return WorkContext.getCurrent().get(LockInfoOperator.class).isTplLocked(template.getEditingFILE().getPath()); + } + + @Override + protected void done() { + boolean unLocked; + loadingDialog.hideDialog(); + try { + unLocked = !get(); + if (unLocked) { + template.whenClose(); + JTemplate newTemplate = JTemplateFactory.createJTemplate(template.getEditingFILE()); + HistoryTemplateListCache.getInstance().replaceCurrentEditingTemplate(newTemplate); + DesignerContext.getDesignerFrame().addAndActivateJTemplate(newTemplate); + } + } catch (Exception e) { + loadingDialog.hideDialog(); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + } + }); + add(lockLabel); + add(tipLabel); + add(refreshButton); + } +} + +class LoadingDialog extends JDialog { + + private static final ImageIcon LOADING_ICON = new ImageIcon(IOUtils.readImage("/com/fr/design/images/mainframe/refreh_icon.png")); + + private GuideView guideView; + + public LoadingDialog() { + super(DesignerContext.getDesignerFrame()); + setLayout(new BorderLayout()); + this.getContentPane().setBackground(Color.WHITE); + this.setResizable(false); + this.setUndecorated(true); + this.setAlwaysOnTop(true); + this.setModal(false); + this.setSize(new Dimension(400, 100)); + this.add(new UILabel(LOADING_ICON, UILabel.CENTER), BorderLayout.NORTH); + this.add(new UILabel(Toolkit.i18nText(Toolkit.i18nText("Fine_Design_Template_Refresh")), UILabel.CENTER), BorderLayout.CENTER); + GUICoreUtils.centerWindow(this); + } + + public void showDialog() { + DesignerContext.getDesignerFrame().setExtendedState(JFrame.MAXIMIZED_BOTH); + guideView = new GuideView(DesignerContext.getDesignerFrame()); + GUICoreUtils.centerWindow(DesignerContext.getDesignerFrame(), guideView); + guideView.setBounds(DesignerContext.getDesignerFrame().getBounds()); + guideView.setVisible(true); + this.setVisible(true); + } + + public void hideDialog() { + this.dispose(); + guideView.dismissGuide(); + } + +} 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 9e5591a55..21f891f1f 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 @@ -58,6 +58,7 @@ import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.DesignUtils; import com.fr.design.worker.save.CallbackSaveWorker; import com.fr.design.worker.save.EmptyCallBackSaveWorker; +import com.fr.design.worker.save.SaveFailureHandler; import com.fr.design.write.submit.DBManipulationInWidgetEventPane; import com.fr.design.write.submit.DBManipulationPane; import com.fr.event.EventDispatcher; @@ -83,8 +84,11 @@ import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEventListener; import com.fr.plugin.observer.PluginEventType; import com.fr.plugin.observer.PluginListenerRegistration; +import com.fr.report.InconsistentLockException; +import com.fr.report.UnLockedException; import com.fr.report.cell.Elem; import com.fr.report.cell.cellattr.CellImage; +import com.fr.report.lock.LockInfoOperator; import com.fr.stable.ArrayUtils; import com.fr.stable.Filter; import com.fr.stable.ProductConstants; @@ -124,6 +128,8 @@ public abstract class JTemplate> protected U authorityUndoState = null; protected T template; // 当前模板 private boolean isNewCreateTpl = false; //当前模板是否为新建模板 + private volatile boolean forbidden; + /** * 模板过程的相关信息 * @@ -964,7 +970,7 @@ public abstract class JTemplate> export(); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); - JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), e.getMessage(), "Save Error", JOptionPane.ERROR_MESSAGE); + SaveFailureHandler.getInstance().process(e); return false; } this.editingFILE = editingFILE; @@ -980,6 +986,14 @@ public abstract class JTemplate> } protected boolean export() throws Exception { + // 保存前校验下未解锁 + if (WorkContext.getCurrent().get(LockInfoOperator.class).isTplUnLocked(getEditingFILE().getPath())) { + throw new UnLockedException(); + } + // 校验锁定信息是否一致 + if (WorkContext.getCurrent().get(LockInfoOperator.class).isConsistentLock(getEditingFILE().getPath())) { + throw new InconsistentLockException(); + } return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(getEditingFILE())); } @@ -1808,8 +1822,16 @@ public abstract class JTemplate> this.openFailed = openFailed; } + public boolean isForbidden() { + return forbidden; + } + + public void setForbidden(boolean forbidden) { + this.forbidden = forbidden; + } + public boolean checkEnable() { - return !isSaving() && !isOpening() && !isOpenFailed(); + return !isSaving() && !isOpening() && !isOpenFailed() && !isForbidden(); } public String getRuntimeId() { @@ -1842,4 +1864,9 @@ public abstract class JTemplate> templateThemeButton.setText(name); templateThemeButton.setToolTipText(name); } + + public void generateForBiddenTemplate() { + + } + } \ 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 new file mode 100644 index 000000000..26435074e --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java @@ -0,0 +1,117 @@ +package com.fr.design.utils; + +import com.fr.base.extension.FileExtension; +import com.fr.design.file.TemplateTreePane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.worker.save.SaveFailureHandler; +import com.fr.file.FILE; +import com.fr.file.FILEChooserPane; +import com.fr.file.filter.ChooseFileFilter; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.CoreConstants; +import com.fr.stable.ProductConstants; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.lock.TplOperator; +import java.io.OutputStream; +import javax.swing.SwingWorker; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2021/12/5 + */ +public class TemplateUtils { + + public static void createAndOpenTemplate(String prefix, FILE file) { + String fileName = file.getName(); + String oldPath = file.getPath(); + int indexOfLastDot = fileName.lastIndexOf(CoreConstants.DOT); + if (indexOfLastDot < 0) { + return; + } + String suffix = fileName.substring(indexOfLastDot + 1); + FILEChooserPane fileChooserPane = FILEChooserPane.getInstance(true, true); + fileChooserPane.setFileNameTextField(prefix + fileName, suffix); + FileExtension fileExtension = FileExtension.parse(suffix); + fileChooserPane.addChooseFILEFilter(new ChooseFileFilter(fileExtension, ProductConstants.APP_NAME + Toolkit.i18nText("Fine-Design_Report_Template_File"))); + fileChooserPane.disableFileNameTextFiled(); + int result = fileChooserPane.showSaveDialog(DesignerContext.getDesignerFrame(), suffix); + fileChooserPane.enableFileNameTextFiled(); + + if (isCancel(result)) { + return; + } + + if (isOk(result)) { + file = fileChooserPane.getSelectedFILE(); + _createAndOpenTemplate(file, oldPath); + } + + } + + + private static void _createAndOpenTemplate(FILE file, String oldPath){ + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + byte[] content = WorkContext.getWorkResource().readFully(oldPath); + if (ArrayUtils.isEmpty(content)) { + throw new Exception(oldPath + " content is empty" ); + } + OutputStream out = null; + try { + // 加锁 + WorkContext.getCurrent().get(TplOperator.class).saveAs(file.getPath()); + out = file.asOutputStream(); + out.write(content); + } finally { + try { + if (out != null) { + out.close(); + } + } finally { + // 解锁 + WorkContext.getCurrent().get(TplOperator.class).closeAndFreeFile(file.getPath()); + } + + } + return null; + } + + @Override + protected void done() { + try { + get(); + DesignerContext.getDesignerFrame().openTemplate(file); + TemplateTreePane.getInstance().refresh(); + } catch (Exception e) { + SaveFailureHandler.Handler.FullDisk.process(e); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }.execute(); + + } + + private static boolean isCancel(int result) { + return result == FILEChooserPane.CANCEL_OPTION || + result == FILEChooserPane.JOPTIONPANE_CANCEL_OPTION; + } + + private static boolean isOk(int result) { + return result == FILEChooserPane.JOPTIONPANE_OK_OPTION || + result == FILEChooserPane.OK_OPTION; + } + + public static String createLockeTemplatedName(JTemplate template, String name) { + int index = name.lastIndexOf(CoreConstants.DOT); + if (index < 0 || !template.isForbidden()) { + return name; + } + return name.substring(0, index) + Toolkit.i18nText("Fine_Design_Template_Has_Been_Locked") + name.substring(index); + } +} diff --git a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java index 40e6683eb..b070b7f07 100644 --- a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java @@ -3,18 +3,23 @@ package com.fr.design.worker.open; import com.fr.base.chart.exception.ChartNotFoundException; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.file.MutilTempalteTabPane; +import com.fr.design.file.TemplateTreePane; import com.fr.design.i18n.Toolkit; +import com.fr.design.lock.LockInfoDialog; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrameFileDealerPane; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.DesignUtils; import com.fr.design.worker.WorkerManager; import com.fr.exception.DecryptTemplateException; +import com.fr.exception.TplLockedException; import com.fr.file.FILE; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; +import java.util.UUID; import javax.swing.JOptionPane; import javax.swing.SwingWorker; import javax.swing.UIManager; @@ -81,6 +86,11 @@ public class OpenWorker extends SwingWorker { JOptionPane.ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); } + if (cause.getCause() instanceof TplLockedException) { + MutilTempalteTabPane.getInstance().closeCurrentTpl(); + TemplateTreePane.getInstance().getFileNode().setLock(UUID.randomUUID().toString()); + LockInfoDialog.show(null); + } FineLoggerFactory.getLogger().error(t.getMessage(), t); return; } 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 new file mode 100644 index 000000000..2ea95e2d2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java @@ -0,0 +1,112 @@ +package com.fr.design.worker.save; + +import com.fr.common.exception.ThrowableHandler; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.TemplateUtils; +import com.fr.file.FileNodeFILE; +import com.fr.file.filetree.FileNode; +import com.fr.report.UnLockedException; +import com.fr.workspace.exception.DiskSpaceFullException; +import com.fr.report.InconsistentLockException; +import java.awt.Frame; +import javax.swing.JOptionPane; +import javax.swing.UIManager; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2021/12/7 + */ +public class SaveFailureHandler implements ThrowableHandler { + + private static final SaveFailureHandler INSTANCE = new SaveFailureHandler(); + + public static SaveFailureHandler getInstance() { + return INSTANCE; + } + + @Override + public boolean process(Throwable e) { + for (Handler handler : Handler.values()) { + if (handler.process(e)) { + break; + } + } + return true; + } + + public enum Handler implements ThrowableHandler { + + FullDisk { + @Override + public boolean process(Throwable e) { + if (e.getCause() instanceof DiskSpaceFullException + || e instanceof DiskSpaceFullException + || e.getCause().getCause() instanceof DiskSpaceFullException) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine_Design_Template_Save_Failed_By_Full_Disk"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + JOptionPane.WARNING_MESSAGE); + return true; + } + return false; + } + }, + UnLocked { + @Override + public boolean process(Throwable e) { + if (e.getCause() instanceof UnLockedException || e instanceof UnLockedException) { + processByBack(Toolkit.i18nText("Fine_Design_Template_Has_Been_UnLocked")); + return true; + } + return false; + } + }, + + InconsistentLock { + @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")); + return true; + } + return false; + } + }, + + Other { + @Override + public boolean process(Throwable e) { + boolean minimized = (DesignerContext.getDesignerFrame().getExtendedState() & Frame.ICONIFIED ) != 0; + FineJOptionPane.showMessageDialog( + minimized ? null : DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design-Basic_Save_Failure"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.ERROR_MESSAGE); + return true; + } + }; + + + protected void processByBack(String tip) { + int option = FineJOptionPane.showOptionDialog(DesignerContext.getDesignerFrame(), + tip, + Toolkit.i18nText("Fine-Design_Basic_Alert"), + JOptionPane.YES_NO_OPTION, + JOptionPane.WARNING_MESSAGE, + UIManager.getIcon("OptionPane.warningIcon"), + 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))); + } + } + } + + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java index 51a79bbad..60d797c3e 100644 --- a/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java @@ -1,8 +1,6 @@ package com.fr.design.worker.save; -import com.fr.design.dialog.FineJOptionPane; import com.fr.design.file.HistoryTemplateListCache; -import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrameFileDealerPane; import com.fr.design.mainframe.EastRegionContainerPane; @@ -10,11 +8,9 @@ import com.fr.design.mainframe.JTemplate; import com.fr.design.worker.WorkerManager; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; -import java.awt.Frame; import java.util.concurrent.Callable; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import javax.swing.JOptionPane; import javax.swing.SwingWorker; /** @@ -55,12 +51,7 @@ public class SaveWorker extends SwingWorker { } catch (Exception e) { processResult(); FineLoggerFactory.getLogger().error(e.getMessage(), e); - boolean minimized = (DesignerContext.getDesignerFrame().getExtendedState() & Frame.ICONIFIED ) != 0; - FineJOptionPane.showMessageDialog( - minimized ? null : DesignerContext.getDesignerFrame(), - Toolkit.i18nText("Fine-Design-Basic_Save_Failure"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), - JOptionPane.ERROR_MESSAGE); + SaveFailureHandler.getInstance().process(e); return; } processResult(); 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 c21c82c75..426fd18e2 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -664,6 +664,16 @@ public class FILEChooserPane extends BasicPane { fileNameTextField.setFilter(new DefaultCompletionFilter(names)); } + public void disableFileNameTextFiled() { + fileNameTextField.setEditable(false); + fileNameTextField.setEnabled(false); + } + + public void enableFileNameTextFiled() { + fileNameTextField.setEditable(true); + fileNameTextField.setEnabled(true); + } + /** * 移除文件后缀的方法 * 解决cptx文件的另存为操作默认会出现双后缀的bug(xxx.cptx.cpt) diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/lock_template.png b/designer-base/src/main/resources/com/fr/design/images/mainframe/lock_template.png new file mode 100644 index 0000000000000000000000000000000000000000..f75bfe4799522037ed9f7fd9b280c8e137130cff GIT binary patch literal 4804 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 literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/mainframe/refreh_icon.png b/designer-base/src/main/resources/com/fr/design/images/mainframe/refreh_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..99b4e53740850182bf52788b368fc16a2524fe3d GIT binary patch literal 1539 zcmV+e2K@PnP)Px)y-7qtR9HvVnSX3kRTRg+=eF;4AgpX+G@6)b6y%2(6r%`?z6~>sB2fcIk;Kq; zOHfdZM*lE^#(#)Li2O*lw!{QAQ8fNQf+MW22#ATI2?Fvfq9htHz@SsszPH|E-s_LG zvt3`;spI~8&yP>fJ?Gr}P6?OEqM_iN5#iAa%<%+qEh9CW7)<2qN~Pr4T2>BiZKX@q z`WYN3Gc`tfXF>7;N!&!hEdWZ{N`Y~dh;}g1N4nqrHHf%U@QOeue#q+87tJRDegVKu zl{!ny(=iZM$5YDY{jFp=wc!|4Yfm(j5bK!v=90#V&M|YG02e@YAdCWYQ6EHfoQPUG z{fh1cwk+s+3aZ~SOoJzg#05Vf&wC7B%(sXzs8U1yNf;NT?t7x9i6aFAB)y3uV zDBrkm!ylta^&SCmonue{3|botsw>KZTGb69w&xX2M_j7&DuJ||G=z<*Zsz%wK-#iG zu;_KK?Vkb#5w-f{HF5J`UJE*vAa!ab$6Ya)LxloREo8I++?LaIiMf>&jzgb=66*tH zCM|3n%iTDPZF-C6fk9cVQb~&>#v?^b^cM9cAbs8DKpVqm1GC(f^}(R&PWoh(Oa4Z=wB1<8l&kcEdeC$0P(nDhrG=6|0?6EAv`!DI%L_n# zq2yr#CfEi^tkeU_Yfg<1rJNQvUjfTkEt?Gd6bpJL=0L6Yq$&;TMzB*sKs0m)mEA)L z;M7)A$ebl1?c=ss4H5V5^3(z=sB9X3ZFN}dBypFVomeBJNP9(`UhSub4q z*O>pWn9h4s;))B|^eHH&yWZv6kv)dBISkvA>fP(7bbGQZKWrQVv)x=lSg8j*!>{36 zZ2ca~!{Q1hruESlby+%gnU#B#Fn$4v&{(f~^_GQ{s{O-fcl}U7l(VC4GMkZ-U-rpSs~%L_ zbI~nl;J?_P9_IQQHhutby`7Il$4}QPlk>ku{}Iv5bmJLjS#h+9#2!7MbXM}??r3AB zRv23WG-oaxCZf4fzp^9WPEi3DE%k>QpZSxf#HteFa48qk(j# zmj$(_c5$;4%rl)jWnfh-=&>KXPFCi)t>HvElJ?@gH9elD?aL|Y2-Fg?Q$QF|0Jl4E zd@|9kPTKbz^*E4)FPxZ5OxD+~os*e$z%+Y&dzOyrDrRHAJZuhgy}{T9JY%~rK`GjkUMl89<^uk<1Y ztro;mF4J3T98CtxMl|1t9bK2X7>pMI9#`(DOYENj=#4X8<(*etR|bxCkF?n(dv002ovPDHLkV1myS+0p<2 literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/toolbarbtn/lock.png b/designer-base/src/main/resources/com/fr/design/images/toolbarbtn/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..882bbaeb32ad8ed1d8a0c56d75e17c58220aa513 GIT binary patch literal 210 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k#^NA%Cx&(BWL^R}J)SO(AsWHS zDGGuHN~`&Kc~gIXdK!JXo~_Mff`u~kVI4WSb-S*v4*%b@()r?pmoM*roZlEYed5D> zD`Vr&|LyA~(+rLN?B7%S`x@68DI1%;_ct0CzskG0>8Ykid1eSda%{O_rCt74En6)x6M6|i^8eRPWWHB&!y85}S Ib4q9e05w-q00000 literal 0 HcmV?d00001 diff --git a/designer-base/src/main/resources/com/fr/design/images/toolbarbtn/unlock.png b/designer-base/src/main/resources/com/fr/design/images/toolbarbtn/unlock.png new file mode 100644 index 0000000000000000000000000000000000000000..69def397eec396efe6ac7c61da553ebb41d7b59e GIT binary patch literal 208 zcmeAS@N?(olHy`uVBq!ia0vp^JRr=$1|-8uW1a&k#^NA%Cx&(BWL^R}U7jwEAsWHS zDGGuHN~`&Kc~gIXdK!JXo~_Mff`u~kVI4WSb-S*v4*%b@()r?pmoM*roZsj;ed5D- zD`Vr&|LyDlpHE6j*s-Vf_cg9HQZ_bw?{73PewBA~(^E~4#^uYGpQ&eC=54(#U-Zz@ zhyVNDMhE7&epl*R(!SjMqm)C}M^=e5X*+liJ2G$7WMN implements BaseJForm jt) { super.onClick(jt); MutilTempalteTabPane.getInstance().closeCurrentTpl(); + jt.generateForBiddenTemplate(); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java index d03db956c..e4b85af22 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java @@ -73,8 +73,7 @@ class CptApp extends AbstractWorkBookApp { } catch (RemoteDesignPermissionDeniedException exp) { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + file, exp); } catch (TplLockedException exp) { - FineLoggerFactory.getLogger().error(file + Toolkit.i18nText("Fine-Design_Basic_Template_Status_Locked"), exp); - TemplateLockedHandler.generateTipAndRefresh(); + throw new RuntimeException(exp); } catch (Exception exp) { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Report_NS_Exception_ReadError") + file, exp); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java index bcc7d26fb..01b3172bd 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java @@ -119,8 +119,7 @@ class FormApp extends AbstractAppProvider { } catch (RemoteDesignPermissionDeniedException exp) { FineLoggerFactory.getLogger().error(Toolkit.i18nText("Fine-Design_Basic_Template_Permission_Denied") + file, exp); } catch (TplLockedException exp) { - FineLoggerFactory.getLogger().error(file + Toolkit.i18nText("Fine-Design_Basic_Template_Status_Locked"), exp); - TemplateLockedHandler.generateTipAndRefresh(); + throw new RuntimeException(exp); } catch (Exception exp) { FineLoggerFactory.getLogger().error("Failed to generate frm from " + file, exp); return null; diff --git a/designer-realize/src/main/java/com/fr/nx/app/designer/CptxApp.java b/designer-realize/src/main/java/com/fr/nx/app/designer/CptxApp.java index 35aba93d8..2f106713f 100644 --- a/designer-realize/src/main/java/com/fr/nx/app/designer/CptxApp.java +++ b/designer-realize/src/main/java/com/fr/nx/app/designer/CptxApp.java @@ -4,6 +4,7 @@ import com.fr.base.extension.FileExtension; import com.fr.design.mainframe.AbstractAppProvider; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JWorkBook; +import com.fr.exception.TplLockedException; import com.fr.file.FILE; import com.fr.log.FineLoggerFactory; import com.fr.main.impl.WorkBook; @@ -45,6 +46,8 @@ public class CptxApp extends AbstractAppProvider { WorkBook workBook = null; try { workBook = CptxFileUtils.getWorkBook(file.asInputStream()); + } catch (TplLockedException e) { + throw new RuntimeException(e); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index ce355076b..0446a690f 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -338,7 +338,7 @@ public class MainDesigner extends BaseDesigner { if (jt == null) { return; } - saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode()); + saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode() && jt.checkEnable()); MutilTempalteTabPane.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList()); MutilTempalteTabPane.getInstance().repaint(); if (DesignerEnvManager.getEnvManager().isSupportUndo()) {