From f2a05352d8681e978754d9a97fe189f7d55a2f10 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 14 Apr 2010 16:00:50 +0400 Subject: [PATCH 1/7] Update on exit option --- .../com/intellij/idea/IdeaApplication.java | 46 ++++++++++++------- .../impl/AbstractUpdateDialog.java | 13 +++++- .../impl/CheckForUpdateAction.java | 4 +- .../updateSettings/impl/NoUpdatesDialog.java | 7 ++- .../updateSettings/impl/UpdateChecker.java | 12 +++-- .../updateSettings/impl/UpdateSettings.java | 6 ++- .../impl/UpdateSettingsConfigurable.java | 5 +- .../src/messages/IdeBundle.properties | 1 + 8 files changed, 64 insertions(+), 30 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java index 88686b89ac7f..c22f0d9dbac3 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java +++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPoint; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; -import com.intellij.openapi.updateSettings.impl.PluginDownloader; -import com.intellij.openapi.updateSettings.impl.UpdateChannel; -import com.intellij.openapi.updateSettings.impl.UpdateChecker; +import com.intellij.openapi.updateSettings.impl.*; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.SystemInfo; @@ -196,22 +194,21 @@ public class IdeaApplication { } }, ModalityState.NON_MODAL); + app.addApplicationListener(new ApplicationAdapter() { + @Override + public boolean canExitApplication() { + if (UpdateSettings.getInstance().isUpdateOnExit()) { + updatePlugins(false); + } + return true; + } + }); + app.invokeLater(new Runnable() { public void run() { if (UpdateChecker.isMyVeryFirstOpening() && UpdateChecker.checkNeeded()) { - try { - UpdateChecker.setMyVeryFirstOpening(false); - final UpdateChannel newVersion = UpdateChecker.checkForUpdates(); - final List updatedPlugins = UpdateChecker.updatePlugins(false); - if (newVersion != null) { - UpdateChecker.showUpdateInfoDialog(true, newVersion, updatedPlugins); - } else if (updatedPlugins != null) { - UpdateChecker.showNoUpdatesDialog(true, updatedPlugins); - } - } - catch (ConnectionException e) { - // It's not a problem on automatic check - } + UpdateChecker.setMyVeryFirstOpening(false); + updatePlugins(true); } if (myPerformProjectLoad) { @@ -226,6 +223,21 @@ public class IdeaApplication { } }, ModalityState.NON_MODAL); } + + private void updatePlugins(boolean showConfirmation) { + try { + final UpdateChannel newVersion = UpdateChecker.checkForUpdates(); + final List updatedPlugins = UpdateChecker.updatePlugins(false); + if (newVersion != null) { + UpdateChecker.showUpdateInfoDialog(true, newVersion, updatedPlugins); + } else if (updatedPlugins != null) { + UpdateChecker.showNoUpdatesDialog(true, updatedPlugins, showConfirmation); + } + } + catch (ConnectionException e) { + // It's not a problem on automatic check + } + } } private void loadProject() { diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java index 00212be88d89..25364e867361 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ import java.util.List; public abstract class AbstractUpdateDialog extends DialogWrapper { private final boolean myEnableLink; protected final List myUploadedPlugins; + protected boolean myShowConfirmation = true; protected AbstractUpdateDialog(boolean canBeParent, boolean enableLink, final List updatePlugins) { super(canBeParent); @@ -95,7 +96,7 @@ public abstract class AbstractUpdateDialog extends DialogWrapper { } protected void doOKAction() { - if (doDownloadAndPrepare()) { + if (doDownloadAndPrepare() && isShowConfirmation()) { final ApplicationEx app = ApplicationManagerEx.getApplicationEx(); if (app.isRestartCapable()) { app.restart(); @@ -121,4 +122,12 @@ public abstract class AbstractUpdateDialog extends DialogWrapper { if (myUploadedPlugins != null) UpdateChecker.install(myUploadedPlugins); //update on restart super.doCancelAction(); } + + public void setShowConfirmation(boolean showConfirmation) { + myShowConfirmation = showConfirmation; + } + + public boolean isShowConfirmation() { + return myShowConfirmation; + } } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java index 7ce314b11cdd..0d131f1ef3ed 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/CheckForUpdateAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,7 +44,7 @@ public class CheckForUpdateAction extends AnAction implements DumbAware { UpdateChecker.showUpdateInfoDialog(enableLink, newVersion, updatedPlugins); } else { - UpdateChecker.showNoUpdatesDialog(enableLink, updatedPlugins); + UpdateChecker.showNoUpdatesDialog(enableLink, updatedPlugins, true); } } catch (ConnectionException e) { diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java index b7ba16704a85..85a714e5a375 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/NoUpdatesDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,7 +27,6 @@ import java.util.List; * @author pti */ class NoUpdatesDialog extends AbstractUpdateDialog { - protected NoUpdatesDialog(final boolean canBeParent, final List updatePlugins, boolean enableLink) { super(canBeParent, enableLink, updatePlugins); setTitle(IdeBundle.message("updates.info.dialog.title")); @@ -54,14 +53,14 @@ class NoUpdatesDialog extends AbstractUpdateDialog { @Override protected boolean doDownloadAndPrepare() { boolean hasSmthToUpdate = super.doDownloadAndPrepare(); - if (hasSmthToUpdate && + if (hasSmthToUpdate && isShowConfirmation() && Messages.showYesNoDialog(IdeBundle.message("message.idea.restart.required", ApplicationNamesInfo.getInstance().getProductName()), IdeBundle.message("title.plugins"), Messages.getQuestionIcon()) != 0) { hasSmthToUpdate = false; } return hasSmthToUpdate; } - + private class NoUpdatesPanel { private JPanel myPanel; private JPanel myPluginsPanel; diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index e3f39d7b317b..048b9a60a07c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,6 +83,9 @@ public final class UpdateChecker { public static String ADDITIONAL_REQUEST_OPTIONS = ""; + private UpdateChecker() { + } + public static enum DownloadPatchResult { SUCCESS, FAILED, CANCELED } @@ -117,11 +120,13 @@ public final class UpdateChecker { } public static boolean checkNeeded() { - final UpdateSettings settings = UpdateSettings.getInstance(); if (settings == null || getUpdateUrl() == null) return false; final String checkPeriod = settings.CHECK_PERIOD; + if (checkPeriod.equals(UpdateSettingsConfigurable.ON_EXIT)) { + return false; + } if (checkPeriod.equals(UpdateSettingsConfigurable.ON_START_UP)) { checkInterval = 0; } @@ -375,8 +380,9 @@ public final class UpdateChecker { return document[0]; } - public static void showNoUpdatesDialog(boolean enableLink, final List updatePlugins) { + public static void showNoUpdatesDialog(boolean enableLink, final List updatePlugins, boolean showConfirmation) { NoUpdatesDialog dialog = new NoUpdatesDialog(true, updatePlugins, enableLink); + dialog.setShowConfirmation(showConfirmation); dialog.show(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java index 06d96d2d9f3b..df6fd65e158a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -73,4 +73,8 @@ public class UpdateSettings implements PersistentStateComponent { LOG.info(e); } } + + public boolean isUpdateOnExit() { + return UpdateSettingsConfigurable.ON_EXIT.equals(CHECK_PERIOD); + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java index e6aaf219f12d..876b9c19f9ff 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateSettingsConfigurable.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2010 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -52,6 +52,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear @NonNls public static final String DAILY = "Daily"; @NonNls public static final String WEEKLY = "Weekly"; @NonNls public static final String MONTHLY = "Monthly"; + @NonNls public static final String ON_EXIT = "On every exit"; private static final Map PERIOD_VALUE_MAP = new HashMap(); static { @@ -59,6 +60,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear PERIOD_VALUE_MAP.put(DAILY, IdeBundle.message("updates.check.period.daily")); PERIOD_VALUE_MAP.put(WEEKLY, IdeBundle.message("updates.check.period.weekly")); PERIOD_VALUE_MAP.put(MONTHLY, IdeBundle.message("updates.check.period.monthly")); + PERIOD_VALUE_MAP.put(ON_EXIT, IdeBundle.message("updates.check.period.on.exit")); } public JComponent createComponent() { @@ -150,6 +152,7 @@ public class UpdateSettingsConfigurable extends BaseConfigurable implements Sear myPeriodCombo.addItem(DAILY); myPeriodCombo.addItem(WEEKLY); myPeriodCombo.addItem(MONTHLY); + myPeriodCombo.addItem(ON_EXIT); myPeriodCombo.setRenderer(new MappingListCellRenderer(PERIOD_VALUE_MAP)); diff --git a/platform/platform-resources-en/src/messages/IdeBundle.properties b/platform/platform-resources-en/src/messages/IdeBundle.properties index 893fe5e91a2f..0a8e3f8fade9 100644 --- a/platform/platform-resources-en/src/messages/IdeBundle.properties +++ b/platform/platform-resources-en/src/messages/IdeBundle.properties @@ -1059,4 +1059,5 @@ FileChooser.listViewActionLabelText=List FileChooser.detailsViewActionLabelText=Details FileChooser.refreshActionLabelText=Refresh browsers.settings=Web Browsers +updates.check.period.on.exit=On every exit From 7c8652e299503ac9182ca983e6ff8aca43130d12 Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Wed, 14 Apr 2010 15:59:56 +0400 Subject: [PATCH 2/7] maven: refactorings (IDEA-53947, IDEA-53954, etc. ) --- .../dom/MavenDomProjectProcessorUtils.java | 23 +++++++++++-------- .../annotator/MavenDomGutterAnnotator.java | 9 +------- .../introduce/IntroducePropertyAction.java | 11 +++++---- .../introduce/IntroducePropertyDialog.java | 3 +-- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java index c0dff80e1804..402041792a47 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenDomProjectProcessorUtils.java @@ -37,21 +37,26 @@ public class MavenDomProjectProcessorUtils { } @NotNull - public static List collectChildrenProjects(@NotNull final MavenDomProjectModel model) { + public static Set getChildrenProjects(@NotNull final MavenDomProjectModel model) { + Set models = new HashSet(); + collectChildrenProjects(model, models); + + return models; + } + + private static void collectChildrenProjects(@NotNull final MavenDomProjectModel model, @NotNull Set models) { MavenProject mavenProject = MavenDomUtil.findProject(model); if (mavenProject != null) { final Project project = model.getManager().getProject(); - Set inheritors = MavenProjectsManager.getInstance(project).findInheritors(mavenProject); - - - return ContainerUtil.mapNotNull(inheritors, new Function() { - public MavenDomProjectModel fun(MavenProject childProject) { - return MavenDomUtil.getMavenDomProjectModel(project, childProject.getFile()); + for (MavenProject inheritor : MavenProjectsManager.getInstance(project).findInheritors(mavenProject)) { + MavenDomProjectModel inheritorProjectModel = MavenDomUtil.getMavenDomProjectModel(project, inheritor.getFile()); + if (inheritorProjectModel != null && !models.contains(inheritorProjectModel)) { + models.add(inheritorProjectModel); + collectChildrenProjects(inheritorProjectModel, models); } - }); + } } - return Collections.emptyList(); } @NotNull public static Set collectParentProjects(@NotNull final MavenDomProjectModel projectDom, diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java index 0ffde5494d59..2c9d5bb47319 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/annotator/MavenDomGutterAnnotator.java @@ -183,15 +183,8 @@ public class MavenDomGutterAnnotator implements Annotator { private static void annotateMavenDomProjectChildren(MavenDomProjectModel model, AnnotationHolder holder) { MavenProject mavenProject = MavenDomUtil.findProject(model); if (mavenProject != null) { - final Project project = model.getManager().getProject(); - Set inheritors = MavenProjectsManager.getInstance(project).findInheritors(mavenProject); + Set children = MavenDomProjectProcessorUtils.getChildrenProjects(model); - - List children = ContainerUtil.mapNotNull(inheritors, new Function() { - public MavenDomProjectModel fun(MavenProject childProject) { - return MavenDomUtil.getMavenDomProjectModel(project, childProject.getFile()); - } - }); if (children.size() > 0) { NavigationGutterIconBuilder.create(MavenIcons.CHILDREN_PROJECTS, MAVEN_PROJECT_CONVERTER). setTargets(children). diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java index db21b39bc8cd..c4acd1de60ca 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyAction.java @@ -205,16 +205,16 @@ public class IntroducePropertyAction extends BaseRefactoringAction { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { collectUsages(myModel); - for (MavenDomProjectModel model : MavenDomProjectProcessorUtils.collectChildrenProjects(myModel)) { + for (MavenDomProjectModel model : MavenDomProjectProcessorUtils.getChildrenProjects(myModel)) { collectUsages(model); } } private void collectUsages(@NotNull MavenDomProjectModel model) { if (model.isValid()) { - XmlElement root = model.getXmlElement(); + final XmlElement root = model.getXmlElement(); if (root != null) { - root.accept(new XmlElementVisitor() { + root.acceptChildren(new XmlElementVisitor() { @Override public void visitXmlText(XmlText text) { @@ -226,7 +226,10 @@ public class IntroducePropertyAction extends BaseRefactoringAction { @Override public void visitXmlAttributeValue(XmlAttributeValue value) { - usages.addAll(getUsages(value)); + XmlTag xmlTag = PsiTreeUtil.getParentOfType(value, XmlTag.class); + if (xmlTag != null && !xmlTag.equals(root)) { + usages.addAll(getUsages(value)); + } } @Override diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java index d4e25f376c30..2d99b166965c 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java @@ -26,7 +26,6 @@ import com.intellij.refactoring.introduceVariable.IntroduceVariableHandler; import com.intellij.refactoring.ui.NameSuggestionsField; import com.intellij.util.Function; import com.intellij.util.containers.OrderedSet; -import com.intellij.util.xml.DomBundle; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.maven.dom.MavenDomBundle; import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils; @@ -212,7 +211,7 @@ public class IntroducePropertyDialog extends DialogWrapper { if (isPropertyExist(text, project)) return true; - for (MavenDomProjectModel child : MavenDomProjectProcessorUtils.collectChildrenProjects(project)) { + for (MavenDomProjectModel child : MavenDomProjectProcessorUtils.getChildrenProjects(project)) { if (isPropertyExist(text, child)) return true; } From 26d59a079c6e4a49a03ac24facec4e1b3d238f5c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 14 Apr 2010 16:03:13 +0400 Subject: [PATCH 3/7] [r: anna] Remove doCancelAction, it installs plugins --- .../openapi/updateSettings/impl/AbstractUpdateDialog.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java index 25364e867361..0b47eda982ac 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/AbstractUpdateDialog.java @@ -117,12 +117,6 @@ public abstract class AbstractUpdateDialog extends DialogWrapper { return false; } - public void doCancelAction() { - UpdateChecker.saveDisabledToUpdatePlugins(); - if (myUploadedPlugins != null) UpdateChecker.install(myUploadedPlugins); //update on restart - super.doCancelAction(); - } - public void setShowConfirmation(boolean showConfirmation) { myShowConfirmation = showConfirmation; } From 3a7c4466e52ce3fb86a1a1ef5c909bf4704b343f Mon Sep 17 00:00:00 2001 From: "sergey.vasiliev" Date: Wed, 14 Apr 2010 16:15:01 +0400 Subject: [PATCH 4/7] maven: refactorings IDEA-53956) --- .../refactorings/introduce/IntroducePropertyDialog.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java index 2d99b166965c..7d09fe904eff 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/refactorings/introduce/IntroducePropertyDialog.java @@ -196,14 +196,7 @@ public class IntroducePropertyDialog extends DialogWrapper { } private static boolean isContainWrongSymbols(@NotNull String text) { - return text.length() == 0 || - text.contains("\"") || - text.contains("'") || - text.contains(">") || - text.contains("<") || - text.contains("/") || - text.contains("\\") || - Character.isDigit(text.charAt(0)); + return text.length() == 0 || StringUtil.containsAnyChar(text, "\t ;*'\"\\/,()^&<>={}[]") ; } private boolean isPropertyExist(@NotNull String text) { From 80d958bd5ede298405a64069d65786a619732291 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Wed, 14 Apr 2010 16:21:01 +0400 Subject: [PATCH 5/7] Get rid of copy-paste round 1 --- .../intellij/execution/ExecutionHelper.java | 323 ++++++++++++++++++ .../com/intellij/execution/ExecutionMode.java | 97 ++++++ .../src/com/intellij/execution/Output.java | 41 +++ .../intellij/execution/OutputListener.java | 29 ++ .../AbstractConsoleRunnerWithHistory.java | 320 +++++++++++++++++ 5 files changed, 810 insertions(+) create mode 100644 platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java create mode 100644 platform/lang-impl/src/com/intellij/execution/ExecutionMode.java create mode 100644 platform/lang-impl/src/com/intellij/execution/Output.java create mode 100644 platform/lang-impl/src/com/intellij/execution/OutputListener.java create mode 100644 platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java new file mode 100644 index 000000000000..142bbfc399b2 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionHelper.java @@ -0,0 +1,323 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed 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 com.intellij.execution; + +import com.intellij.execution.process.OSProcessHandler; +import com.intellij.execution.process.ProcessHandler; +import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.components.ServiceManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.wm.ToolWindowId; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentFactory; +import com.intellij.ui.content.MessageView; +import com.intellij.util.Function; +import com.intellij.util.NotNullFunction; +import com.intellij.util.concurrency.Semaphore; +import com.intellij.util.ui.ErrorTreeView; +import com.intellij.util.ui.MessageCategory; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +/** + * Created by IntelliJ IDEA. + * + * @author: Roman Chernyatchik + * @date: Oct 4, 2007 + */ +public class ExecutionHelper { + private static final Logger LOG = Logger.getInstance(ExecutionHelper.class.getName()); + + private ExecutionHelper() { + } + + public static void showErrors(@NotNull final Project myProject, + @NotNull final List exceptionList, + @NotNull final String tabDisplayName, + @Nullable final VirtualFile file) { + if (ApplicationManager.getApplication().isUnitTestMode() && !exceptionList.isEmpty()) { + throw new RuntimeException(exceptionList.get(0)); + } + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + if (myProject.isDisposed()) return; + if (exceptionList.isEmpty()) { + removeContents(null, myProject, tabDisplayName); + return; + } + + final RailsErrorViewPanel errorTreeView = new RailsErrorViewPanel(myProject); + try { + openMessagesView(errorTreeView, myProject, tabDisplayName); + } + catch (NullPointerException e) { + final StringBuilder builder = new StringBuilder(); + builder.append("Exceptions occured:"); + for (final Exception exception : exceptionList) { + builder.append("\n"); + builder.append(exception.getMessage()); + } + Messages.showErrorDialog(builder.toString(), "Execution Error"); + return; + } + for (final Exception exception : exceptionList) { + String[] messages = new String[]{exception.getMessage()}; + if (messages.length == 0) messages = new String[]{"Unknown Error"}; + errorTreeView.addMessage(MessageCategory.ERROR, messages, file, -1, -1, null); + } + + ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW).activate(null); + } + }); + } + + private static void openMessagesView(@NotNull final RailsErrorViewPanel errorTreeView, + @NotNull final Project myProject, + @NotNull final String tabDisplayName) { + CommandProcessor commandProcessor = CommandProcessor.getInstance(); + commandProcessor.executeCommand(myProject, new Runnable() { + public void run() { + final MessageView messageView = ServiceManager.getService(myProject, MessageView.class); + final Content content = ContentFactory.SERVICE.getInstance().createContent(errorTreeView, tabDisplayName, true); + messageView.getContentManager().addContent(content); + Disposer.register(content, errorTreeView); + messageView.getContentManager().setSelectedContent(content); + removeContents(content, myProject, tabDisplayName); + } + }, "Open message view", null); + } + + private static void removeContents(@Nullable final Content notToRemove, + @NotNull final Project myProject, + @NotNull final String tabDisplayName) { + MessageView messageView = ServiceManager.getService(myProject, MessageView.class); + Content[] contents = messageView.getContentManager().getContents(); + for (Content content : contents) { + LOG.assertTrue(content != null); + if (content.isPinned()) continue; + if (tabDisplayName.equals(content.getDisplayName()) && content != notToRemove) { + ErrorTreeView listErrorView = (ErrorTreeView)content.getComponent(); + if (listErrorView != null) { + if (messageView.getContentManager().removeContent(content, true)) { + content.release(); + } + } + } + } + } + + @Nullable + public static ProcessHandler findRunningConsole(final Project project, + @NotNull final NotNullFunction cmdLineMatcher) { + final ProcessHandler[] processes = ExecutionManager.getInstance(project).getRunningProcesses(); + for (ProcessHandler process : processes) { + if (process instanceof OSProcessHandler && !process.isProcessTerminated()) { + final String commandLine = ((OSProcessHandler)process).getCommandLine(); + if (cmdLineMatcher.fun(commandLine).booleanValue()) { + return process; + } + } + } + return null; + } + + public static class RailsErrorViewPanel extends NewErrorTreeViewPanel { + public RailsErrorViewPanel(final Project project) { + super(project, null); + } + + protected boolean canHideWarnings() { + return false; + } + } + + + public static void executeExternalProcess(@Nullable final Project myProject, + @NotNull final OSProcessHandler processHandler, + @NotNull final ExecutionMode mode) { + final String title = mode.getTitle() != null ? mode.getTitle() : "Running. Please wait..."; + assert title != null; + + final Runnable process; + if (mode.cancelable()) { + process = createCancelableExecutionProcess(processHandler, mode.shouldCancelFun()); + } + else { + if (mode.getTimeout() <= 0) { + process = new Runnable() { + public void run() { + processHandler.waitFor(); + } + }; + } else { + process = createTimelimitedExecutionProcess(processHandler, mode.getTimeout()); + } + } + if (mode.withModalProgress()) { + ProgressManager.getInstance().runProcessWithProgressSynchronously(process, title, mode.cancelable(), myProject, + mode.getProgressParentComponent()); + } + else if (mode.inBackGround()) { + final Task task = new Task.Backgroundable(myProject, title, mode.cancelable()) { + public void run(@NotNull final ProgressIndicator indicator) { + process.run(); + } + }; + ProgressManager.getInstance().run(task); + } + else { + final String title2 = mode.getTitle2(); + final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); + if (indicator != null && title2 != null) { + indicator.setText2(title2); + } + process.run(); + } + } + + private static Runnable createCancelableExecutionProcess(final ProcessHandler processHandler, + final Function cancelableFun) { + return new Runnable() { + private ProgressIndicator myProgressIndicator; + private final Semaphore mySemaphore = new Semaphore(); + + private final Runnable myWaitThread = new Runnable() { + public void run() { + try { + processHandler.waitFor(); + } + finally { + mySemaphore.up(); + } + } + }; + + private final Runnable myCancelListener = new Runnable() { + public void run() { + for (; ;) { + if ((myProgressIndicator != null && (myProgressIndicator.isCanceled() + || !myProgressIndicator.isRunning())) + || (cancelableFun != null && cancelableFun.fun(null).booleanValue()) + || processHandler.isProcessTerminated()) { + + if (!processHandler.isProcessTerminated()) { + try { + processHandler.destroyProcess(); + } + finally { + mySemaphore.up(); + } + } + break; + } + try { + synchronized (this) { + wait(1000); + } + } + catch (InterruptedException e) { + //Do nothing + } + } + } + }; + + public void run() { + myProgressIndicator = ProgressManager.getInstance().getProgressIndicator(); + if (myProgressIndicator != null && StringUtil.isEmpty(myProgressIndicator.getText())) { + myProgressIndicator.setText("Please wait"); + } + + LOG.assertTrue(myProgressIndicator != null || cancelableFun != null, + "Cancelable process must have an opportunity to be canceled!"); + mySemaphore.down(); + ApplicationManager.getApplication().executeOnPooledThread(myWaitThread); + ApplicationManager.getApplication().executeOnPooledThread(myCancelListener); + + mySemaphore.waitFor(); + } + }; + } + + private static Runnable createTimelimitedExecutionProcess(final OSProcessHandler processHandler, + final int timeout) { + return new Runnable() { + private final Semaphore mySemaphore = new Semaphore(); + private final Object LOCK = new Object(); + private Boolean processedFinished = Boolean.FALSE; + + private final Runnable myProcessThread = new Runnable() { + public void run() { + try { + processHandler.waitFor(); + synchronized (LOCK) { + processedFinished = Boolean.TRUE; + } + } + finally { + mySemaphore.up(); + } + } + }; + + private final Runnable myTimeoutListener = new Runnable() { + public void run() { + try { + synchronized (this) { + try { + wait(1000 * timeout); + synchronized (LOCK) { + if (!processedFinished) { + LOG.error("Timeout (" + timeout + " sec) on executing: " + processHandler.getCommandLine()); + processHandler.destroyProcess(); + } + } + } + finally { + mySemaphore.up(); + } + } + } + catch (InterruptedException e) { + //Do nothing + } + } + }; + + public void run() { + mySemaphore.down(); + ApplicationManager.getApplication().executeOnPooledThread(myProcessThread); + ApplicationManager.getApplication().executeOnPooledThread(myTimeoutListener); + + mySemaphore.waitFor(); + } + }; + } +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionMode.java b/platform/lang-impl/src/com/intellij/execution/ExecutionMode.java new file mode 100644 index 000000000000..81e8677fcac8 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionMode.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed 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 com.intellij.execution; + +import com.intellij.util.Function; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** +* @author Roman.Chernyatchik +*/ +public abstract class ExecutionMode { + private final boolean myCancelable; + private final String myTitle; + private final String myTitle2; + private final boolean myRunWithModal; + private final boolean myRunInBG; + private final JComponent myProgressParentComponent; + private Function myShouldCancelFun; + private final Object CANCEL_FUN_LOCK = new Object(); + + public ExecutionMode(final boolean cancelable, + @Nullable final String title, + @Nullable final String title2, + final boolean runInBG, + final boolean runWithModal, + JComponent progressParentComponent) { + myCancelable = cancelable; + myTitle = title; + myTitle2 = title2; + myRunInBG = runInBG; + myRunWithModal = runWithModal; + myProgressParentComponent = progressParentComponent; + } + + public int getTimeout() { + // it is ignored + return -1; + } + + @Nullable + public String getTitle() { + return myTitle; + } + + @Nullable + public String getTitle2() { + return myTitle2; + } + + public boolean cancelable() { + return myCancelable; + } + + public boolean inBackGround() { + return myRunInBG; + } + + public boolean withModalProgress() { + return myRunWithModal; + } + + public JComponent getProgressParentComponent() { + return myProgressParentComponent; + } + + /** + * Runner checks this fun during process running, if returns true, process will be canceled. + */ + @Nullable + public Function shouldCancelFun() { + synchronized (CANCEL_FUN_LOCK) { + return myShouldCancelFun; + } + } + + public void setShouldCancelFun(final Function shouldCancelFun) { + synchronized (CANCEL_FUN_LOCK) { + myShouldCancelFun = shouldCancelFun; + } + } + +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/execution/Output.java b/platform/lang-impl/src/com/intellij/execution/Output.java new file mode 100644 index 000000000000..267046ce7464 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/Output.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2008 JetBrains s.r.o. + * + * Licensed 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 com.intellij.execution; + +/** + * Created by IntelliJ IDEA. + * + * @author: oleg + * @date: 24.08.2006 + */ +public class Output { + private final String stdout; + private final String stderr; + + public Output(String stdout, String stderr) { + this.stdout = stdout; + this.stderr = stderr; + } + + public String getStdout() { + return stdout; + } + + public String getStderr() { + return stderr; + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/OutputListener.java b/platform/lang-impl/src/com/intellij/execution/OutputListener.java new file mode 100644 index 000000000000..cba904e34f8e --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/OutputListener.java @@ -0,0 +1,29 @@ +package com.intellij.execution; + +import com.intellij.execution.process.ProcessAdapter; +import com.intellij.execution.process.ProcessEvent; +import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.openapi.util.Key; +import org.jetbrains.annotations.NotNull; + +/** +* @author oleg +*/ +public class OutputListener extends ProcessAdapter { + private final StringBuilder out; + private final StringBuilder err; + + public OutputListener(@NotNull final StringBuilder out, @NotNull final StringBuilder err) { + this.out = out; + this.err = err; + } + + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (outputType == ProcessOutputTypes.STDOUT) { + out.append(event.getText()); + } + if (outputType == ProcessOutputTypes.STDERR) { + err.append(event.getText()); + } + } +} diff --git a/platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java new file mode 100644 index 000000000000..f1ad4371a82f --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java @@ -0,0 +1,320 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed 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 com.intellij.execution.console; + +import com.intellij.codeInsight.lookup.Lookup; +import com.intellij.codeInsight.lookup.LookupManager; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionManager; +import com.intellij.execution.Executor; +import com.intellij.execution.ExecutorRegistry; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.process.*; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.execution.ui.actions.CloseAction; +import com.intellij.ide.CommonActionsManager; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleManager; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.project.DumbAwareAction; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.encoding.EncodingManager; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.openapi.wm.ToolWindow; +import com.intellij.openapi.wm.ToolWindowManager; +import com.intellij.psi.PsiFile; +import com.intellij.util.PairProcessor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.*; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.Arrays; + +/** + * @author oleg + */ +public class AbstractConsoleRunnerWithHistory { +/* protected final Project myProject; + protected final String myConsoleTitle; + + private OSProcessHandler myProcessHandler; + protected final CommandLineArgumentsProvider myProvider; + protected final String myWorkingDir; + + protected LanguageConsoleViewImpl myConsoleView; + private final ConsoleHistoryModel myHistory = new ConsoleHistoryModel(); + private AnAction myRunAction; + + public AbstractConsoleRunnerWithHistory(@NotNull final Project project, + @NotNull final String consoleTitle, + @NotNull final CommandLineArgumentsProvider provider, + @Nullable final String workingDir) { + myProject = project; + myConsoleTitle = consoleTitle; + myProvider = provider; + myWorkingDir = workingDir; + } + + public static void run(@NotNull final Project project, + @NotNull final String consoleTitle, + @NotNull final CommandLineArgumentsProvider provider, + @Nullable final String workingDir) { + + final AbstractConsoleRunnerWithHistory consoleRunner = new AbstractConsoleRunnerWithHistory(project, consoleTitle, provider, workingDir); + try { + consoleRunner.initAndRun(); + } + catch (ExecutionException e) { + ExecutionHelper.showErrors(project, Arrays.asList(e), consoleTitle, null); + } + } + + public void initAndRun() throws ExecutionException { + // Create Server process + final Process process = createProcess(); + + // Init console view + myConsoleView = createConsoleView(); + + myProcessHandler = createProcessHandler(process); + + ProcessTerminatedListener.attach(myProcessHandler); + + // Set language level + for (Module module : ModuleManager.getInstance(myProject).getModules()) { + final Sdk pythonSdk = PythonSdkType.findPythonSdk(module); + if (pythonSdk != null){ + final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(pythonSdk); + final PsiFile psiFile = getLanguageConsole().getFile(); + // Set module explicitly + psiFile.putUserData(ModuleUtil.KEY_MODULE, module); + final VirtualFile vFile = psiFile.getVirtualFile(); + if (vFile != null) { + // Set language level + vFile.putUserData(LanguageLevel.KEY, languageLevel); + } + break; + } + } + + myProcessHandler.addProcessListener(new ProcessAdapter() { + @Override + public void processTerminated(ProcessEvent event) { + myRunAction.getTemplatePresentation().setEnabled(false); + myConsoleView.getConsole().setPrompt(""); + myConsoleView.getConsole().getConsoleEditor().setRendererMode(true); + ApplicationManager.getApplication().invokeLater(new Runnable() { + public void run() { + myConsoleView.getConsole().getConsoleEditor().getComponent().updateUI(); + } + }); + } + }); + +// Setup default prompt + myConsoleView.getConsole().setPrompt(PyConsoleHighlightingUtil.ORDINARY_PROMPT.trim()); + +// Attach to process + myConsoleView.attachToProcess(myProcessHandler); + +// Add filter TODO[oleg]: Add stacktrace filters +// myConsoleView.addMessageFilter(new OutputConsoleFilter()); + +// Runner creating + final Executor defaultExecutor = ExecutorRegistry.getInstance().getExecutorById(DefaultRunExecutor.EXECUTOR_ID); + final DefaultActionGroup toolbarActions = new DefaultActionGroup(); + final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false); + +// Runner creating + final JPanel panel = new JPanel(new BorderLayout()); + panel.add(actionToolbar.getComponent(), BorderLayout.WEST); + panel.add(myConsoleView.getComponent(), BorderLayout.CENTER); + + final RunContentDescriptor myDescriptor = + new RunContentDescriptor(myConsoleView, myProcessHandler, panel, myConsoleTitle); + +// tool bar actions + final AnAction[] actions = fillToolBarActions(toolbarActions, defaultExecutor, myDescriptor); + registerActionShortcuts(actions, getLanguageConsole().getConsoleEditor().getComponent()); + registerActionShortcuts(actions, panel); + panel.updateUI(); + +// Show in run toolwindow + ExecutionManager.getInstance(myProject).getContentManager().showRunContent(defaultExecutor, myDescriptor); + +// Request focus + final ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(defaultExecutor.getId()); + window.activate(new Runnable() { + public void run() { + IdeFocusManager.getInstance(myProject).requestFocus(getLanguageConsole().getCurrentEditor().getContentComponent(), true); + } + }); +// Run + myProcessHandler.startNotify(); + } + + protected LanguageConsoleViewImpl createConsoleView() { + return new PyLanguageConsoleView(myProject, myConsoleTitle); + } + + + @Nullable + protected Process createProcess() throws ExecutionException { + return Runner.createProcess(myWorkingDir, true, myProvider.getAdditionalEnvs(), myProvider.getArguments()); + } + + private PyConsoleProcessHandler createProcessHandler(final Process process) { + final Charset outputEncoding = EncodingManager.getInstance().getDefaultCharset(); + return new PyConsoleProcessHandler(process, myConsoleView.getConsole(), getProviderCommandLine(myProvider), outputEncoding); + } + + private void registerActionShortcuts(final AnAction[] actions, final JComponent component) { + for (AnAction action : actions) { + if (action.getShortcutSet() != null) { + action.registerCustomShortcutSet(action.getShortcutSet(), component); + } + } + } + + private AnAction[] fillToolBarActions(final DefaultActionGroup toolbarActions, + final Executor defaultExecutor, + final RunContentDescriptor myDescriptor) { +//stop + final AnAction stopAction = createStopAction(); + toolbarActions.add(stopAction); + +//close + final AnAction closeAction = createCloseAction(defaultExecutor, myDescriptor); + toolbarActions.add(closeAction); + +// run action + myRunAction = new DumbAwareAction(null, null, IconLoader.getIcon("/actions/execute.png")) { + public void actionPerformed(final AnActionEvent e) { + runExecuteActionInner(true); + } + + public void update(final AnActionEvent e) { + final EditorEx editor = getLanguageConsole().getConsoleEditor(); + final Lookup lookup = LookupManager.getActiveLookup(editor); + e.getPresentation().setEnabled(!myProcessHandler.isProcessTerminated() && + (lookup == null || !lookup.isCompletion())); + } + }; + EmptyAction.setupAction(myRunAction, "Console.Python.Execute", null); + toolbarActions.add(myRunAction); + +// Help + toolbarActions.add(CommonActionsManager.getInstance().createHelpAction("interactive_console")); + +// history actions + final PairProcessor historyProcessor = new PairProcessor() { + public boolean process(final AnActionEvent e, final String s) { + new WriteCommandAction(myProject, getLanguageConsole().getFile()) { + protected void run(final Result result) throws Throwable { + getLanguageConsole().getEditorDocument().setText(s == null? "" : s); + } + }.execute(); + return true; + } + }; + final AnAction historyNextAction = ConsoleHistoryModel.createHistoryAction(myHistory, true, historyProcessor); + final AnAction historyPrevAction = ConsoleHistoryModel.createHistoryAction(myHistory, false, historyProcessor); + historyNextAction.getTemplatePresentation().setVisible(false); + historyPrevAction.getTemplatePresentation().setVisible(false); + toolbarActions.add(historyNextAction); + toolbarActions.add(historyPrevAction); + + return new AnAction[]{stopAction, closeAction, myRunAction, historyNextAction, historyPrevAction}; + } + + protected AnAction createCloseAction(final Executor defaultExecutor, final RunContentDescriptor myDescriptor) { + return new CloseAction(defaultExecutor, myDescriptor, myProject); + } + + protected AnAction createStopAction() { + return ActionManager.getInstance().getAction(IdeActions.ACTION_STOP_PROGRAM); + } + + protected void sendInput(final String input) { + final Charset charset = myProcessHandler.getCharset(); + final OutputStream outputStream = myProcessHandler.getProcessInput(); + try { + byte[] bytes = input.getBytes(charset.name()); + outputStream.write(bytes); + outputStream.flush(); + } + catch (IOException e) { + // ignore + } + } + + public LanguageConsoleImpl getLanguageConsole() { + return myConsoleView.getConsole(); + } + + private void runExecuteActionInner(final boolean erase) { + // Process input and add to history + final Document document = getLanguageConsole().getCurrentEditor().getDocument(); + final String documentText = document.getText(); + final TextRange range = new TextRange(0, document.getTextLength()); + getLanguageConsole().getCurrentEditor().getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); + getLanguageConsole().addCurrentToHistory(range, false); + if (erase) { + getLanguageConsole().setInputText(""); + } + final String line = documentText; + if (!StringUtil.isEmptyOrSpaces(line)){ + myHistory.addToHistory(line); + } + // Send to interpreter / server + final String text2send = line.length() == 0 ? "\n\n" : line + "\n"; + sendInput(text2send); + + if (myConsoleView instanceof ConsoleNotification){ + ((ConsoleNotification)myConsoleView).inputSent(text2send); + } + } + + private static String getProviderCommandLine(final CommandLineArgumentsProvider provider) { + final StringBuilder builder = new StringBuilder(); + for (String s : provider.getArguments()) { + if (builder.length() > 0){ + builder.append(' '); + } + builder.append(s); + } + return builder.toString(); + } + + public Project getProject() { + return myProject; + }*/ +} From 73fe4e7236a97d1b2a128d54bcc1218fbf06de6b Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Wed, 14 Apr 2010 16:22:38 +0400 Subject: [PATCH 6/7] cleanup --- .../AbstractConsoleRunnerWithHistory.java | 320 ------------------ 1 file changed, 320 deletions(-) delete mode 100644 platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java diff --git a/platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java b/platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java deleted file mode 100644 index f1ad4371a82f..000000000000 --- a/platform/lang-impl/src/com/intellij/execution/console/AbstractConsoleRunnerWithHistory.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed 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 com.intellij.execution.console; - -import com.intellij.codeInsight.lookup.Lookup; -import com.intellij.codeInsight.lookup.LookupManager; -import com.intellij.execution.ExecutionException; -import com.intellij.execution.ExecutionManager; -import com.intellij.execution.Executor; -import com.intellij.execution.ExecutorRegistry; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.execution.process.*; -import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.execution.ui.actions.CloseAction; -import com.intellij.ide.CommonActionsManager; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.Result; -import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.editor.ex.EditorEx; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleManager; -import com.intellij.openapi.module.ModuleUtil; -import com.intellij.openapi.project.DumbAwareAction; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.encoding.EncodingManager; -import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.openapi.wm.ToolWindow; -import com.intellij.openapi.wm.ToolWindowManager; -import com.intellij.psi.PsiFile; -import com.intellij.util.PairProcessor; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; -import java.awt.*; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.charset.Charset; -import java.util.Arrays; - -/** - * @author oleg - */ -public class AbstractConsoleRunnerWithHistory { -/* protected final Project myProject; - protected final String myConsoleTitle; - - private OSProcessHandler myProcessHandler; - protected final CommandLineArgumentsProvider myProvider; - protected final String myWorkingDir; - - protected LanguageConsoleViewImpl myConsoleView; - private final ConsoleHistoryModel myHistory = new ConsoleHistoryModel(); - private AnAction myRunAction; - - public AbstractConsoleRunnerWithHistory(@NotNull final Project project, - @NotNull final String consoleTitle, - @NotNull final CommandLineArgumentsProvider provider, - @Nullable final String workingDir) { - myProject = project; - myConsoleTitle = consoleTitle; - myProvider = provider; - myWorkingDir = workingDir; - } - - public static void run(@NotNull final Project project, - @NotNull final String consoleTitle, - @NotNull final CommandLineArgumentsProvider provider, - @Nullable final String workingDir) { - - final AbstractConsoleRunnerWithHistory consoleRunner = new AbstractConsoleRunnerWithHistory(project, consoleTitle, provider, workingDir); - try { - consoleRunner.initAndRun(); - } - catch (ExecutionException e) { - ExecutionHelper.showErrors(project, Arrays.asList(e), consoleTitle, null); - } - } - - public void initAndRun() throws ExecutionException { - // Create Server process - final Process process = createProcess(); - - // Init console view - myConsoleView = createConsoleView(); - - myProcessHandler = createProcessHandler(process); - - ProcessTerminatedListener.attach(myProcessHandler); - - // Set language level - for (Module module : ModuleManager.getInstance(myProject).getModules()) { - final Sdk pythonSdk = PythonSdkType.findPythonSdk(module); - if (pythonSdk != null){ - final LanguageLevel languageLevel = PythonSdkType.getLanguageLevelForSdk(pythonSdk); - final PsiFile psiFile = getLanguageConsole().getFile(); - // Set module explicitly - psiFile.putUserData(ModuleUtil.KEY_MODULE, module); - final VirtualFile vFile = psiFile.getVirtualFile(); - if (vFile != null) { - // Set language level - vFile.putUserData(LanguageLevel.KEY, languageLevel); - } - break; - } - } - - myProcessHandler.addProcessListener(new ProcessAdapter() { - @Override - public void processTerminated(ProcessEvent event) { - myRunAction.getTemplatePresentation().setEnabled(false); - myConsoleView.getConsole().setPrompt(""); - myConsoleView.getConsole().getConsoleEditor().setRendererMode(true); - ApplicationManager.getApplication().invokeLater(new Runnable() { - public void run() { - myConsoleView.getConsole().getConsoleEditor().getComponent().updateUI(); - } - }); - } - }); - -// Setup default prompt - myConsoleView.getConsole().setPrompt(PyConsoleHighlightingUtil.ORDINARY_PROMPT.trim()); - -// Attach to process - myConsoleView.attachToProcess(myProcessHandler); - -// Add filter TODO[oleg]: Add stacktrace filters -// myConsoleView.addMessageFilter(new OutputConsoleFilter()); - -// Runner creating - final Executor defaultExecutor = ExecutorRegistry.getInstance().getExecutorById(DefaultRunExecutor.EXECUTOR_ID); - final DefaultActionGroup toolbarActions = new DefaultActionGroup(); - final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, toolbarActions, false); - -// Runner creating - final JPanel panel = new JPanel(new BorderLayout()); - panel.add(actionToolbar.getComponent(), BorderLayout.WEST); - panel.add(myConsoleView.getComponent(), BorderLayout.CENTER); - - final RunContentDescriptor myDescriptor = - new RunContentDescriptor(myConsoleView, myProcessHandler, panel, myConsoleTitle); - -// tool bar actions - final AnAction[] actions = fillToolBarActions(toolbarActions, defaultExecutor, myDescriptor); - registerActionShortcuts(actions, getLanguageConsole().getConsoleEditor().getComponent()); - registerActionShortcuts(actions, panel); - panel.updateUI(); - -// Show in run toolwindow - ExecutionManager.getInstance(myProject).getContentManager().showRunContent(defaultExecutor, myDescriptor); - -// Request focus - final ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow(defaultExecutor.getId()); - window.activate(new Runnable() { - public void run() { - IdeFocusManager.getInstance(myProject).requestFocus(getLanguageConsole().getCurrentEditor().getContentComponent(), true); - } - }); -// Run - myProcessHandler.startNotify(); - } - - protected LanguageConsoleViewImpl createConsoleView() { - return new PyLanguageConsoleView(myProject, myConsoleTitle); - } - - - @Nullable - protected Process createProcess() throws ExecutionException { - return Runner.createProcess(myWorkingDir, true, myProvider.getAdditionalEnvs(), myProvider.getArguments()); - } - - private PyConsoleProcessHandler createProcessHandler(final Process process) { - final Charset outputEncoding = EncodingManager.getInstance().getDefaultCharset(); - return new PyConsoleProcessHandler(process, myConsoleView.getConsole(), getProviderCommandLine(myProvider), outputEncoding); - } - - private void registerActionShortcuts(final AnAction[] actions, final JComponent component) { - for (AnAction action : actions) { - if (action.getShortcutSet() != null) { - action.registerCustomShortcutSet(action.getShortcutSet(), component); - } - } - } - - private AnAction[] fillToolBarActions(final DefaultActionGroup toolbarActions, - final Executor defaultExecutor, - final RunContentDescriptor myDescriptor) { -//stop - final AnAction stopAction = createStopAction(); - toolbarActions.add(stopAction); - -//close - final AnAction closeAction = createCloseAction(defaultExecutor, myDescriptor); - toolbarActions.add(closeAction); - -// run action - myRunAction = new DumbAwareAction(null, null, IconLoader.getIcon("/actions/execute.png")) { - public void actionPerformed(final AnActionEvent e) { - runExecuteActionInner(true); - } - - public void update(final AnActionEvent e) { - final EditorEx editor = getLanguageConsole().getConsoleEditor(); - final Lookup lookup = LookupManager.getActiveLookup(editor); - e.getPresentation().setEnabled(!myProcessHandler.isProcessTerminated() && - (lookup == null || !lookup.isCompletion())); - } - }; - EmptyAction.setupAction(myRunAction, "Console.Python.Execute", null); - toolbarActions.add(myRunAction); - -// Help - toolbarActions.add(CommonActionsManager.getInstance().createHelpAction("interactive_console")); - -// history actions - final PairProcessor historyProcessor = new PairProcessor() { - public boolean process(final AnActionEvent e, final String s) { - new WriteCommandAction(myProject, getLanguageConsole().getFile()) { - protected void run(final Result result) throws Throwable { - getLanguageConsole().getEditorDocument().setText(s == null? "" : s); - } - }.execute(); - return true; - } - }; - final AnAction historyNextAction = ConsoleHistoryModel.createHistoryAction(myHistory, true, historyProcessor); - final AnAction historyPrevAction = ConsoleHistoryModel.createHistoryAction(myHistory, false, historyProcessor); - historyNextAction.getTemplatePresentation().setVisible(false); - historyPrevAction.getTemplatePresentation().setVisible(false); - toolbarActions.add(historyNextAction); - toolbarActions.add(historyPrevAction); - - return new AnAction[]{stopAction, closeAction, myRunAction, historyNextAction, historyPrevAction}; - } - - protected AnAction createCloseAction(final Executor defaultExecutor, final RunContentDescriptor myDescriptor) { - return new CloseAction(defaultExecutor, myDescriptor, myProject); - } - - protected AnAction createStopAction() { - return ActionManager.getInstance().getAction(IdeActions.ACTION_STOP_PROGRAM); - } - - protected void sendInput(final String input) { - final Charset charset = myProcessHandler.getCharset(); - final OutputStream outputStream = myProcessHandler.getProcessInput(); - try { - byte[] bytes = input.getBytes(charset.name()); - outputStream.write(bytes); - outputStream.flush(); - } - catch (IOException e) { - // ignore - } - } - - public LanguageConsoleImpl getLanguageConsole() { - return myConsoleView.getConsole(); - } - - private void runExecuteActionInner(final boolean erase) { - // Process input and add to history - final Document document = getLanguageConsole().getCurrentEditor().getDocument(); - final String documentText = document.getText(); - final TextRange range = new TextRange(0, document.getTextLength()); - getLanguageConsole().getCurrentEditor().getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset()); - getLanguageConsole().addCurrentToHistory(range, false); - if (erase) { - getLanguageConsole().setInputText(""); - } - final String line = documentText; - if (!StringUtil.isEmptyOrSpaces(line)){ - myHistory.addToHistory(line); - } - // Send to interpreter / server - final String text2send = line.length() == 0 ? "\n\n" : line + "\n"; - sendInput(text2send); - - if (myConsoleView instanceof ConsoleNotification){ - ((ConsoleNotification)myConsoleView).inputSent(text2send); - } - } - - private static String getProviderCommandLine(final CommandLineArgumentsProvider provider) { - final StringBuilder builder = new StringBuilder(); - for (String s : provider.getArguments()) { - if (builder.length() > 0){ - builder.append(' '); - } - builder.append(s); - } - return builder.toString(); - } - - public Project getProject() { - return myProject; - }*/ -} From 635edf556f8d86aee723806e373c8dad0fed01d9 Mon Sep 17 00:00:00 2001 From: Oleg Shpynov Date: Wed, 14 Apr 2010 16:30:00 +0400 Subject: [PATCH 7/7] Compilation fix. damn you incrementally compilation bugs --- .../intellij/execution/ExecutionModes.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 platform/lang-impl/src/com/intellij/execution/ExecutionModes.java diff --git a/platform/lang-impl/src/com/intellij/execution/ExecutionModes.java b/platform/lang-impl/src/com/intellij/execution/ExecutionModes.java new file mode 100644 index 000000000000..a03ac3ec6ef5 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/execution/ExecutionModes.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed 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 com.intellij.execution; + +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author oleg + */ +public class ExecutionModes { + /** + * Process will be run in back ground mode + */ + public static class BackGroundMode extends ExecutionMode { + + public BackGroundMode(final boolean cancelable, @Nullable final String title) { + super(cancelable, title, null, true, false, null); + } + + public BackGroundMode(@Nullable final String title) { + this(true, title); + } + } + + /** + * Process will be run in modal dialog + */ + public static class ModalProgressMode extends ExecutionMode { + + public ModalProgressMode(final boolean cancelable, @Nullable final String title, JComponent progressParentComponent) { + super(cancelable, title, null, false, true, progressParentComponent); + } + + public ModalProgressMode(@Nullable final String title) { + this(true, title, null); + } + + public ModalProgressMode(@Nullable final String title, JComponent progressParentComponent) { + this(true, title, progressParentComponent); + } + } + + /** + * Process will be run in the same thread. + */ + public static class SameThreadMode extends ExecutionMode { + private final int myTimeout; + + public SameThreadMode(final boolean cancelable, + @Nullable final String title2, + final int timeout) { + super(cancelable, null, title2, false, false, null); + myTimeout = timeout; + } + + public SameThreadMode(@Nullable final String title2) { + this(true, title2, -1); + } + + /** + * @param cancelable + */ + public SameThreadMode(final boolean cancelable) { + this(cancelable, null, -1); + } + + /** + * @param timeout If less than zero it will be ignored + */ + public SameThreadMode(final int timeout) { + this(false, null, timeout); + } + + public SameThreadMode() { + this(true); + } + + public int getTimeout() { + return myTimeout; + } + } +}