package com.github.fabrizioiannetti.largefileeditor; import java.io.File; import java.net.URI; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.action.IAction; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.IFindReplaceTarget; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorSite; import org.eclipse.ui.IURIEditorInput; import org.eclipse.ui.IWorkbenchCommandConstants; import org.eclipse.ui.PartInitException; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; import org.eclipse.ui.part.EditorPart; import org.eclipse.ui.texteditor.FindReplaceAction; import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds; import com.github.fabeclipse.textedgrep.IGrepTarget; public class LargeFileEditor extends EditorPart implements IFindReplaceTarget { private File textFile; private FileTextViewer viewer; private IPropertyChangeListener fFontPropertyChangeListener= new FontPropertyChangeListener(); private IContextActivation context; /** * Internal property change listener for handling workbench font changes. * @since 2.1 */ class FontPropertyChangeListener implements IPropertyChangeListener { /* * @see IPropertyChangeListener#propertyChange(org.eclipse.jface.util.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent event) { if (viewer == null) return; String property= event.getProperty(); if (JFaceResources.TEXT_FONT.equals(property)) { viewer.setFont(JFaceResources.getTextFont()); return; } } } @Override public void doSave(IProgressMonitor monitor) { // this editor is read only : save does not do anything if (monitor != null) { monitor.done(); } } @Override public void doSaveAs() { // TODO allow copy? } @Override public void init(IEditorSite site, IEditorInput input) throws PartInitException { setSite(site); if (input instanceof IURIEditorInput) { setInput(input); IURIEditorInput fileInput = (IURIEditorInput) input; URI uri = fileInput.getURI(); textFile = new File(uri); // TODO: only allow local files? } if (textFile == null) { throw new PartInitException("Could not read input:" + input.getName()); } } @Override public boolean isDirty() { // this editor is read-only return false; } @Override public boolean isSaveAsAllowed() { // TODO allow copy? return false; } @Override public void createPartControl(Composite parent) { parent.setLayout(GridLayoutFactory.fillDefaults().create()); viewer = new FileTextViewer(textFile, parent, SWT.H_SCROLL | SWT.V_SCROLL); viewer.setLayoutData(GridDataFactory.fillDefaults().grab(true, true).create()); viewer.setFont(JFaceResources.getTextFont()); JFaceResources.getFontRegistry().addListener(fFontPropertyChangeListener); createActions(); activateGrepTargetContext(); } private void activateGrepTargetContext() { IContextService contextService = (IContextService) getSite().getService(IContextService.class); context = contextService.activateContext("org.eclipse.ui.textEditorScope"); } private void deactivateGrepTargetContext() { if (context == null) return; IContextService contextService = (IContextService) getSite().getService(IContextService.class); contextService.deactivateContext(context); } private void createActions() { FindReplaceAction action = new FindReplaceAction(new LargeFileEditorMessages(), null, this); //$NON-NLS-1$ action.setHelpContextId(IAbstractTextEditorHelpContextIds.FIND_ACTION); action.setActionDefinitionId(IWorkbenchCommandConstants.EDIT_FIND_AND_REPLACE); putAction(ActionFactory.FIND.getId(), action); } private Map<String, IAction> fActions = new HashMap<String, IAction>(); private void putAction(String key, IAction action) { fActions.put(key, action); } /** * Get an action implemented by this editor by id. * * Currently implemented: * <ul> * <li> find, with id {@link ActionFactory.FIND.getId()} * </ul> * * @param actionId * @return */ public IAction getAction(String actionId) { return fActions.get(actionId); } public void select(int start, int length) { viewer.setSelection(start, start + length); } public FileTextViewer getViewer() { return viewer; } @Override public void setFocus() { viewer.setFocus(); } @Override public void dispose() { super.dispose(); JFaceResources.getFontRegistry().removeListener(fFontPropertyChangeListener); deactivateGrepTargetContext(); } @Override public boolean canPerformFind() { return true; } @Override public int findAndSelect(int widgetOffset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord) { FileTextModel model = viewer.getModel(); long pos = model.findString(findString, widgetOffset, caseSensitive, searchForward, null); if (pos >= 0) { viewer.setSelection((int) pos, (int) pos + findString.length()); } return (int) pos; } @Override public Point getSelection() { // limit to a single line Point selection = viewer.getSelectionMaxOneLine(); return selection; } @Override public String getSelectionText() { // limit to a single line String text = viewer.getSelectionTextMaxOneLine(); return text; } @Override public boolean isEditable() { // edit not supported return false; } @Override public void replaceSelection(String text) { // edit not supported } @SuppressWarnings("unchecked") @Override public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { if (IGrepTarget.class.equals(adapter)) { return new LargeFileGrepTarget(this); } return super.getAdapter(adapter); } }