// 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.filehistory; import com.google.collide.client.AppContext; import com.google.collide.client.code.FileSelectedPlace; import com.google.collide.client.code.EditableContentArea.Content; import com.google.collide.client.history.Place; import com.google.collide.client.util.Elements; import com.google.collide.client.util.PathUtil; import com.google.collide.client.workspace.WorkspacePlace; import com.google.collide.mvp.CompositeView; import com.google.collide.mvp.UiComponent; import com.google.common.annotations.VisibleForTesting; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; import com.google.gwt.resources.client.CssResource; import com.google.gwt.resources.client.ImageResource; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiTemplate; import elemental.events.Event; import elemental.events.EventListener; import elemental.html.Element; /** * The File History diff and bar view, which uses a Javascript timeline widget * to compare past revisions. Also allows for reverting back to previous * revisions. * */ public class FileHistory extends UiComponent<FileHistory.View> implements Content { /** * Static factory method for obtaining an instance of FileHistory. */ public static FileHistory create( Place currentPlace, AppContext appContext, FileHistory.View view) { return new FileHistory(view, currentPlace, appContext); } public interface Css extends CssResource { String base(); String diff(); String timelineBar(); String timelineWrapper(); String timelineTitle(); String filters(); String filter(); String currentFilter(); String closeButton(); String closeIcon(); String button(); String disabledButton(); String title(); String rightRevisionTitle(); String leftRevisionTitle(); String titleBar(); } public interface Resources extends Timeline.Resources { @Source("close.png") ImageResource closeIcon(); @Source("FileHistory.css") Css fileHistoryCss(); } public static class View extends CompositeView<ViewEvents> { @UiTemplate("FileHistory.ui.xml") interface MyBinder extends UiBinder<com.google.gwt.dom.client.DivElement, View> { } static MyBinder binder = GWT.create(MyBinder.class); @UiField DivElement diff; @UiField DivElement timelineBar; @UiField DivElement timelineWrapper; @UiField DivElement timelineTitle; Element leftRevisionTitle; Element rightRevisionTitle; Element titleBar; Element closeButton; Element closeIcon; Timeline.View timelineView; @UiField(provided = true) final Resources res; @UiField(provided = true) final Css css; View(Resources res) { this.res = res; this.css = res.fileHistoryCss(); this.timelineView = new Timeline.View(res); setElement(Elements.asJsElement(binder.createAndBindUi(this))); Elements.asJsElement(timelineWrapper).appendChild(timelineView.getElement()); createDom(); attachEventHandlers(); } protected void attachEventHandlers() { closeButton.setOnClick(new EventListener() { @Override public void handleEvent(Event evt) { ViewEvents delegate = getDelegate(); if (delegate == null) { return; } delegate.onCloseButtonClicked(); } }); } /** * Initialize diff revision titles on the toolbar (default to base version * and current version. */ private void createDom() { closeButton = Elements.createDivElement(css.closeButton()); closeIcon = Elements.createDivElement(css.closeIcon()); closeButton.appendChild(closeIcon); titleBar = Elements.createDivElement(css.titleBar()); leftRevisionTitle = Elements.createDivElement(css.leftRevisionTitle()); rightRevisionTitle = Elements.createDivElement(css.rightRevisionTitle()); leftRevisionTitle.addClassName(css.title()); rightRevisionTitle.addClassName(css.title()); titleBar.appendChild(leftRevisionTitle); titleBar.appendChild(rightRevisionTitle); } } /** * Events reported by the FileHistory's View. */ private interface ViewEvents { void onCloseButtonClicked(); } /** * The delegate implementation for handling events reported by the View. */ private class ViewEventsImpl implements ViewEvents { @Override public void onCloseButtonClicked() { // Clear editor content api.clearDiffEditors(); // unfortunately this must be hard coded since we can be either a child of // the file selected place or the workspace place. WorkspacePlace.PLACE.fireChildPlaceNavigation( FileSelectedPlace.PLACE.createNavigationEvent(path)); } } private final AppContext appContext; private final Place currentPlace; private PathUtil path; private FileHistoryApi api; @VisibleForTesting protected FileHistory(View view, Place currentPlace, AppContext appContext) { super(view); this.currentPlace = currentPlace; this.appContext = appContext; this.path = PathUtil.WORKSPACE_ROOT; view.setDelegate(new ViewEventsImpl()); } public void setPath(PathUtil path) { this.path = path; } public void setApi(FileHistoryApi api) { this.api = api; } @Override public Element getContentElement() { return getView().getElement(); } @Override public void onContentDisplayed() { } /* Setup/teardown for the FileHistory place */ public void setup(Element contentHeader) { contentHeader.appendChild(getView().closeButton); contentHeader.appendChild(getView().titleBar); changeLeftRevisionTitle("Workspace Branched"); changeRightRevisionTitle("Current Version"); } public void teardown() { getView().closeButton.removeFromParent(); getView().titleBar.removeFromParent(); } /* Change revision titles */ public void changeLeftRevisionTitle(String title) { getView().leftRevisionTitle.setTextContent(title); } public void changeRightRevisionTitle(String title) { getView().rightRevisionTitle.setTextContent(title); } }