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