Skip to main content
summaryrefslogtreecommitdiffstats
blob: 8e4798f4055383d1ca62a463020e37b20b929ebc (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
/*******************************************************************************
 * Copyright (c) 2014 OPCoach.
 * 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:
 *     Olivier Prouvost <olivier.prouvost@opcoach.com> - initial API and implementation
 *******************************************************************************/
package org.eclipse.e4.tools.context.spy;

import java.util.List;

import javax.annotation.PostConstruct;
import javax.inject.Inject;

import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.commands.MBindingContext;
import org.eclipse.e4.ui.model.application.commands.MBindingTable;
import org.eclipse.e4.ui.model.application.commands.MCommand;
import org.eclipse.e4.ui.model.application.commands.MHandler;
import org.eclipse.e4.ui.model.application.commands.MKeyBinding;
import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
import org.eclipse.e4.ui.workbench.modeling.EModelService;

public class ContextSpyProcessor
{
	private static final String ORG_ECLIPSE_UI_CONTEXTS_DIALOG_AND_WINDOW = "org.eclipse.ui.contexts.dialogAndWindow";
	private static final String CONTEXT_SPY_SHORTCUT = "M2+M3+F10";
	private static final String E4_SPIES_BINDING_TABLE = "e4.tooling.spies.bindings";
	private static final String CONTEXT_SPY_HANDLER = "e4.tooling.context.spy.handler";
	private static final String CONTEXT_SPY_COMMAND = "e4.tooling.context.spy.command";
	private static final String CONTEXT_SPY_CONTRIBUTOR_URI = "platform:/plugin/org.eclipse.e4.tools.context.spy";

	@Inject
	MApplication application;
	@Inject
	EModelService modelService;

	@PostConstruct
	public void process()
	{
		// This processor must :
		// 1. Add the e4.tooling.context.spy Command, if not present
		// 2. Add the e4.tooling.context.spy.handler Handler, if not present
		// 3. Deal with binding context
		// 4. Add the org.eclipse.e4.tools.context.spy.view part descriptor, if
		// not present
		// Warning : do not use findElement on modelService, it returns only
		// MUIElements

		// ..............................
		// 1. Add the command 
		// ..............................
		MCommand command = null;
		for (MCommand cmd : application.getCommands())
		{
			if (CONTEXT_SPY_COMMAND.equals(cmd.getElementId()))
			{
				command = cmd;
				break;
			}
		}

		if (command == null)
		{
			command = modelService.createModelElement(MCommand.class);
			command.setElementId(CONTEXT_SPY_COMMAND);
			command.setCommandName("Show E4 Context Spy");
			command.setContributorURI(CONTEXT_SPY_CONTRIBUTOR_URI);
			command.setDescription("Show the Eclipse 4 contexts and their contents");
			application.getCommands().add(command);
		}

		// ..............................
		// 2. Add the handler
		// ..............................
		MHandler handler = null;
		for (MHandler hdl : application.getHandlers())
		{
			if (CONTEXT_SPY_HANDLER.equals(hdl.getElementId()))
			{
				handler = hdl;
				break;
			}
		}

		if (handler == null)
		{
			handler = modelService.createModelElement(MHandler.class);
			handler.setElementId(CONTEXT_SPY_HANDLER);
			handler.setContributionURI("bundleclass://org.eclipse.e4.tools.context.spy/org.eclipse.e4.tools.context.spy.ContextSpyHandler");
			handler.setContributorURI(CONTEXT_SPY_CONTRIBUTOR_URI);
			application.getHandlers().add(handler);
		}

		handler.setCommand(command);

		// ..............................
		// 3. Deal with key bindings
		// ..............................
		bindSpyKeyBinding(CONTEXT_SPY_SHORTCUT, command);

		// ..............................
		// 4. Add part descriptor
		// ..............................
		MPartDescriptor descriptor = null;
		for (MPartDescriptor mp : application.getDescriptors())
		{
			if (ContextSpyPart.CONTEXT_SPY_VIEW_DESC.equals(mp.getElementId()))
			{
				descriptor = mp;
				break;
			}
		}

		// If descriptor not yet in descriptor list, add it now
		if (descriptor == null)
		{
			descriptor = modelService.createModelElement(MPartDescriptor.class);
			descriptor.setCategory("org.eclipse.e4.secondaryDataStack");
			descriptor.setElementId(ContextSpyPart.CONTEXT_SPY_VIEW_DESC);
			descriptor.getTags().add("View");
			descriptor.getTags().add("categoryTag:General");

			descriptor.setLabel("Context Spy");
			descriptor
					.setContributionURI("bundleclass://org.eclipse.e4.tools.context.spy/org.eclipse.e4.tools.context.spy.ContextSpyPart");
			descriptor.setContributorURI(CONTEXT_SPY_CONTRIBUTOR_URI);
			descriptor.setIconURI(CONTEXT_SPY_CONTRIBUTOR_URI + "/icons/annotation_obj.gif");
			application.getDescriptors().add(descriptor);
		}

	}

	/**
	 * Helper method to get or create the binding table for all spies (where
	 * spies will add their key binding). Bind this table with the
	 * org.eclipse.ui.contexts.dialogAndWindow binding context which should be
	 * present (create it if not)
	 * 
	 * This method will probably move to the common spy plugin providing common
	 * spy stuff (see bug #428903)
	 * 
	 * @param application
	 * @return
	 */
	public void bindSpyKeyBinding(String keySequence, MCommand cmd)
	{
		// This method must :
		// search for a binding table having the binding context 'dialog and
		// window'
		// If none found, create it and also the binding context
		// Then can add the KeyBinding if not already added

		MBindingTable spyBindingTable = null;
		for (MBindingTable bt : application.getBindingTables())
			if (ORG_ECLIPSE_UI_CONTEXTS_DIALOG_AND_WINDOW.equals(bt.getBindingContext().getElementId()))
			{
				spyBindingTable = bt;
			}

		// Binding table has not been yet added... Create it and bind it to
		// org.eclipse.ui.contexts.dialogAndWindow binding context
		// If this context does not yet exist, create it also.
		if (spyBindingTable == null)
		{
			
			MBindingContext bc = null;
			final List<MBindingContext> bindingContexts = application
					.getBindingContexts();
			if (bindingContexts.size() == 0) {
				bc = modelService.createModelElement(MBindingContext.class);
				bc.setElementId("org.eclipse.ui.contexts.window");
			} else {
				// Prefer org.eclipse.ui.contexts.dialogAndWindow but randomly
				// select another one
				// if org.eclipse.ui.contexts.dialogAndWindow cannot be found
				for (MBindingContext aBindingContext : bindingContexts) {
					bc = aBindingContext;
					if ("org.eclipse.ui.contexts.dialogAndWindow"
							.equals(aBindingContext.getElementId())) {
						break;
					}
				}
			}
			
			
	
			// Can now create the binding table and bind it to this context...
			spyBindingTable = modelService.createModelElement(MBindingTable.class);
			spyBindingTable.setElementId(E4_SPIES_BINDING_TABLE);
			spyBindingTable.setBindingContext(bc);
			application.getBindingTables().add(spyBindingTable);
		}

		// Search for the key binding if already present
		for (MKeyBinding kb : spyBindingTable.getBindings())
			if (keySequence.equals(kb.getKeySequence()))
			{
				// A binding with this key sequence is already present. Check if
				// command is the same
				if (kb.getCommand().getElementId().equals(cmd.getElementId()))
					return;
				else
				{
					// Must log an error : key binding already exists in this
					// table but with another command
					System.out.println("WARNING : Cannot bind the command '" + cmd.getElementId() + "' to the keySequence : "
							+ keySequence + " because the command " + kb.getCommand().getElementId() + " is already bound !");
					return;
				}
			}

		// Key binding is not yet in table... can add it now.
		MKeyBinding binding = modelService.createModelElement(MKeyBinding.class);
		binding.setElementId(cmd.getElementId() + ".binding");
		binding.setContributorURI(cmd.getContributorURI());
		binding.setKeySequence(keySequence);
		spyBindingTable.getBindings().add(binding);
		binding.setCommand(cmd);

	}

}

Back to the top