package org.activityinfo.ui.client.page.config.link;
/*
* #%L
* ActivityInfo Server
* %%
* Copyright (C) 2009 - 2013 UNICEF
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.event.*;
import com.extjs.gxt.ui.client.util.Padding;
import com.extjs.gxt.ui.client.util.Size;
import com.extjs.gxt.ui.client.widget.*;
import com.extjs.gxt.ui.client.widget.button.ToggleButton;
import com.extjs.gxt.ui.client.widget.layout.*;
import com.extjs.gxt.ui.client.widget.layout.HBoxLayout.HBoxLayoutAlign;
import com.extjs.gxt.ui.client.widget.layout.VBoxLayout.VBoxLayoutAlign;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import org.activityinfo.i18n.shared.I18N;
import org.activityinfo.legacy.client.Dispatcher;
import org.activityinfo.legacy.client.state.StateProvider;
import org.activityinfo.legacy.shared.command.GetIndicatorLinks;
import org.activityinfo.legacy.shared.command.LinkIndicators;
import org.activityinfo.legacy.shared.command.result.IndicatorLinkResult;
import org.activityinfo.legacy.shared.command.result.VoidResult;
import org.activityinfo.legacy.shared.model.IndicatorDTO;
import org.activityinfo.legacy.shared.model.UserDatabaseDTO;
import org.activityinfo.ui.client.page.NavigationCallback;
import org.activityinfo.ui.client.page.Page;
import org.activityinfo.ui.client.page.PageId;
import org.activityinfo.ui.client.page.PageState;
import org.activityinfo.ui.client.style.legacy.icon.IconImageBundle;
import java.util.Set;
public class IndicatorLinkPage extends ContentPanel implements Page {
public static final PageId PAGE_ID = new PageId("links");
private final Dispatcher dispatcher;
private LinkGraph linkGraph;
private DatabaseGridPanel sourceDatabaseGrid;
private DatabaseGridPanel destDatabaseGrid;
private IndicatorGridPanel sourceIndicatorGrid;
private IndicatorGridPanel destIndicatorGrid;
private ToggleButton linkButton;
@Inject
public IndicatorLinkPage(Dispatcher dispatcher, StateProvider stateMgr) {
this.dispatcher = dispatcher;
HBoxLayout layout = new HBoxLayout();
layout.setHBoxLayoutAlign(HBoxLayoutAlign.STRETCH);
layout.setPadding(new Padding(10, 5, 5, 5));
setLayout(layout);
setHeadingText(I18N.CONSTANTS.linkIndicators());
addSourceContainer();
addGalley();
addDestinationContainer();
sourceDatabaseGrid.addMouseOverListener(new Listener<GridEvent<UserDatabaseDTO>>() {
@Override
public void handleEvent(GridEvent<UserDatabaseDTO> event) {
sourceDatabaseGrid.getGridView().clearHighlight();
destDatabaseGrid.getGridView().highlight(linkGraph.destinationForDatabase(event.getModel()));
}
});
sourceDatabaseGrid.addSelectionChangeListener(new SelectionChangedListener<UserDatabaseDTO>() {
@Override
public void selectionChanged(SelectionChangedEvent<UserDatabaseDTO> se) {
sourceIndicatorGrid.setDatabase(se.getSelectedItem());
onDatabaseLinksChanged();
}
});
sourceIndicatorGrid.addMouseOverListener(new Listener<GridEvent<IndicatorDTO>>() {
@Override
public void handleEvent(GridEvent<IndicatorDTO> event) {
Set<Integer> linkedTo = linkGraph.destForIndicator(event.getModel(),
destDatabaseGrid.getSelectedItem());
sourceDatabaseGrid.getGridView().clearHighlight();
destDatabaseGrid.getGridView().clearHighlight();
destIndicatorGrid.getGridView().highlight(linkedTo);
}
});
sourceIndicatorGrid.addSelectionChangeListener(new SelectionChangedListener<IndicatorDTO>() {
@Override
public void selectionChanged(SelectionChangedEvent<IndicatorDTO> se) {
onIndicatorSelectionChanged();
}
});
destDatabaseGrid.addMouseOverListener(new Listener<GridEvent<UserDatabaseDTO>>() {
@Override
public void handleEvent(GridEvent<UserDatabaseDTO> event) {
destDatabaseGrid.getGridView().clearHighlight();
sourceDatabaseGrid.getGridView().highlight(linkGraph.sourcesForDatabase(event.getModel()));
}
});
destDatabaseGrid.addSelectionChangeListener(new SelectionChangedListener<UserDatabaseDTO>() {
@Override
public void selectionChanged(SelectionChangedEvent<UserDatabaseDTO> se) {
destIndicatorGrid.setDatabase(se.getSelectedItem());
onDatabaseLinksChanged();
}
});
destIndicatorGrid.addMouseOverListener(new Listener<GridEvent<IndicatorDTO>>() {
@Override
public void handleEvent(GridEvent<IndicatorDTO> be) {
sourceDatabaseGrid.getGridView().clearHighlight();
destDatabaseGrid.getGridView().clearHighlight();
sourceIndicatorGrid.getGridView()
.highlight(linkGraph.sourceForIndicator(sourceDatabaseGrid.getSelectedItem(),
be.getModel()));
}
});
destIndicatorGrid.addSelectionChangeListener(new SelectionChangedListener<IndicatorDTO>() {
@Override
public void selectionChanged(SelectionChangedEvent<IndicatorDTO> se) {
onIndicatorSelectionChanged();
}
});
}
private void addSourceContainer() {
LayoutContainer container = createContainer();
new Html("");
sourceDatabaseGrid = new DatabaseGridPanel(dispatcher);
sourceDatabaseGrid.setHeadingText("Source Database");
container.add(sourceDatabaseGrid, vflex(3));
sourceIndicatorGrid = new IndicatorGridPanel();
container.add(sourceIndicatorGrid, vflex(7));
}
private void addGalley() {
linkButton = new ToggleButton("", IconImageBundle.ICONS.link());
linkButton.disable();
linkButton.setWidth(28);
linkButton.addSelectionListener(new SelectionListener<ButtonEvent>() {
@Override
public void componentSelected(ButtonEvent ce) {
onToggleLink();
}
});
LayoutContainer container = new LayoutContainer();
container.setWidth(35);
container.add(linkButton);
container.setLayout(new BoxLayout() {
@Override
protected void onLayout(Container<?> container, El target) {
super.onLayout(container, target);
Size size = target.getStyleSize();
innerCt.setSize(size.width, size.height, true);
Component c = container.getItem(0);
int ch = c.getOffsetHeight();
setPosition(c, 5, ((int) (size.height * 0.65)) - (ch / 2));
}
});
add(container);
}
private void addDestinationContainer() {
LayoutContainer container = createContainer();
destDatabaseGrid = new DatabaseGridPanel(dispatcher);
destDatabaseGrid.setHeadingText("Destination Database");
container.add(destDatabaseGrid, vflex(3));
destIndicatorGrid = new IndicatorGridPanel();
container.add(destIndicatorGrid, vflex(7));
}
private LayoutContainer createContainer() {
HBoxLayoutData containerData = new HBoxLayoutData();
containerData.setFlex(1.0);
VBoxLayout layout = new VBoxLayout();
layout.setVBoxLayoutAlign(VBoxLayoutAlign.STRETCH);
LayoutContainer container = new LayoutContainer(layout);
add(container, containerData);
return container;
}
private VBoxLayoutData vflex(double flex) {
VBoxLayoutData data = new VBoxLayoutData();
data.setFlex(flex);
return data;
}
private void onDatabaseGraphChanged() {
sourceDatabaseGrid.setLinked(linkGraph.sourceDatabases());
destDatabaseGrid.setLinked(linkGraph.destDatabases());
}
private void onDatabaseLinksChanged() {
sourceIndicatorGrid.setLinked(linkGraph.sourceIndicators(sourceDatabaseGrid.getSelectedItem(),
destDatabaseGrid.getSelectedItem()));
destIndicatorGrid.setLinked(linkGraph.destinationIndicators(sourceDatabaseGrid.getSelectedItem(),
destDatabaseGrid.getSelectedItem()));
}
protected void onIndicatorSelectionChanged() {
IndicatorDTO source = sourceIndicatorGrid.getSelectedItem();
IndicatorDTO dest = destIndicatorGrid.getSelectedItem();
if (source == null || dest == null) {
linkButton.disable();
} else {
sourceIndicatorGrid.getRowY(source);
destIndicatorGrid.getRowY(dest);
sourceIndicatorGrid.el().getRight(false);
linkButton.toggle(linkGraph.linked(source, dest));
linkButton.enable();
// linkButton.showAt(x - LinkTip.WIDTH/2, y - LinkTip.HEIGHT/2);
}
}
protected void onToggleLink() {
IndicatorDTO source = sourceIndicatorGrid.getSelectedItem();
IndicatorDTO dest = destIndicatorGrid.getSelectedItem();
final boolean link = !linkGraph.linked(source, dest);
linkButton.toggle(link);
LinkIndicators update = new LinkIndicators();
update.setLink(link);
update.setSourceIndicatorId(source.getId());
update.setDestIndicatorId(dest.getId());
if (link) {
linkGraph.link(sourceDatabaseGrid.getSelectedItem(), source, destDatabaseGrid.getSelectedItem(), dest);
} else {
linkGraph.unlink(source, dest);
}
destDatabaseGrid.setLinked(linkGraph.destDatabases());
sourceDatabaseGrid.setLinked(linkGraph.sourceDatabases());
onDatabaseLinksChanged();
dispatcher.execute(update, new AsyncCallback<VoidResult>() {
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
@Override
public void onSuccess(VoidResult result) {
Info.display(I18N.CONSTANTS.saved(), link ? "Link created" : "Link removed");
}
});
}
@Override
public PageId getPageId() {
return PAGE_ID;
}
@Override
public Object getWidget() {
return this;
}
@Override
public boolean navigate(PageState place) {
dispatcher.execute(new GetIndicatorLinks(), new AsyncCallback<IndicatorLinkResult>() {
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
@Override
public void onSuccess(IndicatorLinkResult result) {
linkGraph = new LinkGraph(result.getLinks());
onDatabaseGraphChanged();
}
});
return true;
}
@Override
public void shutdown() {
// TODO Auto-generated method stub
}
@Override
public void requestToNavigateAway(PageState place, NavigationCallback callback) {
callback.onDecided(true);
}
@Override
public String beforeWindowCloses() {
return null;
}
}