blob: 7c1d56178221bf267039232cdff1c612568bdcc4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.refactoring.java.ui;
import com.sun.source.tree.Tree;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.util.Collection;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeListener;
import org.netbeans.api.fileinfo.NonRecursiveFolder;
import org.netbeans.api.java.source.CancellableTask;
import org.netbeans.api.java.source.CompilationController;
import org.netbeans.api.java.source.JavaSource;
import org.netbeans.api.java.source.JavaSource.Phase;
import org.netbeans.api.java.source.TreePathHandle;
import org.netbeans.modules.refactoring.api.SafeDeleteRefactoring;
import org.netbeans.modules.refactoring.java.RefactoringModule;
import org.netbeans.modules.refactoring.spi.ui.CustomRefactoringPanel;
import org.openide.awt.Mnemonics;
import org.openide.filesystems.FileObject;
import org.openide.util.Lookup;
import org.openide.util.NbBundle;
/**
* Subclass of CustomRefactoringPanel representing the
* Safe Delete refactoring UI
* @author Bharath Ravikumar
*/
public class SafeDeletePanel extends JPanel implements CustomRefactoringPanel {
private final transient SafeDeleteRefactoring refactoring;
private boolean regulardelete;
private ChangeListener parent;
/**
* Creates new form RenamePanelName
* @param refactoring The SafeDelete refactoring used by this panel
* @param selectedElements A Collection of selected elements
*/
public SafeDeletePanel(SafeDeleteRefactoring refactoring, boolean regulardelete, ChangeListener parent) {
setName(NbBundle.getMessage(SafeDeletePanel.class,
regulardelete ? "LBL_SafeDel_Delete" : "LBL_SafeDel")); // NOI18N
this.refactoring = refactoring;
this.regulardelete = regulardelete;
this.parent = parent;
initComponents();
}
private boolean initialized = false;
private String methodDeclaringClass = null;
String getMethodDeclaringClass() {
return methodDeclaringClass;
}
/**
* Initialization method. Creates appropriate labels in the panel.
*/
@Override
public void initialize() {
//This is needed since the checkBox is gets disabled on a
//repeated invocation of SafeDelete follwing removal of references
//to the element
searchInComments.setEnabled(true);
if (initialized) {
return;
}
final String labelText;
Lookup lkp = refactoring.getRefactoringSource();
NonRecursiveFolder folder = lkp.lookup(NonRecursiveFolder.class);
Collection<? extends FileObject> files = lkp.lookupAll(FileObject.class);
final Collection<? extends TreePathHandle> handles = lkp.lookupAll(TreePathHandle.class);
if (folder != null) {
String pkgName = folder.getFolder().getNameExt().replace('/', '.');
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDelPkg", pkgName);
}else if (files.size()>1 && files.size() == handles.size()) {
//delete multiple files
if (regulardelete) {
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_RegularDelete",handles.size());
} else {
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_Classes",handles.size());
}
} else if (handles.size()>1) {
Tree.Kind kind = null;
for (TreePathHandle handle : handles) {
if(kind == null || handle.getKind() == kind) {
kind = handle.getKind();
} else {
kind = null;
break;
}
}
if(kind == null) {
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_Elements",handles.size());
} else {
switch(kind) {
case CLASS:
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_Classes",handles.size());
break;
case METHOD:
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_Methods",handles.size());
break;
case VARIABLE:
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_Variables",handles.size());
break;
default:
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_Elements",handles.size());
break;
}
}
} else if (handles.size()==1) {
JavaSource s = JavaSource.forFileObject(handles.iterator().next().getFileObject());
final String[] name = new String[1];
try {
s.runUserActionTask(new CancellableTask<CompilationController>() {
@Override
public void cancel() {
}
@Override
public void run(CompilationController parameter) throws Exception {
parameter.toPhase(Phase.RESOLVED);
Element resolvedElement = handles.iterator().next().resolveElement(parameter);
if (resolvedElement == null) {
throw new NullPointerException(
"Please attach your {nb.userdir}/var/log/messages.log" + // NOI18N
" to http://www.netbeans.org/issues/show_bug.cgi?id=115462" + // NOI18N
"\nhandle: " + handles.iterator().next() + // NOI18N
"\nclasspath: " + parameter.getClasspathInfo()); // NOI18N
}
if (resolvedElement.getKind() == ElementKind.CONSTRUCTOR) {
name[0] = resolvedElement.getEnclosingElement().getSimpleName().toString();
} else {
name[0] = resolvedElement.getSimpleName().toString();
}
}
}, true);
} catch (IOException ioe) {
throw new RuntimeException(ioe);
}
if (regulardelete) {
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_RegularDeleteElement",name[0]);
} else {
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDel_Element",name[0]);
}
} else {
FileObject fileObject = files.iterator().next();
boolean isSingleFolderSelected = (files != null && files.size() == 1
&& fileObject.isFolder());
if (isSingleFolderSelected && !regulardelete) {
String folderName = fileObject.getName();
labelText = NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDelFolder", folderName);
}else{
labelText ="";
}
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (regulardelete) {
safeDelete = new JCheckBox();
Mnemonics.setLocalizedText(safeDelete, NbBundle.getMessage(SafeDeletePanel.class, "LBL_SafeDelCheckBox"));
safeDelete.getAccessibleContext().setAccessibleDescription(NbBundle.getMessage(
SafeDeletePanel.class,
"SafeDeletePanel.safeDelete.AccessibleContext.accessibleDescription"));
safeDelete.setMargin(new java.awt.Insets(2, 14, 2, 2));
searchInComments.setEnabled(false);
safeDelete.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent evt) {
searchInComments.setEnabled(safeDelete.isSelected());
parent.stateChanged(null);
}
});
checkBoxes.add(safeDelete, BorderLayout.CENTER);
}
label.setText(labelText);
validate();
}
});
initialized = true;
}
@Override
public boolean requestFocusInWindow() {
if(safeDelete != null) {
safeDelete.requestFocusInWindow();
} else {
searchInComments.requestFocusInWindow();
}
return true;
}
boolean isRegularDelete() {
if (safeDelete!=null) {
return !safeDelete.isSelected();
}
return false;
}
/** 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.
*/
// <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
private void initComponents() {
buttonGroup = new javax.swing.ButtonGroup();
checkBoxes = new javax.swing.JPanel();
label = new javax.swing.JLabel();
searchInComments = new javax.swing.JCheckBox();
setLayout(new java.awt.BorderLayout());
checkBoxes.setLayout(new java.awt.BorderLayout());
label.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 8, 0));
checkBoxes.add(label, java.awt.BorderLayout.NORTH);
searchInComments.setSelected(((Boolean) RefactoringModule.getOption("searchInComments.whereUsed", Boolean.FALSE)).booleanValue());
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/netbeans/modules/refactoring/java/ui/Bundle"); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(searchInComments, bundle.getString("LBL_SafeDelInComents")); // NOI18N
searchInComments.setMargin(new java.awt.Insets(2, 14, 2, 2));
searchInComments.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
searchInCommentsItemStateChanged(evt);
}
});
checkBoxes.add(searchInComments, java.awt.BorderLayout.SOUTH);
searchInComments.getAccessibleContext().setAccessibleDescription(searchInComments.getText());
add(checkBoxes, java.awt.BorderLayout.NORTH);
}// </editor-fold>//GEN-END:initComponents
private void searchInCommentsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_searchInCommentsItemStateChanged
// used for change default value for deleteInComments check-box.
// The value is persisted and then used as default in next IDE run.
Boolean b = evt.getStateChange() == ItemEvent.SELECTED ? Boolean.TRUE : Boolean.FALSE;
RefactoringModule.setOption("searchInComments.whereUsed", b); // NOI18N
refactoring.setCheckInComments(b.booleanValue());
}//GEN-LAST:event_searchInCommentsItemStateChanged
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.ButtonGroup buttonGroup;
private javax.swing.JPanel checkBoxes;
private javax.swing.JLabel label;
private javax.swing.JCheckBox searchInComments;
// End of variables declaration//GEN-END:variables
private javax.swing.JCheckBox safeDelete;
@Override
public Dimension getPreferredSize() {
Dimension orig = super.getPreferredSize();
return new Dimension(orig.width + 30 , orig.height + 30);
}
/**
* Indicates whether the element usage must be checked in comments
* before deleting each element.
* @return Returns the isSelected() attribute of the
* underlying check box that controls search in comments
*/
public boolean isSearchInComments() {
return searchInComments.isSelected();
}
@Override
public Component getComponent() {
return this;
}
}