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:
-1
@@ -111,7 +111,6 @@ public class AnalyzeDependenciesComponent extends MasterDetailsComponent {
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
if (myMessageBusConnection != null) {
|
||||
myMessageBusConnection.dispose();
|
||||
myMessageBusConnection.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
+18
-1
@@ -43,6 +43,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.TreeCellRenderer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
@@ -83,7 +84,23 @@ public class FacetStructureConfigurable extends BaseStructureConfigurable {
|
||||
super.initTree();
|
||||
if (!myTreeWasInitialized) {
|
||||
myTreeWasInitialized = true;
|
||||
myTree.setCellRenderer(new FacetsTreeCellRenderer());
|
||||
final FacetsTreeCellRenderer separatorRenderer = new FacetsTreeCellRenderer();
|
||||
final TreeCellRenderer oldRenderer = myTree.getCellRenderer();
|
||||
myTree.setCellRenderer(new TreeCellRenderer() {
|
||||
@Override
|
||||
public Component getTreeCellRendererComponent(JTree tree,
|
||||
Object value,
|
||||
boolean selected,
|
||||
boolean expanded,
|
||||
boolean leaf,
|
||||
int row,
|
||||
boolean hasFocus) {
|
||||
if (value instanceof MyNode && ((MyNode)value).getConfigurable() instanceof FrameworkDetectionConfigurable) {
|
||||
return separatorRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
}
|
||||
return oldRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
|
||||
}
|
||||
});
|
||||
myTree.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentResized(ComponentEvent e) {
|
||||
|
||||
+3
-2
@@ -57,14 +57,15 @@ public class FacetsTreeCellRenderer extends GroupedElementsRenderer.Tree impleme
|
||||
final boolean showSeparator = configurable instanceof FrameworkDetectionConfigurable;
|
||||
int width = -1;
|
||||
if (showSeparator && tree.isVisible()) {
|
||||
final int treeWidth = tree.getVisibleRect().width - 4;
|
||||
final int treeWidth = tree.getVisibleRect().width;
|
||||
if (treeWidth > 0) {
|
||||
width = treeWidth;
|
||||
}
|
||||
}
|
||||
final JComponent component = configureComponent(node.getDisplayName(), null, icon, icon, selected, showSeparator, null,
|
||||
width);
|
||||
myTextLabel.setOpaque(true);
|
||||
|
||||
myTextLabel.setOpaque(selected);
|
||||
return component;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,9 +178,10 @@ public class VisibilityInspection extends GlobalJavaInspectionTool {
|
||||
}
|
||||
@Modifier String access = getPossibleAccess(refElement);
|
||||
if (access != refElement.getAccessModifier() && access != null) {
|
||||
final PsiElement psiElement = HighlightUsagesHandler.getNameIdentifier(refElement.getElement());
|
||||
if (psiElement != null) {
|
||||
return new ProblemDescriptor[]{manager.createProblemDescriptor(psiElement,
|
||||
final PsiElement element = refElement.getElement();
|
||||
final PsiElement nameIdentifier = element != null ? HighlightUsagesHandler.getNameIdentifier(element) : null;
|
||||
if (nameIdentifier != null) {
|
||||
return new ProblemDescriptor[]{manager.createProblemDescriptor(nameIdentifier,
|
||||
access.equals(PsiModifier.PRIVATE)
|
||||
? CAN_BE_PRIVATE
|
||||
: access.equals(PsiModifier.PACKAGE_LOCAL)
|
||||
|
||||
@@ -128,9 +128,7 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
|
||||
if (classes != null) {
|
||||
topLevelClasses = ArrayUtil.mergeArrays(classes, topLevelClasses, PsiClass.ARRAY_FACTORY);
|
||||
}
|
||||
if (topLevelClasses != null) {
|
||||
result.put(containingFile, topLevelClasses);
|
||||
}
|
||||
result.put(containingFile, topLevelClasses);
|
||||
}
|
||||
|
||||
public void doCopy(PsiElement[] elements, PsiDirectory defaultTargetDirectory) {
|
||||
@@ -361,19 +359,26 @@ public class CopyClassesHandler extends CopyHandlerDelegateBase {
|
||||
}
|
||||
|
||||
private static PsiFile copy(@NotNull PsiFile file, PsiDirectory directory, String name, String relativePath) {
|
||||
final String fileName;
|
||||
if (name != null) {
|
||||
fileName = file instanceof PsiClassOwner ? name + "." + file.getViewProvider().getVirtualFile().getExtension() : name;
|
||||
}
|
||||
else {
|
||||
fileName = file.getName();
|
||||
}
|
||||
final String fileName = getNewFileName(file, name);
|
||||
if (relativePath != null && !relativePath.isEmpty()) {
|
||||
return buildRelativeDir(directory, relativePath).findOrCreateTargetDirectory().copyFileFrom(fileName, file);
|
||||
}
|
||||
return directory.copyFileFrom(fileName, file);
|
||||
}
|
||||
|
||||
private static String getNewFileName(PsiFile file, String name) {
|
||||
if (name != null) {
|
||||
if (file instanceof PsiClassOwner) {
|
||||
final PsiClass[] classes = ((PsiClassOwner)file).getClasses();
|
||||
if (classes.length > 0 && !(classes[0] instanceof SyntheticElement)) {
|
||||
return name + "." + file.getViewProvider().getVirtualFile().getExtension();
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static MoveDirectoryWithClassesProcessor.TargetDirectoryWrapper buildRelativeDir(final @NotNull PsiDirectory directory,
|
||||
final @NotNull String relativePath) {
|
||||
|
||||
+1
@@ -128,6 +128,7 @@ public abstract class DestinationFolderComboBox extends ComboboxWithBrowseButton
|
||||
DirectoryChooser.ItemWrapper item = (DirectoryChooser.ItemWrapper)model.getElementAt(i);
|
||||
if (item != null && fileIndex.getSourceRootForFile(item.getDirectory().getVirtualFile()) == root) {
|
||||
getComboBox().setSelectedItem(item);
|
||||
getComboBox().repaint();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,15 +179,16 @@ public class JavaResolveUtil {
|
||||
final ResolveState state,
|
||||
final PsiElement place,
|
||||
PsiManager manager) {
|
||||
PsiPackage defaultPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage("");
|
||||
if (defaultPackage != null) {
|
||||
if (!defaultPackage.processDeclarations(processor, state, null, place)) return false;
|
||||
}
|
||||
|
||||
PsiPackage langPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage(CommonClassNames.DEFAULT_PACKAGE);
|
||||
if (langPackage != null) {
|
||||
if (!langPackage.processDeclarations(processor, state, null, place)) return false;
|
||||
}
|
||||
|
||||
PsiPackage defaultPackage = JavaPsiFacade.getInstance(manager.getProject()).findPackage("");
|
||||
if (defaultPackage != null) {
|
||||
if (!defaultPackage.processDeclarations(processor, state, null, place)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import java.util.*;
|
||||
|
||||
public class Runner {
|
||||
public static void main(String[] args) {
|
||||
List<Process> src;
|
||||
List<Process> dest = ListUtils.filter(src, new <caret>);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import java.util.*;
|
||||
|
||||
public class Runner {
|
||||
public static void main(String[] args) {
|
||||
List<Process> src;
|
||||
List<Process> dest = ListUtils.filter(src, new Pred<Process>() {
|
||||
@Override
|
||||
public boolean predicate(Process elem) {
|
||||
<selection><caret>return false; //To change body of implemented methods use File | Settings | File Templates.</selection>
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
+15
@@ -478,6 +478,21 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase {
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testAnonymousProcess() {
|
||||
myFixture.addClass 'package java.lang; public class Process {}'
|
||||
myFixture.addClass '''
|
||||
import java.util.*;
|
||||
public class Process {}
|
||||
interface Pred <A> { boolean predicate(A elem); }
|
||||
public class ListUtils {
|
||||
public static <A> List<A> filter(List<A> list, Pred<A> pred) {}
|
||||
}
|
||||
'''
|
||||
configure()
|
||||
type '\n'
|
||||
checkResult()
|
||||
}
|
||||
|
||||
public void testNoThisInComment() throws Throwable { doAntiTest() }
|
||||
|
||||
public void testLastExpressionInFor() throws Throwable { doTest(); }
|
||||
|
||||
@@ -21,12 +21,14 @@ import com.intellij.ide.structureView.StructureView;
|
||||
import com.intellij.ide.structureView.StructureViewBuilder;
|
||||
import com.intellij.ide.structureView.StructureViewModel;
|
||||
import com.intellij.ide.util.FileStructureDialog;
|
||||
import com.intellij.ide.util.FileStructurePopup;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
@@ -55,13 +57,24 @@ public class ViewStructureAction extends AnAction {
|
||||
FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.popup.file.structure");
|
||||
|
||||
Navigatable navigatable = e.getData(PlatformDataKeys.NAVIGATABLE);
|
||||
DialogWrapper dialog = createDialog(editor, project, navigatable, fileEditor);
|
||||
if (dialog != null) {
|
||||
final VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
dialog.setTitle(virtualFile.getName());
|
||||
if (Registry.is("file.structure.tree.mode")) {
|
||||
FileStructurePopup popup = createPopup(editor, project, navigatable, fileEditor);
|
||||
if (popup != null) {
|
||||
final VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
popup.setTitle(virtualFile.getName());
|
||||
}
|
||||
popup.show();
|
||||
}
|
||||
} else {
|
||||
DialogWrapper dialog = createDialog(editor, project, navigatable, fileEditor);
|
||||
if (dialog != null) {
|
||||
final VirtualFile virtualFile = psiFile.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
dialog.setTitle(virtualFile.getName());
|
||||
}
|
||||
dialog.show();
|
||||
}
|
||||
dialog.show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +85,14 @@ public class ViewStructureAction extends AnAction {
|
||||
StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project);
|
||||
return createStructureViewBasedDialog(structureView.getTreeModel(), editor, project, navigatable, structureView);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static FileStructurePopup createPopup(final Editor editor, Project project, Navigatable navigatable, final FileEditor fileEditor) {
|
||||
final StructureViewBuilder structureViewBuilder = fileEditor.getStructureViewBuilder();
|
||||
if (structureViewBuilder == null) return null;
|
||||
StructureView structureView = structureViewBuilder.createStructureView(fileEditor, project);
|
||||
return createStructureViewPopup(structureView.getTreeModel(), editor, project, navigatable, structureView);
|
||||
}
|
||||
|
||||
public static FileStructureDialog createStructureViewBasedDialog(final StructureViewModel structureViewModel,
|
||||
final Editor editor,
|
||||
@@ -80,7 +101,14 @@ public class ViewStructureAction extends AnAction {
|
||||
final @NotNull Disposable alternativeDisposable) {
|
||||
return new FileStructureDialog(structureViewModel, editor, project, navigatable, alternativeDisposable, true);
|
||||
}
|
||||
|
||||
public static FileStructurePopup createStructureViewPopup(final StructureViewModel structureViewModel,
|
||||
final Editor editor,
|
||||
final Project project,
|
||||
final Navigatable navigatable,
|
||||
final @NotNull Disposable alternativeDisposable) {
|
||||
return new FileStructurePopup(structureViewModel, editor, project, navigatable, alternativeDisposable, true);
|
||||
}
|
||||
|
||||
public void update(AnActionEvent event) {
|
||||
Presentation presentation = event.getPresentation();
|
||||
DataContext dataContext = event.getDataContext();
|
||||
|
||||
@@ -373,39 +373,8 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
|
||||
}
|
||||
|
||||
public void installActions(final int index, final NavBarItem component) {
|
||||
DnDSupport.createBuilder(component)
|
||||
.setBeanProvider(new Function<DnDActionInfo, DnDDragStartBean>() {
|
||||
@Override
|
||||
public DnDDragStartBean fun(DnDActionInfo dnDActionInfo) {
|
||||
return new DnDDragStartBean(new TransferableWrapper() {
|
||||
@Override
|
||||
public List<File> asFileList() {
|
||||
final Object o = myModel.get(index);
|
||||
if (o instanceof PsiElement) {
|
||||
final VirtualFile vf = o instanceof PsiDirectory ? ((PsiDirectory)o).getVirtualFile()
|
||||
: ((PsiElement)o).getContainingFile().getVirtualFile();
|
||||
if (vf != null) {
|
||||
return Arrays.asList(new File(vf.getPath()).getAbsoluteFile());
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeNode[] getTreeNodes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement[] getPsiElements() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.setDisposableParent(component)
|
||||
.install();
|
||||
|
||||
//suppress it for a while
|
||||
//installDnD(index, component);
|
||||
|
||||
ListenerUtil.addMouseListener(component, new MouseAdapter() {
|
||||
public void mouseReleased(final MouseEvent e) {
|
||||
@@ -446,6 +415,41 @@ public class NavBarPanel extends JPanel implements DataProvider, PopupOwner, Dis
|
||||
});
|
||||
}
|
||||
|
||||
private void installDnD(final int index, NavBarItem component) {
|
||||
DnDSupport.createBuilder(component)
|
||||
.setBeanProvider(new Function<DnDActionInfo, DnDDragStartBean>() {
|
||||
@Override
|
||||
public DnDDragStartBean fun(DnDActionInfo dnDActionInfo) {
|
||||
return new DnDDragStartBean(new TransferableWrapper() {
|
||||
@Override
|
||||
public List<File> asFileList() {
|
||||
final Object o = myModel.get(index);
|
||||
if (o instanceof PsiElement) {
|
||||
final VirtualFile vf = o instanceof PsiDirectory ? ((PsiDirectory)o).getVirtualFile()
|
||||
: ((PsiElement)o).getContainingFile().getVirtualFile();
|
||||
if (vf != null) {
|
||||
return Arrays.asList(new File(vf.getPath()).getAbsoluteFile());
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TreeNode[] getTreeNodes() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement[] getPsiElements() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.setDisposableParent(component)
|
||||
.install();
|
||||
}
|
||||
|
||||
private void doubleClick(final int index) {
|
||||
doubleClick(myModel.getElement(index));
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
|
||||
class StructureTreeBuilder extends AbstractTreeBuilder {
|
||||
public class StructureTreeBuilder extends AbstractTreeBuilder {
|
||||
private final Project myProject;
|
||||
private final StructureViewModel myStructureModel;
|
||||
|
||||
|
||||
+2
-2
@@ -733,7 +733,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
|
||||
}
|
||||
|
||||
//todo [kirillk] dirty hack for discovering invalid psi elements, to delegate it to a proper place after 8.1
|
||||
private static boolean isValid(Object treeElement) {
|
||||
public static boolean isValid(Object treeElement) {
|
||||
if (treeElement instanceof StructureViewTreeElementWrapper) {
|
||||
final StructureViewTreeElementWrapper wrapper = (StructureViewTreeElementWrapper)treeElement;
|
||||
if (wrapper.getValue() instanceof PsiTreeElementBase) {
|
||||
@@ -744,7 +744,7 @@ public class StructureViewComponent extends SimpleToolWindowPanel implements Tre
|
||||
return true;
|
||||
}
|
||||
|
||||
static class StructureViewTreeElementWrapper extends TreeElementWrapper implements NodeDescriptorProvidingKey {
|
||||
public static class StructureViewTreeElementWrapper extends TreeElementWrapper implements NodeDescriptorProvidingKey {
|
||||
private long childrenStamp = -1;
|
||||
private long modificationCountForChildren = ourSettingsModificationCount;
|
||||
|
||||
|
||||
@@ -16,20 +16,28 @@
|
||||
|
||||
package com.intellij.ide.util;
|
||||
|
||||
import com.intellij.ide.util.gotoByName.ChooseByNamePanel;
|
||||
import com.intellij.ide.util.gotoByName.ChooseByNamePopupComponent;
|
||||
import com.intellij.ide.util.gotoByName.GotoClassModel2;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.FileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.TabbedPaneWrapper;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
@@ -51,6 +59,9 @@ public class DirectoryChooser extends DialogWrapper {
|
||||
private boolean myFilterExisting;
|
||||
private PsiDirectory myDefaultSelection;
|
||||
private List<ItemWrapper> myItems = new ArrayList<ItemWrapper>();
|
||||
private PsiElement mySelection;
|
||||
private final TabbedPaneWrapper myTabbedPaneWrapper;
|
||||
private final ChooseByNamePanel myChooseByNamePanel;
|
||||
|
||||
public DirectoryChooser(Project project){
|
||||
this(project, new DirectoryChooserModuleTreeView(project));
|
||||
@@ -61,12 +72,40 @@ public class DirectoryChooser extends DialogWrapper {
|
||||
myView = view;
|
||||
final PropertiesComponent propertiesComponent = PropertiesComponent.getInstance();
|
||||
myFilterExisting = propertiesComponent.isValueSet(FILTER_NON_EXISTING) && propertiesComponent.isTrueValue(FILTER_NON_EXISTING);
|
||||
myTabbedPaneWrapper = new TabbedPaneWrapper(getDisposable());
|
||||
myChooseByNamePanel = new ChooseByNamePanel(project, new GotoClassModel2(project){
|
||||
@Override
|
||||
public String[] getNames(boolean checkBoxState) {
|
||||
return super.getNames(false);
|
||||
}
|
||||
}, "", false, null) {
|
||||
protected void showTextFieldPanel() {
|
||||
}
|
||||
|
||||
protected void close(boolean isOk) {
|
||||
super.close(isOk);
|
||||
if (isOk) {
|
||||
final List<Object> elements = getChosenElements();
|
||||
if (elements != null && elements.size() > 0) {
|
||||
myActionListener.elementChosen(elements.get(0));
|
||||
}
|
||||
doOKAction();
|
||||
}
|
||||
else {
|
||||
doCancelAction();
|
||||
}
|
||||
}
|
||||
};
|
||||
Disposer.register(myDisposable, myChooseByNamePanel);
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
PropertiesComponent.getInstance().setValue(FILTER_NON_EXISTING, String.valueOf(myFilterExisting));
|
||||
if (myTabbedPaneWrapper.getSelectedIndex() == 1) {
|
||||
setSelection(myChooseByNamePanel.getChosenElement());
|
||||
}
|
||||
super.doOKAction();
|
||||
}
|
||||
|
||||
@@ -93,7 +132,23 @@ public class DirectoryChooser extends DialogWrapper {
|
||||
|
||||
installEnterAction(component);
|
||||
panel.add(jScrollPane, BorderLayout.CENTER);
|
||||
return panel;
|
||||
myTabbedPaneWrapper.addTab("Directory Structure", panel);
|
||||
|
||||
myChooseByNamePanel.invoke(new ChooseByNamePopupComponent.Callback() {
|
||||
@Override
|
||||
public void elementChosen(Object element) {
|
||||
setSelection(element);
|
||||
}
|
||||
}, ModalityState.stateForComponent(getRootPane()), false);
|
||||
myTabbedPaneWrapper.addTab("Choose By Neighbor Class", myChooseByNamePanel.getPanel());
|
||||
|
||||
return myTabbedPaneWrapper.getComponent();
|
||||
}
|
||||
|
||||
private void setSelection(Object element) {
|
||||
if (element instanceof PsiElement) {
|
||||
mySelection = (PsiElement)element;
|
||||
}
|
||||
}
|
||||
|
||||
private void installEnterAction(final JComponent component) {
|
||||
@@ -396,6 +451,12 @@ public class DirectoryChooser extends DialogWrapper {
|
||||
|
||||
@Nullable
|
||||
public PsiDirectory getSelectedDirectory() {
|
||||
if (mySelection != null) {
|
||||
final PsiFile file = mySelection.getContainingFile();
|
||||
if (file != null){
|
||||
return file.getContainingDirectory();
|
||||
}
|
||||
}
|
||||
ItemWrapper wrapper = myView.getSelectedItem();
|
||||
if (wrapper == null) return null;
|
||||
return wrapper.myDirectory;
|
||||
|
||||
@@ -0,0 +1,599 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.ide.util;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.commander.CommanderPanel;
|
||||
import com.intellij.ide.commander.ProjectListBuilder;
|
||||
import com.intellij.ide.structureView.StructureViewBuilder;
|
||||
import com.intellij.ide.structureView.StructureViewModel;
|
||||
import com.intellij.ide.structureView.StructureViewTreeElement;
|
||||
import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
|
||||
import com.intellij.ide.structureView.newStructureView.StructureTreeBuilder;
|
||||
import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
|
||||
import com.intellij.ide.structureView.newStructureView.TreeActionsOwner;
|
||||
import com.intellij.ide.structureView.newStructureView.TreeModelWrapper;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.ide.util.treeView.smartTree.*;
|
||||
import com.intellij.lang.LanguageStructureViewBuilder;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.MnemonicHelper;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
|
||||
import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.ListScrollingUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.SpeedSearchBase;
|
||||
import com.intellij.ui.TreeSpeedSearch;
|
||||
import com.intellij.ui.docking.DockManager;
|
||||
import com.intellij.ui.speedSearch.SpeedSearchSupply;
|
||||
import com.intellij.ui.treeStructure.Tree;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class FileStructurePopup implements Disposable {
|
||||
private final Editor myEditor;
|
||||
private final Navigatable myNavigatable;
|
||||
private final Project myProject;
|
||||
private final StructureViewModel myTreeModel;
|
||||
private final StructureViewModel myBaseTreeModel;
|
||||
@NotNull private final Disposable myDisposable;
|
||||
private final MyTreeActionsOwner myTreeActionsOwner;
|
||||
private JBPopup myPopup;
|
||||
|
||||
@NonNls private static final String ourPropertyKey = "FileStructure.narrowDown";
|
||||
private boolean myShouldNarrowDown = false;
|
||||
private Tree myTree;
|
||||
private AbstractTreeBuilder myAbstractTreeBuilder;
|
||||
private String myTitle;
|
||||
private TreeSpeedSearch mySpeedSearch;
|
||||
private HashSet<TreeElement> myVisibleElements = new HashSet<TreeElement>();
|
||||
private Filter mySearchFilter = new Filter() {
|
||||
@Override
|
||||
public boolean isVisible(TreeElement treeNode) {
|
||||
if (mySpeedSearch != null && myShouldNarrowDown && !StringUtil.isEmpty(mySpeedSearch.getEnteredPrefix())) {
|
||||
|
||||
if (myVisibleElements.contains(treeNode)) return true;
|
||||
ItemPresentation presentation = treeNode.getPresentation();
|
||||
if (presentation == null) return true;
|
||||
String text = presentation.getPresentableText();
|
||||
if (text == null) return true;
|
||||
Iterable<TextRange> ranges = mySpeedSearch.matchingFragments(text);
|
||||
if (ranges == null) return true;
|
||||
Iterator<TextRange> iterator = ranges.iterator();
|
||||
boolean contains = iterator.hasNext();
|
||||
if (contains) {
|
||||
myVisibleElements.add(treeNode);
|
||||
return true;
|
||||
}
|
||||
for (TreeElement child : treeNode.getChildren()) {
|
||||
if (isVisible(child)) {
|
||||
myVisibleElements.add(treeNode);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReverted() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ActionPresentation getPresentation() {
|
||||
return new ActionPresentationData("", "", null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Narrow Down";
|
||||
}
|
||||
};
|
||||
|
||||
public FileStructurePopup(StructureViewModel structureViewModel,
|
||||
@Nullable Editor editor,
|
||||
Project project,
|
||||
Navigatable navigatable,
|
||||
@NotNull final Disposable auxDisposable,
|
||||
final boolean applySortAndFilter) {
|
||||
myProject = project;
|
||||
myEditor = editor;
|
||||
myNavigatable = navigatable;
|
||||
myBaseTreeModel = structureViewModel;
|
||||
myDisposable = auxDisposable;
|
||||
if (applySortAndFilter) {
|
||||
myTreeActionsOwner = new MyTreeActionsOwner();
|
||||
myTreeModel = new TreeModelWrapper(structureViewModel, myTreeActionsOwner) {
|
||||
@NotNull
|
||||
@Override
|
||||
public Filter[] getFilters() {
|
||||
return ArrayUtil.append(super.getFilters(), mySearchFilter);
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
myTreeActionsOwner = null;
|
||||
myTreeModel = structureViewModel;
|
||||
}
|
||||
|
||||
PsiFile psiFile = getPsiFile(project);
|
||||
|
||||
final PsiElement psiElement = getCurrentElement(psiFile);
|
||||
|
||||
//myDialog.setUndecorated(true);
|
||||
|
||||
if (psiElement != null) {
|
||||
if (structureViewModel.shouldEnterElement(psiElement)) {
|
||||
//myCommanderPanel.getBuilder().enterElement(psiElement, PsiUtilBase.getVirtualFile(psiElement));
|
||||
}
|
||||
else {
|
||||
//myCommanderPanel.getBuilder().selectElement(psiElement, PsiUtilBase.getVirtualFile(psiElement));
|
||||
}
|
||||
}
|
||||
|
||||
SmartTreeStructure treeStructure = new SmartTreeStructure(project, myTreeModel){
|
||||
public void rebuildTree() {
|
||||
if (!myPopup.isDisposed()) {
|
||||
super.rebuildTree();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isToBuildChildrenInBackground(final Object element) {
|
||||
return getRootElement() == element;
|
||||
}
|
||||
|
||||
protected TreeElementWrapper createTree() {
|
||||
return new StructureViewComponent.StructureViewTreeElementWrapper(myProject, myModel.getRoot(), myModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "structure view tree structure(model=" + myTreeModel + ")";
|
||||
}
|
||||
};
|
||||
|
||||
final DefaultTreeModel model = new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.getRootElement()));
|
||||
myTree = new Tree(model);
|
||||
myTree.setRootVisible(false);
|
||||
myTree.setShowsRootHandles(true);
|
||||
|
||||
myAbstractTreeBuilder = new StructureTreeBuilder(project, myTree,
|
||||
(DefaultTreeModel)myTree.getModel(),treeStructure, myTreeModel) {
|
||||
@Override
|
||||
protected boolean validateNode(Object child) {
|
||||
return StructureViewComponent.isValid(child);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void show() {
|
||||
final JComponent panel = createCenterPanel();
|
||||
new MnemonicHelper().register(panel);
|
||||
myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(panel, null)
|
||||
.setTitle(myTitle)
|
||||
.setResizable(true)
|
||||
.setFocusable(true)
|
||||
.setMovable(true)
|
||||
.setDimensionServiceKey(null, getDimensionServiceKey(), false)
|
||||
.createPopup();
|
||||
Disposer.register(myPopup, myDisposable);
|
||||
Disposer.register(myPopup, this);
|
||||
Disposer.register(myPopup, myAbstractTreeBuilder);
|
||||
myPopup.showInCenterOf(myEditor.getContentComponent());
|
||||
mySpeedSearch = new TreeSpeedSearch(myTree, TreeSpeedSearch.NODE_DESCRIPTOR_TOSTRING, true);
|
||||
mySpeedSearch.addChangeListener(new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
myVisibleElements.clear();
|
||||
myAbstractTreeBuilder.queueUpdate();
|
||||
|
||||
}
|
||||
});
|
||||
myAbstractTreeBuilder.expandAll(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
IdeFocusManager.getInstance(myProject).requestFocus(myTree, true);
|
||||
myAbstractTreeBuilder.queueUpdate().doWhenDone(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myAbstractTreeBuilder.expandAll(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
protected PsiFile getPsiFile(final Project project) {
|
||||
return PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Border createContentPaneBorder() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
protected String getDimensionServiceKey() {
|
||||
return DockManager.getInstance(myProject).getDimensionKeyForFocus("#com.intellij.ide.util.FileStructureDialog");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected PsiElement getCurrentElement(@Nullable final PsiFile psiFile) {
|
||||
if (psiFile == null) return null;
|
||||
|
||||
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
|
||||
|
||||
Object elementAtCursor = myTreeModel.getCurrentEditorElement();
|
||||
if (elementAtCursor instanceof PsiElement) {
|
||||
return (PsiElement)elementAtCursor;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
List<FileStructureFilter> fileStructureFilters = new ArrayList<FileStructureFilter>();
|
||||
List<FileStructureNodeProvider> fileStructureNodeProviders = new ArrayList<FileStructureNodeProvider>();
|
||||
if (myTreeActionsOwner != null) {
|
||||
for(Filter filter: myBaseTreeModel.getFilters()) {
|
||||
if (filter instanceof FileStructureFilter) {
|
||||
final FileStructureFilter fsFilter = (FileStructureFilter)filter;
|
||||
myTreeActionsOwner.setActionIncluded(fsFilter, true);
|
||||
fileStructureFilters.add(fsFilter);
|
||||
}
|
||||
}
|
||||
|
||||
if (myBaseTreeModel instanceof ProvidingTreeModel) {
|
||||
for (NodeProvider provider : ((ProvidingTreeModel)myBaseTreeModel).getNodeProviders()) {
|
||||
if (provider instanceof FileStructureNodeProvider) {
|
||||
fileStructureNodeProviders.add((FileStructureNodeProvider)provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//new AnAction() {
|
||||
// public void actionPerformed(AnActionEvent e) {
|
||||
// final boolean succeeded = myCommanderPanel.navigateSelectedElement();
|
||||
// if (succeeded) {
|
||||
// unregisterCustomShortcutSet(myCommanderPanel);
|
||||
// }
|
||||
// }
|
||||
//}.registerCustomShortcutSet(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE).getShortcutSet(), myCommanderPanel);
|
||||
|
||||
//myCommanderPanel.setPreferredSize(new Dimension(400, 500));
|
||||
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
JPanel comboPanel = new JPanel(new GridLayout(0, 2, 0, 0));
|
||||
|
||||
addNarrowDownCheckbox(comboPanel);
|
||||
|
||||
for(FileStructureFilter filter: fileStructureFilters) {
|
||||
addCheckbox(comboPanel, filter);
|
||||
}
|
||||
|
||||
for (FileStructureNodeProvider provider : fileStructureNodeProviders) {
|
||||
addCheckbox(comboPanel, provider);
|
||||
}
|
||||
|
||||
//myCommanderPanel.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP));
|
||||
panel.add(comboPanel, BorderLayout.NORTH);
|
||||
panel.add(ScrollPaneFactory.createScrollPane(myAbstractTreeBuilder.getTree()), BorderLayout.CENTER);
|
||||
//new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
protected boolean isShowRoot(final PsiFile psiFile) {
|
||||
StructureViewBuilder viewBuilder = LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(psiFile);
|
||||
return viewBuilder instanceof TreeBasedStructureViewBuilder && ((TreeBasedStructureViewBuilder)viewBuilder).isRootNodeShown();
|
||||
}
|
||||
|
||||
private void addNarrowDownCheckbox(final JPanel panel) {
|
||||
final JCheckBox checkBox = new JCheckBox(IdeBundle.message("checkbox.narrow.down.the.list.on.typing"));
|
||||
checkBox.setSelected(PropertiesComponent.getInstance().isTrueValue(ourPropertyKey));
|
||||
checkBox.addChangeListener(new ChangeListener() {
|
||||
public void stateChanged(ChangeEvent e) {
|
||||
myShouldNarrowDown = checkBox.isSelected();
|
||||
PropertiesComponent.getInstance().setValue(ourPropertyKey, Boolean.toString(myShouldNarrowDown));
|
||||
|
||||
myAbstractTreeBuilder.queueUpdate();
|
||||
}
|
||||
});
|
||||
|
||||
checkBox.setFocusable(false);
|
||||
panel.add(checkBox);
|
||||
//,new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0));
|
||||
}
|
||||
|
||||
private void addCheckbox(final JPanel panel, final TreeAction action) {
|
||||
String text = action instanceof FileStructureFilter ? ((FileStructureFilter)action).getCheckBoxText() :
|
||||
action instanceof FileStructureNodeProvider ? ((FileStructureNodeProvider)action).getCheckBoxText() : null;
|
||||
|
||||
if (text == null) return;
|
||||
|
||||
Shortcut[] shortcuts = action instanceof FileStructureFilter ?
|
||||
((FileStructureFilter)action).getShortcut() : ((FileStructureNodeProvider)action).getShortcut();
|
||||
|
||||
|
||||
final JCheckBox chkFilter = new JCheckBox();
|
||||
chkFilter.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
PsiElement currentParent = null;
|
||||
final AbstractTreeNode parentNode = null;//todo myAbstractTreeBuilder.getUi().getRootNode().;
|
||||
final Object value = null; //todo parentNode.getValue();
|
||||
if (value instanceof StructureViewTreeElement) {
|
||||
final Object elementValue = ((StructureViewTreeElement)value).getValue();
|
||||
if (elementValue instanceof PsiElement) {
|
||||
currentParent = (PsiElement) elementValue;
|
||||
}
|
||||
}
|
||||
final boolean state = chkFilter.isSelected();
|
||||
myTreeActionsOwner.setActionIncluded(action, action instanceof FileStructureFilter ? !state : state);
|
||||
myAbstractTreeBuilder.queueUpdate();
|
||||
if (currentParent != null) {
|
||||
boolean oldNarrowDown = myShouldNarrowDown;
|
||||
myShouldNarrowDown = false;
|
||||
try {
|
||||
//todo builder.enterElement(currentParent, PsiUtilBase.getVirtualFile(currentParent));
|
||||
}
|
||||
finally {
|
||||
myShouldNarrowDown = oldNarrowDown;
|
||||
}
|
||||
}
|
||||
myAbstractTreeBuilder.queueUpdate();
|
||||
|
||||
if (SpeedSearchBase.hasActiveSpeedSearch(myTree)) {
|
||||
final SpeedSearchSupply supply = SpeedSearchSupply.getSupply(myTree);
|
||||
if (supply != null && supply.isPopupActive()) supply.refreshSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
chkFilter.setFocusable(false);
|
||||
|
||||
if (shortcuts.length > 0) {
|
||||
text += " (" + KeymapUtil.getShortcutText(shortcuts[0]) + ")";
|
||||
new AnAction() {
|
||||
public void actionPerformed(final AnActionEvent e) {
|
||||
chkFilter.doClick();
|
||||
}
|
||||
}.registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree);
|
||||
}
|
||||
chkFilter.setText(text);
|
||||
panel.add(chkFilter);
|
||||
//,new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0, 0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected JComponent createSouthPanel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
myTitle = title;
|
||||
}
|
||||
|
||||
private class MyCommanderPanel extends CommanderPanel implements DataProvider {
|
||||
@Override
|
||||
protected boolean shouldDrillDownOnEmptyElement(final AbstractTreeNode node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public MyCommanderPanel(Project _project) {
|
||||
super(_project, false, true);
|
||||
myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
myListSpeedSearch.addChangeListener(new PropertyChangeListener() {
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
ProjectListBuilder builder = (ProjectListBuilder)getBuilder();
|
||||
if (builder == null) {
|
||||
return;
|
||||
}
|
||||
builder.addUpdateRequest(hasPrefixShortened(evt));
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
int index = myList.getSelectedIndex();
|
||||
if (index != -1 && index < myList.getModel().getSize()) {
|
||||
myList.clearSelection();
|
||||
ListScrollingUtil.selectItem(myList, index);
|
||||
}
|
||||
else {
|
||||
ListScrollingUtil.ensureSelectionExists(myList);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
myList.repaint(); // to update match highlighting
|
||||
}
|
||||
});
|
||||
myListSpeedSearch.setComparator(createSpeedSearchComparator());
|
||||
}
|
||||
|
||||
private boolean hasPrefixShortened(final PropertyChangeEvent evt) {
|
||||
return evt.getNewValue() != null && evt.getOldValue() != null &&
|
||||
((String)evt.getNewValue()).length() < ((String)evt.getOldValue()).length();
|
||||
}
|
||||
|
||||
public boolean navigateSelectedElement() {
|
||||
final Ref<Boolean> succeeded = new Ref<Boolean>();
|
||||
final CommandProcessor commandProcessor = CommandProcessor.getInstance();
|
||||
commandProcessor.executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
succeeded.set(MyCommanderPanel.super.navigateSelectedElement());
|
||||
IdeDocumentHistory.getInstance(myProject).includeCurrentCommandAsNavigation();
|
||||
}
|
||||
}, "Navigate", null);
|
||||
if (succeeded.get()) {
|
||||
myPopup.cancel();
|
||||
}
|
||||
return succeeded.get();
|
||||
}
|
||||
|
||||
public Object getData(String dataId) {
|
||||
Object selectedElement = ContainerUtil.getFirstItem(myAbstractTreeBuilder.getSelectedElements());
|
||||
|
||||
if (selectedElement instanceof TreeElement) selectedElement = ((StructureViewTreeElement)selectedElement).getValue();
|
||||
|
||||
if (PlatformDataKeys.NAVIGATABLE.is(dataId)) {
|
||||
return selectedElement instanceof Navigatable ? selectedElement : myNavigatable;
|
||||
}
|
||||
|
||||
if (OpenFileDescriptor.NAVIGATE_IN_EDITOR.is(dataId)) return myEditor;
|
||||
|
||||
return getDataImpl(dataId);
|
||||
}
|
||||
|
||||
public String getEnteredPrefix() {
|
||||
return myListSpeedSearch.getEnteredPrefix();
|
||||
}
|
||||
|
||||
public void updateSpeedSearch() {
|
||||
myListSpeedSearch.refreshSelection();
|
||||
}
|
||||
|
||||
public void scrollSelectionInView() {
|
||||
int selectedIndex = myList.getSelectedIndex();
|
||||
if (selectedIndex >= 0) {
|
||||
ListScrollingUtil.ensureIndexIsVisible(myList, selectedIndex, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyStructureTreeStructure extends SmartTreeStructure {
|
||||
public MyStructureTreeStructure(Project project) {
|
||||
super(project, myTreeModel);
|
||||
}
|
||||
|
||||
public Object[] getChildElements(Object element) {
|
||||
Object[] childElements = super.getChildElements(element);
|
||||
|
||||
if (!myShouldNarrowDown) {
|
||||
return childElements;
|
||||
}
|
||||
|
||||
String enteredPrefix = null;//todo myCommanderPanel.getEnteredPrefix();
|
||||
if (enteredPrefix == null) {
|
||||
return childElements;
|
||||
}
|
||||
|
||||
ArrayList<Object> filteredElements = new ArrayList<Object>(childElements.length);
|
||||
SpeedSearchBase.SpeedSearchComparator speedSearchComparator = createSpeedSearchComparator();
|
||||
|
||||
for (Object child : childElements) {
|
||||
if (child instanceof AbstractTreeNode) {
|
||||
Object value = ((AbstractTreeNode)child).getValue();
|
||||
if (value instanceof TreeElement) {
|
||||
String name = ((TreeElement)value).getPresentation().getPresentableText();
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
if (speedSearchComparator.matchingFragments(enteredPrefix, name) == null) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
filteredElements.add(child);
|
||||
}
|
||||
return ArrayUtil.toObjectArray(filteredElements);
|
||||
}
|
||||
|
||||
public void rebuildTree() {
|
||||
getChildElements(getRootElement()); // for some reason necessary to rebuild tree correctly
|
||||
super.rebuildTree();
|
||||
}
|
||||
}
|
||||
|
||||
private static SpeedSearchBase.SpeedSearchComparator createSpeedSearchComparator() {
|
||||
return new SpeedSearchBase.SpeedSearchComparator(false);
|
||||
}
|
||||
|
||||
private class MyTreeActionsOwner implements TreeActionsOwner {
|
||||
private final Set<TreeAction> myActions = new HashSet<TreeAction>();
|
||||
|
||||
public void setActionActive(String name, boolean state) {
|
||||
}
|
||||
|
||||
public boolean isActionActive(String name) {
|
||||
for (final Sorter sorter : myBaseTreeModel.getSorters()) {
|
||||
if (sorter.getName().equals(name)) {
|
||||
if (!sorter.isVisible()) return true;
|
||||
}
|
||||
}
|
||||
for(TreeAction action: myActions) {
|
||||
if (action.getName().equals(name)) return true;
|
||||
}
|
||||
return Sorter.ALPHA_SORTER_ID.equals(name);
|
||||
}
|
||||
|
||||
public void setActionIncluded(final TreeAction filter, final boolean selected) {
|
||||
if (selected) {
|
||||
myActions.add(filter);
|
||||
}
|
||||
else {
|
||||
myActions.remove(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+9
-9
@@ -92,13 +92,13 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
|
||||
if (localVariable != null) {
|
||||
final PsiElement nameIdentifier = localVariable.getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
myLocalMarker = editor.getDocument().createRangeMarker(nameIdentifier.getTextRange());
|
||||
myLocalMarker = createMarker(nameIdentifier);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myLocalMarker = null;
|
||||
}
|
||||
myExprText = expr != null ? expr.getText() : null;
|
||||
myExprText = getExpressionText(expr);
|
||||
myLocalName = localVariable != null ? localVariable.getName() : null;
|
||||
|
||||
myPreview =
|
||||
@@ -132,6 +132,11 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
|
||||
showDialogAdvertisement(getActionName());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getExpressionText(E expr) {
|
||||
return expr != null ? expr.getText() : null;
|
||||
}
|
||||
|
||||
protected final void setPreviewText(final String text) {
|
||||
if (myPreview == null) return; //already disposed
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@@ -318,11 +323,6 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
|
||||
return myConstantName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean performAutomaticRename() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
@@ -433,7 +433,7 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
|
||||
if (exprMarker != null) {
|
||||
myExpr = restoreExpression(containingFile, psiField, exprMarker, myExprText);
|
||||
if (myExpr != null && myExpr.isPhysical()) {
|
||||
myExprMarker = myEditor.getDocument().createRangeMarker(myExpr.getTextRange());
|
||||
myExprMarker = createMarker(myExpr);
|
||||
}
|
||||
}
|
||||
if (myLocalMarker != null) {
|
||||
@@ -449,7 +449,7 @@ public abstract class AbstractInplaceIntroducer<V extends PsiNameIdentifierOwner
|
||||
if (localVariable != null && localVariable.isPhysical()) {
|
||||
final PsiElement nameIdentifier = localVariable.getNameIdentifier();
|
||||
if (nameIdentifier != null) {
|
||||
myLocalMarker = myEditor.getDocument().createRangeMarker(nameIdentifier.getTextRange());
|
||||
myLocalMarker = createMarker(nameIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
-2
@@ -76,7 +76,7 @@ public class InplaceVariableIntroducer<E extends PsiElement> extends VariableInp
|
||||
myTitle = title;
|
||||
myOccurrences = occurrences;
|
||||
myExpr = expr;
|
||||
myExprMarker = myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null;
|
||||
myExprMarker = myExpr != null && myExpr.isPhysical() ? createMarker(myExpr) : null;
|
||||
initOccurrencesMarkers();
|
||||
}
|
||||
|
||||
@@ -127,10 +127,14 @@ public class InplaceVariableIntroducer<E extends PsiElement> extends VariableInp
|
||||
if (myOccurrenceMarkers != null) return;
|
||||
myOccurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
for (E occurrence : myOccurrences) {
|
||||
myOccurrenceMarkers.add(myEditor.getDocument().createRangeMarker(occurrence.getTextRange()));
|
||||
myOccurrenceMarkers.add(createMarker(occurrence));
|
||||
}
|
||||
}
|
||||
|
||||
protected RangeMarker createMarker(PsiElement element) {
|
||||
return myEditor.getDocument().createRangeMarker(element.getTextRange());
|
||||
}
|
||||
|
||||
|
||||
public RangeMarker getExprMarker() {
|
||||
return myExprMarker;
|
||||
@@ -234,4 +238,8 @@ public class InplaceVariableIntroducer<E extends PsiElement> extends VariableInp
|
||||
//move logic to performRefactoring
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean performAutomaticRename() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -338,7 +338,7 @@ public class VariableInplaceRenamer {
|
||||
performOnInvalidIdentifier(myNewName, nameSuggestions);
|
||||
return;
|
||||
}
|
||||
if (snapshot != null && performAutomaticRename()) {
|
||||
if (myNewName != null && snapshot != null && performAutomaticRename()) {
|
||||
if (LanguageNamesValidation.INSTANCE.forLanguage(scope1.getLanguage()).isIdentifier(myNewName, myProject)) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
public void run() {
|
||||
@@ -536,6 +536,7 @@ public class VariableInplaceRenamer {
|
||||
|
||||
@Nullable
|
||||
protected String getNewName(String newName, ResolveSnapshotProvider.ResolveSnapshot snapshot) {
|
||||
if (!performAutomaticRename()) return null;
|
||||
return snapshot != null ? newName : null;
|
||||
}
|
||||
|
||||
|
||||
@@ -594,9 +594,9 @@ public class IdeEventQueue extends EventQueue {
|
||||
}
|
||||
|
||||
boolean mouseEventsAhead = isMouseEventAhead(e);
|
||||
boolean focusTransferred = IdeFocusManager.getGlobalInstance().isFocusBeingTransferred();
|
||||
boolean focusTransferredNow = IdeFocusManager.getGlobalInstance().isFocusBeingTransferred();
|
||||
|
||||
boolean okToFixFocus = !mouseEventsAhead && focusTransferred;
|
||||
boolean okToFixFocus = !mouseEventsAhead && !focusTransferredNow;
|
||||
|
||||
if (okToFixFocus) {
|
||||
Window showingWindow = mgr.getActiveWindow();
|
||||
|
||||
@@ -158,6 +158,9 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
|
||||
final List<String> paths = new ArrayList<String>();
|
||||
synchronized (myState) {
|
||||
outer: for (String recentPath : myState.recentPaths) {
|
||||
if (recentPath == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (Project openProject : openProjects) {
|
||||
final String path = getProjectPath(openProject);
|
||||
@@ -269,7 +272,7 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
private static String getProjectName(String path) {
|
||||
final File file = new File(path);
|
||||
if (file.isDirectory()) {
|
||||
@@ -294,14 +297,12 @@ public abstract class RecentProjectsManagerBase implements PersistentStateCompon
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return file.getName();
|
||||
}
|
||||
} else {
|
||||
return file.getName();
|
||||
}
|
||||
else {
|
||||
return FileUtil.getNameWithoutExtension(file.getName());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private class MyAppLifecycleListener extends AppLifecycleListener.Adapter {
|
||||
|
||||
+3
-1
@@ -1105,7 +1105,9 @@ public final class ActionManagerImpl extends ActionManagerEx implements Applicat
|
||||
}
|
||||
|
||||
public Set<String> getActionIds(){
|
||||
return new HashSet<String>(myId2Action.keySet());
|
||||
synchronized (myLock) {
|
||||
return new HashSet<String>(myId2Action.keySet());
|
||||
}
|
||||
}
|
||||
|
||||
private int myActionsPreloaded = 0;
|
||||
|
||||
@@ -1330,6 +1330,11 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
|
||||
}
|
||||
|
||||
public void _setBounds(Rectangle bounds) {
|
||||
Rectangle currentBounds = getBounds();
|
||||
if (currentBounds.width != bounds.width || currentBounds.height != bounds.height) {
|
||||
invalidateShadowImage();
|
||||
}
|
||||
|
||||
super.setBounds(bounds);
|
||||
if (myCloseRec.getParent() == null && getParent() != null) {
|
||||
myLayeredPane.add(myCloseRec);
|
||||
@@ -1357,6 +1362,11 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
|
||||
}
|
||||
}
|
||||
|
||||
private void invalidateShadowImage() {
|
||||
myImage = null;
|
||||
myShadow = null;
|
||||
}
|
||||
|
||||
public void repaintButton() {
|
||||
myCloseRec.repaint();
|
||||
}
|
||||
|
||||
@@ -169,3 +169,4 @@ show.anonymous.in.structure.view.description=Enables Java anonymous classes in S
|
||||
|
||||
enable.groovy.hotswap=true
|
||||
enable.groovy.hotswap.description=Whether IDEA should add a special java agent to the debugged process which allows to hot-swap Groovy changes in some cases
|
||||
file.structure.tree.mode=false
|
||||
|
||||
@@ -432,7 +432,7 @@ public class Splitter extends JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets component which is located as the "secont" splitted area. The method doesn't validate and
|
||||
* Sets component which is located as the "second" splitted area. The method doesn't validate and
|
||||
* repaint the splitter.
|
||||
*
|
||||
* @param component
|
||||
|
||||
@@ -19,10 +19,13 @@ import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.SearchTextField;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
/**
|
||||
@@ -56,6 +59,15 @@ public abstract class SearchFieldAction extends AnAction implements CustomCompon
|
||||
actionPerformed(null);
|
||||
}
|
||||
};
|
||||
Border border = myField.getBorder();
|
||||
Border emptyBorder = IdeBorderFactory.createEmptyBorder(3, 0, 2, 0);
|
||||
if (border instanceof CompoundBorder) {
|
||||
myField.setBorder(new CompoundBorder(emptyBorder, ((CompoundBorder)border).getInsideBorder()));
|
||||
}
|
||||
else {
|
||||
myField.setBorder(emptyBorder);
|
||||
}
|
||||
|
||||
myField.setSearchIcon(IconLoader.getIcon("/actions/filter_small.png"));
|
||||
myComponent = new JPanel();
|
||||
final BoxLayout layout = new BoxLayout(myComponent, BoxLayout.X_AXIS);
|
||||
|
||||
@@ -118,11 +118,19 @@ public abstract class XBreakpointType<B extends XBreakpoint<P>, P extends XBreak
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated override {@link #getEditorsProvider(XBreakpoint)} instead
|
||||
*/
|
||||
@Nullable
|
||||
public XDebuggerEditorsProvider getEditorsProvider() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public XDebuggerEditorsProvider getEditorsProvider(@NotNull B breakpoint) {
|
||||
return getEditorsProvider();
|
||||
}
|
||||
|
||||
public List<XBreakpointGroupingRule<B, ?>> getGroupingRules() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class XBreakpointPropertiesPanel<B extends XBreakpoint<?>> {
|
||||
|
||||
mySuspendPolicyPanel.init(project, breakpointManager, breakpoint);
|
||||
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider();
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint);
|
||||
|
||||
myBreakpointActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider);
|
||||
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpoint<?>> implement
|
||||
mySubPanels.add(mySuspendPolicyPanel);
|
||||
myMasterBreakpointPanel.init(project, breakpointManager, breakpoint);
|
||||
mySubPanels.add(myMasterBreakpointPanel);
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider();
|
||||
XDebuggerEditorsProvider debuggerEditorsProvider = breakpointType.getEditorsProvider(breakpoint);
|
||||
|
||||
myActionsPanel.init(project, breakpointManager, breakpoint, debuggerEditorsProvider);
|
||||
mySubPanels.add(myActionsPanel);
|
||||
|
||||
+8
-1
@@ -50,6 +50,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import static org.jetbrains.idea.eclipse.conversion.EPathUtil.*;
|
||||
|
||||
@@ -150,7 +151,13 @@ public class EclipseClasspathReader {
|
||||
}
|
||||
else {
|
||||
String srcUrl = VfsUtil.pathToUrl(myRootPath + "/" + path);
|
||||
final boolean isTestFolder = testPattern != null && testPattern.length() > 0 && path.matches(testPattern);
|
||||
boolean isTestFolder = false;
|
||||
try {
|
||||
isTestFolder = testPattern != null && testPattern.length() > 0 && path.matches(testPattern);
|
||||
}
|
||||
catch (PatternSyntaxException e) {
|
||||
isTestFolder = false;
|
||||
}
|
||||
final EclipseProjectFinder.LinkedResource linkedResource = EclipseProjectFinder.findLinkedResource(myRootPath, path);
|
||||
if (linkedResource != null) {
|
||||
if (linkedResource.containsPathVariable()) {
|
||||
|
||||
@@ -64,6 +64,7 @@ public class GitLogSettings implements PersistentStateComponent<GitLogSettings.M
|
||||
public boolean myHighlight = true;
|
||||
public boolean myShowTree = true;
|
||||
public boolean myTopoOrder = false;
|
||||
public boolean myShowDetails = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -178,4 +179,12 @@ public class GitLogSettings implements PersistentStateComponent<GitLogSettings.M
|
||||
public void setHighlight(final boolean value) {
|
||||
myState.myHighlight = value;
|
||||
}
|
||||
|
||||
public boolean isShowDetails() {
|
||||
return myState.myShowDetails;
|
||||
}
|
||||
|
||||
public void setShowDetails(boolean showDetails) {
|
||||
myState.myShowDetails = showDetails;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,12 +22,13 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.CaptionIcon;
|
||||
import com.intellij.openapi.diff.impl.patch.formove.FilePathComparator;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.project.DumbAwareAction;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.*;
|
||||
import com.intellij.openapi.ui.MessageType;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.Splitter;
|
||||
import com.intellij.openapi.ui.popup.*;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -48,10 +49,7 @@ import com.intellij.ui.*;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.ui.table.JBTable;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import com.intellij.util.Processor;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.*;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
@@ -59,7 +57,6 @@ import com.intellij.util.ui.AdjustComponentWhenShown;
|
||||
import com.intellij.util.ui.ColumnInfo;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import git4idea.GitBranch;
|
||||
import git4idea.GitVcs;
|
||||
import git4idea.changes.GitChangeUtils;
|
||||
import git4idea.history.browser.*;
|
||||
@@ -112,8 +109,6 @@ public class GitLogUI implements Disposable {
|
||||
private RepositoryChangesBrowser myRepositoryChangesBrowser;
|
||||
final List<CommitI> myCommitsInRepositoryChangesBrowser;
|
||||
private boolean myDataBeingAdded;
|
||||
private CardLayout myRepoLayout;
|
||||
private JPanel myRepoPanel;
|
||||
private boolean myStarted;
|
||||
private String myPreviousFilter;
|
||||
private final CommentSearchContext myCommentSearchContext;
|
||||
@@ -134,6 +129,7 @@ public class GitLogUI implements Disposable {
|
||||
private MyRefreshAction myRefreshAction;
|
||||
private MyStructureFilter myStructureFilter;
|
||||
private StructureFilterAction myStructureFilterAction;
|
||||
private ToggleAction myShowDetailsAction;
|
||||
private AnAction myCopyHashAction;
|
||||
// todo group somewhere??
|
||||
private Consumer<CommitI> myDetailsLoaderImpl;
|
||||
@@ -153,6 +149,8 @@ public class GitLogUI implements Disposable {
|
||||
private JViewport myTableViewPort;
|
||||
private GitLogUI.MyGotoCommitAction myMyGotoCommitAction;
|
||||
private final Set<VirtualFile> myClearedHighlightingRoots;
|
||||
private final Splitter myDetailsSplitter;
|
||||
private JScrollPane myTableScrollPane;
|
||||
|
||||
public GitLogUI(Project project, final Mediator mediator) {
|
||||
myProject = project;
|
||||
@@ -192,6 +190,8 @@ public class GitLogUI implements Disposable {
|
||||
reloadRequest();
|
||||
}
|
||||
};
|
||||
myDetailsSplitter = new Splitter(true, 0.6f);
|
||||
myDetailsSplitter.setShowDividerControls(true);
|
||||
}
|
||||
|
||||
public void initFromSettings() {
|
||||
@@ -388,7 +388,6 @@ public class GitLogUI implements Disposable {
|
||||
|
||||
public void createMe() {
|
||||
mySplitter = new Splitter(false, 0.7f);
|
||||
mySplitter.setDividerWidth(4);
|
||||
|
||||
final JPanel wrapper = createMainTable();
|
||||
mySplitter.setFirstComponent(wrapper);
|
||||
@@ -487,10 +486,10 @@ public class GitLogUI implements Disposable {
|
||||
}
|
||||
|
||||
private JComponent createRepositoryBrowserDetails() {
|
||||
myRepoLayout = new CardLayout();
|
||||
myRepoPanel = new JPanel(myRepoLayout);
|
||||
myRepositoryChangesBrowser = new RepositoryChangesBrowser(myProject, Collections.<CommittedChangeList>emptyList(), Collections.<Change>emptyList(), null);
|
||||
myRepositoryChangesBrowser.getDiffAction().registerCustomShortcutSet(CommonShortcuts.getDiff(), myJBTable);
|
||||
myRepositoryChangesBrowser.getViewer().setScrollPaneBorder(IdeBorderFactory.createBorder(SideBorder.LEFT | SideBorder.TOP | SideBorder.RIGHT));
|
||||
myRepositoryChangesBrowser.setBorder(IdeBorderFactory.createEmptyBorder(0, 0, 0, 4));
|
||||
myJBTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
@@ -498,13 +497,7 @@ public class GitLogUI implements Disposable {
|
||||
mySelectionRequestsMerger.request();
|
||||
}
|
||||
});
|
||||
myRepoPanel.add("main", myRepositoryChangesBrowser);
|
||||
// todo loading circle
|
||||
myRepoPanel.add("loading", panelWithCenteredText("Loading..."));
|
||||
myRepoPanel.add("tooMuch", panelWithCenteredText("Too many rows selected"));
|
||||
myRepoPanel.add("empty", panelWithCenteredText("Nothing selected"));
|
||||
myRepoLayout.show(myRepoPanel, "empty");
|
||||
return myRepoPanel;
|
||||
return myRepositoryChangesBrowser;
|
||||
}
|
||||
|
||||
private void selectionChanged() {
|
||||
@@ -516,17 +509,14 @@ public class GitLogUI implements Disposable {
|
||||
selectionChangedForDetails(rows);
|
||||
|
||||
if (rows.length == 0) {
|
||||
myRepoLayout.show(myRepoPanel, "empty");
|
||||
myRepoPanel.repaint();
|
||||
myRepositoryChangesBrowser.getViewer().setEmptyText("Nothing selected");
|
||||
return;
|
||||
} else if (rows.length >= 10) {
|
||||
myRepoLayout.show(myRepoPanel, "tooMuch");
|
||||
myRepoPanel.repaint();
|
||||
myRepositoryChangesBrowser.getViewer().setEmptyText("Too many rows selected");
|
||||
return;
|
||||
}
|
||||
if (! myDataBeingAdded && ! gatherNotLoadedData()) {
|
||||
myRepoLayout.show(myRepoPanel, "loading");
|
||||
myRepoPanel.repaint();
|
||||
myRepositoryChangesBrowser.getViewer().setEmptyText("Loading...");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,16 +581,6 @@ public class GitLogUI implements Disposable {
|
||||
return myDetailsCache.convert(commitAt.selectRepository(myRootsUnderVcs), commitAt.getHash());
|
||||
}
|
||||
|
||||
private static JPanel panelWithCenteredText(final String text) {
|
||||
final JPanel jPanel = new JPanel(new BorderLayout());
|
||||
jPanel.setBackground(UIUtil.getTableBackground());
|
||||
final JLabel label = new JLabel(text, JLabel.CENTER);
|
||||
label.setUI(new MultiLineLabelUI());
|
||||
jPanel.add(label, BorderLayout.CENTER);
|
||||
jPanel.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor()));
|
||||
return jPanel;
|
||||
}
|
||||
|
||||
public void updateByScroll() {
|
||||
gatherNotLoadedData();
|
||||
}
|
||||
@@ -638,8 +618,6 @@ public class GitLogUI implements Disposable {
|
||||
}
|
||||
final List<Change> zipped = CommittedChangesTreeBrowser.zipChanges(changes);
|
||||
myRepositoryChangesBrowser.setChangesToDisplay(zipped);
|
||||
myRepoLayout.show(myRepoPanel, "main");
|
||||
myRepoPanel.repaint();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -678,17 +656,18 @@ public class GitLogUI implements Disposable {
|
||||
};
|
||||
myJBTable.addMouseListener(popupHandler);
|
||||
|
||||
final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myJBTable);
|
||||
myTableScrollPane = ScrollPaneFactory.createScrollPane(myJBTable);
|
||||
myTableScrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT | SideBorder.BOTTOM));
|
||||
myGraphGutter = new GraphGutter(myTableModel);
|
||||
myGraphGutter.setJBTable(myJBTable);
|
||||
myTableViewPort = scrollPane.getViewport();
|
||||
myTableViewPort = myTableScrollPane.getViewport();
|
||||
myGraphGutter.setTableViewPort(myTableViewPort);
|
||||
myGraphGutter.getComponent().addMouseListener(popupHandler);
|
||||
|
||||
new AdjustComponentWhenShown() {
|
||||
@Override
|
||||
protected boolean init() {
|
||||
return adjustColumnSizes(scrollPane);
|
||||
return adjustColumnSizes(myTableScrollPane);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -711,7 +690,7 @@ public class GitLogUI implements Disposable {
|
||||
}
|
||||
}
|
||||
);
|
||||
scrollPane.getViewport().addChangeListener(myMyChangeListener);
|
||||
myTableScrollPane.getViewport().addChangeListener(myMyChangeListener);
|
||||
|
||||
final JPanel wrapper = new DataProviderPanel(new BorderLayout());
|
||||
wrapper.add(actionToolbar.getComponent(), BorderLayout.NORTH);
|
||||
@@ -722,9 +701,10 @@ public class GitLogUI implements Disposable {
|
||||
wrapperGutter.add(myEqualToHeadr, BorderLayout.NORTH);
|
||||
wrapperGutter.add(myGraphGutter.getComponent(), BorderLayout.CENTER);
|
||||
mainBorderWrapper.add(wrapperGutter, BorderLayout.WEST);
|
||||
mainBorderWrapper.add(scrollPane, BorderLayout.CENTER);
|
||||
mainBorderWrapper.add(myTableScrollPane, BorderLayout.CENTER);
|
||||
//mainBorderWrapper.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor()));
|
||||
wrapper.add(mainBorderWrapper, BorderLayout.CENTER);
|
||||
|
||||
myDetailsPanel = new GitLogDetailsPanel(myProject, myDetailsCache, new Convertor<VirtualFile, CachedRefs>() {
|
||||
@Override
|
||||
public CachedRefs convert(VirtualFile o) {
|
||||
@@ -736,15 +716,12 @@ public class GitLogUI implements Disposable {
|
||||
return myMarked.contains(hash);
|
||||
}
|
||||
});
|
||||
final JPanel borderWrapper = new JPanel(new BorderLayout());
|
||||
borderWrapper.setBorder(BorderFactory.createLineBorder(UIUtil.getBorderColor()));
|
||||
borderWrapper.add(myDetailsPanel.getComponent(), BorderLayout.CENTER);
|
||||
|
||||
final Splitter splitter = new Splitter(true, 0.6f);
|
||||
splitter.setFirstComponent(wrapper);
|
||||
splitter.setSecondComponent(borderWrapper);
|
||||
splitter.setDividerWidth(4);
|
||||
return splitter;
|
||||
myDetailsSplitter.setFirstComponent(wrapper);
|
||||
JPanel details = myDetailsPanel.getComponent();
|
||||
details.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT));
|
||||
setupDetailsSplitter(GitLogSettings.getInstance(myProject).isShowDetails());
|
||||
return myDetailsSplitter;
|
||||
}
|
||||
|
||||
private void createTreeUpperComponent() {
|
||||
@@ -888,6 +865,19 @@ public class GitLogUI implements Disposable {
|
||||
myRootsAction = new MyRootsAction(rootsGetter, myJBTable);
|
||||
group.add(myRootsAction);
|
||||
group.add(myMyShowTreeAction);
|
||||
myShowDetailsAction = new ToggleAction("Show Details", "Display details panel", IconLoader.getIcon("/actions/showSource.png")) {
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return GitLogSettings.getInstance(myProject).isShowDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
setupDetailsSplitter(state);
|
||||
GitLogSettings.getInstance(myProject).setShowDetails(state);
|
||||
}
|
||||
};
|
||||
group.add(myShowDetailsAction);
|
||||
myMyGotoCommitAction = new MyGotoCommitAction();
|
||||
group.add(myMyGotoCommitAction);
|
||||
group.add(myRefreshAction);
|
||||
@@ -928,6 +918,16 @@ public class GitLogUI implements Disposable {
|
||||
return ActionManager.getInstance().createActionToolbar("Git log", group, true);
|
||||
}
|
||||
|
||||
private void setupDetailsSplitter(boolean state) {
|
||||
myDetailsSplitter.setSecondComponent(state ? myDetailsPanel.getComponent() : null);
|
||||
if (state) {
|
||||
myTableScrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT | SideBorder.BOTTOM));
|
||||
}
|
||||
else {
|
||||
myTableScrollPane.setBorder(IdeBorderFactory.createBorder(SideBorder.TOP | SideBorder.RIGHT));
|
||||
}
|
||||
}
|
||||
|
||||
private class DataProviderPanel extends JPanel implements TypeSafeDataProvider {
|
||||
private DataProviderPanel(LayoutManager layout) {
|
||||
super(layout);
|
||||
@@ -1461,6 +1461,7 @@ public class GitLogUI implements Disposable {
|
||||
private class MyTextFieldAction extends SearchFieldAction {
|
||||
private MyTextFieldAction() {
|
||||
super("Filter:");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1827,7 +1828,7 @@ public class GitLogUI implements Disposable {
|
||||
private final GitLogSettings myInstance;
|
||||
|
||||
public MyShowTreeAction() {
|
||||
super("Show graph", "Show graph", IconLoader.getIcon("/icons/branch.png"));
|
||||
super("Show Graph", "Display commit graph", IconLoader.getIcon("/icons/branch.png"));
|
||||
myInstance = GitLogSettings.getInstance(myProject);
|
||||
myIsSelected = myInstance.isShowTree();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public final class GitRepositoryManager extends AbstractProjectComponent impleme
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
myProject.getMessageBus().connect(this).subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this);
|
||||
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, this);
|
||||
Disposer.register(myProject, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -1077,6 +1077,10 @@
|
||||
text="Change SDK version" description="Change Grails/Griffon SDK version">
|
||||
</action>
|
||||
|
||||
<action id="Griffon.UpdateDependencies" class="org.jetbrains.plugins.groovy.griffon.UpdateGriffonSettingsAction"
|
||||
text="Synchronize Griffon settings" description="Refresh IntelliJ IDEA project structure so that it matches Griffon build settings">
|
||||
</action>
|
||||
|
||||
<action id="Mvc.RunTarget" class="org.jetbrains.plugins.groovy.mvc.MvcRunTarget"
|
||||
text="Run Target" description="Run arbitrary Grails/Griffon target">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="ctrl alt G"/>
|
||||
|
||||
@@ -295,7 +295,6 @@ default.initializers.are.not.allowed.in.abstract.method=Default initializers are
|
||||
groovy.does.not.support.constructor.type.arguments=Groovy does not support constructor type arguments
|
||||
illegal.escape.character.in.string.literal=Illegal escape character in string literal
|
||||
dollar.slash.end.expected=Dollar slash ending expected
|
||||
regex.cannot.be.first.argument.of.command.method.call=Dollar-slashy strings cannot be the first argument of a command method call
|
||||
add.parentheses=Add parentheses
|
||||
add.parentheses.to.command.method.call=Add parentheses to command method call
|
||||
dollar.slash.strings.are.not.allowed.in.0=Dollar-slash strings are not allowed in Groovy {0}
|
||||
dollar.slash.strings.are.not.allowed.in.0=Dollar slashy strings are not allowed in Groovy {0}
|
||||
|
||||
@@ -279,9 +279,14 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
|
||||
private void checkStringNameIdentifier(GrReferenceExpression ref) {
|
||||
final PsiElement nameElement = ref.getReferenceNameElement();
|
||||
if (nameElement == null) return;
|
||||
if (!GroovyTokenTypes.mSTRING_LITERAL.equals(nameElement.getNode().getElementType())) return;
|
||||
final String text = nameElement.getText();
|
||||
checkStringLiteral(nameElement, text);
|
||||
|
||||
final IElementType elementType = nameElement.getNode().getElementType();
|
||||
if (elementType == GroovyTokenTypes.mSTRING_LITERAL || elementType == GroovyTokenTypes.mGSTRING_LITERAL) {
|
||||
checkStringLiteral(nameElement, nameElement.getText());
|
||||
}
|
||||
else if (elementType == GroovyTokenTypes.mREGEX_LITERAL || elementType == GroovyTokenTypes.mDOLLAR_SLASH_REGEX_LITERAL) {
|
||||
checkRegexLiteral(nameElement);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -856,19 +861,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator {
|
||||
myHolder
|
||||
.createErrorAnnotation(regex, GroovyBundle.message("dollar.slash.strings.are.not.allowed.in.0", config.getSDKVersion(regex)));
|
||||
}
|
||||
if (regex instanceof GrRegex &&
|
||||
regex.getParent() instanceof GrCommandArgumentList &&
|
||||
((GrCommandArgumentList)regex.getParent()).getAllArguments()[0] == regex ||
|
||||
|
||||
!(regex instanceof GrRegex) &&
|
||||
regex.getParent().getParent() instanceof GrCommandArgumentList &&
|
||||
((GrCommandArgumentList)regex.getParent().getParent()).getAllArguments()[0] == regex.getParent()
|
||||
) {
|
||||
final Annotation annotation =
|
||||
myHolder.createErrorAnnotation(regex, GroovyBundle.message("regex.cannot.be.first.argument.of.command.method.call"));
|
||||
annotation.registerFix(new AddParenthesesFix());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public class GeeseUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Alignment calculateRBraceAlignment(PsiElement rBrace, Map<PsiElement, Alignment> alignments, Map<PsiElement, GroovyBlock> blocks) {
|
||||
static Alignment calculateRBraceAlignment(PsiElement rBrace, Map<PsiElement, Alignment> alignments) {
|
||||
int leadingBraceCount = 0;
|
||||
PsiElement next;
|
||||
|
||||
@@ -146,11 +146,7 @@ public class GeeseUtil {
|
||||
|
||||
Alignment alignment = alignments.get(cur);
|
||||
if (alignment == null) {
|
||||
final GroovyBlock block = blocks.get(cur);
|
||||
alignment = Alignment.createAlignment(true);
|
||||
if (block != null) {
|
||||
block.setAlignment(alignment);
|
||||
}
|
||||
alignments.put(cur, alignment);
|
||||
}
|
||||
return alignment;
|
||||
|
||||
@@ -55,7 +55,7 @@ import java.util.Map;
|
||||
*
|
||||
* @author ilyas
|
||||
*/
|
||||
public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock {
|
||||
public class GroovyBlock implements Block, GroovyElementTypes, ASTBlock {
|
||||
final protected ASTNode myNode;
|
||||
protected Alignment myAlignment;
|
||||
final protected Indent myIndent;
|
||||
@@ -63,7 +63,6 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock
|
||||
final protected CommonCodeStyleSettings mySettings;
|
||||
final protected GroovyCodeStyleSettings myGroovySettings;
|
||||
final protected Map<PsiElement, Alignment> myInnerAlignments;
|
||||
final protected Map<PsiElement, GroovyBlock> myBlocks;
|
||||
|
||||
protected List<Block> mySubBlocks = null;
|
||||
|
||||
@@ -73,12 +72,10 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock
|
||||
@Nullable final Wrap wrap,
|
||||
final CommonCodeStyleSettings settings,
|
||||
GroovyCodeStyleSettings groovySettings,
|
||||
@NotNull Map<PsiElement, Alignment> innerAlignments, Map<PsiElement, GroovyBlock> blocks) {
|
||||
@NotNull Map<PsiElement, Alignment> innerAlignments) {
|
||||
myNode = node;
|
||||
myBlocks = blocks;
|
||||
if (groovySettings.USE_FLYING_GEESE_BRACES) {
|
||||
PsiElement psi = myNode.getPsi();
|
||||
myBlocks.put(psi, this);
|
||||
if (alignment == null) {
|
||||
alignment = innerAlignments.get(psi);
|
||||
}
|
||||
@@ -119,8 +116,12 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Block> getSubBlocks() {
|
||||
return mySubBlocks;
|
||||
if (mySubBlocks == null) {
|
||||
mySubBlocks = new GroovyBlockGenerator(this).generateSubBlocks();
|
||||
}
|
||||
return mySubBlocks;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -228,10 +229,6 @@ public abstract class GroovyBlock implements Block, GroovyElementTypes, ASTBlock
|
||||
return isIncomplete(myNode);
|
||||
}
|
||||
|
||||
public void setAlignment(Alignment alignment) {
|
||||
myAlignment = alignment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node Tree node
|
||||
* @return true if node is incomplete
|
||||
|
||||
+15
-28
@@ -82,7 +82,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
private final Wrap myWrap;
|
||||
private final CommonCodeStyleSettings mySettings;
|
||||
private final Map<PsiElement,Alignment> myInnerAlignments;
|
||||
private final Map<PsiElement,GroovyBlock> myBlocks;
|
||||
private final GroovyCodeStyleSettings myGroovySettings;
|
||||
|
||||
public GroovyBlockGenerator(GroovyBlock block) {
|
||||
@@ -93,7 +92,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
mySettings = myBlock.getSettings();
|
||||
myInnerAlignments = myBlock.getInnerAlignments();
|
||||
myGroovySettings = myBlock.getGroovySettings();
|
||||
myBlocks = myBlock.myBlocks;
|
||||
}
|
||||
|
||||
|
||||
@@ -136,8 +134,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
for (ASTNode childNode : children) {
|
||||
if (childNode.getTextRange().getLength() > 0) {
|
||||
final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode);
|
||||
subBlocks.add(new GroovySimpleBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks));
|
||||
subBlocks.add(new GroovyBlock(childNode, myAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments));
|
||||
}
|
||||
}
|
||||
return subBlocks;
|
||||
@@ -158,8 +155,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
final Alignment newAlignment = mustAlign(blockPsi, astNodes) ? Alignment.createAlignment() : null;
|
||||
for (ASTNode childNode : astNodes) {
|
||||
final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode);
|
||||
subBlocks.add(new GroovySimpleBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings,
|
||||
myInnerAlignments, myBlocks));
|
||||
subBlocks.add(new GroovyBlock(childNode, isKeyword(childNode) ? null : newAlignment, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments));
|
||||
}
|
||||
return subBlocks;
|
||||
}
|
||||
@@ -172,8 +168,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
for (ASTNode childNode : children) {
|
||||
final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode);
|
||||
Alignment alignmentToUse = classLevel ? myAlignment : myInnerAlignments.get(childNode.getPsi());
|
||||
subBlocks.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks));
|
||||
subBlocks.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments));
|
||||
}
|
||||
return subBlocks;
|
||||
}
|
||||
@@ -182,8 +177,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
final ArrayList<Block> subBlocks = new ArrayList<Block>();
|
||||
for (ASTNode childNode : visibleChildren(myNode)) {
|
||||
final Indent indent = GroovyIndentProcessor.getChildIndent(myBlock, childNode);
|
||||
subBlocks.add(new GroovySimpleBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings,
|
||||
myInnerAlignments, myBlocks));
|
||||
subBlocks.add(new GroovyBlock(childNode, myInnerAlignments.get(childNode.getPsi()), indent, myWrap, mySettings, myGroovySettings, myInnerAlignments));
|
||||
}
|
||||
return subBlocks;
|
||||
}
|
||||
@@ -232,9 +226,9 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) {
|
||||
/*else if (GeeseUtil.isClosureRBrace(psi) && myGroovySettings.USE_FLYING_GEESE_BRACES) {
|
||||
myInnerAlignments.put(psi, GeeseUtil.calculateRBraceAlignment(psi, myInnerAlignments, myBlocks));
|
||||
}
|
||||
}*/
|
||||
else {
|
||||
if (psi instanceof PsiComment) {
|
||||
PsiElement prev = psi.getPrevSibling();
|
||||
@@ -325,22 +319,19 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
final int start = myNode.getTextRange().getStartOffset();
|
||||
final int end = myNode.getTextRange().getEndOffset();
|
||||
|
||||
subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks) {
|
||||
subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) {
|
||||
@NotNull
|
||||
public TextRange getTextRange() {
|
||||
return new TextRange(start, start + 3);
|
||||
}
|
||||
});
|
||||
subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks) {
|
||||
subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) {
|
||||
@NotNull
|
||||
public TextRange getTextRange() {
|
||||
return new TextRange(start + 3, end - 3);
|
||||
}
|
||||
});
|
||||
subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks) {
|
||||
subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) {
|
||||
@NotNull
|
||||
public TextRange getTextRange() {
|
||||
return new TextRange(end - 3, end);
|
||||
@@ -354,15 +345,13 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
final int start = myNode.getTextRange().getStartOffset();
|
||||
final int end = myNode.getTextRange().getEndOffset();
|
||||
|
||||
subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks) {
|
||||
subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) {
|
||||
@NotNull
|
||||
public TextRange getTextRange() {
|
||||
return new TextRange(start, start + 3);
|
||||
}
|
||||
});
|
||||
subBlocks.add(new GroovySimpleBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks) {
|
||||
subBlocks.add(new GroovyBlock(myNode, myAlignment, Indent.getAbsoluteNoneIndent(), myWrap, mySettings, myGroovySettings, myInnerAlignments) {
|
||||
@NotNull
|
||||
public TextRange getTextRange() {
|
||||
return new TextRange(start + 3, end);
|
||||
@@ -444,8 +433,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
PsiElement psi = childNode.getPsi();
|
||||
if (!(psi instanceof GrBinaryExpression)) {
|
||||
Alignment alignmentToUse = op == psi ? myInnerAlignments.get(op) : alignment;
|
||||
list.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments,
|
||||
myBlocks));
|
||||
list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments));
|
||||
}
|
||||
}
|
||||
if (myExpr.getRightOperand() instanceof GrBinaryExpression) {
|
||||
@@ -474,8 +462,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
}
|
||||
if (i < grandChildren.size()) {
|
||||
LOG.assertTrue(nameElement == grandChildren.get(i).getPsi());
|
||||
list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem,
|
||||
myInnerAlignments, myBlocks));
|
||||
list.add(new MethodCallWithoutQualifierBlock(nameElement, null, myWrap, mySettings, myGroovySettings, topLevel, children, elem, myInnerAlignments));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -496,7 +483,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
else {
|
||||
Alignment alignmentToUse = myInnerAlignments.get(fst.getPsi());
|
||||
Indent indent = Indent.getContinuationWithoutFirstIndent();
|
||||
list.add(new GroovySimpleBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, myBlocks));
|
||||
list.add(new GroovyBlock(fst, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments));
|
||||
}
|
||||
addNestedChildrenSuffix(list, alignment, topLevel, children, limit);
|
||||
}
|
||||
@@ -510,7 +497,7 @@ public class GroovyBlockGenerator implements GroovyElementTypes {
|
||||
Indent.getContinuationWithoutFirstIndent() :
|
||||
Indent.getNoneIndent();
|
||||
Alignment alignmentToUse = TokenSets.DOTS.contains(type) ? alignment : myInnerAlignments.get(childNode.getPsi());
|
||||
list.add(new GroovySimpleBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments, myBlocks));
|
||||
list.add(new GroovyBlock(childNode, alignmentToUse, indent, myWrap, mySettings, myGroovySettings, myInnerAlignments));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+21
-3
@@ -21,6 +21,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiRecursiveElementVisitor;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
@@ -36,6 +37,8 @@ import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
*/
|
||||
@@ -50,9 +53,24 @@ public class GroovyFormattingModelBuilder implements FormattingModelBuilder {
|
||||
assert astNode != null;
|
||||
CommonCodeStyleSettings groovySettings = settings.getCommonSettings(GroovyFileType.GROOVY_LANGUAGE);
|
||||
GroovyCodeStyleSettings customSettings = settings.getCustomSettings(GroovyCodeStyleSettings.class);
|
||||
final GroovyBlock block = new GroovySimpleBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings,
|
||||
CollectionFactory.<PsiElement, Alignment>hashMap(),
|
||||
CollectionFactory.<PsiElement, GroovyBlock>hashMap());
|
||||
|
||||
final Map<PsiElement, Alignment> innerAlignments = CollectionFactory.hashMap();
|
||||
if (customSettings.USE_FLYING_GEESE_BRACES) {
|
||||
element.accept(new PsiRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (GeeseUtil.isClosureRBrace(element)) {
|
||||
final Alignment alignment = GeeseUtil.calculateRBraceAlignment(element, innerAlignments);
|
||||
innerAlignments.put(element, alignment);
|
||||
}
|
||||
else {
|
||||
super.visitElement(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
final GroovyBlock block =
|
||||
new GroovyBlock(astNode, null, Indent.getAbsoluteNoneIndent(), null, groovySettings, customSettings, innerAlignments);
|
||||
return new GroovyFormattingModel(containingFile, block, FormattingDocumentModelImpl.createOn(containingFile));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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 org.jetbrains.plugins.groovy.formatter;
|
||||
|
||||
import com.intellij.formatting.Alignment;
|
||||
import com.intellij.formatting.Indent;
|
||||
import com.intellij.formatting.Wrap;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GroovySimpleBlock extends GroovyBlock {
|
||||
public GroovySimpleBlock(@NotNull ASTNode node,
|
||||
@Nullable Alignment alignment,
|
||||
@NotNull Indent indent,
|
||||
@Nullable Wrap wrap,
|
||||
CommonCodeStyleSettings settings,
|
||||
GroovyCodeStyleSettings groovySettings,
|
||||
@NotNull Map<PsiElement, Alignment> innerAlignments, Map<PsiElement, GroovyBlock> blocks) {
|
||||
super(node, alignment, indent, wrap, settings, groovySettings, innerAlignments, blocks);
|
||||
mySubBlocks = new GroovyBlockGenerator(this).generateSubBlocks();
|
||||
}
|
||||
}
|
||||
+32
-20
@@ -33,36 +33,48 @@ import java.util.Map;
|
||||
* @author peter
|
||||
*/
|
||||
public class MethodCallWithoutQualifierBlock extends GroovyBlock {
|
||||
private final TextRange myRange;
|
||||
private final PsiElement myNameElement;
|
||||
private final boolean myTopLevel;
|
||||
private final List<ASTNode> myChildren;
|
||||
private final PsiElement myElem;
|
||||
|
||||
protected MethodCallWithoutQualifierBlock(PsiElement nameElement,
|
||||
Alignment alignment,
|
||||
Wrap wrap,
|
||||
CommonCodeStyleSettings settings,
|
||||
GroovyCodeStyleSettings groovySettings,
|
||||
boolean topLevel,
|
||||
List<ASTNode> children,
|
||||
PsiElement elem,
|
||||
Map<PsiElement, Alignment> innerAlignments, Map<PsiElement, GroovyBlock> blocks) {
|
||||
super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments,blocks);
|
||||
myRange = new TextRange(nameElement.getTextRange().getStartOffset(), elem.getTextRange().getEndOffset());
|
||||
public MethodCallWithoutQualifierBlock(PsiElement nameElement,
|
||||
Alignment alignment,
|
||||
Wrap wrap,
|
||||
CommonCodeStyleSettings settings,
|
||||
GroovyCodeStyleSettings groovySettings,
|
||||
boolean topLevel,
|
||||
List<ASTNode> children,
|
||||
PsiElement elem,
|
||||
Map<PsiElement, Alignment> innerAlignments) {
|
||||
super(nameElement.getNode(), alignment, Indent.getContinuationWithoutFirstIndent(), wrap, settings, groovySettings, innerAlignments);
|
||||
myNameElement = nameElement;
|
||||
myTopLevel = topLevel;
|
||||
myChildren = children;
|
||||
myElem = elem;
|
||||
}
|
||||
|
||||
mySubBlocks = new ArrayList<Block>();
|
||||
final GroovySimpleBlock first =
|
||||
new GroovySimpleBlock(nameElement.getNode(), myInnerAlignments.get(nameElement), Indent.getContinuationWithoutFirstIndent(), myWrap,
|
||||
mySettings, myGroovySettings, myInnerAlignments, myBlocks);
|
||||
mySubBlocks.add(first);
|
||||
new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, topLevel, children, children.size());
|
||||
@NotNull
|
||||
@Override
|
||||
public List<Block> getSubBlocks() {
|
||||
if (mySubBlocks == null) {
|
||||
mySubBlocks = new ArrayList<Block>();
|
||||
mySubBlocks.add(
|
||||
new GroovyBlock(myNameElement.getNode(), myInnerAlignments.get(myNameElement), Indent.getContinuationWithoutFirstIndent(), myWrap,
|
||||
mySettings, myGroovySettings, myInnerAlignments));
|
||||
new GroovyBlockGenerator(this).addNestedChildrenSuffix(mySubBlocks, myAlignment, myTopLevel, myChildren, myChildren.size());
|
||||
}
|
||||
return mySubBlocks;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TextRange getTextRange() {
|
||||
return myRange;
|
||||
return new TextRange(myNameElement.getTextRange().getStartOffset(), myElem.getTextRange().getEndOffset());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLeaf() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,6 +43,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -234,15 +235,25 @@ public class GrabDependencies implements IntentionAction {
|
||||
for (VirtualFile jar : jars) {
|
||||
final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(jar);
|
||||
if (jarRoot != null) {
|
||||
final String libName = "Grab:" + jar.getName();
|
||||
|
||||
final Library existing = tableModel.getLibraryByName(libName);
|
||||
if (existing != null) {
|
||||
tableModel.removeLibrary(existing);
|
||||
OrderRootType rootType = OrderRootType.CLASSES;
|
||||
String libName = "Grab:" + jar.getName();
|
||||
for (String classifier : CollectionFactory.ar("sources", "source", "src")) {
|
||||
if (libName.endsWith("-" + classifier + ".jar")) {
|
||||
rootType = OrderRootType.SOURCES;
|
||||
libName = StringUtil.trimEnd(libName, "-" + classifier + ".jar") + ".jar";
|
||||
}
|
||||
}
|
||||
|
||||
final Library.ModifiableModel libModel = tableModel.createLibrary(libName).getModifiableModel();
|
||||
libModel.addRoot(jarRoot, OrderRootType.CLASSES);
|
||||
Library library = tableModel.getLibraryByName(libName);
|
||||
if (library == null) {
|
||||
library = tableModel.createLibrary(libName);
|
||||
}
|
||||
|
||||
final Library.ModifiableModel libModel = library.getModifiableModel();
|
||||
for (String url : libModel.getUrls(rootType)) {
|
||||
libModel.removeRoot(url, rootType);
|
||||
}
|
||||
libModel.addRoot(jarRoot, rootType);
|
||||
libModel.commit();
|
||||
}
|
||||
}
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2000-2007 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 org.jetbrains.plugins.groovy.griffon;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.mvc.MvcActionBase;
|
||||
import org.jetbrains.plugins.groovy.mvc.MvcFramework;
|
||||
import org.jetbrains.plugins.groovy.mvc.MvcIcons;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class UpdateGriffonSettingsAction extends MvcActionBase {
|
||||
|
||||
@Override
|
||||
protected boolean isFrameworkSupported(@NotNull MvcFramework framework) {
|
||||
return framework == GriffonFramework.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(@NotNull AnActionEvent e, @NotNull final Module module, @NotNull MvcFramework framework) {
|
||||
GriffonFramework.getInstance().updateProjectStructure(module);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateView(AnActionEvent event, @NotNull MvcFramework framework, @NotNull Module module) {
|
||||
event.getPresentation().setIcon(MvcIcons.PLUGINS_REFRESH);
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -663,9 +663,6 @@ mGSTRING_LITERAL = \"\"
|
||||
|
||||
{mGSTRING_LITERAL} { return mGSTRING_LITERAL; }
|
||||
|
||||
"$""/" { yypushback(2);
|
||||
yybegin(WAIT_FOR_REGEX); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////// keywords /////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -738,13 +735,22 @@ mGSTRING_LITERAL = \"\"
|
||||
"?" { yybegin(WAIT_FOR_REGEX);
|
||||
return(mQUESTION); }
|
||||
"/" { if (zzStartRead == 0 ||
|
||||
zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) {
|
||||
yypushback(1);
|
||||
yybegin(WAIT_FOR_REGEX);
|
||||
zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) {
|
||||
yypushback(1);
|
||||
yybegin(WAIT_FOR_REGEX);
|
||||
} else {
|
||||
return(mDIV);
|
||||
}
|
||||
}
|
||||
"$""/" { if (zzStartRead == 0 ||
|
||||
zzBuffer.subSequence(0, zzStartRead).toString().trim().length() == 0) {
|
||||
yypushback(2);
|
||||
yybegin(WAIT_FOR_REGEX);
|
||||
} else {
|
||||
yypushback(1);
|
||||
return(mDOLLAR);
|
||||
}
|
||||
}
|
||||
"/=" { yybegin(WAIT_FOR_REGEX);
|
||||
return(mDIV_ASSIGN); }
|
||||
"(" { yybegin(WAIT_FOR_REGEX);
|
||||
|
||||
@@ -35,6 +35,70 @@ public class GrStringUtil {
|
||||
private GrStringUtil() {
|
||||
}
|
||||
|
||||
public static String escapeForSlashyStrings(String str) {
|
||||
final StringBuilder buffer = new StringBuilder(str.length());
|
||||
escapeSymbolsForSlashyStrings(buffer, str);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static void escapeSymbolsForSlashyStrings(StringBuilder buffer, String str) {
|
||||
final int length = str.length();
|
||||
for (int idx = 0; idx < length; idx++) {
|
||||
char ch = str.charAt(idx);
|
||||
switch (ch) {
|
||||
case '/':
|
||||
buffer.append("\\/");
|
||||
break;
|
||||
default:
|
||||
if (Character.isISOControl(ch) || ch == '$') {
|
||||
appendUnicode(buffer, ch);
|
||||
}
|
||||
else {
|
||||
buffer.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String escapeSymbolsForDollarSlashyStrings(String str) {
|
||||
final StringBuilder buffer = new StringBuilder(str.length());
|
||||
escapeSymbolsForDollarSlashyStrings(buffer, str);
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static void escapeSymbolsForDollarSlashyStrings(StringBuilder buffer, String str) {
|
||||
final int length = str.length();
|
||||
for (int idx = 0; idx < length; idx++) {
|
||||
char ch = str.charAt(idx);
|
||||
switch (ch) {
|
||||
case '/':
|
||||
if (idx + 1 < length && str.charAt(idx + 1) == '$') {
|
||||
appendUnicode(buffer, '/');
|
||||
appendUnicode(buffer, '$');
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (Character.isISOControl(ch)) {
|
||||
appendUnicode(buffer, ch);
|
||||
}
|
||||
else {
|
||||
buffer.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendUnicode(StringBuilder buffer, char ch) {
|
||||
String hexCode = Integer.toHexString(ch).toUpperCase();
|
||||
buffer.append("\\u");
|
||||
int paddingCount = 4 - hexCode.length();
|
||||
while (paddingCount-- > 0) {
|
||||
buffer.append(0);
|
||||
}
|
||||
buffer.append(hexCode);
|
||||
}
|
||||
|
||||
|
||||
public static String escapeSymbolsForGString(String s, boolean escapeDoubleQuotes) {
|
||||
return escapeSymbolsForGString(s, escapeDoubleQuotes, false);
|
||||
}
|
||||
@@ -115,13 +179,7 @@ public class GrStringUtil {
|
||||
buffer.append("\\").append(ch);
|
||||
}
|
||||
else if (Character.isISOControl(ch)) {
|
||||
String hexCode = Integer.toHexString(ch).toUpperCase();
|
||||
buffer.append("\\u");
|
||||
int paddingCount = 4 - hexCode.length();
|
||||
while (paddingCount-- > 0) {
|
||||
buffer.append(0);
|
||||
}
|
||||
buffer.append(hexCode);
|
||||
appendUnicode(buffer, ch);
|
||||
}
|
||||
else {
|
||||
buffer.append(ch);
|
||||
|
||||
+20
-31
@@ -15,56 +15,45 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.AbstractElementManipulator;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.literals.GrLiteralImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
|
||||
|
||||
public class GroovyStringLiteralManipulator extends AbstractElementManipulator<GrLiteral> {
|
||||
public GrLiteral handleContentChange(GrLiteral expr, TextRange range, String newContent) throws IncorrectOperationException {
|
||||
private static final Logger LOG = Logger.getInstance(GroovyStringLiteralManipulator.class);
|
||||
|
||||
public GrLiteralImpl handleContentChange(GrLiteral expr, TextRange range, String newContent) throws IncorrectOperationException {
|
||||
if (!(expr.getValue() instanceof String)) throw new IncorrectOperationException("cannot handle content change");
|
||||
|
||||
LOG.assertTrue(expr instanceof GrLiteralImpl);
|
||||
|
||||
String oldText = expr.getText();
|
||||
if (oldText.startsWith("'")) {
|
||||
newContent = GrStringUtil.escapeSymbolsForString(newContent, !oldText.startsWith("'''"), true);
|
||||
}
|
||||
else if (oldText.startsWith("\"")) {
|
||||
newContent = GrStringUtil.escapeSymbolsForGString(newContent, !oldText.startsWith("\"\"\""), true);
|
||||
}
|
||||
else if (oldText.startsWith("/")) {
|
||||
newContent = StringUtil.escapeSlashes(newContent);
|
||||
}
|
||||
//if there is $/-string we don't need to escape something
|
||||
final String quote = GrStringUtil.getStartQuote(oldText);
|
||||
|
||||
String newText;
|
||||
if (range.getStartOffset() == 1 && (newContent.indexOf('\n') >= 0 || newContent.indexOf('\r') >= 0)) {
|
||||
String corner = oldText.substring(0, 1) + oldText.substring(0, 1) + oldText.substring(0, 1);
|
||||
newText = corner + newContent + corner;
|
||||
if (quote.startsWith("'")) {
|
||||
newContent = GrStringUtil.escapeSymbolsForString(newContent, !quote.equals("'''"), false);
|
||||
}
|
||||
else {
|
||||
newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset());
|
||||
else if (quote.startsWith("\"")) {
|
||||
newContent = GrStringUtil.escapeSymbolsForGString(newContent, !quote.equals("\"\"\""), true);
|
||||
}
|
||||
else if ("/".equals(quote)) {
|
||||
newContent = GrStringUtil.escapeForSlashyStrings(newContent);
|
||||
}
|
||||
else if ("$/".equals(quote)) {
|
||||
newContent = GrStringUtil.escapeSymbolsForDollarSlashyStrings(newContent);
|
||||
}
|
||||
final GrExpression newExpr = GroovyPsiElementFactory.getInstance(expr.getProject()).createExpressionFromText(newText);
|
||||
|
||||
PsiElement firstChild = expr.getFirstChild();
|
||||
assert firstChild != null && firstChild.getNextSibling() == null;
|
||||
|
||||
PsiElement newElement = newExpr.getFirstChild();
|
||||
assert newElement != null;
|
||||
firstChild.replace(newElement);
|
||||
|
||||
return expr;
|
||||
String newText = oldText.substring(0, range.getStartOffset()) + newContent + oldText.substring(range.getEndOffset());
|
||||
return ((GrLiteralImpl)expr).updateText(newText);
|
||||
}
|
||||
|
||||
public TextRange getRangeInElement(final GrLiteral element) {
|
||||
final String text = element.getText();
|
||||
if (element instanceof GrLiteralImpl && !(element.getValue() instanceof String)) {
|
||||
if (!(element.getValue() instanceof String)) {
|
||||
return super.getRangeInElement(element);
|
||||
}
|
||||
return getLiteralRange(text);
|
||||
|
||||
@@ -18,12 +18,12 @@ public abstract class MvcActionBase extends DumbAwareAction {
|
||||
@Override
|
||||
public final void actionPerformed(AnActionEvent e) {
|
||||
Pair<MvcFramework, Module> pair = guessFramework(e);
|
||||
if (pair != null && isSupportFramework(pair.getFirst())) {
|
||||
if (pair != null && isFrameworkSupported(pair.getFirst())) {
|
||||
actionPerformed(e, pair.getSecond(), pair.getFirst());
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isSupportFramework(@NotNull MvcFramework framework) {
|
||||
protected boolean isFrameworkSupported(@NotNull MvcFramework framework) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public abstract class MvcActionBase extends DumbAwareAction {
|
||||
|
||||
public final void update(AnActionEvent event) {
|
||||
Pair<MvcFramework, Module> pair = guessFramework(event);
|
||||
if (pair != null && isSupportFramework(pair.getFirst())) {
|
||||
if (pair != null && isFrameworkSupported(pair.getFirst())) {
|
||||
event.getPresentation().setVisible(true);
|
||||
updateView(event, pair.getFirst(), pair.getSecond());
|
||||
}
|
||||
|
||||
@@ -323,6 +323,8 @@ public class MvcConsole implements Disposable {
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (myProject.isDisposed()) return;
|
||||
|
||||
module.putUserData(UPDATING_BY_CONSOLE_PROCESS, true);
|
||||
LocalFileSystem.getInstance().refresh(false);
|
||||
module.putUserData(UPDATING_BY_CONSOLE_PROCESS, null);
|
||||
|
||||
+4
-2
@@ -265,12 +265,14 @@ public class GrIntroduceFieldHandler extends GrIntroduceHandlerBase<GrIntroduceF
|
||||
private static GrReferenceExpression createRefExpression(GrField field, PsiElement place) {
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
LOG.assertTrue(containingClass != null);
|
||||
final String qname = containingClass.getQualifiedName();
|
||||
final String prefix = qname != null ? qname + "." : "";
|
||||
final String refText;
|
||||
if (field.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
refText = containingClass.getQualifiedName() + "." + field.getName();
|
||||
refText = prefix + field.getName();
|
||||
}
|
||||
else {
|
||||
refText = containingClass.getQualifiedName() + ".this." + field.getName();
|
||||
refText = prefix + "this." + field.getName();
|
||||
}
|
||||
return GroovyPsiElementFactory.getInstance(place.getProject()).createReferenceExpressionFromText(refText, place);
|
||||
}
|
||||
|
||||
+4
@@ -179,6 +179,10 @@ public class ExpressionsParsingTest extends GroovyParsingTestCase {
|
||||
public void testregex$dollarSlashy3() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashy4() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashy5() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashy6() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashy7() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashy8() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashy9() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashyCode() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashyCodeUnfinished() throws Throwable { doTest(); }
|
||||
public void testregex$dollarSlashyEof() throws Throwable { doTest(); }
|
||||
|
||||
+4
@@ -69,6 +69,10 @@ public class GrIntroduceFieldTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testReplaceExpressionWithAssignment() {
|
||||
doTest(false, false, false, CUR_METHOD, false, null);
|
||||
}
|
||||
|
||||
public void testAnonymousClass() {
|
||||
doTest(false, false, false, CUR_METHOD, false, null);
|
||||
}
|
||||
|
||||
private void doTest(final boolean isStatic,
|
||||
final boolean removeLocal,
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
print <error descr="Dollar-slashy strings cannot be the first argument of a command method call">$/abc/$</error>
|
||||
print <error descr="Dollar-slashy strings cannot be the first argument of a command method call">$/a$bc/$</error>
|
||||
print <error descr="';' or new line expected">$/abc/$</error>
|
||||
print <error descr="';' or new line expected">$/a$bc/$</error>
|
||||
@@ -0,0 +1,8 @@
|
||||
$/abc/$
|
||||
-----
|
||||
Groovy script
|
||||
Literal
|
||||
GroovyASTPsiElementImpl($/ regex literal)
|
||||
PsiElement($/ regex begin)('$/')
|
||||
PsiElement($/ regex content)('abc')
|
||||
PsiElement($/ regex end)('/$')
|
||||
@@ -0,0 +1,12 @@
|
||||
print $/abc/$
|
||||
-----
|
||||
Groovy script
|
||||
Reference expression
|
||||
PsiElement(identifier)('print')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:';' or new line expected
|
||||
PsiElement($)('$')
|
||||
PsiElement(/)('/')
|
||||
PsiElement(identifier)('abc')
|
||||
PsiElement(/)('/')
|
||||
PsiElement(identifier)('$')
|
||||
@@ -0,0 +1,14 @@
|
||||
print($/abc/$)
|
||||
-----
|
||||
Groovy script
|
||||
Method call
|
||||
Reference expression
|
||||
PsiElement(identifier)('print')
|
||||
Arguments
|
||||
PsiElement(()('(')
|
||||
Literal
|
||||
GroovyASTPsiElementImpl($/ regex literal)
|
||||
PsiElement($/ regex begin)('$/')
|
||||
PsiElement($/ regex content)('abc')
|
||||
PsiElement($/ regex end)('/$')
|
||||
PsiElement())(')')
|
||||
@@ -0,0 +1,17 @@
|
||||
print a, $/a/$
|
||||
-----
|
||||
Groovy script
|
||||
Call expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('print')
|
||||
PsiWhiteSpace(' ')
|
||||
Command arguments
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Literal
|
||||
GroovyASTPsiElementImpl($/ regex literal)
|
||||
PsiElement($/ regex begin)('$/')
|
||||
PsiElement($/ regex content)('a')
|
||||
PsiElement($/ regex end)('/$')
|
||||
@@ -0,0 +1,10 @@
|
||||
interface A {
|
||||
void m1()
|
||||
}
|
||||
|
||||
def a = new A() {
|
||||
@Override
|
||||
void m1() {
|
||||
println <selection>123</selection>
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
interface A {
|
||||
void m1()
|
||||
}
|
||||
|
||||
def a = new A() {
|
||||
def f
|
||||
|
||||
@Override
|
||||
void m1() {
|
||||
f = 123
|
||||
println <selection>f</selection>
|
||||
}
|
||||
}
|
||||
@@ -184,13 +184,11 @@ public class DefaultXmlExtension extends XmlExtension {
|
||||
}
|
||||
|
||||
final List<XmlSchemaProvider> providers = XmlSchemaProvider.getAvailableProviders(file);
|
||||
XmlSchemaProvider prefixProvider = null;
|
||||
String prefix = nsPrefix;
|
||||
if (prefix == null) {
|
||||
for (XmlSchemaProvider provider : providers) {
|
||||
prefix = provider.getDefaultPrefix(namespace, file);
|
||||
if (prefix != null) {
|
||||
prefixProvider = provider;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -210,10 +208,10 @@ public class DefaultXmlExtension extends XmlExtension {
|
||||
|
||||
String location = null;
|
||||
if (namespace.length() > 0) {
|
||||
if (prefixProvider != null) {
|
||||
final Set<String> strings = prefixProvider.getLocations(namespace, file);
|
||||
if (strings != null && strings.size() > 0) {
|
||||
location = strings.iterator().next();
|
||||
for (XmlSchemaProvider provider : providers) {
|
||||
Set<String> locations = provider.getLocations(namespace, file);
|
||||
if (locations != null && !locations.isEmpty()) {
|
||||
location = locations.iterator().next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user