org.eclipse.mylyn.wikitext.ui_1.6.1.v20120425-0100

notation)
        {
          if (!annotation.isCollapsed())
          {
            annotation.markCollapsed();
            return true;
          }
          return false;
        }
      }, collapseRegionContainingCaret);
    }
  }
  
  public void collapseElements(Collection<OutlineItem> items, boolean collapseRegionContainingCaret)
  {
    if (!isFoldingEnabled()) {
      return;
    }
    if ((items == null) || (items.isEmpty())) {
      return;
    }
    operateOnAnnotations(new AbstractItemsAnnotationOperation(items)
    {
      public boolean operateOnSelected(HeadingProjectionAnnotation annotation)
      {
        if (!annotation.isCollapsed())
        {
          annotation.markCollapsed();
          return true;
        }
        return false;
      }
    }, collapseRegionContainingCaret);
  }
  
  public void expandAll()
  {
    if (!isFoldingEnabled()) {
      return;
    }
    textOperationTarget.doOperation(20);
  }
  
  public void expandElements(Collection<OutlineItem> items)
  {
    if (!isFoldingEnabled()) {
      return;
    }
    if ((items == null) || (items.isEmpty())) {
      return;
    }
    operateOnAnnotations(new AbstractItemsAnnotationOperation(items)
    {
      public boolean operateOnSelected(HeadingProjectionAnnotation annotation)
      {
        if (annotation.isCollapsed())
        {
          annotation.markExpanded();
          return true;
        }
        return false;
      }
    }, true);
  }
  
  public void expandElementsExclusive(Collection<OutlineItem> items, boolean collapseRegionContainingCaret)
  {
    if (!isFoldingEnabled()) {
      return;
    }
    if ((items == null) || (items.isEmpty()))
    {
      collapseAll(collapseRegionContainingCaret);
      return;
    }
    operateOnAnnotations(new AbstractItemsAnnotationOperation(items)
    {
      public boolean operateOnSelected(HeadingProjectionAnnotation annotation)
      {
        if (annotation.isCollapsed())
        {
          annotation.markExpanded();
          return true;
        }
        return false;
      }
      
      public boolean operateOnUnselected(HeadingProjectionAnnotation annotation)
      {
        if (!annotation.isCollapsed())
        {
          annotation.markCollapsed();
          return true;
        }
        return false;
      }
    }, collapseRegionContainingCaret);
  }
  
  public void operateOnAnnotations(AnnotationOperation operation, boolean collapseRegionIncludingCaret)
  {
    if (!isFoldingEnabled()) {
      return;
    }
    Point selectedRange = viewer.getSelectedRange();
    Position selectedPosition = selectedRange == null ? null : new Position(x, y);
    boolean updateSelectedRange = false;
    ProjectionAnnotationModel annotationModel = viewer.getProjectionAnnotationModel();
    List<Annotation> modifications = null;
    Iterator<Annotation> iterator = annotationModel.getAnnotationIterator();
    while (iterator.hasNext())
    {
      Annotation annotation = (Annotation)iterator.next();
      if ((annotation instanceof HeadingProjectionAnnotation))
      {
        HeadingProjectionAnnotation projectionAnnotation = (HeadingProjectionAnnotation)annotation;
        if (operation.operate(projectionAnnotation))
        {
          if (modifications == null) {
            modifications = new ArrayList();
          }
          modifications.add(projectionAnnotation);
          Position position = annotationModel.getPosition(projectionAnnotation);
          if ((!collapseRegionIncludingCaret) && (projectionAnnotation.isCollapsed()) && (selectedPosition != null) && 
            (selectedPosition.overlapsWith(position.getOffset(), position.getLength()))) {
            projectionAnnotation.markExpanded();
          }
          if ((selectedPosition != null) && (position != null) && (projectionAnnotation.isCollapsed()) && 
            (selectedPosition.overlapsWith(offset, length))) {
            updateSelectedRange = true;
          }
        }
      }
    }
    if (modifications != null)
    {
      if (updateSelectedRange)
      {
        int offset = 0;
        iterator = annotationModel.getAnnotationIterator();
        while (iterator.hasNext())
        {
          Annotation annotation = (Annotation)iterator.next();
          if ((annotation instanceof HeadingProjectionAnnotation))
          {
            HeadingProjectionAnnotation projectionAnnotation = (HeadingProjectionAnnotation)annotation;
            if (!projectionAnnotation.isCollapsed())
            {
              Position position = annotationModel.getPosition(projectionAnnotation);
              if (position != null)
              {
                offset = offset;
                break;
              }
            }
          }
        }
        viewer.setSelectedRange(offset, 0);
      }
      annotationModel.modifyAnnotations(null, null, (Annotation[])modifications.toArray(new Annotation[modifications.size()]));
    }
  }
  
  public final boolean isFoldingEnabled()
  {
    return viewer.getProjectionAnnotationModel() != null;
  }
  
  private static abstract interface AnnotationOperation
  {
    public abstract boolean operate(HeadingProjectionAnnotation paramHeadingProjectionAnnotation);
  }
}

/* Location:
 * Qualified Name:     org.eclipse.mylyn.internal.wikitext.ui.editor.FoldingStructure
 * Java Class Version: 5 (49.0)
 * JD-Core Version:    0.7.1
 */
package org.eclipse.mylyn.internal.wikitext.ui.editor;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.action.AbstractAction;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.commands.ActionHandler;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jface.text.IDocumentPartitioningListener;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.URLHyperlink;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.Annotation;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.projection.IProjectionListener;
import org.eclipse.jface.text.source.projection.ProjectionAnnotationModel;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.mylyn.internal.wikitext.ui.WikiTextUiPlugin;
import org.eclipse.mylyn.internal.wikitext.ui.editor.actions.PreviewOutlineItemAction;
import org.eclipse.mylyn.internal.wikitext.ui.editor.actions.SetMarkupLanguageAction;
import org.eclipse.mylyn.internal.wikitext.ui.editor.operations.CommandManager;
import org.eclipse.mylyn.internal.wikitext.ui.editor.preferences.Preferences;
import org.eclipse.mylyn.internal.wikitext.ui.editor.reconciler.MarkupMonoReconciler;
import org.eclipse.mylyn.internal.wikitext.ui.editor.syntax.FastMarkupPartitioner;
import org.eclipse.mylyn.internal.wikitext.ui.editor.syntax.MarkupDocumentProvider;
import org.eclipse.mylyn.internal.wikitext.ui.editor.syntax.MarkupTokenScanner;
import org.eclipse.mylyn.internal.wikitext.ui.util.NlsResourceBundle;
import org.eclipse.mylyn.wikitext.core.WikiText;
import org.eclipse.mylyn.wikitext.core.parser.Attributes;
import org.eclipse.mylyn.wikitext.core.parser.DocumentBuilder.BlockType;
import org.eclipse.mylyn.wikitext.core.parser.MarkupParser;
import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder;
import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder.Stylesheet;
import org.eclipse.mylyn.wikitext.core.parser.markup.MarkupLanguage;
import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineItem;
import org.eclipse.mylyn.wikitext.core.parser.outline.OutlineParser;
import org.eclipse.mylyn.wikitext.core.util.XmlStreamWriter;
import org.eclipse.mylyn.wikitext.ui.editor.MarkupSourceViewerConfiguration;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.browser.Browser;
import org.eclipse.swt.browser.LocationEvent;
import org.eclipse.swt.browser.LocationListener;
import org.eclipse.swt.browser.ProgressAdapter;
import org.eclipse.swt.browser.ProgressEvent;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.contexts.IContextService;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.handlers.IHandlerService;
import org.eclipse.ui.part.IShowInSource;
import org.eclipse.ui.part.IShowInTarget;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.part.ShowInContext;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.swt.IFocusService;
import org.eclipse.ui.texteditor.ContentAssistAction;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;

public class MarkupEditor
  extends TextEditor
  implements IShowInTarget, IShowInSource, CommandManager
{
  private static final String RULER_CONTEXT_MENU_ID = "org.eclipse.mylyn.internal.wikitext.ui.editor.MarkupEditor.ruler";
  private static final String MARKUP_LANGUAGE = "markupLanguage";
  public static final String CONTEXT = "org.eclipse.mylyn.wikitext.ui.editor.markupSourceContext";
  public static final String ID = "org.eclipse.mylyn.wikitext.ui.editor.markupEditor";
  private static final String[] SHOW_IN_TARGETS = {
    "org.eclipse.ui.views.ResourceNavigator", 
    "org.eclipse.jdt.ui.PackageExplorer", 
    "org.eclipse.ui.navigator.ProjectExplorer", 
    "org.eclipse.ui.views.ContentOutline" };
  private static IShowInTargetList SHOW_IN_TARGET_LIST = new IShowInTargetList()
  {
    public String[] getShowInTargetIds()
    {
      return MarkupEditor.SHOW_IN_TARGETS;
    }
  };
  private IDocument document;
  private IDocumentListener documentListener;
  private boolean previewDirty = true;
  private boolean outlineDirty = true;
  private Browser browser;
  private MarkupEditorOutline outlinePage;
  private OutlineItem outlineModel;
  private final OutlineParser outlineParser = new OutlineParser();
  private boolean disableReveal;
  private ISourceViewer viewer;
  private IPropertyChangeListener preferencesListener;
  private IDocumentPartitioningListener documentPartitioningListener;
  private final MarkupSourceViewerConfiguration sourceViewerConfiguration;
  private CTabItem sourceTab;
  private ProjectionSupport projectionSupport;
  private Map<String, HeadingProjectionAnnotation> projectionAnnotationById;
  private boolean updateJobScheduled;
  protected int documentGeneration;
  public static final String EDITOR_SOURCE_VIEWER = "org.eclipse.mylyn.wikitext.ui.editor.sourceViewer";
  private UIJob updateOutlineJob;
  private IFoldingStructure foldingStructure;
  private CTabFolder tabFolder;
  private CTabItem previewTab;
  private static final String JAVASCRIPT_GETSCROLLTOP = "function getScrollTop() {   if(typeof pageYOffset!='undefined') return pageYOffset;  else{var B=document.body;var D=document.documentElement;D=(D.clientHeight)?D:B;return D.scrollTop;}}; return getScrollTop();";
  
  public MarkupEditor()
  {
    outlineParser.setLabelMaxLength(48);
    outlineModel = outlineParser.createRootItem();
    
    disableReveal = false;
    
    updateJobScheduled = false;
    
    documentGeneration = 0;
    
    setDocumentProvider(new MarkupDocumentProvider());
    sourceViewerConfiguration = new MarkupSourceViewerConfiguration(getPreferenceStore());
    sourceViewerConfiguration.setOutline(outlineModel);
    sourceViewerConfiguration.setShowInTarget(this);
    setSourceViewerConfiguration(sourceViewerConfiguration);
  }
  
  protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler ruler, int styles)
  {
    sourceViewerConfiguration.initializeDefaultFonts();
    tabFolder = new CTabFolder(parent, 1024);
    
    sourceTab = new CTabItem(tabFolder, 0);
    updateSourceTabLabel();
    
    viewer = new MarkupProjectionViewer(tabFolder, ruler, getOverviewRuler(), isOverviewRulerVisible(), styles | 
      0x40);
    
    sourceTab.setControl(((Viewer)viewer).getControl());
    tabFolder.setSelection(sourceTab);
    try
    {
      previewTab = new CTabItem(tabFolder, 0);
      previewTab.setText(Messages.MarkupEditor_preview);
      previewTab.setToolTipText(Messages.MarkupEditor_preview_tooltip);
      
      browser = new Browser(tabFolder, 0);
      
      browser.addLocationListener(new LocationListener()
      {
        public void changed(LocationEvent event)
        {
          doit = false;
        }
        
        public void changing(LocationEvent event)
        {
          if (location.matches("([a-zA-Z]{3,8})://?.*"))
          {
            int idxOfSlashHash = location.indexOf("/#");
            if (idxOfSlashHash != -1)
            {
              if (!location.startsWith("file:///#")) {
                doit = false;
              }
              return;
            }
            doit = false;
            try
            {
              PlatformUI.getWorkbench().getBrowserSupport().createBrowser("org.eclipse.ui.browser").openURL(new URL(location));
            }
            catch (Exception localException)
            {
              new URLHyperlink(new Region(0, 1), location).open();
            }
          }
        }
      });
      previewTab.setControl(browser);
    }
    catch (SWTError localSWTError)
    {
      if (previewTab != null)
      {
        previewTab.dispose();
        previewTab = null;
      }
    }
    tabFolder.addSelectionListener(new SelectionListener()
    {
      public void widgetDefaultSelected(SelectionEvent selectionevent)
      {
        widgetSelected(selectionevent);
      }
      
      public void widgetSelected(SelectionEvent selectionevent)
      {
        if (MarkupEditor.this.isShowingPreview()) {
          MarkupEditor.this.updatePreview();
        }
      }
    });
    viewer.getTextWidget().addSelectionListener(new SelectionListener()
    {
      public void widgetDefaultSelected(SelectionEvent e) {}
      
      public void widgetSelected(SelectionEvent e)
      {
        MarkupEditor.this.updateOutlineSelection();
      }
    });
    viewer.getTextWidget().addKeyListener(new KeyAdapter()
    {
      public void keyReleased(KeyEvent e)
      {
        if (isRelevantKeyCode(keyCode)) {
          MarkupEditor.this.updateOutlineSelection();
        }
      }
      
      private boolean isRelevantKeyCode(int keyCode)
      {
        switch (keyCode)
        {
        case 16777217: 
        case 16777218: 
        case 16777219: 
        case 16777220: 
        case 16777221: 
        case 16777222: 
          return true;
        }
        return false;
      }
    });
    viewer.getTextWidget().addMouseListener(new MouseAdapter()
    {
      public void mouseUp(MouseEvent e)
      {
        MarkupEditor.this.updateOutlineSelection();
      }
    });
    IFocusService focusService = (IFocusService)PlatformUI.getWorkbench().getService(IFocusService.class);
    if (focusService != null) {
      focusService.addFocusTracker(viewer.getTextWidget(), "org.eclipse.mylyn.wikitext.ui.editor.sourceViewer");
    }
    viewer.getTextWidget().setData(MarkupLanguage.class.getName(), getMarkupLanguage());
    viewer.getTextWidget().setData(ISourceViewer.class.getName(), viewer);
    
    getSourceViewerDecorationSupport(viewer);
    
    updateDocument();
    if (preferencesListener == null)
    {
      preferencesListener = new IPropertyChangeListener()
      {
        public void propertyChange(PropertyChangeEvent event)
        {
          if (viewer.getTextWidget().isDisposed()) {
            return;
          }
          if (MarkupEditor.this.isFontPreferenceChange(event)) {
            viewer.getTextWidget().getDisplay().asyncExec(new Runnable()
            {
              public void run()
              {
                MarkupEditor.this.reloadPreferences();
              }
            });
          }
        }
      };
      WikiTextUiPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(preferencesListener);
    }
    return viewer;
  }
  
  public void createPartControl(Composite parent)
  {
    super.createPartControl(parent);
    ProjectionViewer viewer = (ProjectionViewer)getSourceViewer();
    if (sourceViewerConfiguration.getDefaultFont() != null) {
      viewer.getTextWidget().setFont(sourceViewerConfiguration.getDefaultFont());
    }
    projectionSupport = new ProjectionSupport(viewer, getAnnotationAccess(), getSharedColors());
    projectionSupport.install();
    
    syncProjectionModeWithPreferences();
    
    viewer.addProjectionListener(new IProjectionListener()
    {
      public void projectionDisabled()
      {
        projectionAnnotationById = null;
        saveProjectionPreferences();
      }
      
      public void projectionEnabled()
      {
        saveProjectionPreferences();
        MarkupEditor.this.updateProjectionAnnotations();
      }
    });
    if ((!outlineDirty) && (isFoldingEnabled())) {
      updateProjectionAnnotations();
    }
    JFaceResources.getFontRegistry().addListener(preferencesListener);
  }
  
  private void reloadPreferences()
  {
    previewDirty = true;
    syncProjectionModeWithPreferences();
    ((MarkupTokenScanner)sourceViewerConfiguration.getMarkupScanner()).reloadPreferences();
    sourceViewerConfiguration.initializeDefaultFonts();
    viewer.invalidateTextPresentation();
  }
  
  private boolean isFontPreferenceChange(PropertyChangeEvent event)
  {
    if ((event.getProperty().equals(sourceViewerConfiguration.getFontPreference())) || 
      (event.getProperty().equals(sourceViewerConfiguration.getMonospaceFontPreference()))) {
      return true;
    }
    return false;
  }
  
  protected void handlePreferenceStoreChanged(PropertyChangeEvent event)
  {
    super.handlePreferenceStoreChanged(event);
    reloadPreferences();
  }
  
  private void syncProjectionModeWithPreferences()
  {
    ProjectionViewer viewer = (ProjectionViewer)getSourceViewer();
    if (viewer.isProjectionMode() != WikiTextUiPlugin.getDefault().getPreferences().isEditorFolding()) {
      viewer.doOperation(19);
    }
  }
  
  public void updatePartControl(IEditorInput input)
  {
    super.updatePartControl(input);
    updateDocument();
  }
  
  public void saveProjectionPreferences()
  {
    if (isFoldingEnabled() != WikiTextUiPlugin.getDefault().getPreferences().isEditorFolding())
    {
      Preferences preferences = WikiTextUiPlugin.getDefault().getPreferences().clone();
      preferences.setEditorFolding(isFoldingEnabled());
      preferences.save(WikiTextUiPlugin.getDefault().getPreferenceStore(), false);
    }
  }
  
  public void dispose()
  {
    if (document != null)
    {
      if (documentListener != null) {
        document.removeDocumentListener(documentListener);
      }
      if (documentPartitioningListener != null) {
        document.removeDocumentPartitioningListener(documentPartitioningListener);
      }
      document = null;
    }
    if (preferencesListener != null)
    {
      WikiTextUiPlugin.getDefault().getPreferenceStore().removePropertyChangeListener(preferencesListener);
      JFaceResources.getFontRegistry().addListener(preferencesListener);
      preferencesListener = null;
    }
    super.dispose();
  }
  
  protected void initializeEditor()
  {
    super.initializeEditor();
    setHelpContextId("org.eclipse.mylyn.wikitext.ui.editor.markupSourceContext");
    setRulerContextMenuId("org.eclipse.mylyn.internal.wikitext.ui.editor.MarkupEditor.ruler");
  }
  
  protected void doSetInput(IEditorInput input)
    throws CoreException
  {
    super.doSetInput(input);
    updateDocument();
    IFile file = getFile();
    if (sourceViewerConfiguration != null) {
      sourceViewerConfiguration.setFile(file);
    }
    initializeMarkupLanguage(input);
    outlineModel.setResourcePath(file == null ? null : file.getFullPath().toString());
  }
  
  private void updateDocument()
  {
    if (getSourceViewer() != null)
    {
      IDocument previousDocument = document;
      document = getSourceViewer().getDocument();
      if (previousDocument == document) {
        return;
      }
      if ((previousDocument != null) && (documentListener != null)) {
        previousDocument.removeDocumentListener(documentListener);
      }
      if ((previousDocument != null) && (documentPartitioningListener != null)) {
        previousDocument.removeDocumentPartitioningListener(documentPartitioningListener);
      }
      if (document != null)
      {
        if (documentListener == null) {
          documentListener = new IDocumentListener()
          {
            public void documentAboutToBeChanged(DocumentEvent event) {}
            
            public void documentChanged(DocumentEvent event)
            {
              previewDirty = true;
              outlineDirty = true;
              synchronized (MarkupEditor.this)
              {
                documentGeneration += 1;
              }
              MarkupEditor.this.scheduleOutlineUpdate();
              if (MarkupEditor.this.isShowingPreview()) {
                MarkupEditor.this.updatePreview();
              }
            }
          };
        }
        document.addDocumentListener(documentListener);
        if (documentPartitioningListener == null) {
          documentPartitioningListener = new IDocumentPartitioningListener()
          {
            public void documentPartitioningChanged(IDocument document)
            {
              MarkupEditor.this.scheduleOutlineUpdate();
            }
          };
        }
        document.addDocumentPartitioningListener(documentPartitioningListener);
      }
      previewDirty = true;
      outlineDirty = true;
      updateOutline();
    }
  }
  
  private void updatePreview()
  {
    updatePreview(null);
  }
  
  private void updatePreview(final OutlineItem outlineItem)
  {
    if ((previewDirty) && (browser != null))
    {
      Object result = browser.evaluate("function getScrollTop() {   if(typeof pageYOffset!='undefined') return pageYOffset;  else{var B=document.body;var D=document.documentElement;D=(D.clientHeight)?D:B;return D.scrollTop;}}; return getScrollTop();");
      final int verticalScrollbarPos = result != null ? ((Number)result).intValue() : 0;
      String xhtml = null;
      if (document == null) {
        xhtml = "<?xml version=\"1.0\" ?><html xmlns=\"http://www.w3.org/1999/xhtml\"><body></body></html>";
      } else {
        try
        {
          IFile file = getFile();
          String title = file == null ? "" : file.getName();
          if (title.lastIndexOf('.') != -1) {
            title = title.substring(0, title.lastIndexOf('.'));
          }
          StringWriter writer = new StringWriter();
          HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer)
          {
            protected void emitAnchorHref(String href)
            {
              if (href.startsWith("#"))
              {
                writer.writeAttribute(
                  "onclick", String.format("javascript: window.location.hash = '%s'; return false;", new Object[] { href }));
                writer.writeAttribute("href", "#");
              }
              else
              {
                super.emitAnchorHref(href);
              }
            }
          };
          builder.setTitle(title);
          
          IPath location = file == null ? null : file.getLocation();
          if (location != null)
          {
            builder.setBaseInHead(true);
            builder.setBase(location.removeLastSegments(1).toFile().toURI());
          }
          String css = WikiTextUiPlugin.getDefault().getPreferences().getMarkupViewerCss();
          if ((css != null) && (css.length() > 0)) {
            builder.addCssStylesheet(new HtmlDocumentBuilder.Stylesheet(new StringReader(css)));
          }
          MarkupLanguage markupLanguage = getMarkupLanguage();
          if (markupLanguage != null)
          {
            markupLanguage = markupLanguage.clone();
            markupLanguage.setEnableMacros(true);
            markupLanguage.setBlocksOnly(false);
            markupLanguage.setFilterGenerativeContents(false);
            
            MarkupParser markupParser = new MarkupParser();
            markupParser.setBuilder(builder);
            markupParser.setMarkupLanguage(markupLanguage);
            
            markupParser.parse(document.get());
          }
          else
          {
            builder.beginDocument();
            builder.beginBlock(DocumentBuilder.BlockType.PREFORMATTED, new Attributes());
            builder.characters(document.get());
            builder.endBlock();
            builder.endDocument();
          }
          xhtml = writer.toString();
        }
        catch (Exception e)
        {
          StringWriter stackTrace = new StringWriter();
          PrintWriter writer = new PrintWriter(stackTrace);
          e.printStackTrace(writer);
          writer.close();
          
          StringWriter documentWriter = new StringWriter();
          HtmlDocumentBuilder builder = new HtmlDocumentBuilder(documentWriter);
          builder.beginDocument();
          builder.beginBlock(DocumentBuilder.BlockType.PREFORMATTED, new Attributes());
          builder.characters(stackTrace.toString());
          builder.endBlock();
          builder.endDocument();
          
          xhtml = documentWriter.toString();
        }
      }
      browser.addProgressListener(new ProgressAdapter()
      {
        public void completed(ProgressEvent event)
        {
          browser.removeProgressListener(this);
          if (outlineItem != null) {
            MarkupEditor.this.revealInBrowser(outlineItem);
          } else {
            browser.execute(String.format("window.scrollTo(0,%d);", new Object[] { Integer.valueOf(verticalScrollbarPos) }));
          }
        }
      });
      browser.setText(xhtml);
      previewDirty = false;
    }
    else if ((outlineItem != null) && (browser != null))
    {
      revealInBrowser(outlineItem);
    }
  }
  
  public IFile getFile()
  {
    IEditorInput editorInput = getEditorInput();
    if ((editorInput instanceof IFileEditorInput))
    {
      IFileEditorInput fileEditorInput = (IFileEditorInput)editorInput;
      return fileEditorInput.getFile();
    }
    return null;
  }
  
  public Object getAdapter(Class adapter)
  {
    if (IContentOutlinePage.class == adapter)
    {
      if ((outlinePage == null) || (outlinePage.getControl() == null) || (outlinePage.getControl().isDisposed())) {
        outlinePage = new MarkupEditorOutline(this);
      }
      return outlinePage;
    }
    if (adapter == OutlineItem.class) {
      return getOutlineModel();
    }
    if (adapter == IFoldingStructure.class)
    {
      if (!isFoldingEnabled()) {
        return null;
      }
      if (foldingStructure == null) {
        foldingStructure = new FoldingStructure(this);
      }
      return foldingStructure;
    }
    if (adapter == IShowInTargetList.class) {
      return SHOW_IN_TARGET_LIST;
    }
    return super.getAdapter(adapter);
  }
  
  public ISourceViewer getViewer()
  {
    return viewer;
  }
  
  public OutlineItem getOutlineModel()
  {
    if (outlineDirty) {
      updateOutlineNow();
    }
    return outlineModel;
  }
  
  private void scheduleOutlineUpdate()
  {
    synchronized (this)
    {
      if (updateJobScheduled) {
        return;
      }
    }
    updateOutlineJob = new UIJob(Messages.MarkupEditor_updateOutline)
    {
      public IStatus runInUIThread(IProgressMonitor monitor)
      {
        synchronized (MarkupEditor.this)
        {
          updateJobScheduled = false;
        }
        if (!outlineDirty) {
          return Status.CANCEL_STATUS;
        }
        MarkupEditor.this.updateOutline();
        return Status.OK_STATUS;
      }
    };
    updateOutlineJob.addJobChangeListener(new JobChangeAdapter()
    {
      public void scheduled(IJobChangeEvent event)
      {
        synchronized (MarkupEditor.this)
        {
          updateJobScheduled = true;
        }
      }
      
      public void done(IJobChangeEvent event)
      {
        synchronized (MarkupEditor.this)
        {
          updateJobScheduled = false;
          updateOutlineJob = null;
        }
      }
    });
    updateOutlineJob.setUser(false);
    updateOutlineJob.setSystem(true);
    updateOutlineJob.setPriority(10);
    updateOutlineJob.schedule(600L);
  }
  
  private void updateOutlineNow()
  {
    if (!outlineDirty) {
      return;
    }
    if (getSourceViewer().getTextWidget().isDisposed()) {
      return;
    }
    MarkupLanguage markupLanguage = getMarkupLanguage();
    if (markupLanguage == null) {
      return;
    }
    MarkupLanguage language = markupLanguage.clone();
    String content = document.get();
    int contentGeneration;
    synchronized (this)
    {
      contentGeneration = documentGeneration;
    }
    int contentGeneration;
    outlineParser.setMarkupLanguage(language);
    OutlineItem rootItem = outlineParser.parse(content);
    updateOutline(contentGeneration, rootItem);
  }
  
  private void updateOutline()
  {
    if (!outlineDirty) {
      return;
    }
    if (getSourceViewer().getTextWidget().isDisposed()) {
      return;
    }
    MarkupLanguage markupLanguage = getMarkupLanguage();
    if (markupLanguage == null) {
      return;
    }
    final MarkupLanguage language = markupLanguage.clone();
    
    final Display display = getSourceViewer().getTextWidget().getDisplay();
    final String content = document.get();
    int contentGeneration;
    synchronized (this)
    {
      contentGeneration = documentGeneration;
    }
    final int contentGeneration;
    Job parseOutlineJob = new Job(MarkupEditor.class.getSimpleName() + "#updateOutline")
    {
      protected IStatus run(IProgressMonitor monitor)
      {
        outlineParser.setMarkupLanguage(language);
        if (shouldCancel()) {
          return Status.CANCEL_STATUS;
        }
        final OutlineItem rootItem = outlineParser.parse(content);
        if (shouldCancel()) {
          return Status.CANCEL_STATUS;
        }
        display.asyncExec(new Runnable()
        {
          public void run()
          {
            MarkupEditor.this.updateOutline(val$contentGeneration, rootItem);
          }
        });
        return Status.OK_STATUS;
      }
      
      private boolean shouldCancel()
      {
        synchronized (MarkupEditor.this)
        {
          if (contentGeneration != documentGeneration) {
            return true;
          }
        }
        return false;
      }
    };
    parseOutlineJob.setPriority(10);
    parseOutlineJob.setSystem(true);
    parseOutlineJob.schedule();
  }
  
  private void updateOutline(int contentGeneration, OutlineItem rootItem)
  {
    if (getSourceViewer().getTextWidget().isDisposed()) {
      return;
    }
    synchronized (this)
    {
      if (contentGeneration != documentGeneration) {
        return;
      }
    }
    outlineDirty = false;
    
    outlineModel.clear();
    outlineModel.moveChildren(rootItem);
    
    IFile file = getFile();
    outlineModel.setResourcePath(file == null ? null : file.getFullPath().toString());
    if ((outlinePage != null) && (outlinePage.getControl() != null) && (!outlinePage.getControl().isDisposed()))
    {
      outlinePage.refresh();
      
      outlinePage.getControl().getDisplay().asyncExec(new Runnable()
      {
        public void run()
        {
          if ((outlinePage != null) && (outlinePage.getControl() != null) && 
            (!outlinePage.getControl().isDisposed())) {
            MarkupEditor.this.updateOutlineSelection();
          }
        }
      });
    }
    updateProjectionAnnotations();
  }
  
  private void updateProjectionAnnotations()
  {
    ProjectionViewer viewer = (ProjectionViewer)getSourceViewer();
    ProjectionAnnotationModel projectionAnnotationModel = viewer.getProjectionAnnotationModel();
    if (projectionAnnotationModel != null)
    {
      List<Annotation> newProjectionAnnotations = new ArrayList(projectionAnnotationById == null ? 
        10 : 
        projectionAnnotationById.size() + 2);
      Map<HeadingProjectionAnnotation, Position> annotationToPosition = new HashMap();
      
      List<OutlineItem> children = outlineModel.getChildren();
      if (!children.isEmpty()) {
        createProjectionAnnotations(newProjectionAnnotations, annotationToPosition, children, 
          document.getLength());
      }
      if ((newProjectionAnnotations.isEmpty()) && (
        (projectionAnnotationById == null) || (projectionAnnotationById.isEmpty()))) {
        return;
      }
      Map<String, HeadingProjectionAnnotation> newProjectionAnnotationById = new HashMap();
      Iterator<Map.Entry<HeadingProjectionAnnotation, Position>> newPositionIt;
      if (projectionAnnotationById != null)
      {
        Set<HeadingProjectionAnnotation> toDelete = new HashSet(
          projectionAnnotationById.size());
        newPositionIt = annotationToPosition.entrySet()
          .iterator();
        while (newPositionIt.hasNext())
        {
          Map.Entry<HeadingProjectionAnnotation, Position> newAnnotationEnt = (Map.Entry)newPositionIt.next();
          
          HeadingProjectionAnnotation newAnnotation = (HeadingProjectionAnnotation)newAnnotationEnt.getKey();
          Position newPosition = (Position)newAnnotationEnt.getValue();
          HeadingProjectionAnnotation annotation = (HeadingProjectionAnnotation)projectionAnnotationById.get(newAnnotation.getHeadingId());
          if (annotation != null)
          {
            Position position = projectionAnnotationModel.getPosition(annotation);
            if (newPosition.equals(position))
            {
              newPositionIt.remove();
              newProjectionAnnotationById.put(annotation.getHeadingId(), annotation);
            }
            else
            {
              toDelete.add(annotation);
              if (annotation.isCollapsed()) {
                newAnnotation.markCollapsed();
              } else {
                newAnnotation.markExpanded();
              }
              newProjectionAnnotationById.put(annotation.getHeadingId(), newAnnotation);
            }
          }
          else
          {
            newProjectionAnnotationById.put(newAnnotation.getHeadingId(), newAnnotation);
          }
        }
        Iterator<Annotation> annotationIt = projectionAnnotationModel.getAnnotationIterator();
        while (annotationIt.hasNext())
        {
          Annotation annotation = (Annotation)annotationIt.next();
          if ((annotation instanceof HeadingProjectionAnnotation))
          {
            HeadingProjectionAnnotation projectionAnnotation = (HeadingProjectionAnnotation)annotation;
            if ((!projectionAnnotationById.containsKey(projectionAnnotation.getHeadingId())) && 
              (!toDelete.contains(projectionAnnotation))) {
              toDelete.add(projectionAnnotation);
            }
          }
        }
        projectionAnnotationModel.modifyAnnotations(
          toDelete.isEmpty() ? null : (Annotation[])toDelete.toArray(new Annotation[toDelete.size()]), 
          annotationToPosition, null);
      }
      else
      {
        projectionAnnotationModel.modifyAnnotations(null, annotationToPosition, null);
        for (HeadingProjectionAnnotation annotation : annotationToPosition.keySet()) {
          newProjectionAnnotationById.put(annotation.getHeadingId(), annotation);
        }
      }
      projectionAnnotationById = newProjectionAnnotationById;
    }
    else
    {
      projectionAnnotationById = null;
    }
  }
  
  private void createProjectionAnnotations(List<Annotation> newProjectionAnnotations, Map<HeadingProjectionAnnotation, Position> annotationToPosition, List<OutlineItem> children, int endOffset)
  {
    int size = children.size();
    int lastIndex = size - 1;
    for (int x = 0; x < size; x++)
    {
      OutlineItem child = (OutlineItem)children.get(x);
      if ((child.getId() != null) && (child.getId().length() != 0))
      {
        int offset = child.getOffset();
        int end;
        int end;
        if (x == lastIndex) {
          end = endOffset;
        } else {
          end = ((OutlineItem)children.get(x + 1)).getOffset();
        }
        int length = end - offset;
        if (length > 0)
        {
          HeadingProjectionAnnotation annotation = new HeadingProjectionAnnotation(child.getId());
          Position position = new Position(offset, length);
          
          newProjectionAnnotations.add(annotation);
          annotationToPosition.put(annotation, position);
        }
        if (!child.getChildren().isEmpty()) {
          createProjectionAnnotations(newProjectionAnnotations, annotationToPosition, child.getChildren(), end);
        }
      }
    }
  }
  
  /* Error */
  private void updateOutlineSelection()
  {
    // Byte code:
    //   0: aload_0
    //   1: getfield 1162	org/eclipse/mylyn/internal/wikitext/ui/editor/MarkupEditor:disableReveal	Z
    //   4: ifeq +4 -> 8
    //   7: return
    //   8: aload_0
    //   9: getfield 1176	org/eclipse/mylyn/internal/wikitext/ui/editor/MarkupEditor:outlineModel	Lorg/eclipse/mylyn/wikitext/core/parser/outline/OutlineItem;
    //   12: ifnull +55 -> 67
    //   15: aload_0
    //   16: getfield 1175	org/eclipse/mylyn/internal/wikitext/ui/editor/MarkupEditor:outlinePage	Lorg/eclipse/mylyn/internal/wikitext/ui/editor/MarkupEditorOutline;
    //   19: ifnull +48 -> 67
    //   22: aload_0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd