diff --git a/openide.awt/src/org/openide/awt/DropDownButton.java b/openide.awt/src/org/openide/awt/DropDownButton.java --- a/openide.awt/src/org/openide/awt/DropDownButton.java +++ b/openide.awt/src/org/openide/awt/DropDownButton.java @@ -90,11 +90,13 @@ private static final String ICON_ROLLOVER_SELECTED_LINE = "rolloverSelectedLine"; //NOI18N private PopupMenuListener menuListener; + private boolean drawSeparatorLine; /** Creates a new instance of MenuToggleButton */ - public DropDownButton( Icon icon, JPopupMenu popup ) { + public DropDownButton( Icon icon, JPopupMenu popup, boolean drawSeparatorLine) { Parameters.notNull("icon", icon); //NOI18N assert null != icon; + this.drawSeparatorLine = drawSeparatorLine; putClientProperty( DropDownButtonFactory.PROP_DROP_DOWN_MENU, popup ); @@ -124,6 +126,9 @@ @Override public void mousePressed( MouseEvent e ) { + if (!isEnabled()) { // when button is disabled no popup should be shown + return; + } popupMenuOperation = false; JPopupMenu menu = getPopupMenu(); if ( menu != null && getModel() instanceof Model ) { @@ -243,7 +248,7 @@ Icon orig = regIcons.get( ICON_ROLLOVER ); if( null == orig ) orig = regIcons.get( ICON_NORMAL ); - icon = new IconWithArrow( orig, !mouseInArrowArea ); + icon = new IconWithArrow( orig, drawSeparatorLine ? !mouseInArrowArea : false ); arrowIcons.put( mouseInArrowArea ? ICON_ROLLOVER : ICON_ROLLOVER_LINE, icon ); } return icon; @@ -258,7 +263,7 @@ orig = regIcons.get( ICON_ROLLOVER ); if( null == orig ) orig = regIcons.get( ICON_NORMAL ); - icon = new IconWithArrow( orig, !mouseInArrowArea ); + icon = new IconWithArrow( orig, drawSeparatorLine ? !mouseInArrowArea : false ); arrowIcons.put( mouseInArrowArea ? ICON_ROLLOVER_SELECTED : ICON_ROLLOVER_SELECTED_LINE, icon ); } return icon; @@ -277,7 +282,8 @@ } private boolean isInArrowArea( Point p ) { - return p.getLocation().x >= getWidth() - IconWithArrow.getArrowAreaWidth() - getInsets().right; + return p.getLocation().x >= getWidth() - IconWithArrow.getArrowAreaWidth() - getInsets().right || + !drawSeparatorLine; } @Override diff --git a/openide.awt/src/org/openide/awt/DropDownButtonFactory.java b/openide.awt/src/org/openide/awt/DropDownButtonFactory.java --- a/openide.awt/src/org/openide/awt/DropDownButtonFactory.java +++ b/openide.awt/src/org/openide/awt/DropDownButtonFactory.java @@ -80,7 +80,11 @@ * @return A button that is capable of displaying an 'arrow' in its icon to open a popup menu. */ public static JButton createDropDownButton( Icon icon, JPopupMenu dropDownMenu ) { - return new DropDownButton( icon, dropDownMenu ); + return new DropDownButton( icon, dropDownMenu, true); + } + + public static JButton createSimpleDropDownButton( Icon icon, JPopupMenu dropDownMenu) { + return new DropDownButton( icon, dropDownMenu, false); } /** diff --git a/projectui/src/org/netbeans/modules/project/ui/actions/ActiveConfigAction.java b/projectui/src/org/netbeans/modules/project/ui/actions/ActiveConfigAction.java --- a/projectui/src/org/netbeans/modules/project/ui/actions/ActiveConfigAction.java +++ b/projectui/src/org/netbeans/modules/project/ui/actions/ActiveConfigAction.java @@ -548,13 +548,13 @@ ProjectConfigurationProvider _pcp; synchronized (this) { LOGGER.log(Level.FINER, "activeProjectChanged: {0} -> {1}", new Object[] {currentProject, p}); + if (currentProject == p) { + return; + } if (currentResult != null) { currentResult.removeLookupListener(looklst); } currentResult = null; - if (currentProject == p) { - return; - } if (pcp != null) { pcp.removePropertyChangeListener(lst); } diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/api/BrowserFamilyId.java b/web.browser.api/src/org/netbeans/modules/web/browser/api/BrowserFamilyId.java --- a/web.browser.api/src/org/netbeans/modules/web/browser/api/BrowserFamilyId.java +++ b/web.browser.api/src/org/netbeans/modules/web/browser/api/BrowserFamilyId.java @@ -58,9 +58,18 @@ SAFARI, IE, JAVAFX_WEBVIEW, + OPERA, + ANDROID, + IOS, + PHONEGAP, UNKNOWN; public boolean hasNetBeansAdvancedIntegration() { return this == CHROME || this == CHROMIUM || this == JAVAFX_WEBVIEW; } + + public boolean isMobile() { + return this == ANDROID || this == IOS || this == PHONEGAP; + } } + diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowser.java b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowser.java --- a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowser.java +++ b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowser.java @@ -41,7 +41,10 @@ */ package org.netbeans.modules.web.browser.api; +import java.awt.Image; import org.openide.awt.HtmlBrowser; +import org.openide.util.ImageUtilities; +import org.openide.util.NbBundle; /** * Single browser registered in the IDE. @@ -49,9 +52,12 @@ public final class WebBrowser { private WebBrowserFactoryDescriptor factoryDesc; + private boolean withNetBeansIntegration; + static final String INTEGRATED = ".INTEGRATED"; // NOI18N - WebBrowser(WebBrowserFactoryDescriptor factoryDesc) { + WebBrowser(WebBrowserFactoryDescriptor factoryDesc, boolean withNetBeansIntegration) { this.factoryDesc = factoryDesc; + this.withNetBeansIntegration = withNetBeansIntegration; } /** @@ -59,7 +65,11 @@ * user's browser choice. */ public String getId() { - return factoryDesc.getId(); + return factoryDesc.getId() + (withNetBeansIntegration ? INTEGRATED : ""); + } + + public boolean hasNetBeansIntegration() { + return withNetBeansIntegration; } /** @@ -67,9 +77,28 @@ * * @return */ + @NbBundle.Messages({ + "# {0} - web browser", + "WebBrowser.name={0} with NetBeans Integration" + }) public String getName() { + if (withNetBeansIntegration && getBrowserFamily() != BrowserFamilyId.JAVAFX_WEBVIEW) { + return Bundle.WebBrowser_name(factoryDesc.getName()); + } else { return factoryDesc.getName(); } + } + + public Image getIconImage() { + Image im = ImageUtilities.loadImage(getIconFile(getBrowserFamily())); + if (withNetBeansIntegration) { + im = ImageUtilities.mergeImages( + im, + ImageUtilities.loadImage("org/netbeans/modules/web/browser/ui/resources/nb-badge.png"), + 12, 12); + } + return im; + } public BrowserFamilyId getBrowserFamily() { return factoryDesc.getBrowserFamily(); @@ -118,4 +147,27 @@ public HtmlBrowser.Factory getHtmlBrowserFactory() { return factoryDesc.getFactory(); } + + WebBrowserFactoryDescriptor getFactoryDesc() { + return factoryDesc; + } + + private static String getIconFile(BrowserFamilyId browserFamily) { + switch (browserFamily) { + case CHROME: + return "org/netbeans/modules/web/browser/ui/resources/browser-chrome.png"; + case FIREFOX: + return "org/netbeans/modules/web/browser/ui/resources/browser-firefox.png"; + case CHROMIUM: + return "org/netbeans/modules/web/browser/ui/resources/browser-chromium.png"; + case IE: + return "org/netbeans/modules/web/browser/ui/resources/browser-ie.png"; + case SAFARI: + return "org/netbeans/modules/web/browser/ui/resources/browser-safari.png"; + default: + return "org/netbeans/modules/web/browser/ui/resources/browser-generic.png"; + } + + + } } diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserFactoryDescriptor.java b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserFactoryDescriptor.java --- a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserFactoryDescriptor.java +++ b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserFactoryDescriptor.java @@ -71,6 +71,11 @@ } + WebBrowserFactoryDescriptor(WebBrowserFactoryDescriptor delegate, String id, String name) { + this(id, delegate.dob, delegate.def, delegate.factory); + this.name = name; + } + /** * Unique ID of this browser. Should be suitable for persistence reference to this browser. */ diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserSupport.java b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserSupport.java --- a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserSupport.java +++ b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserSupport.java @@ -43,9 +43,6 @@ import java.awt.Component; import java.awt.EventQueue; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; @@ -57,7 +54,6 @@ import javax.swing.ListCellRenderer; import org.netbeans.api.annotations.common.CheckForNull; import org.netbeans.api.annotations.common.NullAllowed; -import org.openide.util.NbBundle; /** * Support for web browsers. @@ -67,10 +63,6 @@ private static final Logger LOGGER = Logger.getLogger(WebBrowserSupport.class.getName()); - private static final String DEFAULT = "default"; // NOI18N - private static final String INTEGRATED = ".INTEGRATED"; // NOI18N - - private WebBrowserSupport() { } @@ -84,60 +76,39 @@ * @return model for component with browsers * @see #createBrowserRenderer() */ - public static BrowserComboBoxModel createBrowserModel(@NullAllowed String selectedBrowserId) { - List browsers = new ArrayList(); - int chrome = 200; - int chromium = 300; - int others = 400; - BrowserWrapper nbChrome = null; - BrowserWrapper nbChromium = null; - BrowserWrapper nbInternal = null; - browsers.add(new BrowserWrapper(null, 1, true)); - for (WebBrowser browser : WebBrowsers.getInstance().getAll(false)) { - if (browser.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW) { - nbInternal = new BrowserWrapper(browser, 100, false); - browsers.add(nbInternal); - } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROME || browser.getId().endsWith("ChromeBrowser")) { // NOI18N - BrowserWrapper wrapper = new BrowserWrapper(browser, chrome++, false); - if (nbChrome == null) { - nbChrome = wrapper; + public static BrowserComboBoxModel createBrowserModel(@NullAllowed String selectedBrowserId, boolean showIDEGlobalBrowserOption) { + List browsers = WebBrowsers.getInstance().getAll(false, true, showIDEGlobalBrowserOption, true); + String chromeId = null, chromiumId = null, javafxId = null; + if (selectedBrowserId == null) { + for (WebBrowser bw : browsers) { + if (bw.getBrowserFamily() == BrowserFamilyId.CHROME && chromeId == null) { + chromeId = bw.getId(); } - browsers.add(wrapper); - browsers.add(new BrowserWrapper(browser, chrome++, true)); - } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROMIUM || browser.getId().endsWith("ChromiumBrowser")) { // NOI18N - BrowserWrapper wrapper = new BrowserWrapper(browser, chromium++, false); - if (nbChromium == null) { - nbChromium = wrapper; + if (bw.getBrowserFamily() == BrowserFamilyId.CHROMIUM && chromiumId == null) { + chromiumId = bw.getId(); } - browsers.add(wrapper); - browsers.add(new BrowserWrapper(browser, chromium++, true)); - } else { - browsers.add(new BrowserWrapper(browser, others++, true)); + if (bw.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW && javafxId == null) { + javafxId = bw.getId(); } } - Collections.sort(browsers, new Comparator() { - @Override - public int compare(BrowserWrapper o1, BrowserWrapper o2) { - return o1.getOrder() - o2.getOrder(); } - }); if (selectedBrowserId == null) { - if (nbChrome != null) { - selectedBrowserId = nbChrome.getId(); - } else if (nbChromium != null) { - selectedBrowserId = nbChromium.getId(); - } else if (nbInternal != null) { - selectedBrowserId = nbInternal.getId(); + if (chromeId != null) { + selectedBrowserId = chromeId; + } else if (chromeId != null) { + selectedBrowserId = chromeId; + } else if (javafxId != null) { + selectedBrowserId = javafxId; } } BrowserComboBoxModel model = new BrowserComboBoxModel(browsers); for (int i = 0; i < model.getSize(); i++) { - BrowserWrapper browserWrapper = (BrowserWrapper) model.getElementAt(i); - assert browserWrapper != null; + WebBrowser browser = (WebBrowser) model.getElementAt(i); + assert browser != null; if ((selectedBrowserId == null - && !browserWrapper.isDisableIntegration()) - || browserWrapper.getId().equals(selectedBrowserId)) { - model.setSelectedItem(browserWrapper); + && browser.hasNetBeansIntegration()) + || browser.getId().equals(selectedBrowserId)) { + model.setSelectedItem(browser); break; } } @@ -159,7 +130,7 @@ * @since 1.11 */ public static String getDefaultBrowserId() { - return DEFAULT; + return WebBrowsers.DEFAULT; } /** @@ -172,11 +143,11 @@ */ public static boolean isIntegratedBrowser(@NullAllowed String browserId) { if (browserId != null - && browserId.endsWith(INTEGRATED)) { + && browserId.endsWith(WebBrowser.INTEGRATED)) { return true; } - ComboBoxModel model = createBrowserModel(browserId); - return !((BrowserWrapper) model.getSelectedItem()).isDisableIntegration(); + ComboBoxModel model = createBrowserModel(browserId, true); + return ((WebBrowser) model.getSelectedItem()).hasNetBeansIntegration(); } /** @@ -185,16 +156,26 @@ * If the browser identifier is {@code null} (likely not set yet?), then the first (external, * if possible) browser with NetBeans integration is returned. * @param browserId browser identifier, can be {@code null} if e.g. not set yet - * @return browser for the given browser identifier or {@code null} for the default IDE browser + * @return browser for the given browser identifier */ @CheckForNull public static WebBrowser getBrowser(@NullAllowed String browserId) { - if (DEFAULT.equals(browserId)) { + if (browserId != null) { + return findWebBrowserById(browserId); + } + // otherwise create a model to figure out default browser: + ComboBoxModel model = createBrowserModel(browserId, true); + return (WebBrowser) model.getSelectedItem(); + } + + private static WebBrowser findWebBrowserById(String id) { + for (WebBrowser wb : WebBrowsers.getInstance().getAll(false, true, true, false)) { + if (wb.getId().equals(id)) { + return wb; + } + } return null; } - ComboBoxModel model = createBrowserModel(browserId); - return ((BrowserWrapper) model.getSelectedItem()).getBrowser(); - } //~ Inner classes @@ -205,12 +186,12 @@ private static final long serialVersionUID = -45857643232L; - private final List browsers = new CopyOnWriteArrayList(); + private final List browsers = new CopyOnWriteArrayList(); - private volatile BrowserWrapper selectedBrowser = null; + private volatile WebBrowser selectedBrowser = null; - BrowserComboBoxModel(List browsers) { + BrowserComboBoxModel(List browsers) { assert browsers != null; assert !browsers.isEmpty(); this.browsers.addAll(browsers); @@ -244,7 +225,7 @@ */ @Override public void setSelectedItem(Object browser) { - selectedBrowser = (BrowserWrapper) browser; + selectedBrowser = (WebBrowser) browser; fireContentsChanged(this, -1, -1); } @@ -264,7 +245,7 @@ @CheckForNull public WebBrowser getSelectedBrowser() { assert selectedBrowser != null; - return selectedBrowser.getBrowser(); + return selectedBrowser; } /** @@ -289,67 +270,12 @@ @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { assert EventQueue.isDispatchThread(); - if (value instanceof BrowserWrapper) { - value = ((BrowserWrapper) value).getDesc(); + if (value instanceof WebBrowser) { + value = ((WebBrowser) value).getName(); } return ORIGINAL_RENDERER.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } } - /** - * Wrapper class for {@link WebBrowser}. - *

- * This class is thread-safe. - */ - private static final class BrowserWrapper { - - private final WebBrowser browser; - private final int order; - private final boolean disableIntegration; - - - public BrowserWrapper(WebBrowser browser, int order, boolean disableIntegration) { - this.browser = browser; - this.order = order; - this.disableIntegration = disableIntegration; - } - - @NbBundle.Messages({ - "WebBrowserSupport.browser.ideDefault=IDE's default browser", - "# {0} - web browser", - "WebBrowserSupport.browser.integrated={0} with NetBeans Integration" - }) - public String getDesc() { - if (browser == null) { - return Bundle.WebBrowserSupport_browser_ideDefault(); - } - if (disableIntegration - || browser.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW) { - return browser.getName(); - } - return Bundle.WebBrowserSupport_browser_integrated(browser.getName()); - } - - public boolean isDisableIntegration() { - return disableIntegration; - } - - public WebBrowser getBrowser() { - return browser; - } - - public String getId() { - if (browser == null) { - return DEFAULT; - } - return browser.getId() + (disableIntegration ? "" : INTEGRATED); // NOI18N - } - - int getOrder() { - return order; - } - - } - } diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowsers.java b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowsers.java --- a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowsers.java +++ b/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowsers.java @@ -45,6 +45,8 @@ import java.beans.PropertyChangeSupport; import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.prefs.PreferenceChangeEvent; import java.util.prefs.PreferenceChangeListener; @@ -56,6 +58,7 @@ import org.openide.loaders.DataObject; import org.openide.util.Exceptions; import org.openide.util.Lookup; +import org.openide.util.NbBundle; import org.openide.util.NbPreferences; /** @@ -83,6 +86,8 @@ private FileChangeListener lis; private PreferenceChangeListener lis2; + static final String DEFAULT = "default"; // NOI18N + private WebBrowsers() { sup = new PropertyChangeSupport(this); FileObject servicesBrowsers = getConfigFolder(); @@ -147,7 +152,7 @@ if (!desc.isDefault()) { continue; } - return new WebBrowser(desc); + return new WebBrowser(desc, false); } assert false : "no default browser instance found: " + getFactories(true); return null; @@ -162,7 +167,7 @@ if (desc.getBrowserFamily() != BrowserFamilyId.JAVAFX_WEBVIEW) { continue; } - return new WebBrowser(desc); + return new WebBrowser(desc, true); } return null; } @@ -170,10 +175,89 @@ /** * Returns all browsers registered in the IDE. */ - public List getAll(boolean includeSystemDefaultBrowser) { + public List getAll(boolean includeSystemDefaultBrowser, + boolean includeBrowsersWithNBIntegration, + boolean includeIDEGlobalBrowserOption, + boolean sortBrowsers) { + if (sortBrowsers) { + return getSortedBrowsers(includeSystemDefaultBrowser, includeBrowsersWithNBIntegration, includeIDEGlobalBrowserOption); + } else { + return getUnsortedBrowsers(includeSystemDefaultBrowser, includeBrowsersWithNBIntegration, includeIDEGlobalBrowserOption); + } + } + + private List getSortedBrowsers(boolean includeSystemDefaultBrowser, + boolean includeBrowsersWithNBIntegration, + boolean includeIDEGlobalBrowserOption) { + List browsers = new ArrayList(); + int chrome = 200; + int chromium = 300; + int others = 400; + for (WebBrowserFactoryDescriptor desc : getFactories(includeSystemDefaultBrowser)) { + WebBrowser browser = new WebBrowser(desc, false); + if (browser.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW) { + browsers.add(new BrowserWrapper(browser, 100)); + } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROME || browser.getId().endsWith("ChromeBrowser")) { // NOI18N + BrowserWrapper wrapper = new BrowserWrapper(browser, chrome++); + browsers.add(wrapper); + if (includeBrowsersWithNBIntegration) { + WebBrowser browser2 = new WebBrowser(desc, true); + browsers.add(new BrowserWrapper(browser2, chrome++)); + } + } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROMIUM || browser.getId().endsWith("ChromiumBrowser")) { // NOI18N + BrowserWrapper wrapper = new BrowserWrapper(browser, chromium++); + browsers.add(wrapper); + if (includeBrowsersWithNBIntegration) { + WebBrowser browser2 = new WebBrowser(desc, true); + browsers.add(new BrowserWrapper(browser2, chromium++)); + } + } else { + browsers.add(new BrowserWrapper(browser, others++)); + } + } + Collections.sort(browsers, new Comparator() { + @Override + public int compare(BrowserWrapper o1, BrowserWrapper o2) { + return o1.getOrder() - o2.getOrder(); + } + }); + List result = new ArrayList(); + if (includeIDEGlobalBrowserOption) { + result.add(createIDEGlobalDelegate()); + } + for (BrowserWrapper bw : browsers) { + result.add(bw.getBrowser()); + } + return result; + } + + + @NbBundle.Messages({ + "WebBrowsers.idebrowser=IDE's default browser" + }) + private WebBrowser createIDEGlobalDelegate() { + WebBrowser ideBrowser = getPreferred(); + return new WebBrowser(new WebBrowserFactoryDescriptor( + ideBrowser.getFactoryDesc(), DEFAULT, Bundle.WebBrowsers_idebrowser()), false); + } + + private List getUnsortedBrowsers(boolean includeSystemDefaultBrowser, + boolean includeBrowsersWithNBIntegration, + boolean includeIDEGlobalBrowserOption) { List browsers = new ArrayList(); + if (includeIDEGlobalBrowserOption) { + browsers.add(createIDEGlobalDelegate()); + } for (WebBrowserFactoryDescriptor desc : getFactories(includeSystemDefaultBrowser)) { - browsers.add(new WebBrowser(desc)); + WebBrowser browser = new WebBrowser(desc, false); + browsers.add(browser); + if (includeBrowsersWithNBIntegration && ( + browser.getBrowserFamily() == BrowserFamilyId.CHROME || + browser.getId().endsWith("ChromeBrowser") || + browser.getBrowserFamily() == BrowserFamilyId.CHROMIUM || + browser.getId().endsWith("ChromiumBrowser"))) { // NOI18N + browsers.add(new WebBrowser(desc, true)); + } } return browsers; } @@ -252,4 +336,30 @@ return browsers; } + /** + * Wrapper class for {@link WebBrowser}. + *

+ * This class is thread-safe. + */ + private static final class BrowserWrapper { + + private final WebBrowser browser; + private final int order; + + public BrowserWrapper(WebBrowser browser, int order) { + this.browser = browser; + this.order = order; + } + + public WebBrowser getBrowser() { + return browser; + } + + int getOrder() { + return order; + } + + } + + } diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/spi/ProjectBrowserProvider.java b/web.browser.api/src/org/netbeans/modules/web/browser/spi/ProjectBrowserProvider.java new file mode 100644 --- /dev/null +++ b/web.browser.api/src/org/netbeans/modules/web/browser/spi/ProjectBrowserProvider.java @@ -0,0 +1,81 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 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]" + * + * 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. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.modules.web.browser.spi; + +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.util.Collection; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.modules.web.browser.api.WebBrowser; + +/** + * Heavily inspired by ProjectConfigurationProvider. + */ +public interface ProjectBrowserProvider { + + /** + * Property name for the active browser. + * Use it when firing a change of project's active browser. + */ + String PROP_BROWSER_ACTIVE = "activeConfiguration"; // NOI18N + + /** + * Property name of the set of browsers. + * Use it when firing a change in the set of project's browsers. + */ + String PROP_BROWSERS = "configurations"; // NOI18N + + Collection getBrowsers(); + + @CheckForNull WebBrowser getActiveBrowser(); + + void setActiveBrowser(WebBrowser browser) throws IllegalArgumentException, IOException; + + boolean hasCustomizer(); + + void customize(); + + void addPropertyChangeListener(PropertyChangeListener lst); + + void removePropertyChangeListener(PropertyChangeListener lst); + +} diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/ui/HtmlPreviewElement.java b/web.browser.api/src/org/netbeans/modules/web/browser/ui/HtmlPreviewElement.java --- a/web.browser.api/src/org/netbeans/modules/web/browser/ui/HtmlPreviewElement.java +++ b/web.browser.api/src/org/netbeans/modules/web/browser/ui/HtmlPreviewElement.java @@ -123,7 +123,7 @@ WebBrowser web = WebBrowsers.getInstance().getPreferred(); if( null != web && !web.isEmbedded() ) { - for( WebBrowser wb : WebBrowsers.getInstance().getAll(true) ) { + for( WebBrowser wb : WebBrowsers.getInstance().getAll(false, false, false, false) ) { if( wb.isEmbedded() ) { web = wb; break; diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/browser-chrome.png b/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/browser-chrome.png new file mode 100644 index 0000000000000000000000000000000000000000..2f267fc9ed81c876b81cd9b3ad3fe8343a5aac85 GIT binary patch literal 1516 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 diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/browser-generic.png b/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/browser-generic.png new file mode 100644 index 0000000000000000000000000000000000000000..2da7fb6e327dbb00c7a99d9115fc0a7abf3dd0f4 GIT binary patch literal 1813 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 diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/browser-safari.png b/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/browser-safari.png new file mode 100644 index 0000000000000000000000000000000000000000..faa2f1c363a20796694dd4911b4bd1374f909bd7 GIT binary patch literal 1819 zc$@(n2juvPP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*e% z1rP&&w#n82000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}000JdNkl3t6Rzk>V3;lqc&JUTkssO$QIVHocpJb18r_w2}9Z}IJ2yFOJf?g!Yh zW5@T`u3f8GmbG%_iWSEi8yX5D(dhhlcJH3KduMcPjIKz8|2j^cIt9S~*I#eE@ZpC) zO{G#5%d*U>Rn3&m@Vef#eJ0x2az2;Mn<+_|!=>-kV9 zwBIlcu3o#wm5)A>^YdvTghGA2Uv{lnDcalH&{U0~p`jm+#A0u}dFW8_o`Bw-9&X&c z$$;=IL!F?_$L7;Pn_Uy7ccs@Y~K7AP17Dcdi1F5?&&3IHH*%UZW?tb)hd|S zP!z})mY9fLA>dwMVk|0ERTb%U`tL@u*#GW{6FJr406@75*tUH;^>uYW5sG;5`0;n- z(RI8-t^GKUQx?H1BDpN2mN@WB0Vw@Wp zC#!o}#p1%8EEJ9ICk6(_FJ8KIZS&^MD8s|U0HP}r`B5gDrOxN&!lZ($wFASlNEc1! z43mtiv1(Ndw{uIxmkg#Cb9DdqMWTicQ}=T<qeyPMFek@N= zEbHu)bLn*R^LzGe__zm=NMyBHskoXN8bwxmnVm0@oG)Su8-{8p*iuJ>S7-Opn}kzC z?7O^=BgSVL3T`65xI|C0Mw@D(`&wyj3yMTy#H##(9+V{3DQV!BjQ! z#VWUNWpM_)B#V-Ay2y(72RuD{m_Ot@dEw`8@{-TbkB<$J&XzD`4aH#*X$cY=9aRd2 zLMI?pK=Jv!ZcVeJY8v^nghU2Uxk5%bd2E%PJx?#^*x(F%ckU#6XB}tGj$+Pf9D9F^ z`2~SFYf>y&Y-!M0(@~FIvokR<;RX~Hkbb|v>~_1*bq5}467<*cl_x@+xR@l=;^n=e zBrmLQ{(#PfigT(h5eER9W(_`DuWvrH`o1<3Z8lwec^gs zx`SjgDW|5U5c=zPV;f}WU(w(VE*%#C?8=REe>QMb2p6vA!axC!jC6(W$T<9*H znS?>ckmzm)QYz>U2Te_0)-CrD8yl0BRV_tt-5UOQin6)fUq_X^GTOM6b&a@b}oYd?Z zs;;5hRc4cd?vRr?Rl((k4c-DTK331wtJgSq;DDH(p1w3QGqVRUKLG$Li@Ds8geR|G zzt+&y)F{8T;UN*x%Q$K!Y>LFGt274$^?HRht!1{g+1M6w@!r|9^3~T~74hl##O&;eLU-(T`^Nt?v3q%PcOVdWEf5GiWm%Tq)6*mR`}+w7gGgXDndJKLFjG@g z2qBEok&)lWh^eAb*Iy%JDn(sQZ&ou*~MJ$N-P#T zRWgh}0*n9GuL7{Es@mw#^`N3CK0sKNO0HBY%}Ocff%2z`{{c5x>bIREz-Ise002ov JPDHLkV1g(5ckciI diff --git a/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/nb-badge.png b/web.browser.api/src/org/netbeans/modules/web/browser/ui/resources/nb-badge.png new file mode 100644 index 0000000000000000000000000000000000000000..1fce858d8655590050fc554293d5ff8e94386b87 GIT binary patch literal 671 zc$@*B0$}}#P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i*e% z6(la5WyK@_000?uMObu0Z*6U5Zgc=ca%Ew3Wn>_CX>@2HM@dakSAh-}0005{Nkl9rF-St`uh=3wrh8Q4f1BnEU(ZRS#;$$#kP!=PLgQLXJ#KFPD)x^ON zHYGZ-IG8vPbQ4K6P53O(A_~^_=+V3P|M9wD!f$<^?fJRmGNmZqj$%8 znmoVuJ(uJEKtw=C#Kfb=lOq>zTz_z~tLw7sx#=jZ7T15|X5PP?di8OBt^fcuHhL@B zKXmh6=1Tu$PhWShn@B*c6%hduk>e1`dw*mtm!Dbvw)n&yzI5$e$MM^5jmb zOxzhsCff!s)HU|pKizwxZ+AQYc6()Mc6Ms|=icER{sGzWAWw@&c+>y@002ovPDHLk FV1g7QBGLc= diff --git a/web.clientproject.api/nbproject/project.xml b/web.clientproject.api/nbproject/project.xml --- a/web.clientproject.api/nbproject/project.xml +++ b/web.clientproject.api/nbproject/project.xml @@ -78,6 +78,15 @@ + org.netbeans.modules.projectuiapi + + + + 1 + 1.69 + + + org.netbeans.modules.web.browser.api @@ -118,6 +127,14 @@ + org.openide.loaders + + + + 7.46 + + + org.openide.modules @@ -126,6 +143,14 @@ + org.openide.nodes + + + + 7.34 + + + org.openide.util @@ -141,6 +166,14 @@ 8.16 + + org.openide.windows + + + + 6.61 + + diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/ActiveBrowserAction.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/ActiveBrowserAction.java new file mode 100644 --- /dev/null +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/ActiveBrowserAction.java @@ -0,0 +1,454 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 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]" + * + * 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. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.modules.web.clientproject.browser; + +import java.awt.Component; +import java.awt.Toolkit; +import java.awt.event.ActionEvent; +import java.awt.image.BufferedImage; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ButtonGroup; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JRadioButtonMenuItem; +import javax.swing.JSeparator; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import org.netbeans.api.annotations.common.NonNull; +import org.netbeans.api.annotations.common.NullAllowed; +import org.netbeans.api.project.FileOwnerQuery; +import org.netbeans.api.project.Project; +import org.netbeans.api.project.ui.OpenProjects; +import org.netbeans.modules.web.browser.api.WebBrowser; +import org.netbeans.modules.web.browser.spi.ProjectBrowserProvider; +import org.netbeans.spi.project.ActionProvider; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.awt.ActionRegistration; +import org.openide.awt.DropDownButtonFactory; +import org.openide.filesystems.FileObject; +import org.openide.loaders.DataObject; +import org.openide.nodes.Node; +import org.openide.util.Exceptions; +import org.openide.util.HelpCtx; +import org.openide.util.ImageUtilities; +import org.openide.util.Lookup; +import org.openide.util.LookupEvent; +import org.openide.util.LookupListener; +import org.openide.util.NbBundle; +import org.openide.util.RequestProcessor; +import org.openide.util.WeakListeners; +import org.openide.util.actions.CallableSystemAction; +import org.openide.util.lookup.ProxyLookup; +import org.openide.windows.TopComponent; + +/** + * + */ +@ActionID(id="org.netbeans.modules.web.clientproject.browser.ActiveBrowserAction", category="Project") +@ActionRegistration(displayName="#ActiveBrowserAction.reg.name", lazy=false) +@ActionReferences({ + @ActionReference(path="Menu/BuildProject", position=307), + @ActionReference(path="Toolbars/Build", position=87) +}) +public class ActiveBrowserAction extends CallableSystemAction implements LookupListener { + + private final Lookup lookup; + private @NullAllowed Project currentProject; + private @NullAllowed ProjectBrowserProvider currentBrowserProvider; + private final PropertyChangeListener currentBrowserProviderListener; + private JButton toolbarButton; + private JMenu menuAction; + + private static final RequestProcessor RP = new RequestProcessor(ActiveBrowserAction.class); + + public ActiveBrowserAction() { + lookup = LastActivatedWindowLookup.INSTANCE; + Lookup.Result resultPrj = lookup.lookupResult(Project.class); + Lookup.Result resultDO = lookup.lookupResult(DataObject.class); + resultPrj.addLookupListener(WeakListeners.create(LookupListener.class, this, resultPrj)); + resultDO.addLookupListener(WeakListeners.create(LookupListener.class, this, resultDO)); + currentBrowserProviderListener = new PropertyChangeListener() { + public @Override void propertyChange(PropertyChangeEvent evt) { + if (ProjectBrowserProvider.PROP_BROWSER_ACTIVE.equals(evt.getPropertyName())) { + updateButton(ActiveBrowserAction.this.getBrowserProvider()); + } + } + }; + refreshView(); + } + + @Override + public void performAction() { + Toolkit.getDefaultToolkit().beep(); + } + + @Override + @NbBundle.Messages({ + "ActiveBrowserAction.name=Set Project Browser" + }) + public String getName() { + return Bundle.ActiveBrowserAction_name(); + } + + @Override + public HelpCtx getHelpCtx() { + return new HelpCtx("org.netbeans.modules.web.clientproject.browser.ActiveBrowserAction"); + } + + @Override + public void resultChanged(LookupEvent ev) { + refreshViewLater(); + } + + @Override + public JMenuItem getMenuPresenter() { + JMenu m = new JMenu(Bundle.ActiveBrowserAction_name()); + m.addMenuListener(new MenuListener() { + @Override + public void menuSelected(MenuEvent e) { + JMenu m = (JMenu)e.getSource(); + m.removeAll(); + ProjectBrowserProvider pbp = ActiveBrowserAction.this.getBrowserProvider(); + for (Component mi : createMenuItems(pbp != null ? pbp.getActiveBrowser() : null)) { + if (mi instanceof JSeparator) { + m.addSeparator(); + } else { + m.add(mi); + } + } + } + + @Override + public void menuDeselected(MenuEvent e) { + } + + @Override + public void menuCanceled(MenuEvent e) { + } + }); + menuAction = m; + return m; + } + + private ProjectBrowserProvider getBrowserProvider() { + synchronized (this) { + return currentBrowserProvider; + } + } + + @NbBundle.Messages({ + "ActiveBrowserAction.customize=Customize" + }) + private List createMenuItems(WebBrowser selectedWebBrowser) { + List l = new ArrayList(); + final ProjectBrowserProvider pbp = getBrowserProvider(); + if (pbp != null) { + ButtonGroup group = new ButtonGroup(); + for (WebBrowser wb : pbp.getBrowsers()) { + JRadioButtonMenuItem mi = new JRadioButtonMenuItem(new SelectBrowserAction(pbp, wb)); + group.add(mi); + if (selectedWebBrowser != null && wb.getId().equals(selectedWebBrowser.getId())) { + mi.setSelected(true); + } + l.add(mi); + } + if (pbp.hasCustomizer()) { + l.add(new JSeparator()); + Action customizeAction = new AbstractAction(Bundle.ActiveBrowserAction_customize()) { + @Override + public void actionPerformed(ActionEvent e) { + pbp.customize(); + } + }; + JMenuItem mi = new JMenuItem(customizeAction); + l.add(mi); + } + } + return l; + } + + private static class SelectBrowserAction extends AbstractAction { + + private ProjectBrowserProvider pbp; + private WebBrowser wb; + + public SelectBrowserAction(ProjectBrowserProvider pbp, WebBrowser wb) { + super(wb.getName(), new ImageIcon(wb.getIconImage())); + this.pbp = pbp; + this.wb = wb; + } + + @Override + public void actionPerformed(ActionEvent e) { + try { + pbp.setActiveBrowser(wb); + } catch (IllegalArgumentException ex) { + Exceptions.printStackTrace(ex); + } catch (IOException ex) { + Exceptions.printStackTrace(ex); + } + } + + } + + @Override + public JMenuItem getPopupPresenter() { + return super.getPopupPresenter(); //To change body of generated methods, choose Tools | Templates. + } + + @Override + public Component getToolbarPresenter() { + JPopupMenu menu = new JPopupMenu(); + JButton button = DropDownButtonFactory.createSimpleDropDownButton( + new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB)), menu); + button.setDisabledIcon(new ImageIcon(ImageUtilities.loadImage("org/netbeans/modules/web/browser/ui/resources/browser-disabled.png"))); + button.setEnabled(false); + menu.add(new JMenuItem("xxx")); // NOI18N + ProjectBrowserProvider pbp = getBrowserProvider(); + toolbarButton = button; + updateButton(pbp); + menu.addPopupMenuListener(new PopupMenuListener() { + + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + JPopupMenu menu = (JPopupMenu) e.getSource(); + menu.removeAll(); + ProjectBrowserProvider pbp = ActiveBrowserAction.this.getBrowserProvider(); + for (Component mi : createMenuItems(pbp.getActiveBrowser())) { + if (mi instanceof JSeparator) { + menu.addSeparator(); + } else { + menu.add(mi); + } + } + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + } + }); + return button; + } + + private void refreshViewLater() { + RP.post(new Runnable() { + public @Override void run() { + refreshView(); + } + }); + } + + private void refreshView() { + Project p = OpenProjects.getDefault().getMainProject(); + if (p != null) { + activeProjectChanged(p); + } else { + Project[] selected = getProjectsFromLookup(lookup, null); + if (selected.length == 1) { + activeProjectChanged(selected[0]); + } else { + Project[] open = OpenProjects.getDefault().getOpenProjects(); + if (open.length == 1) { + activeProjectChanged(open[0]); + } else { + activeProjectChanged(null); + } + } + } + } + + private void activeProjectChanged(Project p) { + ProjectBrowserProvider pbp = null; + synchronized (this) { + if (currentProject == p) { + return; + } + if (currentBrowserProvider != null) { + currentBrowserProvider.removePropertyChangeListener(currentBrowserProviderListener); + currentBrowserProvider = null; + } + currentProject = p; + if (currentProject != null) { + currentBrowserProvider = currentProject.getLookup().lookup(ProjectBrowserProvider.class); + pbp = currentBrowserProvider; + if (currentBrowserProvider != null) { + currentBrowserProvider.addPropertyChangeListener(currentBrowserProviderListener); + } + } + } + updateButton(pbp); + } + + private void updateButton(ProjectBrowserProvider pbp) { + JButton tb = toolbarButton; + if (tb != null) { + if (pbp == null) { + tb.setIcon(new ImageIcon(new BufferedImage(24, 24, BufferedImage.TYPE_INT_RGB))); + tb.setToolTipText(null); + } else { + WebBrowser wb = pbp.getActiveBrowser(); + if (wb != null) { + tb.setIcon(new ImageIcon(wb.getIconImage())); + tb.setToolTipText(wb.getName()); + } else { + tb.setIcon(new ImageIcon(ImageUtilities.loadImage("org/netbeans/modules/web/browser/ui/resources/browser-generic.png"))); + tb.setToolTipText(null); + } + } + tb.setEnabled(pbp != null); + } + JMenu ma = menuAction; + if (ma != null) { + ma.setEnabled(pbp != null); + } + } + + + + + // XXX: copy&pasted from project.ui.actions.LookupSensitiveAction.LastActivatedWindowLookup + /** + * #120721: do not want to use Utilities.actionsGlobalContext since that does not survive focus change, + * and we would like to mimic the selection tracking behavior of Hacks.keepCurrentProjectNameUpdated. + */ + static final class LastActivatedWindowLookup extends ProxyLookup implements PropertyChangeListener { + + static final Lookup INSTANCE = new LastActivatedWindowLookup(); + + private final TopComponent.Registry reg = TopComponent.getRegistry(); + + LastActivatedWindowLookup() { + reg.addPropertyChangeListener(this); + updateLookups(); + } + + private void updateLookups() { + Node[] nodes = reg.getActivatedNodes(); + Lookup[] delegates = new Lookup[nodes.length]; + for (int i = 0; i < nodes.length; i++) { + delegates[i] = nodes[i].getLookup(); + } + setLookups(delegates); + } + + @Override + public void propertyChange(PropertyChangeEvent ev) { + if (TopComponent.Registry.PROP_ACTIVATED_NODES.equals(ev.getPropertyName())) { + updateLookups(); + } + } + + } + + // XXX: copied from project.ui.actions.ActionsUtil: + @NonNull + public static Project[] getProjectsFromLookup( Lookup lookup, String command ) { + // First find out whether there is a project directly in the Lookup + Set result = new LinkedHashSet(); // XXX or use OpenProjectList.projectByDisplayName? + for (Project p : lookup.lookupAll(Project.class)) { + result.add(p); + } + // Now try to guess the project from dataobjects + for (DataObject dObj : lookup.lookupAll(DataObject.class)) { + FileObject fObj = dObj.getPrimaryFile(); + Project p = FileOwnerQuery.getOwner(fObj); + if ( p != null ) { + result.add( p ); + } + } + Project[] projectsArray = result.toArray(new Project[result.size()]); + + if ( command != null ) { + // All projects have to have the command enabled + for (Project p : projectsArray) { + if (!commandSupported(p, command, lookup)) { + return new Project[0]; + } + } + } + + return projectsArray; + } + + // XXX: copied from project.ui.actions.ActionsUtil: + public static boolean commandSupported( Project project, String command, Lookup context ) { + //We have to look whether the command is supported by the project + ActionProvider ap = project.getLookup().lookup(ActionProvider.class); + if ( ap != null ) { + List commands = Arrays.asList(ap.getSupportedActions()); + if ( commands.contains( command ) ) { + try { + if (context == null || ap.isActionEnabled(command, context)) { + //System.err.println("cS: true project=" + project + " command=" + command + " context=" + context); + return true; + } + } catch (IllegalArgumentException x) { + Logger.getLogger(ActiveBrowserAction.class.getName()).log(Level.INFO, "#213589: possible race condition in MergedActionProvider", x); + } + } + } + //System.err.println("cS: false project=" + project + " command=" + command + " context=" + context); + return false; + } +} diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/Bundle.properties b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/Bundle.properties new file mode 100644 --- /dev/null +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/Bundle.properties @@ -0,0 +1,41 @@ +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright 2013 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]" +# +# 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. +# +# Contributor(s): +# +# Portions Copyrighted 2013 Sun Microsystems, Inc. + +ActiveBrowserAction.reg.name=Set Project Browser \ No newline at end of file diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectConfigurationImplementation.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectEnhancedBrowserImplementation.java rename from web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectConfigurationImplementation.java rename to web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectEnhancedBrowserImplementation.java --- a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectConfigurationImplementation.java +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectEnhancedBrowserImplementation.java @@ -41,63 +41,48 @@ */ package org.netbeans.modules.web.clientproject.spi.platform; -import org.netbeans.api.annotations.common.NonNull; import org.netbeans.spi.project.ActionProvider; -import org.netbeans.spi.project.ProjectConfiguration; +import org.netbeans.spi.project.ProjectConfigurationProvider; /** - * Implementation of project configuration and associated actions, customizer, etc. + * Hook into client side project type for different browsers to provider their + * own customizer, actions, configurations, etc. */ -public interface ClientProjectConfigurationImplementation extends ProjectConfiguration { +public interface ClientProjectEnhancedBrowserImplementation { /** - * Configuration's unique ID used to persist selected configuration etc. - */ - @NonNull String getId(); - - /** - * Non localizable ID of the browser used; can be null; only used for usage statistic. - */ - String getBrowserId(); - - /** - * Configuration's customizer. + * Browser's customizer. * @return can return null if none */ ProjectConfigurationCustomizer getProjectConfigurationCustomizer(); /** - * Persist changes done in configuration's customizer. + * Persist changes done in browser's customizer. */ void save(); /** - * Configuration's action provider. + * Browser's action provider. * @return can return null */ ActionProvider getActionProvider(); /** - * Can this platform be deleted? - */ - boolean canBeDeleted(); - - /** - * Delete this configuration. - */ - void delete(); - - - /** - * Configuration's handler changes in project sources. + * Browser's handler for changes in project sources. * @return can return null */ RefreshOnSaveListener getRefreshOnSaveListener(); /** - * Notification that configuration is not active anymore. + * Notification to browser that is not active anymore. */ void deactivate(); boolean isHighlightSelectionEnabled(); + + /** + * Configurations provider associated with this browser. + * @return + */ + ProjectConfigurationProvider getProjectConfigurationProvider(); } diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformProvider.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectEnhancedBrowserProvider.java rename from web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformProvider.java rename to web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectEnhancedBrowserProvider.java --- a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformProvider.java +++ b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectEnhancedBrowserProvider.java @@ -42,20 +42,16 @@ package org.netbeans.modules.web.clientproject.spi.platform; -import java.util.Collection; -import org.netbeans.api.project.Project; +import org.netbeans.modules.web.browser.api.WebBrowser; /** - * Provider of all platforms to be registered in global lookup. Order of - * registrations is important. + * Provider of ClientProjectEnhancedBrowserImplementation to be registered in + * project type lookup via + * @ProjectServiceProvider(projectType = "org-netbeans-modules-web-clientproject", ...). + * Provider decides based on browser family type whether they handle browser or not. */ -public interface ClientProjectPlatformProvider { +public interface ClientProjectEnhancedBrowserProvider { + ClientProjectEnhancedBrowserImplementation getEnhancedBrowser(WebBrowser webBrowser); - Collection getPlatforms(Project p); - -// TODO: do we need listeners? -// String PROP_PLATFORMS = "platforms"; // NOI18N -// void addPropertyChangeListener(PropertyChangeListener lst); -// void removePropertyChangeListener(PropertyChangeListener lst); } diff --git a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformImplementation.java b/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformImplementation.java deleted file mode 100644 --- a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformImplementation.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2012 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]" - * - * 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. - * - * Contributor(s): - * - * Portions Copyrighted 2012 Sun Microsystems, Inc. - */ - -package org.netbeans.modules.web.clientproject.spi.platform; - -import java.beans.PropertyChangeListener; -import java.util.List; -import org.netbeans.spi.project.ActionProvider; - -/** - * Platform here means for example Browser platform which represents all browsers - * for which project can be developed. Or Cordova platform which represents - * all different mobile devices supported by Cordova. - */ -public interface ClientProjectPlatformImplementation { - - String PROP_CONFIGURATIONS = "configurations"; // NOI18N - - /** - * List of configuration this platform provides. - */ - List getConfigurations(); - - /** - * Returns list of types of configurations user can choose from to create a new one. - */ - List getNewConfigurationTypes(); - - /** - * Create new configuration of given type and given name and return new - * configuration's ID. - * @return returns null if configuration type cannot be handled by this platform - */ - String createConfiguration(String configurationType, String configurationName); - - void addPropertyChangeListener(PropertyChangeListener lst); - - void removePropertyChangeListener(PropertyChangeListener lst); - -}