--- a/debugger.jpda/src/org/netbeans/modules/debugger/jpda/breakpoints/JPDABreakpointsActivation.java +++ a/debugger.jpda/src/org/netbeans/modules/debugger/jpda/breakpoints/JPDABreakpointsActivation.java @@ -0,0 +1,116 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2015 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 2015 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.debugger.jpda.breakpoints; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.netbeans.api.debugger.ActiveBreakpoints; +import org.netbeans.api.debugger.jpda.JPDADebugger; +import org.netbeans.spi.debugger.BreakpointsActivationProvider; +import org.netbeans.spi.debugger.ContextProvider; +import org.netbeans.spi.debugger.DebuggerServiceRegistration; + +/** + * JPDA activation/deactivation of breakpoints. + * + * @author Martin Entlicher + */ +@DebuggerServiceRegistration(path="netbeans-JPDASession", types = BreakpointsActivationProvider.class) +public class JPDABreakpointsActivation implements BreakpointsActivationProvider { + + private final JPDADebugger debugger; + private final Map listenersMap = Collections.synchronizedMap(new HashMap()); + + public JPDABreakpointsActivation(ContextProvider contextProvider) { + this.debugger = contextProvider.lookupFirst(null, JPDADebugger.class); + } + + @Override + public boolean areBreakpointsActive() { + return debugger.getBreakpointsActive(); + } + + @Override + public void setBreakpointsActive(boolean active) { + debugger.setBreakpointsActive(active); + } + + @Override + public void addPropertyChangeListener(final PropertyChangeListener l) { + DelegateListener dl = new DelegateListener(this, l); + listenersMap.put(l, dl); + debugger.addPropertyChangeListener(JPDADebugger.PROP_BREAKPOINTS_ACTIVE, dl); + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener l) { + DelegateListener dl = listenersMap.remove(l); + if (dl != null) { + debugger.removePropertyChangeListener(JPDADebugger.PROP_BREAKPOINTS_ACTIVE, dl); + } + } + + private static class DelegateListener implements PropertyChangeListener { + + private final Object source; + private final PropertyChangeListener l; + + public DelegateListener(Object source, PropertyChangeListener l) { + this.source = source; + this.l = l; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + l.propertyChange(new PropertyChangeEvent( + source, + ActiveBreakpoints.PROP_BREAKPOINTS_ACTIVE, + evt.getOldValue(), + evt.getNewValue())); + } + } + +} --- a/spi.debugger.ui/src/org/netbeans/modules/debugger/resources/mf-layer.xml +++ a/spi.debugger.ui/src/org/netbeans/modules/debugger/resources/mf-layer.xml @@ -575,6 +575,13 @@ methodvalue="org.netbeans.modules.debugger.ui.models.BreakpointsViewButtons.createNewBreakpointActionButton" name="instanceCreate"/> + + + + + + --- a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/models/BreakpointsViewButtons.java +++ a/spi.debugger.ui/src/org/netbeans/modules/debugger/ui/models/BreakpointsViewButtons.java @@ -50,19 +50,27 @@ import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.beans.PropertyChangeEvent; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; import java.util.List; import javax.swing.AbstractAction; +import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.Icon; +import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBoxMenuItem; import javax.swing.JPopupMenu; import javax.swing.JRadioButtonMenuItem; +import javax.swing.JToggleButton; import javax.swing.SwingUtilities; +import javax.swing.border.EmptyBorder; +import org.netbeans.api.debugger.ActiveBreakpoints; import org.netbeans.api.debugger.Breakpoint; +import org.netbeans.api.debugger.DebuggerEngine; import org.netbeans.api.debugger.DebuggerManager; import org.netbeans.api.debugger.DebuggerManagerAdapter; - import org.netbeans.api.debugger.Properties; import org.netbeans.api.debugger.Session; import org.netbeans.api.project.Project; @@ -84,6 +92,8 @@ public static final String PREFERENCES_NAME = "variables_view"; // NOI18N public static final String SHOW_VALUE_AS_STRING = "show_value_as_string"; // NOI18N + private static final String DEACTIVATED_LINE_BREAKPOINT = + "org/netbeans/modules/debugger/resources/editor/Breakpoint_stroke.png"; // NOI18N public static JButton createNewBreakpointActionButton() { JButton button = VariablesViewButtons.createButton( @@ -97,6 +107,103 @@ }); return button; } + + @NbBundle.Messages({"CTL_DeactivateAllBreakpoints=Deactivate all breakpoints in current session", + "CTL_ActivateAllBreakpoints=Activate all breakpoints in current session", + "CTL_NoDeactivation=The current session does not allow to deactivate breakpoints", + "CTL_NoSession=No debugger session"}) + public static AbstractButton createActivateBreakpointsActionButton() { + ImageIcon icon = ImageUtilities.loadImageIcon(DEACTIVATED_LINE_BREAKPOINT, false); + final JToggleButton button = new JToggleButton(icon); + // ensure small size, just for the icon + Dimension size = new Dimension(icon.getIconWidth() + 8, icon.getIconHeight() + 8); + button.setPreferredSize(size); + button.setMargin(new Insets(1, 1, 1, 1)); + button.setBorder(new EmptyBorder(button.getBorder().getBorderInsets(button))); + button.setToolTipText(Bundle.CTL_DeactivateAllBreakpoints()); + button.setFocusable(false); + final BreakpointsActivator ba = new BreakpointsActivator(button); + button.addActionListener(ba); + DebuggerManager.getDebuggerManager().addDebuggerListener(DebuggerManager.PROP_CURRENT_ENGINE, new DebuggerManagerAdapter() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + DebuggerEngine de = (DebuggerEngine) evt.getNewValue(); + ba.setCurrentEngine(de); + } + }); + ba.setCurrentEngine(DebuggerManager.getDebuggerManager().getCurrentEngine()); + return button; + } + + private static class BreakpointsActivator implements ActionListener { + + private final Reference buttonRef; + //private DebuggerEngine currentEngine; + private volatile ActiveBreakpoints ab; + //private String name; + + public BreakpointsActivator(JToggleButton button) { + this.buttonRef = new WeakReference(button); + } + + public void setCurrentEngine(DebuggerEngine currentEngine) { + //this.currentEngine = currentEngine; + //Session session = currentEngine.lookupFirst(null, Session.class); + //this.name = session.getName(); + final JToggleButton button = buttonRef.get(); + if (button == null) { + return ; + } + ActiveBreakpoints ab; + final boolean active; + final boolean canDeactivate; + if (currentEngine == null) { + ab = null; + active = canDeactivate = false; + } else { + ab = ActiveBreakpoints.get(currentEngine); + active = ab.areBreakpointsActive(); + canDeactivate = ab.canDeactivateBreakpoints(); + } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + button.setSelected(!active); + button.setEnabled(canDeactivate); + setTooltip(button, active, canDeactivate); + } + }); + this.ab = ab; + } + + @Override + public void actionPerformed(ActionEvent e) { + ActiveBreakpoints ab = this.ab; + if (ab == null || !ab.canDeactivateBreakpoints()) { + return ; + } + JToggleButton button = (JToggleButton) e.getSource(); + final boolean active = !button.isSelected(); + ab.setBreakpointsActive(active); + setTooltip(button, active, true); + } + + private static void setTooltip(JToggleButton button, boolean active, boolean canDeactivate) { + if (!canDeactivate) { + if (active) { + button.setToolTipText(Bundle.CTL_NoDeactivation()); + } else { + button.setToolTipText(Bundle.CTL_NoSession()); + } + } else { + if (active) { + button.setToolTipText(Bundle.CTL_DeactivateAllBreakpoints()); + } else { + button.setToolTipText(Bundle.CTL_ActivateAllBreakpoints()); + } + } + } + } public static synchronized JButton createGroupSelectionButton() { final JButton button = VariablesViewButtons.createButton( --- a/web.javascript.debugger/src/org/netbeans/modules/web/javascript/debugger/breakpoints/WebBreakpointsActivation.java +++ a/web.javascript.debugger/src/org/netbeans/modules/web/javascript/debugger/breakpoints/WebBreakpointsActivation.java @@ -0,0 +1,125 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2015 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 2015 Sun Microsystems, Inc. + */ + +package org.netbeans.modules.web.javascript.debugger.breakpoints; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.netbeans.api.debugger.ActiveBreakpoints; +import org.netbeans.modules.web.webkit.debugging.api.Debugger; +import org.netbeans.spi.debugger.BreakpointsActivationProvider; +import org.netbeans.spi.debugger.ContextProvider; +import org.netbeans.spi.debugger.DebuggerServiceRegistration; +import org.openide.util.RequestProcessor; + +/** + * WEB JavaScript activation/deactivation of breakpoints. + * + * @author Martin Entlicher + */ +@DebuggerServiceRegistration(path="javascript-debuggerengine", types = BreakpointsActivationProvider.class) +public class WebBreakpointsActivation implements BreakpointsActivationProvider { + + private static final RequestProcessor RP = new RequestProcessor(WebBreakpointsActivation.class.getName()); + private final Debugger debugger; + private final Map listenersMap = Collections.synchronizedMap(new HashMap()); + + public WebBreakpointsActivation(ContextProvider contextProvider) { + this.debugger = contextProvider.lookupFirst(null, Debugger.class); + } + + @Override + public boolean areBreakpointsActive() { + return debugger.areBreakpointsActive(); + } + + @Override + public void setBreakpointsActive(final boolean active) { + RP.post(new Runnable() { + @Override + public void run() { + debugger.setBreakpointsActive(active); + } + }); + } + + @Override + public void addPropertyChangeListener(final PropertyChangeListener l) { + DelegateListener dl = new DelegateListener(this, l); + listenersMap.put(l, dl); + debugger.addPropertyChangeListener(dl); + } + + @Override + public void removePropertyChangeListener(PropertyChangeListener l) { + DelegateListener dl = listenersMap.remove(l); + if (dl != null) { + debugger.removePropertyChangeListener(dl); + } + } + + private static class DelegateListener implements PropertyChangeListener { + + private final Object source; + private final PropertyChangeListener l; + + public DelegateListener(Object source, PropertyChangeListener l) { + this.source = source; + this.l = l; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (Debugger.PROP_BREAKPOINTS_ACTIVE.equals(evt.getPropertyName())) { + l.propertyChange(new PropertyChangeEvent( + source, + ActiveBreakpoints.PROP_BREAKPOINTS_ACTIVE, + evt.getOldValue(), + evt.getNewValue())); + } + } + } + +}