Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 33025aa4dc8a0a4b4fc5ef9ac2d0dd2e69edcb47 (plain) (tree)
















































                                                                                 


                                                   

































































                                                                                                               

                        















































                                                                                                     
/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. and others.
 *
 * 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.editors;

import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jst.pagedesigner.utils.SelectionHelper;
import org.eclipse.swt.custom.StyledText;

/**
 * This class handles selection synchronization between the designer and other
 * parts. It listens event from both ViewerSelectionManager and the
 * IDesignerView, and convert the events to each other.
 * <p>
 * SelectionSynchronizer will be registered on the ViewerSelectionManager,
 * basically listens to selection change of other parts, and make the designer
 * sync with them.
 * <p>
 * As ViewerSelectionManager is firing out both textSelectionChange and
 * nodeSelectionChange, we only need to listen to one of them. As
 * textSelectionChange provide more information than nodeSelectionChange, so
 * we'll listen only to textSelectionChange.
 * 
 * @author mengbo
 * @version 1.5
 */
public class SelectionSynchronizer implements ISelectionChangedListener {
	private boolean _firingChange = false;

	private SimpleGraphicalEditor _editor;

	/**
	 * @param editor
	 */
	public SelectionSynchronizer(SimpleGraphicalEditor editor) {
		_editor = editor;
	}

	/**
	 * @return true if the status check is okay
	 */
	protected boolean statusCheckOk() {
		try {
			StyledText text = _editor.getHTMLEditor().getTextEditor()
					.getTextViewer().getTextWidget();
			if (text == null || text.isDisposed()) {
				return false;
			}
			return true;
		} catch (NullPointerException ex) {
			return false;
		}
	}

	/**
	 * This is for event from the designer.
	 */
	public void selectionChanged(SelectionChangedEvent event) {
		ISelection selection = event.getSelection();

		if (!_firingChange) {
			// check current status
			if (!statusCheckOk()) {
				return;
			}

			_firingChange = true;
			try {
				// convert the designer selection into SSE selection
				// (IStructureSelection of nodes
				// or textSelection, and let the ViewerSelectionManager to
				// handle it.
				// if (selection instanceof IStructuredSelection)
				// {
				// IStructuredSelection nodeSel =
				// SelectionHelper.convertFromDesignSelection((IStructuredSelection)selection);
				// can't use DoubleClickEvent, since it requre a Viewer.
				// _viewerSelectionManager.doubleClick(new
				// DoubleClickEvent(null, nodeSel));
				// }
				// else if (selection instanceof DesignRange)
				// {
				// ITextSelection srcselection =
				// SelectionHelper.convertFromDesignSelection((DesignRange)selection);
				// event = new SelectionChangedEvent(_editor.getGraphicViewer(),
				// srcselection);
				// _viewerSelectionManager.selectionChanged(event);
				// }
				ITextSelection srcselection = SelectionHelper
						.convertFromDesignSelectionToTextSelection(selection);

				// ideally, we should let the text editor display the selection
				// through calls to _viewerSelectionManager,
				// but seemed _viewerSelectionManager don't support that, so we
				// do workaround by calling the text editor (lium)
				_editor.getHTMLEditor().getTextEditor().selectAndReveal(
						srcselection.getOffset(), srcselection.getLength());
			} finally {
				_firingChange = false;
			}
		}
	}

	/**
	 * We are listening to the selection change in ViewerSelectionManager. The
	 * original source of the event could be source view or the outline view or
	 * other party that participate in the ViewerSelectionManager.
	 * @param start 
	 * @param end 
	 */
	public void textSelectionChanged(int start, int end) {
		if (!_firingChange) {
			try {
				_firingChange = true;

				// XXX: workaround a SSE problem. In SSE, when user select a
				// range, it will fire two textSelectionChange event
				// the first one indicate the correct range, the second one is
				// zero size for caret position.
				// @see ViewerSelectionManagerImpl.caretMoved
				// We try to ignore the second event by checking whether the
				// current real selection is empty
				if (start == end) {
					ITextSelection sel = (ITextSelection) _editor
							.getHTMLEditor().getTextEditor()
							.getSelectionProvider().getSelection();
					if (sel.getLength() != 0) {
						return;
					}
				}

				if (start > end) {
					int temp = start;
					start = end;
					end = temp;
				}
				int offset = start;
				int length = end - start;

				ITextSelection oldSelection = SelectionHelper
						.convertFromDesignSelectionToTextSelection(_editor
								.getGraphicViewer().getSelection());
				if (oldSelection != null && oldSelection.getOffset() == offset
						&& oldSelection.getLength() == length) {
					return;
				}

				ISelection selection = SelectionHelper
						.convertToDesignerSelection(this._editor
								.getGraphicViewer(), offset, length);
				_editor.getGraphicViewer().setSelection(selection);
			} finally {
				_firingChange = false;
			}
		}
	}
}

Back to the top