diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index cb8634c002..661b4fa5c8 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -16,6 +16,7 @@ import com.fr.design.env.RemoteDesignerWorkspaceInfo; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.locale.impl.ProductImproveMark; import com.fr.design.mainframe.vcs.VcsConfigManager; +import com.fr.design.notification.SnapChatConfig; import com.fr.design.update.push.DesignerPushUpdateConfigManager; import com.fr.design.style.color.ColorSelectConfigManager; import com.fr.design.utils.DesignUtils; @@ -154,6 +155,11 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { * alphafine */ private AlphaFineConfigManager alphaFineConfigManager = AlphaFineConfigManager.getInstance(); + + /** + * 阅后即焚的配置项 + */ + private SnapChatConfig snapChatConfig = SnapChatConfig.getInstance(); private DesignerPushUpdateConfigManager designerPushUpdateConfigManager = DesignerPushUpdateConfigManager.getInstance(); @@ -1548,12 +1554,17 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { readVcsAttr(reader); } else if (DesignerPort.XML_TAG.equals(name)) { readDesignerPort(reader); - } - else { + } else if (name.equals(SnapChatConfig.XML_TAG)) { + readSnapChatConfig(reader); + } else { readLayout(reader, name); } } } + + private void readSnapChatConfig(XMLableReader reader) { + reader.readXMLObject(this.snapChatConfig = SnapChatConfig.getInstance()); + } private void readAlphaFineAttr(XMLableReader reader) { reader.readXMLObject(this.alphaFineConfigManager = AlphaFineConfigManager.getInstance()); @@ -1770,9 +1781,17 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { writeDesignerPushUpdateAttr(writer); writeVcsAttr(writer); writeDesignerPort(writer); + writeSnapChatConfig(writer); writer.end(); } - + + private void writeSnapChatConfig(XMLPrintWriter writer) { + + if (this.snapChatConfig != null) { + this.snapChatConfig.writeXML(writer); + } + } + private void writeAlphaFineAttr(XMLPrintWriter writer) { if (this.alphaFineConfigManager != null) { this.alphaFineConfigManager.writeXML(writer); diff --git a/designer-base/src/main/java/com/fr/design/fun/PropertyItemPaneProvider.java b/designer-base/src/main/java/com/fr/design/fun/PropertyItemPaneProvider.java new file mode 100644 index 0000000000..2c5c3f2d48 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/PropertyItemPaneProvider.java @@ -0,0 +1,46 @@ +package com.fr.design.fun; + +import com.fr.design.mainframe.PaneHolder; +import com.fr.design.mainframe.PropertyItemBean; +import com.fr.stable.fun.mark.Mutable; +import org.jetbrains.annotations.Nullable; + +/** + * created by Harrison on 2020/03/23 + **/ +public interface PropertyItemPaneProvider extends Mutable { + + int CURRENT_LEVEL = 1; + + String XML_TAG = "PropertyItemPaneProvider"; + + /** + * 独一无二的标志 + * + * @return 标志 + */ + String key(); + + /** + * 配置属性 + * + * @return 熟悉 + */ + PropertyItemBean getItem(); + + /** + * 面板持有者 + * + * @param clazz 类型 + * @return 持有者 + */ + @Nullable + PaneHolder getPaneHolder(Class clazz); + + /** + * 想要替代的类型 + * + * @return 替代类型 + */ + String replaceKey(); +} diff --git a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractPropertyItemPaneProvider.java b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractPropertyItemPaneProvider.java new file mode 100644 index 0000000000..44e4abd4d1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractPropertyItemPaneProvider.java @@ -0,0 +1,31 @@ +package com.fr.design.fun.impl; + +import com.fr.design.fun.PropertyItemPaneProvider; +import com.fr.design.mainframe.PaneHolder; +import com.fr.stable.fun.impl.AbstractProvider; +import com.fr.stable.fun.mark.API; + +/** + * created by Harrison on 2020/03/23 + **/ +@API(level = PropertyItemPaneProvider.CURRENT_LEVEL) +public abstract class AbstractPropertyItemPaneProvider extends AbstractProvider implements PropertyItemPaneProvider { + + @Override + public PaneHolder getPaneHolder(Class clazz) { + + if (sign().equals(clazz)) { + return getPathHolder0(); + } + return null; + } + + protected abstract PaneHolder getPathHolder0(); + + protected abstract Class sign(); + + @Override + public int currentAPILevel() { + return PropertyItemPaneProvider.CURRENT_LEVEL; + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/imenu/UIMenuItem.java b/designer-base/src/main/java/com/fr/design/gui/imenu/UIMenuItem.java index 37f1fe0528..3230dbda21 100644 --- a/designer-base/src/main/java/com/fr/design/gui/imenu/UIMenuItem.java +++ b/designer-base/src/main/java/com/fr/design/gui/imenu/UIMenuItem.java @@ -1,15 +1,11 @@ package com.fr.design.gui.imenu; -import java.awt.*; - -import javax.swing.*; -import javax.swing.plaf.basic.BasicMenuItemUI; - import com.fr.design.constants.UIConstants; -import com.fr.stable.Constants; import com.fr.stable.StringUtils; -import com.fr.design.utils.gui.GUIPaintUtils; -import sun.swing.SwingUtilities2; + +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.JMenuItem; public class UIMenuItem extends JMenuItem{ public UIMenuItem() { @@ -42,66 +38,5 @@ public class UIMenuItem extends JMenuItem{ public String getText() { return StringUtils.BLANK + super.getText(); } - - private class UIMenuItemUI extends BasicMenuItemUI { - @Override - protected void paintBackground(Graphics g, JMenuItem menuItem,Color bgColor) { - if(menuItem.getIcon() == null) { - super.paintBackground(g, menuItem, bgColor); - return; - } - ButtonModel model = menuItem.getModel(); - Color oldColor = g.getColor(); - int menuWidth = menuItem.getWidth(); - int menuHeight = menuItem.getHeight(); - - g.setColor(UIConstants.NORMAL_BACKGROUND); - g.fillRect(0, 0, menuWidth, menuHeight); - if(menuItem.isOpaque()) { - if (model.isArmed()|| (menuItem instanceof JMenu && model.isSelected())) { - GUIPaintUtils.fillPaint((Graphics2D)g, 30, 0, menuWidth - 30, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); - } else { - GUIPaintUtils.fillPaint((Graphics2D)g, 30, 0, menuWidth - 30, menuHeight, true, Constants.NULL, menuItem.getBackground(), 7); - } - g.setColor(oldColor); - } - else if (model.isArmed() || (menuItem instanceof JMenu && - model.isSelected())) { - GUIPaintUtils.fillPaint((Graphics2D)g, 30, 0, menuWidth - 30, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); - g.setColor(oldColor); - } - } - - protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { - ButtonModel model = menuItem.getModel(); - FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); - int mnemIndex = menuItem.getDisplayedMnemonicIndex(); - - if(!model.isEnabled()) { - // *** paint the text disabled - if ( UIManager.get("MenuItem.disabledForeground") instanceof Color ) { - g.setColor( UIManager.getColor("MenuItem.disabledForeground") ); - SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text, - -1, textRect.x, textRect.y + fm.getAscent()); - } else { - g.setColor(menuItem.getBackground().brighter()); - SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, - -1, textRect.x, textRect.y + fm.getAscent()); - g.setColor(menuItem.getBackground().darker()); - SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text, - -1, textRect.x - 1, textRect.y + - fm.getAscent() - 1); - } - } else { - // *** paint the text normally - if (model.isArmed()|| (menuItem instanceof JMenu && model.isSelected())) { - g.setColor(Color.WHITE); // Uses protected field. - } - SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text, - -1, textRect.x, textRect.y + fm.getAscent()); - } - } - - } - + } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/gui/imenu/UIMenuItemUI.java b/designer-base/src/main/java/com/fr/design/gui/imenu/UIMenuItemUI.java new file mode 100644 index 0000000000..0d883abfbf --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/imenu/UIMenuItemUI.java @@ -0,0 +1,81 @@ +package com.fr.design.gui.imenu; + +import com.fr.design.constants.UIConstants; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.stable.Constants; +import sun.swing.SwingUtilities2; + +import javax.swing.ButtonModel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.UIManager; +import javax.swing.plaf.basic.BasicMenuItemUI; +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +/** + * created by Harrison on 2020/03/22 + **/ +public class UIMenuItemUI extends BasicMenuItemUI { + + @Override + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + if (menuItem.getIcon() == null) { + super.paintBackground(g, menuItem, bgColor); + return; + } + ButtonModel model = menuItem.getModel(); + Color oldColor = g.getColor(); + int menuWidth = menuItem.getWidth(); + int menuHeight = menuItem.getHeight(); + + g.setColor(UIConstants.NORMAL_BACKGROUND); + g.fillRect(0, 0, menuWidth, menuHeight); + if (menuItem.isOpaque()) { + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 30, 0, menuWidth - 30, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + } else { + GUIPaintUtils.fillPaint((Graphics2D) g, 30, 0, menuWidth - 30, menuHeight, true, Constants.NULL, menuItem.getBackground(), 7); + } + g.setColor(oldColor); + } else if (model.isArmed() || (menuItem instanceof JMenu && + model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 30, 0, menuWidth - 30, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + g.setColor(oldColor); + } + } + + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + ButtonModel model = menuItem.getModel(); + FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); + int mnemIndex = menuItem.getDisplayedMnemonicIndex(); + + if (!model.isEnabled()) { + // *** paint the text disabled + if (UIManager.get("MenuItem.disabledForeground") instanceof Color) { + g.setColor(UIManager.getColor("MenuItem.disabledForeground")); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } else { + g.setColor(menuItem.getBackground().brighter()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + g.setColor(menuItem.getBackground().darker()); + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x - 1, textRect.y + + fm.getAscent() - 1); + } + } else { + // *** paint the text normally + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + g.setColor(Color.WHITE); // Uses protected field. + } + SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, + -1, textRect.x, textRect.y + fm.getAscent()); + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java index 07191d536d..0c23e8658f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java @@ -3,7 +3,9 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignerEnvManager; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.constants.UIConstants; +import com.fr.design.fun.PropertyItemPaneProvider; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UIButtonUI; import com.fr.design.gui.icontainer.UIEastResizableContainer; @@ -12,12 +14,38 @@ import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.design.utils.gui.GUIPaintUtils; import com.fr.general.FRFont; - +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.context.PluginRuntime; +import com.fr.plugin.injectable.PluginModule; +import com.fr.plugin.manage.PluginFilter; +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.stable.StringUtils; -import javax.swing.*; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; +import java.awt.Image; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; @@ -26,6 +54,7 @@ import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.Set; @@ -101,9 +130,101 @@ public class EastRegionContainerPane extends UIEastResizableContainer { defaultAuthorityPane = getDefaultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Not_Support_Authority_Edit")); switchMode(PropertyMode.REPORT); setContainerWidth(CONTAINER_WIDTH); + + initPluginPane(); + listenPlugin(); } - + + private void listenPlugin() { + + PluginFilter filter = new PluginFilter() { + @Override + public boolean accept(PluginContext context) { + return context.contain(PropertyItemPaneProvider.XML_TAG); + } + }; + PluginListenerRegistration.getInstance().listen( + PluginEventType.AfterRun, + new PluginEventListener() { + @Override + public void on(PluginEvent event) { + PluginContext context = event.getContext(); + PluginRuntime runtime = context.getRuntime(); + Set providers = runtime.get(PropertyItemPaneProvider.XML_TAG); + for (PropertyItemPaneProvider provider : providers) { + addPropertyItem(provider); + } + updateAllPropertyPane(); + } + }, filter); + PluginListenerRegistration.getInstance().listen( + PluginEventType.BeforeStop, + new PluginEventListener(10) { + @Override + public void on(PluginEvent event) { + PluginContext context = event.getContext(); + PluginRuntime runtime = context.getRuntime(); + Set providers = runtime.get(PropertyItemPaneProvider.XML_TAG); + for (PropertyItemPaneProvider provider : providers) { + removePropertyItem(provider); + + } + updateAllPropertyPane(); + } + }, filter); + } + + private void removePropertyItem(PropertyItemPaneProvider provider) { + + propertyItemMap.remove(provider.key()); + String replaceKey = provider.replaceKey(); + if (replaceKey == null) { + return; + } + PropertyItem replaceItem = propertyItemMap.get(replaceKey); + if (replaceItem != null) { + replaceItem.setReplace(false); + } + } + + private void initPluginPane() { + + ExtraDesignClassManager classManager = PluginModule.getAgent(PluginModule.ExtraDesign); + Set providers = classManager.getArray(PropertyItemPaneProvider.XML_TAG); + for (PropertyItemPaneProvider provider : providers) { + addPropertyItem(provider); + } + } + + private void addPropertyItem(PropertyItemPaneProvider provider) { + + String key = provider.key(); + PropertyItemBean itemBean = provider.getItem(); + PropertyItem propertyItem = new PropertyItem(itemBean.getName(), + itemBean.getTitle(), + itemBean.getBtnIconName(), + itemBean.getVisibleModes(), + itemBean.getEnableModes()); + UIButton button = propertyItem.getButton(); + List buttonListeners = itemBean.getButtonListeners(); + for (ActionListener buttonListener : buttonListeners) { + button.addActionListener(buttonListener); + } + propertyItemMap.put(key, propertyItem); + + String replaceKey = provider.replaceKey(); + if (replaceKey == null) { + return; + } + PropertyItem replaceItem = propertyItemMap.get(replaceKey); + if (replaceItem != null) { + replaceItem.setReplace(true); + } + + } + private void initPropertyItemList() { + propertyItemMap = new LinkedHashMap<>(); // 有序map // 单元格元素 PropertyItem cellElement = new PropertyItem(KEY_CELL_ELEMENT, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Cell_Element"), @@ -360,6 +481,11 @@ public class EastRegionContainerPane extends UIEastResizableContainer { public void replaceConfiguredRolesPane(JComponent pane) { propertyItemMap.get(KEY_CONFIGURED_ROLES).replaceContentPane(pane); } + + public void replaceKeyPane(String key, JComponent pane) { + + propertyItemMap.get(key).replaceContentPane(pane); + } public JComponent getConfiguredRolesPane() { return propertyItemMap.get(KEY_CONFIGURED_ROLES).getContentPane(); @@ -511,6 +637,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer { private PopupDialog popupDialog; // 弹出框 private boolean isPoppedOut = false; // 是否弹出 private boolean isVisible = true; // 是否可见 + private boolean replace = false; // 是否被替代 private boolean isEnabled = true; // 是否可用 private Set visibleModes; private Set enableModes; @@ -563,13 +690,19 @@ public class EastRegionContainerPane extends UIEastResizableContainer { } public boolean isVisible() { - return isVisible; + // 取决于可见且未替代 + return isVisible && !replace; } public void setVisible(boolean isVisible) { this.isVisible = isVisible; } - + + public void setReplace(boolean replace) { + + this.replace = replace; + } + public boolean isEnabled() { return isEnabled; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/PaneHolder.java b/designer-base/src/main/java/com/fr/design/mainframe/PaneHolder.java new file mode 100644 index 0000000000..aef5e0b137 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/PaneHolder.java @@ -0,0 +1,17 @@ +package com.fr.design.mainframe; + +import javax.swing.JPanel; + +/** + * created by Harrison on 2020/03/23 + **/ +public interface PaneHolder { + + /** + * 得到 Pane + * + * @param arg 参数 + * @return 面板 + */ + JPanel getInstance(T arg); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/PropertyItemBean.java b/designer-base/src/main/java/com/fr/design/mainframe/PropertyItemBean.java new file mode 100644 index 0000000000..f6a250defc --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/PropertyItemBean.java @@ -0,0 +1,68 @@ +package com.fr.design.mainframe; + +import java.awt.event.ActionListener; +import java.util.List; + +/** + * created by Harrison on 2020/03/23 + **/ +public class PropertyItemBean { + + private String name; + private String title; + private String btnIconName; + private EastRegionContainerPane.PropertyMode[] visibleModes; + private EastRegionContainerPane.PropertyMode[] enableModes; + private List buttonListeners; + + public PropertyItemBean() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getBtnIconName() { + return btnIconName; + } + + public void setBtnIconName(String btnIconName) { + this.btnIconName = btnIconName; + } + + public EastRegionContainerPane.PropertyMode[] getVisibleModes() { + return visibleModes; + } + + public void setVisibleModes(EastRegionContainerPane.PropertyMode[] visibleModes) { + this.visibleModes = visibleModes; + } + + public EastRegionContainerPane.PropertyMode[] getEnableModes() { + return enableModes; + } + + public void setEnableModes(EastRegionContainerPane.PropertyMode[] enableModes) { + this.enableModes = enableModes; + } + + public List getButtonListeners() { + return buttonListeners; + } + + public void setButtonListeners(List buttonListeners) { + this.buttonListeners = buttonListeners; + } +} 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 cdafa8c410..bc4b85ced8 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 @@ -12,7 +12,6 @@ import com.fr.design.actions.UpdateAction; import com.fr.design.actions.community.BBSAction; import com.fr.design.actions.community.BugAction; import com.fr.design.actions.community.CenterAction; -import com.fr.design.actions.community.CusDemandAction; import com.fr.design.actions.community.FacebookFansAction; import com.fr.design.actions.community.NeedAction; import com.fr.design.actions.community.QuestionAction; @@ -53,7 +52,9 @@ import com.fr.design.mainframe.ToolBarNewTemplatePane; import com.fr.design.menu.MenuDef; import com.fr.design.menu.SeparatorDef; import com.fr.design.menu.ShortCut; +import com.fr.design.menu.SnapChatMenuDef; import com.fr.design.menu.ToolBarDef; +import com.fr.design.notification.SnapChatAllTypes; import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.remote.action.RemoteDesignAuthManagerAction; import com.fr.design.update.actions.SoftwareUpdateAction; @@ -563,15 +564,24 @@ public abstract class ToolBarMenuDock { * @return 社区菜单的子菜单 */ public ShortCut[] createCommunityShortCuts() { + final java.util.List shortCuts = new ArrayList(); shortCuts.add(new BBSAction()); + + shortCuts.add(SeparatorDef.DEFAULT); + shortCuts.add(new VideoAction()); shortCuts.add(new TutorialAction()); shortCuts.add(new QuestionAction()); shortCuts.add(new TechSolutionAction()); + + shortCuts.add(SeparatorDef.DEFAULT); + shortCuts.add(new BugAction()); shortCuts.add(new NeedAction()); - shortCuts.add(new CusDemandAction()); + + shortCuts.add(SeparatorDef.DEFAULT); + shortCuts.add(new CenterAction()); shortCuts.add(new SignAction()); LocaleCenter.buildAction(new LocaleAction() { @@ -594,7 +604,11 @@ public abstract class ToolBarMenuDock { } public MenuDef createCommunityMenuDef() { - MenuDef menuDef = new MenuDef(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community"), 'C'); + + MenuDef menuDef = new SnapChatMenuDef( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community"), + 'C', + SnapChatAllTypes.Menu.BBS); ShortCut[] otherCommunityShortCuts = createCommunityShortCuts(); for (ShortCut shortCut : otherCommunityShortCuts) { menuDef.addShortCut(shortCut); diff --git a/designer-base/src/main/java/com/fr/design/menu/MenuDef.java b/designer-base/src/main/java/com/fr/design/menu/MenuDef.java index c18749c12c..f495e03f13 100644 --- a/designer-base/src/main/java/com/fr/design/menu/MenuDef.java +++ b/designer-base/src/main/java/com/fr/design/menu/MenuDef.java @@ -38,8 +38,8 @@ public class MenuDef extends ShortCut { protected UIMenu createdJMenu; protected UIButton createdButton; protected JPopupMenu popupMenu; - private boolean hasScrollSubMenu; - private boolean isHeadMenu; + protected boolean hasScrollSubMenu; + protected boolean isHeadMenu; private String anchor; @@ -187,18 +187,13 @@ public class MenuDef extends ShortCut { */ public UIMenu createJMenu() { if (createdJMenu == null) { - if (hasScrollSubMenu) { - createdJMenu = new UIScrollMenu(this.getName()); - } else if (isHeadMenu){ - createdJMenu = new UIHeadMenu(this.getName()); - } else { - createdJMenu = new UIMenu(this.getName()); - } + createdJMenu = createJMenu0(); createdJMenu.setMnemonic(this.getMnemonic()); if (this.iconPath != null) { createdJMenu.setIcon(BaseUtils.readIcon(this.iconPath)); } - createdJMenu.addMenuListener(menuDefListener); + MenuListener menuListener = createMenuListener(); + createdJMenu.addMenuListener(menuListener); ContainerListener listener = getContainerListener(); if (listener != null) { createdJMenu.getPopupMenu().addContainerListener(listener); @@ -207,7 +202,20 @@ public class MenuDef extends ShortCut { return createdJMenu; } - + + protected UIMenu createJMenu0() { + + UIMenu createdJMenu; + if (hasScrollSubMenu) { + createdJMenu = new UIScrollMenu(this.getName()); + } else if (isHeadMenu){ + createdJMenu = new UIHeadMenu(this.getName()); + } else { + createdJMenu = new UIMenu(this.getName()); + } + return createdJMenu; + } + protected ContainerListener getContainerListener() { return null; } @@ -377,6 +385,11 @@ public class MenuDef extends ShortCut { public void intoJToolBar(JToolBar toolBar) { toolBar.add(this.createUIButton()); } + + protected MenuListener createMenuListener() { + + return menuDefListener; + } private MenuListener menuDefListener = new MenuListener() { diff --git a/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuDef.java b/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuDef.java new file mode 100644 index 0000000000..f3c5735f01 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuDef.java @@ -0,0 +1,144 @@ +package com.fr.design.menu; + +import com.fr.design.gui.imenu.UIMenu; +import com.fr.design.gui.imenu.UIScrollMenu; +import com.fr.design.notification.SnapChat; +import com.fr.design.notification.SnapChatConfig; +import com.fr.design.notification.SnapChatKey; + +import javax.swing.JMenu; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; + +/** + * created by Harrison on 2020/03/16 + **/ +public class SnapChatMenuDef extends MenuDef implements SnapChat { + + private SnapChatKey uniqueKey; + private SnapChatMenuUI menuUI = new SnapChatMenuUI(this); + + public SnapChatMenuDef(String name, SnapChatKey uniqueKey) { + super(name); + this.uniqueKey = uniqueKey; + } + + public SnapChatMenuDef(Boolean rePaint, SnapChatKey uniqueKey) { + super(rePaint); + this.uniqueKey = uniqueKey; + } + + public SnapChatMenuDef(String name, char mnemonic, SnapChatKey uniqueKey) { + super(name, mnemonic); + this.uniqueKey = uniqueKey; + } + + @Override + public boolean hasRead() { + + String calcKey = calcKey(); + return SnapChatConfig.getInstance().hasRead(calcKey); + } + + @Override + public void markRead() { + + String calcKey = calcKey(); + SnapChatConfig.getInstance().markRead(calcKey); + } + + @Override + public SnapChatKey key() { + + return this.uniqueKey; + } + + @Override + protected MenuListener createMenuListener() { + + return new SnapChatMenuListener(); + } + + private String calcKey() { + + return key().calc(); + } + + @Override + protected UIMenu createJMenu0() { + + UIMenu createdJMenu; + if (hasScrollSubMenu) { + createdJMenu = new SnapChatUIScrollMenu(this.getName()); + } else if (isHeadMenu){ + createdJMenu = new SnapChatUIHeadMenu(this.getName()); + } else { + createdJMenu = new SnapChatUIMenu(this.getName()); + } + return createdJMenu; + } + + private class SnapChatMenuListener implements MenuListener { + + @Override + public void menuSelected(MenuEvent e) { + + markRead(); + Object source = e.getSource(); + if (!(source instanceof JMenu)) { + return; + } + updateMenu(); + } + + @Override + public void menuDeselected(MenuEvent e) { + + } + + @Override + public void menuCanceled(MenuEvent e) { + + } + } + + private class SnapChatUIScrollMenu extends UIScrollMenu { + + public SnapChatUIScrollMenu(String s) { + super(s); + } + + @Override + public void updateUI() { + setUI(menuUI); + } + } + + private class SnapChatUIMenu extends UIMenu { + + public SnapChatUIMenu(String name) { + + super(name); + } + + @Override + public void updateUI() { + + setUI(menuUI); + } + } + + private class SnapChatUIHeadMenu extends UIMenu { + + public SnapChatUIHeadMenu(String name) { + + super(name); + } + + @Override + public void updateUI() { + + setUI(menuUI); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuItemUI.java b/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuItemUI.java new file mode 100644 index 0000000000..c9ab8532d2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuItemUI.java @@ -0,0 +1,31 @@ +package com.fr.design.menu; + +import com.fr.design.gui.imenu.UIMenuItemUI; + +import javax.swing.JMenuItem; +import java.awt.Graphics; +import java.awt.Rectangle; + +/** + * created by Harrison on 2020/03/22 + **/ +class SnapChatMenuItemUI extends UIMenuItemUI { + + private final SnapChatUpdateAction snapChatUpdateAction; + + public SnapChatMenuItemUI(SnapChatUpdateAction snapChatUpdateAction) { + + this.snapChatUpdateAction = snapChatUpdateAction; + } + + @Override + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + + super.paintText(g, menuItem, textRect, text); + + if (!snapChatUpdateAction.hasRead()) { + SnapChatUtil.paintSnapChat(g, textRect); + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuUI.java b/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuUI.java new file mode 100644 index 0000000000..47bc3c6634 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/menu/SnapChatMenuUI.java @@ -0,0 +1,29 @@ +package com.fr.design.menu; + +import com.fr.design.gui.imenu.UIMenuUI; + +import javax.swing.JMenuItem; +import java.awt.Graphics; +import java.awt.Rectangle; + +/** + * created by Harrison on 2020/03/22 + **/ +public class SnapChatMenuUI extends UIMenuUI { + + private SnapChatMenuDef menuDef; + + public SnapChatMenuUI(SnapChatMenuDef menuDef) { + this.menuDef = menuDef; + } + + @Override + protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { + + super.paintText(g, menuItem, textRect, text); + + if (!menuDef.hasRead()) { + SnapChatUtil.paintSnapChat(g, textRect); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/menu/SnapChatUpdateAction.java b/designer-base/src/main/java/com/fr/design/menu/SnapChatUpdateAction.java new file mode 100644 index 0000000000..4829545468 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/menu/SnapChatUpdateAction.java @@ -0,0 +1,72 @@ +package com.fr.design.menu; + +import com.fr.design.actions.UpdateAction; +import com.fr.design.gui.imenu.UIMenuItem; +import com.fr.design.notification.SnapChat; +import com.fr.design.notification.SnapChatConfig; +import com.fr.design.notification.SnapChatKey; + +import java.awt.event.ActionEvent; + +/** + * created by Harrison on 2020/03/22 + **/ +public abstract class SnapChatUpdateAction extends UpdateAction implements SnapChat { + + private SnapChatKey uniqueKey; + + public SnapChatUpdateAction(SnapChatKey uniqueKey) { + this.uniqueKey = uniqueKey; + } + + @Override + public final void actionPerformed(ActionEvent e) { + + markRead(); + actionPerformed0(e); + } + + protected abstract void actionPerformed0(ActionEvent e); + + @Override + public boolean hasRead() { + + String calcKey = calcKey(); + return SnapChatConfig.getInstance().hasRead(calcKey); + } + + @Override + public void markRead() { + + String calcKey = calcKey(); + SnapChatConfig.getInstance().markRead(calcKey); + } + + @Override + public SnapChatKey key() { + + return this.uniqueKey; + } + + private String calcKey() { + + return key().calc(); + } + + @Override + public UIMenuItem createMenuItem() { + + Object object = this.getValue(UIMenuItem.class.getName()); + if (object == null && !(object instanceof UIMenuItem)) { + UIMenuItem menuItem = new UIMenuItem(this); + // 设置名字用作单元测 + menuItem.setName(getName()); + menuItem.setUI(new SnapChatMenuItemUI(this)); + object = menuItem; + + this.putValue(UIMenuItem.class.getName(), object); + } + return (UIMenuItem) object; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/menu/SnapChatUtil.java b/designer-base/src/main/java/com/fr/design/menu/SnapChatUtil.java new file mode 100644 index 0000000000..6eb648055a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/menu/SnapChatUtil.java @@ -0,0 +1,33 @@ +package com.fr.design.menu; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.geom.Ellipse2D; + +/** + * created by Harrison on 2020/03/22 + **/ +public class SnapChatUtil { + + public static void paintSnapChat(Graphics g, Rectangle textRect) { + + Color oldColor = g.getColor(); + + double x = textRect.getWidth(); + x += textRect.getX(); + x += 2; + + double y = textRect.getY(); + + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(Color.red); + Ellipse2D.Double shape = + new Ellipse2D.Double(x, y, 4, 4); + g2d.fill(shape); + g2d.draw(shape); + + g2d.setColor(oldColor); + } +} diff --git a/designer-base/src/main/java/com/fr/design/notification/SnapChat.java b/designer-base/src/main/java/com/fr/design/notification/SnapChat.java new file mode 100644 index 0000000000..8dd6f8aa28 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/notification/SnapChat.java @@ -0,0 +1,28 @@ +package com.fr.design.notification; + +/** + * 阅后即焚的消息提醒 + * + * created by Harrison on 2020/03/16 + **/ +public interface SnapChat { + + /** + * 已读 + * + * @return 是否为已读 + */ + boolean hasRead(); + + /** + * 标记为已读 + */ + void markRead(); + + /** + * 独一无二的标志 + * + * @return 字符标志 + */ + SnapChatKey key(); +} diff --git a/designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java b/designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java new file mode 100644 index 0000000000..6aeb384df5 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/notification/SnapChatAllTypes.java @@ -0,0 +1,38 @@ +package com.fr.design.notification; + +import com.fr.stable.CommonUtils; + +/** + * created by Harrison on 2020/03/16 + **/ +public abstract class SnapChatAllTypes { + + public enum Menu implements SnapChatKey { + + /** + * 社区按钮 + */ + BBS("BBS"); + + private static final String SIGN = "0001"; + + private String key; + + Menu(String key) { + this.key = key; + } + + public String getKey() { + return key; + } + + @Override + public String calc() { + + return CommonUtils.join( + new String[]{SIGN, getKey()}, "-" + ); + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/notification/SnapChatConfig.java b/designer-base/src/main/java/com/fr/design/notification/SnapChatConfig.java new file mode 100644 index 0000000000..04170e3be8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/notification/SnapChatConfig.java @@ -0,0 +1,89 @@ +package com.fr.design.notification; + +import com.fr.stable.StringUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLReadable; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; + +import java.util.HashMap; +import java.util.Map; + +/** + * created by Harrison on 2020/03/16 + **/ +@SuppressWarnings("unchecked") +public class SnapChatConfig implements XMLable { + + public static final String XML_TAG = "SnapChatConfig"; + + /** + * 已经阅读过的属性 + */ + private Map markReadMap = new HashMap<>(8); + + private static final SnapChatConfig INSTANCE = new SnapChatConfig(); + + public static SnapChatConfig getInstance() { + return INSTANCE; + } + + public Boolean hasRead(String key) { + + Map map = markReadMap; + Boolean val = map.get(key); + return val == null ? Boolean.FALSE : val; + } + + public void markRead(String key) { + + markReadMap.put(key, Boolean.TRUE); + } + + @Override + public void readXML(XMLableReader reader) { + + String tagName = reader.getTagName(); + if ("MarkReadMap".equals(tagName)) { + readMarkReadMapXML(reader); + } + } + + @Override + public void writeXML(XMLPrintWriter writer) { + + writer.startTAG(XML_TAG); + writeMarkReadMapXML(writer); + writer.end(); + } + + private void readMarkReadMapXML(XMLableReader reader) { + + reader.readXMLObject(new XMLReadable() { + @Override + public void readXML(XMLableReader reader) { + String tmpVal = reader.getElementValue(); + Boolean markRead = Boolean.valueOf(tmpVal); + markReadMap.put(reader.getAttrAsString("key", StringUtils.EMPTY), markRead); + } + }); + } + + /** + * 写入map + */ + private void writeMarkReadMapXML(XMLPrintWriter writer) { + + writer.startTAG("MarkReadMap"); + for (Map.Entry item : markReadMap.entrySet()) { + writer.startTAG("item").attr("key", item.getKey()).textNode(item.getValue().toString()).end(); + } + writer.end(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + + return super.clone(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/notification/SnapChatKey.java b/designer-base/src/main/java/com/fr/design/notification/SnapChatKey.java new file mode 100644 index 0000000000..fa316db350 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/notification/SnapChatKey.java @@ -0,0 +1,9 @@ +package com.fr.design.notification; + +/** + * created by Harrison on 2020/03/16 + **/ +public interface SnapChatKey { + + String calc(); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index 756a89f564..0a6e692f49 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -22,15 +22,14 @@ import com.fr.design.icon.IconPathConstants; import com.fr.design.mainframe.chart.info.ChartInfoCollector; import com.fr.design.utils.ComponentUtils; import com.fr.form.share.SharableEditorProvider; +import com.fr.form.share.SharableWidgetProvider; import com.fr.form.share.ShareLoader; import com.fr.form.ui.ChartEditor; -import com.fr.form.ui.SharableWidgetBindInfo; import com.fr.form.ui.Widget; import com.fr.stable.Constants; import javax.swing.BorderFactory; import javax.swing.JWindow; -import java.util.Map; import java.awt.Color; import java.awt.Component; import java.awt.Point; @@ -40,6 +39,7 @@ import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; +import java.util.Map; /** * 添加模式下鼠标事件处理器。 @@ -99,7 +99,7 @@ public class FormCreatorDropTarget extends DropTarget { if (addingXCreator.isShared()) { String shareId = addingXCreator.getShareId(); SharableEditorProvider sharableEditor = ShareLoader.getLoader().getSharedElCaseEditorById(shareId); - SharableWidgetBindInfo bindInfo = ShareLoader.getLoader().getElCaseBindInfoById(shareId); + SharableWidgetProvider bindInfo = ShareLoader.getLoader().getElCaseBindInfoById(shareId); if (sharableEditor != null && bindInfo != null) { Map tdNameMap = TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()).addTableData(bindInfo.getName(), sharableEditor.getTableDataSource()); //合并数据集之后,可能会有数据集名称变化,做一下联动 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index c32abb2ffc..ecb3faa706 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -1,14 +1,15 @@ package com.fr.design.mainframe; import com.fr.base.BaseUtils; +import com.fr.base.FRContext; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.widget.FRWidgetFactory; +import com.fr.form.share.SharableWidgetProvider; import com.fr.form.share.ShareLoader; -import com.fr.form.ui.SharableWidgetBindInfo; import com.fr.general.CloudCenter; import com.fr.log.FineLoggerFactory; import com.fr.share.ShareConstants; @@ -50,7 +51,7 @@ public class FormWidgetDetailPane extends FormDockView{ private UIScrollPane downPane; private JPanel reuWidgetPanel; private UIComboBox comboBox; - private SharableWidgetBindInfo[] elCaseBindInfoList; + private SharableWidgetProvider[] elCaseBindInfoList; private UIButton deleteButton; private JPanel editPanel; private JPanel resetPanel; @@ -303,7 +304,7 @@ public class FormWidgetDetailPane extends FormDockView{ public void actionPerformed(ActionEvent e) { String url = CloudCenter.getInstance().acquireUrlByKind("reuse.url"); if (StringUtils.isEmpty(url)) { - FineLoggerFactory.getLogger().info("The URL is empty!"); + FRContext.getLogger().info("The URL is empty!"); return; } try { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index ab19002c18..74c14a6046 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java @@ -6,6 +6,7 @@ import com.fr.base.Parameter; import com.fr.base.extension.FileExtension; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignState; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.FormMobileAttrAction; import com.fr.design.actions.TemplateParameterAction; import com.fr.design.actions.core.WorkBookSupportable; @@ -29,6 +30,7 @@ import com.fr.design.designer.properties.FormWidgetAuthorityEditPane; import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; import com.fr.design.fun.PreviewProvider; +import com.fr.design.fun.PropertyItemPaneProvider; import com.fr.design.gui.frpane.HyperlinkGroupPane; import com.fr.design.gui.frpane.HyperlinkGroupPaneActionProvider; import com.fr.design.gui.ilable.UILabel; @@ -65,6 +67,14 @@ import com.fr.form.ui.container.WLayout; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.page.PaperSettingProvider; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.context.PluginRuntime; +import com.fr.plugin.injectable.PluginModule; +import com.fr.plugin.manage.PluginFilter; +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.cell.Elem; import com.fr.report.cell.cellattr.CellImage; import com.fr.report.worksheet.FormElementCase; @@ -91,6 +101,7 @@ import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.Set; public class JForm extends JTemplate implements BaseJForm
{ private static final String FORM_CARD = "FORM"; @@ -116,12 +127,58 @@ public class JForm extends JTemplate implements BaseJForm providers = runtime.get(PropertyItemPaneProvider.XML_TAG); + for (PropertyItemPaneProvider provider : providers) { + addPane(provider); + } + } + }, filter); + } + + private void initPluginPane() { + + ExtraDesignClassManager classManager = PluginModule.getAgent(PluginModule.ExtraDesign); + Set providers = classManager.getArray(PropertyItemPaneProvider.XML_TAG); + for (PropertyItemPaneProvider provider : providers) { + addPane(provider); + } } - + + private void addPane(PropertyItemPaneProvider provider) { + + PaneHolder holder = provider.getPaneHolder(FormDesigner.class); + if (holder != null) { + JPanel panel = holder.getInstance(formDesign); + EastRegionContainerPane.getInstance().replaceKeyPane(provider.key(), panel); + } + } + @Override public void refreshEastPropertiesPane() { // 暂时用不到,遇到的时候再加刷新右侧tab面板的代码 @@ -765,7 +822,7 @@ public class JForm extends JTemplate implements BaseJForm