6261f4ddfa09c2a9f61b85081986daf3836c1fa7
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / viewsupport / ProblemTreeViewer.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.internal.ui.viewsupport;
13
14 import java.util.ArrayList;
15
16 import org.eclipse.core.resources.IResource;
17
18 import org.eclipse.swt.widgets.Composite;
19 import org.eclipse.swt.widgets.Item;
20 import org.eclipse.swt.widgets.Tree;
21 import org.eclipse.swt.widgets.Widget;
22
23 import org.eclipse.jface.viewers.IBaseLabelProvider;
24 import org.eclipse.jface.viewers.LabelProviderChangedEvent;
25 import org.eclipse.jface.viewers.TreeViewer;
26
27 import net.sourceforge.phpdt.core.IMember;
28
29 import net.sourceforge.phpdt.ui.IWorkingCopyProvider;
30 import net.sourceforge.phpdt.ui.ProblemsLabelDecorator.ProblemsLabelChangedEvent;
31
32 /**
33  * Extends a  TreeViewer to allow more performance when showing error ticks.
34  * A <code>ProblemItemMapper</code> is contained that maps all items in
35  * the tree to underlying resource
36  */
37 public class ProblemTreeViewer extends TreeViewer {
38
39         protected ResourceToItemsMapper fResourceToItemsMapper;
40
41         /*
42          * @see TreeViewer#TreeViewer(Composite)
43          */
44         public ProblemTreeViewer(Composite parent) {
45                 super(parent);
46                 initMapper();
47         }
48
49         /*
50          * @see TreeViewer#TreeViewer(Composite, int)
51          */
52         public ProblemTreeViewer(Composite parent, int style) {
53                 super(parent, style);
54                 initMapper();
55         }
56
57         /*
58          * @see TreeViewer#TreeViewer(Tree)
59          */
60         public ProblemTreeViewer(Tree tree) {
61                 super(tree);
62                 initMapper();
63         }
64         
65         private void initMapper() {
66                 fResourceToItemsMapper= new ResourceToItemsMapper(this);
67         }
68         
69         
70         /*
71          * @see StructuredViewer#mapElement(Object, Widget)
72          */
73         protected void mapElement(Object element, Widget item) {
74                 super.mapElement(element, item);
75                 if (item instanceof Item) {
76                         fResourceToItemsMapper.addToMap(element, (Item) item);
77                 }
78         }
79
80         /*
81          * @see StructuredViewer#unmapElement(Object, Widget)
82          */
83         protected void unmapElement(Object element, Widget item) {
84                 if (item instanceof Item) {
85                         fResourceToItemsMapper.removeFromMap(element, (Item) item);
86                 }               
87                 super.unmapElement(element, item);
88         }
89
90         /*
91          * @see StructuredViewer#unmapAllElements()
92          */
93         protected void unmapAllElements() {
94                 fResourceToItemsMapper.clearMap();
95                 super.unmapAllElements();
96         }
97
98         /*
99          * @see ContentViewer#handleLabelProviderChanged(LabelProviderChangedEvent)
100          */
101         protected void handleLabelProviderChanged(LabelProviderChangedEvent event) {
102                 if (event instanceof ProblemsLabelChangedEvent) {
103                         ProblemsLabelChangedEvent e= (ProblemsLabelChangedEvent) event;
104                         if (!e.isMarkerChange() && canIgnoreChangesFromAnnotionModel()) {
105                                 return;
106                         }
107                 }               
108                 
109                 Object[] changed= event.getElements();
110                 if (changed != null && !fResourceToItemsMapper.isEmpty()) {
111                         ArrayList others= new ArrayList();
112                         for (int i= 0; i < changed.length; i++) {
113                                 Object curr= changed[i];
114                                 if (curr instanceof IResource) {
115                                         fResourceToItemsMapper.resourceChanged((IResource) curr);
116                                 } else {
117                                         others.add(curr);
118                                 }
119                         }
120                         if (others.isEmpty()) {
121                                 return;
122                         }
123                         event= new LabelProviderChangedEvent((IBaseLabelProvider) event.getSource(), others.toArray());
124                 }
125                 super.handleLabelProviderChanged(event);
126         }
127         
128         /**
129          * Answers whether this viewer can ignore label provider changes resulting from
130          * marker changes in annotation models
131          */
132         private boolean canIgnoreChangesFromAnnotionModel() {
133                 Object contentProvider= getContentProvider();
134                 return contentProvider instanceof IWorkingCopyProvider && !((IWorkingCopyProvider)contentProvider).providesWorkingCopies();
135         }
136         
137         /* (non-Javadoc)
138          * @see org.eclipse.jface.viewers.AbstractTreeViewer#isExpandable(java.lang.Object)
139          */
140         public boolean isExpandable(Object element) {
141                 // workaround for 65762
142                 if (hasFilters() && element instanceof IMember) {
143                         return getFilteredChildren(element).length > 0;
144                 }
145                 return super.isExpandable(element);
146         }
147 }
148