/* * Copyright 2011 gitblit.com. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.gitblit.client; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.RowFilter; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.TableRowSorter; import com.gitblit.Constants.RpcRequest; import com.gitblit.models.TeamModel; import com.gitblit.utils.StringUtils; /** * Users panel displays a list of user accounts and allows management of those * accounts. * * @author James Moger * */ public abstract class TeamsPanel extends JPanel { private static final long serialVersionUID = 1L; private final GitblitClient gitblit; private HeaderPanel header; private JTable table; private TeamsTableModel tableModel; private TableRowSorter<TeamsTableModel> defaultSorter; private JTextField filterTextfield; public TeamsPanel(GitblitClient gitblit) { super(); this.gitblit = gitblit; initialize(); } private void initialize() { JButton refreshTeams = new JButton(Translation.get("gb.refresh")); refreshTeams.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { refreshTeams(); } }); JButton createTeam = new JButton(Translation.get("gb.create")); createTeam.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { createTeam(); } }); final JButton editTeam = new JButton(Translation.get("gb.edit")); editTeam.setEnabled(false); editTeam.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { editTeam(getSelectedTeams().get(0)); } }); final JButton delTeam = new JButton(Translation.get("gb.delete")); delTeam.setEnabled(false); delTeam.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { deleteTeams(getSelectedTeams()); } }); NameRenderer nameRenderer = new NameRenderer(); tableModel = new TeamsTableModel(); defaultSorter = new TableRowSorter<TeamsTableModel>(tableModel); table = Utils.newTable(tableModel, Utils.DATE_FORMAT); String name = table.getColumnName(TeamsTableModel.Columns.Name.ordinal()); table.getColumn(name).setCellRenderer(nameRenderer); int w = 125; name = table.getColumnName(TeamsTableModel.Columns.Members.ordinal()); table.getColumn(name).setMinWidth(w); table.getColumn(name).setMaxWidth(w); name = table.getColumnName(TeamsTableModel.Columns.Repositories.ordinal()); table.getColumn(name).setMinWidth(w); table.getColumn(name).setMaxWidth(w); table.setRowSorter(defaultSorter); table.getRowSorter().toggleSortOrder(TeamsTableModel.Columns.Name.ordinal()); table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } boolean selected = table.getSelectedRow() > -1; boolean singleSelection = table.getSelectedRows().length == 1; editTeam.setEnabled(singleSelection && selected); delTeam.setEnabled(selected); } }); table.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { editTeam(getSelectedTeams().get(0)); } } }); filterTextfield = new JTextField(); filterTextfield.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { filterTeams(filterTextfield.getText()); } }); filterTextfield.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { filterTeams(filterTextfield.getText()); } }); JPanel teamFilterPanel = new JPanel(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); teamFilterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST); teamFilterPanel.add(filterTextfield, BorderLayout.CENTER); JPanel teamTablePanel = new JPanel(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); teamTablePanel.add(teamFilterPanel, BorderLayout.NORTH); teamTablePanel.add(new JScrollPane(table), BorderLayout.CENTER); JPanel teamControls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0)); teamControls.add(refreshTeams); teamControls.add(createTeam); teamControls.add(editTeam); teamControls.add(delTeam); setLayout(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); header = new HeaderPanel(Translation.get("gb.teams"), "users_16x16.png"); add(header, BorderLayout.NORTH); add(teamTablePanel, BorderLayout.CENTER); add(teamControls, BorderLayout.SOUTH); } @Override public void requestFocus() { filterTextfield.requestFocus(); } @Override public Insets getInsets() { return Utils.INSETS; } protected abstract void updateUsersTable(); protected void updateTable(boolean pack) { tableModel.list.clear(); tableModel.list.addAll(gitblit.getTeams()); tableModel.fireTableDataChanged(); header.setText(Translation.get("gb.teams") + " (" + gitblit.getTeams().size() + ")"); if (pack) { Utils.packColumns(table, Utils.MARGIN); } } private void filterTeams(final String fragment) { if (StringUtils.isEmpty(fragment)) { table.setRowSorter(defaultSorter); return; } RowFilter<TeamsTableModel, Object> containsFilter = new RowFilter<TeamsTableModel, Object>() { @Override public boolean include(Entry<? extends TeamsTableModel, ? extends Object> entry) { for (int i = entry.getValueCount() - 1; i >= 0; i--) { if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) { return true; } } return false; } }; TableRowSorter<TeamsTableModel> sorter = new TableRowSorter<TeamsTableModel>(tableModel); sorter.setRowFilter(containsFilter); table.setRowSorter(sorter); } private List<TeamModel> getSelectedTeams() { List<TeamModel> teams = new ArrayList<TeamModel>(); for (int viewRow : table.getSelectedRows()) { int modelRow = table.convertRowIndexToModel(viewRow); TeamModel model = tableModel.list.get(modelRow); teams.add(model); } return teams; } protected void refreshTeams() { GitblitWorker worker = new GitblitWorker(TeamsPanel.this, RpcRequest.LIST_TEAMS) { @Override protected Boolean doRequest() throws IOException { gitblit.refreshTeams(); return true; } @Override protected void onSuccess() { updateTable(false); } }; worker.execute(); } /** * Displays the create team dialog and fires a SwingWorker to update the * server, if appropriate. * */ protected void createTeam() { EditTeamDialog dialog = new EditTeamDialog(gitblit.getProtocolVersion(), gitblit.getSettings()); dialog.setLocationRelativeTo(TeamsPanel.this); dialog.setTeams(gitblit.getTeams()); dialog.setRepositories(gitblit.getRepositories(), null); dialog.setUsers(gitblit.getUsernames(), null); dialog.setPreReceiveScripts(gitblit.getPreReceiveScriptsUnused(null), gitblit.getPreReceiveScriptsInherited(null), null); dialog.setPostReceiveScripts(gitblit.getPostReceiveScriptsUnused(null), gitblit.getPostReceiveScriptsInherited(null), null); dialog.setVisible(true); final TeamModel newTeam = dialog.getTeam(); if (newTeam == null) { return; } GitblitWorker worker = new GitblitWorker(this, RpcRequest.CREATE_TEAM) { @Override protected Boolean doRequest() throws IOException { boolean success = gitblit.createTeam(newTeam); if (success) { gitblit.refreshTeams(); gitblit.refreshUsers(); } return success; } @Override protected void onSuccess() { updateTable(false); updateUsersTable(); } @Override protected void onFailure() { showFailure("Failed to execute request \"{0}\" for team \"{1}\".", getRequestType(), newTeam.name); } }; worker.execute(); } /** * Displays the edit team dialog and fires a SwingWorker to update the * server, if appropriate. * * @param user */ protected void editTeam(final TeamModel team) { EditTeamDialog dialog = new EditTeamDialog(gitblit.getProtocolVersion(), team, gitblit.getSettings()); dialog.setLocationRelativeTo(TeamsPanel.this); dialog.setTeams(gitblit.getTeams()); dialog.setRepositories(gitblit.getRepositories(), team.getRepositoryPermissions()); dialog.setUsers(gitblit.getUsernames(), team.users == null ? null : new ArrayList<String>( team.users)); dialog.setPreReceiveScripts(gitblit.getPreReceiveScriptsUnused(null), gitblit.getPreReceiveScriptsInherited(null), team.preReceiveScripts); dialog.setPostReceiveScripts(gitblit.getPostReceiveScriptsUnused(null), gitblit.getPostReceiveScriptsInherited(null), team.postReceiveScripts); dialog.setVisible(true); final TeamModel revisedTeam = dialog.getTeam(); if (revisedTeam == null) { return; } GitblitWorker worker = new GitblitWorker(this, RpcRequest.EDIT_TEAM) { @Override protected Boolean doRequest() throws IOException { boolean success = gitblit.updateTeam(team.name, revisedTeam); if (success) { gitblit.refreshTeams(); gitblit.refreshUsers(); } return success; } @Override protected void onSuccess() { updateTable(false); updateUsersTable(); } @Override protected void onFailure() { showFailure("Failed to execute request \"{0}\" for team \"{1}\".", getRequestType(), team.name); } }; worker.execute(); } protected void deleteTeams(final List<TeamModel> teams) { if (teams == null || teams.size() == 0) { return; } StringBuilder message = new StringBuilder("Delete the following teams?\n\n"); for (TeamModel team : teams) { message.append(team.name).append("\n"); } int result = JOptionPane.showConfirmDialog(TeamsPanel.this, message.toString(), "Delete Teams?", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { GitblitWorker worker = new GitblitWorker(this, RpcRequest.DELETE_TEAM) { @Override protected Boolean doRequest() throws IOException { boolean success = true; for (TeamModel team : teams) { success &= gitblit.deleteTeam(team); } if (success) { gitblit.refreshTeams(); gitblit.refreshUsers(); } return success; } @Override protected void onSuccess() { updateTable(false); updateUsersTable(); } @Override protected void onFailure() { showFailure("Failed to delete specified teams!"); } }; worker.execute(); } } }