001: /*******************************************************************************
002: * Copyright (c) 2005, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.services;
011:
012: import java.util.HashMap;
013: import java.util.Map;
014:
015: import org.eclipse.jface.util.IPropertyChangeListener;
016: import org.eclipse.jface.util.PropertyChangeEvent;
017: import org.eclipse.swt.SWT;
018: import org.eclipse.swt.widgets.Display;
019: import org.eclipse.swt.widgets.Event;
020: import org.eclipse.swt.widgets.Listener;
021: import org.eclipse.swt.widgets.Shell;
022: import org.eclipse.ui.AbstractSourceProvider;
023: import org.eclipse.ui.ISources;
024: import org.eclipse.ui.IWorkbenchWindow;
025: import org.eclipse.ui.contexts.IContextService;
026: import org.eclipse.ui.internal.Workbench;
027: import org.eclipse.ui.internal.WorkbenchWindow;
028:
029: /**
030: * A provider of notifications for when the active shell changes.
031: *
032: * @since 3.1
033: */
034: public final class ActiveShellSourceProvider extends
035: AbstractSourceProvider {
036:
037: /**
038: * The names of the sources supported by this source provider.
039: */
040: private static final String[] PROVIDED_SOURCE_NAMES = new String[] {
041: ISources.ACTIVE_SHELL_NAME,
042: ISources.ACTIVE_WORKBENCH_WINDOW_NAME,
043: ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
044: ISources.ACTIVE_WORKBENCH_WINDOW_IS_COOLBAR_VISIBLE_NAME,
045: ISources.ACTIVE_WORKBENCH_WINDOW_IS_PERSPECTIVEBAR_VISIBLE_NAME };
046:
047: /**
048: * The display on which this provider is working.
049: */
050: private final Display display;
051:
052: /**
053: * The last shell seen as active by this provider. This value may be
054: * <code>null</code> if the last call to
055: * <code>Display.getActiveShell()</code> returned <code>null</code>.
056: */
057: private Shell lastActiveShell = null;
058:
059: /**
060: * The last workbench window shell seen as active by this provider. This
061: * value may be <code>null</code> if the last call to
062: * <code>workbench.getActiveWorkbenchWindow()</code> returned
063: * <code>null</code>.
064: */
065: private Shell lastActiveWorkbenchWindowShell = null;
066:
067: /**
068: * The last workbench window seen as active by this provider. This value may
069: * be null if the last call to
070: * <code>workbench.getActiveWorkbenchWindow()</code> returned
071: * <code>null</code>.
072: *
073: * @since 3.3
074: */
075: private WorkbenchWindow lastActiveWorkbenchWindow = null;
076:
077: /**
078: * The result of the last visibility check on the coolbar of the last active
079: * workbench window.
080: *
081: * @since 3.3
082: */
083: private Boolean lastCoolbarVisibility = Boolean.FALSE;
084:
085: /**
086: * The result of the last visibility check on the perspective bar of the
087: * last active workbench window.
088: *
089: * @since 3.3
090: */
091: private Boolean lastPerspectiveBarVisibility = Boolean.FALSE;
092:
093: /**
094: * The listener to individual window properties.
095: *
096: * @since 3.3
097: */
098: private final IPropertyChangeListener propertyListener = new IPropertyChangeListener() {
099:
100: public void propertyChange(PropertyChangeEvent event) {
101: if (WorkbenchWindow.PROP_COOLBAR_VISIBLE.equals(event
102: .getProperty())) {
103: Object newValue = event.getNewValue();
104: if (newValue == null || !(newValue instanceof Boolean))
105: return;
106: if (!lastCoolbarVisibility.equals(newValue)) {
107: fireSourceChanged(
108: ISources.ACTIVE_WORKBENCH_WINDOW_SUBORDINATE,
109: ISources.ACTIVE_WORKBENCH_WINDOW_IS_COOLBAR_VISIBLE_NAME,
110: newValue);
111: lastCoolbarVisibility = (Boolean) newValue;
112: }
113: } else if (WorkbenchWindow.PROP_PERSPECTIVEBAR_VISIBLE
114: .equals(event.getProperty())) {
115: Object newValue = event.getNewValue();
116: if (newValue == null || !(newValue instanceof Boolean))
117: return;
118: if (!lastPerspectiveBarVisibility.equals(newValue)) {
119: fireSourceChanged(
120: ISources.ACTIVE_WORKBENCH_WINDOW_SUBORDINATE,
121: ISources.ACTIVE_WORKBENCH_WINDOW_IS_PERSPECTIVEBAR_VISIBLE_NAME,
122: newValue);
123: lastPerspectiveBarVisibility = (Boolean) newValue;
124: }
125: }
126: }
127:
128: };
129:
130: /**
131: * The listener to shell activations on the display.
132: */
133: private final Listener listener = new Listener() {
134: /**
135: * Notifies all listeners that the source has changed.
136: */
137: public final void handleEvent(final Event event) {
138: if (!(event.widget instanceof Shell)) {
139: if (DEBUG) {
140: logDebuggingInfo("ASSP: passOnEvent: " + event.widget); //$NON-NLS-1$
141: }
142: return;
143: }
144:
145: if (DEBUG) {
146: logDebuggingInfo("\tASSP:lastActiveShell: " + lastActiveShell); //$NON-NLS-1$
147: logDebuggingInfo("\tASSP:lastActiveWorkbenchWindowShell" + lastActiveWorkbenchWindowShell); //$NON-NLS-1$
148: }
149:
150: final Map currentState = getCurrentState();
151: final Shell newActiveShell = (Shell) currentState
152: .get(ISources.ACTIVE_SHELL_NAME);
153: final WorkbenchWindow newActiveWorkbenchWindow = (WorkbenchWindow) currentState
154: .get(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
155: final Shell newActiveWorkbenchWindowShell = (Shell) currentState
156: .get(ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME);
157:
158: // dont update the coolbar/perspective bar visibility unless we're
159: // processing a workbench window change
160: final Boolean newCoolbarVisibility = newActiveWorkbenchWindow == null ? lastCoolbarVisibility
161: : (newActiveWorkbenchWindow.getCoolBarVisible() ? Boolean.TRUE
162: : Boolean.FALSE);
163: final Boolean newPerspectiveBarVisibility = newActiveWorkbenchWindow == null ? lastPerspectiveBarVisibility
164: : (newActiveWorkbenchWindow
165: .getPerspectiveBarVisible() ? Boolean.TRUE
166: : Boolean.FALSE);
167:
168: // Figure out which variables have changed.
169: final boolean shellChanged = newActiveShell != lastActiveShell;
170: final boolean windowChanged = newActiveWorkbenchWindowShell != lastActiveWorkbenchWindowShell;
171: final boolean coolbarChanged = newCoolbarVisibility != lastCoolbarVisibility;
172: final boolean perspectiveBarChanged = newPerspectiveBarVisibility != lastPerspectiveBarVisibility;
173: // Fire an event for those sources that have changed.
174: if (shellChanged && windowChanged) {
175: final Map sourceValuesByName = new HashMap(5);
176: sourceValuesByName.put(ISources.ACTIVE_SHELL_NAME,
177: newActiveShell);
178: sourceValuesByName.put(
179: ISources.ACTIVE_WORKBENCH_WINDOW_NAME,
180: newActiveWorkbenchWindow);
181: sourceValuesByName.put(
182: ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
183: newActiveWorkbenchWindowShell);
184: int sourceFlags = ISources.ACTIVE_SHELL
185: | ISources.ACTIVE_WORKBENCH_WINDOW;
186:
187: if (coolbarChanged) {
188: sourceValuesByName
189: .put(
190: ISources.ACTIVE_WORKBENCH_WINDOW_IS_COOLBAR_VISIBLE_NAME,
191: newCoolbarVisibility);
192: sourceFlags |= ISources.ACTIVE_WORKBENCH_WINDOW_SUBORDINATE;
193: }
194: if (perspectiveBarChanged) {
195: sourceValuesByName
196: .put(
197: ISources.ACTIVE_WORKBENCH_WINDOW_IS_PERSPECTIVEBAR_VISIBLE_NAME,
198: newPerspectiveBarVisibility);
199: sourceFlags |= ISources.ACTIVE_WORKBENCH_WINDOW_SUBORDINATE;
200: }
201:
202: if (DEBUG) {
203: logDebuggingInfo("Active shell changed to " //$NON-NLS-1$
204: + newActiveShell);
205: logDebuggingInfo("Active workbench window changed to " //$NON-NLS-1$
206: + newActiveWorkbenchWindow);
207: logDebuggingInfo("Active workbench window shell changed to " //$NON-NLS-1$
208: + newActiveWorkbenchWindowShell);
209: logDebuggingInfo("Active workbench window coolbar visibility " //$NON-NLS-1$
210: + newCoolbarVisibility);
211: logDebuggingInfo("Active workbench window perspective bar visibility " //$NON-NLS-1$
212: + newPerspectiveBarVisibility);
213: }
214:
215: fireSourceChanged(sourceFlags, sourceValuesByName);
216: hookListener(lastActiveWorkbenchWindow,
217: newActiveWorkbenchWindow);
218:
219: } else if (shellChanged) {
220: if (DEBUG) {
221: logDebuggingInfo("Active shell changed to " //$NON-NLS-1$
222: + newActiveShell);
223: }
224: fireSourceChanged(ISources.ACTIVE_SHELL,
225: ISources.ACTIVE_SHELL_NAME, newActiveShell);
226:
227: } else if (windowChanged) {
228: final Map sourceValuesByName = new HashMap(4);
229: sourceValuesByName.put(
230: ISources.ACTIVE_WORKBENCH_WINDOW_NAME,
231: newActiveWorkbenchWindow);
232: sourceValuesByName.put(
233: ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
234: newActiveWorkbenchWindowShell);
235:
236: int sourceFlags = ISources.ACTIVE_SHELL
237: | ISources.ACTIVE_WORKBENCH_WINDOW;
238:
239: if (coolbarChanged) {
240: sourceValuesByName
241: .put(
242: ISources.ACTIVE_WORKBENCH_WINDOW_IS_COOLBAR_VISIBLE_NAME,
243: newCoolbarVisibility);
244: sourceFlags |= ISources.ACTIVE_WORKBENCH_WINDOW_SUBORDINATE;
245: }
246: if (perspectiveBarChanged) {
247: sourceValuesByName
248: .put(
249: ISources.ACTIVE_WORKBENCH_WINDOW_IS_PERSPECTIVEBAR_VISIBLE_NAME,
250: newPerspectiveBarVisibility);
251: sourceFlags |= ISources.ACTIVE_WORKBENCH_WINDOW_SUBORDINATE;
252: }
253:
254: if (DEBUG) {
255: logDebuggingInfo("Active workbench window changed to " //$NON-NLS-1$
256: + newActiveWorkbenchWindow);
257: logDebuggingInfo("Active workbench window shell changed to " //$NON-NLS-1$
258: + newActiveWorkbenchWindowShell);
259: logDebuggingInfo("Active workbench window coolbar visibility " //$NON-NLS-1$
260: + newCoolbarVisibility);
261: logDebuggingInfo("Active workbench window perspective bar visibility " //$NON-NLS-1$
262: + newPerspectiveBarVisibility);
263: }
264:
265: fireSourceChanged(sourceFlags, sourceValuesByName);
266: hookListener(lastActiveWorkbenchWindow,
267: newActiveWorkbenchWindow);
268: }
269:
270: // Update the member variables.
271: lastActiveShell = newActiveShell;
272: lastActiveWorkbenchWindowShell = newActiveWorkbenchWindowShell;
273: lastActiveWorkbenchWindow = newActiveWorkbenchWindow;
274: lastCoolbarVisibility = newCoolbarVisibility;
275: lastPerspectiveBarVisibility = newPerspectiveBarVisibility;
276: }
277: };
278:
279: /**
280: * The workbench on which to work; never <code>null</code>.
281: */
282: private final Workbench workbench;
283:
284: /**
285: * Constructs a new instance of <code>ShellSourceProvider</code>.
286: *
287: * @param workbench
288: * The workbench on which to monitor shell activations; must not
289: * be <code>null</code>.
290: */
291: public ActiveShellSourceProvider(final Workbench workbench) {
292: this .workbench = workbench;
293: this .display = workbench.getDisplay();
294: this .display.addFilter(SWT.Activate, listener);
295: }
296:
297: public final void dispose() {
298: display.removeFilter(SWT.Activate, listener);
299: hookListener(lastActiveWorkbenchWindow, null);
300: lastActiveWorkbenchWindow = null;
301: lastActiveWorkbenchWindowShell = null;
302: lastActiveShell = null;
303: }
304:
305: public final Map getCurrentState() {
306: final Map currentState = new HashMap(4);
307:
308: final Shell newActiveShell = display.getActiveShell();
309: currentState.put(ISources.ACTIVE_SHELL_NAME, newActiveShell);
310:
311: /*
312: * We will fallback to the workbench window, but only if a dialog is not
313: * open.
314: */
315: final IContextService contextService = (IContextService) workbench
316: .getService(IContextService.class);
317: final int shellType = contextService
318: .getShellType(newActiveShell);
319: if (shellType != IContextService.TYPE_DIALOG) {
320: final IWorkbenchWindow newActiveWorkbenchWindow = workbench
321: .getActiveWorkbenchWindow();
322: final Shell newActiveWorkbenchWindowShell;
323: if (newActiveWorkbenchWindow == null) {
324: newActiveWorkbenchWindowShell = null;
325: } else {
326: newActiveWorkbenchWindowShell = newActiveWorkbenchWindow
327: .getShell();
328: }
329: currentState.put(ISources.ACTIVE_WORKBENCH_WINDOW_NAME,
330: newActiveWorkbenchWindow);
331: currentState.put(
332: ISources.ACTIVE_WORKBENCH_WINDOW_SHELL_NAME,
333: newActiveWorkbenchWindowShell);
334: }
335:
336: return currentState;
337: }
338:
339: public final String[] getProvidedSourceNames() {
340: return PROVIDED_SOURCE_NAMES;
341: }
342:
343: private void hookListener(
344: WorkbenchWindow lastActiveWorkbenchWindow,
345: WorkbenchWindow newActiveWorkbenchWindow) {
346: if (lastActiveWorkbenchWindow != null)
347: lastActiveWorkbenchWindow
348: .removePropertyChangeListener(propertyListener);
349:
350: if (newActiveWorkbenchWindow != null)
351: newActiveWorkbenchWindow
352: .addPropertyChangeListener(propertyListener);
353: }
354: }
|