mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
async structure view: tool window
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.ide.structureView;
|
||||
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
/**
|
||||
* @author gregsh
|
||||
*/
|
||||
public interface HelpID {
|
||||
@NonNls String STRUCTURE_VIEW = "viewingStructure.fileStructureView";
|
||||
}
|
||||
+16
-45
@@ -17,9 +17,12 @@ package com.intellij.ide.structureView.impl;
|
||||
|
||||
import com.intellij.ide.IdeBundle;
|
||||
import com.intellij.ide.impl.StructureViewWrapperImpl;
|
||||
import com.intellij.ide.structureView.*;
|
||||
import com.intellij.ide.structureView.StructureView;
|
||||
import com.intellij.ide.structureView.StructureViewBuilder;
|
||||
import com.intellij.ide.structureView.StructureViewFactoryEx;
|
||||
import com.intellij.ide.structureView.StructureViewWrapper;
|
||||
import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
|
||||
import com.intellij.ide.util.treeView.smartTree.TreeElement;
|
||||
import com.intellij.ide.util.treeView.TreeState;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageStructureViewBuilder;
|
||||
import com.intellij.lang.PsiStructureViewFactory;
|
||||
@@ -33,7 +36,10 @@ import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
|
||||
import com.intellij.psi.util.PsiModificationTracker;
|
||||
import com.intellij.util.Alarm;
|
||||
@@ -41,6 +47,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -64,7 +71,7 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
|
||||
|
||||
private void updateAfterPsiChange() {
|
||||
if (myProject.isDisposed()) return;
|
||||
if (myBaseStructureViewDescriptor != null && ((StructureViewComponent)myBaseStructureViewDescriptor.structureView).getTree() == null) return;
|
||||
if (((StructureViewComponent)myBaseStructureViewDescriptor.structureView).isDisposed()) return;
|
||||
ApplicationManager.getApplication().runReadAction(() -> {
|
||||
if (!myVirtualFile.isValid() || getViewProvider() == null) return;
|
||||
|
||||
@@ -84,20 +91,10 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
|
||||
}
|
||||
|
||||
private static boolean isPsiValid(@NotNull StructureViewComposite.StructureViewDescriptor baseStructureViewDescriptor) {
|
||||
final StructureViewComponent view = (StructureViewComponent)baseStructureViewDescriptor.structureView;
|
||||
StructureViewComponent view = (StructureViewComponent)baseStructureViewDescriptor.structureView;
|
||||
if (view.isDisposed()) return false;
|
||||
|
||||
final Object root = view.getTreeStructure().getRootElement();
|
||||
if (root instanceof StructureViewComponent.StructureViewTreeElementWrapper) {
|
||||
final TreeElement value = ((StructureViewComponent.StructureViewTreeElementWrapper)root).getValue();
|
||||
if (value instanceof StructureViewTreeElement) {
|
||||
final Object psi = ((StructureViewTreeElement)value).getValue();
|
||||
if (psi instanceof PsiElement) {
|
||||
return ((PsiElement)psi).isValid();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
Object value = StructureViewComponent.unwrapValue(view.getTree().getModel().getRoot());
|
||||
return !(value instanceof PsiElement && !((PsiElement)value).isValid());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -117,37 +114,11 @@ public abstract class TemplateLanguageStructureViewBuilder implements StructureV
|
||||
final StructureViewComponent view = (StructureViewComponent)myBaseStructureViewDescriptor.structureView;
|
||||
if (view.isDisposed()) return;
|
||||
|
||||
StructureViewState state = view.getState();
|
||||
List<PsiAnchor> expanded = collectAnchors(state.getExpandedElements());
|
||||
List<PsiAnchor> selected = collectAnchors(state.getSelectedElements());
|
||||
TreeState treeState = TreeState.createOn(view.getTree(), new TreePath(view.getTree().getModel().getRoot()));
|
||||
updateTemplateDataFileView();
|
||||
|
||||
if (view.isDisposed()) return;
|
||||
|
||||
for (PsiAnchor pointer : expanded) {
|
||||
PsiElement element = pointer.retrieve();
|
||||
if (element != null) {
|
||||
view.expandPathToElement(element);
|
||||
}
|
||||
}
|
||||
for (PsiAnchor pointer : selected) {
|
||||
PsiElement element = pointer.retrieve();
|
||||
if (element != null) {
|
||||
view.addSelectionPathTo(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<PsiAnchor> collectAnchors(final Object[] expandedElements) {
|
||||
List<PsiAnchor> expanded = new ArrayList<>(expandedElements == null ? 0 : expandedElements.length);
|
||||
if (expandedElements != null) {
|
||||
for (Object element : expandedElements) {
|
||||
if (element instanceof PsiElement && ((PsiElement) element).isValid()) {
|
||||
expanded.add(PsiAnchor.create((PsiElement)element));
|
||||
}
|
||||
}
|
||||
}
|
||||
return expanded;
|
||||
treeState.applyTo(view.getTree());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+9
-13
@@ -48,7 +48,7 @@ public class StructureTreeBuilder extends AbstractTreeBuilder {
|
||||
private final StructureViewModel myStructureModel;
|
||||
|
||||
private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, this);
|
||||
|
||||
|
||||
public StructureTreeBuilder(Project project,
|
||||
JTree tree,
|
||||
DefaultTreeModel treeModel,
|
||||
@@ -93,20 +93,16 @@ public class StructureTreeBuilder extends AbstractTreeBuilder {
|
||||
protected final boolean isAutoExpandNode(NodeDescriptor nodeDescriptor) {
|
||||
StructureViewModel model = myStructureModel;
|
||||
if (model instanceof TreeModelWrapper) {
|
||||
model = ((TreeModelWrapper) model).getModel();
|
||||
model = ((TreeModelWrapper)model).getModel();
|
||||
}
|
||||
if (model instanceof StructureViewModel.ExpandInfoProvider) {
|
||||
StructureViewModel.ExpandInfoProvider provider = (StructureViewModel.ExpandInfoProvider)model;
|
||||
Object element = nodeDescriptor.getElement();
|
||||
if (element instanceof StructureViewComponent.StructureViewTreeElementWrapper) {
|
||||
StructureViewComponent.StructureViewTreeElementWrapper wrapper = (StructureViewComponent.StructureViewTreeElementWrapper)element;
|
||||
if (wrapper.getValue() instanceof StructureViewTreeElement) {
|
||||
final StructureViewTreeElement value = (StructureViewTreeElement)wrapper.getValue();
|
||||
if (value != null) {
|
||||
return provider.isAutoExpand(value);
|
||||
}
|
||||
}
|
||||
} else if (element instanceof GroupWrapper) {
|
||||
Object value = StructureViewComponent.unwrapValue(element);
|
||||
if (value instanceof StructureViewTreeElement) {
|
||||
return provider.isAutoExpand((StructureViewTreeElement)value);
|
||||
}
|
||||
else if (element instanceof GroupWrapper) {
|
||||
final Group group = ((GroupWrapper)element).getValue();
|
||||
for (TreeElement treeElement : group.getChildren()) {
|
||||
if (treeElement instanceof StructureViewTreeElement && !provider.isAutoExpand((StructureViewTreeElement)treeElement)) {
|
||||
@@ -124,7 +120,7 @@ public class StructureTreeBuilder extends AbstractTreeBuilder {
|
||||
protected final boolean isSmartExpand() {
|
||||
StructureViewModel model = myStructureModel;
|
||||
if (model instanceof TreeModelWrapper) {
|
||||
model = ((TreeModelWrapper) model).getModel();
|
||||
model = ((TreeModelWrapper)model).getModel();
|
||||
}
|
||||
if (model instanceof StructureViewModel.ExpandInfoProvider) {
|
||||
return ((StructureViewModel.ExpandInfoProvider)model).isSmartExpand();
|
||||
@@ -215,6 +211,6 @@ public class StructureTreeBuilder extends AbstractTreeBuilder {
|
||||
@Override
|
||||
@NotNull
|
||||
protected final AbstractTreeNode createSearchingTreeNodeWrapper() {
|
||||
return new StructureViewComponent.StructureViewTreeElementWrapper(null,null, null);
|
||||
return StructureViewComponent.createWrapper(null, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
+544
-386
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,6 @@ import com.intellij.ide.dnd.aware.DnDAwareTree;
|
||||
import com.intellij.ide.structureView.ModelListener;
|
||||
import com.intellij.ide.structureView.StructureView;
|
||||
import com.intellij.ide.structureView.StructureViewModel;
|
||||
import com.intellij.ide.structureView.StructureViewTreeElement;
|
||||
import com.intellij.ide.structureView.impl.StructureViewComposite;
|
||||
import com.intellij.ide.structureView.impl.common.PsiTreeElementBase;
|
||||
import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
|
||||
@@ -34,8 +33,8 @@ import com.intellij.ide.structureView.newStructureView.TreeActionsOwner;
|
||||
import com.intellij.ide.structureView.newStructureView.TreeModelWrapper;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.ide.util.treeView.NodeRenderer;
|
||||
import com.intellij.ide.util.treeView.ValidateableNode;
|
||||
import com.intellij.ide.util.treeView.smartTree.*;
|
||||
import com.intellij.navigation.ItemPresentation;
|
||||
import com.intellij.navigation.LocationPresentation;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.MnemonicHelper;
|
||||
@@ -181,7 +180,7 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
|
||||
|
||||
@Override
|
||||
protected TreeElementWrapper createTree() {
|
||||
return new StructureViewComponent.StructureViewTreeElementWrapper(myProject, myModel.getRoot(), myModel);
|
||||
return StructureViewComponent.createWrapper(myProject, myModel.getRoot(), myModel);
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@@ -260,7 +259,9 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
|
||||
|
||||
@Override
|
||||
protected boolean validateNode(Object child) {
|
||||
return StructureViewComponent.isValid(child);
|
||||
Object o = child instanceof FilteringTreeStructure.FilteringNode ?
|
||||
((FilteringTreeStructure.FilteringNode)child).getDelegate() : child;
|
||||
return !(o instanceof ValidateableNode) || ((ValidateableNode)o).isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -504,17 +505,7 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
|
||||
|
||||
@Nullable
|
||||
private PsiElement getPsi(FilteringTreeStructure.FilteringNode n) {
|
||||
final Object delegate = n.getDelegate();
|
||||
if (delegate instanceof StructureViewComponent.StructureViewTreeElementWrapper) {
|
||||
final TreeElement value = ((StructureViewComponent.StructureViewTreeElementWrapper)delegate).getValue();
|
||||
if (value instanceof StructureViewTreeElement) {
|
||||
final Object element = ((StructureViewTreeElement)value).getValue();
|
||||
if (element instanceof PsiElement) {
|
||||
return (PsiElement)element;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return ObjectUtils.tryCast(StructureViewComponent.unwrapValue(n.getDelegate()), PsiElement.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -924,38 +915,32 @@ public class FileStructurePopup implements Disposable, TreeActionsOwner {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getSpeedSearchText(final Object userObject) {
|
||||
public static String getSpeedSearchText(Object userObject) {
|
||||
String text = String.valueOf(userObject);
|
||||
TreeElement unwrapped = (TreeElement)StructureViewComponent.unwrapWrapper(userObject);
|
||||
if (text != null) {
|
||||
if (userObject instanceof StructureViewComponent.StructureViewTreeElementWrapper) {
|
||||
final TreeElement value = ((StructureViewComponent.StructureViewTreeElementWrapper)userObject).getValue();
|
||||
if (value instanceof PsiTreeElementBase && ((PsiTreeElementBase)value).isSearchInLocationString()) {
|
||||
final String locationString = ((PsiTreeElementBase)value).getLocationString();
|
||||
if (!StringUtil.isEmpty(locationString)) {
|
||||
String locationPrefix = null;
|
||||
String locationSuffix = null;
|
||||
if (value instanceof LocationPresentation) {
|
||||
locationPrefix = ((LocationPresentation)value).getLocationPrefix();
|
||||
locationSuffix = ((LocationPresentation)value).getLocationSuffix();
|
||||
}
|
||||
|
||||
return text +
|
||||
StringUtil.notNullize(locationPrefix, LocationPresentation.DEFAULT_LOCATION_PREFIX) +
|
||||
locationString +
|
||||
StringUtil.notNullize(locationSuffix, LocationPresentation.DEFAULT_LOCATION_SUFFIX);
|
||||
if (unwrapped instanceof PsiTreeElementBase && ((PsiTreeElementBase)unwrapped).isSearchInLocationString()) {
|
||||
String locationString = ((PsiTreeElementBase)unwrapped).getLocationString();
|
||||
if (!StringUtil.isEmpty(locationString)) {
|
||||
String locationPrefix = null;
|
||||
String locationSuffix = null;
|
||||
if (unwrapped instanceof LocationPresentation) {
|
||||
locationPrefix = ((LocationPresentation)unwrapped).getLocationPrefix();
|
||||
locationSuffix = ((LocationPresentation)unwrapped).getLocationSuffix();
|
||||
}
|
||||
|
||||
return text +
|
||||
StringUtil.notNullize(locationPrefix, LocationPresentation.DEFAULT_LOCATION_PREFIX) +
|
||||
locationString +
|
||||
StringUtil.notNullize(locationSuffix, LocationPresentation.DEFAULT_LOCATION_SUFFIX);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
// NB!: this point is achievable if the following method returns null
|
||||
// see com.intellij.ide.util.treeView.NodeDescriptor.toString
|
||||
if (userObject instanceof StructureViewComponent.StructureViewTreeElementWrapper) {
|
||||
return ReadAction.compute(() -> {
|
||||
final ItemPresentation presentation =
|
||||
((StructureViewComponent.StructureViewTreeElementWrapper)userObject).getValue().getPresentation();
|
||||
return presentation.getPresentableText();
|
||||
});
|
||||
if (unwrapped != null) {
|
||||
return ReadAction.compute(() -> unwrapped.getPresentation().getPresentableText());
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -25,20 +25,16 @@ import com.intellij.util.concurrency.Invoker;
|
||||
import com.intellij.util.concurrency.InvokerSupplier;
|
||||
import com.intellij.util.ui.tree.AbstractTreeModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.concurrency.AsyncPromise;
|
||||
import org.jetbrains.concurrency.Promise;
|
||||
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.MutableTreeNode;
|
||||
import javax.swing.tree.TreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.enumeration;
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
import static java.util.Collections.*;
|
||||
|
||||
/**
|
||||
* @author Sergey.Malenkov
|
||||
@@ -95,14 +91,22 @@ public class StructureTreeModel extends AbstractTreeModel implements Disposable,
|
||||
return false;
|
||||
}
|
||||
|
||||
public final void invalidate() {
|
||||
@NotNull
|
||||
public final Promise<?> invalidate() {
|
||||
AsyncPromise<Object> promise = new AsyncPromise<>();
|
||||
invoker.invokeLaterIfNeeded(() -> {
|
||||
if (disposed) return;
|
||||
if (disposed) {
|
||||
promise.setError("rejected");
|
||||
return;
|
||||
}
|
||||
root.invalidate();
|
||||
Node node = root.get();
|
||||
LOG.debug("root invalidated: ", node);
|
||||
if (node != null) node.invalidate();
|
||||
treeStructureChanged(null, null, null);
|
||||
promise.setResult(null);
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
|
||||
public final void invalidate(@NotNull TreePath path, boolean structure) {
|
||||
@@ -127,7 +131,11 @@ public class StructureTreeModel extends AbstractTreeModel implements Disposable,
|
||||
public final Object getRoot() {
|
||||
if (disposed || !isValidThread()) return null;
|
||||
if (!root.isValid()) {
|
||||
root.set(getValidRoot());
|
||||
Node validRoot = getValidRoot();
|
||||
LOG.debug("old root: " + root.get());
|
||||
LOG.debug("new root: " + validRoot);
|
||||
LOG.debug(new IllegalStateException());
|
||||
root.set(validRoot);
|
||||
}
|
||||
return root.get();
|
||||
}
|
||||
|
||||
-43
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.intellij.ide.structureView.impl;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author Yura Cangea
|
||||
*/
|
||||
public final class StructureViewState {
|
||||
private Object[] myExpandedElements;
|
||||
private Object[] mySelectedElements;
|
||||
|
||||
public Object[] getExpandedElements() {
|
||||
return myExpandedElements;
|
||||
}
|
||||
|
||||
public void setExpandedElements(Object[] expandedElements) {
|
||||
myExpandedElements = expandedElements;
|
||||
}
|
||||
|
||||
public Object[] getSelectedElements() {
|
||||
return mySelectedElements;
|
||||
}
|
||||
|
||||
public void setSelectedElements(Object[] selectedElements) {
|
||||
mySelectedElements = selectedElements;
|
||||
}
|
||||
}
|
||||
@@ -157,11 +157,9 @@ class NewPropertyAction extends AnAction {
|
||||
});
|
||||
|
||||
resourceBundleEditor.updateTreeRoot();
|
||||
resourceBundleEditor
|
||||
.getStructureViewComponent()
|
||||
.getTreeBuilder()
|
||||
.queueUpdate()
|
||||
.doWhenDone(() -> finalResourceBundleEditor.selectProperty(keyToInsert));
|
||||
resourceBundleEditor.getStructureViewComponent()
|
||||
.select(keyToInsert, false)
|
||||
.processed(p -> finalResourceBundleEditor.selectProperty(keyToInsert));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-41
@@ -25,7 +25,6 @@ import com.intellij.ide.structureView.newStructureView.StructureViewComponent;
|
||||
import com.intellij.ide.ui.customization.CustomActionsSchema;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeUi;
|
||||
import com.intellij.ide.util.treeView.smartTree.CachingChildrenTreeNode;
|
||||
import com.intellij.ide.util.treeView.smartTree.Sorter;
|
||||
import com.intellij.ide.util.treeView.smartTree.TreeElement;
|
||||
import com.intellij.lang.properties.IProperty;
|
||||
@@ -76,12 +75,13 @@ import com.intellij.ui.components.JBScrollPane;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.EditorPopupHandler;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.NullableFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.ContainerUtilRt;
|
||||
import com.intellij.util.containers.JBIterable;
|
||||
import com.intellij.util.containers.Stack;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.tree.TreeUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -92,8 +92,6 @@ import javax.swing.*;
|
||||
import javax.swing.border.TitledBorder;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.TreePath;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
@@ -228,10 +226,7 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
}
|
||||
|
||||
public void updateTreeRoot() {
|
||||
final Object element = myStructureViewComponent.getTreeStructure().getRootElement();
|
||||
if (element instanceof CachingChildrenTreeNode) {
|
||||
((CachingChildrenTreeNode)element).rebuildChildren();
|
||||
}
|
||||
myStructureViewComponent.rebuild();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -280,10 +275,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
return;
|
||||
}
|
||||
JTree tree = myStructureViewComponent.getTree();
|
||||
if (tree == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object root = tree.getModel().getRoot();
|
||||
if (AbstractTreeUi.isLoadingChildrenFor(root)) {
|
||||
boolean isEditorVisible = false;
|
||||
@@ -360,14 +351,6 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ResourceBundleEditorViewElement getSelectedElement(@NotNull DefaultMutableTreeNode node) {
|
||||
Object userObject = node.getUserObject();
|
||||
if (!(userObject instanceof AbstractTreeNode)) return null;
|
||||
Object value = ((AbstractTreeNode)userObject).getValue();
|
||||
return value instanceof ResourceBundleEditorViewElement ? (ResourceBundleEditorViewElement) value : null;
|
||||
}
|
||||
|
||||
private void writeEditorPropertyValue(final @Nullable String propertyName,
|
||||
final @NotNull Editor editor,
|
||||
final @NotNull VirtualFile propertiesFile) {
|
||||
@@ -597,15 +580,13 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<DefaultMutableTreeNode> getSelectedNodes() {
|
||||
private JBIterable<Object> getSelectedNodes() {
|
||||
if (!isValid()) {
|
||||
return Collections.emptyList();
|
||||
return JBIterable.empty();
|
||||
}
|
||||
JTree tree = myStructureViewComponent.getTree();
|
||||
if (tree == null) return Collections.emptyList();
|
||||
TreePath[] selected = tree.getSelectionModel().getSelectionPaths();
|
||||
if (selected == null || selected.length == 0) return Collections.emptyList();
|
||||
return ContainerUtil.map(selected, treePath -> (DefaultMutableTreeNode)treePath.getLastPathComponent());
|
||||
return JBIterable.of(tree.getSelectionModel().getSelectionPaths())
|
||||
.map(o -> TreeUtil.getUserObject(o.getLastPathComponent()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -616,25 +597,22 @@ public class ResourceBundleEditor extends UserDataHolderBase implements Document
|
||||
|
||||
@Nullable
|
||||
IProperty getSelectedProperty() {
|
||||
final Collection<DefaultMutableTreeNode> selectedNode = getSelectedNodes();
|
||||
if (selectedNode.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final ResourceBundleEditorViewElement element = getSelectedElement(ContainerUtil.getFirstItem(selectedNode));
|
||||
return element instanceof ResourceBundlePropertyStructureViewElement ? ((ResourceBundlePropertyStructureViewElement)element).getProperty()
|
||||
: null;
|
||||
ResourceBundleEditorViewElement first = getSelectedNodes()
|
||||
.filter(AbstractTreeNode.class)
|
||||
.filterMap(AbstractTreeNode::getValue)
|
||||
.filter(ResourceBundleEditorViewElement.class)
|
||||
.first();
|
||||
return first instanceof ResourceBundlePropertyStructureViewElement ?
|
||||
((ResourceBundlePropertyStructureViewElement)first).getProperty() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<ResourceBundleEditorViewElement> getSelectedElements() {
|
||||
final Collection<DefaultMutableTreeNode> selectedNodes = getSelectedNodes();
|
||||
return ContainerUtil.mapNotNull(selectedNodes,
|
||||
(NullableFunction<DefaultMutableTreeNode, ResourceBundleEditorViewElement>)selectedNode -> {
|
||||
Object userObject = selectedNode.getUserObject();
|
||||
if (!(userObject instanceof AbstractTreeNode)) return null;
|
||||
Object value = ((AbstractTreeNode)userObject).getValue();
|
||||
return value instanceof ResourceBundleEditorViewElement ? (ResourceBundleEditorViewElement) value : null;
|
||||
});
|
||||
return getSelectedNodes()
|
||||
.filter(AbstractTreeNode.class)
|
||||
.filterMap(AbstractTreeNode::getValue)
|
||||
.filter(ResourceBundleEditorViewElement.class)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -387,6 +387,9 @@
|
||||
<experimentalFeature id="project.view.async.tree.model" internalFeature="true" percentOfUsers="10" requireRestart="true">
|
||||
<description>New implementation based on AsyncTreeModel + StructureTreeModel</description>
|
||||
</experimentalFeature>
|
||||
<experimentalFeature id="structure.view.async.tree.model" internalFeature="true" percentOfUsers="10" requireRestart="false">
|
||||
<description>New implementation based on AsyncTreeModel + StructureTreeModel</description>
|
||||
</experimentalFeature>
|
||||
|
||||
<editorActionHandler action="EditorChooseLookupItemReplace"
|
||||
implementationClass="com.intellij.codeInsight.hint.NextParameterAfterCompletionHandler"/>
|
||||
|
||||
Reference in New Issue
Block a user