Browse Source

REPORT-62438 远程模板锁定优化

feature/x
hades 3 years ago
parent
commit
d8650de421
  1. 12
      designer-base/src/main/java/com/fr/common/exception/ThrowableHandler.java
  2. 4
      designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java
  3. 17
      designer-base/src/main/java/com/fr/design/file/TemplateTreePane.java
  4. 7
      designer-base/src/main/java/com/fr/design/gui/itextfield/UIAutoCompletionField.java
  5. 111
      designer-base/src/main/java/com/fr/design/lock/LockInfoDialog.java
  6. 11
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  7. 61
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  8. 12
      designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java
  9. 181
      designer-base/src/main/java/com/fr/design/mainframe/ForbiddenPane.java
  10. 31
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  11. 117
      designer-base/src/main/java/com/fr/design/utils/TemplateUtils.java
  12. 10
      designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java
  13. 112
      designer-base/src/main/java/com/fr/design/worker/save/SaveFailureHandler.java
  14. 11
      designer-base/src/main/java/com/fr/design/worker/save/SaveWorker.java
  15. 10
      designer-base/src/main/java/com/fr/file/FILEChooserPane.java
  16. BIN
      designer-base/src/main/resources/com/fr/design/images/mainframe/lock_template.png
  17. BIN
      designer-base/src/main/resources/com/fr/design/images/mainframe/refreh_icon.png
  18. BIN
      designer-base/src/main/resources/com/fr/design/images/toolbarbtn/lock.png
  19. BIN
      designer-base/src/main/resources/com/fr/design/images/toolbarbtn/unlock.png
  20. 11
      designer-form/src/main/java/com/fr/design/mainframe/JForm.java
  21. 1
      designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java
  22. 3
      designer-realize/src/main/java/com/fr/design/mainframe/app/CptApp.java
  23. 3
      designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java
  24. 3
      designer-realize/src/main/java/com/fr/nx/app/designer/CptxApp.java
  25. 2
      designer-realize/src/main/java/com/fr/start/MainDesigner.java

12
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);
}

4
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 += " *";
}

17
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)));
}

7
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();

111
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);
}
}

11
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();
}

61
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);
}
}
/**
* 重命名对话框
* 支持快捷键EnterESC

12
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<Component, Boolean> 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();

181
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<Boolean, Void>(){
@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();
}
}

31
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<T extends BaseBook, U extends BaseUndoState<?>>
protected U authorityUndoState = null;
protected T template; // 当前模板
private boolean isNewCreateTpl = false; //当前模板是否为新建模板
private volatile boolean forbidden;
/**
* 模板过程的相关信息
*
@ -964,7 +970,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
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<T extends BaseBook, U extends BaseUndoState<?>>
}
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<T extends BaseBook, U extends BaseUndoState<?>>
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<T extends BaseBook, U extends BaseUndoState<?>>
templateThemeButton.setText(name);
templateThemeButton.setToolTipText(name);
}
public void generateForBiddenTemplate() {
}
}

117
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<Void, Void>() {
@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);
}
}

10
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<T> extends SwingWorker<T, Void> {
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;
}

112
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)));
}
}
}
}
}

11
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<Boolean, Void> {
} 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();

10
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)

BIN
designer-base/src/main/resources/com/fr/design/images/mainframe/lock_template.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
designer-base/src/main/resources/com/fr/design/images/mainframe/refreh_icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
designer-base/src/main/resources/com/fr/design/images/toolbarbtn/lock.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

BIN
designer-base/src/main/resources/com/fr/design/images/toolbarbtn/unlock.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

11
designer-form/src/main/java/com/fr/design/mainframe/JForm.java

@ -71,6 +71,8 @@ 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.FileNodeFILE;
import com.fr.file.filetree.FileNode;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.form.FormElementCaseContainerProvider;
import com.fr.form.FormElementCaseProvider;
@ -1224,4 +1226,13 @@ public class JForm extends JTemplate<Form, FormUndoState> implements BaseJForm<F
super.setTemplateTheme(newTheme, compatible);
}
@Override
public void generateForBiddenTemplate() {
Form form = Form.getEmptyBodyForm();
JForm jForm = new JForm(form, new FileNodeFILE(new FileNode(this.getPath(), false)));
jForm.setForbidden(true);
DesignerContext.getDesignerFrame().addAndActivateJTemplate(jForm);
DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showForbiddenStatus();
}
}

1
designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java

@ -45,6 +45,7 @@ public class DeveloperPreview extends AbstractPreviewProvider {
public void onClick(JTemplate<?, ?> jt) {
super.onClick(jt);
MutilTempalteTabPane.getInstance().closeCurrentTpl();
jt.generateForBiddenTemplate();
}

3
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);
}

3
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;

3
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 workBook = null;
try {
workBook = CptxFileUtils.getWorkBook(file.asInputStream());
} catch (TplLockedException e) {
throw new RuntimeException(e);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}

2
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()) {

Loading…
Cancel
Save