Package com.intellij.openapi.diff

Source Code of com.intellij.openapi.diff.FragmentContent

/*
* Copyright 2000-2007 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.diff;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vfs.VirtualFile;

import java.io.IOException;

/**
* Represents sub text of other content. Original content should provide not null document.
*/
public class FragmentContent extends DiffContent {
  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.FragmentContent");
  private final DiffContent myOriginal;
  private final FileType myType;
  private final MyDocumentsSynchonizer mySynchonizer;
  public final static Key<Document> ORIGINAL_DOCUMENT = new Key<Document>("ORIGINAL_DOCUMENT");

  public FragmentContent(DiffContent original, TextRange range, Project project, VirtualFile file) {
    this(original, range, project, file != null ? DiffContentUtil.getContentType(file) : null);
  }

  public FragmentContent(DiffContent original, TextRange range, Project project, FileType type) {
    this(original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true), original, type, project);
  }

  private FragmentContent(RangeMarker rangeMarker, DiffContent original, FileType fileType, Project project) {
    mySynchonizer = new MyDocumentsSynchonizer(project, rangeMarker);
    myOriginal = original;
    myType = fileType;
  }

  public FragmentContent(DiffContent original, TextRange range, Project project) {
    this(original, range, project, (FileType)null);
  }

  private String subText(Document document, int startOffset, int length) {
    return document.getCharsSequence().subSequence(startOffset, startOffset + length).toString();
  }


  public void onAssigned(boolean isAssigned) {
    myOriginal.onAssigned(isAssigned);
    mySynchonizer.listenDocuments(isAssigned);
    super.onAssigned(isAssigned);
  }

  public Document getDocument() {
    return mySynchonizer.getCopy();
  }

  public OpenFileDescriptor getOpenFileDescriptor(int offset) {
    return myOriginal.getOpenFileDescriptor(offset + mySynchonizer.getStartOffset());
  }

  public VirtualFile getFile() { return null; }

  public FileType getContentType() {
    return myType != null ? myType : myOriginal.getContentType();
  }

  public byte[] getBytes() throws IOException {
    return getDocument().getText().getBytes();
  }

  public static FragmentContent fromRangeMarker(RangeMarker rangeMarker, Project project) {
    Document document = rangeMarker.getDocument();
    VirtualFile file = FileDocumentManager.getInstance().getFile(document);
    FileType type = FileTypeManager.getInstance().getFileTypeByFile(file);
    return new FragmentContent(new DocumentContent(project, document), new TextRange(rangeMarker.getStartOffset(), rangeMarker.getEndOffset()), project, type);
  }

  private class MyDocumentsSynchonizer extends DocumentsSynchonizer {
    private final RangeMarker myRangeMarker;

    public MyDocumentsSynchonizer(Project project, RangeMarker originalRange) {
      super(project);
      myRangeMarker = originalRange;
    }

    public int getStartOffset() { return myRangeMarker.getStartOffset(); }

    protected void onOriginalChanged(DocumentEvent event, Document copy) {
      if (!myRangeMarker.isValid()) {
        fireContentInvalid();
        return;
      }
      replaceString(copy, 0, copy.getTextLength(),
                    subText(event.getDocument(), myRangeMarker.getStartOffset(), getLength()));
    }

    protected void beforeListenersAttached(Document original, Document copy) {
      boolean writable = copy.isWritable();
      Document copyEx = copy;
      if (!writable) copyEx.setReadOnly(false);
      replaceString(copy, 0, copy.getTextLength(),
                    subText(original, myRangeMarker.getStartOffset(), getLength()));
      copyEx.setReadOnly(!writable);
    }

    private int getLength() {
      return myRangeMarker.getEndOffset() - myRangeMarker.getStartOffset();
    }

    protected Document createOriginal() {
      return myRangeMarker.getDocument();
    }

    protected Document createCopy() {
      final Document originalDocument = myRangeMarker.getDocument();
      String textInRange = originalDocument.getCharsSequence().subSequence(myRangeMarker.getStartOffset(), myRangeMarker.getEndOffset()).toString();
      final Document result = EditorFactory.getInstance().createDocument(textInRange);
      result.setReadOnly(!originalDocument.isWritable());
      result.putUserData(ORIGINAL_DOCUMENT, originalDocument);
      return result;
    }

    protected void onCopyChanged(DocumentEvent event, Document original) {
      final int originalOffset = event.getOffset() + myRangeMarker.getStartOffset();
      LOG.assertTrue(originalOffset >= 0);
      if (!original.isWritable()) return;
      final String newText = subText(event.getDocument(), event.getOffset(), event.getNewLength());
      final int originalEnd = originalOffset + event.getOldLength();
      replaceString(original, originalOffset, originalEnd, newText);
    }
  }
}
TOP

Related Classes of com.intellij.openapi.diff.FragmentContent

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.