James Moger
2011-10-13 b7f591781f4bd2e3c94596a2b1f2cf73cdc0d7cd
Localized RPC client using server's resource file.
1 files renamed
1 files added
10 files modified
414 ■■■■ changed files
build.xml 1 ●●●● patch | view | raw | blame | history
src/com/gitblit/build/Build.java 8 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/EditRepositoryDialog.java 130 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/EditUserDialog.java 30 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitClient.java 24 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitClientLauncher.java 7 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/GitblitPanel.java 61 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/IndicatorsRenderer.java 49 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/JPalette.java 11 ●●●●● patch | view | raw | blame | history
src/com/gitblit/client/RepositoriesModel.java 20 ●●●● patch | view | raw | blame | history
src/com/gitblit/client/Translation.java 57 ●●●●● patch | view | raw | blame | history
src/com/gitblit/wicket/GitBlitWebApp.properties 16 ●●●●● patch | view | raw | blame | history
build.xml
@@ -434,6 +434,7 @@
            <resource file="${basedir}/resources/book_16x16.png" />
            <resource file="${basedir}/resources/bug_16x16.png" />
            <resource file="${basedir}/resources/blank.png" />
            <resource file="${basedir}/src/com/gitblit/wicket/GitBlitWebApp.properties" />
                
            <class name="com.gitblit.client.GitblitClientLauncher" />
            <classfilter>
src/com/gitblit/build/Build.java
@@ -139,6 +139,8 @@
        downloadListener = listener;
        downloadFromApache(MavenObject.GSON, BuildType.RUNTIME);
        downloadFromApache(MavenObject.JSCH, BuildType.RUNTIME);
        downloadFromApache(MavenObject.SLF4JAPI, BuildType.RUNTIME);
        downloadFromApache(MavenObject.SLF4JNOP, BuildType.RUNTIME);
        
        downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME);
    }
@@ -389,6 +391,12 @@
                "46a386136c901748e6a3af67ebde6c22bc6b4524",
                "e223571d77769cdafde59040da235842f3326453");
        public static final MavenObject SLF4JNOP = new MavenObject("SLF4J NOP", "org/slf4j",
                "slf4j-nop", "1.6.1", 4800, 4100, 32300,
                "70249094d4e5653b6bdfea46f3a1a4165c1e1993",
                "4a8e77f7bf6897a3c3b7fc3acb4c862dfb905baa",
                "24b2b46f9025f2db53b5b32143f7832538fa3178");
        public static final MavenObject SLF4LOG4J = new MavenObject("SLF4J LOG4J", "org/slf4j",
                "slf4j-log4j12", "1.6.1", 9800, 9500, 52400,
                "bd245d6746cdd4e6203e976e21d597a46f115802",
src/com/gitblit/client/EditRepositoryDialog.java
@@ -16,6 +16,7 @@
package com.gitblit.client;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
@@ -32,9 +33,11 @@
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import com.gitblit.Constants.AccessRestrictionType;
import com.gitblit.Constants.FederationStrategy;
@@ -42,6 +45,11 @@
import com.gitblit.models.UserModel;
import com.gitblit.utils.StringUtils;
/**
 * Dialog to create/edit a repository.
 *
 * @author James Moger
 */
public class EditRepositoryDialog extends JDialog {
    private static final long serialVersionUID = 1L;
@@ -76,7 +84,7 @@
    public EditRepositoryDialog(List<UserModel> allusers) {
        this(new RepositoryModel(), allusers);
        setTitle("Create Repository");
        setTitle(Translation.get("gb.newRepository"));
    }
    public EditRepositoryDialog(RepositoryModel aRepository, List<UserModel> allUsers) {
@@ -84,7 +92,7 @@
        this.repository = new RepositoryModel();
        initialize(aRepository, allUsers);
        setModal(true);
        setTitle("Edit Repository: " + aRepository.name);
        setTitle(Translation.get("gb.edit") + ": " + aRepository.name);
        setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
    }
@@ -105,48 +113,56 @@
            owner.setSelectedItem(currentOwner);
        }
        useTickets = new JCheckBox("distributed Ticgit issues", anRepository.useTickets);
        useDocs = new JCheckBox("enumerates Markdown documentation in repository",
                anRepository.useDocs);
        showRemoteBranches = new JCheckBox("show remote branches", anRepository.showRemoteBranches);
        showReadme = new JCheckBox("show a \"readme\" Markdown file on the summary page",
        useTickets = new JCheckBox(Translation.get("gb.useTicketsDescription"),
                anRepository.useTickets);
        useDocs = new JCheckBox(Translation.get("gb.useDocsDescription"), anRepository.useDocs);
        showRemoteBranches = new JCheckBox(Translation.get("gb.showRemoteBranchesDescription"),
                anRepository.showRemoteBranches);
        showReadme = new JCheckBox(Translation.get("gb.showReadmeDescription"),
                anRepository.showReadme);
        isFrozen = new JCheckBox("deny push operations", anRepository.isFrozen);
        isFrozen = new JCheckBox(Translation.get("gb.isFrozenDescription"), anRepository.isFrozen);
        accessRestriction = new JComboBox(AccessRestrictionType.values());
        accessRestriction.setRenderer(new AccessRestrictionRenderer());
        accessRestriction.setSelectedItem(anRepository.accessRestriction);
        federationStrategy = new JComboBox(FederationStrategy.values());
        federationStrategy.setRenderer(new FederationStrategyRenderer());
        federationStrategy.setSelectedItem(anRepository.federationStrategy);
        JPanel fieldsPanel = new JPanel(new GridLayout(0, 1));
        fieldsPanel.add(newFieldPanel("name", nameField));
        fieldsPanel.add(newFieldPanel("description", descriptionField));
        fieldsPanel.add(newFieldPanel("owner", owner));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.name"), nameField));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.description"), descriptionField));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.owner"), owner));
        fieldsPanel.add(newFieldPanel("enable tickets", useTickets));
        fieldsPanel.add(newFieldPanel("enable docs", useDocs));
        fieldsPanel.add(newFieldPanel("show remote branches", showRemoteBranches));
        fieldsPanel.add(newFieldPanel("show readme", showReadme));
        fieldsPanel.add(newFieldPanel("is frozen", isFrozen));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.enableTickets"), useTickets));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.enableDocs"), useDocs));
        fieldsPanel
                .add(newFieldPanel(Translation.get("gb.showRemoteBranches"), showRemoteBranches));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.showReadme"), showReadme));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.isFrozen"), isFrozen));
        usersPalette = new JPalette<String>();
        JPanel accessPanel = new JPanel(new BorderLayout(5, 5));
        accessPanel.add(newFieldPanel("access restriction", accessRestriction), BorderLayout.NORTH);
        accessPanel.add(newFieldPanel("permitted users", usersPalette), BorderLayout.CENTER);
        accessPanel.add(newFieldPanel(Translation.get("gb.accessRestriction"), accessRestriction),
                BorderLayout.NORTH);
        accessPanel.add(newFieldPanel(Translation.get("gb.permittedUsers"), usersPalette),
                BorderLayout.CENTER);
        setsPalette = new JPalette<String>();
        JPanel federationPanel = new JPanel(new BorderLayout(5, 5));
        federationPanel.add(newFieldPanel("federation strategy", federationStrategy),
        federationPanel.add(
                newFieldPanel(Translation.get("gb.federationStrategy"), federationStrategy),
                BorderLayout.NORTH);
        federationPanel.add(newFieldPanel("federation sets", setsPalette), BorderLayout.CENTER);
        federationPanel.add(newFieldPanel(Translation.get("gb.federationSets"), setsPalette),
                BorderLayout.CENTER);
        JPanel panel = new JPanel(new BorderLayout(5, 5));
        panel.add(fieldsPanel, BorderLayout.NORTH);
        panel.add(accessPanel, BorderLayout.CENTER);
        panel.add(federationPanel, BorderLayout.SOUTH);
        JButton createButton = new JButton("Save");
        JButton createButton = new JButton(Translation.get("gb.save"));
        createButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateFields()) {
@@ -156,7 +172,7 @@
            }
        });
        JButton cancelButton = new JButton("Cancel");
        JButton cancelButton = new JButton(Translation.get("gb.cancel"));
        cancelButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                canceled = true;
@@ -203,8 +219,8 @@
    }
    private void showValidationError(String message) {
        JOptionPane.showMessageDialog(EditRepositoryDialog.this, message, "Validation Error",
                JOptionPane.ERROR_MESSAGE);
        JOptionPane.showMessageDialog(EditRepositoryDialog.this, message,
                Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
    }
    public void setUsers(List<String> all, List<String> selected) {
@@ -221,4 +237,70 @@
        }
        return repository;
    }
    /**
     * ListCellRenderer to display descriptive text about the access
     * restriction.
     *
     */
    private class AccessRestrictionRenderer extends JLabel implements ListCellRenderer {
        private static final long serialVersionUID = 1L;
        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index,
                boolean isSelected, boolean cellHasFocus) {
            if (value instanceof AccessRestrictionType) {
                AccessRestrictionType restriction = (AccessRestrictionType) value;
                switch (restriction) {
                case NONE:
                    setText(Translation.get("gb.notRestricted"));
                    break;
                case PUSH:
                    setText(Translation.get("gb.pushRestricted"));
                    break;
                case CLONE:
                    setText(Translation.get("gb.cloneRestricted"));
                    break;
                case VIEW:
                    setText(Translation.get("gb.viewRestricted"));
                    break;
                }
            } else {
                setText(value.toString());
            }
            return this;
        }
    }
    /**
     * ListCellRenderer to display descriptive text about the federation
     * strategy.
     */
    private class FederationStrategyRenderer extends JLabel implements ListCellRenderer {
        private static final long serialVersionUID = 1L;
        @Override
        public Component getListCellRendererComponent(JList list, Object value, int index,
                boolean isSelected, boolean cellHasFocus) {
            if (value instanceof FederationStrategy) {
                FederationStrategy strategy = (FederationStrategy) value;
                switch (strategy) {
                case EXCLUDE:
                    setText(Translation.get("gb.excludeFromFederation"));
                    break;
                case FEDERATE_THIS:
                    setText(Translation.get("gb.federateThis"));
                    break;
                case FEDERATE_ORIGIN:
                    setText(Translation.get("gb.federateOrigin"));
                    break;
                }
            } else {
                setText(value.toString());
            }
            return this;
        }
    }
}
src/com/gitblit/client/EditUserDialog.java
@@ -70,7 +70,7 @@
    public EditUserDialog(IStoredSettings settings) {
        this(new UserModel(""), settings);
        setTitle("Create User");
        setTitle(Translation.get("gb.newUser"));
    }
    public EditUserDialog(UserModel anUser, IStoredSettings settings) {
@@ -79,7 +79,7 @@
        this.settings = settings;
        initialize(anUser);
        setModal(true);
        setTitle("Edit User: " + anUser.username);
        setTitle(Translation.get("gb.edit") + ": " + anUser.username);
        setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
    }
@@ -88,24 +88,26 @@
        passwordField = new JPasswordField(anUser.password == null ? "" : anUser.password, 25);
        confirmPasswordField = new JPasswordField(anUser.password == null ? "" : anUser.password,
                25);
        canAdminCheckbox = new JCheckBox("can administer Gitblit server", anUser.canAdmin);
        canAdminCheckbox = new JCheckBox(Translation.get("gb.canAdminDescription"), anUser.canAdmin);
        notFederatedCheckbox = new JCheckBox(
                "block federated Gitblit instances from pulling this account",
                Translation.get("gb.excludeFromFederationDescription"),
                anUser.excludeFromFederation);
        JPanel fieldsPanel = new JPanel(new GridLayout(0, 1));
        fieldsPanel.add(newFieldPanel("username", usernameField));
        fieldsPanel.add(newFieldPanel("password", passwordField));
        fieldsPanel.add(newFieldPanel("confirm password", confirmPasswordField));
        fieldsPanel.add(newFieldPanel("can admin", canAdminCheckbox));
        fieldsPanel.add(newFieldPanel("exclude from federation", notFederatedCheckbox));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.username"), usernameField));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.password"), passwordField));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.confirmPassword"), confirmPasswordField));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.canAdmin"), canAdminCheckbox));
        fieldsPanel.add(newFieldPanel(Translation.get("gb.excludeFromFederation"),
                notFederatedCheckbox));
        repositoryPalette = new JPalette<String>();
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(fieldsPanel, BorderLayout.NORTH);
        panel.add(newFieldPanel("restricted repositories", repositoryPalette), BorderLayout.CENTER);
        panel.add(newFieldPanel(Translation.get("gb.restrictedRepositories"), repositoryPalette),
                BorderLayout.CENTER);
        JButton createButton = new JButton("Save");
        JButton createButton = new JButton(Translation.get("gb.save"));
        createButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateFields()) {
@@ -115,7 +117,7 @@
            }
        });
        JButton cancelButton = new JButton("Cancel");
        JButton cancelButton = new JButton(Translation.get("gb.cancel"));
        cancelButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                canceled = true;
@@ -164,7 +166,7 @@
        }
        // TODO verify username uniqueness on create
        // if (isCreate) {
        // UserModel model = GitBlit.self().getUserModel(username);
        // if (model != null) {
@@ -210,7 +212,7 @@
    }
    private void showValidationError(String message) {
        JOptionPane.showMessageDialog(EditUserDialog.this, message, "Validation Error",
        JOptionPane.showMessageDialog(EditUserDialog.this, message, Translation.get("gb.error"),
                JOptionPane.ERROR_MESSAGE);
    }
src/com/gitblit/client/GitblitClient.java
@@ -18,6 +18,7 @@
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -92,11 +93,11 @@
    private JMenuBar setupMenu() {
        JMenuBar menuBar = new JMenuBar();
        JMenu serversMenu = new JMenu("Servers");
        JMenu serversMenu = new JMenu(Translation.get("gb.servers"));
        menuBar.add(serversMenu);
        recentMenu = new JMenu("Recent");
        recentMenu = new JMenu(Translation.get("gb.recent"));
        serversMenu.add(recentMenu);
        JMenuItem login = new JMenuItem("Login...");
        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) {
@@ -109,6 +110,7 @@
    private JPanel newLabelPanel(String text, JTextField field) {
        JLabel label = new JLabel(text);
        label.setFont(label.getFont().deriveFont(Font.BOLD));
        label.setPreferredSize(new Dimension(75, 10));
        JPanel jpanel = new JPanel(new BorderLayout());
        jpanel.add(label, BorderLayout.WEST);
@@ -132,13 +134,13 @@
        JPasswordField passwordField = new JPasswordField(new String(reg.password));
        JPanel panel = new JPanel(new GridLayout(0, 1, 5, 5));
        panel.add(newLabelPanel("name", nameField));
        panel.add(newLabelPanel("url", urlField));
        panel.add(newLabelPanel("account", accountField));
        panel.add(newLabelPanel("password", passwordField));
        panel.add(newLabelPanel(Translation.get("gb.name"), nameField));
        panel.add(newLabelPanel(Translation.get("gb.url"), urlField));
        panel.add(newLabelPanel(Translation.get("gb.username"), accountField));
        panel.add(newLabelPanel(Translation.get("gb.password"), passwordField));
        int result = JOptionPane.showConfirmDialog(GitblitClient.this, panel, "Login",
                JOptionPane.OK_CANCEL_OPTION);
        int result = JOptionPane.showConfirmDialog(GitblitClient.this, panel,
                Translation.get("gb.login"), JOptionPane.OK_CANCEL_OPTION);
        if (result != JOptionPane.OK_OPTION) {
            return false;
        }
@@ -165,8 +167,8 @@
                    panel));
            return true;
        } catch (IOException e) {
            JOptionPane.showMessageDialog(GitblitClient.this, e.getMessage(), "Error",
                    JOptionPane.ERROR_MESSAGE);
            JOptionPane.showMessageDialog(GitblitClient.this, e.getMessage(),
                    Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
        }
        return false;
    }
src/com/gitblit/client/GitblitClientLauncher.java
@@ -44,14 +44,13 @@
        DownloadListener downloadListener = new DownloadListener() {
            @Override
            public void downloading(String name) {
                updateSplash(splash, "Downloading " + name + "...");
                updateSplash(splash, Translation.get("gb.downloading") + " " + name + "...");
            }
        };
        
        // download rpc client runtime dependencies
        Build.rpcClient(downloadListener);
        updateSplash(splash, "Scanning Library Folder...");
        File libFolder = new File("ext");
        List<File> jars = Launcher.findJars(libFolder.getAbsoluteFile());
        
@@ -61,14 +60,14 @@
        Collections.reverse(jars);
        for (File jar : jars) {
            try {
                updateSplash(splash, "Loading " + jar.getName() + "...");
                updateSplash(splash, Translation.get("gb.loading") + " " + jar.getName() + "...");
                Launcher.addJarFile(jar);
            } catch (IOException e) {
            }
        }
        
        updateSplash(splash, "Starting Gitblit RPC Client...");
        updateSplash(splash, Translation.get("gb.starting") + " Gitblit RPC Client...");
        GitblitClient.main(args);
    }
src/com/gitblit/client/GitblitPanel.java
@@ -108,7 +108,7 @@
    private NameRenderer nameRenderer;
    private TypeRenderer typeRenderer;
    private IndicatorsRenderer typeRenderer;
    private DefaultTableCellRenderer ownerRenderer;
@@ -127,7 +127,7 @@
        this.account = account;
        this.password = password;
        final JButton browseRepository = new JButton("Browse");
        final JButton browseRepository = new JButton(Translation.get("gb.browse"));
        browseRepository.setEnabled(false);
        browseRepository.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
@@ -142,7 +142,7 @@
            }
        });
        JButton refreshRepositories = new JButton("Refresh");
        JButton refreshRepositories = new JButton(Translation.get("gb.refresh"));
        refreshRepositories.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
@@ -157,14 +157,14 @@
            }
        });
        createRepository = new JButton("Create");
        createRepository = new JButton(Translation.get("gb.create"));
        createRepository.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                createRepository();
            }
        });
        final JButton editRepository = new JButton("Edit");
        final JButton editRepository = new JButton(Translation.get("gb.edit"));
        editRepository.setEnabled(false);
        editRepository.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
@@ -172,7 +172,7 @@
            }
        });
        delRepository = new JButton("Delete");
        delRepository = new JButton(Translation.get("gb.delete"));
        delRepository.setEnabled(false);
        delRepository.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
@@ -180,7 +180,7 @@
            }
        });
        final JButton cloneRepository = new JButton("Clone");
        final JButton cloneRepository = new JButton(Translation.get("gb.clone"));
        cloneRepository.setEnabled(false);
        cloneRepository.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
@@ -191,7 +191,7 @@
        });
        nameRenderer = new NameRenderer();
        typeRenderer = new TypeRenderer();
        typeRenderer = new IndicatorsRenderer();
        sizeRenderer = new DefaultTableCellRenderer();
        sizeRenderer.setHorizontalAlignment(SwingConstants.RIGHT);
@@ -216,7 +216,7 @@
        repositoriesTable.setDefaultRenderer(Date.class,
                new DateCellRenderer(null, Color.orange.darker()));
        setRenderer(RepositoriesModel.Columns.Name, nameRenderer);
        setRenderer(RepositoriesModel.Columns.Type, typeRenderer);
        setRenderer(RepositoriesModel.Columns.Indicators, typeRenderer);
        setRenderer(RepositoriesModel.Columns.Owner, ownerRenderer);
        setRenderer(RepositoriesModel.Columns.Size, sizeRenderer);
@@ -252,7 +252,7 @@
        });
        JPanel filterPanel = new JPanel(new BorderLayout(margin, margin));
        filterPanel.add(new JLabel("Filter"), BorderLayout.WEST);
        filterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST);
        filterPanel.add(repositoryFilter, BorderLayout.CENTER);
        JPanel tablePanel = new JPanel(new BorderLayout(margin, margin));
@@ -267,11 +267,12 @@
        repositoryControls.add(delRepository);
        JPanel repositoriesPanel = new JPanel(new BorderLayout(margin, margin));
        repositoriesPanel.add(newHeaderLabel("Repositories"), BorderLayout.NORTH);
        repositoriesPanel.add(newHeaderLabel(Translation.get("gb.repositories")),
                BorderLayout.NORTH);
        repositoriesPanel.add(tablePanel, BorderLayout.CENTER);
        repositoriesPanel.add(repositoryControls, BorderLayout.SOUTH);
        JButton refreshUsers = new JButton("Refresh");
        JButton refreshUsers = new JButton(Translation.get("gb.refresh"));
        refreshUsers.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
@@ -286,14 +287,14 @@
            }
        });
        JButton createUser = new JButton("Create");
        JButton createUser = new JButton(Translation.get("gb.create"));
        createUser.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                createUser();
            }
        });
        final JButton editUser = new JButton("Edit");
        final JButton editUser = new JButton(Translation.get("gb.edit"));
        editUser.setEnabled(false);
        editUser.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
@@ -301,7 +302,7 @@
            }
        });
        final JButton delUser = new JButton("Delete");
        final JButton delUser = new JButton(Translation.get("gb.delete"));
        delUser.setEnabled(false);
        delUser.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
@@ -331,7 +332,7 @@
        userControls.add(delUser);
        usersPanel = new JPanel(new BorderLayout(margin, margin));
        usersPanel.add(newHeaderLabel("Users"), BorderLayout.NORTH);
        usersPanel.add(newHeaderLabel(Translation.get("gb.users")), BorderLayout.NORTH);
        usersPanel.add(new JScrollPane(usersList), BorderLayout.CENTER);
        usersPanel.add(userControls, BorderLayout.SOUTH);
@@ -343,8 +344,8 @@
        mainPanel.add(usersPanel, BorderLayout.EAST);
        tabs = new JTabbedPane(JTabbedPane.BOTTOM);
        tabs.addTab("Main", mainPanel);
        tabs.addTab("Federation", new JPanel());
        tabs.addTab(Translation.get("gb.repositories"), mainPanel);
        tabs.addTab(Translation.get("gb.federation"), new JPanel());
        setLayout(new BorderLayout());
        add(tabs, BorderLayout.CENTER);
@@ -541,8 +542,8 @@
                        String msg = MessageFormat.format(
                                "Failed to execute request \"{0}\" for repository \"{1}\".",
                                request.name(), newRepository.name);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!",
                                JOptionPane.ERROR_MESSAGE);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg,
                                Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
                    }
                } catch (ForbiddenException e) {
                    explainForbidden(request);
@@ -597,8 +598,8 @@
                        String msg = MessageFormat.format(
                                "Failed to execute request \"{0}\" for repository \"{1}\".",
                                request.name(), repository.name);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!",
                                JOptionPane.ERROR_MESSAGE);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg,
                                Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
                    }
                } catch (ForbiddenException e) {
                    explainForbidden(request);
@@ -642,8 +643,8 @@
                            refreshRepositoriesTable();
                        } else {
                            String msg = "Failed to delete specified repositories!";
                            JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!",
                                    JOptionPane.ERROR_MESSAGE);
                            JOptionPane.showMessageDialog(GitblitPanel.this, msg,
                                    Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
                        }
                    } catch (ForbiddenException e) {
                        explainForbidden(request);
@@ -690,8 +691,8 @@
                        String msg = MessageFormat.format(
                                "Failed to execute request \"{0}\" for user \"{1}\".",
                                request.name(), newUser.username);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!",
                                JOptionPane.ERROR_MESSAGE);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg,
                                Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
                    }
                } catch (ForbiddenException e) {
                    explainForbidden(request);
@@ -738,8 +739,8 @@
                        String msg = MessageFormat.format(
                                "Failed to execute request \"{0}\" for user \"{1}\".",
                                request.name(), user.username);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!",
                                JOptionPane.ERROR_MESSAGE);
                        JOptionPane.showMessageDialog(GitblitPanel.this, msg,
                                Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
                    }
                } catch (ForbiddenException e) {
                    explainForbidden(request);
@@ -783,8 +784,8 @@
                            refreshUsersTable();
                        } else {
                            String msg = "Failed to delete specified users!";
                            JOptionPane.showMessageDialog(GitblitPanel.this, msg, "Error!",
                                    JOptionPane.ERROR_MESSAGE);
                            JOptionPane.showMessageDialog(GitblitPanel.this, msg,
                                    Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
                        }
                    } catch (ForbiddenException e) {
                        explainForbidden(request);
src/com/gitblit/client/IndicatorsRenderer.java
File was renamed from src/com/gitblit/client/TypeRenderer.java
@@ -34,7 +34,7 @@
 * @author James Moger
 * 
 */
public class TypeRenderer extends JPanel implements TableCellRenderer, Serializable {
public class IndicatorsRenderer extends JPanel implements TableCellRenderer, Serializable {
    private static final long serialVersionUID = 1L;
@@ -54,7 +54,7 @@
    private final ImageIcon federatedIcon;
    public TypeRenderer() {
    public IndicatorsRenderer() {
        super(new GridLayout(1, 0, 1, 0));
        blankIcon = new ImageIcon(getClass().getResource("/blank.png"));
        pushIcon = new ImageIcon(getClass().getResource("/lock_go_16x16.png"));
@@ -75,44 +75,67 @@
            setBackground(table.getBackground());
        removeAll();
        if (value instanceof RepositoryModel) {
            StringBuilder tooltip = new StringBuilder();
            RepositoryModel model = (RepositoryModel) value;
            if (model.useTickets) {
                add(new JLabel(tixIcon));
                JLabel icon = new JLabel(tixIcon);
                tooltip.append(Translation.get("gb.tickets")).append("<br/>");
                add(icon);
            } else {
                add(new JLabel(blankIcon));
            }
            if (model.useDocs) {
                add(new JLabel(doxIcon));
                JLabel icon = new JLabel(doxIcon);
                tooltip.append(Translation.get("gb.docs")).append("<br/>");
                add(icon);
            } else {
                add(new JLabel(blankIcon));
            }
            if (model.isFrozen) {
                add(new JLabel(frozenIcon));
                JLabel icon = new JLabel(frozenIcon);
                tooltip.append(Translation.get("gb.isFrozen")).append("<br/>");
                add(icon);
            } else {
                add(new JLabel(blankIcon));
            }
            if (model.isFederated) {
                add(new JLabel(federatedIcon));
                JLabel icon = new JLabel(federatedIcon);
                tooltip.append(Translation.get("gb.isFederated")).append("<br/>");
                add(icon);
            } else {
                add(new JLabel(blankIcon));
            }
            switch (model.accessRestriction) {
            case NONE:
            case NONE: {
                add(new JLabel(blankIcon));
                break;
            case PUSH:
                add(new JLabel(pushIcon));
            }
            case PUSH: {
                JLabel icon = new JLabel(pushIcon);
                tooltip.append(Translation.get("gb.pushRestricted")).append("<br/>");
                add(icon);
                break;
            case CLONE:
                add(new JLabel(pullIcon));
            }
            case CLONE: {
                JLabel icon = new JLabel(pullIcon);
                tooltip.append(Translation.get("gb.pullRestricted")).append("<br/>");
                add(icon);
                break;
            case VIEW:
                add(new JLabel(viewIcon));
            }
            case VIEW: {
                JLabel icon = new JLabel(viewIcon);
                tooltip.append(Translation.get("gb.viewRestricted")).append("<br/>");
                add(icon);
                break;
            }
            default:
                add(new JLabel(blankIcon));
            }
            if (tooltip.length() > 0) {
                tooltip.insert(0, "<html><body>");
                setToolTipText(tooltip.toString().trim());
            }
        }
        return this;
    }
src/com/gitblit/client/JPalette.java
@@ -18,6 +18,7 @@
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
@@ -92,9 +93,9 @@
        JPanel center = new JPanel(new GridBagLayout());
        center.add(controls);
        add(newListPanel("Available", available), BorderLayout.WEST);
        add(newListPanel(Translation.get("gb.available"), available), BorderLayout.WEST);
        add(center, BorderLayout.CENTER);
        add(newListPanel("Selected", selected), BorderLayout.EAST);
        add(newListPanel(Translation.get("gb.selected"), selected), BorderLayout.EAST);
    }
    private JPanel newListPanel(String label, JTable table) {
@@ -110,7 +111,9 @@
        JScrollPane jsp = new JScrollPane(table);
        jsp.setPreferredSize(new Dimension(225, 175));
        JPanel panel = new JPanel(new BorderLayout());
        panel.add(new JLabel(label), BorderLayout.NORTH);
        JLabel jlabel = new JLabel(label);
        jlabel.setFont(jlabel.getFont().deriveFont(Font.BOLD));
        panel.add(jlabel, BorderLayout.NORTH);
        panel.add(jsp, BorderLayout.CENTER);
        return panel;
    }
@@ -161,7 +164,7 @@
        @Override
        public String getColumnName(int column) {
            return "Name";
            return Translation.get("gb.name");
        }
        public Class<?> getColumnClass(int columnIndex) {
src/com/gitblit/client/RepositoriesModel.java
@@ -37,7 +37,7 @@
    List<RepositoryModel> list;
    enum Columns {
        Name, Description, Owner, Type, Last_Change, Size;
        Name, Description, Owner, Indicators, Last_Change, Size;
        @Override
        public String toString() {
@@ -67,7 +67,19 @@
    @Override
    public String getColumnName(int column) {
        Columns col = Columns.values()[column];
        return col.toString();
        switch (col) {
        case Name:
            return Translation.get("gb.name");
        case Description:
            return Translation.get("gb.description");
        case Owner:
            return Translation.get("gb.owner");
        case Last_Change:
            return Translation.get("gb.lastChange");
        case Size:
            return Translation.get("gb.size");
        }
        return "";
    }
    /**
@@ -81,7 +93,7 @@
        Columns col = Columns.values()[columnIndex];
        switch (col) {
        case Name:
        case Type:
        case Indicators:
            return RepositoryModel.class;
        case Last_Change:
            return Date.class;
@@ -100,7 +112,7 @@
            return model.description;
        case Owner:
            return model.owner;
        case Type:
        case Indicators:
            return model;
        case Last_Change:
            return model.lastChange;
src/com/gitblit/client/Translation.java
New file
@@ -0,0 +1,57 @@
/*
 * 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.io.InputStream;
import java.util.Properties;
public class Translation {
    private final static Properties translation;
    static {
        translation = new Properties();
        InputStream is = null;
        try {
            is = Translation.class.getResource("/com/gitblit/wicket/GitBlitWebApp.properties")
                    .openStream();
        } catch (Throwable t) {
            try {
                is = Translation.class.getResource("/GitBlitWebApp.properties").openStream();
            } catch (Throwable x) {
            }
        }
        if (is != null) {
            try {
                translation.load(is);
            } catch (Throwable t) {
            } finally {
                try {
                    is.close();
                } catch (Throwable t) {
                }
            }
        }
    }
    public static String get(String key) {
        if (translation.containsKey(key)) {
            return translation.getProperty(key).trim();
        }
        return key;
    }
}
src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -140,4 +140,18 @@
gb.destinationUrl = send to
gb.destinationUrlDescription = the url of the Gitblit instance to send your proposal
gb.users = users
gb.federation = federation
gb.federation = federation
gb.error = error
gb.refresh = refresh
gb.browse = browse
gb.clone = clone
gb.filter = filter
gb.create = create
gb.servers = servers
gb.recent = recent
gb.available = available
gb.selected = selected
gb.size = size
gb.downloading = downloading
gb.loading = loading
gb.starting = starting