From cb285cbfddfc0b633d6b8cdb4dc0d2bd2b8b51ef Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Thu, 05 Jan 2012 17:34:05 -0500 Subject: [PATCH] Fixed bug in receive hook for repositories in subfolders --- src/com/gitblit/client/FeedsPanel.java | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 217 insertions(+), 21 deletions(-) diff --git a/src/com/gitblit/client/FeedsPanel.java b/src/com/gitblit/client/FeedsPanel.java index c6b464d..97f37c0 100644 --- a/src/com/gitblit/client/FeedsPanel.java +++ b/src/com/gitblit/client/FeedsPanel.java @@ -18,23 +18,33 @@ import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.Insets; +import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; +import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; +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.FeedEntryModel; import com.gitblit.models.FeedModel; -import com.gitblit.models.SyndicatedEntryModel; +import com.gitblit.utils.StringUtils; /** * RSS Feeds Panel displays recent entries and launches the browser to view the @@ -49,11 +59,29 @@ private final GitblitClient gitblit; - private SyndicatedEntryTableModel tableModel; + private final String ALL = "*"; + + private FeedEntryTableModel tableModel; + + private TableRowSorter<FeedEntryTableModel> defaultSorter; private HeaderPanel header; private JTable table; + + private DefaultComboBoxModel repositoryChoices; + + private JComboBox repositorySelector; + + private DefaultComboBoxModel authorChoices; + + private JComboBox authorSelector; + + private int page; + + private JButton prev; + + private JButton next; public FeedsPanel(GitblitClient gitblit) { super(); @@ -62,10 +90,29 @@ } private void initialize() { + + prev = new JButton("<"); + prev.setToolTipText(Translation.get("gb.pagePrevious")); + prev.setEnabled(false); + prev.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + refreshFeeds(--page); + } + }); + + next = new JButton(">"); + next.setToolTipText(Translation.get("gb.pageNext")); + next.setEnabled(false); + next.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + refreshFeeds(++page); + } + }); + JButton refreshFeeds = new JButton(Translation.get("gb.refresh")); refreshFeeds.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - refreshFeeds(); + refreshFeeds(0); } }); @@ -108,17 +155,21 @@ controls.add(viewTree); NameRenderer nameRenderer = new NameRenderer(); - tableModel = new SyndicatedEntryTableModel(); - header = new HeaderPanel(Translation.get("gb.timeline"), "feed_16x16.png"); + tableModel = new FeedEntryTableModel(); + header = new HeaderPanel(Translation.get("gb.activity"), "feed_16x16.png"); table = Utils.newTable(tableModel, Utils.DATE_FORMAT); - String name = table.getColumnName(SyndicatedEntryTableModel.Columns.Author.ordinal()); + defaultSorter = new TableRowSorter<FeedEntryTableModel>(tableModel); + String name = table.getColumnName(FeedEntryTableModel.Columns.Author.ordinal()); table.setRowHeight(nameRenderer.getFont().getSize() + 8); table.getColumn(name).setCellRenderer(nameRenderer); - name = table.getColumnName(SyndicatedEntryTableModel.Columns.Repository.ordinal()); + name = table.getColumnName(FeedEntryTableModel.Columns.Repository.ordinal()); table.getColumn(name).setCellRenderer(nameRenderer); - name = table.getColumnName(SyndicatedEntryTableModel.Columns.Branch.ordinal()); + name = table.getColumnName(FeedEntryTableModel.Columns.Branch.ordinal()); table.getColumn(name).setCellRenderer(new BranchRenderer()); + + name = table.getColumnName(FeedEntryTableModel.Columns.Message.ordinal()); + table.getColumn(name).setCellRenderer(new MessageRenderer(gitblit)); table.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { @@ -145,8 +196,50 @@ } }); + repositoryChoices = new DefaultComboBoxModel(); + repositorySelector = new JComboBox(repositoryChoices); + repositorySelector.setRenderer(nameRenderer); + repositorySelector.setForeground(nameRenderer.getForeground()); + repositorySelector.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + // repopulate the author list based on repository selection + // preserve author selection, if possible + String selectedAuthor = null; + if (authorSelector.getSelectedIndex() > -1) { + selectedAuthor = authorSelector.getSelectedItem().toString(); + } + updateAuthors(); + if (selectedAuthor != null) { + if (authorChoices.getIndexOf(selectedAuthor) > -1) { + authorChoices.setSelectedItem(selectedAuthor); + } + } + filterFeeds(); + } + }); + authorChoices = new DefaultComboBoxModel(); + authorSelector = new JComboBox(authorChoices); + authorSelector.setRenderer(nameRenderer); + authorSelector.setForeground(nameRenderer.getForeground()); + authorSelector.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + filterFeeds(); + } + }); + JPanel northControls = new JPanel(new FlowLayout(FlowLayout.LEFT, Utils.MARGIN, 0)); + northControls.add(new JLabel(Translation.get("gb.repository"))); + northControls.add(repositorySelector); + northControls.add(new JLabel(Translation.get("gb.author"))); + northControls.add(authorSelector); +// northControls.add(prev); +// northControls.add(next); + + JPanel northPanel = new JPanel(new BorderLayout(0, Utils.MARGIN)); + northPanel.add(header, BorderLayout.NORTH); + northPanel.add(northControls, BorderLayout.CENTER); + setLayout(new BorderLayout(Utils.MARGIN, Utils.MARGIN)); - add(header, BorderLayout.NORTH); + add(northPanel, BorderLayout.NORTH); add(new JScrollPane(table), BorderLayout.CENTER); add(controls, BorderLayout.SOUTH); } @@ -156,12 +249,12 @@ return Utils.INSETS; } - protected void refreshFeeds() { - // TODO change request type here - GitblitWorker worker = new GitblitWorker(FeedsPanel.this, RpcRequest.LIST_USERS) { + protected void refreshFeeds(final int page) { + this.page = page; + GitblitWorker worker = new GitblitWorker(FeedsPanel.this, null) { @Override protected Boolean doRequest() throws IOException { - gitblit.refreshSubscribedFeeds(); + gitblit.refreshSubscribedFeeds(page); return true; } @@ -179,32 +272,135 @@ tableModel.entries.clear(); tableModel.entries.addAll(gitblit.getSyndicatedEntries()); tableModel.fireTableDataChanged(); - header.setText(Translation.get("gb.timeline") + " (" - + gitblit.getSyndicatedEntries().size() + ")"); + header.setText(Translation.get("gb.activity") + " (" + + gitblit.getSyndicatedEntries().size() + (page > 0 ? (", pg " + (page + 1)) : "") + + ")"); if (pack) { Utils.packColumns(table, Utils.MARGIN); } + table.scrollRectToVisible(new Rectangle(table.getCellRect(0, 0, true))); + + if (page == 0) { + // determine unique repositories + Set<String> uniqueRepositories = new HashSet<String>(); + for (FeedEntryModel entry : tableModel.entries) { + uniqueRepositories.add(entry.repository); + } + + // repositories + List<String> sortedRespositories = new ArrayList<String>(uniqueRepositories); + StringUtils.sortRepositorynames(sortedRespositories); + repositoryChoices.removeAllElements(); + repositoryChoices.addElement(ALL); + for (String repo : sortedRespositories) { + repositoryChoices.addElement(repo); + } + } + + // update pagination buttons + next.setEnabled(tableModel.entries.size() > 0); + prev.setEnabled(page > 0); } - protected SyndicatedEntryModel getSelectedSyndicatedEntry() { + private void updateAuthors() { + String repository = ALL; + if (repositorySelector.getSelectedIndex() > -1) { + repository = repositorySelector.getSelectedItem().toString(); + } + + // determine unique repositories and authors + Set<String> uniqueAuthors = new HashSet<String>(); + for (FeedEntryModel entry : tableModel.entries) { + if (repository.equals(ALL) || entry.repository.equalsIgnoreCase(repository)) { + uniqueAuthors.add(entry.author); + } + } + // authors + List<String> sortedAuthors = new ArrayList<String>(uniqueAuthors); + Collections.sort(sortedAuthors); + authorChoices.removeAllElements(); + authorChoices.addElement(ALL); + for (String author : sortedAuthors) { + authorChoices.addElement(author); + } + } + + protected FeedEntryModel getSelectedSyndicatedEntry() { int viewRow = table.getSelectedRow(); int modelRow = table.convertRowIndexToModel(viewRow); - SyndicatedEntryModel entry = tableModel.get(modelRow); + FeedEntryModel entry = tableModel.get(modelRow); return entry; } protected void viewCommit() { - SyndicatedEntryModel entry = getSelectedSyndicatedEntry(); + FeedEntryModel entry = getSelectedSyndicatedEntry(); Utils.browse(entry.link); } protected void viewCommitDiff() { - SyndicatedEntryModel entry = getSelectedSyndicatedEntry(); + FeedEntryModel entry = getSelectedSyndicatedEntry(); Utils.browse(entry.link.replace("/commit/", "/commitdiff/")); } protected void viewTree() { - SyndicatedEntryModel entry = getSelectedSyndicatedEntry(); + FeedEntryModel entry = getSelectedSyndicatedEntry(); Utils.browse(entry.link.replace("/commit/", "/tree/")); } + + protected void filterFeeds() { + final String repository; + if (repositorySelector.getSelectedIndex() > -1) { + repository = repositorySelector.getSelectedItem().toString(); + } else { + repository = ALL; + } + + final String author; + if (authorSelector.getSelectedIndex() > -1) { + author = authorSelector.getSelectedItem().toString(); + } else { + author = ALL; + } + + if (repository.equals(ALL) && author.equals(ALL)) { + table.setRowSorter(defaultSorter); + return; + } + final int repositoryIndex = FeedEntryTableModel.Columns.Repository.ordinal(); + final int authorIndex = FeedEntryTableModel.Columns.Author.ordinal(); + RowFilter<FeedEntryTableModel, Object> containsFilter; + if (repository.equals(ALL)) { + // author filter + containsFilter = new RowFilter<FeedEntryTableModel, Object>() { + public boolean include( + Entry<? extends FeedEntryTableModel, ? extends Object> entry) { + return entry.getStringValue(authorIndex).equalsIgnoreCase(author); + } + }; + } else if (author.equals(ALL)) { + // repository filter + containsFilter = new RowFilter<FeedEntryTableModel, Object>() { + public boolean include( + Entry<? extends FeedEntryTableModel, ? extends Object> entry) { + return entry.getStringValue(repositoryIndex).equalsIgnoreCase(repository); + } + }; + } else { + // repository-author filter + containsFilter = new RowFilter<FeedEntryTableModel, Object>() { + public boolean include( + Entry<? extends FeedEntryTableModel, ? extends Object> entry) { + boolean authorMatch = entry.getStringValue(authorIndex) + .equalsIgnoreCase(author); + boolean repositoryMatch = entry.getStringValue(repositoryIndex) + .equalsIgnoreCase(repository); + return authorMatch && repositoryMatch; + } + }; + } + TableRowSorter<FeedEntryTableModel> sorter = new TableRowSorter<FeedEntryTableModel>( + tableModel); + sorter.setRowFilter(containsFilter); + table.setRowSorter(sorter); + } } -- Gitblit v1.9.1