Skip to main content
summaryrefslogblamecommitdiffstats
blob: dbc24cc8b26e37fc2237dd2bf4a92ed58ea4a5fc (plain) (tree)






















































































































































































































                                                                                                                     
/*******************************************************************************
 * Copyright (c) 2006, 2008 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jpa.ui.internal.selection;

import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.jpa.core.JpaFile;
import org.eclipse.jpt.jpa.core.JpaStructureNode;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.texteditor.ITextEditor;

public class TextEditorSelectionParticipant
	implements JpaSelectionParticipant
{
	private final JpaSelectionManager selectionManager;

	final ITextEditor textEditor;

	private final IPropertyListener editorInputListener;

	private final ISelectionChangedListener editorSelectionListener;

	private JpaSelection currentSelection;

	private boolean forwardSelection = true;  // TODO this just smells wrong  ~bjv


	public TextEditorSelectionParticipant(JpaSelectionManager selectionManager, ITextEditor textEditor) {
		super();
		this.selectionManager = selectionManager;
		this.textEditor = textEditor;
		this.editorInputListener = new EditorInputListener();
		this.textEditor.addPropertyListener(this.editorInputListener);
		this.editorSelectionListener = new EditorSelectionListener();
		this.getPostSelectionProvider().addPostSelectionChangedListener(this.editorSelectionListener);
		this.currentSelection = this.calculateSelection();
	}

	// ********** IJpaSelectionParticipant implementation **********

	public JpaSelection getSelection() {
		return this.currentSelection;
	}

	public void selectionChanged(JpaSelectionEvent evt) {
		JpaSelection newSelection = evt.getSelection();

		if ((newSelection == JpaSelection.NULL_SELECTION)
			|| newSelection.equals(this.currentSelection)) {
			return;
		}

		if (getActiveTextEditor() != this.textEditor) {
			return;
		}

		this.forwardSelection = false;
		TextRange textRange = newSelection.getSelectedNode().getSelectionTextRange();
		if (textRange != null) {
			this.textEditor.selectAndReveal(textRange.getOffset(), textRange.getLength());
			this.currentSelection = newSelection;
		}
		this.forwardSelection = true;
	}

	public boolean disposeOnHide() {
		return true;
	}

	public void dispose() {
		this.textEditor.removePropertyListener(this.editorInputListener);
		this.getPostSelectionProvider().removePostSelectionChangedListener(this.editorSelectionListener);
	}


	// ********** internal methods **********

	protected JpaSelection calculateSelection() {
		ISelection selection = this.textEditor.getSelectionProvider().getSelection();
		if (! (selection instanceof ITextSelection)) {
			return JpaSelection.NULL_SELECTION;
		}

		JpaFile jpaFile = this.getJpaFile();
		if (jpaFile == null) {
			return JpaSelection.NULL_SELECTION;
		}

		return this.buildSelection(jpaFile.getStructureNode(((ITextSelection) selection).getOffset()));
	}

	protected JpaSelection buildSelection(JpaStructureNode selectedNode) {
		return (selectedNode == null) ? JpaSelection.NULL_SELECTION : new DefaultJpaSelection(selectedNode);
	}

	protected IWorkbenchPage getActivePage() {
		return this.textEditor.getEditorSite().getWorkbenchWindow().getActivePage();
	}
	
	protected IWorkbenchPart getActivePart() {
		IWorkbenchPage activePage = getActivePage();
		return (activePage == null) ? null: activePage.getActivePart();
	}
	
	protected IEditorPart getActiveEditor() {
		IWorkbenchPage activePage = getActivePage();
		return (activePage == null) ? null: activePage.getActiveEditor();
	}
	
	protected ITextEditor getActiveTextEditor() {
		return getTextEditor(getActiveEditor());
	}
	
	protected ITextEditor getTextEditor(IWorkbenchPart part) {
		return (part == null) ? null : (ITextEditor) part.getAdapter(ITextEditor.class);
	}
	
	protected JpaFile getJpaFile() {
		IEditorInput input = this.textEditor.getEditorInput();
		if ( ! (input instanceof IFileEditorInput)) {
			return null;
		}
		return JptJpaCorePlugin.getJpaFile(((IFileEditorInput) input).getFile());
	}

	protected IPostSelectionProvider getPostSelectionProvider() {
		return (IPostSelectionProvider) this.textEditor.getSelectionProvider();
	}


	// ********** listener callbacks **********

	protected void editorInputChanged() {
		this.selectionChanged();
	}

	protected void editorSelectionChanged(SelectionChangedEvent event) {
		// This is a bit kludgey.  We check to see if the selection event 
		// occurred when a participating part is active (and so, ostensibly,
		// *because* of the participating part).  If so, we reselect the valid 
		// text.
		IWorkbenchPart activePart = getActivePart();
		if (getTextEditor(activePart) != this.textEditor && this.selectionManager.isRegistered(activePart)) {
			if (this.currentSelection.isEmpty()) {
				return;
			}
			
			this.forwardSelection = false;
			TextRange textRange = this.currentSelection.getSelectedNode().getSelectionTextRange();
			if (textRange != null) {
				this.textEditor.selectAndReveal(textRange.getOffset(), textRange.getLength());
			}
			this.forwardSelection = true;
			
			return;
		}
		
		this.selectionChanged();
	}

	protected void selectionChanged() {
		JpaSelection newSelection = this.calculateSelection();
		if (newSelection.equals(this.currentSelection)) {
			return;
		}
		this.currentSelection = newSelection;
		
		if (this.forwardSelection) {
			this.selectionManager.select(newSelection, this);
		}
	}


	// ********** listeners **********

	protected class EditorInputListener implements IPropertyListener {
		protected EditorInputListener() {
			super();
		}
		public void propertyChanged(Object source, int propId) {
			if ((source == TextEditorSelectionParticipant.this.textEditor)
						&& (propId == IEditorPart.PROP_INPUT)) {
				TextEditorSelectionParticipant.this.editorInputChanged();
			}
		}
	}


	protected class EditorSelectionListener implements ISelectionChangedListener {
		protected EditorSelectionListener() {
			super();
		}
		public void selectionChanged(SelectionChangedEvent event) {
			TextEditorSelectionParticipant.this.editorSelectionChanged(event);
		}
	}

}

Back to the top