/*******************************************************************************
* 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.ide.command.editor.page.project;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import org.eclipse.che.ide.api.app.AppContext;
import org.eclipse.che.ide.api.command.CommandImpl.ApplicableContext;
import org.eclipse.che.ide.api.resources.Project;
import org.eclipse.che.ide.api.resources.Resource;
import org.eclipse.che.ide.api.resources.ResourceChangedEvent;
import org.eclipse.che.ide.api.resources.ResourceChangedEvent.ResourceChangedHandler;
import org.eclipse.che.ide.api.resources.ResourceDelta;
import org.eclipse.che.ide.command.editor.EditorMessages;
import org.eclipse.che.ide.command.editor.page.AbstractCommandEditorPage;
import org.eclipse.che.ide.command.editor.page.CommandEditorPage;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/** Presenter for {@link CommandEditorPage} which allows to edit command's applicable projects. */
public class ProjectsPage extends AbstractCommandEditorPage implements ProjectsPageView.ActionDelegate,
ResourceChangedHandler {
private final ProjectsPageView view;
private final AppContext appContext;
/** Initial value of the applicable projects list. */
private Set<String> applicableProjectsInitial;
@Inject
public ProjectsPage(ProjectsPageView view,
AppContext appContext,
EditorMessages messages,
EventBus eventBus) {
super(messages.pageProjectsTitle());
this.view = view;
this.appContext = appContext;
eventBus.addHandler(ResourceChangedEvent.getType(), this);
view.setDelegate(this);
}
@Override
public IsWidget getView() {
return view;
}
@Override
protected void initialize() {
final ApplicableContext context = editedCommand.getApplicableContext();
applicableProjectsInitial = new HashSet<>(context.getApplicableProjects());
refreshProjects();
}
/** Refresh 'Projects' section in the view. */
private void refreshProjects() {
final Map<Project, Boolean> projectsStates = new HashMap<>();
for (Project project : appContext.getProjects()) {
ApplicableContext context = editedCommand.getApplicableContext();
boolean applicable = context.getApplicableProjects().contains(project.getPath());
projectsStates.put(project, applicable);
}
view.setProjects(projectsStates);
}
@Override
public boolean isDirty() {
if (editedCommand == null) {
return false;
}
ApplicableContext context = editedCommand.getApplicableContext();
return !(applicableProjectsInitial.equals(context.getApplicableProjects()));
}
@Override
public void onApplicableProjectChanged(Project project, boolean applicable) {
final ApplicableContext context = editedCommand.getApplicableContext();
if (applicable) {
// if command is bound with one project at least
// then remove command from the workspace
if (context.getApplicableProjects().isEmpty()) {
context.setWorkspaceApplicable(false);
}
context.addProject(project.getPath());
} else {
context.removeProject(project.getPath());
// if command isn't bound to any project
// then save it to the workspace
if (context.getApplicableProjects().isEmpty()) {
context.setWorkspaceApplicable(true);
}
}
notifyDirtyStateChanged();
}
@Override
public void onResourceChanged(ResourceChangedEvent event) {
final ResourceDelta delta = event.getDelta();
final Resource resource = delta.getResource();
if (resource.isProject()) {
// defer refreshing the projects section since appContext#getProjects may return old data
Scheduler.get().scheduleDeferred(this::refreshProjects);
}
}
}