From 2d417386939eb6c3cb964749beee92f8abce91f6 Mon Sep 17 00:00:00 2001 From: author Date: Sat, 21 Sep 2019 13:26:09 +0800 Subject: [PATCH] =?UTF-8?q?REPORT-20549=20=E8=BF=9C=E7=A8=8B=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=94=B9=E8=BF=9B=EF=BC=88=E8=AE=BE=E8=AE=A1=E6=9D=83?= =?UTF-8?q?=E9=99=90=E5=8A=A0=E4=B8=8A=E8=A7=92=E8=89=B2=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/file/NodeAuthProcessor.java | 10 +- .../action/RemoteDesignAuthManagerAction.java | 16 +- ...Pane.java => AbstractListControlPane.java} | 64 +-- .../design/remote/ui/AbstractManagerPane.java | 440 ++++++++++++++++++ .../design/remote/ui/AuthorityEditorPane.java | 6 +- .../ui/AuthorityListCustomRolePane.java | 38 ++ .../remote/ui/AuthorityListUserPane.java | 38 ++ .../remote/ui/AuthorityManagerPane.java | 39 +- .../remote/ui/CustomRoleManagerPane.java | 83 ++++ .../fr/design/remote/ui/UserManagerPane.java | 427 ++--------------- .../remote/ui/list/AddedMemberList.java | 21 +- .../ui/list/AddedMemberListCellRender.java | 12 +- .../remote/ui/list/AddingMemberList.java | 21 +- .../ui/list/AddingMemberListCellRender.java | 14 +- .../ui/list/AuthorityListCellRenderer.java | 12 +- .../cell/AddedCustomRoleListCellRender.java | 24 + .../ui/list/cell/AddedUserListCellRender.java | 24 + .../cell/AddingCustomRoleListCellRender.java | 24 + .../list/cell/AddingUserListCellRender.java | 24 + .../AuthorityCustomRoleListCellRender.java | 24 + .../cell/AuthorityUserListCellRender.java | 24 + .../com/fr/design/utils/gui/GUICoreUtils.java | 6 +- .../images/icon_Custom_Role_normal@1x.png | Bin 0 -> 612 bytes .../images/icon_Custom_Role_normal@2x.png | Bin 0 -> 1422 bytes 24 files changed, 929 insertions(+), 462 deletions(-) rename designer-base/src/main/java/com/fr/design/remote/ui/{AuthorityListControlPane.java => AbstractListControlPane.java} (89%) create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/AbstractManagerPane.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListCustomRolePane.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListUserPane.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/CustomRoleManagerPane.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedCustomRoleListCellRender.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedUserListCellRender.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingCustomRoleListCellRender.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingUserListCellRender.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityCustomRoleListCellRender.java create mode 100644 designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityUserListCellRender.java create mode 100644 designer-base/src/main/resources/com/fr/design/remote/images/icon_Custom_Role_normal@1x.png create mode 100644 designer-base/src/main/resources/com/fr/design/remote/images/icon_Custom_Role_normal@2x.png diff --git a/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java b/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java index 01c4615af..2a1c0cc94 100644 --- a/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java +++ b/designer-base/src/main/java/com/fr/design/file/NodeAuthProcessor.java @@ -11,6 +11,7 @@ import com.fr.stable.CoreConstants; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; import com.fr.workspace.server.authority.AuthorityOperator; +import com.fr.workspace.server.authority.decision.DecisionOperator; import java.util.ArrayList; @@ -39,14 +40,15 @@ public class NodeAuthProcessor { authPaths.clear(); if (!WorkContext.getCurrent().isLocal()) { try { - String username = WorkContext.getCurrent().getConnection().getUserName(); - // 远程设计获取全部设计成员的权限列表 - DesignAuthority[] authorities = WorkContext.getCurrent().get(AuthorityOperator.class).getAuthorities(); + String userName = WorkContext.getCurrent().getConnection().getUserName(); + String userId = WorkContext.getCurrent().get(DecisionOperator.class).getUserIdByName(userName); + // 远程设计获取设计成员的权限列表 + DesignAuthority[] authorities = WorkContext.getCurrent().get(AuthorityOperator.class).getAuthorities(userId); DesignAuthority authority = null; if (authorities != null) { for (DesignAuthority designAuthority : authorities) { - if (ComparatorUtils.equals(designAuthority.getUsername(), username)) { + if (ComparatorUtils.equals(designAuthority.getUsername(), userName)) { authority = designAuthority; } } diff --git a/designer-base/src/main/java/com/fr/design/remote/action/RemoteDesignAuthManagerAction.java b/designer-base/src/main/java/com/fr/design/remote/action/RemoteDesignAuthManagerAction.java index ff96907a7..63929685d 100644 --- a/designer-base/src/main/java/com/fr/design/remote/action/RemoteDesignAuthManagerAction.java +++ b/designer-base/src/main/java/com/fr/design/remote/action/RemoteDesignAuthManagerAction.java @@ -9,6 +9,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.remote.ui.AuthorityManagerPane; import com.fr.log.FineLoggerFactory; import com.fr.report.DesignAuthority; +import com.fr.stable.ArrayUtils; import com.fr.workspace.WorkContext; import com.fr.workspace.server.authority.AuthorityOperator; @@ -22,6 +23,7 @@ public class RemoteDesignAuthManagerAction extends UpdateAction { public RemoteDesignAuthManagerAction() { this.setName(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Authority_Manager")); + // 远程设计权限管理 this.setSmallIcon(BaseUtils.readIcon("com/fr/design/remote/images/icon_Remote_Design_Auth_Manager_normal@1x.png")); } @@ -36,9 +38,13 @@ public class RemoteDesignAuthManagerAction extends UpdateAction { if (!WorkContext.getCurrent().isLocal()) { try { // 远程设计获取全部设计成员的权限列表 - DesignAuthority[] authorities = WorkContext.getCurrent().get(AuthorityOperator.class).getAuthorities(); - if (authorities != null && authorities.length != 0) { - managerPane.populate(authorities); + DesignAuthority[] userAuthorities = WorkContext.getCurrent().get(AuthorityOperator.class).getUserAuthorities(); + DesignAuthority[] customAuthorities = WorkContext.getCurrent().get(AuthorityOperator.class).getCustomRoleAuthorities(); + if (userAuthorities != null && userAuthorities.length != 0) { + managerPane.populateByUser(userAuthorities); + } + if (customAuthorities != null && customAuthorities.length != 0) { + managerPane.populateByCustom(customAuthorities); } } catch (Exception exception) { FineLoggerFactory.getLogger().error(exception.getMessage(), exception); @@ -49,7 +55,9 @@ public class RemoteDesignAuthManagerAction extends UpdateAction { @Override public void doOk() { - DesignAuthority[] authorities = managerPane.update(); + DesignAuthority[] userAuthorities = managerPane.updateByUser(); + DesignAuthority[] customRoleAuthorities = managerPane.updateByCustom(); + DesignAuthority[] authorities = ArrayUtils.addAll(userAuthorities, customRoleAuthorities); if (!WorkContext.getCurrent().isLocal()) { boolean success = false; try { diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListControlPane.java b/designer-base/src/main/java/com/fr/design/remote/ui/AbstractListControlPane.java similarity index 89% rename from designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListControlPane.java rename to designer-base/src/main/java/com/fr/design/remote/ui/AbstractListControlPane.java index 1d027ac8a..c41e4800a 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListControlPane.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/AbstractListControlPane.java @@ -40,10 +40,15 @@ import java.awt.event.ActionEvent; import java.util.ArrayList; import java.util.List; -public class AuthorityListControlPane extends BasicPane { +/** + * 左侧面板的基类 + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2019/9/19 + */ +public abstract class AbstractListControlPane extends BasicPane { - - private static final String LIST_NAME = "AuthorityListControlPaneList"; + private static final String LIST_NAME = "AbstractListControlPane"; private static final String UNSELECTED_EDITOR_NAME = "UNSELECTED"; private static final String SELECTED_EDITOR_NAME = "SELECTED"; @@ -68,7 +73,7 @@ public class AuthorityListControlPane extends BasicPane { private UIToolbar toolBar; - public AuthorityListControlPane() { + public AbstractListControlPane() { super(); initComponentPane(); } @@ -76,13 +81,8 @@ public class AuthorityListControlPane extends BasicPane { private void initComponentPane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - this.authorityCreators = new RemoteDesignAuthorityCreator[]{ - new RemoteDesignAuthorityCreator( - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_User"), - BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"), - DesignAuthority.class, - AuthorityEditorPane.class) - }; + this.authorityCreators = getAuthorityCreators(); + editorCtrl = new ListEditorControlPane(); // 左侧列表面板 @@ -107,6 +107,7 @@ public class AuthorityListControlPane extends BasicPane { checkButtonEnabled(); } + protected abstract RemoteDesignAuthorityCreator[] getAuthorityCreators(); private void initLeftToolbar(JPanel leftPane) { shortCuts = createShortcuts(); @@ -139,17 +140,19 @@ public class AuthorityListControlPane extends BasicPane { if (hasInvalid()) { return; } - AuthorityListControlPane.this.editorCtrl.update(); - AuthorityListControlPane.this.editorCtrl.populate(); - AuthorityListControlPane.this.checkButtonEnabled(); + AbstractListControlPane.this.editorCtrl.update(); + AbstractListControlPane.this.editorCtrl.populate(); + AbstractListControlPane.this.checkButtonEnabled(); } } }); } + protected abstract AuthorityListCellRenderer getAuthorityListCellRender(); + private AuthorityList createList() { AuthorityList list = new AuthorityList(new DefaultListModel()); - list.setCellRenderer(new AuthorityListCellRenderer()); + list.setCellRenderer(getAuthorityListCellRender()); return list; } @@ -168,7 +171,9 @@ public class AuthorityListControlPane extends BasicPane { this.editorCtrl.update(); DefaultListModel listModel = (DefaultListModel) this.authorityList.getModel(); for (int i = 0, len = listModel.getSize(); i < len; i++) { - res.add((DesignAuthority) listModel.getElementAt(i)); + DesignAuthority authority = (DesignAuthority) listModel.getElementAt(i); +// authority.setRoleType(RoleType.USER); + res.add(authority); } return res.toArray(new DesignAuthority[res.size()]); } @@ -315,7 +320,7 @@ public class AuthorityListControlPane extends BasicPane { public void checkEnable() { this.shortCut.setEnabled(authorityList.getModel() .getSize() > 0 - && AuthorityListControlPane.this.authorityList.getSelectedIndex() != -1); + && AbstractListControlPane.this.authorityList.getSelectedIndex() != -1); } } @@ -356,13 +361,13 @@ public class AuthorityListControlPane extends BasicPane { } private boolean hasInvalid() { - int idx = AuthorityListControlPane.this.getInValidIndex(); + int idx = AbstractListControlPane.this.getInValidIndex(); if (authorityList.getSelectedIndex() != idx) { try { checkValid(); } catch (Exception exp) { FineLoggerFactory.getLogger().error(exp.getMessage(), exp); - JOptionPane.showMessageDialog(AuthorityListControlPane.this, exp.getMessage()); + JOptionPane.showMessageDialog(AbstractListControlPane.this, exp.getMessage()); authorityList.setSelectedIndex(idx); return true; } @@ -442,7 +447,7 @@ public class AuthorityListControlPane extends BasicPane { } public void populate() { - authority = AuthorityListControlPane.this.authorityList.getSelectedValue(); + authority = AbstractListControlPane.this.authorityList.getSelectedValue(); if (authority == null) { return; @@ -485,6 +490,10 @@ public class AuthorityListControlPane extends BasicPane { } } + protected abstract AbstractManagerPane getManagerPane(); + + protected abstract String getKey(); + /** * 选择按钮 */ @@ -498,17 +507,17 @@ public class AuthorityListControlPane extends BasicPane { @Override public void actionPerformed(ActionEvent e) { - final UserManagerPane userManagerPane = new UserManagerPane(); - BasicDialog dialog = userManagerPane.showWindow(SwingUtilities.getWindowAncestor(AuthorityListControlPane.this)); + final AbstractManagerPane managerPane = getManagerPane(); + BasicDialog dialog = managerPane.showWindow(SwingUtilities.getWindowAncestor(AbstractListControlPane.this)); // 刷新用户管理面板展示信息 - final DesignAuthority[] authorities = AuthorityListControlPane.this.update(); + final DesignAuthority[] authorities = AbstractListControlPane.this.update(); dialog.addDialogActionListener(new DialogActionAdapter() { @Override public void doOk() { // 获取添加的用户到权限编辑面板 - List members = userManagerPane.update(); + List members = managerPane.update(); List oldAuthorities = new ArrayList<>(); @@ -529,6 +538,7 @@ public class AuthorityListControlPane extends BasicPane { authority.setUsername(member.getUsername()); authority.setUserId(member.getUserId()); authority.setRealName(member.getRealName()); + authority.setRoleType(member.getRoleType()); addAuthority(authority, getModel().getSize()); } @@ -543,9 +553,11 @@ public class AuthorityListControlPane extends BasicPane { m.setUserId(authority.getUserId()); m.setRealName(authority.getRealName()); m.setSelected(true); + m.setRoleType(authority.getRoleType()); + m.setAuthority(true); members.add(m); } - userManagerPane.populate(members); + managerPane.populate(members); dialog.setModal(true); dialog.setVisible(true); @@ -567,7 +579,7 @@ public class AuthorityListControlPane extends BasicPane { public void actionPerformed(ActionEvent evt) { doBeforeRemove(); if (GUICoreUtils.removeJListSelectedNodes(SwingUtilities - .getWindowAncestor(AuthorityListControlPane.this), authorityList)) { + .getWindowAncestor(AbstractListControlPane.this), authorityList, getKey())) { checkButtonEnabled(); doAfterRemove(); } diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/AbstractManagerPane.java b/designer-base/src/main/java/com/fr/design/remote/ui/AbstractManagerPane.java new file mode 100644 index 000000000..1b8b71dc4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/AbstractManagerPane.java @@ -0,0 +1,440 @@ +package com.fr.design.remote.ui; + +import com.fr.base.BaseUtils; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.remote.ui.list.AddedMemberList; +import com.fr.design.remote.ui.list.AddedMemberListCellRender; +import com.fr.design.remote.ui.list.AddingMemberList; +import com.fr.design.remote.ui.list.AddingMemberListCellRender; +import com.fr.design.remote.ui.list.MemberListSelectedChangeListener; +import com.fr.stable.StringUtils; +import com.fr.third.guava.collect.ImmutableList; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.authority.RemoteDesignMember; + +import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; +import javax.swing.JPanel; +import javax.swing.JViewport; +import javax.swing.ListSelectionModel; +import javax.swing.SwingWorker; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + + +/** + * 选择设计角色、用户面板的基类 + * @author yaohwu + */ +public abstract class AbstractManagerPane extends BasicPane { + + /** + * 每页个数 + */ + private static final int DEFAULT_NUM_EACH_PAGE = 50; + + /** + * 获取的决策平台用户 + */ + private final List addingMembers = new ArrayList<>(); + /** + * 添加到设计的决策平台用户 + */ + private List addedMembers = new ArrayList<>(); + + /** + * 决策平台用户列表model + */ + private DefaultListModel addingListModel = new DefaultListModel<>(); + /** + * 搜索输入框 + */ + private UITextField keyField = new UITextField(); + /** + * 搜索按钮 + */ + private UIButton keyButton = new UIButton(); + + /** + * 搜索按钮绑定事件 + */ + private ActionListener keyButtonActionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + searchAddingMembers(keyWord); + } + }; + + /** + * 输入框绑定事件 + */ + private KeyAdapter keyFieldKeyListener = new KeyAdapter() { + + @Override + public void keyPressed(KeyEvent e) { + // 判断按下的键是否是回车键 + // 对话框回车键绑定的是对话框的确定按钮 + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + searchAddingMembers(keyWord); + // has been processed + e.consume(); + } + } + }; + /** + * 添加到设计的决策用户计数标签 + */ + private UILabel countLabel = new UILabel(); + /** + * 添加到设计的决策用户计数标签 + */ + private DefaultListModel addedListModel; + + + /** + * 左侧列表变动事件 + */ + private MemberListSelectedChangeListener addingListChangeListener = new MemberListSelectedChangeListener() { + @Override + public void selectedChange() { + sync2AddedMembersFromAdding(); + // 刷新右侧列表显示 + addToAddedMemberList(); + } + }; + + /** + * 右侧列表变动事件 + */ + private MemberListSelectedChangeListener addedListChangeListener = new MemberListSelectedChangeListener() { + @Override + public void selectedChange() { + addingList.revalidate(); + addingList.repaint(); + resetAddedMembers(); + sync2AddedMembersFormAdded(); + // 不需要重复更新右侧列表显示 但是更新一下计数显示 + countLabel.setText( + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Member_Count", + String.valueOf(addedMembers.size()) + ) + ); + // 刷新左侧列表显示 + addToMemberList(); + } + }; + + + /** + * 已经添加的用户列表 + */ + private AddedMemberList addedList; + /** + * 待添加的用户列表 + */ + private AddingMemberList addingList; + + /** + * 搜索关键字 + */ + private String keyWord; + + /** + * 搜索关键词变更监听 + */ + private transient DocumentListener documentListener = new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + keyWord = keyField.getText(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + keyWord = keyField.getText(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + keyWord = keyField.getText(); + } + }; + + /** + * 当前分页计数 + */ + private int pageNum = 1; + + + public AbstractManagerPane() { + this.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4)); + this.setLayout(new BorderLayout()); + this.add( + TableLayoutHelper.createCommonTableLayoutPane( + new Component[][]{ + new Component[]{createLeftPanel(), createRightPanel()} + }, + new double[]{TableLayout.FILL}, + new double[]{TableLayout.FILL, TableLayout.FILL}, + LayoutConstants.VGAP_LARGE + ), + BorderLayout.CENTER); + } + + public void populate(List addedMembers) { + + // 已选信息 + resetAddedMembers(); + this.addedMembers.addAll(addedMembers); + + // 刷新右侧面板 + addToAddedMemberList(); + + // 刷新左侧展示信息 + addToMemberList(); + } + + + @Override + protected String title4PopupWindow() { + // 选择设计用户 + return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Choose_User"); + } + + protected abstract JPanel leftPanel(); + + private JPanel createLeftPanel() { + JPanel content = leftPanel(); + + // 搜索 + JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); + searchPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); + keyField.setPreferredSize(new Dimension(270, 20)); + keyField.requestFocus(); + keyField.addKeyListener(keyFieldKeyListener); + keyField.getDocument().addDocumentListener(documentListener); + keyButton.setIcon(BaseUtils.readIcon("com/fr/design/images/buttonicon/user_search_normal.png")); + keyButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Search")); + keyButton.addActionListener(keyButtonActionListener); + searchPanel.add(keyField); + searchPanel.add(keyButton); + + // 内容列表 + addingListModel = new DefaultListModel<>(); + addingList = new AddingMemberList(addingListModel); + addingList.setCellRenderer(getAddingMemberListCellRender()); + addingList.addSelectedChangeListener(addingListChangeListener); + resetMembers(); + addToMemberList(); + searchAddingMembers(StringUtils.EMPTY); + final UIScrollPane listPane = new UIScrollPane(addingList); + listPane.addMouseWheelListener(new MouseWheelListener() { + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + JViewport vp = listPane.getViewport(); + if (vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y) { + loadMoreAddingMembers(keyWord, DEFAULT_NUM_EACH_PAGE); + } + } + }); + listPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { + @Override + public void adjustmentValueChanged(AdjustmentEvent e) { + JViewport vp = listPane.getViewport(); + if (vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y && e.getValueIsAdjusting()) { + loadMoreAddingMembers(keyWord, DEFAULT_NUM_EACH_PAGE); + } + } + }); + listPane.setBorder(BorderFactory.createEmptyBorder()); + + content.add(searchPanel, BorderLayout.NORTH); + content.add(listPane, BorderLayout.CENTER); + return content; + } + + protected abstract AddingMemberListCellRender getAddingMemberListCellRender(); + + protected abstract AddedMemberListCellRender getAddedMemberListCellRender(); + + protected abstract JPanel rightPanel(); + + private JPanel createRightPanel() { + JPanel content = rightPanel(); + + // 计数 + countLabel.setText( + // 已选择{}人 + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Member_Count", + String.valueOf(addedMembers.size())) + ); + countLabel.setBorder(BorderFactory.createEmptyBorder(7, 12, 8, 0)); + countLabel.setForeground(new Color(0x8F8F92)); + + addedListModel = new DefaultListModel<>(); + addedList = new AddedMemberList(addedListModel); + addedList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + addedList.setCellRenderer(getAddedMemberListCellRender()); + addedList.addSelectedChangeListener(addedListChangeListener); + resetAddedMembers(); + addToAddedMemberList(); + UIScrollPane listPane = new UIScrollPane(addedList); + listPane.setBorder(BorderFactory.createEmptyBorder()); + + content.add(countLabel, BorderLayout.NORTH); + content.add(listPane, BorderLayout.CENTER); + return content; + + } + + + private void addToMemberList() { + addingListModel.clear(); + for (RemoteDesignMember member : addingMembers) { + // 如果包含在右侧列表中,那么左侧列表默认选中 + if (addedMembers.contains(member)) { + member.setAuthority(true); + member.setSelected(true); + } else { + member.setAuthority(false); + member.setSelected(false); + } + addingListModel.addElement(member); + } + addingList.revalidate(); + addingList.repaint(); + } + + private void addToAddedMemberList() { + addedListModel.clear(); + for (RemoteDesignMember member : addedMembers) { + addedListModel.addElement(member); + } + addedList.revalidate(); + addedList.repaint(); + countLabel.setText( + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Member_Count", + String.valueOf(addedMembers.size()) + )); + } + + private void resetMembers() { + addingMembers.clear(); + addingMembers.add(RemoteDesignMember.DEFAULT_MEMBER); + } + + private void resetAddedMembers() { + addedMembers.clear(); + } + + protected abstract Collection getMembers(String userName, String keyWord); + + protected abstract Collection getMembers(String userName, String keyWord, int pageNum, int count); + + private void searchAddingMembers(final String keyword) { + + final SwingWorker getMemberWorker = new SwingWorker, Void>() { + @Override + protected List doInBackground() { + String username = WorkContext.getCurrent().getConnection().getUserName(); + synchronized (addingMembers) { + addingMembers.clear(); + Collection more = getMembers(username, keyword); + pageNum = 1; + if (!more.isEmpty()) { + addingMembers.addAll(more); + if (more.size() >= DEFAULT_NUM_EACH_PAGE) { + addingMembers.add(RemoteDesignMember.DEFAULT_MEMBER); + } + } + } + return addingMembers; + } + + @Override + protected void done() { + addToMemberList(); + } + }; + getMemberWorker.execute(); + } + + private void loadMoreAddingMembers(final String keyword, final int count) { + + final SwingWorker loadMoreWorker = new SwingWorker, Void>() { + @Override + protected List doInBackground() { + + String username = WorkContext.getCurrent().getConnection().getUserName(); + synchronized (addingMembers) { + addingMembers.remove(RemoteDesignMember.DEFAULT_MEMBER); + Collection more = getMembers(username, keyword, pageNum + 1, count); + if (!more.isEmpty()) { + pageNum += 1; + addingMembers.addAll(more); + addingMembers.add(RemoteDesignMember.DEFAULT_MEMBER); + } + } + return addingMembers; + } + + @Override + protected void done() { + addToMemberList(); + } + }; + loadMoreWorker.execute(); + } + + + private void sync2AddedMembersFromAdding() { + RemoteDesignMember[] members = new RemoteDesignMember[addingListModel.getSize()]; + // shallow copy + addingListModel.copyInto(members); + for (RemoteDesignMember member : members) { + + if (!member.isSelected()) { + addedMembers.remove(member); + } + if (member.isSelected() && !addedMembers.contains(member)) { + addedMembers.add(member); + } + } + } + + private void sync2AddedMembersFormAdded() { + RemoteDesignMember[] members = new RemoteDesignMember[addedListModel.getSize()]; + // shallow copy + addedListModel.copyInto(members); + addedMembers.addAll(Arrays.asList(members)); + } + + + public ImmutableList update() { + return ImmutableList.copyOf(addedMembers); + } +} diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityEditorPane.java b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityEditorPane.java index eaa96f330..26fc0c28a 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityEditorPane.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityEditorPane.java @@ -19,12 +19,15 @@ import java.awt.BorderLayout; import java.util.ArrayList; import java.util.List; +/** + * 右面板 + */ public class AuthorityEditorPane extends BasicBeanPane { private FileAuthorityTree tree = new FileAuthorityTree(); - + // 模板设计权限配置 public AuthorityEditorPane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setBorder( @@ -47,6 +50,7 @@ public class AuthorityEditorPane extends BasicBeanPane { @Override protected String title4PopupWindow() { + // 编辑文件权限 return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Configure_Authority"); } diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListCustomRolePane.java b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListCustomRolePane.java new file mode 100644 index 000000000..3ae6a097b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListCustomRolePane.java @@ -0,0 +1,38 @@ +package com.fr.design.remote.ui; + +import com.fr.base.BaseUtils; +import com.fr.design.i18n.Toolkit; +import com.fr.design.remote.RemoteDesignAuthorityCreator; +import com.fr.design.remote.ui.list.AuthorityListCellRenderer; +import com.fr.design.remote.ui.list.cell.AuthorityCustomRoleListCellRender; +import com.fr.report.DesignAuthority; + +public class AuthorityListCustomRolePane extends AbstractListControlPane { + + @Override + protected RemoteDesignAuthorityCreator[] getAuthorityCreators() { + return new RemoteDesignAuthorityCreator[]{ + new RemoteDesignAuthorityCreator( + // 远程设计用户 + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Custom"), + BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"), + DesignAuthority.class, + AuthorityEditorPane.class) + }; + } + + @Override + protected AuthorityListCellRenderer getAuthorityListCellRender() { + return new AuthorityCustomRoleListCellRender(); + } + + @Override + protected AbstractManagerPane getManagerPane() { + return new CustomRoleManagerPane(); + } + + @Override + protected String getKey() { + return "Fine-Design_Basic_Utils_Are_You_Sure_To_Delete_The_Role_And_Its_Design_Authorities"; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListUserPane.java b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListUserPane.java new file mode 100644 index 000000000..ccc85049a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityListUserPane.java @@ -0,0 +1,38 @@ +package com.fr.design.remote.ui; + +import com.fr.base.BaseUtils; +import com.fr.design.i18n.Toolkit; +import com.fr.design.remote.RemoteDesignAuthorityCreator; +import com.fr.design.remote.ui.list.AuthorityListCellRenderer; +import com.fr.design.remote.ui.list.cell.AuthorityUserListCellRender; +import com.fr.report.DesignAuthority; + +public class AuthorityListUserPane extends AbstractListControlPane { + + @Override + protected RemoteDesignAuthorityCreator[] getAuthorityCreators() { + return new RemoteDesignAuthorityCreator[]{ + new RemoteDesignAuthorityCreator( + // 远程设计用户 + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_User"), + BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"), + DesignAuthority.class, + AuthorityEditorPane.class) + }; + } + + @Override + protected AuthorityListCellRenderer getAuthorityListCellRender() { + return new AuthorityUserListCellRender(); + } + + @Override + protected AbstractManagerPane getManagerPane() { + return new UserManagerPane(); + } + + @Override + protected String getKey() { + return "Fine-Design_Basic_Utils_Are_You_Sure_To_Delete_The_User_And_Its_Design_Authorities"; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityManagerPane.java b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityManagerPane.java index 7dbf8ed4e..2e68cd27a 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityManagerPane.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/AuthorityManagerPane.java @@ -1,36 +1,51 @@ package com.fr.design.remote.ui; import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; import com.fr.report.DesignAuthority; -import javax.swing.BorderFactory; import java.awt.BorderLayout; public class AuthorityManagerPane extends BasicPane { - private AuthorityListControlPane list; - + private AuthorityListUserPane userList = new AuthorityListUserPane(); + private AuthorityListCustomRolePane roleList = new AuthorityListCustomRolePane(); public AuthorityManagerPane() { - this.setLayout(new BorderLayout()); - this.setBorder(BorderFactory.createEmptyBorder()); - list = new AuthorityListControlPane(); - this.add(list, BorderLayout.CENTER); - } + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + //Tabbed Pane + UITabbedPane tabbedPane = new UITabbedPane(); + this.add(tabbedPane, BorderLayout.CENTER); + tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_User"), userList); + tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Role"), roleList); + + } @Override protected String title4PopupWindow() { + // 远程设计权限管理 return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Authority_Manager"); } - public void populate(DesignAuthority[] authorities) { - list.populate(authorities); + public void populateByUser(DesignAuthority[] authorities) { + userList.populate(authorities); } - public DesignAuthority[] update() { - return list.update(); + public void populateByCustom(DesignAuthority[] authorities) { + roleList.populate(authorities); } + + public DesignAuthority[] updateByUser() { + return userList.update(); + } + + public DesignAuthority[] updateByCustom() { + return roleList.update(); + } + } diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/CustomRoleManagerPane.java b/designer-base/src/main/java/com/fr/design/remote/ui/CustomRoleManagerPane.java new file mode 100644 index 000000000..eeedd6eca --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/CustomRoleManagerPane.java @@ -0,0 +1,83 @@ +package com.fr.design.remote.ui; + +import com.fr.design.border.UITitledBorder; +import com.fr.design.i18n.Toolkit; +import com.fr.design.remote.ui.list.AddedMemberListCellRender; +import com.fr.design.remote.ui.list.AddingMemberListCellRender; +import com.fr.design.remote.ui.list.cell.AddedCustomRoleListCellRender; +import com.fr.design.remote.ui.list.cell.AddingCustomRoleListCellRender; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.authority.RemoteDesignMember; +import com.fr.workspace.server.authority.decision.DecisionOperator; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import java.awt.BorderLayout; +import java.util.Collection; + + +/** + * 选择设计角色 + */ +public class CustomRoleManagerPane extends AbstractManagerPane { + + @Override + protected String title4PopupWindow() { + // 选择设计角色 + return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Choose_Custom"); + } + + @Override + protected JPanel rightPanel(){ + JPanel content = new JPanel(new BorderLayout()); + + content.setBorder( + BorderFactory.createCompoundBorder( + new EmptyBorder(6, 0, 0, 0), + UITitledBorder.createBorderWithTitle( + // 已选择的设计角色 + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Custom"), + 4 + ) + ) + ); + return content; + } + + @Override + protected JPanel leftPanel(){ + JPanel content = new JPanel(new BorderLayout()); + + content.setBorder( + BorderFactory.createCompoundBorder( + new EmptyBorder(6, 0, 0, 0), + UITitledBorder.createBorderWithTitle( + // 决策系统角色 + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Decision_Custom"), + 4) + ) + ); + return content; + } + + @Override + protected AddingMemberListCellRender getAddingMemberListCellRender() { + return new AddingCustomRoleListCellRender(); + } + + @Override + protected AddedMemberListCellRender getAddedMemberListCellRender() { + return new AddedCustomRoleListCellRender(); + } + + @Override + protected Collection getMembers(String userName, String keyWord){ + return WorkContext.getCurrent().get(DecisionOperator.class).getCustoms(userName, keyWord); + } + + @Override + protected Collection getMembers(String userName, String keyWord, int pageNum, int count){ + return WorkContext.getCurrent().get(DecisionOperator.class).getCustoms(userName, keyWord, pageNum, count); + } +} diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/UserManagerPane.java b/designer-base/src/main/java/com/fr/design/remote/ui/UserManagerPane.java index 8b8688e99..900f98031 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/UserManagerPane.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/UserManagerPane.java @@ -1,450 +1,83 @@ package com.fr.design.remote.ui; -import com.fr.base.BaseUtils; import com.fr.design.border.UITitledBorder; -import com.fr.design.constants.LayoutConstants; -import com.fr.design.dialog.BasicPane; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.gui.icontainer.UIScrollPane; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itextfield.UITextField; import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.remote.ui.list.AddedMemberList; import com.fr.design.remote.ui.list.AddedMemberListCellRender; -import com.fr.design.remote.ui.list.AddingMemberList; import com.fr.design.remote.ui.list.AddingMemberListCellRender; -import com.fr.design.remote.ui.list.MemberListSelectedChangeListener; -import com.fr.stable.StringUtils; -import com.fr.third.guava.collect.ImmutableList; +import com.fr.design.remote.ui.list.cell.AddedUserListCellRender; +import com.fr.design.remote.ui.list.cell.AddingUserListCellRender; import com.fr.workspace.WorkContext; import com.fr.workspace.server.authority.RemoteDesignMember; import com.fr.workspace.server.authority.decision.DecisionOperator; import javax.swing.BorderFactory; -import javax.swing.DefaultListModel; import javax.swing.JPanel; -import javax.swing.JViewport; -import javax.swing.ListSelectionModel; -import javax.swing.SwingWorker; import javax.swing.border.EmptyBorder; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.AdjustmentEvent; -import java.awt.event.AdjustmentListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; -import java.util.List; /** - * @author yaohwu + * 选择设计用户 */ -public class UserManagerPane extends BasicPane { - - /** - * 每页个数 - */ - private static final int DEFAULT_NUM_EACH_PAGE = 50; - - /** - * 获取的决策平台成员 - */ - private final List addingMembers = new ArrayList<>(); - /** - * 添加到设计的决策平台成员 - */ - private List addedMembers = new ArrayList<>(); - - /** - * 决策平台成员列表model - */ - private DefaultListModel addingListModel = new DefaultListModel<>(); - /** - * 搜索输入框 - */ - private UITextField keyField = new UITextField(); - /** - * 搜索按钮 - */ - private UIButton keyButton = new UIButton(); - - /** - * 搜索按钮绑定事件 - */ - private ActionListener keyButtonActionListener = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - searchAddingMembers(keyWord); - } - }; - - /** - * 输入框绑定事件 - */ - private KeyAdapter keyFieldKeyListener = new KeyAdapter() { - - @Override - public void keyPressed(KeyEvent e) { - // 判断按下的键是否是回车键 - // 对话框回车键绑定的是对话框的确定按钮 - if (e.getKeyCode() == KeyEvent.VK_ENTER) { - searchAddingMembers(keyWord); - // has been processed - e.consume(); - } - } - }; - /** - * 添加到设计的决策成员计数标签 - */ - private UILabel countLabel = new UILabel(); - /** - * 添加到设计的决策成员计数标签 - */ - private DefaultListModel addedListModel; - - - /** - * 左侧列表变动事件 - */ - private MemberListSelectedChangeListener addingListChangeListener = new MemberListSelectedChangeListener() { - @Override - public void selectedChange() { - // 右侧列表发生变化后,将右侧列表中选中但是在左侧列表中没有的成员添加进来,同时移除取消选中的 - sync2AddedMembersFromAdding(); - // 刷新右侧列表显示 - addToAddedMemberList(); - } - }; - - /** - * 右侧列表变动事件 - */ - private MemberListSelectedChangeListener addedListChangeListener = new MemberListSelectedChangeListener() { - @Override - public void selectedChange() { - addingList.revalidate(); - addingList.repaint(); - resetAddedMembers(); - sync2AddedMembersFormAdded(); - // 不需要重复更新右侧列表显示 但是更新一下计数显示 - countLabel.setText( - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Member_Count", - String.valueOf(addedMembers.size()) - ) - ); - // 刷新左侧列表显示 - addToMemberList(); - - } - }; - - - /** - * 已经添加的成员列表 - */ - private AddedMemberList addedList; - /** - * 待添加的成员列表 - */ - private AddingMemberList addingList; - - /** - * 搜索关键字 - */ - private String keyWord; - - /** - * 搜索关键词变更监听 - */ - private transient DocumentListener documentListener = new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - keyWord = keyField.getText(); - } - - @Override - public void removeUpdate(DocumentEvent e) { - keyWord = keyField.getText(); - } - - @Override - public void changedUpdate(DocumentEvent e) { - keyWord = keyField.getText(); - } - }; - - /** - * 当前分页计数 - */ - private int pageNum = 1; - - - public UserManagerPane() { - this.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4)); - this.setLayout(new BorderLayout()); - this.add( - TableLayoutHelper.createCommonTableLayoutPane( - new Component[][]{ - new Component[]{createLeftPanel(), createRightPanel()} - }, - new double[]{TableLayout.FILL}, - new double[]{TableLayout.FILL, TableLayout.FILL}, - LayoutConstants.VGAP_LARGE - ), - BorderLayout.CENTER); - } - - public void populate(List addedMembers) { - - // 已选信息 - resetAddedMembers(); - this.addedMembers.addAll(addedMembers); - - // 刷新右侧面板 - addToAddedMemberList(); - - // 刷新左侧展示信息 - addToMemberList(); - } - +public class UserManagerPane extends AbstractManagerPane { @Override protected String title4PopupWindow() { - return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Choose_Member"); + // 选择设计用户 + return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Choose_User"); } - private JPanel createLeftPanel() { + @Override + protected JPanel rightPanel(){ JPanel content = new JPanel(new BorderLayout()); content.setBorder( BorderFactory.createCompoundBorder( new EmptyBorder(6, 0, 0, 0), UITitledBorder.createBorderWithTitle( - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Decision_Member"), - 4) + // 已选择的设计用户 + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_User"), + 4 + ) ) ); - - // 搜索 - JPanel searchPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5)); - searchPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); - keyField.setPreferredSize(new Dimension(270, 20)); - keyField.requestFocus(); - keyField.addKeyListener(keyFieldKeyListener); - keyField.getDocument().addDocumentListener(documentListener); - keyButton.setIcon(BaseUtils.readIcon("com/fr/design/images/buttonicon/user_search_normal.png")); - keyButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Search")); - keyButton.addActionListener(keyButtonActionListener); - searchPanel.add(keyField); - searchPanel.add(keyButton); - - // 内容列表 - addingListModel = new DefaultListModel<>(); - addingList = new AddingMemberList(addingListModel); - addingList.setCellRenderer(new AddingMemberListCellRender()); - addingList.addSelectedChangeListener(addingListChangeListener); - resetMembers(); - addToMemberList(); - searchAddingMembers(StringUtils.EMPTY); - final UIScrollPane listPane = new UIScrollPane(addingList); - listPane.addMouseWheelListener(new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - JViewport vp = listPane.getViewport(); - if (vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y) { - loadMoreAddingMembers(keyWord, DEFAULT_NUM_EACH_PAGE); - } - } - }); - listPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { - @Override - public void adjustmentValueChanged(AdjustmentEvent e) { - JViewport vp = listPane.getViewport(); - if (vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y && e.getValueIsAdjusting()) { - loadMoreAddingMembers(keyWord, DEFAULT_NUM_EACH_PAGE); - } - } - }); - listPane.setBorder(BorderFactory.createEmptyBorder()); - - content.add(searchPanel, BorderLayout.NORTH); - content.add(listPane, BorderLayout.CENTER); return content; } - - private JPanel createRightPanel() { + @Override + protected JPanel leftPanel(){ JPanel content = new JPanel(new BorderLayout()); content.setBorder( BorderFactory.createCompoundBorder( new EmptyBorder(6, 0, 0, 0), UITitledBorder.createBorderWithTitle( - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Member"), - 4 - ) + // 决策系统用户 + Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Decision_User"), + 4) ) ); - - // 计数 - countLabel.setText( - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Member_Count", - String.valueOf(addedMembers.size())) - ); - countLabel.setBorder(BorderFactory.createEmptyBorder(7, 12, 8, 0)); - countLabel.setForeground(new Color(0x8F8F92)); - - addedListModel = new DefaultListModel<>(); - addedList = new AddedMemberList(addedListModel); - addedList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - addedList.setCellRenderer(new AddedMemberListCellRender()); - addedList.addSelectedChangeListener(addedListChangeListener); - resetAddedMembers(); - addToAddedMemberList(); - UIScrollPane listPane = new UIScrollPane(addedList); - listPane.setBorder(BorderFactory.createEmptyBorder()); - - content.add(countLabel, BorderLayout.NORTH); - content.add(listPane, BorderLayout.CENTER); return content; - } - - private void addToMemberList() { - addingListModel.clear(); - for (RemoteDesignMember member : addingMembers) { - // 如果包含在右侧列表中,那么左侧列表默认选中 - if (addedMembers.contains(member)) { - member.setSelected(true); - } else { - member.setSelected(false); - } - addingListModel.addElement(member); - } - addingList.revalidate(); - addingList.repaint(); - } - - private void addToAddedMemberList() { - addedListModel.clear(); - for (RemoteDesignMember member : addedMembers) { - addedListModel.addElement(member); - } - addedList.revalidate(); - addedList.repaint(); - countLabel.setText( - Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Selected_Member_Count", - String.valueOf(addedMembers.size()) - )); - } - - private void resetMembers() { - addingMembers.clear(); - addingMembers.add(RemoteDesignMember.DEFAULT_MEMBER); - } - - private void resetAddedMembers() { - addedMembers.clear(); - } - - - private void searchAddingMembers(final String keyword) { - - final SwingWorker getMemberWorker = new SwingWorker, Void>() { - @Override - protected List doInBackground() { - String username = WorkContext.getCurrent().getConnection().getUserName(); - synchronized (addingMembers) { - addingMembers.clear(); - Collection more = WorkContext.getCurrent().get(DecisionOperator.class).getMembers(username, keyword); - pageNum = 1; - if (!more.isEmpty()) { - addingMembers.addAll(more); - if (more.size() >= DEFAULT_NUM_EACH_PAGE) { - addingMembers.add(RemoteDesignMember.DEFAULT_MEMBER); - } - } - } - return addingMembers; - } - - @Override - protected void done() { - addToMemberList(); - } - }; - getMemberWorker.execute(); - } - - private void loadMoreAddingMembers(final String keyword, final int count) { - - final SwingWorker loadMoreWorker = new SwingWorker, Void>() { - @Override - protected List doInBackground() { - - String username = WorkContext.getCurrent().getConnection().getUserName(); - synchronized (addingMembers) { - addingMembers.remove(RemoteDesignMember.DEFAULT_MEMBER); - Collection more = - WorkContext.getCurrent().get(DecisionOperator.class).getMembers(username, keyword, pageNum + 1, count); - if (!more.isEmpty()) { - pageNum += 1; - addingMembers.addAll(more); - addingMembers.add(RemoteDesignMember.DEFAULT_MEMBER); - } - } - return addingMembers; - } - - @Override - protected void done() { - addToMemberList(); - } - }; - loadMoreWorker.execute(); + @Override + protected AddingMemberListCellRender getAddingMemberListCellRender() { + return new AddingUserListCellRender(); } - - private void sync2AddedMembersFromAdding() { - RemoteDesignMember[] members = new RemoteDesignMember[addingListModel.getSize()]; - // shallow copy - addingListModel.copyInto(members); - for (RemoteDesignMember member : members) { - - if (!member.isSelected()) { - addedMembers.remove(member); - } - if (member.isSelected() && !addedMembers.contains(member)) { - addedMembers.add(member); - } - } + @Override + protected AddedMemberListCellRender getAddedMemberListCellRender() { + return new AddedUserListCellRender(); } - private void sync2AddedMembersFormAdded() { - RemoteDesignMember[] members = new RemoteDesignMember[addedListModel.getSize()]; - // shallow copy - addedListModel.copyInto(members); - addedMembers.addAll(Arrays.asList(members)); + @Override + protected Collection getMembers(String userName, String keyWord){ + return WorkContext.getCurrent().get(DecisionOperator.class).getMembers(userName, keyWord); } - - public ImmutableList update() { - return ImmutableList.copyOf(addedMembers); + @Override + protected Collection getMembers(String userName, String keyWord, int pageNum, int count){ + return WorkContext.getCurrent().get(DecisionOperator.class).getMembers(userName, keyWord, pageNum, count); } -} +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberList.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberList.java index 2d95dce4b..5c2b39e6d 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberList.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberList.java @@ -1,8 +1,12 @@ package com.fr.design.remote.ui.list; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.report.constant.RoleType; import com.fr.workspace.server.authority.RemoteDesignMember; import javax.swing.DefaultListModel; +import javax.swing.JOptionPane; import java.util.Vector; public class AddedMemberList extends MemberList { @@ -27,8 +31,21 @@ public class AddedMemberList extends MemberList { protected void displaySelected() { RemoteDesignMember member = getSelectedValue(); if (member != null) { - member.setSelected(!member.isSelected()); - ((DefaultListModel) getModel()).removeElement(member); + String keyTitle = member.getRoleType() == RoleType.CUSTOM ? + "Fine-Design_Basic_Utils_Are_You_Sure_To_Delete_The_Role_And_Its_Design_Authorities" : + "Fine-Design_Basic_Utils_Are_You_Sure_To_Delete_The_User_And_Its_Design_Authorities"; + if (member.isSelected() && member.hasAuthority()){ + int val = JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText(keyTitle), + Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (val == JOptionPane.OK_OPTION) { + member.setSelected(!member.isSelected()); + ((DefaultListModel) getModel()).removeElement(member); + } + } + else { + member.setSelected(!member.isSelected()); + ((DefaultListModel) getModel()).removeElement(member); + } } revalidate(); repaint(); diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberListCellRender.java index f29378f62..74dba29fa 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberListCellRender.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddedMemberListCellRender.java @@ -1,11 +1,11 @@ package com.fr.design.remote.ui.list; -import com.fr.base.BaseUtils; import com.fr.design.gui.ilable.UILabel; import com.fr.design.remote.button.IconButton; import com.fr.workspace.server.authority.RemoteDesignMember; import javax.swing.BorderFactory; +import javax.swing.Icon; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; @@ -13,7 +13,7 @@ import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; -public class AddedMemberListCellRender extends JPanel implements ListCellRenderer { +public abstract class AddedMemberListCellRender extends JPanel implements ListCellRenderer { private UILabel label; @@ -25,7 +25,7 @@ public class AddedMemberListCellRender extends JPanel implements ListCellRendere label = new UILabel(); label.setPreferredSize(new Dimension(264, 20)); this.setPreferredSize(new Dimension(this.getPreferredSize().width, 25)); - label.setIcon(BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png")); + label.setIcon(getMemberIcon()); this.add(label); this.add(new IconButton()); @@ -33,7 +33,7 @@ public class AddedMemberListCellRender extends JPanel implements ListCellRendere @Override public Component getListCellRendererComponent(JList list, RemoteDesignMember member, int index, boolean isSelected, boolean cellHasFocus) { - this.setLabelText(member.getRealName() + "(" + member.getUsername() + ")"); + this.setLabelText(getMemberName(member)); return this; } @@ -41,4 +41,8 @@ public class AddedMemberListCellRender extends JPanel implements ListCellRendere label.setText(name); } + protected abstract Icon getMemberIcon(); + + protected abstract String getMemberName(RemoteDesignMember member); + } diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberList.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberList.java index 649907d05..ea748816f 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberList.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberList.java @@ -1,13 +1,16 @@ package com.fr.design.remote.ui.list; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.report.constant.RoleType; import com.fr.workspace.server.authority.RemoteDesignMember; import javax.swing.DefaultListModel; +import javax.swing.JOptionPane; import java.util.Vector; public class AddingMemberList extends MemberList { - public AddingMemberList() { super(); } @@ -29,7 +32,21 @@ public class AddingMemberList extends MemberList { @Override protected void displaySelected() { RemoteDesignMember member = getSelectedValue(); - member.setSelected(!member.isSelected()); + if (member != null) { + String keyTitle = member.getRoleType() == RoleType.CUSTOM ? + "Fine-Design_Basic_Utils_Are_You_Sure_To_Delete_The_Role_And_Its_Design_Authorities" : + "Fine-Design_Basic_Utils_Are_You_Sure_To_Delete_The_User_And_Its_Design_Authorities"; + if (member.isSelected() && member.hasAuthority()){ + int val = JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText(keyTitle), + Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (val == JOptionPane.OK_OPTION) { + member.setSelected(!member.isSelected()); + } + } + else { + member.setSelected(!member.isSelected()); + } + } revalidate(); repaint(); fireSelectedChange(); diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberListCellRender.java index b2ca3f812..d25702780 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberListCellRender.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/AddingMemberListCellRender.java @@ -1,11 +1,11 @@ package com.fr.design.remote.ui.list; -import com.fr.base.BaseUtils; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; import com.fr.workspace.server.authority.RemoteDesignMember; import javax.swing.BorderFactory; +import javax.swing.Icon; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.ListCellRenderer; @@ -14,7 +14,7 @@ import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; -public class AddingMemberListCellRender extends JPanel implements ListCellRenderer { +public abstract class AddingMemberListCellRender extends JPanel implements ListCellRenderer { private UILabel label; private UICheckBox check; @@ -27,7 +27,7 @@ public class AddingMemberListCellRender extends JPanel implements ListCellRender label = new UILabel(); label.setPreferredSize(new Dimension(260, 20)); this.setPreferredSize(new Dimension(this.getPreferredSize().width, 25)); - label.setIcon(BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png")); + label.setIcon(getMemberIcon()); check = new UICheckBox(); check.setSelected(false); @@ -46,7 +46,7 @@ public class AddingMemberListCellRender extends JPanel implements ListCellRender check.setVisible(false); fixLoadingDisplay(); } else { - this.setLabelText(member.getRealName() + "(" + member.getUsername() + ")"); + this.setLabelText(getMemberName(member)); check.setVisible(true); check.setSelected(member.isSelected()); recoveryCommonDisplay(); @@ -64,7 +64,11 @@ public class AddingMemberListCellRender extends JPanel implements ListCellRender } private void recoveryCommonDisplay() { - label.setIcon(BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png")); + label.setIcon(getMemberIcon()); label.setHorizontalAlignment(SwingConstants.LEFT); } + + protected abstract Icon getMemberIcon(); + + protected abstract String getMemberName(RemoteDesignMember member); } diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/AuthorityListCellRenderer.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/AuthorityListCellRenderer.java index 4cd9c69f9..506c86664 100644 --- a/designer-base/src/main/java/com/fr/design/remote/ui/list/AuthorityListCellRenderer.java +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/AuthorityListCellRenderer.java @@ -1,9 +1,9 @@ package com.fr.design.remote.ui.list; -import com.fr.base.BaseUtils; import com.fr.report.DesignAuthority; import sun.swing.DefaultLookup; +import javax.swing.Icon; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; @@ -12,7 +12,7 @@ import javax.swing.border.EmptyBorder; import java.awt.Color; import java.awt.Component; -public class AuthorityListCellRenderer extends +public abstract class AuthorityListCellRenderer extends JLabel implements ListCellRenderer { /** @@ -81,8 +81,8 @@ public class AuthorityListCellRenderer extends } setBorder(border); - this.setIcon(BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png")); - this.setText(authority.getRealName() + "(" + authority.getUsername() + ")"); + this.setIcon(getMemberIcon()); + this.setText(getMemberName(authority)); return this; } @@ -126,4 +126,8 @@ public class AuthorityListCellRenderer extends p.isOpaque(); return !colorMatch && super.isOpaque(); } + + protected abstract Icon getMemberIcon(); + + protected abstract String getMemberName(DesignAuthority authority); } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedCustomRoleListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedCustomRoleListCellRender.java new file mode 100644 index 000000000..55b558852 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedCustomRoleListCellRender.java @@ -0,0 +1,24 @@ +package com.fr.design.remote.ui.list.cell; + +import com.fr.base.BaseUtils; +import com.fr.design.remote.ui.list.AddedMemberListCellRender; +import com.fr.workspace.server.authority.RemoteDesignMember; + +import javax.swing.Icon; + +/** + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2019/9/19 + */ +public class AddedCustomRoleListCellRender extends AddedMemberListCellRender { + @Override + protected Icon getMemberIcon() { + return BaseUtils.readIcon("com/fr/design/remote/images/icon_Custom_Role_normal@1x.png"); + } + + @Override + protected String getMemberName(RemoteDesignMember member) { + return member.getUsername(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedUserListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedUserListCellRender.java new file mode 100644 index 000000000..e848547b5 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddedUserListCellRender.java @@ -0,0 +1,24 @@ +package com.fr.design.remote.ui.list.cell; + +import com.fr.base.BaseUtils; +import com.fr.design.remote.ui.list.AddedMemberListCellRender; +import com.fr.workspace.server.authority.RemoteDesignMember; + +import javax.swing.Icon; + +/** + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2019/9/19 + */ +public class AddedUserListCellRender extends AddedMemberListCellRender { + @Override + protected Icon getMemberIcon() { + return BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"); + } + + @Override + protected String getMemberName(RemoteDesignMember member) { + return member.getRealName() + "(" + member.getUsername() + ")"; + } +} diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingCustomRoleListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingCustomRoleListCellRender.java new file mode 100644 index 000000000..3de4569d6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingCustomRoleListCellRender.java @@ -0,0 +1,24 @@ +package com.fr.design.remote.ui.list.cell; + +import com.fr.base.BaseUtils; +import com.fr.design.remote.ui.list.AddingMemberListCellRender; +import com.fr.workspace.server.authority.RemoteDesignMember; + +import javax.swing.Icon; + +/** + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2019/9/19 + */ +public class AddingCustomRoleListCellRender extends AddingMemberListCellRender { + @Override + protected Icon getMemberIcon() { + return BaseUtils.readIcon("com/fr/design/remote/images/icon_Custom_Role_normal@1x.png"); + } + + @Override + protected String getMemberName(RemoteDesignMember member) { + return member.getUsername(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingUserListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingUserListCellRender.java new file mode 100644 index 000000000..dda8fc70a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AddingUserListCellRender.java @@ -0,0 +1,24 @@ +package com.fr.design.remote.ui.list.cell; + +import com.fr.base.BaseUtils; +import com.fr.design.remote.ui.list.AddingMemberListCellRender; +import com.fr.workspace.server.authority.RemoteDesignMember; + +import javax.swing.Icon; + +/** + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2019/9/19 + */ +public class AddingUserListCellRender extends AddingMemberListCellRender { + @Override + protected Icon getMemberIcon() { + return BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"); + } + + @Override + protected String getMemberName(RemoteDesignMember member) { + return member.getRealName() + "(" + member.getUsername() + ")"; + } +} diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityCustomRoleListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityCustomRoleListCellRender.java new file mode 100644 index 000000000..6bec15a33 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityCustomRoleListCellRender.java @@ -0,0 +1,24 @@ +package com.fr.design.remote.ui.list.cell; + +import com.fr.base.BaseUtils; +import com.fr.design.remote.ui.list.AuthorityListCellRenderer; +import com.fr.report.DesignAuthority; + +import javax.swing.Icon; + +/** + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2019/9/19 + */ +public class AuthorityCustomRoleListCellRender extends AuthorityListCellRenderer { + @Override + protected Icon getMemberIcon() { + return BaseUtils.readIcon("com/fr/design/remote/images/icon_Custom_Role_normal@1x.png"); + } + + @Override + protected String getMemberName(DesignAuthority authority) { + return authority.getUsername(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityUserListCellRender.java b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityUserListCellRender.java new file mode 100644 index 000000000..82b1afeb8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/list/cell/AuthorityUserListCellRender.java @@ -0,0 +1,24 @@ +package com.fr.design.remote.ui.list.cell; + +import com.fr.base.BaseUtils; +import com.fr.design.remote.ui.list.AuthorityListCellRenderer; +import com.fr.report.DesignAuthority; + +import javax.swing.Icon; + +/** + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2019/9/19 + */ +public class AuthorityUserListCellRender extends AuthorityListCellRenderer { + @Override + protected Icon getMemberIcon() { + return BaseUtils.readIcon("com/fr/design/remote/images/icon_Member_normal@1x.png"); + } + + @Override + protected String getMemberName(DesignAuthority authority) { + return authority.getRealName() + "(" + authority.getUsername() + ")"; + } +} diff --git a/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java b/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java index c30637509..12fc96e96 100644 --- a/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java @@ -729,12 +729,16 @@ public final class GUICoreUtils { * @return 布尔值 */ public static boolean removeJListSelectedNodes(Window ancestorWindow, JList nodeList) { + return removeJListSelectedNodes(ancestorWindow, nodeList, "Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item"); + } + + public static boolean removeJListSelectedNodes(Window ancestorWindow, JList nodeList, String key) { int selectedIndex = nodeList.getSelectedIndex(); if (selectedIndex == -1) { return false; } - int returnVal = JOptionPane.showConfirmDialog(ancestorWindow, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"), + int returnVal = JOptionPane.showConfirmDialog(ancestorWindow, com.fr.design.i18n.Toolkit.i18nText(key), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (returnVal == JOptionPane.OK_OPTION) { int minSelectedIndex = nodeList.getMinSelectionIndex(); diff --git a/designer-base/src/main/resources/com/fr/design/remote/images/icon_Custom_Role_normal@1x.png b/designer-base/src/main/resources/com/fr/design/remote/images/icon_Custom_Role_normal@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..67c53fff58711ba529af3172947a46537a762fed GIT binary patch literal 612 zcmV-q0-ODbP)-FLT z5s$ZuP2SDG6+$2HC=?2q_B!wmK+uv>`d&DEX}G~95{W*gXbw+XYG94E>o4HF^EmAe zGcTiXPiu`v^0wCJC!~DiHpFJNS~n=%Rr_nyBvtnzoLcNWcGBKeKoM{1MUC3ZCRgUW=wdu~>viUm)_2 zO1b%r$m!QwUB_*%xUPHJwhQ=$-cj^npj_TvJY*0-pl})nx262_(~!)bY1(s~{Iput za|V-g{jU%_ji+9N~XvNAbsCF!<+yH8ZbbI%l$)0lF=OP~Qw-Ldumr y+ulqe{fhA;m71K$<#M}*GhtcOtUW-EFz*9?Jj66#@-S`p!6XU z5)TxC)IK1}k4g!@K|Fv|9uP=8@F(Db7DZ4f4L_l%Nl1y~_z<8r5={_^fCNDrQesob z=iKs*eRnzA=h%7fNb8-Q`F3V@c6Rs7*riTgFT;Uv1t*^{R<>7FPhMC7W2uS`KvC+RXG}axGdbrM(S3xm z%9u2V{zi=3gb+In{aK&S+uYyZKTqS8sHgzy>gw*$b#a^wA!c`D83|Ly7NNgz|-7>K6)$h4+l0F3Dy2nwTPs``dj$Y5G8 zellh;KJl83}Fl};5C}I zbP&aLJMeVV*(qZY$c|grSvhXOnL@W98OfMzw@Q3lTU*KO?Cc@jXis3}HphGt>N99F zX!I~uBDiW`6!2Cy5X^^=Ka3|j=jsM7MR@~Il$$DH`xsC`Lc-VreqY1IbOevgnLr@0 z9$PX2l?U~(m7FL_O9kiu?M5JnP!HQ^9%#ncl1O@(`D;aM7gNePkB1>kIfvsnh49uy zBH^dVIbo6JN70p`T@Hr_Nv5j(v%tJvTI#(Ha}Gd+Vq}#FbinVgcf6K!GSJY_P@YI= zr!lb>tB%9aJ{Wx;V~cPq%A(QO6dbQLgfV=hR8s&J2n-6h9?p*ew-L6^3*io`>UXJ! z%EaYlK+}@1Ls^TaWB=~Sc1{zc(dYqk4*k~%@B~C&#$uF_3>q0331KU!aAUyZIZwQY zK4Z}t1MF)DBK|CGg?Fjy=t~(EF=%RPDviezQ!u;^dwa94yB3AeMzF$v*Q_b2#<#*h z*>n7U|J^9$BP2)A_hTF1F)oS!=u0trWO2gdlsw!6s4XD&Zv0Sg%6Kpwx!nARxdue9w9ka^1`y-mEvLeA-b@Z z<;xsSN@{Vy>;UE#Q)30d*it(QsaU*T?-wS(-p|d=--q#)X!9i{CEuGmS!VS9|4o@m zCdC7$+}@)ehA^hjcbp*oHdAK{fVGeidv(HT^`w&|M%OD{K4tOvVhAhQrYOx@uyu55 z5E%bUmiYkq9Kyl`^z^cVtgkHlt;MQSD$d8LcOvZhkFx9vz}OE+<#sp@alRM^e?5$j zx!tZHR*Fycyks81EhfUAfeJ(To2hi_;o$f3@^#G!;y4_aqiq0xlCdiqL!r>5(;QQV zB>Z9Urmy7;KyehS825POFU<-0`o6xtSVu?u9^hX@dli2|+KTxn