# HG changeset patch # User Vladimir Kvashin # Date 1491162999 -10800 # Sun Apr 02 22:56:39 2017 +0300 # Branch release82 # Node ID 9d2f3b1aada4c197bb139734a70a783d4f202537 # Parent c38319da61697ace5575157b97251839c607bc18 fixing #270034 - Inconveniences when working with multiple specializations diff -r c38319da6169 -r 9d2f3b1aada4 cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/ClassHierarchyPanel.java --- a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/ClassHierarchyPanel.java Thu Mar 30 20:21:32 2017 +0300 +++ b/cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/ClassHierarchyPanel.java Sun Apr 02 22:56:39 2017 +0300 @@ -657,7 +657,7 @@ children.remove(children.getNodes()); HierarchyModel curModel = model; if (curModel != null) { - final Node node = new HierarchyNode(csmClass, curModel, null); + final Node node = new HierarchyNode(csmClass, curModel, null, false); children.add(new Node[]{node}); try { getExplorerManager().setSelectedNodes(new Node[]{node}); diff -r c38319da6169 -r 9d2f3b1aada4 cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/HierarchyChildren.java --- a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/HierarchyChildren.java Thu Mar 30 20:21:32 2017 +0300 +++ b/cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/HierarchyChildren.java Sun Apr 02 22:56:39 2017 +0300 @@ -49,6 +49,8 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedQueue; import org.netbeans.modules.cnd.api.model.CsmClass; import org.netbeans.modules.cnd.api.model.CsmFile; import org.netbeans.modules.cnd.api.model.CsmFriend; @@ -77,6 +79,7 @@ private final HierarchyModel model; private final HierarchyChildren parent; private boolean isInited = false; + private ConcurrentLinkedQueue specializations = new ConcurrentLinkedQueue(); public HierarchyChildren(CsmClass object, HierarchyModel model, HierarchyChildren parent) { this.object = object; @@ -87,13 +90,24 @@ public void dispose(){ if (isInited) { isInited = false; - resetKeys(Collections.emptyList()); + resetKeys(); } } - private synchronized void resetKeys(List list) { - if (list.size() > 1) { - Collections.sort(list, COMARATOR); + private synchronized void resetKeys() { + resetKeys(Collections.emptyList(), Collections.emptyList()); + } + + /** @param list will be changed! */ + private synchronized void resetKeys(List list, List specList) { + specializations.clear(); + if (!list.isEmpty() || !specList.isEmpty()) { + specializations.addAll(specList); + list = new ArrayList(list); + list.addAll(specList); + if (list.size() > 1) { + Collections.sort(list, COMARATOR); + } } setKeys(list); } @@ -104,10 +118,14 @@ if (cls instanceof DummyClass) { node = new LoadingNode(); } else { + final boolean specialization = specializations.contains(cls); + if (specialization) { + System.err.println("HAHAHA"); + } if (checkRecursion(cls)) { - node = new HierarchyNode(cls, Children.LEAF, model, true); + node = new HierarchyNode(cls, Children.LEAF, model, true, specialization); } else { - node = new HierarchyNode(cls, model, this); + node = new HierarchyNode(cls, model, this, specialization); } } return new Node[]{node}; @@ -131,19 +149,23 @@ protected void addNotify() { isInited = true; if (!object.isValid()) { - resetKeys(Collections.emptyList()); + resetKeys(); } else { - resetKeys(Collections.singletonList(new DummyClass())); + resetKeys(Collections.singletonList(new DummyClass()), Collections.emptyList()); RP.post(new Runnable(){ @Override public void run() { Collection set = model.getHierarchy(object); + Collection specSet = model.getSpecializationsHierarchy(object); + List list = Collections.emptyList(); + List specList = Collections.emptyList(); if (set != null && set.size() > 0) { - List list = new ArrayList(set); - resetKeys(list); - } else { - resetKeys(Collections.emptyList()); + list = new ArrayList(set); } + if (specSet != null && specSet.size() > 0) { + specList = new ArrayList(specSet); + } + resetKeys(list, specList); } }); } diff -r c38319da6169 -r 9d2f3b1aada4 cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/HierarchyNode.java --- a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/HierarchyNode.java Thu Mar 30 20:21:32 2017 +0300 +++ b/cnd.navigation/src/org/netbeans/modules/cnd/navigation/classhierarchy/HierarchyNode.java Sun Apr 02 22:56:39 2017 +0300 @@ -44,11 +44,18 @@ package org.netbeans.modules.cnd.navigation.classhierarchy; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Image; import java.awt.event.ActionEvent; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import javax.swing.Action; +import javax.swing.ImageIcon; import org.netbeans.modules.cnd.api.model.CsmClass; import org.netbeans.modules.cnd.api.model.CsmDeclaration; import org.netbeans.modules.cnd.api.model.CsmObject; @@ -56,8 +63,10 @@ import org.netbeans.modules.cnd.api.model.CsmProject; import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities; import org.netbeans.modules.cnd.modelutil.AbstractCsmNode; +import org.netbeans.modules.cnd.modelutil.CsmImageLoader; import org.netbeans.modules.cnd.navigation.services.HierarchyModel; import org.openide.nodes.Children; +import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; /** @@ -68,12 +77,13 @@ private CsmProject project; private HierarchyModel model; private CharSequence uin; + private boolean specialization; - public HierarchyNode(CsmClass element, HierarchyModel model, HierarchyChildren parent) { - this(element, new HierarchyChildren(element, model, parent), model, false); + public HierarchyNode(CsmClass element, HierarchyModel model, HierarchyChildren parent, boolean specialization) { + this(element, new HierarchyChildren(element, model, parent), model, false, specialization); } - public HierarchyNode(CsmClass element, Children children, HierarchyModel model, boolean recursion) { + public HierarchyNode(CsmClass element, Children children, HierarchyModel model, boolean recursion, boolean specialization) { super(children); if (recursion) { setName(element.getName()+" "+getString("CTL_Recuesion")); // NOI18N @@ -84,6 +94,17 @@ this.model = model; uin = object.getUniqueName(); project = object.getContainingFile().getProject(); + this.specialization = specialization; + } + + @Override + public Image getIcon(int param) { + ImageIcon icon = CsmImageLoader.getIcon(object); + if (specialization) { + Image badge = ImageUtilities.loadImage("org/netbeans/modules/cnd/modelutil/resources/specialization-badge.png"); + return ImageUtilities.mergeImages(icon.getImage(), badge, 16, 0); + } + return icon.getImage(); } @Override diff -r c38319da6169 -r 9d2f3b1aada4 cnd.navigation/src/org/netbeans/modules/cnd/navigation/services/HierarchyModel.java --- a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/services/HierarchyModel.java Thu Mar 30 20:21:32 2017 +0300 +++ b/cnd.navigation/src/org/netbeans/modules/cnd/navigation/services/HierarchyModel.java Sun Apr 02 22:56:39 2017 +0300 @@ -40,4 +40,6 @@ public interface HierarchyModel extends HierarchyActions { public Collection getHierarchy(CsmClass cls); + + public Collection getSpecializationsHierarchy(CsmClass cls); } diff -r c38319da6169 -r 9d2f3b1aada4 cnd.navigation/src/org/netbeans/modules/cnd/navigation/services/HierarchyModelImpl.java --- a/cnd.navigation/src/org/netbeans/modules/cnd/navigation/services/HierarchyModelImpl.java Thu Mar 30 20:21:32 2017 +0300 +++ b/cnd.navigation/src/org/netbeans/modules/cnd/navigation/services/HierarchyModelImpl.java Sun Apr 02 22:56:39 2017 +0300 @@ -57,8 +57,10 @@ import org.netbeans.modules.cnd.api.model.CsmInheritance; import org.netbeans.modules.cnd.api.model.CsmInstantiation; import org.netbeans.modules.cnd.api.model.CsmObject; +import org.netbeans.modules.cnd.api.model.CsmOffsetableDeclaration; import org.netbeans.modules.cnd.api.model.services.CsmCacheManager; import org.netbeans.modules.cnd.api.model.services.CsmInheritanceUtilities; +import org.netbeans.modules.cnd.api.model.services.CsmInstantiationProvider; import org.netbeans.modules.cnd.api.model.util.CsmKindUtilities; import org.netbeans.modules.cnd.api.model.xref.CsmReference; import org.netbeans.modules.cnd.api.model.xref.CsmTypeHierarchyResolver; @@ -111,7 +113,43 @@ CsmCacheManager.leave(); } } - + + @Override + public Collection getSpecializationsHierarchy(CsmClass cls) { + CsmCacheManager.enter(); + try { + return getSpecializationsHierarchyImpl(cls); + } finally { + CsmCacheManager.leave(); + } + } + + private Collection getSpecializationsHierarchyImpl(CsmClass cls) { + Collection specClasses = Collections.emptyList(); + if (subDirection) { + Collection templateSpecializations = CsmInstantiationProvider.getDefault().getSpecializations(cls); + if (templateSpecializations != null && ! templateSpecializations.isEmpty()) { + specClasses = new ArrayList(); + for (CsmOffsetableDeclaration ts : templateSpecializations) { + if (ts instanceof CsmClass) { + specClasses.add((CsmClass) ts); + } + } + } + } else { + Collection baseTemplates = CsmInstantiationProvider.getDefault().getBaseTemplate(cls); + if (baseTemplates != null && !baseTemplates.isEmpty()) { + specClasses = new ArrayList(); + for (CsmOffsetableDeclaration bt : baseTemplates) { + if (bt instanceof CsmClass) { + specClasses.add((CsmClass) bt); + } + } + } + } + return specClasses; + } + private Collection getHierarchyImpl(CsmClass cls) { if (subDirection) { Collection subRefs = Collections.emptyList();