/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.pullrequest.client.parts.contribute; import org.eclipse.che.plugin.pullrequest.client.ContributeMessages; import org.eclipse.che.plugin.pullrequest.client.ContributeResources; import org.eclipse.che.plugin.pullrequest.client.dialogs.paste.PasteEvent; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.KeyUpEvent; import com.google.gwt.event.dom.client.KeyUpHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.uibinder.client.UiHandler; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HTMLPanel; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.TextArea; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.ValueBoxBase; import com.google.gwt.user.client.ui.Widget; import org.eclipse.che.ide.FontAwesome; import org.eclipse.che.ide.api.parts.PartStackUIResources; import org.eclipse.che.ide.api.parts.base.BaseView; import org.eclipse.che.ide.ui.buttonLoader.ButtonLoaderResources; import org.eclipse.che.ide.ui.listbox.CustomListBox; import org.vectomatic.dom.svg.ui.SVGPushButton; import javax.inject.Inject; import javax.validation.constraints.NotNull; import java.util.ArrayList; import java.util.List; import static com.google.gwt.dom.client.Style.Cursor.POINTER; import static com.google.gwt.dom.client.Style.Unit.PX; /** * Implementation of {@link ContributePartView}. */ public class ContributePartViewImpl extends BaseView<ContributePartView.ActionDelegate> implements ContributePartView { /** The status component. */ private final StatusSteps statusSteps; /** The contribute button. */ @UiField Button contributeButton; /** The resources for the view. */ @UiField(provided = true) ContributeResources resources; /** The component for the URL of factory repository. */ @UiField Anchor repositoryUrl; /** The component for the name of contribute to branch. */ @UiField Label contributeToBranch; /** The component for the name of the project */ @UiField Label projectName; /** The input component for the contribution branch name. */ @UiField CustomListBox contributionBranchName; /** Button used to refresh the contribution branch name list. */ @UiField SVGPushButton refreshContributionBranchNameListButton; /** The input component for the contribution title. */ @UiField TextBox contributionTitle; /** The input zone for the contribution comment. */ @UiField TextArea contributionComment; /** The i18n messages. */ @UiField(provided = true) ContributeMessages messages; /** The contribution status section. */ @UiField FlowPanel statusSection; /** The status section message. */ @UiField Label statusSectionMessage; /** Open on repository host button. */ @UiField Button openPullRequestOnVcsHostButton; /** The start new contribution section. */ @UiField HTMLPanel newContributionSection; /** The new contribution button. */ @UiField Button newContributionButton; /** The contribute button text. */ private String contributeButtonText; @Inject public ContributePartViewImpl(@NotNull final PartStackUIResources partStackUIResources, @NotNull final ContributeMessages messages, @NotNull final ContributeResources resources, @NotNull final ButtonLoaderResources buttonLoaderResources, @NotNull final ContributePartViewUiBinder uiBinder) { super(partStackUIResources); this.messages = messages; this.resources = resources; this.statusSteps = new StatusSteps(); setContentWidget(uiBinder.createAndBindUi(this)); setTitle(messages.contributePartTitle()); this.contributeButtonText = contributeButton.getText(); this.contributeButton.addStyleName(buttonLoaderResources.Css().buttonLoader()); this.refreshContributionBranchNameListButton.getElement().getStyle().setWidth(23, PX); this.refreshContributionBranchNameListButton.getElement().getStyle().setHeight(20, PX); this.refreshContributionBranchNameListButton.getElement().getStyle().setCursor(POINTER); this.refreshContributionBranchNameListButton.getElement().getStyle().setProperty("fill", "#dbdbdb"); this.statusSection.setVisible(false); this.newContributionSection.setVisible(false); this.contributionTitle.getElement().setPropertyString("placeholder", messages.contributePartConfigureContributionSectionContributionTitlePlaceholder()); this.contributionComment.getElement().setPropertyString("placeholder", messages.contributePartConfigureContributionSectionContributionCommentPlaceholder()); this.statusSection.insert(statusSteps, 1); } @Override public void setRepositoryUrl(final String url) { repositoryUrl.setHref(url); repositoryUrl.setText(url); } @Override public void setContributeToBranch(final String branch) { contributeToBranch.setText(branch); } @Override public void setProjectName(String projectName) { this.projectName.setText(projectName); } @Override public void setContributeButtonText(final String text) { contributeButton.setText(text); contributeButtonText = contributeButton.getText(); } @Override public String getContributionBranchName() { final int selectedIndex = contributionBranchName.getSelectedIndex(); return selectedIndex == -1 ? null : contributionBranchName.getValue(selectedIndex); } @Override public void setContributionBranchName(final String branchName) { for (int i = 0; i < contributionBranchName.getItemCount(); i++) { if (contributionBranchName.getValue(i).equals(branchName)) { contributionBranchName.setSelectedIndex(i); return; } } if (contributionBranchName.getItemCount() > 1) { contributionBranchName.setSelectedIndex(1); } } @Override public void setContributionBranchNameList(final List<String> branchNames) { final String selectedBranchName = getContributionBranchName(); contributionBranchName.clear(); contributionBranchName.addItem(messages.contributePartConfigureContributionSectionContributionBranchNameCreateNewItemText()); for (final String oneBranchName : branchNames) { contributionBranchName.addItem(oneBranchName); } setContributionBranchName(selectedBranchName); } @Override public String getContributionComment() { return contributionComment.getValue(); } @Override public void setContributionComment(final String comment) { contributionComment.setText(comment); } @Override public void addContributionCommentChangedHandler(TextChangedHandler handler) { contributionComment.addKeyUpHandler(new TextChangedHandlerAdapter(handler)); } @Override public String getContributionTitle() { return contributionTitle.getValue(); } @Override public void setContributionTitle(final String title) { contributionTitle.setText(title); } @Override public void addContributionTitleChangedHandler(TextChangedHandler handler) { contributionTitle.addKeyUpHandler(new TextChangedHandlerAdapter(handler)); } @Override public void addBranchChangedHandler(final TextChangedHandler changeHandler) { contributionBranchName.addChangeHandler(new ChangeHandler() { @Override public void onChange(ChangeEvent event) { changeHandler.onTextChanged(contributionBranchName.getSelectedItemText()); } }); } @Override public void setContributionBranchNameEnabled(final boolean enabled) { contributionBranchName.setEnabled(enabled); } @Override public void setContributionCommentEnabled(final boolean enabled) { contributionComment.setEnabled(enabled); if (!enabled) { contributionComment.getElement().getStyle().setBackgroundColor("#5a5c5c"); } else { contributionComment.getElement().getStyle().clearBackgroundColor(); } } @Override public void setContributionTitleEnabled(final boolean enabled) { contributionTitle.setEnabled(enabled); } @Override public void setContributeButtonEnabled(final boolean enabled) { contributeButton.setEnabled(enabled); } @Override public void showContributionTitleError(final boolean showError) { if (showError) { contributionTitle.addStyleName(resources.contributeCss().inputError()); } else { contributionTitle.removeStyleName(resources.contributeCss().inputError()); } } @Override public void showStatusSection(final String... statusSteps) { this.statusSteps.removeAll(); for (final String oneStatusStep : statusSteps) { this.statusSteps.addStep(oneStatusStep); } statusSection.setVisible(true); } @Override public void setCurrentStatusStepStatus(boolean success) { statusSteps.setCurrentStepStatus(success); } @Override public String getCurrentStatusStepName() { return statusSteps.getCurrentStepName(); } @Override public void showStatusSectionMessage(final String message, final boolean error) { if (error) { statusSectionMessage.addStyleName(resources.contributeCss().errorMessage()); } else { statusSectionMessage.removeStyleName(resources.contributeCss().errorMessage()); } statusSectionMessage.setText(message); statusSectionMessage.setVisible(true); } @Override public void hideStatusSectionMessage() { statusSectionMessage.setVisible(false); } @Override public void hideStatusSection() { statusSection.setVisible(false); } @Override public void setContributionProgressState(final boolean progress) { if (progress) { contributeButton.setHTML("<i></i>"); } else { contributeButton.setText(contributeButtonText); } } @Override public void showNewContributionSection(final String vcsHostName) { openPullRequestOnVcsHostButton .setText(messages.contributePartNewContributionSectionButtonOpenPullRequestOnVcsHostText(vcsHostName)); newContributionSection.setVisible(true); } @Override public void hideNewContributionSection() { newContributionSection.setVisible(false); } @SuppressWarnings("UnusedParameters") @UiHandler("contributionBranchName") protected void contributionBranchNameChange(final ChangeEvent event) { final int selectedIndex = contributionBranchName.getSelectedIndex(); if (selectedIndex == 0) { delegate.onCreateNewBranch(); } } @SuppressWarnings("UnusedParameters") @UiHandler("refreshContributionBranchNameListButton") protected void refreshContributionBranchNameList(final ClickEvent event) { delegate.onRefreshContributionBranchNameList(); } @SuppressWarnings("UnusedParameters") @UiHandler("contributionComment") protected void contributionCommentChanged(final ValueChangeEvent<String> event) { delegate.updateControls(); } @SuppressWarnings("UnusedParameters") @UiHandler("contributionTitle") protected void contributionTitleChanged(final ValueChangeEvent<String> event) { delegate.updateControls(); } @SuppressWarnings("UnusedParameters") @UiHandler("openPullRequestOnVcsHostButton") protected void openPullRequestOnVcsHostClick(final ClickEvent event) { delegate.onOpenPullRequestOnVcsHost(); } @SuppressWarnings("UnusedParameters") @UiHandler("newContributionButton") protected void newContributionClick(final ClickEvent event) { delegate.onNewContribution(); } @SuppressWarnings("UnusedParameters") @UiHandler("contributeButton") protected void contributeClick(final ClickEvent event) { delegate.onContribute(); } @SuppressWarnings("UnusedParameters") @UiHandler("contributionTitle") protected void contributionTitleKeyUp(final KeyUpEvent event) { delegate.updateControls(); } @SuppressWarnings("UnusedParameters") @UiHandler("contributionTitle") protected void contributionTitlePaste(final PasteEvent event) { delegate.updateControls(); } private class StatusSteps extends FlowPanel { private final List<StatusStep> steps; private int currentStep; private StatusSteps() { this.currentStep = 0; this.steps = new ArrayList<>(); addStyleName(resources.contributeCss().statusSteps()); } public void addStep(final String label) { final StatusStep statusStep = new StatusStep(steps.size() + 1, label); steps.add(statusStep); add(statusStep); } public void removeAll() { clear(); currentStep = 0; steps.clear(); } public void setCurrentStepStatus(final boolean status) { steps.get(currentStep).setStatus(status); currentStep++; } public String getCurrentStepName() { return steps.get(currentStep).getLabel(); } } private class StatusStep extends FlowPanel { private final SimplePanel status; private final String label; private StatusStep(final int index, final String label) { final Label indexLabel = new Label(); final Label titleLabel = new Label(this.label = label); this.status = new SimplePanel(); add(indexLabel); add(titleLabel); add(this.status); // initialize panel style addStyleName(resources.contributeCss().stepLabelRow()); // initialize index style indexLabel.addStyleName(resources.contributeCss().statusIndexStepLabel()); // initialize label style titleLabel.addStyleName(resources.contributeCss().statusTitleStepLabel()); // initialize status style this.status.addStyleName(resources.contributeCss().stepLabel()); } public void setStatus(final boolean success) { status.clear(); status.add(getStatusIcon(success)); } public String getLabel() { return label; } private Widget getStatusIcon(final boolean success) { final Widget icon = new HTML(success ? FontAwesome.CHECK : FontAwesome.EXCLAMATION_TRIANGLE); icon.addStyleName(success ? resources.contributeCss().checkIcon() : resources.contributeCss().errorIcon()); return icon; } } /** Adapts {@link TextChangedHandler} to the {@link KeyUpEvent}. */ private static class TextChangedHandlerAdapter implements KeyUpHandler { private final TextChangedHandler handler; public TextChangedHandlerAdapter(TextChangedHandler handler) { this.handler = handler; } @Override public void onKeyUp(KeyUpEvent event) { if (event.getSource() instanceof ValueBoxBase) { handler.onTextChanged(((ValueBoxBase)event.getSource()).getText()); } } } }