diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 7603a00d0d..26fd1214de 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -105,12 +105,9 @@ public class Base { PreferencesFrame preferencesFrame; // A single instance of the library manager window - ContributionManagerDialog libraryManagerFrame; - ContributionManagerDialog toolManagerFrame; - ContributionManagerDialog modeManagerFrame; - ContributionManagerDialog exampleManagerFrame; - ContributionManagerDialog updateManagerFrame; + ContributionManagerDialog contributionManagerFrame; + // Location for untitled items static File untitledFolder; @@ -397,16 +394,8 @@ public Base(String[] args) throws Exception { } } - libraryManagerFrame = - new ContributionManagerDialog(ContributionType.LIBRARY); - toolManagerFrame = - new ContributionManagerDialog(ContributionType.TOOL); - modeManagerFrame = - new ContributionManagerDialog(ContributionType.MODE); - exampleManagerFrame = - new ContributionManagerDialog(ContributionType.EXAMPLES); - updateManagerFrame = - new ContributionManagerDialog(null); + contributionManagerFrame = + new ContributionManagerDialog(); // Make sure ThinkDifferent has library examples too nextMode.rebuildLibraryList(); @@ -1468,7 +1457,7 @@ public void handlePrefs() { * Show the library installer window. */ public void handleOpenLibraryManager() { - libraryManagerFrame.showFrame(activeEditor); + contributionManagerFrame.showFrame(activeEditor,ContributionType.LIBRARY); } @@ -1476,7 +1465,7 @@ public void handleOpenLibraryManager() { * Show the tool installer window. */ public void handleOpenToolManager() { - toolManagerFrame.showFrame(activeEditor); + contributionManagerFrame.showFrame(activeEditor,ContributionType.TOOL); } @@ -1484,7 +1473,7 @@ public void handleOpenToolManager() { * Show the mode installer window. */ public void handleOpenModeManager() { - modeManagerFrame.showFrame(activeEditor); + contributionManagerFrame.showFrame(activeEditor,ContributionType.MODE); } @@ -1492,12 +1481,12 @@ public void handleOpenModeManager() { * Show the examples installer window. */ public void handleOpenExampleManager() { - exampleManagerFrame.showFrame(activeEditor); + contributionManagerFrame.showFrame(activeEditor,ContributionType.EXAMPLES); } public void handleShowUpdates() { - updateManagerFrame.showFrame(activeEditor); + contributionManagerFrame.showFrame(activeEditor,null); } diff --git a/app/src/processing/app/UpdateCheck.java b/app/src/processing/app/UpdateCheck.java index eac71115ff..458c09af4a 100644 --- a/app/src/processing/app/UpdateCheck.java +++ b/app/src/processing/app/UpdateCheck.java @@ -130,14 +130,8 @@ public void updateCheck() throws IOException, InterruptedException { // Wait for xml file to be downloaded and updates to come in. // (this should really be handled better). Thread.sleep(5 * 1000); - if ((!base.libraryManagerFrame.hasAlreadyBeenOpened() && - !base.toolManagerFrame.hasAlreadyBeenOpened() && - !base.modeManagerFrame.hasAlreadyBeenOpened() && - !base.exampleManagerFrame.hasAlreadyBeenOpened()) && - (base.libraryManagerFrame.hasUpdates(base) || - base.toolManagerFrame.hasUpdates(base) || - base.modeManagerFrame.hasUpdates(base) || - base.exampleManagerFrame.hasUpdates(base))) { + if ((!base.contributionManagerFrame.hasAlreadyBeenOpened() + && (base.contributionManagerFrame.hasUpdates(base)))){ promptToOpenContributionManager(); } } diff --git a/app/src/processing/app/contrib/ContributionListPanel.java b/app/src/processing/app/contrib/ContributionListPanel.java index 4e01060c64..01c1d52c55 100644 --- a/app/src/processing/app/contrib/ContributionListPanel.java +++ b/app/src/processing/app/contrib/ContributionListPanel.java @@ -41,7 +41,7 @@ public class ContributionListPanel extends JPanel implements Scrollable, ContributionChangeListener { - ContributionManagerDialog contribManager; + ContributionTab contributionTab; TreeMap panelByContribution; static HyperlinkListener nullHyperlinkListener = new HyperlinkListener() { @@ -56,10 +56,10 @@ public void hyperlinkUpdate(HyperlinkEvent e) { } private ContributionListing contribListing = ContributionListing.getInstance(); - public ContributionListPanel(ContributionManagerDialog libraryManager, + public ContributionListPanel(ContributionTab contributionTab, ContributionFilter filter) { super(); - this.contribManager = libraryManager; + this.contributionTab = contributionTab; this.filter = filter; // contribListing = ContributionListing.getInstance(); diff --git a/app/src/processing/app/contrib/ContributionManagerDialog.java b/app/src/processing/app/contrib/ContributionManagerDialog.java index 7342e3881b..5dc8e9a32c 100644 --- a/app/src/processing/app/contrib/ContributionManagerDialog.java +++ b/app/src/processing/app/contrib/ContributionManagerDialog.java @@ -1,31 +1,26 @@ /* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* - Part of the Processing project - http://processing.org + Part of the Processing project - http://processing.org - Copyright (c) 2013 The Processing Foundation - Copyright (c) 2011-12 Ben Fry and Casey Reas + Copyright (c) 2013 The Processing Foundation + Copyright (c) 2011-12 Ben Fry and Casey Reas - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License version 2 - as published by the Free Software Foundation. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 + as published by the Free Software Foundation. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ package processing.app.contrib; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Font; import java.awt.event.*; import java.io.File; import java.io.IOException; @@ -34,181 +29,181 @@ import java.util.*; import javax.swing.*; -import javax.swing.border.EmptyBorder; -import javax.swing.event.*; import processing.app.*; - +/** + * + * @author akarshit + * + * This class is the main Contribution Manager Dialog. + * It contains all the contributions tab and the upadate tab. + * + */ public class ContributionManagerDialog { static final String ANY_CATEGORY = Language.text("contrib.all"); JFrame dialog; + JTabbedPane tabbedPane; String title; - ContributionFilter filter; - JComboBox categoryChooser; - JScrollPane scrollPane; - ContributionListPanel contributionListPanel; - StatusPanel status; - FilterField filterField; JButton restartButton; - JButton retryConnectingButton; - JProgressBar progressBar; // the calling editor, so updates can be applied Editor editor; - String category; - String compatibleCheckboxLabel; - boolean isCompatibilityFilter; - ContributionListing contribListing; - - - public ContributionManagerDialog(ContributionType type) { - if (type == null) { - title = Language.text("contrib.manager_title.update"); - filter = ContributionType.createUpdateFilter(); - compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.update"); - } else { - if (type == ContributionType.MODE) { - title = Language.text("contrib.manager_title.mode"); - compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.mode"); - } - else if (type == ContributionType.TOOL) { - title = Language.text("contrib.manager_title.tool"); - compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.tool"); - } - else if (type == ContributionType.LIBRARY) { - title = Language.text("contrib.manager_title.library"); - compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.library"); - } - else if (type == ContributionType.EXAMPLES) { - title = Language.text("contrib.manager_title.examples"); - compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.examples"); - } - - filter = type.createFilter(); - } - contribListing = ContributionListing.getInstance(); - contributionListPanel = new ContributionListPanel(this, filter); - contribListing.addContributionListener(contributionListPanel); + + //The tabs + ContributionTab toolsContributionTab; + ContributionTab librariesContributionTab; + ContributionTab examplesContributionTab; + ContributionTab modesContributionTab; + ContributionTab updatesContributionTab; + + public ContributionManagerDialog() { + toolsContributionTab = new ContributionTab(ContributionType.TOOL); + librariesContributionTab = new ContributionTab(ContributionType.LIBRARY); + modesContributionTab = new ContributionTab(ContributionType.MODE); + examplesContributionTab = new ContributionTab(ContributionType.EXAMPLES); + updatesContributionTab = new ContributionTab(null); } - public boolean hasUpdates() { - return contribListing.hasUpdates(); + return toolsContributionTab.hasUpdates() + || librariesContributionTab.hasUpdates() + || examplesContributionTab.hasUpdates() + || modesContributionTab.hasUpdates(); } - public boolean hasUpdates(Base base) { - return contribListing.hasUpdates(base); + return toolsContributionTab.hasUpdates(base) + || modesContributionTab.hasUpdates(base) + || librariesContributionTab.hasUpdates(base) + || examplesContributionTab.hasUpdates(base); } - - public void showFrame(final Editor editor) { + public void showFrame(final Editor editor, ContributionType contributionType) { this.editor = editor; + //Calculating index to switch to the required tab + int index; + if (contributionType == ContributionType.TOOL) { + index = 0; + } else if (contributionType == ContributionType.LIBRARY) { + index = 1; + } else if (contributionType == ContributionType.MODE) { + index = 2; + } else if (contributionType == ContributionType.EXAMPLES) { + index = 3; + } else { + index = 4; + } if (dialog == null) { - dialog = new JFrame(title); - - restartButton = new JButton(Language.text("contrib.restart")); - restartButton.setVisible(false); - restartButton.addActionListener(new ActionListener() { - - @Override - public void actionPerformed(ActionEvent arg0) { - - Iterator iter = editor.getBase().getEditors().iterator(); - while (iter.hasNext()) { - Editor ed = iter.next(); - if (ed.getSketch().isModified()) { - int option = Base - .showYesNoQuestion(editor, title, - Language.text("contrib.unsaved_changes"), - Language.text("contrib.unsaved_changes.prompt")); - - if (option == JOptionPane.NO_OPTION) - return; - else - break; - } - } + makeFrame(editor); + tabbedPane.setSelectedIndex(index); //done before as downloadAndUpdateContributionListing() requires the current selected tab + downloadAndUpdateContributionListing(editor.getBase()); + } + tabbedPane.setSelectedIndex(index); + dialog.setVisible(true); + } - // Why the f*k is this happening here? This is nuts, and likely - // to cause all kinds of hell across different platforms. [fry] - // Thanks to http://stackoverflow.com/a/4160543 - StringBuilder cmd = new StringBuilder(); - cmd.append(System.getProperty("java.home") + File.separator + "bin" - + File.separator + "java "); - for (String jvmArg : ManagementFactory.getRuntimeMXBean() - .getInputArguments()) { - cmd.append(jvmArg + " "); - } - cmd.append("-cp ") - .append(ManagementFactory.getRuntimeMXBean().getClassPath()) - .append(" "); - cmd.append(Base.class.getName()); - - try { - Runtime.getRuntime().exec(cmd.toString()); - System.exit(0); - } catch (IOException e) { - e.printStackTrace(); - } + public void makeFrame(final Editor editor) { + dialog = new JFrame(title); + tabbedPane = new JTabbedPane(); - } + toolsContributionTab.showFrame(editor); - }); + tabbedPane.addTab("Tools", null, toolsContributionTab.panel, "Tools"); + tabbedPane.setMnemonicAt(0, KeyEvent.VK_1); + + librariesContributionTab.showFrame(editor); + tabbedPane.addTab("Libraries", null, librariesContributionTab.panel, + "Libraries"); + tabbedPane.setMnemonicAt(1, KeyEvent.VK_2); + + modesContributionTab.showFrame(editor); + tabbedPane.addTab("Modes", null, modesContributionTab.panel, "Modes"); + tabbedPane.setMnemonicAt(2, KeyEvent.VK_3); + + examplesContributionTab.showFrame(editor); + tabbedPane.addTab("Examples", null, examplesContributionTab.panel, + "Examples"); + tabbedPane.setMnemonicAt(3, KeyEvent.VK_4); + + updatesContributionTab.showFrame(editor); + tabbedPane.addTab("Updates", null, updatesContributionTab.panel, "Updates"); + tabbedPane.setMnemonicAt(3, KeyEvent.VK_5); + + dialog.add(tabbedPane); - retryConnectingButton = new JButton("Retry"); - retryConnectingButton.setVisible(false); - retryConnectingButton.addActionListener(new ActionListener() { + restartButton = new JButton(Language.text("contrib.restart")); + restartButton.setVisible(false); + restartButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent arg0) { - // The message is set to null so that every time the retry button is hit - // no previous error is displayed in the status - status.setMessage(null); - downloadAndUpdateContributionListing(editor.getBase()); + @Override + public void actionPerformed(ActionEvent arg0) { + + Iterator iter = editor.getBase().getEditors().iterator(); + while (iter.hasNext()) { + Editor ed = iter.next(); + if (ed.getSketch().isModified()) { + int option = Base.showYesNoQuestion(editor, title, Language + .text("contrib.unsaved_changes"), Language + .text("contrib.unsaved_changes.prompt")); + + if (option == JOptionPane.NO_OPTION) + return; + else + break; + } } - }); - progressBar = new JProgressBar(); - progressBar.setVisible(true); + // Thanks to http://stackoverflow.com/a/4160543 + StringBuilder cmd = new StringBuilder(); + cmd.append(System.getProperty("java.home") + File.separator + "bin" + + File.separator + "java "); + for (String jvmArg : ManagementFactory.getRuntimeMXBean() + .getInputArguments()) { + cmd.append(jvmArg + " "); + } + cmd.append("-cp ") + .append(ManagementFactory.getRuntimeMXBean().getClassPath()) + .append(" "); + cmd.append(Base.class.getName()); + + try { + Runtime.getRuntime().exec(cmd.toString()); + System.exit(0); + } catch (IOException e) { + e.printStackTrace(); + } - Toolkit.setIcon(dialog); - createComponents(); - registerDisposeListeners(); + } - dialog.pack(); - dialog.setLocationRelativeTo(null); - } - dialog.setVisible(true); - contributionListPanel.grabFocus(); + }); - if (contribListing.hasDownloadedLatestList()) { - updateContributionListing(); + Toolkit.setIcon(dialog); + registerDisposeListeners(); - } else { - downloadAndUpdateContributionListing(editor.getBase()); - } + dialog.pack(); + dialog.setLocationRelativeTo(null); } - /** * Close the window after an OK or Cancel. */ protected void disposeFrame() { - status.clear(); dialog.dispose(); editor = null; } - - /** Creates and arranges the Swing components in the dialog. */ - private void createComponents() { +/* *//** + * Creates and arranges the Swing components in the dialog. + * + * @param panel1 + *//* + private void createComponents(JPanel panel1) { dialog.setResizable(true); - Container pane = dialog.getContentPane(); + Container pane = panel1; // pane.setLayout(new GridBagLayout()); // // { // Shows "Filter by Category" and the combo box for selecting a category @@ -217,56 +212,56 @@ private void createComponents() { // c.gridy = 0; pane.setLayout(new BorderLayout()); - JPanel filterPanel = new JPanel(); - filterPanel.setLayout(new BoxLayout(filterPanel, BoxLayout.X_AXIS)); + JPanel filterPanel = new JPanel(); + filterPanel.setLayout(new BoxLayout(filterPanel, BoxLayout.X_AXIS)); // pane.add(filterPanel, c); - pane.add(filterPanel, BorderLayout.NORTH); + pane.add(filterPanel, BorderLayout.NORTH); - filterPanel.add(Box.createHorizontalStrut(6)); + filterPanel.add(Box.createHorizontalStrut(6)); - JLabel categoryLabel = new JLabel(Language.text("contrib.category")); - filterPanel.add(categoryLabel); + JLabel categoryLabel = new JLabel(Language.text("contrib.category")); + filterPanel.add(categoryLabel); - filterPanel.add(Box.createHorizontalStrut(5)); + filterPanel.add(Box.createHorizontalStrut(5)); - categoryChooser = new JComboBox(); - categoryChooser.setMaximumRowCount(20); - updateCategoryChooser(); + categoryChooser = new JComboBox(); + categoryChooser.setMaximumRowCount(20); + updateCategoryChooser(); // filterPanel.add(categoryChooser, c); - filterPanel.add(categoryChooser); - categoryChooser.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - category = (String) categoryChooser.getSelectedItem(); - if (ContributionManagerDialog.ANY_CATEGORY.equals(category)) { - category = null; - } - filterLibraries(category, filterField.filters, isCompatibilityFilter); - contributionListPanel.updateColors(); + filterPanel.add(categoryChooser); + categoryChooser.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + category = (String) categoryChooser.getSelectedItem(); + if (ContributionManagerDialog.ANY_CATEGORY.equals(category)) { + category = null; } - }); + filterLibraries(category, filterField.filters, isCompatibilityFilter); + contributionListPanel.updateColors(); + } + }); - filterPanel.add(Box.createHorizontalStrut(5)); + filterPanel.add(Box.createHorizontalStrut(5)); // filterPanel.add(Box.createHorizontalGlue()); - filterField = new FilterField(); - filterPanel.add(filterField); + filterField = new FilterField(); + filterPanel.add(filterField); - filterPanel.add(Box.createHorizontalStrut(5)); + filterPanel.add(Box.createHorizontalStrut(5)); - final JCheckBox compatibleContrib = new JCheckBox(compatibleCheckboxLabel); - compatibleContrib.addItemListener(new ItemListener() { + final JCheckBox compatibleContrib = new JCheckBox(compatibleCheckboxLabel); + compatibleContrib.addItemListener(new ItemListener() { - @Override - public void itemStateChanged(ItemEvent arg0) { - isCompatibilityFilter = compatibleContrib.isSelected(); - filterLibraries(category, filterField.filters, isCompatibilityFilter); - contributionListPanel.updateColors(); - } - }); - filterPanel.add(compatibleContrib); + @Override + public void itemStateChanged(ItemEvent arg0) { + isCompatibilityFilter = compatibleContrib.isSelected(); + filterLibraries(category, filterField.filters, isCompatibilityFilter); + contributionListPanel.updateColors(); + } + }); + filterPanel.add(compatibleContrib); // filterPanel.add(Box.createHorizontalGlue()); // } - //filterPanel.setBorder(new EmptyBorder(13, 13, 13, 13)); - filterPanel.setBorder(new EmptyBorder(7, 7, 7, 7)); + //filterPanel.setBorder(new EmptyBorder(13, 13, 13, 13)); + filterPanel.setBorder(new EmptyBorder(7, 7, 7, 7)); // { // The scroll area containing the contribution listing and the status bar. // GridBagConstraints c = new GridBagConstraints(); @@ -277,38 +272,39 @@ public void itemStateChanged(ItemEvent arg0) { // c.weighty = 1; // c.weightx = 1; - scrollPane = new JScrollPane(); - scrollPane.setPreferredSize(new Dimension(300, 300)); - scrollPane.setViewportView(contributionListPanel); + scrollPane = new JScrollPane(); + scrollPane.setPreferredSize(new Dimension(300, 300)); + scrollPane.setViewportView(contributionListPanel); // scrollPane.getViewport().setOpaque(true); // scrollPane.getViewport().setBackground(contributionListPanel.getBackground()); - scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); - scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane + .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane + .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); // scrollPane.setBorder(new EmptyBorder(0, 7, 0, 7)); - pane.add(scrollPane, BorderLayout.CENTER); + pane.add(scrollPane, BorderLayout.CENTER); - pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST); - pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST); + pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST); + pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST); - status = new StatusPanel(); + status = new StatusPanel(); // status.setBorder(new EmptyBorder(7, 7, 7, 7)); - JPanel statusRestartPane = new JPanel(); - statusRestartPane.setLayout(new BorderLayout()); + JPanel statusRestartPane = new JPanel(); + statusRestartPane.setLayout(new BorderLayout()); - statusRestartPane.setBorder(new EmptyBorder(7, 7, 7, 7)); - statusRestartPane.setOpaque(false); + statusRestartPane.setBorder(new EmptyBorder(7, 7, 7, 7)); + statusRestartPane.setOpaque(false); - statusRestartPane.add(status, BorderLayout.WEST); - statusRestartPane.add(progressBar, BorderLayout.LINE_END); + statusRestartPane.add(status, BorderLayout.WEST); + statusRestartPane.add(progressBar, BorderLayout.LINE_END); - // Adding both of these to EAST shouldn't pose too much of a problem, + Adding both of these to EAST shouldn't pose too much of a problem, // since they can never get added together. - statusRestartPane.add(restartButton, BorderLayout.EAST); - statusRestartPane.add(retryConnectingButton, BorderLayout.EAST); - - pane.add(statusRestartPane, BorderLayout.SOUTH); + statusRestartPane.add(restartButton, BorderLayout.EAST); + statusRestartPane.add(retryConnectingButton, BorderLayout.EAST); + pane.add(statusRestartPane, BorderLayout.SOUTH); // status = new StatusPanel(); // status.setBorder(BorderFactory.createEtchedBorder()); @@ -369,7 +365,6 @@ public void itemStateChanged(ItemEvent arg0) { dialog.setMinimumSize(new Dimension(450, 400)); } - private void updateCategoryChooser() { if (categoryChooser != null) { ArrayList categories; @@ -391,8 +386,7 @@ private void updateCategoryChooser() { categoryChooser.setEnabled(categoriesFound); } } - - +*/ private void registerDisposeListeners() { dialog.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { @@ -410,36 +404,35 @@ public void actionPerformed(ActionEvent actionEvent) { public void keyPressed(KeyEvent e) { //System.out.println(e); KeyStroke wc = Toolkit.WINDOW_CLOSE_KEYSTROKE; - if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) || - (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) { + if ((e.getKeyCode() == KeyEvent.VK_ESCAPE) + || (KeyStroke.getKeyStrokeForEvent(e).equals(wc))) { disposeFrame(); } } }); } - - protected void filterLibraries(String category, List filters) { - List filteredLibraries = - contribListing.getFilteredLibraryList(category, filters); + /*protected void filterLibraries(String category, List filters) { + List filteredLibraries = contribListing + .getFilteredLibraryList(category, filters); contributionListPanel.filterLibraries(filteredLibraries); } - - protected void filterLibraries(String category, List filters, boolean isCompatibilityFilter) { - List filteredLibraries = - contribListing.getFilteredLibraryList(category, filters); - filteredLibraries = contribListing.getCompatibleContributionList(filteredLibraries, isCompatibilityFilter); + protected void filterLibraries(String category, List filters, + boolean isCompatibilityFilter) { + List filteredLibraries = contribListing + .getFilteredLibraryList(category, filters); + filteredLibraries = contribListing + .getCompatibleContributionList(filteredLibraries, isCompatibilityFilter); contributionListPanel.filterLibraries(filteredLibraries); } - - - protected void updateContributionListing() { +*/ + /*protected void updateContributionListing() { if (editor != null) { - List contributions = new ArrayList(); + ArrayList contributions = new ArrayList(); - List libraries = - new ArrayList(editor.getMode().contribLibraries); + ArrayList libraries = new ArrayList( + editor.getMode().contribLibraries); contributions.addAll(libraries); //ArrayList tools = editor.contribTools; @@ -449,7 +442,8 @@ protected void updateContributionListing() { List modes = editor.getBase().getModeContribs(); contributions.addAll(modes); - List examples = editor.getBase().getExampleContribs(); + List examples = editor.getBase() + .getExampleContribs(); contributions.addAll(examples); // ArrayList compilations = LibraryCompilation.list(libraries); @@ -468,24 +462,22 @@ protected void updateContributionListing() { contribListing.updateInstalledList(contributions); } } - - +*/ protected void downloadAndUpdateContributionListing(Base base) { - if (!UpdateCheck.isAllowed()) { - // A dialog box seems to in-your-face, but not saying anything seems - // problematic. This isn't a great option but it'll do for beta 1. - System.out.println("Cannot update contributions because " + - "updates are disabled in preferences."); - return; // update checking phones home! IT! PHONES! HOME! - } - - retryConnectingButton.setEnabled(false); - status.setMessage(Language.text("contrib.status.downloading_list")); - contribListing.downloadAvailableList(base, new ContribProgressBar(progressBar) { + + //activeTab is required now but should be removed + //as there is only one instance of contribListing and it should be present in this class + final ContributionTab activeTab = getActiveTab(); + activeTab.retryConnectingButton.setEnabled(false); + activeTab.status.setMessage(Language + .text("contrib.status.downloading_list")); + activeTab.contribListing.downloadAvailableList(base, new ContribProgressBar( + activeTab.progressBar) { @Override public void startTask(String name, int maxValue) { super.startTask(name, maxValue); + progressBar.setVisible(true); progressBar.setString(null); } @@ -495,38 +487,59 @@ public void setProgress(int value) { // int percent = 100 * value / this.max; progressBar.setValue(value); progressBar.setStringPainted(true); - status.setMessage(Language.text("contrib.status.downloading_list")); + activeTab.status.setMessage(Language + .text("contrib.status.downloading_list")); } @Override public void finishedAction() { progressBar.setVisible(false); + activeTab.updateContributionListing(); + activeTab.updateCategoryChooser(); - updateContributionListing(); - updateCategoryChooser(); - - retryConnectingButton.setEnabled(true); + activeTab.retryConnectingButton.setEnabled(true); if (error) { if (exception instanceof SocketTimeoutException) { - status.setErrorMessage(Language + activeTab.status.setErrorMessage(Language .text("contrib.errors.list_download.timeout")); } else { - status.setErrorMessage(Language + activeTab.status.setErrorMessage(Language .text("contrib.errors.list_download")); } exception.printStackTrace(); - retryConnectingButton.setVisible(true); + activeTab.retryConnectingButton.setVisible(true); } else { - status.setMessage(Language.text("contrib.status.done")); - retryConnectingButton.setVisible(false); + activeTab.status.setMessage(Language.text("contrib.status.done")); + activeTab.retryConnectingButton.setVisible(false); } } }); } + /** + * + * @return the currently selected tab + */ + private ContributionTab getActiveTab() { + + switch (tabbedPane.getSelectedIndex()) { + case 0: + return toolsContributionTab; + case 1: + return librariesContributionTab; + case 2: + return modesContributionTab; + case 3: + return examplesContributionTab; + default: + return updatesContributionTab; + } + + } +/* protected void setFilterText(String filter) { if (filter == null || filter.isEmpty()) { filterField.setText(""); @@ -538,18 +551,18 @@ protected void setFilterText(String filter) { filterField.applyFilter(); } - // private JPanel getPlaceholder() { // return contributionListPanel.statusPlaceholder; // } - class FilterField extends JTextField { String filterHint; + boolean showingHint; + List filters; - public FilterField () { + public FilterField() { super(Language.text("contrib.filter_your_search")); filterHint = Language.text("contrib.filter_your_search"); @@ -616,8 +629,7 @@ public void updateStyle() { setFont(getFont().deriveFont(Font.PLAIN)); } } - } - + }*/ public boolean hasAlreadyBeenOpened() { return dialog != null; diff --git a/app/src/processing/app/contrib/ContributionPanel.java b/app/src/processing/app/contrib/ContributionPanel.java index 3d937fd151..2110a3321d 100644 --- a/app/src/processing/app/contrib/ContributionPanel.java +++ b/app/src/processing/app/contrib/ContributionPanel.java @@ -128,7 +128,7 @@ public void hyperlinkUpdate(HyperlinkEvent e) { installActionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { - listPanel.contribManager.status.clear(); + listPanel.contributionTab.status.clear(); isInstallInProgress = true; ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); if (contrib instanceof AvailableContribution) { @@ -140,7 +140,7 @@ public void actionPerformed(ActionEvent e) { undoActionListener = new ActionListener() { public void actionPerformed(ActionEvent e) { - listPanel.contribManager.status.clear(); + listPanel.contributionTab.status.clear(); if (contrib instanceof LocalContribution) { LocalContribution installed = (LocalContribution) contrib; installed.setDeletionFlag(false); @@ -157,14 +157,14 @@ public void actionPerformed(ActionEvent e) { } } } - listPanel.contribManager.restartButton.setVisible(toBeRestarted); + listPanel.contributionTab.restartButton.setVisible(toBeRestarted); } } }; removeActionListener = new ActionListener() { public void actionPerformed(ActionEvent arg) { - listPanel.contribManager.status.clear(); + listPanel.contributionTab.status.clear(); if (contrib.isInstalled() && contrib instanceof LocalContribution) { isRemoveInProgress = true; ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, PROGRESS_BAR_CONSTRAINT); @@ -193,12 +193,12 @@ public void cancel() { reorganizePaneComponents(); setSelected(true); - ContributionManagerDialog manager = listPanel.contribManager; + ContributionTab contributionTab = listPanel.contributionTab; boolean isModeActive = false; if (contrib.getType() == ContributionType.MODE) { ModeContribution m = (ModeContribution) contrib; // TODO there's gotta be a cleaner way to do this accessor - for (Editor e : manager.editor.getBase().getEditors()) { + for (Editor e : contributionTab.editor.getBase().getEditors()) { //Iterator iter = listPanel.contribManager.editor.getBase().getEditors().iterator(); //while (iter.hasNext()) { //Editor e = iter.next(); @@ -211,13 +211,13 @@ public void cancel() { if (isModeActive) { updateButton.setEnabled(true); } else { - manager.restartButton.setVisible(true); + contributionTab.restartButton.setVisible(true); } } }; - ContributionManagerDialog manager = listPanel.contribManager; + ContributionTab contributionTab = listPanel.contributionTab; LocalContribution localContrib = (LocalContribution) contrib; - localContrib.removeContribution(manager.editor, monitor, manager.status); + localContrib.removeContribution(contributionTab.editor, monitor, contributionTab.status); } } }; @@ -248,7 +248,7 @@ public void mousePressed(MouseEvent e) { } else { final String msg = contrib.getName() + " is not compatible with this version of Processing"; - listPanel.contribManager.status.setErrorMessage(msg); + listPanel.contributionTab.status.setErrorMessage(msg); } } }); @@ -306,7 +306,7 @@ private void addPaneComponents() { updateButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - listPanel.contribManager.status.clear(); + listPanel.contributionTab.status.clear(); isUpdateInProgress = true; if (contrib.getType().requiresRestart()) { installRemoveButton.setEnabled(false); @@ -328,7 +328,7 @@ public void finishedAction() { public void cancel() { super.cancel(); resetInstallProgressBarState(); - listPanel.contribManager.status.setMessage(""); + listPanel.contributionTab.status.setMessage(""); isUpdateInProgress = false; installRemoveButton.setEnabled(true); if (contrib.isDeletionFlagged()) { @@ -343,7 +343,7 @@ public void cancel() { //Iterator iter = listPanel.contribManager.editor.getBase().getEditors().iterator(); //while (iter.hasNext()) { // TODO there's gotta be a cleaner way to do this accessor - Base base = listPanel.contribManager.editor.getBase(); + Base base = listPanel.contributionTab.editor.getBase(); for (Editor e : base.getEditors()) { //Editor e = iter.next(); if (e.getMode().equals(m.getMode())) { @@ -355,13 +355,13 @@ public void cancel() { if (isModeActive) { updateButton.setEnabled(true); } else { - listPanel.contribManager.restartButton.setVisible(true); + listPanel.contributionTab.restartButton.setVisible(true); } } }; ((LocalContribution) contrib) - .removeContribution(listPanel.contribManager.editor, - progress, listPanel.contribManager.status); + .removeContribution(listPanel.contributionTab.editor, + progress, listPanel.contributionTab.status); } else { updateButton.setEnabled(false); installRemoveButton.setEnabled(false); @@ -689,7 +689,7 @@ else if (version.toLowerCase().startsWith("v")) // For ketai library private void installContribution(AvailableContribution info) { if (info.link == null) { - listPanel.contribManager.status.setErrorMessage(Language.interpolate("contrib.unsupported_operating_system", info.getType())); + listPanel.contributionTab.status.setErrorMessage(Language.interpolate("contrib.unsupported_operating_system", info.getType())); } else { installContribution(info, info.link); } @@ -729,7 +729,7 @@ public void finishedAction() { installRemoveButton.setEnabled(!contrib.isUpdateFlagged()); if (isError()) { - listPanel.contribManager.status.setErrorMessage(Language.text("contrib.download_error")); + listPanel.contributionTab.status.setErrorMessage(Language.text("contrib.download_error")); } ((CardLayout) barButtonCardPane.getLayout()).show(barButtonCardPane, BUTTON_CONSTRAINT); isInstallInProgress = false; @@ -744,10 +744,10 @@ public void cancel() { } }; - ContributionManager.downloadAndInstall(listPanel.contribManager.editor, + ContributionManager.downloadAndInstall(listPanel.contributionTab.editor, downloadUrl, ad, downloadProgress, installProgress, - listPanel.contribManager.status); + listPanel.contributionTab.status); } catch (MalformedURLException e) { Base.showWarning(Language.text("contrib.errors.install_failed"), diff --git a/app/src/processing/app/contrib/ContributionTab.java b/app/src/processing/app/contrib/ContributionTab.java new file mode 100644 index 0000000000..03db75ebac --- /dev/null +++ b/app/src/processing/app/contrib/ContributionTab.java @@ -0,0 +1,589 @@ +/* -*- mode: java; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2013 The Processing Foundation + Copyright (c) 2011-12 Ben Fry and Casey Reas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 + as published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +package processing.app.contrib; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.event.*; +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.net.SocketTimeoutException; +import java.util.*; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import javax.swing.event.*; + +import processing.app.*; + + +public class ContributionTab { + static final String ANY_CATEGORY = Language.text("contrib.all"); + + JPanel panel; + ContributionType contributionType; + String title; + ContributionFilter filter; + JComboBox categoryChooser; + JScrollPane scrollPane; + ContributionListPanel contributionListPanel; + StatusPanel status; + FilterField filterField; + JButton restartButton; + JButton retryConnectingButton; + JProgressBar progressBar; + + // the calling editor, so updates can be applied + Editor editor; + String category; + String compatibleCheckboxLabel; + boolean isCompatibilityFilter; + ContributionListing contribListing; + + + public ContributionTab(ContributionType type) { + if (type == null) { + title = Language.text("contrib.manager_title.update"); + filter = ContributionType.createUpdateFilter(); + compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.update"); + } else { + if (type == ContributionType.MODE) { + title = Language.text("contrib.manager_title.mode"); + compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.mode"); + } + else if (type == ContributionType.TOOL) { + title = Language.text("contrib.manager_title.tool"); + compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.tool"); + } + else if (type == ContributionType.LIBRARY) { + title = Language.text("contrib.manager_title.library"); + compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.library"); + } + else if (type == ContributionType.EXAMPLES) { + title = Language.text("contrib.manager_title.examples"); + compatibleCheckboxLabel = Language.text("contrib.show_only_compatible.examples"); + } + + filter = type.createFilter(); + } + contribListing = ContributionListing.getInstance(); + contributionListPanel = new ContributionListPanel(this, filter); + contribListing.addContributionListener(contributionListPanel); + } + + + public boolean hasUpdates() { + return contribListing.hasUpdates(); + } + + + public boolean hasUpdates(Base base) { + return contribListing.hasUpdates(base); + } + +// protected JPanel makeTextPanel(String text) { +// JPanel panel = new JPanel(false); +// JLabel filler = new JLabel(text); +// filler.setHorizontalAlignment(JLabel.CENTER); +// panel.setLayout(new GridLayout(1, 1)); +// panel.add(filler); +// return panel; +// } + + public void showFrame(final Editor editor) { + this.editor = editor; + + if (panel == null) { + makePanel(editor); + } + panel.setVisible(true); +// contributionListPanel.grabFocus(); + +// if (!contribListing.hasDownloadedLatestList()) { +// updateContributionListing(); +// downloadAndUpdateContributionListing(); +// } + } + + + public void makePanel(final Editor editor) { + panel = new JPanel(true); + + restartButton = new JButton(Language.text("contrib.restart")); + restartButton.setVisible(false); + restartButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + + Iterator iter = editor.getBase().getEditors().iterator(); + while (iter.hasNext()) { + Editor ed = iter.next(); + if (ed.getSketch().isModified()) { + int option = Base + .showYesNoQuestion(editor, title, + Language.text("contrib.unsaved_changes"), + Language.text("contrib.unsaved_changes.prompt")); + + if (option == JOptionPane.NO_OPTION) + return; + else + break; + } + } + + // Thanks to http://stackoverflow.com/a/4160543 + StringBuilder cmd = new StringBuilder(); + cmd.append(System.getProperty("java.home") + File.separator + "bin" + + File.separator + "java "); + for (String jvmArg : ManagementFactory.getRuntimeMXBean() + .getInputArguments()) { + cmd.append(jvmArg + " "); + } + cmd.append("-cp ") + .append(ManagementFactory.getRuntimeMXBean().getClassPath()) + .append(" "); + cmd.append(Base.class.getName()); + + try { + Runtime.getRuntime().exec(cmd.toString()); + System.exit(0); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + }); + + retryConnectingButton = new JButton("Retry"); + retryConnectingButton.setVisible(false); + retryConnectingButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + // The message is set to null so that every time the retry button is hit + // no previous error is displayed in the status + status.setMessage(null); + downloadAndUpdateContributionListing(editor.getBase()); + } + }); + + progressBar = new JProgressBar(); + progressBar.setVisible(false); + + createComponents(); + } + + + /** Creates and arranges the Swing components in the dialog. + */ + private void createComponents() { + + Container pane = panel; +// pane.setLayout(new GridBagLayout()); +// +// { // Shows "Filter by Category" and the combo box for selecting a category +// GridBagConstraints c = new GridBagConstraints(); +// c.gridx = 0; +// c.gridy = 0; + pane.setLayout(new BorderLayout()); + + JPanel filterPanel = new JPanel(); + filterPanel.setLayout(new BoxLayout(filterPanel, BoxLayout.X_AXIS)); +// pane.add(filterPanel, c); + pane.add(filterPanel, BorderLayout.NORTH); + + filterPanel.add(Box.createHorizontalStrut(6)); + + JLabel categoryLabel = new JLabel(Language.text("contrib.category")); + filterPanel.add(categoryLabel); + + filterPanel.add(Box.createHorizontalStrut(5)); + + categoryChooser = new JComboBox(); + categoryChooser.setMaximumRowCount(20); + + updateCategoryChooser(); + +// filterPanel.add(categoryChooser, c); + filterPanel.add(categoryChooser); + categoryChooser.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + category = (String) categoryChooser.getSelectedItem(); + if (ContributionManagerDialog.ANY_CATEGORY.equals(category)) { + category = null; + } + filterLibraries(category, filterField.filters, isCompatibilityFilter); + contributionListPanel.updateColors(); + } + }); + + filterPanel.add(Box.createHorizontalStrut(5)); +// filterPanel.add(Box.createHorizontalGlue()); + filterField = new FilterField(); + filterPanel.add(filterField); + + filterPanel.add(Box.createHorizontalStrut(5)); + + final JCheckBox compatibleContrib = new JCheckBox(compatibleCheckboxLabel); + compatibleContrib.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent arg0) { + isCompatibilityFilter = compatibleContrib.isSelected(); + filterLibraries(category, filterField.filters, isCompatibilityFilter); + contributionListPanel.updateColors(); + } + }); + filterPanel.add(compatibleContrib); +// filterPanel.add(Box.createHorizontalGlue()); +// } + //filterPanel.setBorder(new EmptyBorder(13, 13, 13, 13)); + filterPanel.setBorder(new EmptyBorder(7, 7, 7, 7)); + +// { // The scroll area containing the contribution listing and the status bar. +// GridBagConstraints c = new GridBagConstraints(); +// c.fill = GridBagConstraints.BOTH; +// c.gridx = 0; +// c.gridy = 1; +// c.gridwidth = 2; +// c.weighty = 1; +// c.weightx = 1; + + scrollPane = new JScrollPane(); + scrollPane.setPreferredSize(new Dimension(300, 300)); + scrollPane.setViewportView(contributionListPanel); +// scrollPane.getViewport().setOpaque(true); +// scrollPane.getViewport().setBackground(contributionListPanel.getBackground()); + scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); +// scrollPane.setBorder(new EmptyBorder(0, 7, 0, 7)); + pane.add(scrollPane, BorderLayout.CENTER); + + pane.add(Box.createHorizontalStrut(10), BorderLayout.WEST); + pane.add(Box.createHorizontalStrut(10), BorderLayout.EAST); + + status = new StatusPanel(); +// status.setBorder(new EmptyBorder(7, 7, 7, 7)); + + JPanel statusRestartPane = new JPanel(); + statusRestartPane.setLayout(new BorderLayout()); + + statusRestartPane.setBorder(new EmptyBorder(7, 7, 7, 7)); + statusRestartPane.setOpaque(false); + + statusRestartPane.add(status, BorderLayout.WEST); + statusRestartPane.add(progressBar, BorderLayout.LINE_END); + + // Adding both of these to EAST shouldn't pose too much of a problem, + // since they can never get added together. + statusRestartPane.add(restartButton, BorderLayout.EAST); + statusRestartPane.add(retryConnectingButton, BorderLayout.EAST); + + pane.add(statusRestartPane, BorderLayout.SOUTH); + + +// status = new StatusPanel(); +// status.setBorder(BorderFactory.createEtchedBorder()); + +// final JLayeredPane layeredPane = new JLayeredPane(); +// layeredPane.add(scrollPane, JLayeredPane.DEFAULT_LAYER); +// layeredPane.add(status, JLayeredPane.PALETTE_LAYER); +// +// layeredPane.addComponentListener(new ComponentAdapter() { +// +// void resizeLayers() { +// scrollPane.setSize(layeredPane.getSize()); +// scrollPane.updateUI(); +// } +// +// public void componentShown(ComponentEvent e) { +// resizeLayers(); +// } +// +// public void componentResized(ComponentEvent arg0) { +// resizeLayers(); +// } +// }); +// +// final JViewport viewport = scrollPane.getViewport(); +// viewport.addComponentListener(new ComponentAdapter() { +// void resizeLayers() { +// status.setLocation(0, viewport.getHeight() - 18); +// +// Dimension d = viewport.getSize(); +// d.height = 20; +// d.width += 3; +// status.setSize(d); +// } +// public void componentShown(ComponentEvent e) { +// resizeLayers(); +// } +// public void componentResized(ComponentEvent e) { +// resizeLayers(); +// } +// }); +// +// pane.add(layeredPane, c); +// } + +// { // The filter text area +// GridBagConstraints c = new GridBagConstraints(); +// c.gridx = 0; +// c.gridy = 2; +// c.gridwidth = 2; +// c.weightx = 1; +// c.fill = GridBagConstraints.HORIZONTAL; +// filterField = new FilterField(); +// +// pane.add(filterField, c); +// } + + panel.setMinimumSize(new Dimension(450, 400)); + } + + + protected void updateCategoryChooser() { + if (categoryChooser != null) { + ArrayList categories; + categoryChooser.removeAllItems(); + categories = new ArrayList(contribListing.getCategories(filter)); +// for (int i = 0; i < categories.size(); i++) { +// System.out.println(i + " category: " + categories.get(i)); +// } + Collections.sort(categories); +// categories.add(0, ContributionManagerDialog.ANY_CATEGORY); + boolean categoriesFound = false; + categoryChooser.addItem(ContributionManagerDialog.ANY_CATEGORY); + for (String s : categories) { + categoryChooser.addItem(s); + if (!s.equals("Unknown")) { + categoriesFound = true; + } + } + categoryChooser.setEnabled(categoriesFound); + } + } + + + protected void filterLibraries(String category, List filters) { + List filteredLibraries = + contribListing.getFilteredLibraryList(category, filters); + contributionListPanel.filterLibraries(filteredLibraries); + } + + + protected void filterLibraries(String category, List filters, boolean isCompatibilityFilter) { + List filteredLibraries = + contribListing.getFilteredLibraryList(category, filters); + filteredLibraries = contribListing.getCompatibleContributionList(filteredLibraries, isCompatibilityFilter); + contributionListPanel.filterLibraries(filteredLibraries); + } + + + protected void updateContributionListing() { + if (editor != null) { + List contributions = new ArrayList(); + + List libraries = + new ArrayList(editor.getMode().contribLibraries); + contributions.addAll(libraries); + + //ArrayList tools = editor.contribTools; + List tools = editor.getToolContribs(); + contributions.addAll(tools); + + List modes = editor.getBase().getModeContribs(); + contributions.addAll(modes); + + List examples = editor.getBase().getExampleContribs(); + contributions.addAll(examples); + +// ArrayList compilations = LibraryCompilation.list(libraries); +// +// // Remove libraries from the list that are part of a compilations +// for (LibraryCompilation compilation : compilations) { +// Iterator it = libraries.iterator(); +// while (it.hasNext()) { +// Library current = it.next(); +// if (compilation.getFolder().equals(current.getFolder().getParentFile())) { +// it.remove(); +// } +// } +// } + + contribListing.updateInstalledList(contributions); + } + } + + + protected void downloadAndUpdateContributionListing(Base base) { + retryConnectingButton.setEnabled(false); + status.setMessage(Language.text("contrib.status.downloading_list")); + contribListing.downloadAvailableList(base, new ContribProgressBar(progressBar) { + + + @Override + public void startTask(String name, int maxValue) { + super.startTask(name, maxValue); + progressBar.setString(null); + } + + @Override + public void setProgress(int value) { + super.setProgress(value); +// int percent = 100 * value / this.max; + progressBar.setValue(value); + progressBar.setStringPainted(true); + status.setMessage(Language.text("contrib.status.downloading_list")); + } + + @Override + public void finishedAction() { + progressBar.setVisible(false); + + updateContributionListing(); + updateCategoryChooser(); + + retryConnectingButton.setEnabled(true); + + if (error) { + if (exception instanceof SocketTimeoutException) { + status.setErrorMessage(Language + .text("contrib.errors.list_download.timeout")); + } else { + status.setErrorMessage(Language + .text("contrib.errors.list_download")); + } + exception.printStackTrace(); + retryConnectingButton.setVisible(true); + + } else { + status.setMessage(Language.text("contrib.status.done")); + retryConnectingButton.setVisible(false); + } + } + }); + } + + + protected void setFilterText(String filter) { + if (filter == null || filter.isEmpty()) { + filterField.setText(""); + filterField.showingHint = true; + } else { + filterField.setText(filter); + filterField.showingHint = false; + } + filterField.applyFilter(); + } + + +// private JPanel getPlaceholder() { +// return contributionListPanel.statusPlaceholder; +// } + + + class FilterField extends JTextField { + String filterHint; + boolean showingHint; + List filters; + + public FilterField () { + super(Language.text("contrib.filter_your_search")); + filterHint = Language.text("contrib.filter_your_search"); + + showingHint = true; + filters = new ArrayList(); + updateStyle(); + + addFocusListener(new FocusListener() { + public void focusLost(FocusEvent focusEvent) { + if (filterField.getText().isEmpty()) { + showingHint = true; + } + updateStyle(); + } + + public void focusGained(FocusEvent focusEvent) { + if (showingHint) { + showingHint = false; + filterField.setText(""); + } + updateStyle(); + } + }); + + getDocument().addDocumentListener(new DocumentListener() { + public void removeUpdate(DocumentEvent e) { + applyFilter(); + } + + public void insertUpdate(DocumentEvent e) { + applyFilter(); + } + + public void changedUpdate(DocumentEvent e) { + applyFilter(); + } + }); + } + + public void applyFilter() { + String filter = filterField.getFilterText(); + filter = filter.toLowerCase(); + + // Replace anything but 0-9, a-z, or : with a space + filter = filter.replaceAll("[^\\x30-\\x39^\\x61-\\x7a^\\x3a]", " "); + filters = Arrays.asList(filter.split(" ")); + filterLibraries(category, filters, isCompatibilityFilter); + + contributionListPanel.updateColors(); + } + + public String getFilterText() { + return showingHint ? "" : getText(); + } + + public void updateStyle() { + if (showingHint) { + setText(filterHint); + // setForeground(UIManager.getColor("TextField.light")); // too light + setForeground(Color.gray); + setFont(getFont().deriveFont(Font.ITALIC)); + } else { + setForeground(UIManager.getColor("TextField.foreground")); + setFont(getFont().deriveFont(Font.PLAIN)); + } + } + } + + + public boolean hasAlreadyBeenOpened() { + return panel != null; + } +}