diff --git a/app/src/processing/app/contrib/UpdateContributionListPanel.java b/app/src/processing/app/contrib/UpdateContributionListPanel.java new file mode 100644 index 000000000..e3644356d --- /dev/null +++ b/app/src/processing/app/contrib/UpdateContributionListPanel.java @@ -0,0 +1,242 @@ +package processing.app.contrib; + +import java.awt.Color; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Font; +import java.util.Comparator; +import java.util.Set; +import java.util.TreeMap; + +import javax.swing.BorderFactory; +import javax.swing.GroupLayout; +import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableCellRenderer; + +import processing.app.Base; +import processing.app.ui.Toolkit; + + +public class UpdateContributionListPanel extends ContributionListPanel { + + public UpdateContributionListPanel(ContributionTab contributionTab, + ContributionFilter filter) { + this.contributionTab = contributionTab; + this.filter = filter; + + setOpaque(true); + setBackground(Color.WHITE); + + model = new DefaultTableModel() { + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + + @Override + public Class getColumnClass(int columnIndex) { + return (columnIndex == 0) ? Icon.class : String.class; + } + }; + + model.setColumnIdentifiers(new String[] { + "", "Name", "Author", "Installed", "Update To" + }); + + table = new JTable(model) { + @Override + public Component prepareRenderer(TableCellRenderer renderer, int row, int column) { + Component c = super.prepareRenderer(renderer, row, column); + String title = (String) getValueAt(row, 1); + if (title.equals("Library") || title.equals("Tools") + || title.equals("Modes") || title.equals("Examples")) { + ((JComponent) c).setBorder(BorderFactory + .createMatteBorder(row == 0 ? 0 : 2, 0, 2, 0, Color.BLACK)); + } + return c; + } + + @Override + public void changeSelection(int rowIndex, int columnIndex, + boolean toggle, boolean extend) { + String title = (String) getValueAt(rowIndex, 1); + if (title.equals("Library") || + title.equals("Tools") || + title.equals("Modes") || + title.equals("Examples")){ + return; + } + super.changeSelection(rowIndex, columnIndex, toggle, extend); + } + }; + + scrollPane = new JScrollPane(table); + table.setFillsViewportHeight(true); + table.setSelectionBackground(new Color(0xe0fffd)); + table.setSelectionForeground(table.getForeground()); + table.setFont(Toolkit.getSansFont(14, Font.PLAIN)); + table.setRowHeight(30); + table.setRowMargin(6); + table.getColumnModel().setColumnMargin(-1); + table.getColumnModel().getColumn(0).setMaxWidth(60); + table.setShowGrid(false); + table.setCellSelectionEnabled(false); + table.setRowSelectionAllowed(true); + table.setAutoCreateColumnsFromModel(true); + table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + table.setDefaultRenderer(String.class, new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, int column) { + return super.getTableCellRendererComponent(table, value, isSelected, + false, row, column); + } + }); + + table.getTableHeader().setDefaultRenderer(new ContribHeaderRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, int row, + int column) { + // TODO this doesn't do anything with the returned value? [fry] + super.getTableCellRendererComponent(table, value, isSelected, + hasFocus, row, column); + JTableHeader tableHeader = table.getTableHeader(); + if (tableHeader != null) { + setForeground(tableHeader.getForeground()); + } + setIcon(getIcon(table, column)); + setBackground(new Color(0xebebeb)); + return this; + } + }); + + GroupLayout layout = new GroupLayout(this); + layout.setHorizontalGroup(layout.createParallelGroup().addComponent(scrollPane)); + layout.setVerticalGroup(layout.createSequentialGroup().addComponent(scrollPane)); + + setLayout(layout); + table.setVisible(true); + + panelByContribution = new TreeMap(new Comparator() { + @Override + public int compare(Contribution o1, Contribution o2) { + int diff = + ContributionManagerDialog.getTypeIndex(o1.getType()) - + ContributionManagerDialog.getTypeIndex(o2.getType()); + if (diff == 0) { + diff = o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase()); + } + return diff; + } + }); + } + + @Override + void updatePanelOrdering(Set contributionsSet) { + JLabel label = contributionTab.contributionManagerDialog.numberLabel; + if (getNoOfRows() == 0) { + label.setVisible(false); + } else { + label.setVisible(true); + label.setText(Integer.toString(panelByContribution.size())); + } + model.getDataVector().removeAllElements(); + model.fireTableDataChanged(); + ContributionType temp = null; + + // Avoid ugly synthesized bold + Font boldFont = Toolkit.getSansFont(table.getFont().getSize(), Font.BOLD); + String fontFace = ""; + + for (Contribution entry : contributionsSet) { + if (entry.getType() != temp) { + temp = entry.getType(); + model.addRow(new Object[] { + null, + "" + temp.getTitle() + "", + null, null, null + }); + } + //TODO Make this into a function + StringBuilder name = new StringBuilder(""); + String authorList = entry.getAuthorList(); + if (authorList != null) { + for (int i = 0; i < authorList.length(); i++) { + if (authorList.charAt(i) == '[' || authorList.charAt(i) == ']') { + continue; + } + if (authorList.charAt(i) == '(') { + i++; + while (authorList.charAt(i) != ')') { + i++; + } + } else { + name.append(authorList.charAt(i)); + } + } + } + Icon icon = null; + if (entry.isInstalled()) { + icon = upToDateIcon; + if (contribListing.hasUpdates(entry)) { + icon = updateAvailableIcon; + } + if (!entry.isCompatible(Base.getRevision())) { + icon = incompatibleIcon; + } + } + model.addRow(new Object[] { + icon, + "" + fontFace + entry.getName() + "", + name, + entry.getPrettyVersion(), + contributionTab.contribListing.getLatestVersion(entry) + }); + } + UpdateContributionTab tab = (UpdateContributionTab) contributionTab; + ((UpdateStatusPanel) tab.statusPanel).update(); + } + + + @Override + public void contributionAdded(final Contribution contribution) { + if (filter.matches(contribution)) { + EventQueue.invokeLater(new Runnable() { + public void run() { + // TODO make this longer and more contorted [fry] + ContributionPanel newPanel = + contributionTab.contributionManagerDialog.getTab(contribution.getType()).contributionListPanel.panelByContribution.get(contribution); + if (newPanel == null) { + newPanel = new ContributionPanel(UpdateContributionListPanel.this); + } + if (!panelByContribution.containsKey(contribution)) { + synchronized (panelByContribution) { + panelByContribution.put(contribution, newPanel); + } + } + if (newPanel != null) { + newPanel.setContribution(contribution); + add(newPanel); + updatePanelOrdering(panelByContribution.keySet()); + updateColors(); // XXX this is the place + } + } + }); + } + } +} \ No newline at end of file diff --git a/app/src/processing/app/contrib/UpdateStatusPanel.java b/app/src/processing/app/contrib/UpdateStatusPanel.java new file mode 100644 index 000000000..03a6d2f15 --- /dev/null +++ b/app/src/processing/app/contrib/UpdateStatusPanel.java @@ -0,0 +1,61 @@ +package processing.app.contrib; + +import java.awt.Color; +import java.awt.Font; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Collection; + +import javax.swing.GroupLayout; +import javax.swing.JButton; +import javax.swing.LayoutStyle; +import javax.swing.SwingConstants; + +import processing.app.ui.Toolkit; + +public class UpdateStatusPanel extends StatusPanel { + + /** + * + */ + private final UpdateContributionTab parent; + + public UpdateStatusPanel(UpdateContributionTab updateContributionTab, int width, final ContributionTab contributionTab) { + super(); + parent = updateContributionTab; + + updateButton = new JButton("Update All", Toolkit.getLibIconX("manager/update")); + updateButton.setFont(Toolkit.getSansFont(14, Font.PLAIN)); + updateButton.setHorizontalAlignment(SwingConstants.LEFT); + updateButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Collection c = + contributionTab.contributionListPanel.panelByContribution.values(); + for (ContributionPanel contributionPanel : c) { + contributionPanel.update(); + } + } + }); + setBackground(new Color(0xebebeb)); + layout = new GroupLayout(this); + this.setLayout(layout); + + layout.setAutoCreateContainerGaps(true); + layout.setAutoCreateGaps(true); + + layout.setHorizontalGroup(layout + .createSequentialGroup() + .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, + GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE) + .addComponent(updateButton, BUTTON_WIDTH, BUTTON_WIDTH, BUTTON_WIDTH)); + layout.setVerticalGroup(layout.createParallelGroup() + .addComponent(updateButton)); + updateButton.setVisible(true); + updateButton.setEnabled(false); + } + + public void update() { + updateButton.setEnabled(parent.contributionListPanel.getNoOfRows() > 0); + } +} \ No newline at end of file