Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 20ba2b1ec493d6221b9434346929fc1b4547eec9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/*****************************************************************************
 * Copyright (c) 2010 CEA LIST.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
 *****************************************************************************/
package org.eclipse.papyrus.views.properties.xwt;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.jface.viewers.ISelection;
import org.eclipse.papyrus.views.properties.Activator;
import org.eclipse.papyrus.views.properties.contexts.View;
import org.eclipse.papyrus.views.properties.runtime.ConfigurationManager;
import org.eclipse.papyrus.views.properties.runtime.DefaultDisplayEngine;
import org.eclipse.papyrus.views.properties.runtime.DisplayEngine;
import org.eclipse.papyrus.views.properties.runtime.ViewConstraintEngine;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyRegistry;
import org.eclipse.ui.internal.views.properties.tabbed.view.TabbedPropertyRegistryFactory;
import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider;
import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor;

/**
 * An implementation of ITabDescriptorProvider, which displays the Property view
 * from XWT files.
 * 
 * @author Camille Letavernier
 */
public class XWTTabDescriptorProvider implements ITabDescriptorProvider {

	private ITabDescriptor[] cachedResult;

	private ISelection previousSelection;

	private IWorkbenchPart previousPart;

	private final Map<IWorkbenchPart, DisplayEngine> displays = new HashMap<IWorkbenchPart, DisplayEngine>();

	private DisplayEngine getDisplay(final IWorkbenchPart part) {
		if(!displays.containsKey(part)) {
			displays.put(part, new DefaultDisplayEngine());
			part.getSite().getPage().addPartListener(new IPartListener() {

				public void partClosed(IWorkbenchPart part) {
					part.getSite().getPage().removePartListener(this);
					DisplayEngine display = displays.get(part);
					if(display != null) {
						display.dispose();
						displays.remove(part);
					}
				}

				public void partActivated(IWorkbenchPart part) {
					//Nothing
				}

				public void partBroughtToTop(IWorkbenchPart part) {
					//Nothing
				}

				public void partDeactivated(IWorkbenchPart part) {
					//Nothing
				}

				public void partOpened(IWorkbenchPart part) {
					//Nothing
				}

			});
		}

		return displays.get(part);
	}

	public ITabDescriptor[] getTabDescriptors(final IWorkbenchPart part, final ISelection selection) {
		if(selection != this.previousSelection || part != previousPart) {
			this.previousSelection = selection;
			this.previousPart = part;

			ViewConstraintEngine constraintEngine = ConfigurationManager.instance.constraintEngine;

			List<ITabDescriptor> descriptors = new LinkedList<ITabDescriptor>();

			Set<View> views = constraintEngine.getViews(selection);
			if(!views.isEmpty()) {
				descriptors.addAll(getDisplay(part).getTabDescriptors(views));
			}

			//FIXME: In some cases (e.g. Selection in the Papyrus Tree outline), the IWorkbenchPart is not an ITabbedPropertySheetPageContributor
			//TODO: Investigate on this case and fix the issue (contributor == null in this case)
			ITabbedPropertySheetPageContributor contributor;
			if(part instanceof ITabbedPropertySheetPageContributor) {
				contributor = (ITabbedPropertySheetPageContributor)part;
			} else {
				contributor = (ITabbedPropertySheetPageContributor)(part.getAdapter(ITabbedPropertySheetPageContributor.class));
			}

			if(contributor != null) {
				// get all tab descriptors for the registered extension points
				TabbedPropertyRegistry registry = TabbedPropertyRegistryFactory.getInstance().createRegistry(contributor);

				// invoke dynamically on the tab registry, as method is private
				// problem of implementation of tabbed properties tabbed registry. Either contribution using extension points, either a tabprovider
				// both contribution can not exist together, the only solution is to make a workaround.
				try {
					Method method = TabbedPropertyRegistry.class.getDeclaredMethod("getAllTabDescriptors"); //$NON-NLS-1$
					method.setAccessible(true);
					ITabDescriptor[] registeredTabDesriptors;

					registeredTabDesriptors = (ITabDescriptor[])method.invoke(registry);

					if(registeredTabDesriptors != null) {
						for(ITabDescriptor descriptor : registeredTabDesriptors) {
							if(descriptor.getSectionDescriptors().size() > 0) {
								descriptors.add(descriptor);
							}
						}
					}
				} catch (IllegalArgumentException e) {
					Activator.log.error(e);
				} catch (IllegalAccessException e) {
					Activator.log.error(e);
				} catch (InvocationTargetException e) {
					Activator.log.error(e);
				} catch (SecurityException e) {
					Activator.log.error(e);
				} catch (NoSuchMethodException e) {
					Activator.log.error(e);
				}
			}

			orderTabDescriptors(descriptors);

			cachedResult = descriptors.toArray(new ITabDescriptor[descriptors.size()]);
		}

		return cachedResult;
	}

	/**
	 * Order the tab descriptors in the given list, given the afterTab comparator
	 * 
	 * @param descriptors
	 *        tab descriptor list to order
	 */
	protected void orderTabDescriptors(final List<ITabDescriptor> descriptors) {

		Collections.sort(descriptors, new Comparator<ITabDescriptor>() {

			/**
			 * compares two tab descriptors each other
			 * 
			 * @param tabDescriptor1
			 *        first tab to compare
			 * @param tabDescriptor2
			 *        second tab to compare
			 * @return an integer lesser than -1 if the first tab should be placed before the second tab
			 */
			public int compare(ITabDescriptor tabDescriptor1, ITabDescriptor tabDescriptor2) {
				int priority1 = getPriority(tabDescriptor1);
				int priority2 = getPriority(tabDescriptor2);

				if(priority1 < priority2) {
					return -1;
				}

				if(priority1 > priority2) {
					return 1;
				}

				//p1 == p2

				priority1 = getXWTTabPriority(tabDescriptor1);
				priority2 = getXWTTabPriority(tabDescriptor2);

				if(priority1 < priority2) {
					return -1;
				}

				if(priority1 > priority2) {
					return 1;
				}

				//p1 == p2

				String label1 = tabDescriptor1.getLabel();
				String label2 = tabDescriptor2.getLabel();

				return Collator.getInstance().compare(label1, label2);
			}

			/**
			 * Returns the tab descriptor before tab
			 * 
			 * @param tab
			 *        the tab to test
			 * @return the tab descriptor before tab
			 */
			private ITabDescriptor getPreviousTab(ITabDescriptor tab) {
				String afterId = tab.getAfterTab();
				if(!(ITabDescriptor.TOP.equals(afterId))) {
					for(ITabDescriptor descriptor : descriptors) {
						String id = descriptor.getId();
						if(id != null && id.equals(afterId)) {
							return descriptor;
						}
					}

				}
				// not found. Return null
				return null;
			}

			private int getPriority(ITabDescriptor tab) {
				ITabDescriptor previousTab = getPreviousTab(tab);
				if(previousTab != null) {
					return getPriority(previousTab) + 1;
				}

				return getXWTTabPriority(tab);
			}

			private int getXWTTabPriority(ITabDescriptor tab) {
				if(tab instanceof XWTTabDescriptor) {
					XWTTabDescriptor xwtTab = (XWTTabDescriptor)tab;
					return xwtTab.getPriority();
				} else {
					return 100; //This tab is not handled by our framework
				}
			}

		});
	}
}

Back to the top