src/com/gitblit/client/EditRepositoryDialog.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/client/EditUserDialog.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/client/GitblitManager.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/client/GitblitPanel.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/client/GitblitRegistration.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/client/RegistrationsDialog.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/client/RegistrationsModel.java | ●●●●● patch | view | raw | blame | history | |
src/com/gitblit/wicket/GitBlitWebApp.properties | ●●●●● patch | view | raw | blame | history |
src/com/gitblit/client/EditRepositoryDialog.java
@@ -24,6 +24,7 @@ import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -42,8 +43,10 @@ import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.ListCellRenderer; import com.gitblit.Constants.AccessRestrictionType; @@ -108,6 +111,18 @@ setResizable(false); setTitle(Translation.get("gb.edit") + ": " + aRepository.name); setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage()); } @Override protected JRootPane createRootPane() { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); JRootPane rootPane = new JRootPane(); rootPane.registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { setVisible(false); } }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return rootPane; } private void initialize(RepositoryModel anRepository) { @@ -216,7 +231,6 @@ getContentPane().setLayout(new BorderLayout(5, 5)); getContentPane().add(centerPanel, BorderLayout.CENTER); pack(); setLocationRelativeTo(null); } private JPanel newFieldPanel(String label, JComponent comp) { src/com/gitblit/client/EditUserDialog.java
@@ -23,6 +23,7 @@ import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; @@ -39,7 +40,9 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JRootPane; import javax.swing.JTextField; import javax.swing.KeyStroke; import com.gitblit.Constants.AccessRestrictionType; import com.gitblit.IStoredSettings; @@ -90,6 +93,18 @@ setModal(true); setTitle(Translation.get("gb.edit") + ": " + anUser.username); setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage()); } @Override protected JRootPane createRootPane() { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); JRootPane rootPane = new JRootPane(); rootPane.registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { setVisible(false); } }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return rootPane; } private void initialize(UserModel anUser) { @@ -154,7 +169,6 @@ getContentPane().setLayout(new BorderLayout(5, 5)); getContentPane().add(centerPanel, BorderLayout.CENTER); pack(); setLocationRelativeTo(null); } private JPanel newFieldPanel(String label, JComponent comp) { src/com/gitblit/client/GitblitManager.java
@@ -16,6 +16,7 @@ package com.gitblit.client; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; @@ -29,9 +30,17 @@ import java.io.File; import java.io.IOException; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; import javax.swing.ImageIcon; import javax.swing.JFrame; @@ -45,6 +54,7 @@ import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.KeyStroke; import javax.swing.SwingWorker; import javax.swing.UIManager; import org.eclipse.jgit.errors.ConfigInvalidException; @@ -62,19 +72,21 @@ * @author James Moger * */ public class GitblitManager extends JFrame { public class GitblitManager extends JFrame implements RegistrationsDialog.RegistrationListener { private static final long serialVersionUID = 1L; private final SimpleDateFormat dateFormat; private JTabbedPane serverTabs; private File configFile = new File(System.getProperty("user.home"), ".gitblit/config"); private GitblitRegistration localhost = new GitblitRegistration("default", "https://localhost:8443", "admin", "admin".toCharArray()); private Map<String, GitblitRegistration> registrations = new LinkedHashMap<String, GitblitRegistration>(); private JMenu recentMenu; private int maxRecentCount = 5; private GitblitManager() { super(); dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); } private void initialize() { @@ -142,31 +154,27 @@ } } public void setVisible(boolean value) { if (value) { if (registrations.size() == 0) { // default prompt loginPrompt(localhost); } else if (registrations.size() == 1) { // single registration prompt GitblitRegistration reg = registrations.values().iterator().next(); loginPrompt(reg); } super.setVisible(value); } } private JMenuBar setupMenu() { JMenuBar menuBar = new JMenuBar(); JMenu serversMenu = new JMenu(Translation.get("gb.servers")); menuBar.add(serversMenu); recentMenu = new JMenu(Translation.get("gb.recent")); serversMenu.add(recentMenu); JMenuItem manage = new JMenuItem(Translation.get("gb.manage") + "..."); manage.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, KeyEvent.CTRL_DOWN_MASK, false)); manage.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { manageRegistrations(); } }); serversMenu.add(manage); JMenuItem login = new JMenuItem(Translation.get("gb.login") + "..."); login.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_DOWN_MASK, false)); login.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { loginPrompt(localhost); loginPrompt(GitblitRegistration.LOCALHOST); } }); serversMenu.add(login); @@ -192,7 +200,15 @@ return panel; } private boolean loginPrompt(GitblitRegistration reg) { private void manageRegistrations() { RegistrationsDialog dialog = new RegistrationsDialog(new ArrayList<GitblitRegistration>( registrations.values()), this); dialog.setLocationRelativeTo(GitblitManager.this); dialog.setVisible(true); } @Override public void loginPrompt(GitblitRegistration reg) { JTextField urlField = new JTextField(reg.url, 30); JTextField nameField = new JTextField(reg.name); JTextField accountField = new JTextField(reg.account); @@ -207,46 +223,81 @@ int result = JOptionPane.showConfirmDialog(GitblitManager.this, panel, Translation.get("gb.login"), JOptionPane.OK_CANCEL_OPTION); if (result != JOptionPane.OK_OPTION) { return false; return; } String url = urlField.getText(); if (StringUtils.isEmpty(url)) { return false; return; } String originalName = reg.name; reg = new GitblitRegistration(nameField.getText(), url, accountField.getText(), passwordField.getPassword()); boolean success = login(reg); registrations.put(reg.name, reg); rebuildRecentMenu(); return success; if (!StringUtils.isEmpty(originalName) && !originalName.equals(reg.name)) { // delete old registration try { StoredConfig config = getConfig(); config.unsetSection("servers", originalName); config.save(); } catch (Throwable t) { Utils.showException(GitblitManager.this, t); } } login(reg); } private boolean login(GitblitRegistration reg) { try { GitblitPanel panel = new GitblitPanel(reg); panel.login(); serverTabs.addTab(reg.name, panel); int idx = serverTabs.getTabCount() - 1; serverTabs.setSelectedIndex(idx); serverTabs.setTabComponentAt(idx, new ClosableTabComponent(reg.name, null, serverTabs, panel)); saveRegistration(reg); return true; } catch (IOException e) { JOptionPane.showMessageDialog(GitblitManager.this, e.getMessage(), Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE); } return false; @Override public void login(final GitblitRegistration reg) { setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); final GitblitPanel panel = new GitblitPanel(reg); SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { @Override protected Boolean doInBackground() throws IOException { panel.login(); return true; } @Override protected void done() { try { boolean success = get(); serverTabs.addTab(reg.name, panel); int idx = serverTabs.getTabCount() - 1; serverTabs.setSelectedIndex(idx); serverTabs.setTabComponentAt(idx, new ClosableTabComponent(reg.name, null, serverTabs, panel)); reg.lastLogin = new Date(); saveRegistration(reg); registrations.put(reg.name, reg); rebuildRecentMenu(); } catch (Throwable t) { Utils.showException(GitblitManager.this, t); } finally { setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } } }; worker.execute(); } private void rebuildRecentMenu() { recentMenu.removeAll(); ImageIcon icon = new ImageIcon(getClass().getResource("/gitblt-favicon.png")); for (final GitblitRegistration reg : registrations.values()) { List<GitblitRegistration> list = new ArrayList<GitblitRegistration>(registrations.values()); Collections.sort(list, new Comparator<GitblitRegistration>() { @Override public int compare(GitblitRegistration o1, GitblitRegistration o2) { return o2.lastLogin.compareTo(o1.lastLogin); } }); if (list.size() > maxRecentCount) { list = list.subList(0, maxRecentCount); } for (final GitblitRegistration reg : list) { JMenuItem item = new JMenuItem(reg.name, icon); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { loginPrompt(reg); login(reg); } }); recentMenu.add(item); @@ -258,11 +309,14 @@ StoredConfig config = getConfig(); Set<String> servers = config.getSubsections("servers"); for (String server : servers) { Date lastLogin = dateFormat.parse(config.getString("servers", server, "lastLogin")); String url = config.getString("servers", server, "url"); String account = config.getString("servers", server, "account"); // FIXME this is pretty lame char[] password = new String(Base64.decode(config.getString("servers", server, "password"))).toCharArray(); GitblitRegistration reg = new GitblitRegistration(server, url, account, password); reg.lastLogin = lastLogin; registrations.put(reg.name, reg); } } catch (Throwable t) { @@ -275,14 +329,31 @@ StoredConfig config = getConfig(); config.setString("servers", reg.name, "url", reg.url); config.setString("servers", reg.name, "account", reg.account); // FIXME this is pretty lame config.setString("servers", reg.name, "password", Base64.encodeBytes(new String(reg.password).getBytes("UTF-8"))); config.setString("servers", reg.name, "lastLogin", dateFormat.format(reg.lastLogin)); config.save(); } catch (Throwable t) { Utils.showException(GitblitManager.this, t); } } public boolean deleteRegistrations(List<GitblitRegistration> list) { boolean success = false; try { StoredConfig config = getConfig(); for (GitblitRegistration reg : list) { config.unsetSection("servers", reg.name); } config.save(); success = true; } catch (Throwable t) { Utils.showException(GitblitManager.this, t); } return success; } private StoredConfig getConfig() throws IOException, ConfigInvalidException { FileBasedConfig config = new FileBasedConfig(configFile, FS.detect()); config.load(); src/com/gitblit/client/GitblitPanel.java
@@ -25,6 +25,8 @@ 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.net.URI; import java.text.MessageFormat; @@ -212,6 +214,14 @@ } } }); repositoriesTable.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { editRepository(getSelectedRepositories().get(0)); } } }); final JTextField repositoryFilter = new JTextField(); repositoryFilter.addActionListener(new ActionListener() { @@ -316,6 +326,14 @@ boolean singleSelection = usersTable.getSelectedRows().length == 1; editUser.setEnabled(singleSelection && selected); delUser.setEnabled(selected); } }); usersTable.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { editUser(getSelectedUsers().get(0)); } } }); @@ -553,7 +571,7 @@ gitblit = null; } protected void refreshRepositories() { protected void refreshRepositories() { GitblitWorker worker = new GitblitWorker(GitblitPanel.this, RpcRequest.LIST_REPOSITORIES) { @Override protected Boolean doRequest() throws IOException { @@ -576,6 +594,7 @@ */ protected void createRepository() { EditRepositoryDialog dialog = new EditRepositoryDialog(); dialog.setLocationRelativeTo(GitblitPanel.this); dialog.setUsers(null, gitblit.getUsernames(), null); dialog.setRepositories(gitblit.getRepositories()); dialog.setVisible(true); @@ -622,6 +641,7 @@ */ protected void editRepository(final RepositoryModel repository) { EditRepositoryDialog dialog = new EditRepositoryDialog(repository); dialog.setLocationRelativeTo(GitblitPanel.this); List<String> usernames = gitblit.getUsernames(); List<String> members = gitblit.getPermittedUsernames(repository); dialog.setUsers(repository.owner, usernames, members); @@ -724,6 +744,7 @@ */ protected void createUser() { EditUserDialog dialog = new EditUserDialog(gitblit.getSettings()); dialog.setLocationRelativeTo(GitblitPanel.this); dialog.setUsers(gitblit.getUsers()); dialog.setRepositories(gitblit.getRepositories(), null); dialog.setVisible(true); @@ -765,6 +786,7 @@ */ protected void editUser(final UserModel user) { EditUserDialog dialog = new EditUserDialog(user, gitblit.getSettings()); dialog.setLocationRelativeTo(GitblitPanel.this); dialog.setRepositories(gitblit.getRepositories(), new ArrayList<String>(user.repositories)); dialog.setVisible(true); final UserModel revisedUser = dialog.getUser(); src/com/gitblit/client/GitblitRegistration.java
@@ -16,6 +16,7 @@ package com.gitblit.client; import java.io.Serializable; import java.util.Date; import com.gitblit.utils.StringUtils; @@ -25,14 +26,17 @@ * @author James Moger * */ public class GitblitRegistration implements Serializable { public class GitblitRegistration implements Serializable, Comparable<GitblitRegistration> { public static final GitblitRegistration LOCALHOST = new GitblitRegistration("localhost", "https://localhost:8443", "admin", "admin".toCharArray()); private static final long serialVersionUID = 1L; String name; String url; String account; char[] password; Date lastLogin; public GitblitRegistration(String name, String url, String account, char[] password) { this.url = url; @@ -44,4 +48,9 @@ this.name = name; } } @Override public int compareTo(GitblitRegistration o) { return name.compareTo(o.name); } } src/com/gitblit/client/RegistrationsDialog.java
New file @@ -0,0 +1,192 @@ /* * 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.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.JRootPane; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; public class RegistrationsDialog extends JDialog { interface RegistrationListener { boolean deleteRegistrations(List<GitblitRegistration> list); void loginPrompt(GitblitRegistration reg); void login(GitblitRegistration reg); } private static final long serialVersionUID = 1L; private final List<GitblitRegistration> registrations; private final RegistrationListener listener; private JTable registrationsTable; private RegistrationsModel model; public RegistrationsDialog(List<GitblitRegistration> registrations, RegistrationListener listener) { super(); this.registrations = registrations; this.listener = listener; setTitle(Translation.get("gb.manage")); setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage()); initialize(); setSize(600, 400); } @Override protected JRootPane createRootPane() { KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); JRootPane rootPane = new JRootPane(); rootPane.registerKeyboardAction(new ActionListener() { public void actionPerformed(ActionEvent actionEvent) { setVisible(false); } }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); return rootPane; } private void initialize() { NameRenderer nameRenderer = new NameRenderer(); model = new RegistrationsModel(registrations); registrationsTable = Utils.newTable(model); registrationsTable.setRowHeight(nameRenderer.getFont().getSize() + 8); String id = registrationsTable.getColumnName(RegistrationsModel.Columns.Name.ordinal()); registrationsTable.getColumn(id).setCellRenderer(nameRenderer); registrationsTable.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { login(false); } } }); final JButton create = new JButton(Translation.get("gb.create")); create.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { listener.loginPrompt(GitblitRegistration.LOCALHOST); } }); final JButton login = new JButton(Translation.get("gb.login")); login.setEnabled(false); login.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { login(false); } }); final JButton loginPrompt = new JButton(Translation.get("gb.login") + "..."); loginPrompt.setEnabled(false); loginPrompt.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { login(true); } }); final JButton delete = new JButton(Translation.get("gb.delete")); delete.setEnabled(false); delete.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { delete(); } }); registrationsTable.getSelectionModel().addListSelectionListener( new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) { return; } boolean singleSelection = registrationsTable.getSelectedRowCount() == 1; boolean selected = registrationsTable.getSelectedRow() > -1; login.setEnabled(singleSelection); loginPrompt.setEnabled(singleSelection); delete.setEnabled(selected); } }); JPanel controls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0)); controls.add(create); controls.add(login); controls.add(loginPrompt); controls.add(delete); final Insets insets = new Insets(5, 5, 5, 5); JPanel centerPanel = new JPanel(new BorderLayout(5, 5)) { private static final long serialVersionUID = 1L; public Insets getInsets() { return insets; } }; centerPanel.add(new JScrollPane(registrationsTable), BorderLayout.CENTER); centerPanel.add(controls, BorderLayout.SOUTH); getContentPane().setLayout(new BorderLayout(5, 5)); getContentPane().add(centerPanel, BorderLayout.CENTER); } private void login(boolean prompt) { int viewRow = registrationsTable.getSelectedRow(); int modelRow = registrationsTable.convertRowIndexToModel(viewRow); GitblitRegistration reg = registrations.get(modelRow); RegistrationsDialog.this.setVisible(false); if (prompt) { listener.loginPrompt(reg); } else { listener.login(reg); } } private void delete() { List<GitblitRegistration> list = new ArrayList<GitblitRegistration>(); for (int i : registrationsTable.getSelectedRows()) { int model = registrationsTable.convertRowIndexToModel(i); GitblitRegistration reg = registrations.get(model); list.add(reg); } if (listener.deleteRegistrations(list)) { registrations.removeAll(list); model.fireTableDataChanged(); } } } src/com/gitblit/client/RegistrationsModel.java
New file @@ -0,0 +1,102 @@ /* * 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.util.Collections; import java.util.Date; import java.util.List; import javax.swing.table.AbstractTableModel; /** * Table model of a list of Gitblit server registrations. * * @author James Moger * */ public class RegistrationsModel extends AbstractTableModel { private static final long serialVersionUID = 1L; List<GitblitRegistration> list; enum Columns { Name, URL, Last_Login; @Override public String toString() { return name().replace('_', ' '); } } public RegistrationsModel(List<GitblitRegistration> list) { this.list = list; Collections.sort(this.list); } @Override public int getRowCount() { return list.size(); } @Override public int getColumnCount() { return Columns.values().length; } @Override public String getColumnName(int column) { Columns col = Columns.values()[column]; switch (col) { case Name: return Translation.get("gb.name"); case URL: return Translation.get("gb.url"); case Last_Login: return Translation.get("gb.lastLogin"); } return ""; } /** * Returns <code>Object.class</code> regardless of <code>columnIndex</code>. * * @param columnIndex * the column being queried * @return the Object.class */ public Class<?> getColumnClass(int columnIndex) { if (columnIndex == Columns.Last_Login.ordinal()) { return Date.class; } return String.class; } @Override public Object getValueAt(int rowIndex, int columnIndex) { GitblitRegistration model = list.get(rowIndex); Columns col = Columns.values()[columnIndex]; switch (col) { case Name: return model.name; case URL: return model.url; case Last_Login: return model.lastLogin; } return null; } } src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -156,4 +156,6 @@ gb.loading = loading gb.starting = starting gb.general = general gb.settings = settings gb.settings = settings gb.manage = manage gb.lastLogin = last login