This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 226124
Collapse All | Expand All

(-)a/openide.awt/src/org/openide/awt/DropDownButton.java (-4 / +10 lines)
Lines 90-100 Link Here
90
    private static final String ICON_ROLLOVER_SELECTED_LINE = "rolloverSelectedLine"; //NOI18N
90
    private static final String ICON_ROLLOVER_SELECTED_LINE = "rolloverSelectedLine"; //NOI18N
91
91
92
    private PopupMenuListener menuListener;
92
    private PopupMenuListener menuListener;
93
    private boolean drawSeparatorLine;
93
    
94
    
94
    /** Creates a new instance of MenuToggleButton */
95
    /** Creates a new instance of MenuToggleButton */
95
    public DropDownButton( Icon icon, JPopupMenu popup ) {
96
    public DropDownButton( Icon icon, JPopupMenu popup, boolean drawSeparatorLine) {
96
        Parameters.notNull("icon", icon); //NOI18N
97
        Parameters.notNull("icon", icon); //NOI18N
97
        assert null != icon;
98
        assert null != icon;
99
        this.drawSeparatorLine = drawSeparatorLine;
98
        
100
        
99
        putClientProperty( DropDownButtonFactory.PROP_DROP_DOWN_MENU, popup );
101
        putClientProperty( DropDownButtonFactory.PROP_DROP_DOWN_MENU, popup );
100
        
102
        
Lines 124-129 Link Here
124
            
126
            
125
            @Override
127
            @Override
126
            public void mousePressed( MouseEvent e ) {
128
            public void mousePressed( MouseEvent e ) {
129
                if (!isEnabled()) { // when button is disabled no popup should be shown
130
                    return;
131
                }
127
                popupMenuOperation = false;
132
                popupMenuOperation = false;
128
                JPopupMenu menu = getPopupMenu();
133
                JPopupMenu menu = getPopupMenu();
129
                if ( menu != null && getModel() instanceof Model ) {
134
                if ( menu != null && getModel() instanceof Model ) {
Lines 243-249 Link Here
243
            Icon orig = regIcons.get( ICON_ROLLOVER );
248
            Icon orig = regIcons.get( ICON_ROLLOVER );
244
            if( null == orig )
249
            if( null == orig )
245
                orig = regIcons.get( ICON_NORMAL );
250
                orig = regIcons.get( ICON_NORMAL );
246
            icon = new IconWithArrow( orig, !mouseInArrowArea );
251
            icon = new IconWithArrow( orig, drawSeparatorLine ? !mouseInArrowArea : false );
247
            arrowIcons.put( mouseInArrowArea ? ICON_ROLLOVER : ICON_ROLLOVER_LINE, icon );
252
            arrowIcons.put( mouseInArrowArea ? ICON_ROLLOVER : ICON_ROLLOVER_LINE, icon );
248
        }
253
        }
249
        return icon;
254
        return icon;
Lines 258-264 Link Here
258
                orig = regIcons.get( ICON_ROLLOVER );
263
                orig = regIcons.get( ICON_ROLLOVER );
259
            if( null == orig )
264
            if( null == orig )
260
                orig = regIcons.get( ICON_NORMAL );
265
                orig = regIcons.get( ICON_NORMAL );
261
            icon = new IconWithArrow( orig, !mouseInArrowArea );
266
            icon = new IconWithArrow( orig, drawSeparatorLine ? !mouseInArrowArea : false );
262
            arrowIcons.put( mouseInArrowArea ? ICON_ROLLOVER_SELECTED : ICON_ROLLOVER_SELECTED_LINE, icon );
267
            arrowIcons.put( mouseInArrowArea ? ICON_ROLLOVER_SELECTED : ICON_ROLLOVER_SELECTED_LINE, icon );
263
        }
268
        }
264
        return icon;
269
        return icon;
Lines 277-283 Link Here
277
    }
282
    }
278
    
283
    
279
    private boolean isInArrowArea( Point p ) {
284
    private boolean isInArrowArea( Point p ) {
280
        return p.getLocation().x >= getWidth() - IconWithArrow.getArrowAreaWidth() - getInsets().right;
285
        return p.getLocation().x >= getWidth() - IconWithArrow.getArrowAreaWidth() - getInsets().right ||
286
                !drawSeparatorLine;
281
    }
287
    }
282
288
283
    @Override
289
    @Override
(-)a/openide.awt/src/org/openide/awt/DropDownButtonFactory.java (-1 / +5 lines)
Lines 80-86 Link Here
80
     * @return A button that is capable of displaying an 'arrow' in its icon to open a popup menu.
80
     * @return A button that is capable of displaying an 'arrow' in its icon to open a popup menu.
81
     */
81
     */
82
    public static JButton createDropDownButton( Icon icon, JPopupMenu dropDownMenu ) {
82
    public static JButton createDropDownButton( Icon icon, JPopupMenu dropDownMenu ) {
83
        return new DropDownButton( icon, dropDownMenu );
83
        return new DropDownButton( icon, dropDownMenu, true);
84
    }
85
86
    public static JButton createSimpleDropDownButton( Icon icon, JPopupMenu dropDownMenu) {
87
        return new DropDownButton( icon, dropDownMenu, false);
84
    }
88
    }
85
    
89
    
86
    /**
90
    /**
(-)a/projectui/src/org/netbeans/modules/project/ui/actions/ActiveConfigAction.java (-3 / +3 lines)
Lines 548-560 Link Here
548
        ProjectConfigurationProvider<?> _pcp;
548
        ProjectConfigurationProvider<?> _pcp;
549
        synchronized (this) {
549
        synchronized (this) {
550
            LOGGER.log(Level.FINER, "activeProjectChanged: {0} -> {1}", new Object[] {currentProject, p});
550
            LOGGER.log(Level.FINER, "activeProjectChanged: {0} -> {1}", new Object[] {currentProject, p});
551
            if (currentProject == p) {
552
                return;
553
            }
551
            if (currentResult != null) {
554
            if (currentResult != null) {
552
                currentResult.removeLookupListener(looklst);
555
                currentResult.removeLookupListener(looklst);
553
            }
556
            }
554
            currentResult = null;
557
            currentResult = null;
555
            if (currentProject == p) {
556
                return;
557
            }
558
            if (pcp != null) {
558
            if (pcp != null) {
559
                pcp.removePropertyChangeListener(lst);
559
                pcp.removePropertyChangeListener(lst);
560
            }
560
            }
(-)a/web.browser.api/src/org/netbeans/modules/web/browser/api/BrowserFamilyId.java (+9 lines)
Lines 58-66 Link Here
58
    SAFARI,
58
    SAFARI,
59
    IE,
59
    IE,
60
    JAVAFX_WEBVIEW,
60
    JAVAFX_WEBVIEW,
61
    OPERA,
62
    ANDROID,
63
    IOS,
64
    PHONEGAP,
61
    UNKNOWN;
65
    UNKNOWN;
62
    
66
    
63
    public boolean hasNetBeansAdvancedIntegration() {
67
    public boolean hasNetBeansAdvancedIntegration() {
64
        return this == CHROME || this == CHROMIUM || this == JAVAFX_WEBVIEW;
68
        return this == CHROME || this == CHROMIUM || this == JAVAFX_WEBVIEW;
65
    }
69
    }
70
71
    public boolean isMobile() {
72
        return this == ANDROID || this == IOS || this == PHONEGAP;
73
    }
66
}
74
}
75
(-)a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowser.java (-2 / +54 lines)
Lines 41-47 Link Here
41
 */
41
 */
42
package org.netbeans.modules.web.browser.api;
42
package org.netbeans.modules.web.browser.api;
43
43
44
import java.awt.Image;
44
import org.openide.awt.HtmlBrowser;
45
import org.openide.awt.HtmlBrowser;
46
import org.openide.util.ImageUtilities;
47
import org.openide.util.NbBundle;
45
48
46
/**
49
/**
47
 * Single browser registered in the IDE.
50
 * Single browser registered in the IDE.
Lines 49-57 Link Here
49
public final class WebBrowser {
52
public final class WebBrowser {
50
53
51
    private WebBrowserFactoryDescriptor factoryDesc;
54
    private WebBrowserFactoryDescriptor factoryDesc;
55
    private boolean withNetBeansIntegration;
56
    static final String INTEGRATED = ".INTEGRATED"; // NOI18N
52
57
53
    WebBrowser(WebBrowserFactoryDescriptor factoryDesc) {
58
    WebBrowser(WebBrowserFactoryDescriptor factoryDesc, boolean withNetBeansIntegration) {
54
        this.factoryDesc = factoryDesc;
59
        this.factoryDesc = factoryDesc;
60
        this.withNetBeansIntegration = withNetBeansIntegration;
55
    }
61
    }
56
    
62
    
57
    /**
63
    /**
Lines 59-65 Link Here
59
     * user's browser choice.
65
     * user's browser choice.
60
     */
66
     */
61
    public String getId() {
67
    public String getId() {
62
        return factoryDesc.getId();
68
        return factoryDesc.getId() + (withNetBeansIntegration ? INTEGRATED : "");
69
    }
70
71
    public boolean hasNetBeansIntegration() {
72
        return withNetBeansIntegration;
63
    }
73
    }
64
74
65
    /**
75
    /**
Lines 67-75 Link Here
67
     *
77
     *
68
     * @return
78
     * @return
69
     */
79
     */
80
    @NbBundle.Messages({
81
        "# {0} - web browser",
82
        "WebBrowser.name={0} with NetBeans Integration"
83
    })
70
    public String getName() {
84
    public String getName() {
85
        if (withNetBeansIntegration && getBrowserFamily() != BrowserFamilyId.JAVAFX_WEBVIEW) {
86
            return Bundle.WebBrowser_name(factoryDesc.getName());
87
        } else {
71
        return factoryDesc.getName();
88
        return factoryDesc.getName();
72
    }
89
    }
90
    }
91
92
    public Image getIconImage() {
93
        Image im = ImageUtilities.loadImage(getIconFile(getBrowserFamily()));
94
        if (withNetBeansIntegration) {
95
            im = ImageUtilities.mergeImages(
96
                im,
97
                ImageUtilities.loadImage("org/netbeans/modules/web/browser/ui/resources/nb-badge.png"),
98
            12, 12);
99
        }
100
        return im;
101
    }
73
    
102
    
74
    public BrowserFamilyId getBrowserFamily() {
103
    public BrowserFamilyId getBrowserFamily() {
75
        return factoryDesc.getBrowserFamily();
104
        return factoryDesc.getBrowserFamily();
Lines 118-121 Link Here
118
    public HtmlBrowser.Factory getHtmlBrowserFactory() {
147
    public HtmlBrowser.Factory getHtmlBrowserFactory() {
119
        return factoryDesc.getFactory();
148
        return factoryDesc.getFactory();
120
    }
149
    }
150
151
    WebBrowserFactoryDescriptor getFactoryDesc() {
152
        return factoryDesc;
153
    }
154
155
    private static String getIconFile(BrowserFamilyId browserFamily) {
156
        switch (browserFamily) {
157
            case CHROME:
158
                return "org/netbeans/modules/web/browser/ui/resources/browser-chrome.png";
159
            case FIREFOX:
160
                return "org/netbeans/modules/web/browser/ui/resources/browser-firefox.png";
161
            case CHROMIUM:
162
                return "org/netbeans/modules/web/browser/ui/resources/browser-chromium.png";
163
            case IE:
164
                return "org/netbeans/modules/web/browser/ui/resources/browser-ie.png";
165
            case SAFARI:
166
                return "org/netbeans/modules/web/browser/ui/resources/browser-safari.png";
167
            default:
168
                return "org/netbeans/modules/web/browser/ui/resources/browser-generic.png";
169
        }
170
            
171
       
172
    }
121
}
173
}
(-)a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserFactoryDescriptor.java (+5 lines)
Lines 71-76 Link Here
71
    }
71
    }
72
    
72
    
73
    
73
    
74
    WebBrowserFactoryDescriptor(WebBrowserFactoryDescriptor delegate, String id, String name) {
75
        this(id, delegate.dob, delegate.def, delegate.factory);
76
        this.name = name;
77
    }
78
    
74
    /**
79
    /**
75
    * Unique ID of this browser. Should be suitable for persistence reference to this browser.
80
    * Unique ID of this browser. Should be suitable for persistence reference to this browser.
76
    */
81
    */
(-)a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowserSupport.java (-122 / +48 lines)
Lines 43-51 Link Here
43
43
44
import java.awt.Component;
44
import java.awt.Component;
45
import java.awt.EventQueue;
45
import java.awt.EventQueue;
46
import java.util.ArrayList;
47
import java.util.Collections;
48
import java.util.Comparator;
49
import java.util.List;
46
import java.util.List;
50
import java.util.concurrent.CopyOnWriteArrayList;
47
import java.util.concurrent.CopyOnWriteArrayList;
51
import java.util.logging.Level;
48
import java.util.logging.Level;
Lines 57-63 Link Here
57
import javax.swing.ListCellRenderer;
54
import javax.swing.ListCellRenderer;
58
import org.netbeans.api.annotations.common.CheckForNull;
55
import org.netbeans.api.annotations.common.CheckForNull;
59
import org.netbeans.api.annotations.common.NullAllowed;
56
import org.netbeans.api.annotations.common.NullAllowed;
60
import org.openide.util.NbBundle;
61
57
62
/**
58
/**
63
 * Support for web browsers.
59
 * Support for web browsers.
Lines 67-76 Link Here
67
63
68
    private static final Logger LOGGER = Logger.getLogger(WebBrowserSupport.class.getName());
64
    private static final Logger LOGGER = Logger.getLogger(WebBrowserSupport.class.getName());
69
65
70
    private static final String DEFAULT = "default"; // NOI18N
71
    private static final String INTEGRATED = ".INTEGRATED"; // NOI18N
72
73
74
    private WebBrowserSupport() {
66
    private WebBrowserSupport() {
75
    }
67
    }
76
68
Lines 84-143 Link Here
84
     * @return model for component with browsers
76
     * @return model for component with browsers
85
     * @see #createBrowserRenderer()
77
     * @see #createBrowserRenderer()
86
     */
78
     */
87
    public static BrowserComboBoxModel createBrowserModel(@NullAllowed String selectedBrowserId) {
79
    public static BrowserComboBoxModel createBrowserModel(@NullAllowed String selectedBrowserId, boolean showIDEGlobalBrowserOption) {
88
        List<BrowserWrapper> browsers = new ArrayList<BrowserWrapper>();
80
        List<WebBrowser> browsers = WebBrowsers.getInstance().getAll(false, true, showIDEGlobalBrowserOption, true);
89
        int chrome = 200;
81
        String chromeId = null, chromiumId = null, javafxId = null;
90
        int chromium = 300;
82
        if (selectedBrowserId == null) {
91
        int others = 400;
83
            for (WebBrowser bw : browsers) {
92
        BrowserWrapper nbChrome = null;
84
                if (bw.getBrowserFamily() == BrowserFamilyId.CHROME && chromeId == null) {
93
        BrowserWrapper nbChromium = null;
85
                    chromeId = bw.getId();
94
        BrowserWrapper nbInternal = null;
95
        browsers.add(new BrowserWrapper(null, 1, true));
96
        for (WebBrowser browser : WebBrowsers.getInstance().getAll(false)) {
97
            if (browser.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW) {
98
                nbInternal = new BrowserWrapper(browser, 100, false);
99
                browsers.add(nbInternal);
100
            } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROME || browser.getId().endsWith("ChromeBrowser")) { // NOI18N
101
                BrowserWrapper wrapper = new BrowserWrapper(browser, chrome++, false);
102
                if (nbChrome == null) {
103
                    nbChrome = wrapper;
104
                }
86
                }
105
                browsers.add(wrapper);
87
                if (bw.getBrowserFamily() == BrowserFamilyId.CHROMIUM && chromiumId == null) {
106
                browsers.add(new BrowserWrapper(browser, chrome++, true));
88
                    chromiumId = bw.getId();
107
            } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROMIUM || browser.getId().endsWith("ChromiumBrowser")) { // NOI18N
108
                BrowserWrapper wrapper = new BrowserWrapper(browser, chromium++, false);
109
                if (nbChromium == null) {
110
                    nbChromium = wrapper;
111
                }
89
                }
112
                browsers.add(wrapper);
90
                if (bw.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW && javafxId == null) {
113
                browsers.add(new BrowserWrapper(browser, chromium++, true));
91
                    javafxId = bw.getId();
114
            } else {
115
                browsers.add(new BrowserWrapper(browser, others++, true));
116
            }
92
            }
117
        }
93
        }
118
        Collections.sort(browsers, new Comparator<BrowserWrapper>() {
119
            @Override
120
            public int compare(BrowserWrapper o1, BrowserWrapper o2) {
121
                return o1.getOrder() - o2.getOrder();
122
            }
94
            }
123
        });
124
        if (selectedBrowserId == null) {
95
        if (selectedBrowserId == null) {
125
            if (nbChrome != null) {
96
            if (chromeId != null) {
126
                selectedBrowserId = nbChrome.getId();
97
                selectedBrowserId = chromeId;
127
            } else if (nbChromium != null) {
98
            } else if (chromeId != null) {
128
                selectedBrowserId = nbChromium.getId();
99
                selectedBrowserId = chromeId;
129
            } else if (nbInternal != null) {
100
            } else if (javafxId != null) {
130
                selectedBrowserId = nbInternal.getId();
101
                selectedBrowserId = javafxId;
131
            }
102
            }
132
        }
103
        }
133
        BrowserComboBoxModel model = new BrowserComboBoxModel(browsers);
104
        BrowserComboBoxModel model = new BrowserComboBoxModel(browsers);
134
        for (int i = 0; i < model.getSize(); i++) {
105
        for (int i = 0; i < model.getSize(); i++) {
135
            BrowserWrapper browserWrapper = (BrowserWrapper) model.getElementAt(i);
106
            WebBrowser browser = (WebBrowser) model.getElementAt(i);
136
            assert browserWrapper != null;
107
            assert browser != null;
137
            if ((selectedBrowserId == null
108
            if ((selectedBrowserId == null
138
                    && !browserWrapper.isDisableIntegration())
109
                    && browser.hasNetBeansIntegration())
139
                    || browserWrapper.getId().equals(selectedBrowserId)) {
110
                    || browser.getId().equals(selectedBrowserId)) {
140
                model.setSelectedItem(browserWrapper);
111
                model.setSelectedItem(browser);
141
                break;
112
                break;
142
            }
113
            }
143
        }
114
        }
Lines 159-165 Link Here
159
     * @since 1.11
130
     * @since 1.11
160
     */
131
     */
161
    public static String getDefaultBrowserId() {
132
    public static String getDefaultBrowserId() {
162
        return DEFAULT;
133
        return WebBrowsers.DEFAULT;
163
    }
134
    }
164
135
165
    /**
136
    /**
Lines 172-182 Link Here
172
     */
143
     */
173
    public static boolean isIntegratedBrowser(@NullAllowed String browserId) {
144
    public static boolean isIntegratedBrowser(@NullAllowed String browserId) {
174
        if (browserId != null
145
        if (browserId != null
175
                && browserId.endsWith(INTEGRATED)) {
146
                && browserId.endsWith(WebBrowser.INTEGRATED)) {
176
            return true;
147
            return true;
177
        }
148
        }
178
        ComboBoxModel model = createBrowserModel(browserId);
149
        ComboBoxModel model = createBrowserModel(browserId, true);
179
        return !((BrowserWrapper) model.getSelectedItem()).isDisableIntegration();
150
        return ((WebBrowser) model.getSelectedItem()).hasNetBeansIntegration();
180
    }
151
    }
181
152
182
    /**
153
    /**
Lines 185-200 Link Here
185
     * If the browser identifier is {@code null} (likely not set yet?), then the first (external,
156
     * If the browser identifier is {@code null} (likely not set yet?), then the first (external,
186
     * if possible) browser with NetBeans integration is returned.
157
     * if possible) browser with NetBeans integration is returned.
187
     * @param browserId browser identifier, can be {@code null} if e.g. not set yet
158
     * @param browserId browser identifier, can be {@code null} if e.g. not set yet
188
     * @return browser for the given browser identifier or {@code null} for the default IDE browser
159
     * @return browser for the given browser identifier
189
     */
160
     */
190
    @CheckForNull
161
    @CheckForNull
191
    public static WebBrowser getBrowser(@NullAllowed String browserId) {
162
    public static WebBrowser getBrowser(@NullAllowed String browserId) {
192
        if (DEFAULT.equals(browserId)) {
163
        if (browserId != null) {
164
            return findWebBrowserById(browserId);
165
        }
166
        // otherwise create a model to figure out default browser:
167
        ComboBoxModel model = createBrowserModel(browserId, true);
168
        return (WebBrowser) model.getSelectedItem();
169
    }
170
171
    private static WebBrowser findWebBrowserById(String id) {
172
        for (WebBrowser wb : WebBrowsers.getInstance().getAll(false, true, true, false)) {
173
            if (wb.getId().equals(id)) {
174
                return wb;
175
            }
176
        }
193
            return null;
177
            return null;
194
        }
178
        }
195
        ComboBoxModel model = createBrowserModel(browserId);
196
        return ((BrowserWrapper) model.getSelectedItem()).getBrowser();
197
    }
198
179
199
    //~ Inner classes
180
    //~ Inner classes
200
181
Lines 205-216 Link Here
205
186
206
        private static final long serialVersionUID = -45857643232L;
187
        private static final long serialVersionUID = -45857643232L;
207
188
208
        private final List<BrowserWrapper> browsers = new CopyOnWriteArrayList<BrowserWrapper>();
189
        private final List<WebBrowser> browsers = new CopyOnWriteArrayList<WebBrowser>();
209
190
210
        private volatile BrowserWrapper selectedBrowser = null;
191
        private volatile WebBrowser selectedBrowser = null;
211
192
212
193
213
        BrowserComboBoxModel(List<BrowserWrapper> browsers) {
194
        BrowserComboBoxModel(List<WebBrowser> browsers) {
214
            assert browsers != null;
195
            assert browsers != null;
215
            assert !browsers.isEmpty();
196
            assert !browsers.isEmpty();
216
            this.browsers.addAll(browsers);
197
            this.browsers.addAll(browsers);
Lines 244-250 Link Here
244
         */
225
         */
245
        @Override
226
        @Override
246
        public void setSelectedItem(Object browser) {
227
        public void setSelectedItem(Object browser) {
247
            selectedBrowser = (BrowserWrapper) browser;
228
            selectedBrowser = (WebBrowser) browser;
248
            fireContentsChanged(this, -1, -1);
229
            fireContentsChanged(this, -1, -1);
249
        }
230
        }
250
231
Lines 264-270 Link Here
264
        @CheckForNull
245
        @CheckForNull
265
        public WebBrowser getSelectedBrowser() {
246
        public WebBrowser getSelectedBrowser() {
266
            assert selectedBrowser != null;
247
            assert selectedBrowser != null;
267
            return selectedBrowser.getBrowser();
248
            return selectedBrowser;
268
        }
249
        }
269
250
270
        /**
251
        /**
Lines 289-355 Link Here
289
        @Override
270
        @Override
290
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
271
        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
291
            assert EventQueue.isDispatchThread();
272
            assert EventQueue.isDispatchThread();
292
            if (value instanceof BrowserWrapper) {
273
            if (value instanceof WebBrowser) {
293
                value = ((BrowserWrapper) value).getDesc();
274
                value = ((WebBrowser) value).getName();
294
            }
275
            }
295
            return ORIGINAL_RENDERER.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
276
            return ORIGINAL_RENDERER.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
296
        }
277
        }
297
278
298
    }
279
    }
299
280
300
    /**
301
     * Wrapper class for {@link WebBrowser}.
302
     * <p>
303
     * This class is thread-safe.
304
     */
305
    private static final class BrowserWrapper {
306
307
        private final WebBrowser browser;
308
        private final int order;
309
        private final boolean disableIntegration;
310
311
312
        public BrowserWrapper(WebBrowser browser, int order, boolean disableIntegration) {
313
            this.browser = browser;
314
            this.order = order;
315
            this.disableIntegration = disableIntegration;
316
        }
317
318
        @NbBundle.Messages({
319
            "WebBrowserSupport.browser.ideDefault=IDE's default browser",
320
            "# {0} - web browser",
321
            "WebBrowserSupport.browser.integrated={0} with NetBeans Integration"
322
        })
323
        public String getDesc() {
324
            if (browser == null) {
325
                return Bundle.WebBrowserSupport_browser_ideDefault();
326
            }
327
            if (disableIntegration
328
                    || browser.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW) {
329
                return browser.getName();
330
            }
331
            return Bundle.WebBrowserSupport_browser_integrated(browser.getName());
332
        }
333
334
        public boolean isDisableIntegration() {
335
            return disableIntegration;
336
        }
337
338
        public WebBrowser getBrowser() {
339
            return browser;
340
        }
341
342
        public String getId() {
343
            if (browser == null) {
344
                return DEFAULT;
345
            }
346
            return browser.getId() + (disableIntegration ? "" : INTEGRATED); // NOI18N
347
        }
348
349
        int getOrder() {
350
            return order;
351
        }
352
353
    }
354
355
}
281
}
(-)a/web.browser.api/src/org/netbeans/modules/web/browser/api/WebBrowsers.java (-4 / +114 lines)
Lines 45-50 Link Here
45
import java.beans.PropertyChangeSupport;
45
import java.beans.PropertyChangeSupport;
46
import java.io.IOException;
46
import java.io.IOException;
47
import java.util.ArrayList;
47
import java.util.ArrayList;
48
import java.util.Collections;
49
import java.util.Comparator;
48
import java.util.List;
50
import java.util.List;
49
import java.util.prefs.PreferenceChangeEvent;
51
import java.util.prefs.PreferenceChangeEvent;
50
import java.util.prefs.PreferenceChangeListener;
52
import java.util.prefs.PreferenceChangeListener;
Lines 56-61 Link Here
56
import org.openide.loaders.DataObject;
58
import org.openide.loaders.DataObject;
57
import org.openide.util.Exceptions;
59
import org.openide.util.Exceptions;
58
import org.openide.util.Lookup;
60
import org.openide.util.Lookup;
61
import org.openide.util.NbBundle;
59
import org.openide.util.NbPreferences;
62
import org.openide.util.NbPreferences;
60
63
61
/**
64
/**
Lines 83-88 Link Here
83
    private FileChangeListener lis;
86
    private FileChangeListener lis;
84
    private PreferenceChangeListener lis2;
87
    private PreferenceChangeListener lis2;
85
    
88
    
89
    static final String DEFAULT = "default"; // NOI18N
90
    
86
    private WebBrowsers() {
91
    private WebBrowsers() {
87
        sup = new PropertyChangeSupport(this);
92
        sup = new PropertyChangeSupport(this);
88
        FileObject servicesBrowsers = getConfigFolder();
93
        FileObject servicesBrowsers = getConfigFolder();
Lines 147-153 Link Here
147
            if (!desc.isDefault()) {
152
            if (!desc.isDefault()) {
148
                continue;
153
                continue;
149
            }
154
            }
150
            return new WebBrowser(desc);
155
            return new WebBrowser(desc, false);
151
        }
156
        }
152
        assert false : "no default browser instance found: " + getFactories(true);
157
        assert false : "no default browser instance found: " + getFactories(true);
153
        return null;
158
        return null;
Lines 162-168 Link Here
162
            if (desc.getBrowserFamily() != BrowserFamilyId.JAVAFX_WEBVIEW) {
167
            if (desc.getBrowserFamily() != BrowserFamilyId.JAVAFX_WEBVIEW) {
163
                continue;
168
                continue;
164
            }
169
            }
165
            return new WebBrowser(desc);
170
            return new WebBrowser(desc, true);
166
        }
171
        }
167
        return null;
172
        return null;
168
    }
173
    }
Lines 170-179 Link Here
170
    /**
175
    /**
171
     * Returns all browsers registered in the IDE.
176
     * Returns all browsers registered in the IDE.
172
     */
177
     */
173
    public List<WebBrowser> getAll(boolean includeSystemDefaultBrowser) {
178
    public List<WebBrowser> getAll(boolean includeSystemDefaultBrowser,
179
            boolean includeBrowsersWithNBIntegration,
180
            boolean includeIDEGlobalBrowserOption,
181
            boolean sortBrowsers) {
182
        if (sortBrowsers) {
183
            return getSortedBrowsers(includeSystemDefaultBrowser, includeBrowsersWithNBIntegration, includeIDEGlobalBrowserOption);
184
        } else {
185
            return getUnsortedBrowsers(includeSystemDefaultBrowser, includeBrowsersWithNBIntegration, includeIDEGlobalBrowserOption);
186
        }
187
    }
188
189
    private List<WebBrowser> getSortedBrowsers(boolean includeSystemDefaultBrowser, 
190
            boolean includeBrowsersWithNBIntegration,
191
            boolean includeIDEGlobalBrowserOption) {
192
        List<BrowserWrapper> browsers = new ArrayList<BrowserWrapper>();
193
        int chrome = 200;
194
        int chromium = 300;
195
        int others = 400;
196
        for (WebBrowserFactoryDescriptor desc : getFactories(includeSystemDefaultBrowser)) {
197
            WebBrowser browser = new WebBrowser(desc, false);
198
            if (browser.getBrowserFamily() == BrowserFamilyId.JAVAFX_WEBVIEW) {
199
                browsers.add(new BrowserWrapper(browser, 100));
200
            } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROME || browser.getId().endsWith("ChromeBrowser")) { // NOI18N
201
                BrowserWrapper wrapper = new BrowserWrapper(browser, chrome++);
202
                browsers.add(wrapper);
203
                if (includeBrowsersWithNBIntegration) {
204
                    WebBrowser browser2 = new WebBrowser(desc, true);
205
                    browsers.add(new BrowserWrapper(browser2, chrome++));
206
                }
207
            } else if (browser.getBrowserFamily() == BrowserFamilyId.CHROMIUM || browser.getId().endsWith("ChromiumBrowser")) { // NOI18N
208
                BrowserWrapper wrapper = new BrowserWrapper(browser, chromium++);
209
                browsers.add(wrapper);
210
                if (includeBrowsersWithNBIntegration) {
211
                    WebBrowser browser2 = new WebBrowser(desc, true);
212
                    browsers.add(new BrowserWrapper(browser2, chromium++));
213
                }
214
            } else {
215
                browsers.add(new BrowserWrapper(browser, others++));
216
            }
217
        }
218
        Collections.sort(browsers, new Comparator<BrowserWrapper>() {
219
            @Override
220
            public int compare(BrowserWrapper o1, BrowserWrapper o2) {
221
                return o1.getOrder() - o2.getOrder();
222
            }
223
        });
224
        List<WebBrowser> result = new ArrayList<WebBrowser>();
225
        if (includeIDEGlobalBrowserOption) {
226
            result.add(createIDEGlobalDelegate());
227
        }
228
        for (BrowserWrapper bw : browsers) {
229
            result.add(bw.getBrowser());
230
        }
231
        return result;
232
    }
233
234
235
    @NbBundle.Messages({
236
        "WebBrowsers.idebrowser=IDE's default browser"
237
    })
238
    private WebBrowser createIDEGlobalDelegate() {
239
        WebBrowser ideBrowser = getPreferred();
240
        return new WebBrowser(new WebBrowserFactoryDescriptor(
241
                ideBrowser.getFactoryDesc(), DEFAULT, Bundle.WebBrowsers_idebrowser()), false);
242
    }
243
244
    private List<WebBrowser> getUnsortedBrowsers(boolean includeSystemDefaultBrowser, 
245
            boolean includeBrowsersWithNBIntegration,
246
            boolean includeIDEGlobalBrowserOption) {
174
        List<WebBrowser> browsers = new ArrayList<WebBrowser>();
247
        List<WebBrowser> browsers = new ArrayList<WebBrowser>();
248
        if (includeIDEGlobalBrowserOption) {
249
            browsers.add(createIDEGlobalDelegate());
250
        }
175
        for (WebBrowserFactoryDescriptor desc : getFactories(includeSystemDefaultBrowser)) {
251
        for (WebBrowserFactoryDescriptor desc : getFactories(includeSystemDefaultBrowser)) {
176
            browsers.add(new WebBrowser(desc));
252
            WebBrowser browser = new WebBrowser(desc, false);
253
            browsers.add(browser);
254
            if (includeBrowsersWithNBIntegration && (
255
                    browser.getBrowserFamily() == BrowserFamilyId.CHROME ||
256
                    browser.getId().endsWith("ChromeBrowser") ||
257
                    browser.getBrowserFamily() == BrowserFamilyId.CHROMIUM ||
258
                    browser.getId().endsWith("ChromiumBrowser"))) { // NOI18N
259
                browsers.add(new WebBrowser(desc, true));
260
            }
177
        }
261
        }
178
        return browsers;
262
        return browsers;
179
    }
263
    }
Lines 252-255 Link Here
252
        return browsers;
336
        return browsers;
253
    }
337
    }
254
    
338
    
339
    /**
340
     * Wrapper class for {@link WebBrowser}.
341
     * <p>
342
     * This class is thread-safe.
343
     */
344
    private static final class BrowserWrapper {
345
346
        private final WebBrowser browser;
347
        private final int order;
348
349
        public BrowserWrapper(WebBrowser browser, int order) {
350
            this.browser = browser;
351
            this.order = order;
352
        }
353
354
        public WebBrowser getBrowser() {
355
            return browser;
356
        }
357
358
        int getOrder() {
359
            return order;
360
        }
361
362
    }
363
364
255
}
365
}
(-)a/web.browser.api/src/org/netbeans/modules/web/browser/spi/ProjectBrowserProvider.java (+81 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.web.browser.spi;
43
44
import java.beans.PropertyChangeListener;
45
import java.io.IOException;
46
import java.util.Collection;
47
import org.netbeans.api.annotations.common.CheckForNull;
48
import org.netbeans.modules.web.browser.api.WebBrowser;
49
50
/**
51
 * Heavily inspired by ProjectConfigurationProvider.
52
 */
53
public interface ProjectBrowserProvider {
54
55
    /**
56
     * Property name for the active browser.
57
     * Use it when firing a change of project's active browser.
58
     */
59
    String PROP_BROWSER_ACTIVE = "activeConfiguration"; // NOI18N
60
61
    /**
62
     * Property name of the set of browsers.
63
     * Use it when firing a change in the set of project's browsers.
64
     */
65
    String PROP_BROWSERS = "configurations"; // NOI18N
66
67
    Collection<WebBrowser> getBrowsers();
68
69
    @CheckForNull WebBrowser getActiveBrowser();
70
71
    void setActiveBrowser(WebBrowser browser) throws IllegalArgumentException, IOException;
72
73
    boolean hasCustomizer();
74
75
    void customize();
76
77
    void addPropertyChangeListener(PropertyChangeListener lst);
78
79
    void removePropertyChangeListener(PropertyChangeListener lst);
80
81
}
(-)a/web.browser.api/src/org/netbeans/modules/web/browser/ui/HtmlPreviewElement.java (-1 / +1 lines)
Lines 123-129 Link Here
123
123
124
        WebBrowser web = WebBrowsers.getInstance().getPreferred();
124
        WebBrowser web = WebBrowsers.getInstance().getPreferred();
125
        if( null != web && !web.isEmbedded() ) {
125
        if( null != web && !web.isEmbedded() ) {
126
            for( WebBrowser wb : WebBrowsers.getInstance().getAll(true) ) {
126
            for( WebBrowser wb : WebBrowsers.getInstance().getAll(false, false, false, false) ) {
127
                if( wb.isEmbedded() ) {
127
                if( wb.isEmbedded() ) {
128
                    web = wb;
128
                    web = wb;
129
                    break;
129
                    break;
(-)a/web.clientproject.api/nbproject/project.xml (+33 lines)
Lines 78-83 Link Here
78
                    </run-dependency>
78
                    </run-dependency>
79
                </dependency>
79
                </dependency>
80
                <dependency>
80
                <dependency>
81
                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
82
                    <build-prerequisite/>
83
                    <compile-dependency/>
84
                    <run-dependency>
85
                        <release-version>1</release-version>
86
                        <specification-version>1.69</specification-version>
87
                    </run-dependency>
88
                </dependency>
89
                <dependency>
81
                    <code-name-base>org.netbeans.modules.web.browser.api</code-name-base>
90
                    <code-name-base>org.netbeans.modules.web.browser.api</code-name-base>
82
                    <build-prerequisite/>
91
                    <build-prerequisite/>
83
                    <compile-dependency/>
92
                    <compile-dependency/>
Lines 118-123 Link Here
118
                    </run-dependency>
127
                    </run-dependency>
119
                </dependency>
128
                </dependency>
120
                <dependency>
129
                <dependency>
130
                    <code-name-base>org.openide.loaders</code-name-base>
131
                    <build-prerequisite/>
132
                    <compile-dependency/>
133
                    <run-dependency>
134
                        <specification-version>7.46</specification-version>
135
                    </run-dependency>
136
                </dependency>
137
                <dependency>
121
                    <code-name-base>org.openide.modules</code-name-base>
138
                    <code-name-base>org.openide.modules</code-name-base>
122
                    <build-prerequisite/>
139
                    <build-prerequisite/>
123
                    <compile-dependency/>
140
                    <compile-dependency/>
Lines 126-131 Link Here
126
                    </run-dependency>
143
                    </run-dependency>
127
                </dependency>
144
                </dependency>
128
                <dependency>
145
                <dependency>
146
                    <code-name-base>org.openide.nodes</code-name-base>
147
                    <build-prerequisite/>
148
                    <compile-dependency/>
149
                    <run-dependency>
150
                        <specification-version>7.34</specification-version>
151
                    </run-dependency>
152
                </dependency>
153
                <dependency>
129
                    <code-name-base>org.openide.util</code-name-base>
154
                    <code-name-base>org.openide.util</code-name-base>
130
                    <build-prerequisite/>
155
                    <build-prerequisite/>
131
                    <compile-dependency/>
156
                    <compile-dependency/>
Lines 141-146 Link Here
141
                        <specification-version>8.16</specification-version>
166
                        <specification-version>8.16</specification-version>
142
                    </run-dependency>
167
                    </run-dependency>
143
                </dependency>
168
                </dependency>
169
                <dependency>
170
                    <code-name-base>org.openide.windows</code-name-base>
171
                    <build-prerequisite/>
172
                    <compile-dependency/>
173
                    <run-dependency>
174
                        <specification-version>6.61</specification-version>
175
                    </run-dependency>
176
                </dependency>
144
            </module-dependencies>
177
            </module-dependencies>
145
            <test-dependencies>
178
            <test-dependencies>
146
                <test-type>
179
                <test-type>
(-)a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/ActiveBrowserAction.java (+454 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.web.clientproject.browser;
43
44
import java.awt.Component;
45
import java.awt.Toolkit;
46
import java.awt.event.ActionEvent;
47
import java.awt.image.BufferedImage;
48
import java.beans.PropertyChangeEvent;
49
import java.beans.PropertyChangeListener;
50
import java.io.IOException;
51
import java.util.ArrayList;
52
import java.util.Arrays;
53
import java.util.LinkedHashSet;
54
import java.util.List;
55
import java.util.Set;
56
import java.util.logging.Level;
57
import java.util.logging.Logger;
58
import javax.swing.AbstractAction;
59
import javax.swing.Action;
60
import javax.swing.ButtonGroup;
61
import javax.swing.ImageIcon;
62
import javax.swing.JButton;
63
import javax.swing.JMenu;
64
import javax.swing.JMenuItem;
65
import javax.swing.JPopupMenu;
66
import javax.swing.JRadioButtonMenuItem;
67
import javax.swing.JSeparator;
68
import javax.swing.event.MenuEvent;
69
import javax.swing.event.MenuListener;
70
import javax.swing.event.PopupMenuEvent;
71
import javax.swing.event.PopupMenuListener;
72
import org.netbeans.api.annotations.common.NonNull;
73
import org.netbeans.api.annotations.common.NullAllowed;
74
import org.netbeans.api.project.FileOwnerQuery;
75
import org.netbeans.api.project.Project;
76
import org.netbeans.api.project.ui.OpenProjects;
77
import org.netbeans.modules.web.browser.api.WebBrowser;
78
import org.netbeans.modules.web.browser.spi.ProjectBrowserProvider;
79
import org.netbeans.spi.project.ActionProvider;
80
import org.openide.awt.ActionID;
81
import org.openide.awt.ActionReference;
82
import org.openide.awt.ActionReferences;
83
import org.openide.awt.ActionRegistration;
84
import org.openide.awt.DropDownButtonFactory;
85
import org.openide.filesystems.FileObject;
86
import org.openide.loaders.DataObject;
87
import org.openide.nodes.Node;
88
import org.openide.util.Exceptions;
89
import org.openide.util.HelpCtx;
90
import org.openide.util.ImageUtilities;
91
import org.openide.util.Lookup;
92
import org.openide.util.LookupEvent;
93
import org.openide.util.LookupListener;
94
import org.openide.util.NbBundle;
95
import org.openide.util.RequestProcessor;
96
import org.openide.util.WeakListeners;
97
import org.openide.util.actions.CallableSystemAction;
98
import org.openide.util.lookup.ProxyLookup;
99
import org.openide.windows.TopComponent;
100
101
/**
102
 *
103
 */
104
@ActionID(id="org.netbeans.modules.web.clientproject.browser.ActiveBrowserAction", category="Project")
105
@ActionRegistration(displayName="#ActiveBrowserAction.reg.name", lazy=false)
106
@ActionReferences({
107
    @ActionReference(path="Menu/BuildProject", position=307),
108
    @ActionReference(path="Toolbars/Build", position=87)
109
})
110
public class ActiveBrowserAction extends CallableSystemAction implements LookupListener {
111
112
    private final Lookup lookup;
113
    private @NullAllowed Project currentProject;
114
    private @NullAllowed ProjectBrowserProvider currentBrowserProvider;
115
    private final PropertyChangeListener currentBrowserProviderListener;
116
    private JButton toolbarButton;
117
    private JMenu menuAction;
118
    
119
    private static final RequestProcessor RP = new RequestProcessor(ActiveBrowserAction.class);
120
121
    public ActiveBrowserAction() {
122
        lookup = LastActivatedWindowLookup.INSTANCE;
123
        Lookup.Result<Project> resultPrj = lookup.lookupResult(Project.class);
124
        Lookup.Result<DataObject> resultDO = lookup.lookupResult(DataObject.class);
125
        resultPrj.addLookupListener(WeakListeners.create(LookupListener.class, this, resultPrj));
126
        resultDO.addLookupListener(WeakListeners.create(LookupListener.class, this, resultDO));
127
        currentBrowserProviderListener = new PropertyChangeListener() {
128
            public @Override void propertyChange(PropertyChangeEvent evt) {
129
                if (ProjectBrowserProvider.PROP_BROWSER_ACTIVE.equals(evt.getPropertyName())) {
130
                    updateButton(ActiveBrowserAction.this.getBrowserProvider());
131
                }
132
            }
133
        };
134
        refreshView();
135
    }
136
137
    @Override
138
    public void performAction() {
139
        Toolkit.getDefaultToolkit().beep();
140
    }
141
142
    @Override
143
    @NbBundle.Messages({
144
        "ActiveBrowserAction.name=Set Project Browser"
145
    })
146
    public String getName() {
147
        return Bundle.ActiveBrowserAction_name();
148
    }
149
150
    @Override
151
    public HelpCtx getHelpCtx() {
152
        return new HelpCtx("org.netbeans.modules.web.clientproject.browser.ActiveBrowserAction");
153
    }
154
155
    @Override
156
    public void resultChanged(LookupEvent ev) {
157
        refreshViewLater();
158
    }
159
160
    @Override
161
    public JMenuItem getMenuPresenter() {
162
        JMenu m = new JMenu(Bundle.ActiveBrowserAction_name());
163
        m.addMenuListener(new MenuListener() {
164
            @Override
165
            public void menuSelected(MenuEvent e) {
166
                JMenu m = (JMenu)e.getSource();
167
                m.removeAll();
168
                ProjectBrowserProvider pbp = ActiveBrowserAction.this.getBrowserProvider();
169
                for (Component mi : createMenuItems(pbp != null ? pbp.getActiveBrowser() : null)) {
170
                    if (mi instanceof JSeparator) {
171
                        m.addSeparator();
172
                    } else {
173
                        m.add(mi);
174
                    }
175
                }
176
            }
177
178
            @Override
179
            public void menuDeselected(MenuEvent e) {
180
            }
181
182
            @Override
183
            public void menuCanceled(MenuEvent e) {
184
            }
185
        });
186
        menuAction = m;
187
        return m;
188
    }
189
190
    private ProjectBrowserProvider getBrowserProvider() {
191
        synchronized (this) {
192
            return currentBrowserProvider;
193
        }
194
    }
195
196
    @NbBundle.Messages({
197
        "ActiveBrowserAction.customize=Customize"
198
    })
199
    private List<Component> createMenuItems(WebBrowser selectedWebBrowser) {
200
        List<Component> l = new ArrayList<Component>();
201
        final ProjectBrowserProvider pbp = getBrowserProvider();
202
        if (pbp != null) {
203
            ButtonGroup group = new ButtonGroup();
204
            for (WebBrowser wb : pbp.getBrowsers()) {
205
                JRadioButtonMenuItem mi = new JRadioButtonMenuItem(new SelectBrowserAction(pbp, wb));
206
                group.add(mi);
207
                if (selectedWebBrowser != null && wb.getId().equals(selectedWebBrowser.getId())) {
208
                    mi.setSelected(true);
209
                }
210
                l.add(mi);
211
            }
212
            if (pbp.hasCustomizer()) {
213
                l.add(new JSeparator());
214
                Action customizeAction = new AbstractAction(Bundle.ActiveBrowserAction_customize()) {
215
                    @Override
216
                    public void actionPerformed(ActionEvent e) {
217
                        pbp.customize();
218
                    }
219
                };
220
                JMenuItem mi = new JMenuItem(customizeAction);
221
                l.add(mi);
222
            }
223
        }
224
        return l;
225
    }
226
227
    private static class SelectBrowserAction extends AbstractAction {
228
229
        private ProjectBrowserProvider pbp;
230
        private WebBrowser wb;
231
232
        public SelectBrowserAction(ProjectBrowserProvider pbp, WebBrowser wb) {
233
            super(wb.getName(), new ImageIcon(wb.getIconImage()));
234
            this.pbp = pbp;
235
            this.wb = wb;
236
        }
237
238
        @Override
239
        public void actionPerformed(ActionEvent e) {
240
            try {
241
                pbp.setActiveBrowser(wb);
242
            } catch (IllegalArgumentException ex) {
243
                Exceptions.printStackTrace(ex);
244
            } catch (IOException ex) {
245
                Exceptions.printStackTrace(ex);
246
            }
247
        }
248
249
    }
250
251
    @Override
252
    public JMenuItem getPopupPresenter() {
253
        return super.getPopupPresenter(); //To change body of generated methods, choose Tools | Templates.
254
    }
255
256
    @Override
257
    public Component getToolbarPresenter() {
258
        JPopupMenu menu = new JPopupMenu();
259
        JButton button = DropDownButtonFactory.createSimpleDropDownButton(
260
                new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB)), menu);
261
        button.setDisabledIcon(new ImageIcon(ImageUtilities.loadImage("org/netbeans/modules/web/browser/ui/resources/browser-disabled.png")));
262
        button.setEnabled(false);
263
        menu.add(new JMenuItem("xxx")); // NOI18N
264
        ProjectBrowserProvider pbp = getBrowserProvider();
265
        toolbarButton = button;
266
        updateButton(pbp);
267
        menu.addPopupMenuListener(new PopupMenuListener() {
268
269
            @Override
270
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
271
                JPopupMenu menu = (JPopupMenu) e.getSource();
272
                menu.removeAll();
273
                ProjectBrowserProvider pbp = ActiveBrowserAction.this.getBrowserProvider();
274
                for (Component mi : createMenuItems(pbp.getActiveBrowser())) {
275
                    if (mi instanceof JSeparator) {
276
                        menu.addSeparator();
277
                    } else {
278
                        menu.add(mi);
279
                    }
280
                }
281
            }
282
283
            @Override
284
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
285
            }
286
287
            @Override
288
            public void popupMenuCanceled(PopupMenuEvent e) {
289
            }
290
        });
291
        return button;
292
    }
293
294
    private void refreshViewLater() {
295
        RP.post(new Runnable() {
296
            public @Override void run() {
297
                refreshView();
298
            }
299
        });
300
    }
301
302
    private void refreshView() {
303
        Project p = OpenProjects.getDefault().getMainProject();
304
        if (p != null) {
305
            activeProjectChanged(p);
306
        } else {
307
            Project[] selected = getProjectsFromLookup(lookup, null);
308
            if (selected.length == 1) {
309
                activeProjectChanged(selected[0]);
310
            } else {
311
                Project[] open = OpenProjects.getDefault().getOpenProjects();
312
                if (open.length == 1) {
313
                    activeProjectChanged(open[0]);
314
                } else {
315
                    activeProjectChanged(null);
316
                }
317
            }
318
        }
319
    }
320
321
    private void activeProjectChanged(Project p) {
322
        ProjectBrowserProvider pbp = null;
323
        synchronized (this) {
324
            if (currentProject == p) {
325
                return;
326
            }
327
            if (currentBrowserProvider != null) {
328
                currentBrowserProvider.removePropertyChangeListener(currentBrowserProviderListener);
329
                currentBrowserProvider = null;
330
            }
331
            currentProject = p;
332
            if (currentProject != null) {
333
                currentBrowserProvider = currentProject.getLookup().lookup(ProjectBrowserProvider.class);
334
                pbp = currentBrowserProvider;
335
                if (currentBrowserProvider != null) {
336
                    currentBrowserProvider.addPropertyChangeListener(currentBrowserProviderListener);
337
                }
338
            }
339
        }
340
        updateButton(pbp);
341
    }
342
343
    private void updateButton(ProjectBrowserProvider pbp) {
344
        JButton tb = toolbarButton;
345
        if (tb != null) {
346
            if (pbp == null) {
347
                tb.setIcon(new ImageIcon(new BufferedImage(24, 24, BufferedImage.TYPE_INT_RGB)));
348
                tb.setToolTipText(null);
349
            } else {
350
                WebBrowser wb = pbp.getActiveBrowser();
351
                if (wb != null) {
352
                    tb.setIcon(new ImageIcon(wb.getIconImage()));
353
                    tb.setToolTipText(wb.getName());
354
                } else {
355
                    tb.setIcon(new ImageIcon(ImageUtilities.loadImage("org/netbeans/modules/web/browser/ui/resources/browser-generic.png")));
356
                    tb.setToolTipText(null);
357
                }
358
            }
359
            tb.setEnabled(pbp != null);
360
        }
361
        JMenu ma = menuAction;
362
        if (ma != null) {
363
            ma.setEnabled(pbp != null);
364
        }
365
    }
366
367
368
369
    
370
    // XXX: copy&pasted from project.ui.actions.LookupSensitiveAction.LastActivatedWindowLookup
371
    /**
372
     * #120721: do not want to use Utilities.actionsGlobalContext since that does not survive focus change,
373
     * and we would like to mimic the selection tracking behavior of Hacks.keepCurrentProjectNameUpdated.
374
     */
375
    static final class LastActivatedWindowLookup extends ProxyLookup implements PropertyChangeListener {
376
377
        static final Lookup INSTANCE = new LastActivatedWindowLookup();
378
379
        private final TopComponent.Registry reg = TopComponent.getRegistry();
380
381
        LastActivatedWindowLookup() {
382
            reg.addPropertyChangeListener(this);
383
            updateLookups();
384
        }
385
386
        private void updateLookups() {
387
            Node[] nodes = reg.getActivatedNodes();
388
            Lookup[] delegates = new Lookup[nodes.length];
389
            for (int i = 0; i < nodes.length; i++) {
390
                delegates[i] = nodes[i].getLookup();
391
            }
392
            setLookups(delegates);
393
        }
394
395
        @Override
396
        public void propertyChange(PropertyChangeEvent ev) {
397
            if (TopComponent.Registry.PROP_ACTIVATED_NODES.equals(ev.getPropertyName())) {
398
                updateLookups();
399
            }
400
        }
401
402
    }
403
404
    // XXX: copied from project.ui.actions.ActionsUtil:
405
    @NonNull
406
    public static Project[] getProjectsFromLookup( Lookup lookup, String command ) {
407
        // First find out whether there is a project directly in the Lookup
408
        Set<Project> result = new LinkedHashSet<Project>(); // XXX or use OpenProjectList.projectByDisplayName?
409
        for (Project p : lookup.lookupAll(Project.class)) {
410
            result.add(p);
411
        }
412
        // Now try to guess the project from dataobjects
413
        for (DataObject dObj : lookup.lookupAll(DataObject.class)) {
414
            FileObject fObj = dObj.getPrimaryFile();
415
            Project p = FileOwnerQuery.getOwner(fObj);
416
            if ( p != null ) {
417
                result.add( p );
418
            }
419
        }
420
        Project[] projectsArray = result.toArray(new Project[result.size()]);
421
422
        if ( command != null ) {
423
            // All projects have to have the command enabled
424
            for (Project p : projectsArray) {
425
                if (!commandSupported(p, command, lookup)) {
426
                    return new Project[0];
427
                }
428
            }
429
        }
430
431
        return projectsArray;
432
    }
433
434
    // XXX: copied from project.ui.actions.ActionsUtil:
435
    public static boolean commandSupported( Project project, String command, Lookup context ) {
436
        //We have to look whether the command is supported by the project
437
        ActionProvider ap = project.getLookup().lookup(ActionProvider.class);
438
        if ( ap != null ) {
439
            List<String> commands = Arrays.asList(ap.getSupportedActions());
440
            if ( commands.contains( command ) ) {
441
                try {
442
                if (context == null || ap.isActionEnabled(command, context)) {
443
                    //System.err.println("cS: true project=" + project + " command=" + command + " context=" + context);
444
                    return true;
445
                }
446
                } catch (IllegalArgumentException x) {
447
                    Logger.getLogger(ActiveBrowserAction.class.getName()).log(Level.INFO, "#213589: possible race condition in MergedActionProvider", x);
448
                }
449
            }
450
        }
451
        //System.err.println("cS: false project=" + project + " command=" + command + " context=" + context);
452
        return false;
453
    }
454
}
(-)a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/browser/Bundle.properties (+41 lines)
Line 0 Link Here
1
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
2
#
3
# Copyright 2013 Oracle and/or its affiliates. All rights reserved.
4
#
5
# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
6
# Other names may be trademarks of their respective owners.
7
#
8
# The contents of this file are subject to the terms of either the GNU
9
# General Public License Version 2 only ("GPL") or the Common
10
# Development and Distribution License("CDDL") (collectively, the
11
# "License"). You may not use this file except in compliance with the
12
# License. You can obtain a copy of the License at
13
# http://www.netbeans.org/cddl-gplv2.html
14
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
15
# specific language governing permissions and limitations under the
16
# License.  When distributing the software, include this License Header
17
# Notice in each file and include the License file at
18
# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
19
# particular file as subject to the "Classpath" exception as provided
20
# by Oracle in the GPL Version 2 section of the License file that
21
# accompanied this code. If applicable, add the following below the
22
# License Header, with the fields enclosed by brackets [] replaced by
23
# your own identifying information:
24
# "Portions Copyrighted [year] [name of copyright owner]"
25
#
26
# If you wish your version of this file to be governed by only the CDDL
27
# or only the GPL Version 2, indicate your decision by adding
28
# "[Contributor] elects to include this software in this distribution
29
# under the [CDDL or GPL Version 2] license." If you do not indicate a
30
# single choice of license, a recipient has the option to distribute
31
# your version of this file under either the CDDL, the GPL Version 2 or
32
# to extend the choice of license to its licensees as provided above.
33
# However, if you add GPL Version 2 code and therefore, elected the GPL
34
# Version 2 license, then the option applies only if the new code is
35
# made subject to such option by the copyright holder.
36
#
37
# Contributor(s):
38
#
39
# Portions Copyrighted 2013 Sun Microsystems, Inc.
40
41
ActiveBrowserAction.reg.name=Set Project Browser
(-)a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectConfigurationImplementation.java (-30 / +15 lines)
Lines 41-103 Link Here
41
 */
41
 */
42
package org.netbeans.modules.web.clientproject.spi.platform;
42
package org.netbeans.modules.web.clientproject.spi.platform;
43
43
44
import org.netbeans.api.annotations.common.NonNull;
45
import org.netbeans.spi.project.ActionProvider;
44
import org.netbeans.spi.project.ActionProvider;
46
import org.netbeans.spi.project.ProjectConfiguration;
45
import org.netbeans.spi.project.ProjectConfigurationProvider;
47
46
48
/**
47
/**
49
 * Implementation of project configuration and associated actions, customizer, etc.
48
 * Hook into client side project type for different browsers to provider their
49
 * own customizer, actions, configurations, etc.
50
 */
50
 */
51
public interface ClientProjectConfigurationImplementation extends ProjectConfiguration {
51
public interface ClientProjectEnhancedBrowserImplementation {
52
52
53
    /**
53
    /**
54
     * Configuration's unique ID used to persist selected configuration etc.
54
     * Browser's customizer.
55
     */
56
    @NonNull String getId();
57
    
58
    /**
59
     * Non localizable ID of the browser used; can be null; only used for usage statistic.
60
     */
61
    String getBrowserId();
62
63
    /**
64
     * Configuration's customizer.
65
     * @return can return null if none
55
     * @return can return null if none
66
     */
56
     */
67
    ProjectConfigurationCustomizer getProjectConfigurationCustomizer();
57
    ProjectConfigurationCustomizer getProjectConfigurationCustomizer();
68
58
69
    /**
59
    /**
70
     * Persist changes done in configuration's customizer.
60
     * Persist changes done in browser's customizer.
71
     */
61
     */
72
    void save();
62
    void save();
73
    
63
    
74
    /**
64
    /**
75
     * Configuration's action provider.
65
     * Browser's action provider.
76
     * @return can return null
66
     * @return can return null
77
     */
67
     */
78
    ActionProvider getActionProvider();
68
    ActionProvider getActionProvider();
79
69
80
    /**
70
    /**
81
     * Can this platform be deleted?
71
     * Browser's handler for changes in project sources.
82
     */
83
    boolean canBeDeleted();
84
85
    /**
86
     * Delete this configuration.
87
     */
88
    void delete();
89
90
91
    /**
92
     * Configuration's handler changes in project sources.
93
     * @return can return null
72
     * @return can return null
94
     */
73
     */
95
    RefreshOnSaveListener getRefreshOnSaveListener();
74
    RefreshOnSaveListener getRefreshOnSaveListener();
96
75
97
    /**
76
    /**
98
     * Notification that configuration is not active anymore.
77
     * Notification to browser that is not active anymore.
99
     */
78
     */
100
    void deactivate();
79
    void deactivate();
101
80
102
    boolean isHighlightSelectionEnabled();
81
    boolean isHighlightSelectionEnabled();
82
83
    /**
84
     * Configurations provider associated with this browser.
85
     * @return
86
     */
87
    ProjectConfigurationProvider getProjectConfigurationProvider();
103
}
88
}
(-)a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformProvider.java (-11 / +7 lines)
Lines 42-61 Link Here
42
42
43
package org.netbeans.modules.web.clientproject.spi.platform;
43
package org.netbeans.modules.web.clientproject.spi.platform;
44
44
45
import java.util.Collection;
45
import org.netbeans.modules.web.browser.api.WebBrowser;
46
import org.netbeans.api.project.Project;
47
46
48
/**
47
/**
49
 * Provider of all platforms to be registered in global lookup. Order of 
48
 * Provider of ClientProjectEnhancedBrowserImplementation to be registered in
50
 * registrations is important.
49
 * project type lookup via
50
 * @ProjectServiceProvider(projectType = "org-netbeans-modules-web-clientproject", ...).
51
 * Provider decides based on browser family type whether they handle browser or not.
51
 */
52
 */
52
public interface ClientProjectPlatformProvider {
53
public interface ClientProjectEnhancedBrowserProvider {
53
    
54
    
55
    ClientProjectEnhancedBrowserImplementation getEnhancedBrowser(WebBrowser webBrowser);
54
    
56
    
55
    Collection<ClientProjectPlatformImplementation> getPlatforms(Project p);
56
57
// TODO: do we need listeners?     
58
//    String PROP_PLATFORMS = "platforms"; // NOI18N
59
//    void addPropertyChangeListener(PropertyChangeListener lst);
60
//    void removePropertyChangeListener(PropertyChangeListener lst);
61
}
57
}
(-)a/web.clientproject.api/src/org/netbeans/modules/web/clientproject/spi/platform/ClientProjectPlatformImplementation.java (-79 lines)
Lines 1-79 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.web.clientproject.spi.platform;
44
45
import java.beans.PropertyChangeListener;
46
import java.util.List;
47
import org.netbeans.spi.project.ActionProvider;
48
49
/**
50
 * Platform here means for example Browser platform which represents all browsers
51
 * for which project can be developed. Or Cordova platform which represents
52
 * all different mobile devices supported by Cordova.
53
 */
54
public interface ClientProjectPlatformImplementation {
55
    
56
    String PROP_CONFIGURATIONS = "configurations"; // NOI18N
57
58
    /**
59
     * List of configuration this platform provides.
60
     */
61
    List<? extends ClientProjectConfigurationImplementation> getConfigurations();
62
    
63
    /**
64
     * Returns list of types of configurations user can choose from to create a new one.
65
     */
66
    List<String> getNewConfigurationTypes();
67
68
    /**
69
     * Create new configuration of given type and given name and return new
70
     * configuration's ID.
71
     * @return returns null if configuration type cannot be handled by this platform
72
     */
73
    String createConfiguration(String configurationType, String configurationName);
74
    
75
    void addPropertyChangeListener(PropertyChangeListener lst);
76
77
    void removePropertyChangeListener(PropertyChangeListener lst);
78
    
79
}

Return to bug 226124