IDEA-85574 Restart action, pressed while the application is running must show confirmation

This commit is contained in:
Vassiliy Kudryashov
2012-05-05 20:20:06 +04:00
parent 19d5580e34
commit 369a1aa420
4 changed files with 87 additions and 11 deletions
@@ -26,6 +26,7 @@ public class RunManagerConfig {
private final StoringPropertyContainer myProperties;
private final PropertiesComponent myPropertiesComponent;
@NonNls private static final String RECENTS_LIMIT = "recentsLimit";
@NonNls private static final String RESTART_REQUIRES_CONFIRMATION = "restartRequiresConfirmation";
public RunManagerConfig(PropertiesComponent propertiesComponent,
RunManagerImpl manager) {
@@ -45,4 +46,12 @@ public class RunManagerConfig {
public void setRecentsLimit(int recentsLimit) {
myPropertiesComponent.setValue(RECENTS_LIMIT, Integer.toString(recentsLimit));
}
public boolean isRestartRequiresConfirmation() {
return myPropertiesComponent.getBoolean(RESTART_REQUIRES_CONFIRMATION, true);
}
public void setRestartRequiresConfirmation (boolean restartRequiresConfirmation) {
myPropertiesComponent.setValue(RESTART_REQUIRES_CONFIRMATION, String.valueOf(restartRequiresConfirmation));
}
}
@@ -46,6 +46,7 @@ import com.intellij.util.containers.HashMap;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import gnu.trove.THashSet;
import net.miginfocom.swing.MigLayout;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -91,7 +92,8 @@ class RunConfigurable extends BaseConfigurable {
private final StorageAccessors myProperties = StorageAccessors.createGlobal("RunConfigurable");
private Configurable mySelectedConfigurable = null;
private static final Logger LOG = Logger.getInstance("#com.intellij.execution.impl.RunConfigurable");
private final JTextField myRecentsLimit = new JTextField("5");
private final JTextField myRecentsLimit = new JTextField("5", 2);
private final JCheckBox myConfirmation = new JCheckBox(ExecutionBundle.message("rerun.confirmation.checkbox"), true);
private Map<ConfigurationFactory, Configurable> myStoredComponents = new HashMap<ConfigurationFactory, Configurable>();
public RunConfigurable(final Project project) {
@@ -449,21 +451,23 @@ class RunConfigurable extends BaseConfigurable {
}
private JPanel createRecentLimitPanel() {
final JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
final JPanel bottomPanel = new JPanel(new MigLayout("ins 5, gap 5"));
// box.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
bottomPanel.add(new JLabel("<html>Temporary configurations limit:</html>"));
Dimension size = new Dimension(25, myRecentsLimit.getPreferredSize().height);
myRecentsLimit.setPreferredSize(size);
myRecentsLimit.setMaximumSize(size);
myRecentsLimit.setMinimumSize(size);
bottomPanel.add(myRecentsLimit);
bottomPanel.add(myRecentsLimit, "wrap, h pref!, w pref!");
bottomPanel.add(myConfirmation, "spanx 2");
myRecentsLimit.getDocument().addDocumentListener(new DocumentAdapter() {
@Override
protected void textChanged(DocumentEvent e) {
setModified(true);
}
});
myConfirmation.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
setModified(true);
}
});
return bottomPanel;
}
@@ -534,6 +538,7 @@ class RunConfigurable extends BaseConfigurable {
final RunManagerEx manager = getRunManager();
final RunManagerConfig config = manager.getConfig();
myRecentsLimit.setText(Integer.toString(config.getRecentsLimit()));
myConfirmation.setSelected(config.isRestartRequiresConfirmation());
setModified(false);
}
@@ -562,6 +567,7 @@ class RunConfigurable extends BaseConfigurable {
catch (NumberFormatException e) {
// ignore
}
manager.getConfig().setRestartRequiresConfirmation(myConfirmation.isSelected());
for (Configurable configurable : myStoredComponents.values()) {
if (configurable.isModified()){
@@ -15,7 +15,9 @@
*/
package com.intellij.execution.runners;
import com.intellij.CommonBundle;
import com.intellij.execution.*;
import com.intellij.execution.impl.RunManagerImpl;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.RunContentDescriptor;
import com.intellij.ide.DataManager;
@@ -23,8 +25,10 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.IconLoader;
import com.intellij.util.Alarm;
import javax.swing.*;
@@ -40,6 +44,7 @@ public class RestartAction extends AnAction implements DumbAware {
private final Executor myExecutor;
private final Icon myIcon;
private final ExecutionEnvironment myEnvironment;
private final Alarm awaitingTerminationAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
public RestartAction(final Executor executor,
final ProgramRunner runner,
@@ -60,8 +65,60 @@ public class RestartAction extends AnAction implements DumbAware {
public void actionPerformed(final AnActionEvent e) {
final DataContext dataContext = e.getDataContext();
final RunManagerConfig config = RunManagerImpl.getInstanceImpl(myEnvironment.getProject()).getConfig();
if (myProcessHandler != null && !myProcessHandler.isProcessTerminated() && config.isRestartRequiresConfirmation()) {
DialogWrapper.DoNotAskOption option = new DialogWrapper.DoNotAskOption() {
@Override
public boolean isToBeShown() {
return config.isRestartRequiresConfirmation();
}
@Override
public void setToBeShown(boolean value, int exitCode) {
config.setRestartRequiresConfirmation(value);
}
@Override
public boolean canBeHidden() {
return true;
}
@Override
public boolean shouldSaveOptionsOnCancel() {
return false;
}
@Override
public String getDoNotShowMessage() {
return CommonBundle.message("dialog.options.do.not.show");
}
};
if (Messages.OK != Messages.showOkCancelDialog(ExecutionBundle.message("rerun.confirmation.message", myEnvironment.getRunProfile().getName()),
ExecutionBundle.message("rerun.confirmation.title"), CommonBundle.message("button.ok"),
CommonBundle.message("button.cancel"),
Messages.getQuestionIcon(), option)) {
return;
}
}
ActionManager.getInstance().getAction(IdeActions.ACTION_STOP_PROGRAM).actionPerformed(e);
doRestart(dataContext);
update(e);
if (myProcessHandler != null) {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (myProcessHandler == null || myProcessHandler.isProcessTerminated()) {
doRestart(dataContext);
}
else {
awaitingTerminationAlarm.addRequest(this, 100);
}
}
};
awaitingTerminationAlarm.addRequest(runnable, 100);
}
else {
doRestart(dataContext);
}
}
public void restart() {
@@ -93,8 +150,9 @@ public class RestartAction extends AnAction implements DumbAware {
myProcessHandler = null; // already terminated
}
presentation.setIcon(isRunning ? STOP_AND_START_ICON : myIcon);
presentation.setEnabled(!ExecutorRegistry.getInstance().isStarting(myEnvironment.getProject(), myExecutor.getId(), myRunner.getRunnerId()));
boolean isTerminating = myProcessHandler != null && myProcessHandler.isProcessTerminating();
boolean isStarting = ExecutorRegistry.getInstance().isStarting(myEnvironment.getProject(), myExecutor.getId(), myRunner.getRunnerId());
presentation.setEnabled(!isStarting && !isTerminating);
}
public void registerShortcut(final JComponent component) {
@@ -159,6 +159,9 @@ terminating.process.progress.title=Terminating ''{0}''
waiting.for.vm.detach.progress.text=Waiting for process detach
restart.error.message.title=Restart Error
rerun.configuration.action.name=Rerun {0}
rerun.confirmation.message=Are you sure you want to stop ''{0}''
rerun.confirmation.title=Stop Confirmation
rerun.confirmation.checkbox=Confirm rerun with process termination
run.configuration.dump.threads.action.name=Dump Threads
run.configuration.exit.action.name=Exit
run.error.message.title=Run Error