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 33761a92e2..e38a39895a 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 @@ -68,7 +68,7 @@ public class SwitchExistEnv extends MenuDef { EnvChangeEntrance.getInstance().chooseEnv(envName); } else { SaveSomeTemplatePane saveSomeTemplatePane = new SaveSomeTemplatePane(true); - if (saveSomeTemplatePane.showSavePane()) { + if (saveSomeTemplatePane.showSavePane(true)) { // 用户模板保存后,才进行切换目录操作 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 86820aa227..f895a4f5b4 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 @@ -268,7 +268,8 @@ public class HistoryTemplateListCache implements CallbackEvent { boolean replaceWithJVirtualTemplate = overTemplate.getEditingFILE().exists() && overTemplate.isALLSaved() && overTemplate != editingTemplate - && overTemplate.checkEnable(); + && overTemplate.checkEnable() + && overTemplate.supportCache(); if (replaceWithJVirtualTemplate) { closeVirtualSelectedReport(overTemplate); historyList.set(i, new JVirtualTemplate(overTemplate.getEditingFILE())); @@ -297,7 +298,9 @@ public class HistoryTemplateListCache implements CallbackEvent { int index = iterator.nextIndex(); if (size == index + 1 && index > 0) { //如果删除的是后一个Tab,则定位到前一个 - MultiTemplateTabPane.getInstance().setSelectedIndex(index - 1); + MultiTemplateTabPane.getInstance().setSelectedIndex( + MultiTemplateTabPane.getInstance().calNextShowJTemplateIndex(index - 1)); + } } } diff --git a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java new file mode 100644 index 0000000000..6b5f9e324b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabMenuFactory.java @@ -0,0 +1,350 @@ +package com.fr.design.file; + +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.imenu.UIMenuItem; +import com.fr.design.gui.imenu.UIScrollPopUpMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.TemplateUtils; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.collections.CollectionUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * 右侧下拉菜单的工厂类 + * @author Carlson + * @since 11.0 + * created on 2023-04-14 + **/ +public class MultiTemplateTabMenuFactory { + + private static final Icon CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/close_icon.png"); + private static final Icon MOUSE_OVER_CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/mouseoverclose icon.png"); + private static final Icon MOUSE_PRESS_CLOSE = IOUtils.readIcon("/com/fr/design/images/buttonicon/pressclose icon.png"); + + private static final int ITEM_SIZE = 25; + + private UIScrollPopUpMenu menu = null; + + private static MultiTemplateTabMenuFactory INSTANCE = new MultiTemplateTabMenuFactory(); + + private MultiTemplateTabMenuFactory() { + + } + + /** + * 返回右侧下拉菜单的工厂类 + * @return + */ + public static MultiTemplateTabMenuFactory getInstance() { + return INSTANCE; + } + + /** + * tab上的下拉菜单 + */ + public UIScrollPopUpMenu createMenu() { + menu = new UIScrollPopUpMenu(); + menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0)); + + menu.add(initCloseOther()); + menu.add(createEmptyRow()); + menu.addSeparator(); + menu.add(createEmptyRow()); + menu.add(createCategory(Toolkit.i18nText("Fine-Design_Basic_Tab_Current_Category_Templates"))); + Component[] items = createCurrentCategory(); + for (Component item : items) { + menu.add(item); + } + items = createOtherCategory(); + if (items.length > 0) { + menu.addSeparator(); + menu.add(createEmptyRow()); + menu.add(createCategory(Toolkit.i18nText("Fine-Design_Basic_Tab_Other_Category_Templates"))); + for (Component item : items) { + menu.add(item); + } + } + Dimension dimension = menu.getPreferredSize(); + dimension.width += ITEM_SIZE; + menu.setPreferredSize(dimension); + return menu; + } + + /** + * 关闭其它按钮 + */ + private UIMenuItem initCloseOther() { + UIMenuItem closeOther = new UIMenuItem(Toolkit.i18nText("Fine-Design_Basic_Tab_Close_Other_Templates_Of_Current_Category")); + closeOther.setHorizontalAlignment(SwingConstants.CENTER); + Dimension dimension = closeOther.getPreferredSize(); + dimension.height = ITEM_SIZE; + closeOther.setPreferredSize(dimension); + String currentOperator = getCurrentTabOperatorType(); + closeOther.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + + MultiTemplateTabPane.getInstance().closeAllByOperatorType(currentOperator); + } + }); + if (MultiTemplateTabPane.getInstance().getOpenedJTemplatesByOperator(currentOperator).size() <= 1) { + closeOther.setEnabled(false); + } + return closeOther; + } + + + /** + * 美观用 + */ + private JPanel createEmptyRow() { + return new JPanel() { + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.height = 1; + return d; + } + }; + } + + /** + * 模板分类item + */ + private UIButton createCategory(String categoryName) { + UIButton button = new UIButton(categoryName); + button.setBorderPainted(false); + button.setExtraPainted(false); + button.setPreferredSize(new Dimension(menu.getWidth(), ITEM_SIZE)); + button.setOpaque(true); + button.setBackground(UIConstants.NORMAL_BACKGROUND); + button.setHorizontalAlignment(SwingConstants.LEFT); + button.setForeground(UIConstants.FLESH_BLUE); + return button; + } + + /** + * 创建 当前分类模板 item数组 + */ + private Component[] createCurrentCategory() { + return createListDownItem(MultiTemplateTabPane.getInstance().getOpenedJTemplatesByOperator(getCurrentTabOperatorType())); + } + + private String getCurrentTabOperatorType(){ + JTemplate jTemplate= HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + return jTemplate.getTemplateTabOperatorType(); + } + + /** + * 创建 其它分类模板 item数组 + */ + private Component[] createOtherCategory() { + String currentOperator = getCurrentTabOperatorType(); + List> openedTemplates = new ArrayList<>(); + Map>> map = MultiTemplateTabPane.getInstance().getOpenedJTemplatesByCategory(); + for (Map.Entry>> entry : map.entrySet()) { + if (!StringUtils.equals(currentOperator, entry.getKey())) { + openedTemplates.addAll(entry.getValue()); + } + } + return createListDownItem(openedTemplates); + } + + /** + * 根据template列表创建多个item + */ + private Component[] createListDownItem(List> openedTemplates) { + if (!CollectionUtils.isEmpty(openedTemplates)) { + Component[] templates = new Component[openedTemplates.size()]; + for (int i = 0; i < openedTemplates.size(); i++) { + templates[i] = createListDownMenuItem(openedTemplates.get(i)); + } + return templates; + } + return new Component[0]; + } + + /** + * 根据template对象创建item + */ + private Component createListDownMenuItem(JTemplate template) { + JPanel jPanel = new JPanel(); + jPanel.setPreferredSize(new Dimension(menu.getWidth(), ITEM_SIZE)); + jPanel.setLayout(new BorderLayout()); + + MenuItemButtonGroup menuItemButtonGroup = new MenuItemButtonGroup(template); + if (template == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()) { + menuItemButtonGroup.templateButton.setForeground(UIConstants.FLESH_BLUE); + } + + jPanel.add(menuItemButtonGroup.iconButton, BorderLayout.WEST); + jPanel.add(menuItemButtonGroup.templateButton, BorderLayout.CENTER); + jPanel.add(menuItemButtonGroup.closeButton, BorderLayout.EAST); + + return jPanel; + } + + /** + * menu的item由模板图标、模板名、模板关闭按钮组成 + */ + private class MenuItemButtonGroup { + + private final UIButton iconButton; + private final UIButton templateButton; + private final UIButton closeButton; + + public MenuItemButtonGroup(JTemplate template) { + iconButton = createIconButton(template); + templateButton = createTemplateButton(template); + closeButton = createCloseButton(); + initListener(template); + } + + /** + * item[0] 模板图标按钮初始化 + */ + private UIButton createIconButton(JTemplate template) { + UIButton button = new UIButton(template.getIcon(), template.getIcon(), template.getIcon()); + button.setPreferredSize(new Dimension(ITEM_SIZE, ITEM_SIZE)); + button.setOpaque(true); + button.setBackground(UIConstants.NORMAL_BACKGROUND); + return button; + } + + /** + * item[1] 切换模板按钮初始化 + */ + private UIButton createTemplateButton(JTemplate template) { + UIButton button = new UIButton(TemplateUtils.createLockeTemplatedName(template, template.getTemplateName())); + button.setBorderPainted(false); + button.setExtraPainted(false); + button.setPreferredSize(new Dimension(menu.getWidth() - ITEM_SIZE * 2, ITEM_SIZE)); + button.setOpaque(true); + button.setBackground(UIConstants.NORMAL_BACKGROUND); + button.setHorizontalAlignment(SwingConstants.LEFT); + return button; + } + + /** + * item[2] 关闭模板图标按钮初始化 + */ + private UIButton createCloseButton() { + UIButton button = new UIButton(CLOSE, MOUSE_OVER_CLOSE, MOUSE_PRESS_CLOSE); + button.setPreferredSize(new Dimension(ITEM_SIZE, ITEM_SIZE)); + button.setOpaque(true); + button.setBackground(UIConstants.NORMAL_BACKGROUND); + button.setVisible(false); + return button; + } + + private void initListener(JTemplate template) { + initIconButtonListener(); + initTemplateButtonListener(template); + initCloseButtonListener(template); + } + + /** + * item[0] 模板图标按钮鼠标事件 + */ + private void initIconButtonListener() { + iconButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + fireMouseEnteredEvent(); + } + + @Override + public void mouseExited(MouseEvent e) { + fireMouseExitedEvent(); + } + }); + } + + /** + * item[1] 切换模板按钮鼠标事件 + */ + private void initTemplateButtonListener(JTemplate template) { + templateButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + menu.setVisible(false); + MultiTemplateTabPane.getInstance().switchJTemplate(template); + } + + @Override + public void mouseEntered(MouseEvent e) { + fireMouseEnteredEvent(); + } + + @Override + public void mouseExited(MouseEvent e) { + fireMouseExitedEvent(); + } + }); + } + + /** + * item[2] 关闭模板按钮鼠标事件 + */ + private void initCloseButtonListener(JTemplate template) { + closeButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + menu.setVisible(false); + MultiTemplateTabPane.getInstance().setIsCloseCurrent(template == HistoryTemplateListCache.getInstance().getCurrentEditingTemplate()); + MultiTemplateTabPane.getInstance().closeFormat(template); + MultiTemplateTabPane.getInstance().closeSpecifiedTemplate(template); + } + + @Override + public void mouseEntered(MouseEvent e) { + fireMouseEnteredEvent(); + } + + @Override + public void mouseExited(MouseEvent e) { + fireMouseExitedEvent(); + } + }); + } + + /** + * mouse移入item范围 + */ + private void fireMouseEnteredEvent() { + iconButton.setBackground(UIConstants.HOVER_BLUE); + templateButton.setBackground(UIConstants.HOVER_BLUE); + closeButton.setBackground(UIConstants.HOVER_BLUE); + closeButton.setVisible(true); + } + + /** + * mouse移出item范围 + */ + private void fireMouseExitedEvent() { + iconButton.setBackground(UIConstants.NORMAL_BACKGROUND); + templateButton.setBackground(UIConstants.NORMAL_BACKGROUND); + closeButton.setBackground(UIConstants.NORMAL_BACKGROUND); + closeButton.setVisible(false); + } + + } + +} diff --git a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java index 8e302fd977..4f292ecfe7 100644 --- a/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java +++ b/designer-base/src/main/java/com/fr/design/file/MultiTemplateTabPane.java @@ -1,7 +1,6 @@ package com.fr.design.file; -import com.fr.base.BaseUtils; import com.fr.base.GraphHelper; import com.fr.base.svg.IconUtils; import com.fr.base.vcs.DesignerMode; @@ -19,7 +18,6 @@ import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.TemplateSavingChecker; import com.fr.design.mainframe.manager.search.TemplateTreeSearchManager; import com.fr.design.utils.DesignUtils; -import com.fr.design.utils.TemplateUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUIPaintUtils; import com.fr.design.worker.WorkerManager; @@ -42,7 +40,6 @@ import javax.swing.JComponent; import javax.swing.JMenu; import javax.swing.JMenuItem; import javax.swing.JOptionPane; -import javax.swing.JPanel; import javax.swing.JSeparator; import javax.swing.MenuElement; import javax.swing.SwingConstants; @@ -70,6 +67,8 @@ import java.awt.geom.Line2D; import java.awt.geom.Path2D; import java.awt.geom.RoundRectangle2D; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import static com.fr.design.dialog.FineJOptionPane.showConfirmDialog; import static javax.swing.JOptionPane.OK_CANCEL_OPTION; @@ -333,8 +332,10 @@ public class MultiTemplateTabPane extends JComponent { JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); closeTemplate(templates, currentTemplate); - if (option == CloseOption.All) { + if (openedTemplate.size() == 0) { DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + } else if (option == CloseOption.All){ + DesignerContext.getDesignerFrame().activateJTemplate(openedTemplate.get(0)); } else { DesignerContext.getDesignerFrame().activateJTemplate(currentTemplate); } @@ -344,8 +345,9 @@ public class MultiTemplateTabPane extends JComponent { } private void closeTemplate(JTemplate[] templates, JTemplate currentTemplate) { + String operator = currentTemplate.getTemplateTabOperatorType(); for (int i = 0; i < templates.length; i++) { - if (option.shouldClose(tplIndex, i)) { + if (option.shouldClose(tplIndex, i) && ComparatorUtils.equals(operator, templates[i].getTemplateTabOperatorType())) { JTemplate jTemplate = templates[i]; if (jTemplate == currentTemplate) { currentTemplate = option == CloseOption.All ? null : templates[tplIndex]; @@ -378,6 +380,47 @@ public class MultiTemplateTabPane extends JComponent { return openedTemplate.get(selectedIndex); } + /** + * 关闭所有指定模板tab操作类型的模板 + * @param operatorType + */ + public void closeAllByOperatorType(String operatorType){ + SaveSomeTemplatePane saveSomeTempaltePane = new SaveSomeTemplatePane(false); + if (saveSomeTempaltePane.showSavePane()) { + List> openedTemplate = HistoryTemplateListCache.getInstance().getHistoryList(); + + JTemplate[] templates = new JTemplate[openedTemplate.size()]; + for (int i = 0; i < openedTemplate.size(); i++) { + templates[i] = openedTemplate.get(i); + } + closeTemplate(templates, operatorType); + + if (openedTemplate.size() == 0) { + DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + } else { + DesignerContext.getDesignerFrame().activateJTemplate(openedTemplate.get(0)); + } + MultiTemplateTabPane.getInstance().repaint(); + } + } + + /** + * 关闭指定模板 + * @param templates + * @param operatorType + */ + private static void closeTemplate(JTemplate[] templates, String operatorType) { + for (int i = 0; i < templates.length; i++) { + JTemplate jTemplate = templates[i]; + if (!ComparatorUtils.equals(operatorType, jTemplate.getTemplateTabOperatorType())){ + continue; + } + MultiTemplateTabPane.getInstance().closeFormat(jTemplate); + HistoryTemplateListCache.getInstance().closeSelectedReport(jTemplate); + MultiTemplateTabPane.getInstance().closeAndFreeLock(jTemplate); + } + } + /** * 关闭掉当前已打开文件列表中指定的文件 @@ -478,11 +521,7 @@ public class MultiTemplateTabPane extends JComponent { private String tempalteShowName(JTemplate template) { - String name = TemplateUtils.createLockeTemplatedName(template, template.getTemplateName()); - if (!template.isSaved() && !name.endsWith(" *")) { - name += " *"; - } - return name; + return template.getTabShowName(template); } /** @@ -500,40 +539,7 @@ public class MultiTemplateTabPane extends JComponent { private void showListDown() { - - UIScrollPopUpMenu menu = new UIScrollPopUpMenu(); - menu.setBorder(BorderFactory.createEmptyBorder(-3, 3, 3, 0)); - menu.add(initCloseOther()); - JSeparator separator = new JSeparator() { - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.height = 1; - return d; - } - }; - menu.add(new JPanel() { - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.height = 1; - return d; - } - }); - separator.setForeground(UIConstants.LINE_COLOR); - menu.add(separator); - menu.add(new JPanel() { - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.height = 1; - return d; - } - }); - UIMenuItem[] items = createListDownTemplate(); - for (int i = 0; i < items.length; i++) { - menu.add(items[i]); - } + UIScrollPopUpMenu menu = MultiTemplateTabMenuFactory.getInstance().createMenu(); GUICoreUtils.showPopupMenu(menu, MultiTemplateTabPane.getInstance(), MultiTemplateTabPane.getInstance().getWidth() - menu.getPreferredSize().width, getY() - 1 + getHeight()); } @@ -583,6 +589,9 @@ public class MultiTemplateTabPane extends JComponent { //从可以开始展示在tab面板上的tab开始画 for (int i = minPaintIndex; i <= maxPaintIndex; i++) { JTemplate template = openedTemplate.get(i); + if (!showJTemplateTab(template)){ + continue; + } Icon icon = template.getIcon(); String name = tempalteShowName(template); //如果tab名字的长度大于最大能显示的英文字符长度,则进行省略号处理 @@ -722,8 +731,10 @@ public class MultiTemplateTabPane extends JComponent { //个数小于最多能容纳的个数的情况下,看看宽度每个要画多少 private void calculateRealAverageWidth(double maxwidth, int templateNum) { + JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + List> showTemplates = getOpenedJTemplatesByOperator(jTemplate.getTemplateTabOperatorType()); - int num = openedTemplate.size() > templateNum ? templateNum : openedTemplate.size(); + int num = Math.min(showTemplates.size(), templateNum); realWidth = (int) (maxwidth / (num)); if (realWidth > MAXWIDTH) { realWidth = MAXWIDTH; @@ -932,7 +943,7 @@ public class MultiTemplateTabPane extends JComponent { activePrevTemplateAfterClose(); } - private void closeAndFreeLock(@Nonnull JTemplate template) { + public void closeAndFreeLock(@Nonnull JTemplate template) { FILE file = template.getEditingFILE(); // 只有是环境内的文件,才执行释放锁 if (file != null && file.isEnvFile()) { @@ -988,7 +999,7 @@ public class MultiTemplateTabPane extends JComponent { // 如果当前关闭的模板在最右侧,那么预览上一个,防止数组越界 if (selectedIndex >= maxPaintIndex) { // selectIndex 不会 <0 因为如果关闭的是打开的最后一个模板,那么关闭之后 openedTemplate.isEmpty() = true - selectedIndex--; + selectedIndex = calNextShowJTemplateIndex(selectedIndex - 1); } isCloseCurrent = false; } @@ -1005,6 +1016,26 @@ public class MultiTemplateTabPane extends JComponent { } } + /** + * 计算下一个可以展示的模板index + * @param currentIndex + * @return + */ + public int calNextShowJTemplateIndex(int currentIndex) { + //先看是否有可以展示的模板 + for (int i = currentIndex; i >= 0; i--) { + if (showJTemplateTab(openedTemplate.get(i))) { + return i; + } + } + for (int i = currentIndex; i >= 0; i--) { + if (!showJTemplateTab(openedTemplate.get(i))) { + return i; + } + } + return -1; + } + private boolean isOverCloseIcon(int evtX) { boolean isOverCloseIcon = false; @@ -1027,7 +1058,7 @@ public class MultiTemplateTabPane extends JComponent { private int getTemplateIndex(int evtX) { int textX = 0; for (int i = minPaintIndex; i <= maxPaintIndex; i++) { - int textWidth = realWidth; + int textWidth = showJTemplateTab(openedTemplate.get(i)) ? realWidth : 0; if (evtX >= textX && evtX < textX + textWidth) { return i; } @@ -1184,29 +1215,44 @@ public class MultiTemplateTabPane extends JComponent { //没有点击关闭和ListDown按钮,则切换到点击的模板处 closeIconIndex = -1; clodeMode = CLOSE; - int tempSelectedIndex = selectedIndex; - if (selectedIndex != getTemplateIndex(evtX) && getTemplateIndex(evtX) != -1) { - openedTemplate.get(selectedIndex).stopEditing(); - selectedIndex = getTemplateIndex(evtX); - //如果在权限编辑情况下,不允许切换到表单类型的工作簿 - if (DesignerMode.isAuthorityEditing() && !openedTemplate.get(selectedIndex).isJWorkBook()) { - DesignerContext.getDesignerFrame().addAndActivateJTemplate(openedTemplate.get(tempSelectedIndex)); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported") - + "!", Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); - MultiTemplateTabPane.this.repaint(); - return; - } - JTemplate evtXTemplate = openedTemplate.get(getTemplateIndex(evtX)); - evtXTemplate.activeNewJTemplate(); - } + switchJTemplate(getTemplateIndex(evtX)); isShowList = false; } MultiTemplateTabPane.this.repaint(); - - } + } + /** + * 切换到指定模板 + * @param jTemplate + */ + public void switchJTemplate(JTemplate jTemplate) { + int switchIndex = this.openedTemplate.indexOf(jTemplate); + if (switchIndex >= 0) { + switchJTemplate(switchIndex); + } + } + /** + * 切换到指定index + * @param switchIndex + */ + private void switchJTemplate(int switchIndex){ + int tempSelectedIndex = selectedIndex; + if (selectedIndex != switchIndex && switchIndex != -1) { + openedTemplate.get(selectedIndex).stopEditing(); + selectedIndex = switchIndex; + //如果在权限编辑情况下,不允许切换到表单类型的工作簿 + if (DesignerMode.isAuthorityEditing() && !openedTemplate.get(selectedIndex).isJWorkBook()) { + DesignerContext.getDesignerFrame().addAndActivateJTemplate(openedTemplate.get(tempSelectedIndex)); + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Form_Authority_Edited_Cannot_Be_Supported") + + "!", Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); + MultiTemplateTabPane.this.repaint(); + return; + } + JTemplate evtXTemplate = openedTemplate.get(switchIndex); + evtXTemplate.activeNewJTemplate(); + } } private boolean checkCurrentClose(JTemplate template) { @@ -1251,5 +1297,34 @@ public class MultiTemplateTabPane extends JComponent { } } + /** + * 判断是否显示在tab栏上 + * @param jTemplate + * @return + */ + private boolean showJTemplateTab(JTemplate jTemplate){ + JTemplate current = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + return ComparatorUtils.equals(current.getTemplateTabOperatorType(), jTemplate.getTemplateTabOperatorType()); + } + + /** + * 获取tab操作类型的模板 + * @param operator + * @return + */ + public List> getOpenedJTemplatesByOperator(String operator) { + return openedTemplate.stream().filter((jTemplate) -> ComparatorUtils.equals(jTemplate.getTemplateTabOperatorType(), operator)) + .collect(Collectors.toList()); + } + + /** + * 根据tab操作类型进行分类 + * @return + */ + public Map>> getOpenedJTemplatesByCategory() { + return openedTemplate.stream() + .collect(Collectors.groupingBy(JTemplate::getTemplateTabOperatorType)); + } + } diff --git a/designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java b/designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java index dae921a1c8..81f82e78c6 100644 --- a/designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java +++ b/designer-base/src/main/java/com/fr/design/file/NewTemplatePane.java @@ -81,11 +81,19 @@ public abstract class NewTemplatePane extends JComponent implements MouseListene } if (isOverNewIcon(evtX) && newWorkBookIconMode != GRAY_NEW_CPT) { newWorkBookIconMode = getMousePressNew(); - DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + createNewTemplate(); } this.repaint(); } + + /** + * 新建模板 + */ + protected void createNewTemplate() { + DesignerContext.getDesignerFrame().addAndActivateJTemplate(); + } + /** *鼠标松开 * @param 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 72945b31c9..fa8e3d385d 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 @@ -47,6 +47,7 @@ public class SaveSomeTemplatePane extends BasicPane { /** * 支持自定义设置 dialog的父窗口 + * * @param isNeedTojudgeCurrent * @param parent */ @@ -79,11 +80,14 @@ public class SaveSomeTemplatePane extends BasicPane { this.isJudgeCurrentEditingTemplate = isNeedTojudgeCurrent; } - private void initTemplatesChoosePane() { + + private void initTemplatesChoosePane(boolean judgeJTemplateMustSave) { templatesChoosePane.setBorder(BorderFactory.createTitledBorder("")); for (int i = 0; i < unSavedTemplate.size(); i++) { templateCheckBoxes[i] = new UICheckBox(unSavedTemplate.get(i).getEditingFILE().getName()); templateCheckBoxes[i].setSelected(true); + boolean needSave = judgeJTemplateMustSave && unSavedTemplate.get(i).needSaveBeforeSwitchEnv(); + templateCheckBoxes[i].setEnabled(!needSave); } final UIList templatesList = new UIList(templateCheckBoxes); @@ -103,7 +107,10 @@ public class SaveSomeTemplatePane extends BasicPane { boolean isSelected = chooseAllCheckBox.isSelected(); for (int i = 0; i < templatesList.getModel().getSize(); i++) { UICheckBox checkBox = (UICheckBox) templatesList.getModel().getElementAt(i); - checkBox.setSelected(isSelected); + boolean mustSaveBeforeSwitchEnv = judgeJTemplateMustSave && unSavedTemplate.get(i).needSaveBeforeSwitchEnv(); + checkBox.setSelected(mustSaveBeforeSwitchEnv || isSelected); + templateCheckBoxes[i].setEnabled(!mustSaveBeforeSwitchEnv); + } templatesList.repaint(); } @@ -139,7 +146,7 @@ public class SaveSomeTemplatePane extends BasicPane { /** * 获取templateCheckBoxes中状态为选中状态的CheckBox数量 - * */ + */ private int calculateSelectedNum() { int count = 0; for (UICheckBox checkBox : templateCheckBoxes) { @@ -152,7 +159,11 @@ public class SaveSomeTemplatePane extends BasicPane { public boolean showSavePane() { - populate(); + return showSavePane(false); + } + + public boolean showSavePane(boolean judgeJTemplateMustSave) { + populate(judgeJTemplateMustSave); //如果有未保存的文件 ,则跳出保存对话框,选择要存储的项目 if (!unSavedTemplate.isEmpty()) { dialog.setVisible(true); @@ -162,8 +173,12 @@ public class SaveSomeTemplatePane extends BasicPane { return isAllSaved; } - public void populate() { - java.util.List> opendedTemplate = HistoryTemplateListPane.getInstance().getHistoryList(); + protected java.util.List> getOpenedTemplatesToProcess(){ + return HistoryTemplateListPane.getInstance().getHistoryList(); + } + + public void populate(boolean judgeJTemplateMustSave) { + java.util.List> opendedTemplate = getOpenedTemplatesToProcess(); JTemplate currentTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); for (int i = 0; i < opendedTemplate.size(); i++) { if (isneedToAdd(opendedTemplate.get(i), currentTemplate)) { @@ -171,10 +186,10 @@ public class SaveSomeTemplatePane extends BasicPane { } } templateCheckBoxes = new UICheckBox[unSavedTemplate.size()]; - initTemplatesChoosePane(); + initTemplatesChoosePane(judgeJTemplateMustSave); } - private boolean isneedToAdd(JTemplate template, JTemplate currentTemplate) { + protected boolean isneedToAdd(JTemplate template, JTemplate currentTemplate) { //所有模板都判断是不是保存 if (isJudgeCurrentEditingTemplate) { return !template.isALLSaved(); @@ -194,7 +209,7 @@ public class SaveSomeTemplatePane extends BasicPane { specifiedTemplate.stopEditing(); return specifiedTemplate.saveTemplate(); } - FineLoggerFactory.getLogger().info( com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName())); + FineLoggerFactory.getLogger().info(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Template_Already_Saved", specifiedTemplate.getEditingFILE().getName())); return true; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java index 63c00deaaf..3cceff5a75 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java @@ -311,4 +311,11 @@ public class CenterRegionContainerPane extends JPanel { return toolbarComponentState; } + /** + * 重置下RegionContainerpane + */ + public void resetCenterRegionContainerPane(){ + templateTabPane.add(MultiTemplateTabPane.getInstance(), BorderLayout.CENTER); + } + } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java b/designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java index 581dc54cb8..73daf052f1 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DefaultToolKitConfig.java @@ -2,7 +2,6 @@ package com.fr.design.mainframe; import com.fr.design.base.mode.DesignModeContext; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; - import javax.swing.JPanel; @@ -24,6 +23,7 @@ public class DefaultToolKitConfig implements ToolKitConfigStrategy { @Override public JPanel customNorthPane(JPanel toolBarPane, ToolBarMenuDockPlus plus) { + CenterRegionContainerPane.getInstance().resetCenterRegionContainerPane(); return toolBarPane; } } 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 229ba848d8..17a5afb2b6 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.module.DesignModuleFactory; import com.fr.design.preview.PagePreview; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.TemplateUtils; import com.fr.design.worker.save.CallbackSaveWorker; import com.fr.design.worker.save.EmptyCallBackSaveWorker; import com.fr.design.worker.save.SaveFailureHandler; @@ -120,6 +121,8 @@ import java.util.concurrent.Callable; * 报表设计和表单设计的编辑区域(设计器编辑的IO文件) */ public abstract class JTemplate> extends TargetComponent implements ToolBarMenuDockPlus, DesignerProxy, JTemplateSave, TabChangeListener, ThemedTemplate { + + private static final String DEFAULT_TAB_OPERATOR = "DefaultTabOperator"; // TODO ALEX_SEP editingFILE这个属性一定要吗?如果非要不可,有没有可能保证不为null private static final int PREDEFINED_ICON_WIDTH = 27; @@ -2060,4 +2063,50 @@ public abstract class JTemplate> public static boolean isValid(JTemplate jt) { return jt != null && jt != JNullTemplate.NULL; } + + /** + * 获取此模板所使用的tab栏操作类型 + * @return + */ + public String getTemplateTabOperatorType(){ + return DEFAULT_TAB_OPERATOR; + } + + /** + * 当前模板是否可以被保存 + * @return 是/否 + */ + public boolean canBeSaved(){ + return true; + } + + /** + * 当前的模板是否支持缓存 + * + * @return 是/否 + */ + public boolean supportCache(){ + return true; + } + + /** + * 获取此模板在tab栏中显示的名称 + * @return + */ + public String getTabShowName(JTemplate jTemplate){ + String name = TemplateUtils.createLockeTemplatedName(jTemplate, jTemplate.getTemplateName()); + if (!jTemplate.isSaved() && !name.endsWith(" *")) { + name += " *"; + } + return name; + } + + /** + * 切换环境之前是否需要保存 + * @return + */ + public boolean needSaveBeforeSwitchEnv(){ + return false; + } + } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index 3372e2ad13..37812c106f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java @@ -416,9 +416,7 @@ public abstract class ToolBarMenuDock { menuDef.addShortCut(new OpenRecentReportMenuDef()); - if (!DesignModeContext.isDuchampMode()) { - addCloseCurrentTemplateAction(menuDef); - } + addCloseCurrentTemplateAction(menuDef); scs = plus.shortcut4FileMenu(); if (!ArrayUtils.isEmpty(scs)) {