/**
* Copyright 2004-2016 Riccardo Solmi. All rights reserved.
* This file is part of the Whole Platform.
*
* The Whole Platform is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Whole Platform 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
*/
package org.whole.lang.changes.ui.editparts;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.whole.lang.changes.model.ChangeSides;
import org.whole.lang.changes.model.Revision;
import org.whole.lang.changes.model.RevisionChange;
import org.whole.lang.changes.model.RevisionTrack;
import org.whole.lang.changes.model.Revisions;
import org.whole.lang.changes.reflect.ChangesEntityDescriptorEnum;
import org.whole.lang.changes.reflect.ChangesFeatureDescriptorEnum;
import org.whole.lang.matchers.Matcher;
import org.whole.lang.model.IEntity;
import org.whole.lang.ui.editparts.AbstractContentPanePart;
import org.whole.lang.ui.editparts.IEntityPart;
import org.whole.lang.ui.editparts.IGraphicalEntityPart;
import org.whole.lang.ui.editparts.ModelObserver;
import org.whole.lang.ui.figures.FigureConstants;
import org.whole.lang.util.EntityUtils;
/**
* @author Riccardo Solmi
*/
public abstract class AbstractComparePart extends AbstractContentPanePart {
public class CompareMapper {
public Map<IEntity, IEntity> map = new HashMap<IEntity, IEntity>();
public void rebuildRevisionMap(Revision revision) {
map = new HashMap<IEntity, IEntity>();
try {
revision.getChanges().forEach(rc -> {
if (EntityUtils.isResolver(rc))
return;
ChangeSides sides = rc.getSides();
map.put(sides.wGet(0), sides.wGet(1));
});
} catch (IllegalArgumentException e) {
}
}
public void rebuildRevisionMap(IEntity content, int index) {
map = new HashMap<IEntity, IEntity>();
if (content.wGetParent().wGetEntityDescriptor().equals(ChangesEntityDescriptorEnum.RevisionTrack)) {
RevisionTrack revisionTrack = (RevisionTrack) content.wGetParent();
Revisions revisions = revisionTrack.getRevisions();
try {
if (revisions.size() > index) {
Revision revision = revisions.get(index);
for (RevisionChange rc : revision.getChanges()) {
if (EntityUtils.isResolver(rc))
continue;
ChangeSides sides = rc.getSides();
if (index == 0) //left mapping
map.put(sides.wGet(1), sides.wGet(0));
else
map.put(sides.wGet(0), sides.wGet(1));
}
// revisions.get(index)
// .getChanges().stream()
// .map(rc -> rc.getSides())
// .filter(cs -> cs.size() == 2)
// .forEach(s -> map.put(s.wGet(0), s.wGet(1)));
}
} catch (IllegalArgumentException e) {
}
}
}
public void paintMapping(Graphics g, int x0, int x1) {
Map<IEntity, IEntityPart> editPartRegistry = getViewer().getEditPartRegistry();
for (Map.Entry<IEntity, IEntity> entry : map.entrySet()) {
IEntity le = entry.getKey();
IEntity re = entry.getValue();
IEntityPart lePart = ModelObserver.getShowingObserver(le, editPartRegistry);
IEntityPart rePart = ModelObserver.getShowingObserver(re, editPartRegistry);
if (lePart != null && rePart != null) {
boolean leHidden = le != lePart.getModelEntity();
boolean reHidden = re != rePart.getModelEntity();
boolean lePlaceholder = //le.wContains(ChangesFeatureDescriptorEnum.content) &&
Matcher.match(ChangesEntityDescriptorEnum.Nothing, le.wGet(ChangesFeatureDescriptorEnum.content));
boolean rePlaceholder = //re.wContains(ChangesFeatureDescriptorEnum.content) &&
Matcher.match(ChangesEntityDescriptorEnum.Nothing, re.wGet(ChangesFeatureDescriptorEnum.content));
IFigure leFigure = ((IGraphicalEntityPart) lePart).getFigure();
IFigure reFigure = ((IGraphicalEntityPart) rePart).getFigure();
Rectangle leBounds = leFigure.getBounds();
Rectangle reBounds = reFigure.getBounds();
int y0Center = leBounds.y + leBounds.height / 2;
int y1Center = reBounds.y + reBounds.height / 2;
g.setBackgroundColor(le.wGetEntityDescriptor().equals(ChangesEntityDescriptorEnum.Insert) ?
FigureConstants.addBackgroundColor : FigureConstants.deleteBackgroundColor);
g.setForegroundColor(FigureConstants.collapseColor);
if (lePlaceholder)
g.drawLine(x0, y0Center, x0 + 4, y0Center);
else {
g.fillRectangle(x0, leBounds.y, 4, leBounds.height);
g.drawPolyline(new int[] {
x0, leBounds.y, x0 + 4, leBounds.y,
x0 + 4, leBounds.bottom()-1, x0, leBounds.bottom()-1
});
}
g.setBackgroundColor(re.wGetEntityDescriptor().equals(ChangesEntityDescriptorEnum.Insert) ?
FigureConstants.addBackgroundColor : FigureConstants.deleteBackgroundColor);
g.setForegroundColor(FigureConstants.collapseColor);
if (rePlaceholder)
g.drawLine(x1, y1Center, x1 - 5, y1Center);
else {
g.fillRectangle(x1 - 5, reBounds.y, 5, reBounds.height);
g.drawPolyline(new int[] {
x1, reBounds.y, x1 - 5, reBounds.y,
x1 - 5, reBounds.bottom()-1, x1, reBounds.bottom()-1
});
}
g.setForegroundColor(FigureConstants.collapseColor);
g.drawLine(x0 + 4, y0Center, x1 - 5, y1Center);
g.pushState();
g.setLineStyle(SWT.LINE_CUSTOM);
g.setLineDash(new int[] {1,3});
if (leBounds.right() < x0) {
if (lePlaceholder)
g.drawLine(leBounds.right(), y0Center, x0, y0Center);
else {
g.drawLine(leBounds.right(), leBounds.y, x0, leBounds.y);
g.drawLine(leBounds.right(), leBounds.bottom()-1, x0, leBounds.bottom()-1);
}
}
if (reBounds.x > x1) {//FIXME < bounds.right()
if (rePlaceholder)
g.drawLine(x1, y1Center, reBounds.x, y1Center);
else {
g.drawLine(x1, reBounds.y, reBounds.x, reBounds.y);
g.drawLine(x1, reBounds.bottom()-1, reBounds.x, reBounds.bottom()-1);
}
}
g.popState();
if (leBounds.x < x0 && leHidden)
g.drawRectangle(leBounds.x-1, leBounds.y, leBounds.width+1, leBounds.height-1);
if (reBounds.x > x1 && reHidden)
g.drawRectangle(reBounds.x-1, reBounds.y, reBounds.width+1, reBounds.height-1);
}
}
}
}
}