blob: 33025aa4dc8a0a4b4fc5ef9ac2d0dd2e69edcb47 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}
}
}