mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+4
-4
@@ -885,13 +885,13 @@ public class InspectionProfileImpl extends ProfileEx implements ModifiableModel,
|
||||
getTools(toolId, project).removeScope(scopeIdx);
|
||||
}
|
||||
|
||||
public void removeScope(@NotNull String toolId, @NotNull NamedScope scope, Project project) {
|
||||
getTools(toolId, project).removeScope(scope);
|
||||
public void removeScope(@NotNull String toolId, @NotNull String scopeName, Project project) {
|
||||
getTools(toolId, project).removeScope(scopeName);
|
||||
}
|
||||
|
||||
public void removeScopes(@NotNull List<String> toolIds, @NotNull NamedScope scope, Project project) {
|
||||
public void removeScopes(@NotNull List<String> toolIds, @NotNull String scopeName, Project project) {
|
||||
for (final String toolId : toolIds) {
|
||||
removeScope(toolId, scope, project);
|
||||
removeScope(toolId, scopeName, project);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -267,25 +267,26 @@ public class ToolsImpl implements Tools {
|
||||
public void removeScope(int scopeIdx) {
|
||||
if (myTools != null && scopeIdx >= 0 && myTools.size() > scopeIdx) {
|
||||
myTools.remove(scopeIdx);
|
||||
if (myTools.isEmpty()) {
|
||||
myTools = null;
|
||||
setEnabled(myDefaultState.isEnabled());
|
||||
}
|
||||
checkToolsIsEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
public void removeScope(final NamedScope scope) {
|
||||
public void removeScope(final @NotNull String scopeName) {
|
||||
if (myTools != null) {
|
||||
for (final ScopeToolState tool : myTools) {
|
||||
if (Comparing.equal(tool.getScopeName(), scope.getName())) {
|
||||
for (ScopeToolState tool : myTools) {
|
||||
if (scopeName.equals(tool.getScopeName())) {
|
||||
myTools.remove(tool);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (myTools.isEmpty()) {
|
||||
myTools = null;
|
||||
setEnabled(myDefaultState.isEnabled());
|
||||
}
|
||||
checkToolsIsEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkToolsIsEmpty() {
|
||||
if (myTools.isEmpty()) {
|
||||
myTools = null;
|
||||
setEnabled(myDefaultState.isEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.lang.customFolding;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public class CustomFoldingRegionsPopup {
|
||||
private final @NotNull JBList myRegionsList;
|
||||
private final @NotNull JBPopup myPopup;
|
||||
private final @NotNull Editor myEditor;
|
||||
|
||||
CustomFoldingRegionsPopup(@NotNull Collection<FoldingDescriptor> descriptors,
|
||||
@NotNull final Editor editor,
|
||||
@NotNull final Project project) {
|
||||
myEditor = editor;
|
||||
myRegionsList = new JBList();
|
||||
//noinspection unchecked
|
||||
myRegionsList.setModel(new MyListModel(orderByPosition(descriptors)));
|
||||
myRegionsList.setSelectedIndex(0);
|
||||
|
||||
final PopupChooserBuilder popupBuilder = JBPopupFactory.getInstance().createListPopupBuilder(myRegionsList);
|
||||
myPopup = popupBuilder
|
||||
.setTitle(IdeBundle.message("goto.custom.region.command"))
|
||||
.setResizable(false)
|
||||
.setMovable(false)
|
||||
.setItemChoosenCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
PsiElement navigationElement = getNavigationElement();
|
||||
if (navigationElement != null) {
|
||||
navigateTo(editor, navigationElement);
|
||||
IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation();
|
||||
}
|
||||
}
|
||||
}).createPopup();
|
||||
}
|
||||
|
||||
void show() {
|
||||
myPopup.showInBestPositionFor(myEditor);
|
||||
}
|
||||
|
||||
private static class MyListModel extends DefaultListModel {
|
||||
private MyListModel(Collection<FoldingDescriptor> descriptors) {
|
||||
for (FoldingDescriptor descriptor : descriptors) {
|
||||
//noinspection unchecked
|
||||
super.addElement(new MyFoldingDescriptorWrapper(descriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyFoldingDescriptorWrapper {
|
||||
private final @NotNull FoldingDescriptor myDescriptor;
|
||||
|
||||
private MyFoldingDescriptorWrapper(@NotNull FoldingDescriptor descriptor) {
|
||||
myDescriptor = descriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FoldingDescriptor getDescriptor() {
|
||||
return myDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String toString() {
|
||||
return myDescriptor.getPlaceholderText();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getNavigationElement() {
|
||||
Object selection = myRegionsList.getSelectedValue();
|
||||
if (selection instanceof MyFoldingDescriptorWrapper) {
|
||||
return ((MyFoldingDescriptorWrapper)selection).getDescriptor().getElement().getPsi();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Collection<FoldingDescriptor> orderByPosition(Collection<FoldingDescriptor> descriptors) {
|
||||
List<FoldingDescriptor> sorted = new ArrayList<FoldingDescriptor>(descriptors.size());
|
||||
sorted.addAll(descriptors);
|
||||
Collections.sort(sorted, new Comparator<FoldingDescriptor>() {
|
||||
@Override
|
||||
public int compare(FoldingDescriptor descriptor1, FoldingDescriptor descriptor2) {
|
||||
int pos1 = descriptor1.getElement().getTextRange().getStartOffset();
|
||||
int pos2 = descriptor2.getElement().getTextRange().getStartOffset();
|
||||
return pos1 - pos2;
|
||||
}
|
||||
});
|
||||
return sorted;
|
||||
}
|
||||
|
||||
private static void navigateTo(@NotNull Editor editor, @NotNull PsiElement element) {
|
||||
int offset = element.getTextRange().getStartOffset();
|
||||
if (offset >= 0 && offset < editor.getDocument().getTextLength()) {
|
||||
editor.getCaretModel().removeSecondaryCarets();
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
|
||||
editor.getSelectionModel().removeSelection();
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
-26
@@ -16,26 +16,35 @@
|
||||
package com.intellij.lang.customFolding;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.folding.*;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public class GotoCustomRegionAction extends AnAction implements DumbAware {
|
||||
public class GotoCustomRegionAction extends AnAction implements DumbAware, PopupAction {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
final Project project = e.getProject();
|
||||
final Editor editor = e.getData(CommonDataKeys.EDITOR);
|
||||
if (Boolean.TRUE.equals(e.getData(PlatformDataKeys.IS_MODAL_CONTEXT))) {
|
||||
@@ -52,14 +61,13 @@ public class GotoCustomRegionAction extends AnAction implements DumbAware {
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
GotoCustomRegionDialog dialog = new GotoCustomRegionDialog(project, editor);
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
PsiElement navigationElement = dialog.getNavigationElement();
|
||||
if (navigationElement != null) {
|
||||
navigateTo(editor, navigationElement);
|
||||
IdeDocumentHistory.getInstance(project).includeCurrentCommandAsNavigation();
|
||||
}
|
||||
Collection<FoldingDescriptor> foldingDescriptors = getCustomFoldingDescriptors(editor, project);
|
||||
if (foldingDescriptors.size() > 0) {
|
||||
CustomFoldingRegionsPopup regionsPopup = new CustomFoldingRegionsPopup(foldingDescriptors, editor, project);
|
||||
regionsPopup.show();
|
||||
}
|
||||
else {
|
||||
notifyCustomRegionsUnavailable(editor, project);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -71,7 +79,7 @@ public class GotoCustomRegionAction extends AnAction implements DumbAware {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
Presentation presentation = e.getPresentation();
|
||||
presentation.setText("Custom Region...");
|
||||
presentation.setText(IdeBundle.message("goto.custom.region.menu.item"));
|
||||
final Editor editor = e.getData(CommonDataKeys.EDITOR);
|
||||
final Project project = e.getProject();
|
||||
boolean isAvailable = editor != null && project != null;
|
||||
@@ -79,13 +87,49 @@ public class GotoCustomRegionAction extends AnAction implements DumbAware {
|
||||
presentation.setVisible(isAvailable);
|
||||
}
|
||||
|
||||
private static void navigateTo(Editor editor, PsiElement element) {
|
||||
int offset = element.getTextRange().getStartOffset();
|
||||
if (offset >= 0 && offset < editor.getDocument().getTextLength()) {
|
||||
editor.getCaretModel().removeSecondaryCarets();
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
|
||||
editor.getSelectionModel().removeSelection();
|
||||
@NotNull
|
||||
private static Collection<FoldingDescriptor> getCustomFoldingDescriptors(@NotNull Editor editor, @NotNull Project project) {
|
||||
Set<FoldingDescriptor> foldingDescriptors = new HashSet<FoldingDescriptor>();
|
||||
final Document document = editor.getDocument();
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
|
||||
PsiFile file = documentManager != null ? documentManager.getPsiFile(document) : null;
|
||||
if (file != null) {
|
||||
final FileViewProvider viewProvider = file.getViewProvider();
|
||||
for (final Language language : viewProvider.getLanguages()) {
|
||||
final PsiFile psi = viewProvider.getPsi(language);
|
||||
final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(language);
|
||||
if (psi != null) {
|
||||
for (FoldingDescriptor descriptor : LanguageFolding.buildFoldingDescriptors(foldingBuilder, psi, document, false)) {
|
||||
CustomFoldingBuilder customFoldingBuilder = getCustomFoldingBuilder(foldingBuilder, descriptor);
|
||||
if (customFoldingBuilder != null) {
|
||||
if (customFoldingBuilder.isCustomRegionStart(descriptor.getElement())) {
|
||||
foldingDescriptors.add(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return foldingDescriptors;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CustomFoldingBuilder getCustomFoldingBuilder(FoldingBuilder builder, FoldingDescriptor descriptor) {
|
||||
if (builder instanceof CustomFoldingBuilder) return (CustomFoldingBuilder)builder;
|
||||
FoldingBuilder originalBuilder = descriptor.getElement().getUserData(CompositeFoldingBuilder.FOLDING_BUILDER);
|
||||
if (originalBuilder instanceof CustomFoldingBuilder) return (CustomFoldingBuilder)originalBuilder;
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void notifyCustomRegionsUnavailable(@NotNull Editor editor, @NotNull Project project) {
|
||||
final JBPopupFactory popupFactory = JBPopupFactory.getInstance();
|
||||
Balloon balloon = popupFactory
|
||||
.createHtmlTextBalloonBuilder(IdeBundle.message("goto.custom.region.message.unavailable"), MessageType.INFO, null)
|
||||
.setFadeoutTime(2000)
|
||||
.setHideOnClickOutside(true)
|
||||
.setHideOnKeyOutside(true)
|
||||
.createBalloon();
|
||||
Disposer.register(project, balloon);
|
||||
balloon.show(popupFactory.guessBestPopupLocation(editor), Balloon.Position.above);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.lang.customFolding.GotoCustomRegionDialog">
|
||||
<grid id="27dc6" binding="myContentPane" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<scrollpane id="7557d" class="com.intellij.ui.components.JBScrollPane" binding="myScrollPane" custom-create="true">
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="2f5d5" class="com.intellij.ui.components.JBList" binding="myRegionsList" custom-create="true">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<selectionMode value="0"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 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.lang.customFolding;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.folding.*;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Rustam Vishnyakov
|
||||
*/
|
||||
public class GotoCustomRegionDialog extends DialogWrapper {
|
||||
private JBList myRegionsList;
|
||||
private JPanel myContentPane;
|
||||
private JBScrollPane myScrollPane;
|
||||
private final Editor myEditor;
|
||||
private final Project myProject;
|
||||
|
||||
protected GotoCustomRegionDialog(@Nullable Project project, @NotNull Editor editor) {
|
||||
super(project);
|
||||
myEditor = editor;
|
||||
myProject = project;
|
||||
Collection<FoldingDescriptor> descriptors = getCustomFoldingDescriptors();
|
||||
init();
|
||||
if (descriptors.size() == 0) {
|
||||
myScrollPane.setVisible(false);
|
||||
myContentPane.add(new JLabel(IdeBundle.message("goto.custom.region.message.unavailable")), BorderLayout.NORTH);
|
||||
setOKActionEnabled(false);
|
||||
}
|
||||
else {
|
||||
myRegionsList.setModel(new MyListModel(orderByPosition(descriptors)));
|
||||
myRegionsList.setSelectedIndex(0);
|
||||
}
|
||||
setTitle(IdeBundle.message("goto.custom.region.command"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
if (!myRegionsList.isEmpty()) {
|
||||
return myRegionsList;
|
||||
}
|
||||
return super.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myContentPane;
|
||||
}
|
||||
|
||||
private Collection<FoldingDescriptor> getCustomFoldingDescriptors() {
|
||||
Set<FoldingDescriptor> foldingDescriptors = new HashSet<FoldingDescriptor>();
|
||||
final Document document = myEditor.getDocument();
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
|
||||
PsiFile file = documentManager != null ? documentManager.getPsiFile(document) : null;
|
||||
if (file != null) {
|
||||
final FileViewProvider viewProvider = file.getViewProvider();
|
||||
for (final Language language : viewProvider.getLanguages()) {
|
||||
final PsiFile psi = viewProvider.getPsi(language);
|
||||
final FoldingBuilder foldingBuilder = LanguageFolding.INSTANCE.forLanguage(language);
|
||||
if (psi != null) {
|
||||
for (FoldingDescriptor descriptor : LanguageFolding.buildFoldingDescriptors(foldingBuilder, psi, document, false)) {
|
||||
CustomFoldingBuilder customFoldingBuilder = getCustomFoldingBuilder(foldingBuilder, descriptor);
|
||||
if (customFoldingBuilder != null) {
|
||||
if (customFoldingBuilder.isCustomRegionStart(descriptor.getElement())) {
|
||||
foldingDescriptors.add(descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return foldingDescriptors;
|
||||
}
|
||||
|
||||
private static Collection<FoldingDescriptor> orderByPosition(Collection<FoldingDescriptor> descriptors) {
|
||||
List<FoldingDescriptor> sorted = new ArrayList<FoldingDescriptor>(descriptors.size());
|
||||
sorted.addAll(descriptors);
|
||||
Collections.sort(sorted, new Comparator<FoldingDescriptor>() {
|
||||
@Override
|
||||
public int compare(FoldingDescriptor descriptor1, FoldingDescriptor descriptor2) {
|
||||
int pos1 = descriptor1.getElement().getTextRange().getStartOffset();
|
||||
int pos2 = descriptor2.getElement().getTextRange().getStartOffset();
|
||||
return pos1 - pos2;
|
||||
}
|
||||
});
|
||||
return sorted;
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myRegionsList = new JBList();
|
||||
myScrollPane = new JBScrollPane(myRegionsList);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CustomFoldingBuilder getCustomFoldingBuilder(FoldingBuilder builder, FoldingDescriptor descriptor) {
|
||||
if (builder instanceof CustomFoldingBuilder) return (CustomFoldingBuilder)builder;
|
||||
FoldingBuilder originalBuilder = descriptor.getElement().getUserData(CompositeFoldingBuilder.FOLDING_BUILDER);
|
||||
if (originalBuilder instanceof CustomFoldingBuilder) return (CustomFoldingBuilder)originalBuilder;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static class MyListModel extends DefaultListModel {
|
||||
private MyListModel(Collection<FoldingDescriptor> descriptors) {
|
||||
for (FoldingDescriptor descriptor : descriptors) {
|
||||
super.addElement(new MyFoldingDescriptorWrapper(descriptor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyFoldingDescriptorWrapper {
|
||||
private final @NotNull FoldingDescriptor myDescriptor;
|
||||
|
||||
private MyFoldingDescriptorWrapper(@NotNull FoldingDescriptor descriptor) {
|
||||
myDescriptor = descriptor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FoldingDescriptor getDescriptor() {
|
||||
return myDescriptor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String toString() {
|
||||
return myDescriptor.getPlaceholderText();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getNavigationElement() {
|
||||
Object selection = myRegionsList.getSelectedValue();
|
||||
if (selection instanceof MyFoldingDescriptorWrapper) {
|
||||
return ((MyFoldingDescriptorWrapper)selection).getDescriptor().getElement().getPsi();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -357,6 +357,9 @@ public class ScopesAndSeveritiesTable extends JBTable {
|
||||
}
|
||||
else if (columnIndex == SCOPE_ENABLED_COLUMN) {
|
||||
final NamedScope scope = getScope(rowIndex);
|
||||
if (scope == null) {
|
||||
return;
|
||||
}
|
||||
if ((Boolean)value) {
|
||||
if (rowIndex == lastRowIndex()) {
|
||||
myInspectionProfile.enableToolsByDefault(myKeyNames, myProject);
|
||||
@@ -381,7 +384,7 @@ public class ScopesAndSeveritiesTable extends JBTable {
|
||||
@Override
|
||||
public void removeRow(final int idx) {
|
||||
if (idx != lastRowIndex()) {
|
||||
myInspectionProfile.removeScopes(myKeyNames, getScope(idx), myProject);
|
||||
myInspectionProfile.removeScopes(myKeyNames, getScopeName(idx), myProject);
|
||||
refreshAggregatedScopes();
|
||||
myTableSettings.onScopeRemoved(getRowCount());
|
||||
}
|
||||
|
||||
@@ -1142,8 +1142,9 @@ whatsnew.action.custom.text=What''s _New in {0}
|
||||
whatsnew.action.custom.description=Find out about the new features in this version of {0}
|
||||
diff.dialog.title=Diff Between ''{0}'' and ''{1}''
|
||||
|
||||
goto.custom.region.command=Go to Custom Region
|
||||
goto.custom.region.message.dumb.mode=Go to Custom Region action is not available until indices are built.
|
||||
goto.custom.region.menu.item=Custom Folding Region...
|
||||
goto.custom.region.command=Go to Custom Folding Region
|
||||
goto.custom.region.message.dumb.mode=Go to Custom Folding Region action is not available until indices are built.
|
||||
goto.custom.region.message.unavailable=There are no custom folding regions in the current file.
|
||||
alphabetical.mode.is.on.warning=Alphabetical order for tabs is ON. Switch it OFF?
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ public class MockVirtualFileSystem extends DeprecatedVirtualFileSystem {
|
||||
public static final String PROTOCOL = "mock";
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VirtualFile findFileByPath(@NotNull String path) {
|
||||
path = path.replace(File.separatorChar, '/');
|
||||
path = path.replace('/', ':');
|
||||
@@ -106,6 +107,7 @@ public class MockVirtualFileSystem extends DeprecatedVirtualFileSystem {
|
||||
return MockVirtualFileSystem.this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public MyVirtualFile getOrCreate(String name) {
|
||||
MyVirtualFile file = myChildren.get(name);
|
||||
if (file == null) {
|
||||
|
||||
+2
@@ -37,6 +37,7 @@ public abstract class IdeaTestFixtureFactory {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static IdeaTestFixtureFactory getFixtureFactory() {
|
||||
return ourInstance;
|
||||
}
|
||||
@@ -59,6 +60,7 @@ public abstract class IdeaTestFixtureFactory {
|
||||
|
||||
public abstract TestFixtureBuilder<IdeaProjectTestFixture> createFixtureBuilder(@NotNull String name);
|
||||
|
||||
@NotNull
|
||||
public abstract TestFixtureBuilder<IdeaProjectTestFixture> createLightFixtureBuilder();
|
||||
|
||||
public abstract TestFixtureBuilder<IdeaProjectTestFixture> createLightFixtureBuilder(@Nullable LightProjectDescriptor projectDescriptor);
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
package com.intellij.testFramework.fixtures;
|
||||
|
||||
import com.intellij.testFramework.builders.ModuleFixtureBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
*/
|
||||
public interface TestFixtureBuilder<T extends IdeaTestFixture> {
|
||||
@NotNull
|
||||
T getFixture();
|
||||
|
||||
<M extends ModuleFixtureBuilder> M addModule(Class<M> builderClass);
|
||||
|
||||
+2
@@ -22,6 +22,7 @@ import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
|
||||
import com.intellij.testFramework.fixtures.TestFixtureBuilder;
|
||||
import com.intellij.util.pico.ConstructorInjectionComponentAdapter;
|
||||
import com.intellij.util.pico.IdeaPicoContainer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.picocontainer.MutablePicoContainer;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -50,6 +51,7 @@ class HeavyTestFixtureBuilderImpl implements TestFixtureBuilder<IdeaProjectTestF
|
||||
return (M)adapter.getComponentInstance(myContainer);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HeavyIdeaTestFixture getFixture() {
|
||||
return myFixture;
|
||||
|
||||
+1
@@ -62,6 +62,7 @@ public class IdeaTestFixtureFactoryImpl extends IdeaTestFixtureFactory {
|
||||
return new HeavyTestFixtureBuilderImpl(new HeavyIdeaTestFixtureImpl(name), myFixtureBuilderProviders);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TestFixtureBuilder<IdeaProjectTestFixture> createLightFixtureBuilder() {
|
||||
return new LightTestFixtureBuilderImpl<IdeaProjectTestFixture>(new LightIdeaTestFixtureImpl(
|
||||
|
||||
+2
@@ -19,6 +19,7 @@ package com.intellij.testFramework.fixtures.impl;
|
||||
import com.intellij.testFramework.builders.ModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
|
||||
import com.intellij.testFramework.fixtures.TestFixtureBuilder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
@@ -31,6 +32,7 @@ class LightTestFixtureBuilderImpl<F extends IdeaProjectTestFixture> implements T
|
||||
myFixture = fixture;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public F getFixture() {
|
||||
return myFixture;
|
||||
|
||||
+4
-2
@@ -39,7 +39,7 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor {
|
||||
@Nullable private final WatchNode myOldNode;
|
||||
|
||||
public WatchInplaceEditor(@NotNull WatchesRootNode rootNode,
|
||||
@NotNull XDebugSession session, XWatchesView watchesView, final WatchNode node,
|
||||
@Nullable XDebugSession session, XWatchesView watchesView, final WatchNode node,
|
||||
@NonNls final String historyId,
|
||||
final @Nullable WatchNode oldNode) {
|
||||
super((XDebuggerTreeNode)node, historyId);
|
||||
@@ -47,7 +47,9 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor {
|
||||
myWatchesView = watchesView;
|
||||
myOldNode = oldNode;
|
||||
myExpressionEditor.setExpression(oldNode != null ? oldNode.getExpression() : null);
|
||||
new WatchEditorSessionListener(session).install();
|
||||
if (session != null) {
|
||||
new WatchEditorSessionListener(session).install();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.execution.ui.layout.ViewContext;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.ui.content.ContentManager;
|
||||
import com.intellij.util.SingleAlarm;
|
||||
import com.intellij.xdebugger.XDebugSession;
|
||||
@@ -66,15 +67,20 @@ public abstract class XDebugView implements Disposable {
|
||||
|
||||
@Nullable
|
||||
public static XDebugSession getSession(@NotNull Component component) {
|
||||
return getData(XDebugSession.DATA_KEY, component);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static <T> T getData(DataKey<T> key, @NotNull Component component) {
|
||||
DataContext dataContext = DataManager.getInstance().getDataContext(component);
|
||||
ViewContext viewContext = ViewContext.CONTEXT_KEY.getData(dataContext);
|
||||
ContentManager contentManager = viewContext == null ? null : viewContext.getContentManager();
|
||||
if (contentManager != null) {
|
||||
XDebugSession session = XDebugSession.DATA_KEY.getData(DataManager.getInstance().getDataContext(contentManager.getComponent()));
|
||||
if (session != null) {
|
||||
return session;
|
||||
T data = key.getData(DataManager.getInstance().getDataContext(contentManager.getComponent()));
|
||||
if (data != null) {
|
||||
return data;
|
||||
}
|
||||
}
|
||||
return XDebugSession.DATA_KEY.getData(dataContext);
|
||||
return key.getData(dataContext);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-7
@@ -40,6 +40,7 @@ import com.intellij.xdebugger.frame.XStackFrame;
|
||||
import com.intellij.xdebugger.impl.XDebugSessionImpl;
|
||||
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
|
||||
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
|
||||
import com.intellij.xdebugger.impl.ui.XDebugSessionData;
|
||||
import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
|
||||
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
|
||||
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
|
||||
@@ -220,13 +221,9 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa
|
||||
@Override
|
||||
public void addWatchExpression(@NotNull XExpression expression, int index, final boolean navigateToWatchNode) {
|
||||
XDebugSession session = getSession(getTree());
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
myRootNode.addWatchExpression(session.getDebugProcess().getEvaluator(), expression, index, navigateToWatchNode);
|
||||
myRootNode.addWatchExpression(session != null ? session.getDebugProcess().getEvaluator() : null, expression, index, navigateToWatchNode);
|
||||
updateSessionData();
|
||||
if (navigateToWatchNode) {
|
||||
if (navigateToWatchNode && session != null) {
|
||||
showWatchesTab((XDebugSessionImpl)session);
|
||||
}
|
||||
}
|
||||
@@ -342,8 +339,15 @@ public class XWatchesViewImpl extends XDebugView implements DnDNativeTarget, XWa
|
||||
}
|
||||
|
||||
XDebugSession session = getSession(getTree());
|
||||
XExpression[] expressions = watchExpressions.toArray(new XExpression[watchExpressions.size()]);
|
||||
if (session != null) {
|
||||
((XDebugSessionImpl)session).setWatchExpressions(watchExpressions.toArray(new XExpression[watchExpressions.size()]));
|
||||
((XDebugSessionImpl)session).setWatchExpressions(expressions);
|
||||
}
|
||||
else {
|
||||
XDebugSessionData data = getData(XDebugSessionData.DATA_KEY, getTree());
|
||||
if (data != null) {
|
||||
data.setWatchExpressions(expressions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-3
@@ -188,9 +188,7 @@ public class WatchesRootNode extends XDebuggerTreeNode {
|
||||
fireNodeStructureChanged(messageNode);
|
||||
}
|
||||
XDebugSession session = XDebugView.getSession(myTree);
|
||||
if (session != null) {
|
||||
new WatchInplaceEditor(this, session, myWatchesView, messageNode, "watch", node).show();
|
||||
}
|
||||
new WatchInplaceEditor(this, session, myWatchesView, messageNode, "watch", node).show();
|
||||
}
|
||||
|
||||
private class MyEvaluationCallback extends XEvaluationCallbackBase {
|
||||
|
||||
@@ -480,49 +480,44 @@ public abstract class TestObject implements JavaCommandLine {
|
||||
return StringUtil.compare(o1.getName(), o2.getName(), true);
|
||||
}
|
||||
}) : null;
|
||||
final PrintWriter writer = new PrintWriter(myTempFile, CharsetToolkit.UTF8);
|
||||
try {
|
||||
writer.println(packageName);
|
||||
final JUnitConfiguration.Data data = myConfiguration.getPersistentData();
|
||||
final String category = data.TEST_OBJECT == JUnitConfiguration.TEST_CATEGORY ? data.getCategory() : "";
|
||||
writer.println(category);
|
||||
final List<String> testNames = new ArrayList<String>();
|
||||
for (final T element : elements) {
|
||||
final String name = nameFunction.fun(element);
|
||||
if (name == null) {
|
||||
LOG.error("invalid element " + element);
|
||||
return;
|
||||
}
|
||||
|
||||
if (perModule != null && element instanceof PsiElement) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement((PsiElement)element);
|
||||
if (module != null) {
|
||||
List<String> list = perModule.get(module);
|
||||
if (list == null) {
|
||||
list = new ArrayList<String>();
|
||||
perModule.put(module, list);
|
||||
}
|
||||
list.add(name);
|
||||
final List<String> testNames = new ArrayList<String>();
|
||||
|
||||
for (final T element : elements) {
|
||||
final String name = nameFunction.fun(element);
|
||||
if (name == null) {
|
||||
LOG.error("invalid element " + element);
|
||||
return;
|
||||
}
|
||||
|
||||
if (perModule != null && element instanceof PsiElement) {
|
||||
final Module module = ModuleUtilCore.findModuleForPsiElement((PsiElement)element);
|
||||
if (module != null) {
|
||||
List<String> list = perModule.get(module);
|
||||
if (list == null) {
|
||||
list = new ArrayList<String>();
|
||||
perModule.put(module, list);
|
||||
}
|
||||
} else {
|
||||
testNames.add(name);
|
||||
list.add(name);
|
||||
}
|
||||
}
|
||||
if (perModule != null) {
|
||||
for (List<String> perModuleClasses : perModule.values()) {
|
||||
Collections.sort(perModuleClasses);
|
||||
testNames.addAll(perModuleClasses);
|
||||
}
|
||||
} else {
|
||||
Collections.sort(testNames); //sort tests in FQN order
|
||||
}
|
||||
for (String testName : testNames) {
|
||||
writer.println(testName);
|
||||
else {
|
||||
testNames.add(name);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
if (perModule != null) {
|
||||
for (List<String> perModuleClasses : perModule.values()) {
|
||||
Collections.sort(perModuleClasses);
|
||||
testNames.addAll(perModuleClasses);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Collections.sort(testNames); //sort tests in FQN order
|
||||
}
|
||||
|
||||
final JUnitConfiguration.Data data = myConfiguration.getPersistentData();
|
||||
final String category = data.TEST_OBJECT == JUnitConfiguration.TEST_CATEGORY ? data.getCategory() : "";
|
||||
JUnitStarter.printClassesList(testNames, packageName, category, myTempFile);
|
||||
|
||||
if (perModule != null && perModule.size() > 1) {
|
||||
final PrintWriter wWriter = new PrintWriter(myWorkingDirsFile, CharsetToolkit.UTF8);
|
||||
|
||||
@@ -106,37 +106,27 @@ public class JUnitForkedStarter {
|
||||
final String packageName = perDirReader.readLine();
|
||||
String workingDir;
|
||||
while ((workingDir = perDirReader.readLine()) != null) {
|
||||
final String classpath = perDirReader.readLine();
|
||||
try {
|
||||
File tempFile = File.createTempFile("idea_junit", ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
|
||||
final FileOutputStream writer = new FileOutputStream(tempFile);
|
||||
|
||||
final String classpath = perDirReader.readLine();
|
||||
|
||||
List classNames = new ArrayList();
|
||||
try {
|
||||
final int classNamesSize = Integer.parseInt(perDirReader.readLine());
|
||||
writer.write((packageName + ", working directory: \'" + workingDir + "\'\n").getBytes("UTF-8")); //instead of package name
|
||||
writer.write("\n".getBytes("UTF-8")); //category
|
||||
for (int i = 0; i < classNamesSize; i++) {
|
||||
String className = perDirReader.readLine();
|
||||
if (className == null) {
|
||||
System.err.println("Class name is expected. Working dir: " + workingDir);
|
||||
return -1;
|
||||
}
|
||||
classNames.add(className);
|
||||
writer.write((className + "\n").getBytes("UTF-8"));
|
||||
final int classNamesSize = Integer.parseInt(perDirReader.readLine());
|
||||
for (int i = 0; i < classNamesSize; i++) {
|
||||
String className = perDirReader.readLine();
|
||||
if (className == null) {
|
||||
System.err.println("Class name is expected. Working dir: " + workingDir);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
classNames.add(className);
|
||||
}
|
||||
|
||||
final Object rootDescriptor = findByClassName(testRunner, (String)classNames.get(0), description);
|
||||
final int childResult;
|
||||
final File dir = new File(workingDir);
|
||||
if (forkMode.equals("none")) {
|
||||
File tempFile = File.createTempFile("idea_junit", ".tmp");
|
||||
tempFile.deleteOnExit();
|
||||
JUnitStarter.printClassesList(classNames, packageName + ", working directory: \'" + workingDir + "\'", "", tempFile);
|
||||
childResult =
|
||||
runChild(isJUnit4, listeners, out, err, parameters, "@" + tempFile.getAbsolutePath(), dir,
|
||||
String.valueOf(testRunner.getRegistry().getKnownObject(rootDescriptor) - 1), classpath);
|
||||
|
||||
@@ -226,4 +226,19 @@ public class JUnitStarter {
|
||||
: Class.forName("com.intellij.junit3.JUnit3IdeaTestRunner");
|
||||
|
||||
}
|
||||
|
||||
public static void printClassesList(List classNames, String packageName, String category, File tempFile) throws IOException {
|
||||
final PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream(tempFile), "UTF-8"));
|
||||
|
||||
try {
|
||||
writer.println(packageName); //package name
|
||||
writer.println(category); //category
|
||||
for (int i = 0; i < classNames.size(); i++) {
|
||||
writer.println(classNames.get(i));
|
||||
}
|
||||
}
|
||||
finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -96,7 +96,9 @@ public class CCProjectComponent implements ProjectComponent {
|
||||
}
|
||||
|
||||
public void projectClosed() {
|
||||
VirtualFileManager.getInstance().removeVirtualFileListener(myListener);
|
||||
if (myListener != null) {
|
||||
VirtualFileManager.getInstance().removeVirtualFileListener(myListener);
|
||||
}
|
||||
}
|
||||
|
||||
private class FileDeletedListener extends VirtualFileAdapter {
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
<action id="WelcomeScreen.LearnPython" class="com.jetbrains.python.edu.actions.StudyNewProject" icon="StudyIcons.EducationalProjectType">
|
||||
<add-to-group group-id="WelcomeScreen.QuickStart" relative-to-action="WelcomeScreen.PythonIntro" anchor="after"/>
|
||||
</action>
|
||||
<action id="ReloadCourseAction" class="com.jetbrains.python.edu.actions.StudyReloadCourseAction"/>
|
||||
|
||||
</actions>
|
||||
|
||||
|
||||
+121
-90
@@ -22,108 +22,139 @@ import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.*;
|
||||
import com.jetbrains.python.edu.editor.StudyEditor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class StudyRefreshTaskFileAction extends DumbAwareAction {
|
||||
private static final Logger LOG = Logger.getInstance(StudyRefreshTaskFileAction.class.getName());
|
||||
|
||||
public void refresh(final Project project) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public static void refresh(final Project project) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
@Override
|
||||
public void run() {
|
||||
final Editor editor = StudyEditor.getSelectedEditor(project);
|
||||
assert editor != null;
|
||||
final Document document = editor.getDocument();
|
||||
StudyDocumentListener listener = StudyEditor.getListener(document);
|
||||
if (listener != null) {
|
||||
document.removeDocumentListener(listener);
|
||||
}
|
||||
final int lineCount = document.getLineCount();
|
||||
if (lineCount != 0) {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
document.deleteString(0, document.getLineEndOffset(lineCount - 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
|
||||
Course course = taskManager.getCourse();
|
||||
assert course != null;
|
||||
File resourceFile = new File(course.getResourcePath());
|
||||
File resourceRoot = resourceFile.getParentFile();
|
||||
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
VirtualFile openedFile = fileDocumentManager.getFile(document);
|
||||
assert openedFile != null;
|
||||
final TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
|
||||
assert selectedTaskFile != null;
|
||||
Task currentTask = selectedTaskFile.getTask();
|
||||
String lessonDir = Lesson.LESSON_DIR + String.valueOf(currentTask.getLesson().getIndex() + 1);
|
||||
String taskDir = Task.TASK_DIR + String.valueOf(currentTask.getIndex() + 1);
|
||||
File pattern = new File(new File(new File(resourceRoot, lessonDir), taskDir), openedFile.getName());
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(pattern)));
|
||||
String line;
|
||||
StringBuilder patternText = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
patternText.append(line);
|
||||
patternText.append("\n");
|
||||
}
|
||||
int patternLength = patternText.length();
|
||||
if (patternText.charAt(patternLength - 1) == '\n') {
|
||||
patternText.delete(patternLength - 1, patternLength);
|
||||
}
|
||||
document.setText(patternText);
|
||||
StudyStatus oldStatus = currentTask.getStatus();
|
||||
LessonInfo lessonInfo = currentTask.getLesson().getLessonInfo();
|
||||
lessonInfo.update(oldStatus, -1);
|
||||
lessonInfo.update(StudyStatus.Unchecked, +1);
|
||||
StudyUtils.updateStudyToolWindow(project);
|
||||
for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) {
|
||||
taskWindow.reset();
|
||||
}
|
||||
ProjectView.getInstance(project).refresh();
|
||||
if (listener != null) {
|
||||
document.addDocumentListener(listener);
|
||||
}
|
||||
selectedTaskFile.drawAllWindows(editor);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
|
||||
}
|
||||
});
|
||||
selectedTaskFile.navigateToFirstTaskWindow(editor);
|
||||
BalloonBuilder balloonBuilder =
|
||||
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("You can now start again", MessageType.INFO, null);
|
||||
final Balloon balloon = balloonBuilder.createBalloon();
|
||||
StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
|
||||
assert selectedStudyEditor != null;
|
||||
balloon.showInCenterOf(selectedStudyEditor.getRefreshButton());
|
||||
Disposer.register(project, balloon);
|
||||
}
|
||||
catch (FileNotFoundException e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
catch (IOException e1) {
|
||||
LOG.error(e1);
|
||||
}
|
||||
finally {
|
||||
StudyUtils.closeSilently(reader);
|
||||
}
|
||||
}
|
||||
});
|
||||
final Editor editor = StudyEditor.getSelectedEditor(project);
|
||||
assert editor != null;
|
||||
final Document document = editor.getDocument();
|
||||
refreshFile(editor, document, project);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
public static void refreshFile(@NotNull final Editor editor, @NotNull final Document document, @NotNull final Project project) {
|
||||
StudyTaskManager taskManager = StudyTaskManager.getInstance(project);
|
||||
Course course = taskManager.getCourse();
|
||||
assert course != null;
|
||||
FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
|
||||
VirtualFile openedFile = fileDocumentManager.getFile(document);
|
||||
assert openedFile != null;
|
||||
final TaskFile selectedTaskFile = taskManager.getTaskFile(openedFile);
|
||||
assert selectedTaskFile != null;
|
||||
String openedFileName = openedFile.getName();
|
||||
Task currentTask = selectedTaskFile.getTask();
|
||||
resetTaskFile(document, project, course, selectedTaskFile, openedFileName, currentTask);
|
||||
selectedTaskFile.drawAllWindows(editor);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IdeFocusManager.getInstance(project).requestFocus(editor.getContentComponent(), true);
|
||||
}
|
||||
});
|
||||
selectedTaskFile.navigateToFirstTaskWindow(editor);
|
||||
showBaloon(project);
|
||||
}
|
||||
|
||||
public static void resetTaskFile(Document document, Project project, Course course, TaskFile taskFile, String name, Task task) {
|
||||
resetDocument(document, course, name, task);
|
||||
updateLessonInfo(task);
|
||||
StudyUtils.updateStudyToolWindow(project);
|
||||
resetTaskWindows(taskFile);
|
||||
ProjectView.getInstance(project).refresh();
|
||||
}
|
||||
|
||||
private static void showBaloon(Project project) {
|
||||
BalloonBuilder balloonBuilder =
|
||||
JBPopupFactory.getInstance().createHtmlTextBalloonBuilder("You can now start again", MessageType.INFO, null);
|
||||
final Balloon balloon = balloonBuilder.createBalloon();
|
||||
StudyEditor selectedStudyEditor = StudyEditor.getSelectedStudyEditor(project);
|
||||
assert selectedStudyEditor != null;
|
||||
balloon.showInCenterOf(selectedStudyEditor.getRefreshButton());
|
||||
Disposer.register(project, balloon);
|
||||
}
|
||||
|
||||
private static void resetTaskWindows(TaskFile selectedTaskFile) {
|
||||
for (TaskWindow taskWindow : selectedTaskFile.getTaskWindows()) {
|
||||
taskWindow.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateLessonInfo(Task currentTask) {
|
||||
StudyStatus oldStatus = currentTask.getStatus();
|
||||
LessonInfo lessonInfo = currentTask.getLesson().getLessonInfo();
|
||||
lessonInfo.update(oldStatus, -1);
|
||||
lessonInfo.update(StudyStatus.Unchecked, +1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
|
||||
private static void resetDocument(Document document, Course course, String fileName, Task task) {
|
||||
BufferedReader reader = null;
|
||||
StudyDocumentListener listener = StudyEditor.getListener(document);
|
||||
if (listener != null) {
|
||||
document.removeDocumentListener(listener);
|
||||
}
|
||||
clearDocument(document);
|
||||
try {
|
||||
String lessonDir = Lesson.LESSON_DIR + String.valueOf(task.getLesson().getIndex() + 1);
|
||||
String taskDir = Task.TASK_DIR + String.valueOf(task.getIndex() + 1);
|
||||
File resourceFile = new File(course.getResourcePath());
|
||||
File resourceRoot = resourceFile.getParentFile();
|
||||
File pattern = new File(new File(new File(resourceRoot, lessonDir), taskDir), fileName);
|
||||
reader = new BufferedReader(new InputStreamReader(new FileInputStream(pattern)));
|
||||
String line;
|
||||
StringBuilder patternText = new StringBuilder();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
patternText.append(line);
|
||||
patternText.append("\n");
|
||||
}
|
||||
int patternLength = patternText.length();
|
||||
if (patternText.charAt(patternLength - 1) == '\n') {
|
||||
patternText.delete(patternLength - 1, patternLength);
|
||||
}
|
||||
document.setText(patternText);
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
finally {
|
||||
StudyUtils.closeSilently(reader);
|
||||
}
|
||||
if (listener != null) {
|
||||
document.addDocumentListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
private static void clearDocument(final Document document) {
|
||||
final int lineCount = document.getLineCount();
|
||||
if (lineCount != 0) {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
document.deleteString(0, document.getLineEndOffset(lineCount - 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
refresh(e.getProject());
|
||||
}
|
||||
}
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.jetbrains.python.edu.actions;
|
||||
|
||||
import com.intellij.ide.projectView.ProjectView;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.StudyUtils;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.python.edu.course.Lesson;
|
||||
import com.jetbrains.python.edu.course.Task;
|
||||
import com.jetbrains.python.edu.course.TaskFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class StudyReloadCourseAction extends DumbAwareAction {
|
||||
|
||||
public StudyReloadCourseAction() {
|
||||
super("Reload Course", "Reload Course", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
Presentation presentation = e.getPresentation();
|
||||
Project project = e.getProject();
|
||||
if (project != null) {
|
||||
Course course = StudyTaskManager.getInstance(project).getCourse();
|
||||
if (course != null) {
|
||||
presentation.setVisible(true);
|
||||
presentation.setEnabled(true);
|
||||
}
|
||||
}
|
||||
presentation.setVisible(false);
|
||||
presentation.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
Project project = e.getProject();
|
||||
if (project == null) {
|
||||
return;
|
||||
}
|
||||
reloadCourse(project);
|
||||
}
|
||||
|
||||
public static void reloadCourse(@NotNull final Project project) {
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Course course = StudyTaskManager.getInstance(project).getCourse();
|
||||
if (course == null) {
|
||||
return;
|
||||
}
|
||||
for (VirtualFile file : FileEditorManager.getInstance(project).getOpenFiles()) {
|
||||
FileEditorManager.getInstance(project).closeFile(file);
|
||||
}
|
||||
JTree tree = ProjectView.getInstance(project).getCurrentProjectViewPane().getTree();
|
||||
TreePath path = TreeUtil.getFirstNodePath(tree);
|
||||
tree.collapsePath(path);
|
||||
List<Lesson> lessons = course.getLessons();
|
||||
for (Lesson lesson : lessons) {
|
||||
List<Task> tasks = lesson.getTaskList();
|
||||
VirtualFile lessonDir = project.getBaseDir().findChild(Lesson.LESSON_DIR + (lesson.getIndex() + 1));
|
||||
if (lessonDir == null) {
|
||||
continue;
|
||||
}
|
||||
for (Task task : tasks) {
|
||||
VirtualFile taskDir = lessonDir.findChild(Task.TASK_DIR + (task.getIndex() + 1));
|
||||
if (taskDir == null) {
|
||||
continue;
|
||||
}
|
||||
Map<String, TaskFile> taskFiles = task.getTaskFiles();
|
||||
for (Map.Entry<String, TaskFile> entry : taskFiles.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
TaskFile taskFile = entry.getValue();
|
||||
VirtualFile file = taskDir.findChild(name);
|
||||
if (file == null) {
|
||||
continue;
|
||||
}
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
if (document == null) {
|
||||
continue;
|
||||
}
|
||||
StudyRefreshTaskFileAction.resetTaskFile(document, project, course, taskFile, name, task);
|
||||
}
|
||||
}
|
||||
}
|
||||
Lesson firstLesson = StudyUtils.getFirst(lessons);
|
||||
if (firstLesson == null) {
|
||||
return;
|
||||
}
|
||||
Task firstTask = StudyUtils.getFirst(firstLesson.getTaskList());
|
||||
VirtualFile lessonDir = project.getBaseDir().findChild(Lesson.LESSON_DIR + (firstLesson.getIndex() + 1));
|
||||
if (lessonDir != null) {
|
||||
VirtualFile taskDir = lessonDir.findChild(Task.TASK_DIR + (firstTask.getIndex() + 1));
|
||||
if (taskDir != null) {
|
||||
ProjectView.getInstance(project).select(taskDir, taskDir, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentFactory;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.jetbrains.python.edu.StudyTaskManager;
|
||||
import com.jetbrains.python.edu.actions.StudyReloadCourseAction;
|
||||
import com.jetbrains.python.edu.course.Course;
|
||||
import com.jetbrains.python.edu.course.Lesson;
|
||||
import com.jetbrains.python.edu.course.LessonInfo;
|
||||
@@ -17,6 +18,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
|
||||
public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
|
||||
@@ -41,7 +44,15 @@ public class StudyToolWindowFactory implements ToolWindowFactory, DumbAware {
|
||||
contentPanel.add(new JLabel(authorLabel));
|
||||
contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
contentPanel.add(new JLabel(description));
|
||||
contentPanel.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
JButton reloadCourseButton = new JButton("reload course");
|
||||
reloadCourseButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
StudyReloadCourseAction.reloadCourse(project);
|
||||
}
|
||||
});
|
||||
|
||||
contentPanel.add(reloadCourseButton);
|
||||
int taskNum = 0;
|
||||
int taskSolved = 0;
|
||||
int lessonsCompleted = 0;
|
||||
|
||||
Reference in New Issue
Block a user