// Copyright 2012 Google Inc. All Rights Reserved.
//
// 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.google.collide.client.diff;
import com.google.collide.client.editor.renderer.PreviousAnchorRenderer;
import com.google.collide.dto.DiffChunkResponse;
import com.google.collide.json.shared.JsonStringMap;
import com.google.collide.shared.document.Document;
import com.google.collide.shared.document.Line;
import com.google.collide.shared.document.anchor.Anchor;
import com.google.collide.shared.document.anchor.AnchorManager;
import com.google.collide.shared.document.anchor.AnchorType;
import com.google.collide.shared.util.JsonCollections;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
/**
* A @{link {@link PreviousAnchorRenderer} for diff chunks
*/
public class DiffRenderer extends PreviousAnchorRenderer {
private static final AnchorType DIFF_CHUNK_ANCHOR_TYPE =
AnchorType.create(DiffRenderer.class, "chunk");
private final String diffBlockStyle;
private final JsonStringMap<String> chunkStyles;
private boolean isBeforeFile;
public DiffRenderer(Document document, Resources resources, boolean isBeforeFile) {
super(document, DIFF_CHUNK_ANCHOR_TYPE, PreviousAnchorRenderer.ANCHOR_VALUE_IS_STYLE);
chunkStyles = JsonCollections.createMap();
Css css = resources.diffRendererCss();
chunkStyles.put(DiffChunkResponse.DiffType.ADDED_LINE.toString(), css.addedLine());
chunkStyles.put(DiffChunkResponse.DiffType.REMOVED_LINE.toString(), css.removedLine());
chunkStyles.put(DiffChunkResponse.DiffType.CHANGED_LINE.toString(), css.changedLine());
chunkStyles.put(DiffChunkResponse.DiffType.ADDED.toString(), css.added());
chunkStyles.put(DiffChunkResponse.DiffType.CHANGED.toString(), css.changed());
chunkStyles.put(DiffChunkResponse.DiffType.REMOVED.toString(), css.removed());
chunkStyles.put(DiffChunkResponse.DiffType.UNCHANGED.toString(), css.unchanged());
diffBlockStyle = css.diffBlock();
this.isBeforeFile = isBeforeFile;
}
public interface Css extends CssResource {
String addedLine();
String removedLine();
String changedLine();
String added();
String changed();
String removed();
String unchanged();
String diffBlock();
}
public interface Resources extends ClientBundle {
@Source("DiffRenderer.css")
Css diffRendererCss();
}
/**
* Append a diff chunk to the document.
*
* @param chunkType the type of the diff chunk
* @param chunkText the contents of the diff chunk
*/
void addDiffChunk(DiffChunkResponse.DiffType chunkType, String chunkText) {
if (!chunkText.isEmpty()) {
Line lastLine = document.getLastLine();
int lastColumn = lastLine.getText().length();
document.insertText(lastLine, document.getLastLineNumber(), lastColumn, chunkText);
Anchor anchor = document.getAnchorManager().createAnchor(
DIFF_CHUNK_ANCHOR_TYPE, lastLine, AnchorManager.IGNORE_LINE_NUMBER, lastColumn);
anchor.setValue(chunkStyles.get(chunkType.toString()));
// TODO Below is temp fix to ensure
// "Left should never have Green. Right should never have Red"
if (isBeforeFile) {
if (chunkType == DiffChunkResponse.DiffType.ADDED_LINE
|| chunkType == DiffChunkResponse.DiffType.ADDED) {
anchor.setValue(diffBlockStyle);
} else if (chunkType == DiffChunkResponse.DiffType.CHANGED) {
anchor.setValue(chunkStyles.get(DiffChunkResponse.DiffType.REMOVED.toString()));
} else if (chunkType == DiffChunkResponse.DiffType.CHANGED_LINE) {
anchor.setValue(chunkStyles.get(DiffChunkResponse.DiffType.REMOVED_LINE.toString()));
}
} else {
if (chunkType == DiffChunkResponse.DiffType.REMOVED
|| chunkType == DiffChunkResponse.DiffType.REMOVED_LINE) {
anchor.setValue(diffBlockStyle);
} else if (chunkType == DiffChunkResponse.DiffType.CHANGED) {
anchor.setValue(chunkStyles.get(DiffChunkResponse.DiffType.ADDED.toString()));
} else if (chunkType == DiffChunkResponse.DiffType.CHANGED_LINE) {
anchor.setValue(chunkStyles.get(DiffChunkResponse.DiffType.ADDED_LINE.toString()));
}
}
}
}
}