Package it.unibz.instasearch.ui

Source Code of it.unibz.instasearch.ui.MatchHighlightJob$MatchHighliter

/*
* Copyright (c) 2009 Andrejs Jermakovics.
*
* 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:
*     Andrejs Jermakovics - initial implementation
*/
package it.unibz.instasearch.ui;

import it.unibz.instasearch.InstaSearchPlugin;
import it.unibz.instasearch.indexing.SearchResultDoc;
import it.unibz.instasearch.ui.ResultContentProvider.MatchLine;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.search.ui.NewSearchUI;
import org.eclipse.search.ui.text.Match;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.MultiPageEditorPart;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.MarkerUtilities;

class MatchHighlightJob extends Job implements ISchedulingRule, IPartListener
{
  private SearchResultDoc doc;
  private MatchLine selectedLineMatches;
  private ResultContentProvider contentProvider;
  private ITextEditor editor;
  private Job searchJob;
  private IDocument document;
  private IWorkbenchPage workbenchPage;
  private IFile file;

  /**
   * @param doc
   * @param selectedLineMatches
   * @param contentProvider
   * @param workbenchPage
   * @throws Exception
   */
  public MatchHighlightJob(SearchResultDoc doc, MatchLine selectedLineMatches, ResultContentProvider contentProvider, Job searchJob, IWorkbenchPage workbenchPage) throws Exception
  {
    super("Highlight Matches");
   
    this.doc = doc;
    this.selectedLineMatches = selectedLineMatches;
    this.contentProvider = contentProvider;
    this.searchJob = searchJob;
    this.workbenchPage = workbenchPage;
   
    IEditorInput input = contentProvider.getEditorInput(doc);
    IEditorDescriptor editorDesc = IDE.getEditorDescriptor(doc.getFileName());
   
    IEditorPart editorPart = IDE.openEditor(workbenchPage, input, editorDesc.getId());
    this.editor = getTextEditor(input, editorPart);
    this.document = editor.getDocumentProvider().getDocument(editor.getEditorInput());
   
    IStorage storage = contentProvider.getStorage(doc);
    this.file = null;
    if( storage instanceof IFile )
      file = (IFile) storage;
  }
 
  @Override
  protected IStatus run(IProgressMonitor monitor)
  {
    try {
      if( editor != null )
      {
        workbenchPage.addPartListener(this);
       
        findAndHighlightMatches(doc, monitor);
      }
    } catch (Exception e) {
      InstaSearchPlugin.log(e);
    } finally {
      workbenchPage.removePartListener(this);
    }

    return Status.OK_STATUS;
  }
 
  private void findAndHighlightMatches(SearchResultDoc doc, final IProgressMonitor monitor)
    throws Exception, BadLocationException, CoreException
  {
    if( file != null )
    {
      deleteMarkers();
      addMarkerRemover(file);
    }
   
    MatchHighliter highlighter = new MatchHighliter(monitor);
   
    if( selectedLineMatches != null )
      highlighter.highlightMatchLine(file, selectedLineMatches);
   
    contentProvider.getMatchLines(doc, false, highlighter);
   
    //highlightMatches(file, selectedLineMatches, lineMatchesList, monitor);
  }
 
  private class MatchHighliter implements ResultContentProvider.MatchFindCallback
  {
    private IProgressMonitor monitor;
    private boolean matchSelected = false;

    /**
     * @param monitor
     */
    public MatchHighliter(IProgressMonitor monitor)
    {
      this.monitor = monitor;
    }

    public void matchFound(MatchLine line)
    {
      try
      {
        highlightMatchLine(file, line);
      }
      catch (Exception e)
      {
        InstaSearchPlugin.log(e);
        monitor.setCanceled(true);
      }
    }

    public boolean isCanceled()
    {
      return monitor.isCanceled();
    }
   
    /**
     * @param file
     * @throws CoreException
     * @throws BadLocationException
     */
    protected void highlightMatchLine(IFile file, MatchLine lineMatches) throws CoreException, BadLocationException
    {
      int lineNum = lineMatches.getLineNumber();
   
      if( document.getNumberOfLines() < lineNum )
        return;
   
      if( selectedLineMatches == null ) selectedLineMatches = lineMatches; // pick first
     
      int pos = document.getLineOffset(lineNum-1);
   
      for(Match match: lineMatches.getMatches())
      {
        if( monitor.isCanceled() ) break;
       
        editor.setHighlightRange(pos+match.getOffset(), match.getLength(), false);
       
        IMarker marker = createMarker(pos, lineNum, match, file, editor);
       
        if(selectedLineMatches != null && lineNum == selectedLineMatches.getLineNumber())
        {
          if( marker != null && ! matchSelected )
          {
            gotoEditorMarker(marker);
            matchSelected = true;
          }
         
          if( !matchSelected ) {
            int selectedOffset = pos+match.getOffset();
            int selectedLength = match.getLength();
            editor.setHighlightRange(selectedOffset, selectedLength, true);
            matchSelected = true;
          }
        }
      }
    }

    private IMarker createMarker(int pos, int lineNumber, Match match, IFile file, ITextEditor textEditor) throws CoreException {
     
      if( file == null )
        return null;
     
      IMarker marker = null
     
      marker = file.createMarker(NewSearchUI.SEARCH_MARKER);
      marker.setAttribute(IMarker.TRANSIENT, true);
      marker.setAttribute(IMarker.MESSAGE, match.getElement());
     
      MarkerUtilities.setLineNumber(marker, lineNumber);
      MarkerUtilities.setCharStart(marker, pos + match.getOffset());
      MarkerUtilities.setCharEnd(marker, pos + match.getOffset() + match.getLength());
     
      return marker;
    }

    private void gotoEditorMarker(final IMarker selectedMarker)
    {
      if( selectedMarker == null )
        return;
     
      Runnable runnable = new Runnable()
      {
        public void run()
        {
          IDE.gotoMarker(editor, selectedMarker);
        }
      };
     
      editor.getSite().getShell().getDisplay().asyncExec(runnable)
    }

  }
 
  private ITextEditor getTextEditor(IEditorInput input, IEditorPart editor)
  {
    if( editor instanceof MultiPageEditorPart )
    {
      MultiPageEditorPart multiPageEditor = (MultiPageEditorPart) editor;
      IEditorPart[] editors = multiPageEditor.findEditors(input);
     
      for(IEditorPart ed: editors)
      {
        if( ed instanceof ITextEditor )
        {
          multiPageEditor.setActiveEditor(ed);
          return (ITextEditor) ed;
        }
      }
    }
    else if( editor instanceof ITextEditor )
    {
      return (ITextEditor) editor;
    }
   
    return null;
  }

  /**
   * Remove markers when new search is made
   * @param file
   */
  private void addMarkerRemover(final IFile file)
  {
     searchJob.addJobChangeListener(new JobChangeAdapter(){
      public void done(IJobChangeEvent event) {
        try {
          cancel();
          deleteMarkers();
        } finally {
          searchJob.removeJobChangeListener(this);
        }
      }
     });
  }
 
  public boolean contains(ISchedulingRule rule) {
    return rule.getClass() == this.getClass();
  }

  public boolean isConflicting(ISchedulingRule rule) {
    return rule.getClass() == this.getClass();
  }


  public void partClosed(IWorkbenchPart part)
  {
    if( part == editor ) // if closing editor
    {
      this.cancel(); // cancel highlight job
      deleteMarkers();
    }
  }

  private void deleteMarkers()
  {
    try
    {
      if( file != null )
        file.deleteMarkers(NewSearchUI.SEARCH_MARKER, true, IResource.DEPTH_INFINITE);
    }
    catch (CoreException e)
    {
      InstaSearchPlugin.log(e);
    }
  }

  public void partDeactivated(IWorkbenchPart part)
  {
  }

  public void partOpened(IWorkbenchPart part)
  {
  }
 
  public void partActivated(IWorkbenchPart part)
  {
  }

  public void partBroughtToTop(IWorkbenchPart part)
  {
  }

}
TOP

Related Classes of it.unibz.instasearch.ui.MatchHighlightJob$MatchHighliter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.