diff --git a/php.dbgp/nbproject/project.xml b/php.dbgp/nbproject/project.xml
--- a/php.dbgp/nbproject/project.xml
+++ b/php.dbgp/nbproject/project.xml
@@ -133,6 +133,15 @@
+ org.netbeans.modules.editor.mimelookup
+
+
+
+ 1
+ 1.41
+
+
+
org.netbeans.modules.lexer
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointsReader.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointsReader.java
--- a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointsReader.java
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BreakpointsReader.java
@@ -47,11 +47,8 @@
import java.net.URL;
import org.netbeans.api.debugger.Properties;
import org.netbeans.modules.php.dbgp.breakpoints.FunctionBreakpoint.Type;
-import org.openide.cookies.LineCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
-import org.openide.loaders.DataObject;
-import org.openide.loaders.DataObjectNotFoundException;
import org.openide.text.Line;
/**
@@ -59,8 +56,7 @@
* @author ads
*/
public class BreakpointsReader implements Properties.Reader {
- private static final String LINE_NUMBER = "lineNumber"; // NOI18N
- private static final String URL = "url"; // NOI18N
+
private static final String ENABED = "enabled"; // NOI18N
private static final String FUNC_NAME = "functionName"; // NOI18N
private static final String TYPE = "type"; // NOI18N
@@ -77,7 +73,7 @@
@Override
public Object read(String typeID, Properties properties) {
if (typeID.equals(LineBreakpoint.class.getName())) {
- Line line = getLine(properties.getString(URL, null), properties.getInt(LINE_NUMBER, 1));
+ Line line = getLine(properties.getString(LineBreakpoint.PROP_URL, null), properties.getInt(LineBreakpoint.PROP_LINE_NUMBER, 1));
if (line == null) {
return null;
}
@@ -86,6 +82,7 @@
breakpoint.disable();
}
breakpoint.setGroupName(properties.getString(GROUP_NAME, ""));
+ breakpoint.setCondition(properties.getString(LineBreakpoint.PROP_CONDITION, null));
return breakpoint;
} else if (typeID.equals(FunctionBreakpoint.class.getName())) {
String func = properties.getString(FUNC_NAME, null);
@@ -109,10 +106,11 @@
if (object instanceof LineBreakpoint) {
LineBreakpoint breakpoint = (LineBreakpoint) object;
FileObject fileObject = breakpoint.getLine().getLookup().lookup(FileObject.class);
- properties.setString(URL, fileObject.toURL().toString());
- properties.setInt(LINE_NUMBER, breakpoint.getLine().getLineNumber());
+ properties.setString(LineBreakpoint.PROP_URL, fileObject.toURL().toString());
+ properties.setInt(LineBreakpoint.PROP_LINE_NUMBER, breakpoint.getLine().getLineNumber());
properties.setBoolean(ENABED, breakpoint.isEnabled());
properties.setString(GROUP_NAME, breakpoint.getGroupName());
+ properties.setString(LineBreakpoint.PROP_CONDITION, breakpoint.getCondition());
} else if (object instanceof FunctionBreakpoint) {
FunctionBreakpoint breakpoint = (FunctionBreakpoint) object;
String func = breakpoint.getFunction();
@@ -128,28 +126,7 @@
if (file == null) {
return null;
}
- DataObject dataObject;
- try {
- dataObject = DataObject.find(file);
- } catch (DataObjectNotFoundException ex) {
- return null;
- }
- if (dataObject == null) {
- return null;
- }
- LineCookie lineCookie = dataObject.getLookup().lookup(LineCookie.class);
- if (lineCookie == null) {
- return null;
- }
- Line.Set ls = lineCookie.getLineSet();
- if (ls == null) {
- return null;
- }
- try {
- return ls.getCurrent(lineNumber);
- } catch (IndexOutOfBoundsException e) {
- return null;
- }
+ return Utils.getLine(file, lineNumber);
}
private FileObject getFileObject(String url) {
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BrkptsViewActionProvider.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BrkptsViewActionProvider.java
--- a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BrkptsViewActionProvider.java
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/BrkptsViewActionProvider.java
@@ -43,13 +43,25 @@
*/
package org.netbeans.modules.php.dbgp.breakpoints;
+import java.awt.Dialog;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import javax.swing.Action;
-
+import org.netbeans.modules.php.dbgp.ui.DbgpLineBreakpointCustomizer;
+import org.netbeans.modules.php.dbgp.ui.DbgpLineBreakpointCustomizerPanel;
+import org.netbeans.spi.debugger.ui.Controller;
import org.netbeans.spi.viewmodel.Models;
import org.netbeans.spi.viewmodel.NodeActionsProvider;
import org.netbeans.spi.viewmodel.NodeActionsProviderFilter;
import org.netbeans.spi.viewmodel.UnknownTypeException;
+import org.openide.DialogDescriptor;
+import org.openide.DialogDisplayer;
+import org.openide.NotificationLineSupport;
+import org.openide.NotifyDescriptor;
import org.openide.text.Line;
+import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
/**
@@ -63,10 +75,12 @@
public Action[] getActions(NodeActionsProvider original, Object node) throws UnknownTypeException {
Action[] actions = original.getActions(node);
if (node instanceof LineBreakpoint) {
- Action[] newActions = new Action[actions.length + 2];
+ Action[] newActions = new Action[actions.length + 4];
newActions[0] = GO_TO_SOURCE_ACTION;
newActions[1] = null;
System.arraycopy(actions, 0, newActions, 2, actions.length);
+ newActions[newActions.length - 2] = null;
+ newActions[newActions.length - 1] = CUSTOMIZE_ACTION;
actions = newActions;
}
return actions;
@@ -87,6 +101,64 @@
line.show(Line.ShowOpenType.REUSE, Line.ShowVisibilityType.FOCUS);
}
}
+
+ @NbBundle.Messages("CTL_Breakpoint_Customizer_Title=Breakpoint Properties")
+ private static void customize(LineBreakpoint lb) {
+ DbgpLineBreakpointCustomizerPanel panel = DbgpLineBreakpointCustomizer.getCustomizerComponent(lb);
+ HelpCtx helpCtx = HelpCtx.findHelp(panel);
+ if (helpCtx == null) {
+ helpCtx = new HelpCtx("debug.add.breakpoint"); // NOI18N
+ }
+
+ Controller controller = panel.getController();
+ if (controller == null) {
+ return;
+ }
+
+ final Controller[] cPtr = new Controller[]{controller};
+ final DialogDescriptor[] descriptorPtr = new DialogDescriptor[1];
+ final Dialog[] dialogPtr = new Dialog[1];
+ final PropertyChangeListener propertyChangeListener = (PropertyChangeEvent e) -> {
+ if (e.getPropertyName().equals(NotifyDescriptor.PROP_ERROR_NOTIFICATION)) {
+ Object v = e.getNewValue();
+ String message = (v == null) ? null : v.toString();
+ descriptorPtr[0].getNotificationLineSupport().setErrorMessage(message);
+ } else if (e.getPropertyName().equals(Controller.PROP_VALID)) {
+ descriptorPtr[0].setValid(controller.isValid());
+ }
+ };
+ controller.addPropertyChangeListener(propertyChangeListener);
+ ActionListener buttonsActionListener = (ActionEvent e) -> {
+ if (descriptorPtr[0].getValue() == DialogDescriptor.OK_OPTION) {
+ boolean ok = cPtr[0].ok();
+ if (ok) {
+ dialogPtr[0].setVisible(false);
+ cPtr[0].removePropertyChangeListener(propertyChangeListener);
+ }
+ } else {
+ dialogPtr[0].setVisible(false);
+ cPtr[0].removePropertyChangeListener(propertyChangeListener);
+ }
+ };
+ DialogDescriptor descriptor = new DialogDescriptor(
+ panel,
+ Bundle.CTL_Breakpoint_Customizer_Title(),
+ true,
+ DialogDescriptor.OK_CANCEL_OPTION,
+ DialogDescriptor.OK_OPTION,
+ DialogDescriptor.DEFAULT_ALIGN,
+ helpCtx,
+ buttonsActionListener
+ );
+ descriptor.setClosingOptions(new Object[]{});
+ descriptor.createNotificationLineSupport();
+ Dialog d = DialogDisplayer.getDefault().createDialog(descriptor);
+ d.pack();
+ descriptorPtr[0] = descriptor;
+ dialogPtr[0] = d;
+ d.setVisible(true);
+ }
+
private static final Action GO_TO_SOURCE_ACTION = Models.createAction(
NbBundle.getMessage(BrkptsViewActionProvider.class, GO_TO_SOURCE_LABEL),
new GoToSourcePerformer(),
@@ -106,4 +178,24 @@
}
+ @NbBundle.Messages("CTL_Breakpoint_Customize_Label=Properties")
+ private static final Action CUSTOMIZE_ACTION = Models.createAction(
+ Bundle.CTL_Breakpoint_Customize_Label(),
+ new CustomizePerformer(),
+ Models.MULTISELECTION_TYPE_EXACTLY_ONE
+ );
+
+ private static class CustomizePerformer implements Models.ActionPerformer {
+
+ @Override
+ public boolean isEnabled(Object node) {
+ return true;
+ }
+
+ @Override
+ public void perform(Object[] nodes) {
+ customize((LineBreakpoint) nodes[0]);
+ }
+ }
+
}
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/DbgpLineBreakpointType.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/DbgpLineBreakpointType.java
new file mode 100644
--- /dev/null
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/DbgpLineBreakpointType.java
@@ -0,0 +1,115 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 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):
+ */
+package org.netbeans.modules.php.dbgp.breakpoints;
+
+import javax.swing.JComponent;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.JTextComponent;
+import org.netbeans.api.editor.EditorRegistry;
+import org.netbeans.api.editor.document.LineDocumentUtils;
+import org.netbeans.editor.BaseDocument;
+import org.netbeans.modules.editor.NbEditorUtilities;
+import org.netbeans.modules.php.api.util.FileUtils;
+import org.netbeans.modules.php.dbgp.ui.DbgpLineBreakpointCustomizerPanel;
+import org.netbeans.spi.debugger.ui.BreakpointType;
+import org.netbeans.spi.debugger.ui.Controller;
+import org.openide.filesystems.FileObject;
+import org.openide.text.Line;
+import org.openide.util.NbBundle;
+
+@NbBundle.Messages({
+ "DbgpLineBreakpointType.CategoryDisplayName=PHP",
+ "DbgpLineBreakpointType.TypeDisplayName=Line"
+})
+@BreakpointType.Registration(displayName = "#DbgpLineBreakpointType.TypeDisplayName")
+public class DbgpLineBreakpointType extends BreakpointType {
+
+ private Controller controller;
+
+ @Override
+ public String getCategoryDisplayName() {
+ return Bundle.DbgpLineBreakpointType_CategoryDisplayName();
+ }
+
+ @Override
+ public String getTypeDisplayName() {
+ return Bundle.DbgpLineBreakpointType_TypeDisplayName();
+ }
+
+ @Override
+ public JComponent getCustomizer() {
+ JTextComponent lastFocusedComponent = EditorRegistry.lastFocusedComponent();
+ Line line;
+ if (lastFocusedComponent != null) {
+ FileObject fileObject = NbEditorUtilities.getFileObject(lastFocusedComponent.getDocument());
+ int caretPosition = lastFocusedComponent.getCaretPosition();
+ try {
+ int lineNumber = LineDocumentUtils.getLineIndex((BaseDocument) lastFocusedComponent.getDocument(), caretPosition);
+ line = Utils.getLine(fileObject, lineNumber);
+ } catch (BadLocationException ex) {
+ line = null;
+ }
+ } else {
+ line = null;
+ }
+ DbgpLineBreakpointCustomizerPanel customizer = new DbgpLineBreakpointCustomizerPanel(line);
+ controller = customizer.getController();
+ return customizer;
+ }
+
+ @Override
+ public Controller getController() {
+ return controller;
+ }
+
+ @Override
+ public boolean isDefault() {
+ JTextComponent lastFocusedComponent = EditorRegistry.lastFocusedComponent();
+ if (lastFocusedComponent == null) {
+ return false;
+ }
+ FileObject fileObject = NbEditorUtilities.getFileObject(lastFocusedComponent.getDocument());
+ if (fileObject == null) {
+ return false;
+ }
+ return FileUtils.isPhpFile(fileObject);
+ }
+
+}
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/LineBreakpoint.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/LineBreakpoint.java
--- a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/LineBreakpoint.java
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/LineBreakpoint.java
@@ -61,6 +61,7 @@
import org.netbeans.editor.BaseDocument;
import org.netbeans.editor.Utilities;
import org.netbeans.modules.csl.api.OffsetRange;
+import org.netbeans.modules.csl.spi.support.CancelSupport;
import org.netbeans.modules.parsing.api.ParserManager;
import org.netbeans.modules.parsing.api.ResultIterator;
import org.netbeans.modules.parsing.api.Source;
@@ -79,6 +80,7 @@
import org.openide.filesystems.FileChangeListener;
import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileRenameEvent;
import org.openide.loaders.DataObject;
import org.openide.text.DataEditorSupport;
import org.openide.text.Line;
@@ -87,17 +89,26 @@
import org.openide.util.WeakListeners;
/**
+ * If this class name is changed, {@link LineBreakpointBeanInfo} class name must
+ * be changed.
*
* @author ads
*/
public class LineBreakpoint extends AbstractBreakpoint {
+
private static final Logger LOGGER = Logger.getLogger(LineBreakpoint.class.getName());
private static final RequestProcessor RP = new RequestProcessor(LineBreakpoint.class);
+ public static final String PROP_URL = "url"; // NOI18N
+ public static final String PROP_LINE_NUMBER = "lineNumber"; // NOI18N
+ public static final String PROP_CONDITION = "condition"; // NOI18N
+
private final Line myLine;
private final FileRemoveListener myListener;
private FileChangeListener myWeakListener;
private final String myFileUrl;
private final Future isValidFuture;
+ // @GuardedBy("this")
+ private String condition;
public LineBreakpoint(Line line) {
myLine = line;
@@ -188,6 +199,24 @@
return myFileUrl;
}
+ public synchronized final String getCondition() {
+ return condition;
+ }
+
+ public synchronized final void setCondition(String condition) {
+ String oldCondition = this.condition;
+ if ((condition != null && condition.equals(oldCondition))
+ || (condition == null && oldCondition == null)) {
+ return;
+ }
+ this.condition = condition;
+ firePropertyChange(PROP_CONDITION, oldCondition, condition);
+ }
+
+ public synchronized final boolean isConditional() {
+ return condition != null && !condition.isEmpty();
+ }
+
@Override
public int isTemp() {
return 0;
@@ -215,6 +244,11 @@
return new PhpGroupProperties();
}
+ void fireLineNumberChanged() {
+ int lineNumber = getLine().getLineNumber();
+ firePropertyChange(PROP_LINE_NUMBER, null, lineNumber);
+ }
+
//~ Inner classes
private final class PhpGroupProperties extends GroupProperties {
@@ -277,6 +311,12 @@
LineBreakpoint.this);
}
+ @Override
+ public void fileRenamed(FileRenameEvent fe) {
+ FileObject renamedFo = fe.getFile();
+ firePropertyChange(PROP_URL, myFileUrl, renamedFo.toURL().toString());
+ }
+
}
private static final class StatementVisitor extends DefaultVisitor {
@@ -291,6 +331,9 @@
@Override
public void scan(ASTNode node) {
+ if (CancelSupport.getDefault().isCancelled()) {
+ return;
+ }
if (node != null) {
OffsetRange nodeRange = new OffsetRange(node.getStartOffset(), node.getEndOffset());
if (node instanceof Statement && nodeRange.containsInclusive(contentStart) && nodeRange.containsInclusive(contentEnd)) {
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/LineBreakpointBeanInfo.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/LineBreakpointBeanInfo.java
new file mode 100644
--- /dev/null
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/LineBreakpointBeanInfo.java
@@ -0,0 +1,67 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 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):
+ */
+package org.netbeans.modules.php.dbgp.breakpoints;
+
+import java.beans.BeanDescriptor;
+import java.beans.SimpleBeanInfo;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.openide.util.Lookup;
+
+/**
+ * Don't change this class name. If it is changed, {@link LineBreakpoint} class name
+ * must be changed.
+ */
+public class LineBreakpointBeanInfo extends SimpleBeanInfo {
+
+ private static final Logger LOGGER = Logger.getLogger(LineBreakpointBeanInfo.class.getName());
+
+ @Override
+ public BeanDescriptor getBeanDescriptor() {
+ Class customizer = null;
+ try {
+ customizer = Class.forName("org.netbeans.modules.php.dbgp.ui.DbgpLineBreakpointCustomizer", // NOI18N
+ true, Lookup.getDefault().lookup(ClassLoader.class));
+ } catch (ClassNotFoundException cnfex) {
+ LOGGER.log(Level.WARNING, "No BP customizer", cnfex); // NOI18N
+ }
+ return new BeanDescriptor(LineBreakpoint.class, customizer);
+ }
+}
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/UpdatePropertiesOnSaveTask.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/UpdatePropertiesOnSaveTask.java
new file mode 100644
--- /dev/null
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/UpdatePropertiesOnSaveTask.java
@@ -0,0 +1,99 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 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):
+ */
+package org.netbeans.modules.php.dbgp.breakpoints;
+
+import javax.swing.text.Document;
+import org.netbeans.api.debugger.Breakpoint;
+import org.netbeans.api.debugger.DebuggerManager;
+import org.netbeans.api.editor.mimelookup.MimeRegistration;
+import org.netbeans.modules.editor.NbEditorUtilities;
+import org.netbeans.modules.php.api.util.FileUtils;
+import org.netbeans.spi.editor.document.OnSaveTask;
+import org.openide.filesystems.FileObject;
+
+/**
+ * Save line number on save.
+ */
+public class UpdatePropertiesOnSaveTask implements OnSaveTask {
+
+ private final Context context;
+
+ private UpdatePropertiesOnSaveTask(Context context) {
+ this.context = context;
+ }
+
+ @Override
+ public void performTask() {
+ Document document = context.getDocument();
+ FileObject fileObject = NbEditorUtilities.getFileObject(document);
+ if (fileObject == null) {
+ return;
+ }
+ String fileUrl = fileObject.toURL().toString();
+ DebuggerManager manager = DebuggerManager.getDebuggerManager();
+ for (Breakpoint breakpoint : manager.getBreakpoints()) {
+ if (breakpoint instanceof LineBreakpoint) {
+ LineBreakpoint lineBreakpoint = (LineBreakpoint) breakpoint;
+ if (fileUrl.equals(lineBreakpoint.getFileUrl())) {
+ lineBreakpoint.fireLineNumberChanged();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void runLocked(Runnable run) {
+ run.run();
+ }
+
+ @Override
+ public boolean cancel() {
+ return true;
+ }
+
+ @MimeRegistration(mimeType = FileUtils.PHP_MIME_TYPE, service = OnSaveTask.Factory.class, position = 1100)
+ public static final class FactoryImpl implements Factory {
+
+ @Override
+ public OnSaveTask createTask(Context context) {
+ return new UpdatePropertiesOnSaveTask(context);
+ }
+ }
+}
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/Utils.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/Utils.java
--- a/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/Utils.java
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/breakpoints/Utils.java
@@ -46,6 +46,7 @@
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
+import org.netbeans.api.annotations.common.CheckForNull;
import org.netbeans.api.debugger.Breakpoint;
import org.netbeans.api.debugger.DebuggerManager;
import org.netbeans.api.options.OptionsDisplayer;
@@ -80,6 +81,12 @@
Utils.lineFactory = lineFactory;
}
+ /**
+ * Get the current line.
+ *
+ * @return the current line if the file is php, otherwise {@code null}.
+ */
+ @CheckForNull
public static Line getCurrentLine() {
FileObject fileObject = EditorContextDispatcher.getDefault().getCurrentFile();
@@ -90,6 +97,44 @@
return EditorContextDispatcher.getDefault().getCurrentLine();
}
+ /**
+ * Get the Line from FileObject.
+ *
+ * @param file the FileObject
+ * @param lineNumber the line number
+ * @return the line if it is found with the file and the line number,
+ * otherwise {@code null}
+ */
+ @CheckForNull
+ public static Line getLine(FileObject file, int lineNumber) {
+ if (file == null || lineNumber < 0) {
+ return null;
+ }
+
+ DataObject dataObject;
+ try {
+ dataObject = DataObject.find(file);
+ } catch (DataObjectNotFoundException ex) {
+ return null;
+ }
+ if (dataObject == null) {
+ return null;
+ }
+ LineCookie lineCookie = dataObject.getLookup().lookup(LineCookie.class);
+ if (lineCookie == null) {
+ return null;
+ }
+ Line.Set ls = lineCookie.getLineSet();
+ if (ls == null) {
+ return null;
+ }
+ try {
+ return ls.getCurrent(lineNumber);
+ } catch (IndexOutOfBoundsException e) {
+ return null;
+ }
+ }
+
public static BrkpntSetCommand getCommand(DebugSession session, SessionId id, AbstractBreakpoint breakpoint) {
if (!breakpoint.isSessionRelated(session)) {
return null;
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntCommandBuilder.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntCommandBuilder.java
--- a/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntCommandBuilder.java
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntCommandBuilder.java
@@ -55,10 +55,15 @@
*
*/
public final class BrkpntCommandBuilder {
+
private BrkpntCommandBuilder() {
}
public static BrkpntSetCommand buildLineBreakpoint(SessionId id, String transactionId, FileObject localFile, int lineNumber) {
+ return buildLineBreakpoint(id, transactionId, localFile, lineNumber, null);
+ }
+
+ public static BrkpntSetCommand buildLineBreakpoint(SessionId id, String transactionId, FileObject localFile, int lineNumber, String condition) {
if (localFile == null) {
// #251806
return null;
@@ -71,13 +76,14 @@
command.setType(Types.LINE);
command.setFile(uri);
command.setLineNumber(lineNumber);
+ command.setExpression(condition);
return command;
}
public static BrkpntSetCommand buildLineBreakpoint(SessionId id, String transactionId, LineBreakpoint breakpoint) {
Line line = breakpoint.getLine();
FileObject fileObject = line.getLookup().lookup(FileObject.class);
- BrkpntSetCommand command = buildLineBreakpoint(id, transactionId, fileObject, line.getLineNumber());
+ BrkpntSetCommand command = buildLineBreakpoint(id, transactionId, fileObject, line.getLineNumber(), breakpoint.getCondition());
if (command != null) {
command.setBreakpoint(breakpoint);
}
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntSetCommand.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntSetCommand.java
--- a/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntSetCommand.java
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/packets/BrkpntSetCommand.java
@@ -158,7 +158,7 @@
}
public void setExpression(String expression) {
- myException = expression;
+ myExpression = expression;
}
public void setTemporary(boolean isTemp) {
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/Bundle.properties b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/Bundle.properties
--- a/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/Bundle.properties
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/Bundle.properties
@@ -41,6 +41,7 @@
# made subject to such option by the copyright holder.
LBL_Settings=Settings
+LBL_Condition=Condition
LBL_MethodName=&Method Name:
LBL_StopOn=&Stop On:
A11_SettingsName=Settings
@@ -88,3 +89,9 @@
LocalFilterPanel.myResource.AccessibleContext.accessibleDescription=Enable for resource
LocalFilterPanel.myNull.AccessibleContext.accessibleDescription=Enable for null type
LocalFilterPanel.mySelectLbl.AccessibleContext.accessibleName=Select types to show
+DbgpLineBreakpointCustomizerPanel.conditionCheckBox.text=&Condition:
+DbgpLineBreakpointCustomizerPanel.lineNumberTextField.text=
+DbgpLineBreakpointCustomizerPanel.fileTextField.text=
+DbgpLineBreakpointCustomizerPanel.lineNumberLabel.text=&Line Number:
+DbgpLineBreakpointCustomizerPanel.fileLabel.text=&File:
+DbgpLineBreakpointCustomizerPanel.conditionComboBox.toolTipText=Breakpoint is hit when this condition evaluates to true.
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/ControllerProvider.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/ControllerProvider.java
new file mode 100644
--- /dev/null
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/ControllerProvider.java
@@ -0,0 +1,47 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 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):
+ */
+package org.netbeans.modules.php.dbgp.ui;
+
+import org.netbeans.spi.debugger.ui.Controller;
+
+public interface ControllerProvider {
+
+ Controller getController();
+}
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizer.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizer.java
new file mode 100644
--- /dev/null
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizer.java
@@ -0,0 +1,97 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 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):
+ */
+package org.netbeans.modules.php.dbgp.ui;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.beans.Customizer;
+import javax.swing.JPanel;
+import org.netbeans.modules.php.dbgp.breakpoints.LineBreakpoint;
+import org.netbeans.spi.debugger.ui.Controller;
+import org.openide.util.NbBundle;
+
+public class DbgpLineBreakpointCustomizer extends JPanel implements Customizer, Controller {
+
+ private static final long serialVersionUID = 3626744241527549679L;
+
+ private LineBreakpoint b;
+ private DbgpLineBreakpointCustomizerPanel c;
+
+ public DbgpLineBreakpointCustomizer() {
+ }
+
+ @NbBundle.Messages("ACSD_Breakpoint_Customizer_Dialog=Customize this breakpoint's properties")
+ public static DbgpLineBreakpointCustomizerPanel getCustomizerComponent(LineBreakpoint lineBreakpoint) {
+ DbgpLineBreakpointCustomizerPanel panel;
+ panel = new DbgpLineBreakpointCustomizerPanel(lineBreakpoint);
+ panel.getAccessibleContext().setAccessibleDescription(Bundle.ACSD_Breakpoint_Customizer_Dialog());
+ return panel;
+ }
+
+ @Override
+ public void setObject(Object bean) {
+ if (!(bean instanceof LineBreakpoint)) {
+ throw new IllegalArgumentException(bean.toString());
+ }
+ this.b = (LineBreakpoint) bean;
+ init(b);
+ }
+
+ private void init(LineBreakpoint b) {
+ c = getCustomizerComponent(b);
+ setLayout(new GridBagLayout());
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.fill = GridBagConstraints.BOTH;
+ gbc.weightx = 1.0;
+ gbc.weighty = 1.0;
+ add(c, gbc);
+ }
+
+ @Override
+ public boolean ok() {
+ return c.getController().ok();
+ }
+
+ @Override
+ public boolean cancel() {
+ return c.getController().cancel();
+ }
+
+}
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizerPanel.form b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizerPanel.form
new file mode 100644
--- /dev/null
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizerPanel.form
@@ -0,0 +1,170 @@
+
+
+
diff --git a/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizerPanel.java b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizerPanel.java
new file mode 100644
--- /dev/null
+++ b/php.dbgp/src/org/netbeans/modules/php/dbgp/ui/DbgpLineBreakpointCustomizerPanel.java
@@ -0,0 +1,466 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2017 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):
+ */
+package org.netbeans.modules.php.dbgp.ui;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.File;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import org.netbeans.api.debugger.DebuggerManager;
+import org.netbeans.api.debugger.Properties;
+import org.netbeans.modules.php.dbgp.breakpoints.LineBreakpoint;
+import org.netbeans.modules.php.dbgp.breakpoints.Utils;
+import org.netbeans.spi.debugger.ui.Controller;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
+import org.openide.text.Line;
+import org.openide.util.NbBundle;
+
+public class DbgpLineBreakpointCustomizerPanel extends JPanel implements ControllerProvider {
+
+ private static final int MAX_SAVED_CONDITIONS = 10;
+ private static final String BP_CONDITIONS = "BPConditions"; // NOI18N
+ private static final String DEBUGGER_PHP = "debugger.php"; // NOI18N
+ private static final long serialVersionUID = 6364512868561614302L;
+
+ private final LineBreakpoint lineBreakpoint;
+ private final Controller controller;
+ private boolean createBreakpoint;
+
+ private static LineBreakpoint createLineBreakpoint() {
+ Line currentLine = Utils.getCurrentLine();
+ return createLineBreakpoint(currentLine);
+ }
+
+ private static LineBreakpoint createLineBreakpoint(Line line) {
+ if (line != null) {
+ return new LineBreakpoint(line);
+ }
+ return null;
+ }
+
+ public DbgpLineBreakpointCustomizerPanel() {
+ this(createLineBreakpoint(), true);
+ createBreakpoint = true;
+ }
+
+ public DbgpLineBreakpointCustomizerPanel(Line line) {
+ this(createLineBreakpoint(line), true);
+ createBreakpoint = true;
+ }
+
+ public DbgpLineBreakpointCustomizerPanel(LineBreakpoint lineBreakpoint) {
+ this(lineBreakpoint, false);
+ }
+
+ private DbgpLineBreakpointCustomizerPanel(LineBreakpoint lineBreakpoint, boolean isEditable) {
+ this.lineBreakpoint = lineBreakpoint;
+ controller = createController();
+ initComponents();
+
+ DocumentListener defaultDocumentListener = new DocumentListener() {
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ processUpdate();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ processUpdate();
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ processUpdate();
+ }
+
+ private void processUpdate() {
+ ((CustomizerController) controller).firePropertyChange();
+ }
+ };
+ fileTextField.setEditable(isEditable);
+ fileTextField.getDocument().addDocumentListener(defaultDocumentListener);
+ lineNumberTextField.setEditable(isEditable);
+ lineNumberTextField.getDocument().addDocumentListener(defaultDocumentListener);
+ Object[] conditions = getSavedConditions();
+ conditionComboBox.setModel(new DefaultComboBoxModel(conditions));
+
+ if (lineBreakpoint != null) {
+ Line line = lineBreakpoint.getLine();
+ FileObject fo = line.getLookup().lookup(FileObject.class);
+ updateComponents(fo, line.getLineNumber() + 1, lineBreakpoint.getCondition());
+ }
+ }
+
+ private void updateComponents(FileObject fileObject, int lineNumber, String condition) {
+ assert SwingUtilities.isEventDispatchThread();
+ if (fileObject != null) {
+ File file = FileUtil.toFile(fileObject);
+ if (file != null) {
+ fileTextField.setText(file.getAbsolutePath());
+ } else {
+ fileTextField.setText(fileObject.toURL().toExternalForm());
+ }
+ }
+
+ lineNumberTextField.setText(Integer.toString(lineNumber));
+
+ if (condition != null && !condition.isEmpty()) {
+ conditionCheckBox.setSelected(true);
+ conditionComboBox.setEnabled(true);
+ conditionComboBox.getEditor().setItem(condition);
+ } else {
+ conditionCheckBox.setSelected(false);
+ conditionComboBox.setEnabled(false);
+ }
+ }
+
+ private static Object[] getSavedConditions() {
+ return Properties.getDefault()
+ .getProperties(DEBUGGER_PHP)
+ .getArray(BP_CONDITIONS, new Object[0]);
+ }
+
+ private static void saveCondition(String condition) {
+ Object[] savedConditions = getSavedConditions();
+ Object[] conditions = null;
+ boolean containsCondition = false;
+ for (int i = 0; i < savedConditions.length; i++) {
+ Object c = savedConditions[i];
+ if (condition.equals(c)) {
+ containsCondition = true;
+ conditions = savedConditions;
+ if (i > 0) {
+ System.arraycopy(conditions, 0, conditions, 1, i);
+ conditions[0] = condition;
+ }
+ break;
+ }
+ }
+ if (!containsCondition) {
+ if (savedConditions.length < MAX_SAVED_CONDITIONS) {
+ conditions = new Object[savedConditions.length + 1];
+ conditions[0] = condition;
+ System.arraycopy(savedConditions, 0, conditions, 1, savedConditions.length);
+ } else {
+ conditions = savedConditions;
+ System.arraycopy(conditions, 0, conditions, 1, conditions.length - 1);
+ conditions[0] = condition;
+ }
+ }
+ Properties.getDefault()
+ .getProperties(DEBUGGER_PHP)
+ .setArray(BP_CONDITIONS, conditions);
+ }
+
+ private Controller createController() {
+ return new CustomizerController();
+ }
+
+ @Override
+ public Controller getController() {
+ return controller;
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // //GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ settingsPanel = new javax.swing.JPanel();
+ fileLabel = new javax.swing.JLabel();
+ lineNumberLabel = new javax.swing.JLabel();
+ fileTextField = new javax.swing.JTextField();
+ lineNumberTextField = new javax.swing.JTextField();
+ conditionPanel = new javax.swing.JPanel();
+ conditionCheckBox = new javax.swing.JCheckBox();
+ conditionComboBox = new javax.swing.JComboBox<>();
+
+ settingsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "LBL_Settings"))); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(fileLabel, org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "DbgpLineBreakpointCustomizerPanel.fileLabel.text")); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(lineNumberLabel, org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "DbgpLineBreakpointCustomizerPanel.lineNumberLabel.text")); // NOI18N
+
+ fileTextField.setText(org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "DbgpLineBreakpointCustomizerPanel.fileTextField.text")); // NOI18N
+
+ lineNumberTextField.setText(org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "DbgpLineBreakpointCustomizerPanel.lineNumberTextField.text")); // NOI18N
+
+ javax.swing.GroupLayout settingsPanelLayout = new javax.swing.GroupLayout(settingsPanel);
+ settingsPanel.setLayout(settingsPanelLayout);
+ settingsPanelLayout.setHorizontalGroup(
+ settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(settingsPanelLayout.createSequentialGroup()
+ .addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lineNumberLabel)
+ .addComponent(fileLabel))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(fileTextField)
+ .addComponent(lineNumberTextField)))
+ );
+ settingsPanelLayout.setVerticalGroup(
+ settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(settingsPanelLayout.createSequentialGroup()
+ .addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(fileLabel)
+ .addComponent(fileTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lineNumberLabel)
+ .addComponent(lineNumberTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ );
+
+ conditionPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "LBL_Condition"))); // NOI18N
+
+ org.openide.awt.Mnemonics.setLocalizedText(conditionCheckBox, org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "DbgpLineBreakpointCustomizerPanel.conditionCheckBox.text")); // NOI18N
+ conditionCheckBox.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ conditionCheckBoxActionPerformed(evt);
+ }
+ });
+
+ conditionComboBox.setEditable(true);
+ conditionComboBox.setToolTipText(org.openide.util.NbBundle.getMessage(DbgpLineBreakpointCustomizerPanel.class, "DbgpLineBreakpointCustomizerPanel.conditionComboBox.toolTipText")); // NOI18N
+
+ javax.swing.GroupLayout conditionPanelLayout = new javax.swing.GroupLayout(conditionPanel);
+ conditionPanel.setLayout(conditionPanelLayout);
+ conditionPanelLayout.setHorizontalGroup(
+ conditionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(conditionPanelLayout.createSequentialGroup()
+ .addComponent(conditionCheckBox)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(conditionComboBox, 0, 281, Short.MAX_VALUE))
+ );
+ conditionPanelLayout.setVerticalGroup(
+ conditionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(conditionPanelLayout.createSequentialGroup()
+ .addGap(0, 0, 0)
+ .addGroup(conditionPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(conditionCheckBox)
+ .addComponent(conditionComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
+ this.setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(settingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(conditionPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(settingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(conditionPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ }// //GEN-END:initComponents
+
+ private void conditionCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_conditionCheckBoxActionPerformed
+ conditionComboBox.setEnabled(conditionCheckBox.isSelected());
+ if (conditionCheckBox.isSelected()) {
+ conditionComboBox.requestFocusInWindow();
+ }
+ }//GEN-LAST:event_conditionCheckBoxActionPerformed
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JCheckBox conditionCheckBox;
+ private javax.swing.JComboBox conditionComboBox;
+ private javax.swing.JPanel conditionPanel;
+ private javax.swing.JLabel fileLabel;
+ private javax.swing.JTextField fileTextField;
+ private javax.swing.JLabel lineNumberLabel;
+ private javax.swing.JTextField lineNumberTextField;
+ private javax.swing.JPanel settingsPanel;
+ // End of variables declaration//GEN-END:variables
+
+ //~ Inner classes
+ private class CustomizerController implements Controller {
+
+ private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
+ private String errorMessage;
+
+ @Override
+ public boolean ok() {
+ if (!isValid()) {
+ final String message = getErrorMessage();
+ if (message != null) {
+ if (SwingUtilities.isEventDispatchThread()) {
+ showMessageDialog(message);
+ } else {
+ SwingUtilities.invokeLater(() -> {
+ showMessageDialog(message);
+ });
+ }
+ }
+ return false;
+ }
+
+ String condition = null;
+ if (conditionCheckBox.isSelected()) {
+ condition = conditionComboBox.getSelectedItem().toString().trim();
+ }
+
+ if (createBreakpoint) {
+ String fileName = fileTextField.getText();
+ String lineNumberString = lineNumberTextField.getText();
+ if (fileName == null) {
+ return false;
+ }
+ File file = new File(fileName.trim());
+ FileObject fileObject = FileUtil.toFileObject(file);
+ if (fileObject == null) {
+ return false;
+ }
+ Line line = Utils.getLine(fileObject, Integer.parseInt(lineNumberString) - 1);
+ LineBreakpoint lb = createLineBreakpoint(line);
+ setCondition(lb, condition);
+ DebuggerManager.getDebuggerManager().addBreakpoint(lb);
+ } else {
+ setCondition(lineBreakpoint, condition);
+ }
+
+ return true;
+ }
+
+ private void setCondition(LineBreakpoint lb, String condition) {
+ if (condition != null && !condition.isEmpty()) {
+ lb.setCondition(condition);
+ saveCondition(condition);
+ } else {
+ lb.setCondition(null);
+ }
+ }
+
+ @Override
+ public boolean cancel() {
+ return true;
+ }
+
+ @NbBundle.Messages({
+ "CustomizerController.invalid.file=Existing file must be set.",
+ "CustomizerController.invalid.line=Valid line number must be set."
+ })
+ @Override
+ public boolean isValid() {
+ boolean isValid = true;
+ // file
+ String fileName = fileTextField.getText();
+ if (fileName == null || fileName.trim().length() == 0) {
+ setErrorMessage(Bundle.CustomizerController_invalid_file());
+ return false;
+ }
+ File file = new File(fileName.trim());
+ if (!file.exists()) {
+ setErrorMessage(Bundle.CustomizerController_invalid_file());
+ return false;
+ }
+ FileObject fileObject = FileUtil.toFileObject(file);
+ if (fileObject == null) {
+ setErrorMessage(Bundle.CustomizerController_invalid_file());
+ return false;
+ }
+
+ // line number
+ String lineNumberString = lineNumberTextField.getText();
+ if (lineNumberString == null || lineNumberString.trim().length() == 0) {
+ setErrorMessage(Bundle.CustomizerController_invalid_line());
+ return false;
+ }
+ try {
+ int lineNumber = Integer.parseInt(lineNumberTextField.getText());
+ if (lineNumber <= 0) {
+ setErrorMessage(Bundle.CustomizerController_invalid_line());
+ return false;
+ }
+ } catch (NumberFormatException nfe) {
+ setErrorMessage(Bundle.CustomizerController_invalid_line());
+ isValid = false;
+ }
+
+ if (isValid) {
+ setErrorMessage(null);
+ }
+ return isValid;
+ }
+
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ propertyChangeSupport.addPropertyChangeListener(l);
+ }
+
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ propertyChangeSupport.removePropertyChangeListener(l);
+ }
+
+ void firePropertyChange() {
+ propertyChangeSupport.firePropertyChange(Controller.PROP_VALID, null, null);
+ }
+
+ void setErrorMessage(String message) {
+ errorMessage = message;
+ propertyChangeSupport.firePropertyChange(NotifyDescriptor.PROP_ERROR_NOTIFICATION, null, message);
+ }
+
+ String getErrorMessage() {
+ return errorMessage;
+ }
+
+ private void showMessageDialog(String message) {
+ NotifyDescriptor descr = new NotifyDescriptor.Message(message);
+ DialogDisplayer.getDefault().notify(descr);
+ }
+
+ }
+
+}