/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. * * Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun * Microsystems, Inc. All Rights Reserved. * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. */ package org.netbeans.modules.ruby.railsprojects.plugins; import java.awt.Dialog; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JList; import javax.swing.JTextField; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.netbeans.api.options.OptionsDisplayer; import org.openide.DialogDescriptor; import org.openide.DialogDisplayer; import org.openide.NotifyDescriptor; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.openide.util.Parameters; import org.openide.util.RequestProcessor; /** * * @todo Use a table instead of a list for the plugin lists, use checkboxes to choose * items to be uninstalled, and show the installation date (based * on file timestamps) * @todo Add a project chooser at the top (with refresh behavior on selection) * and add the Rails Plugins actions to the global menu? * @todo If there is an error, remember that and don't allow users to select error output * lines as regular plugins * * @author Tor Norbye */ public class PluginPanel extends javax.swing.JPanel { static final String MSG_WAIT = NbBundle.getMessage(PluginPanel.class, "PleaseWait"); static final String MSG_NO_NETWORK = NbBundle.getMessage(PluginPanel.class, "NoNetwork"); static final String MSG_FETCHING_LOCAL_REPOS = NbBundle.getMessage(PluginPanel.class, "FetchingLocalRepos"); static final String MSG_FETCHING_REMOTE_REPOS = NbBundle.getMessage(PluginPanel.class, "FetchingRemoteRepos"); static final String MSG_FETCHING_LOCAL_PLUGINS = NbBundle.getMessage(PluginPanel.class, "FetchingLocalPlugins"); static final String MSG_FETCHING_REMOTE_PLUGINS = NbBundle.getMessage(PluginPanel.class, "FetchingRemotePlugins"); private final PluginManager pluginManager; private List<Plugin> installedPlugins; private List<Plugin> newPlugins; private List<String> activeRepositories; private boolean installedInitialized; private boolean newInitialized; private boolean repositoriesInitialized; private boolean installedModified; private boolean newModified; private boolean repositoriesModified; private boolean pluginsModified; /** Creates new form PluginPanel */ public PluginPanel(PluginManager pluginManager) { Parameters.notNull("pluginManager", pluginManager); initComponents(); this.pluginManager = pluginManager; } /** Return whether any plugins were modified - roots should be recomputed after panel is taken down */ public boolean isModified() { return pluginsModified; } private void refreshInstalled() { refreshPluginList(getPluginFilter(true), true, installedList, true); pluginsModified = pluginsModified || installedModified; installedModified = false; } private void refreshNew() { refreshPluginList(getPluginFilter(false), true, newList, false); newModified = false; } private void refreshRepositories() { refreshRepositoryList(getRepositoryFilter(false), true, repositoryList, true); repositoriesModified = false; } // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { pluginsTab = new javax.swing.JTabbedPane(); installedPanel = new javax.swing.JPanel(); instSearchText = new javax.swing.JTextField(); instSearchLbl = new javax.swing.JLabel(); reloadInstalledButton = new javax.swing.JButton(); uninstallButton = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); installedList = new javax.swing.JList(); updateButton = new javax.swing.JButton(); updateAllButton = new javax.swing.JButton(); newPanel = new javax.swing.JPanel(); searchNewText = new javax.swing.JTextField(); newSearchLbl = new javax.swing.JLabel(); reloadNewButton = new javax.swing.JButton(); installButton = new javax.swing.JButton(); jScrollPane2 = new javax.swing.JScrollPane(); newList = new javax.swing.JList(); repositoryPanel = new javax.swing.JPanel(); searchReposText = new javax.swing.JTextField(); repSearchLbl = new javax.swing.JLabel(); reloadReposButton = new javax.swing.JButton(); unregisterButton = new javax.swing.JButton(); jScrollPane3 = new javax.swing.JScrollPane(); repositoryList = new javax.swing.JList(); discoverButton = new javax.swing.JButton(); addUrlButton = new javax.swing.JButton(); jPanel1 = new javax.swing.JPanel(); proxyButton = new javax.swing.JButton(); FormListener formListener = new FormListener(); installedPanel.addComponentListener(formListener); instSearchText.setColumns(14); instSearchText.addActionListener(formListener); instSearchLbl.setLabelFor(instSearchText); org.openide.awt.Mnemonics.setLocalizedText(instSearchLbl, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.instSearchLbl.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(reloadInstalledButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.reloadInstalledButton.text")); // NOI18N reloadInstalledButton.addActionListener(formListener); org.openide.awt.Mnemonics.setLocalizedText(uninstallButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.uninstallButton.text")); // NOI18N uninstallButton.setEnabled(false); uninstallButton.addActionListener(formListener); jScrollPane1.setViewportView(installedList); installedList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.installedList.AccessibleContext.accessibleName")); // NOI18N installedList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.installedList.AccessibleContext.accessibleDescription")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(updateButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.updateButton.text")); // NOI18N updateButton.setEnabled(false); updateButton.addActionListener(formListener); org.openide.awt.Mnemonics.setLocalizedText(updateAllButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.updateAllButton.text")); // NOI18N updateAllButton.addActionListener(formListener); org.jdesktop.layout.GroupLayout installedPanelLayout = new org.jdesktop.layout.GroupLayout(installedPanel); installedPanel.setLayout(installedPanelLayout); installedPanelLayout.setHorizontalGroup( installedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(installedPanelLayout.createSequentialGroup() .addContainerGap() .add(installedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE) .add(org.jdesktop.layout.GroupLayout.TRAILING, installedPanelLayout.createSequentialGroup() .add(reloadInstalledButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 376, Short.MAX_VALUE) .add(instSearchLbl) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(instSearchText, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 156, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(installedPanelLayout.createSequentialGroup() .add(uninstallButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(updateButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(updateAllButton))) .addContainerGap()) ); installedPanelLayout.setVerticalGroup( installedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(installedPanelLayout.createSequentialGroup() .addContainerGap() .add(installedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(instSearchLbl) .add(reloadInstalledButton) .add(instSearchText, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 352, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .add(installedPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(uninstallButton) .add(updateAllButton) .add(updateButton)) .addContainerGap()) ); instSearchText.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.instSearchText.AccessibleContext.accessibleDescription")); // NOI18N reloadInstalledButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.reloadInstalledButton.AccessibleContext.accessibleDescription")); // NOI18N uninstallButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.uninstallButton.AccessibleContext.accessibleDescription")); // NOI18N updateButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.updateButton.AccessibleContext.accessibleDescription")); // NOI18N updateAllButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.updateAllButton.AccessibleContext.accessibleDescription")); // NOI18N pluginsTab.addTab(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.installedPanel.TabConstraints.tabTitle"), installedPanel); // NOI18N newPanel.addComponentListener(formListener); searchNewText.setColumns(14); searchNewText.addActionListener(formListener); newSearchLbl.setLabelFor(searchNewText); org.openide.awt.Mnemonics.setLocalizedText(newSearchLbl, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.newSearchLbl.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(reloadNewButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.reloadNewButton.text")); // NOI18N reloadNewButton.addActionListener(formListener); org.openide.awt.Mnemonics.setLocalizedText(installButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.installButton.text")); // NOI18N installButton.setEnabled(false); installButton.addActionListener(formListener); jScrollPane2.setViewportView(newList); newList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.newList.AccessibleContext.accessibleName")); // NOI18N newList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.newList.AccessibleContext.accessibleDescription")); // NOI18N org.jdesktop.layout.GroupLayout newPanelLayout = new org.jdesktop.layout.GroupLayout(newPanel); newPanel.setLayout(newPanelLayout); newPanelLayout.setHorizontalGroup( newPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(newPanelLayout.createSequentialGroup() .addContainerGap() .add(newPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE) .add(org.jdesktop.layout.GroupLayout.TRAILING, newPanelLayout.createSequentialGroup() .add(reloadNewButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 376, Short.MAX_VALUE) .add(newSearchLbl) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(searchNewText, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 156, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(installButton)) .addContainerGap()) ); newPanelLayout.setVerticalGroup( newPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(newPanelLayout.createSequentialGroup() .addContainerGap() .add(newPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(newSearchLbl) .add(reloadNewButton) .add(searchNewText, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 352, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .add(installButton) .addContainerGap()) ); searchNewText.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.searchNewText.AccessibleContext.accessibleDescription")); // NOI18N reloadNewButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.reloadNewButton.AccessibleContext.accessibleDescription")); // NOI18N installButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.installButton.AccessibleContext.accessibleDescription")); // NOI18N pluginsTab.addTab(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.newPanel.TabConstraints.tabTitle"), newPanel); // NOI18N repositoryPanel.addComponentListener(formListener); searchReposText.setColumns(14); searchReposText.addActionListener(formListener); repSearchLbl.setLabelFor(searchReposText); org.openide.awt.Mnemonics.setLocalizedText(repSearchLbl, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.repSearchLbl.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(reloadReposButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.reloadReposButton.text")); // NOI18N reloadReposButton.addActionListener(formListener); org.openide.awt.Mnemonics.setLocalizedText(unregisterButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.unregisterButton.text")); // NOI18N unregisterButton.setEnabled(false); unregisterButton.addActionListener(formListener); jScrollPane3.setViewportView(repositoryList); repositoryList.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.repositoryList.AccessibleContext.accessibleName")); // NOI18N repositoryList.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.repositoryList.AccessibleContext.accessibleDescription")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(discoverButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.discoverButton.text")); // NOI18N discoverButton.addActionListener(formListener); org.openide.awt.Mnemonics.setLocalizedText(addUrlButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.addUrlButton.text")); // NOI18N addUrlButton.addActionListener(formListener); org.jdesktop.layout.GroupLayout repositoryPanelLayout = new org.jdesktop.layout.GroupLayout(repositoryPanel); repositoryPanel.setLayout(repositoryPanelLayout); repositoryPanelLayout.setHorizontalGroup( repositoryPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(repositoryPanelLayout.createSequentialGroup() .addContainerGap() .add(repositoryPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jScrollPane3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE) .add(org.jdesktop.layout.GroupLayout.TRAILING, repositoryPanelLayout.createSequentialGroup() .add(discoverButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .add(addUrlButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .add(reloadReposButton) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 144, Short.MAX_VALUE) .add(repSearchLbl) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(searchReposText, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 156, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .add(unregisterButton)) .addContainerGap()) ); repositoryPanelLayout.setVerticalGroup( repositoryPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(repositoryPanelLayout.createSequentialGroup() .addContainerGap() .add(repositoryPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(repSearchLbl) .add(searchReposText, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .add(discoverButton) .add(addUrlButton) .add(reloadReposButton)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(jScrollPane3, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 352, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED) .add(unregisterButton) .addContainerGap()) ); searchReposText.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.searchReposText.AccessibleContext.accessibleDescription")); // NOI18N reloadReposButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.reloadReposButton.AccessibleContext.accessibleDescription")); // NOI18N unregisterButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.unregisterButton.AccessibleContext.accessibleDescription")); // NOI18N discoverButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.discoverButton.AccessibleContext.accessibleDescription")); // NOI18N addUrlButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.addUrlButton.AccessibleContext.accessibleDescription")); // NOI18N pluginsTab.addTab(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.repositoryPanel.TabConstraints.tabTitle"), repositoryPanel); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(proxyButton, org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.proxyButton.text")); // NOI18N proxyButton.addActionListener(formListener); org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel1Layout.createSequentialGroup() .addContainerGap() .add(proxyButton) .addContainerGap(564, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(jPanel1Layout.createSequentialGroup() .addContainerGap() .add(proxyButton) .addContainerGap(406, Short.MAX_VALUE)) ); proxyButton.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.proxyButton.AccessibleContext.accessibleDescription")); // NOI18N pluginsTab.addTab(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.jPanel1.TabConstraints.tabTitle"), jPanel1); // NOI18N org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() .addContainerGap() .add(pluginsTab, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 721, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(pluginsTab, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 468, Short.MAX_VALUE) .addContainerGap()) ); pluginsTab.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.pluginsTab.AccessibleContext.accessibleDescription")); // NOI18N getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(PluginPanel.class, "PluginPanel.AccessibleContext.accessibleDescription")); // NOI18N } // Code for dispatching events from components to event handlers. private class FormListener implements java.awt.event.ActionListener, java.awt.event.ComponentListener { FormListener() {} public void actionPerformed(java.awt.event.ActionEvent evt) { if (evt.getSource() == instSearchText) { PluginPanel.this.instSearchTextActionPerformed(evt); } else if (evt.getSource() == reloadInstalledButton) { PluginPanel.this.reloadInstalledButtonActionPerformed(evt); } else if (evt.getSource() == uninstallButton) { PluginPanel.this.uninstallButtonActionPerformed(evt); } else if (evt.getSource() == updateButton) { PluginPanel.this.updateButtonActionPerformed(evt); } else if (evt.getSource() == updateAllButton) { PluginPanel.this.updateAllButtonActionPerformed(evt); } else if (evt.getSource() == searchNewText) { PluginPanel.this.searchNewTextActionPerformed(evt); } else if (evt.getSource() == reloadNewButton) { PluginPanel.this.reloadNewButtonActionPerformed(evt); } else if (evt.getSource() == installButton) { PluginPanel.this.installButtonActionPerformed(evt); } else if (evt.getSource() == searchReposText) { PluginPanel.this.searchReposTextActionPerformed(evt); } else if (evt.getSource() == reloadReposButton) { PluginPanel.this.reloadReposButtonActionPerformed(evt); } else if (evt.getSource() == unregisterButton) { PluginPanel.this.unregisterButtonActionPerformed(evt); } else if (evt.getSource() == discoverButton) { PluginPanel.this.discoverButtonActionPerformed(evt); } else if (evt.getSource() == addUrlButton) { PluginPanel.this.addUrlButtonActionPerformed(evt); } else if (evt.getSource() == proxyButton) { PluginPanel.this.proxyButtonActionPerformed(evt); } } public void componentHidden(java.awt.event.ComponentEvent evt) { } public void componentMoved(java.awt.event.ComponentEvent evt) { } public void componentResized(java.awt.event.ComponentEvent evt) { } public void componentShown(java.awt.event.ComponentEvent evt) { if (evt.getSource() == installedPanel) { PluginPanel.this.installedPanelComponentShown(evt); } else if (evt.getSource() == newPanel) { PluginPanel.this.newPanelComponentShown(evt); } else if (evt.getSource() == repositoryPanel) { PluginPanel.this.repositoryPanelComponentShown(evt); } } }// </editor-fold>//GEN-END:initComponents private void reloadNewButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reloadNewButtonActionPerformed refreshNew(); }//GEN-LAST:event_reloadNewButtonActionPerformed private void addUrlButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addUrlButtonActionPerformed assert SwingUtilities.isEventDispatchThread(); NewUrlPanel panel = new NewUrlPanel(); DialogDescriptor descriptor = new DialogDescriptor(panel, NbBundle.getMessage(PluginPanel.class, "AddUrl")); // NOI18N Dialog dlg = null; //descriptor.setModal(true); try { dlg = DialogDisplayer.getDefault().createDialog(descriptor); dlg.setVisible(true); } finally { if (dlg != null) dlg.dispose(); } if (descriptor.getValue() == DialogDescriptor.OK_OPTION) { String url = panel.getUrl(); if (url != null) { pluginManager.addRepositories(new String[] { url }, this, null, true, new RepositoryListRefresher(repositoryList, true)); newModified = true; repositoriesModified = true; } } }//GEN-LAST:event_addUrlButtonActionPerformed private void proxyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_proxyButtonActionPerformed OptionsDisplayer.getDefault().open("General"); // NOI18Nd }//GEN-LAST:event_proxyButtonActionPerformed private void discoverButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_discoverButtonActionPerformed assert SwingUtilities.isEventDispatchThread(); // Bring up a selection list RepositorySelectionPanel panel = new RepositorySelectionPanel(); final JList list = panel.getList(); list.getAccessibleContext().setAccessibleName( NbBundle.getMessage(PluginPanel.class, "SelectRepos.List")); list.getAccessibleContext().setAccessibleDescription( NbBundle.getMessage(PluginPanel.class, "SelectRepos.List.AccessibleContext.accessibleDescription")); list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); DialogDescriptor descriptor = new DialogDescriptor(panel, NbBundle.getMessage(PluginPanel.class, "SelectRepos")); // NOI18N Dialog dlg = null; //descriptor.setModal(true); try { dlg = DialogDisplayer.getDefault().createDialog(descriptor); dlg.getAccessibleContext().setAccessibleDescription( NbBundle.getMessage(PluginPanel.class, "SelectRepos.AccessibleContext.accessibleDescription")); refreshRepositoryList(null, true, list, false); dlg.setVisible(true); } finally { if (dlg != null) dlg.dispose(); } if (descriptor.getValue() == DialogDescriptor.OK_OPTION) { Object[] urls = list.getSelectedValues(); if (urls != null && urls.length > 0) { List<String> reps = new ArrayList<String>(urls.length); for (int i = 0; i < urls.length; i++) { if (!isMsg(urls[i])) { reps.add(urls[i].toString()); } } if (!reps.isEmpty()) { pluginManager.addRepositories(reps.toArray(new String[reps.size()]), this, null, true, new RepositoryListRefresher(repositoryList, true)); newModified = true; repositoriesModified = true; } } } }//GEN-LAST:event_discoverButtonActionPerformed private boolean isMsg(Object object) { return MSG_WAIT.equals(object) || MSG_NO_NETWORK.equals(object) || MSG_FETCHING_LOCAL_REPOS.equals(object) || MSG_FETCHING_REMOTE_REPOS.equals(object) || MSG_FETCHING_LOCAL_PLUGINS.equals(object) || MSG_FETCHING_REMOTE_PLUGINS.equals(object); } private void searchNewTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchNewTextActionPerformed refreshPluginList(getPluginFilter(false), false, newList, false); }//GEN-LAST:event_searchNewTextActionPerformed private void searchReposTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_searchReposTextActionPerformed refreshRepositoryList(getRepositoryFilter(true), false, repositoryList, true); }//GEN-LAST:event_searchReposTextActionPerformed private void reloadReposButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reloadReposButtonActionPerformed refreshRepositories(); }//GEN-LAST:event_reloadReposButtonActionPerformed private void unregisterButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_unregisterButtonActionPerformed assert SwingUtilities.isEventDispatchThread(); int[] indices = repositoryList.getSelectedIndices(); List<String> repositories = new ArrayList<String>(); if (indices != null) { for (int index : indices) { assert index >= 0; String o = repositoryList.getModel().getElementAt(index).toString(); if (!MSG_WAIT.equals(o)) { repositories.add(o); } } } if (repositories.size() > 0) { Runnable completionTask = new RepositoryListRefresher(repositoryList, true); pluginManager.removeRepositories(repositories.toArray(new String[repositories.size()]), this, null, true, completionTask); repositoriesModified = true; newModified = true; } }//GEN-LAST:event_unregisterButtonActionPerformed private void repositoryPanelComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_repositoryPanelComponentShown assert SwingUtilities.isEventDispatchThread(); // Make sure the list is shown if (!repositoriesInitialized) { repositoriesInitialized = true; repositoryList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); repositoryList.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent ev) { if (ev.getValueIsAdjusting()) { return; } int index = repositoryList.getSelectedIndex(); unregisterButton.setEnabled(index != -1); } }); repositoriesModified = true; } if (repositoriesModified) { refreshRepositories(); } }//GEN-LAST:event_repositoryPanelComponentShown private void newPanelComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_newPanelComponentShown assert SwingUtilities.isEventDispatchThread(); // Make sure the list is shown if (!newInitialized) { newInitialized = true; newList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); newList.getSelectionModel().addListSelectionListener(new MyListSelectionListener(newList, new JButton[] { installButton })); newModified = true; } if (newModified) { refreshNew(); } }//GEN-LAST:event_newPanelComponentShown private void installButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_installButtonActionPerformed assert SwingUtilities.isEventDispatchThread(); int[] indices = newList.getSelectedIndices(); List<Plugin> plugins = new ArrayList<Plugin>(); for (int index : indices) { Object o = newList.getModel().getElementAt(index); if (o instanceof Plugin) { // Could be "Please Wait..." String Plugin plugin = (Plugin)o; plugins.add(plugin); } } if (plugins.size() > 0) { for (Plugin chosen : plugins) { // Get some information about the chosen plugin InstallationSettingsPanel panel = new InstallationSettingsPanel(chosen); DialogDescriptor dd = new DialogDescriptor(panel, NbBundle.getMessage(PluginPanel.class, "ChoosePluginSettings")); dd.setOptionType(NotifyDescriptor.OK_CANCEL_OPTION); dd.setModal(true); dd.setHelpCtx(new HelpCtx(InstallationSettingsPanel.class)); Object result = DialogDisplayer.getDefault().notify(dd); if (result.equals(NotifyDescriptor.OK_OPTION)) { Plugin plugin = new Plugin(panel.getPluginName(), null); // XXX Do I really need to refresh it right way? PluginListRefresher completionTask = new PluginListRefresher(newList, false); boolean changed = pluginManager.install(new Plugin[] { plugin }, this, null, panel.isSvnExternals(), panel.isSvnCheckout(), panel.getRevision(), true, completionTask); installedModified = installedModified || changed; } } } }//GEN-LAST:event_installButtonActionPerformed private void instSearchTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_instSearchTextActionPerformed refreshPluginList(getPluginFilter(true), false, installedList, true); }//GEN-LAST:event_instSearchTextActionPerformed private void updateAllButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateAllButtonActionPerformed Runnable completionTask = new PluginListRefresher(installedList, true); pluginManager.update(null, null, null, this, true, completionTask); installedModified = true; }//GEN-LAST:event_updateAllButtonActionPerformed private void updateButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateButtonActionPerformed assert SwingUtilities.isEventDispatchThread(); int[] indices = installedList.getSelectedIndices(); List<Plugin> plugins = new ArrayList<Plugin>(); if (indices != null) { for (int index : indices) { assert index >= 0; Object o = installedList.getModel().getElementAt(index); if (o instanceof Plugin) { // Could be "Please Wait..." String Plugin plugin = (Plugin)o; plugins.add(plugin); } } } if (plugins.size() > 0) { Runnable completionTask = new PluginListRefresher(installedList, true); pluginManager.update(plugins.toArray(new Plugin[plugins.size()]), null, null, this, true, completionTask); installedModified = true; } }//GEN-LAST:event_updateButtonActionPerformed private void uninstallButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_uninstallButtonActionPerformed assert SwingUtilities.isEventDispatchThread(); int[] indices = installedList.getSelectedIndices(); List<Plugin> plugins = new ArrayList<Plugin>(); if (indices != null) { for (int index : indices) { assert index >= 0; Object o = installedList.getModel().getElementAt(index); if (o instanceof Plugin) { // Could be "Please Wait..." String Plugin plugin = (Plugin)o; plugins.add(plugin); } } } if (plugins.size() > 0) { Runnable completionTask = new PluginListRefresher(installedList, true); pluginManager.uninstall(plugins.toArray(new Plugin[plugins.size()]), null, this, true, completionTask); installedModified = true; } }//GEN-LAST:event_uninstallButtonActionPerformed private void reloadInstalledButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reloadInstalledButtonActionPerformed refreshInstalled(); }//GEN-LAST:event_reloadInstalledButtonActionPerformed private void installedPanelComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_installedPanelComponentShown assert SwingUtilities.isEventDispatchThread(); // Make sure the list is shown if (!installedInitialized) { installedInitialized = true; installedList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); installedList.getSelectionModel().addListSelectionListener(new MyListSelectionListener(installedList, new JButton[] { updateButton, uninstallButton })); installedModified = true; } if (installedModified) { refreshInstalled(); } }//GEN-LAST:event_installedPanelComponentShown /** Refresh the list of displayed plugins. If refresh is true, refresh the list from the plugin manager, otherwise just refilter list */ private void refreshPluginList(final String filter, final boolean refresh, final JList list, final boolean local) { assert SwingUtilities.isEventDispatchThread(); boolean showRefreshMessage = true; // if (!pluginManager.hasUptodateAvailableList()) { // // No need to ask for cached version if the full version will be displayed shortly // List<Plugin> cachedList = pluginManager.getCachedAvailablePlugins(); // if (cachedList != null && cachedList.size() > 0) { // plugins = cachedList; // DefaultListModel model = new DefaultListModel(); // for (Plugin plugin : cachedList) { // model.addElement(plugin); // } // pluginList.setModel(model); // showRefreshMessage = false; // String cacheMsg = NbBundle.getMessage(PluginPanel.class, "ShowingCached"); // //descArea.setText(""); // repositoryText.setText(cacheMsg); // } // } Runnable runner = new Runnable() { public void run() { synchronized(this) { final DefaultListModel model = new DefaultListModel(); List<String> lines = new ArrayList<String>(500); List<Plugin> plugins; if (local) { if (refresh || installedPlugins == null) { installedPlugins = pluginManager.getInstalledPlugins(true, null, lines); } plugins = installedPlugins; } else { if (refresh || newPlugins == null) { newPlugins = pluginManager.getAvailablePlugins(true, null, lines); } plugins = newPlugins; } Pattern pattern = null; String lcFilter = null; if ((filter != null) && (filter.indexOf('*') != -1 || filter.indexOf('^') != -1 || filter.indexOf('$') != -1)) { try { pattern = Pattern.compile(filter, Pattern.CASE_INSENSITIVE); } catch (PatternSyntaxException pse) { // Don't treat the filter as a regexp } } else if (filter != null) { lcFilter = filter.toLowerCase(); } for (Plugin plugin : plugins) { if (filter == null || filter.length() == 0) { model.addElement(plugin); } else if (pattern == null) { if (lcFilter != null) { String lcPlugin = plugin.getName().toLowerCase(); if (lcPlugin.indexOf(lcFilter) != -1) { model.addElement(plugin); } else if (plugin.getRepository() != null) { String lcRepository = plugin.getRepository().toLowerCase(); if (lcRepository.indexOf(lcFilter) != -1) { model.addElement(plugin); } } } else { model.addElement(plugin); } } else if (pattern.matcher(plugin.getName()).find() || (plugin.getRepository() != null && pattern.matcher(plugin.getRepository()).find())) { model.addElement(plugin); } } if (refresh && plugins.size() == 0) { // TODO - don't do this when I'm showing a cached list!!! if (!local) { // having nothing is not unusual - it's how you start out model.addElement(MSG_NO_NETWORK); } for (String line : lines) { model.addElement("<html><span color=\"red\">" + line + "</span></html>"); // NOI18N } } final int pluginsCount = plugins.size(); SwingUtilities.invokeLater(new Runnable() { public void run() { list.clearSelection(); list.setModel(model); list.invalidate(); list.repaint(); if (pluginsCount > 0) { list.setSelectedIndex(0); } int tabIndex = local ? 0 : 1; String tabTitle = pluginsTab.getTitleAt(tabIndex); String originalTabTitle = tabTitle; int index = tabTitle.lastIndexOf('('); if (index != -1) { tabTitle = tabTitle.substring(0, index); } tabTitle = tabTitle + "(" + pluginsCount + ")"; if (!tabTitle.equals(originalTabTitle)) { pluginsTab.setTitleAt(tabIndex, tabTitle); } } }); } } }; if (refresh || (local && installedPlugins == null) || (!local && newPlugins == null)) { if (showRefreshMessage) { DefaultListModel model = new DefaultListModel(); model.addElement(local ? MSG_FETCHING_LOCAL_PLUGINS : MSG_FETCHING_REMOTE_PLUGINS); list.setModel(model); } RequestProcessor.getDefault().post(runner, 50); } else { // Do immediate runner.run(); } } /** Refresh the list of displayed plugins. If refresh is true, refresh the list from the plugin manager, otherwise just refilter list */ private void refreshRepositoryList(final String filter, final boolean refresh, final JList list, final boolean local) { assert SwingUtilities.isEventDispatchThread(); Runnable runner = new Runnable() { public void run() { synchronized(this) { final DefaultListModel model = new DefaultListModel(); List<String> lines = new ArrayList<String>(500); List<String> repositories; if (local) { if (refresh || activeRepositories == null) { activeRepositories = pluginManager.getRepositories(local); } repositories = activeRepositories; } else { // No filtering for the remote repository list repositories = pluginManager.getRepositories(local); } Pattern pattern = null; String lcFilter = null; if ((filter != null) && (filter.indexOf('*') != -1 || filter.indexOf('^') != -1 || filter.indexOf('$') != -1)) { try { pattern = Pattern.compile(filter, Pattern.CASE_INSENSITIVE); } catch (PatternSyntaxException pse) { // Don't treat the filter as a regexp } } else if (filter != null) { lcFilter = filter.toLowerCase(); } Collections.sort(repositories); for (String repository : repositories) { if (filter == null || filter.length() == 0) { model.addElement(repository); } else if (pattern == null) { if (lcFilter != null) { String lcRepository = repository.toLowerCase(); if (lcRepository.indexOf(lcFilter) != -1) { model.addElement(repository); } } else { model.addElement(repository); } } else if (pattern.matcher(repository).find()) { model.addElement(repository); } } if (refresh && repositories.size() == 0) { // TODO - don't do this when I'm showing a cached list!!! model.addElement(MSG_NO_NETWORK); for (String line : lines) { model.addElement("<html><span color=\"red\">" + line + "</span></html>"); // NOI18N } } final int repositoryCount = repositories.size(); SwingUtilities.invokeLater(new Runnable() { public void run() { list.clearSelection(); list.setModel(model); list.invalidate(); list.repaint(); if (repositoryCount > 0) { list.setSelectedIndex(0); } } }); } } }; if (refresh || (local && activeRepositories == null) || !local) { DefaultListModel model = new DefaultListModel(); model.addElement(local ? MSG_FETCHING_LOCAL_REPOS : MSG_FETCHING_REMOTE_REPOS); list.setModel(model); RequestProcessor.getDefault().post(runner, 50); } else { // Do immediate runner.run(); } } private String getRepositoryFilter(boolean local) { assert SwingUtilities.isEventDispatchThread(); String filter = null; if (local) { filter = searchReposText.getText().trim(); if (filter.length() == 0) { filter = null; } } return filter; } private String getPluginFilter(boolean local) { assert SwingUtilities.isEventDispatchThread(); String filter = null; JTextField tf = local ? instSearchText : searchNewText; filter = tf.getText().trim(); if (filter.length() == 0) { filter = null; } return filter; } private class PluginListRefresher implements Runnable { private JList list; private boolean local; public PluginListRefresher(JList list, boolean local) { this.list = list; this.local = local; } public void run() { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(this); return; } refreshPluginList(getPluginFilter(local), true, list, local); if (list == newList) { newModified = false; } else if (list == installedList) { pluginsModified = pluginsModified || installedModified; installedModified = false; } } } private class RepositoryListRefresher implements Runnable { private JList list; private boolean local; public RepositoryListRefresher(JList list, boolean local) { this.list = list; this.local = local; } public void run() { if (!SwingUtilities.isEventDispatchThread()) { SwingUtilities.invokeLater(this); return; } refreshRepositoryList(getRepositoryFilter(local), true, list, local); if (list == repositoryList) { repositoriesModified = false; } } } private class MyListSelectionListener implements ListSelectionListener { private JButton[] buttons; private JList list; private MyListSelectionListener(JList list, JButton[] buttons) { this.list = list; this.buttons = buttons; } public void valueChanged(ListSelectionEvent ev) { if (ev.getValueIsAdjusting()) { return; } int index = list.getSelectedIndex(); if (index != -1) { Object o = list.getModel().getElementAt(index); if (o instanceof Plugin) { // Could be "Please Wait..." String for (JButton button :buttons) { button.setEnabled(true); } return; } } for (JButton button :buttons) { button.setEnabled(index != -1); } } } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton addUrlButton; private javax.swing.JButton discoverButton; private javax.swing.JLabel instSearchLbl; private javax.swing.JTextField instSearchText; private javax.swing.JButton installButton; private javax.swing.JList installedList; private javax.swing.JPanel installedPanel; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JScrollPane jScrollPane2; private javax.swing.JScrollPane jScrollPane3; private javax.swing.JList newList; private javax.swing.JPanel newPanel; private javax.swing.JLabel newSearchLbl; private javax.swing.JTabbedPane pluginsTab; private javax.swing.JButton proxyButton; private javax.swing.JButton reloadInstalledButton; private javax.swing.JButton reloadNewButton; private javax.swing.JButton reloadReposButton; private javax.swing.JLabel repSearchLbl; private javax.swing.JList repositoryList; private javax.swing.JPanel repositoryPanel; private javax.swing.JTextField searchNewText; private javax.swing.JTextField searchReposText; private javax.swing.JButton uninstallButton; private javax.swing.JButton unregisterButton; private javax.swing.JButton updateAllButton; private javax.swing.JButton updateButton; // End of variables declaration//GEN-END:variables }