diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java index 27e65dd..075144b 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/BggApi.java @@ -181,15 +181,62 @@ public class BggApi { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; - ThingMetaData tmd = new ThingMetaData( - Integer.parseInt(eElement.getAttribute("objectid")), - getValue(eElement, "name"), - getValue(eElement, "image"), - getValue(eElement, "thumbnail"), - getValue(eElement, "comment"), - Integer.parseInt(getValue(eElement, "numplays")) - ); - metas.add(tmd); + + // thing + if( eElement.hasAttribute("objecttype") + && eElement.getAttribute("objecttype").equals("thing")) + { + Integer id = Integer.parseInt(eElement.getAttribute("objectid")); + if(id != 0) { + ThingMetaData tmd = new ThingMetaData( + id, + getValue(eElement, "name"), + getValue(eElement, "image"), + getValue(eElement, "thumbnail"), + getValue(eElement, "comment"), + Integer.parseInt(getValue(eElement, "numplays")) + ); + metas.add(tmd); + } + } + // family has "type" + else if(eElement.hasAttribute("type") + && eElement.getAttribute("type").equals("boardgamefamily")) + { + // get name and description + StringBuilder fInfo = new StringBuilder(); + + NodeList nListName = eElement.getElementsByTagName("name"); + if(nListName.getLength() > 0) { + fInfo.append(nListName.item(0).getTextContent() + "\r\n"); + } + + NodeList nListDesc = doc.getElementsByTagName("description"); + if(nListDesc.getLength() > 0) { + fInfo.append(nListDesc.item(0).getTextContent()); + } + eventBroker.send(EventConstants.TOPIC_FAMILY_INFO, fInfo.toString()); + + NodeList nLinks = eElement.getElementsByTagName("link"); + for(int l = 0; l < nLinks.getLength(); l++) { + Node link = nLinks.item(l); + if (link.getNodeType() == Node.ELEMENT_NODE) { + Element eLink = (Element) link; + Integer id = Integer.parseInt(eLink.getAttribute("id")); + if(id != 0) { + ThingMetaData tmd = new ThingMetaData( + id, + eLink.getAttribute("value"), + "", "", "", null); + metas.add(tmd); + } + } + } + + // because of our input, there shouldn't be more than one family in the result + // but do not iterate over items just to make sure + break; + } } } } @@ -213,11 +260,14 @@ public class BggApi { Node nNode = nList.item(i); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; - ThingMetaData tmd = new ThingMetaData( - Integer.parseInt(eElement.getAttribute("objectid")), - eElement.getAttribute("objectname"), - "", "", "", null); - metas.add(tmd); + Integer id = Integer.parseInt(eElement.getAttribute("objectid")); + if(id != 0) { + ThingMetaData tmd = new ThingMetaData( + Integer.parseInt(eElement.getAttribute("objectid")), + eElement.getAttribute("objectname"), + "", "", "", null); + metas.add(tmd); + } } } } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ResultConfig.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ResultConfig.java index ad144b7..c255d2e 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ResultConfig.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ResultConfig.java @@ -14,7 +14,7 @@ public class ResultConfig { // TODO: integrate different filters (or extend?) public SourceFilter source = SourceFilter.BGG_USER; - public ResultAction action = ResultAction.ADD; + public ResultAction action = ResultAction.REP; public Subtype subtype = Subtype.BOARDGAME; // bgg user filter settings diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java index 8200a25..f88f779 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/result/ThingProvider.java @@ -2,6 +2,7 @@ package xyz.veronie.bgg.result; import java.util.ArrayList; import java.util.List; +import java.util.function.Predicate; public enum ThingProvider { INSTANCE; @@ -12,10 +13,41 @@ public enum ThingProvider { thingMetas = new ArrayList(); } - public void setThingMetas(ArrayList metas) { + public void replaceThingMetas(ArrayList metas) { this.thingMetas = metas; } + public void addThingMetas(ArrayList metas) { + this.thingMetas.addAll(metas); + } + + + + public static Predicate thingEqual(ThingMetaData other) + { + return p -> p.getId() == other.getId(); + } + + public void subtractThingMetas(ArrayList metas) { + for(ThingMetaData tmd : metas) { + this.thingMetas.removeIf(thingEqual(tmd)); + } + } + + + public void intersectThingMetas(ArrayList metas) { + List cpMetas = new ArrayList(this.thingMetas); + this.thingMetas.clear(); + for(ThingMetaData tmd : metas) { + for(ThingMetaData thisTmd : cpMetas) { + if(tmd.getId() == thisTmd.getId()) { + this.thingMetas.add(tmd); + } + } + } + } + + public List getThingMetas() { return thingMetas; } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/types/EventConstants.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/types/EventConstants.java index 57c1ca9..0c47131 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/types/EventConstants.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/types/EventConstants.java @@ -24,4 +24,6 @@ public interface EventConstants { String TOPIC_GEEKLIST_INFO = "INFO/GEEKLIST"; + String TOPIC_FAMILY_INFO = "INFO/FAMILY"; + } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/AgeSourceFilter.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/AgeSourceFilter.java index 0d470d1..39e3176 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/AgeSourceFilter.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/AgeSourceFilter.java @@ -1,14 +1,24 @@ package xyz.veronie.bgg.ui.filters; +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import xyz.veronie.bgg.result.ResultConfigManager; + +@Creatable public class AgeSourceFilter { - public static void create(Composite parent, int style) { + @Inject private IEventBroker eventBroker; + @Inject private ResultConfigManager configManager; + + public void create(Composite parent, int style) { GridLayout filterLayout = new GridLayout(2, false); parent.setLayout(filterLayout); diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/FamilySourceFilter.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/FamilySourceFilter.java index ad19b06..ed64bbf 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/FamilySourceFilter.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/FamilySourceFilter.java @@ -3,9 +3,12 @@ package xyz.veronie.bgg.ui.filters; import javax.inject.Inject; import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.e4.core.di.annotations.Optional; import org.eclipse.e4.core.services.events.IEventBroker; +import org.eclipse.e4.ui.di.UIEventTopic; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.FocusEvent; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.SelectionAdapter; @@ -25,6 +28,7 @@ public class FamilySourceFilter { @Inject private IEventBroker eventBroker; @Inject private ResultConfigManager configManager; + private StyledText confLabel; public void create(Composite parent, int style) { GridLayout filterLayout = new GridLayout(2, false); @@ -36,11 +40,17 @@ public class FamilySourceFilter { Combo cbFamilyId = new Combo(parent, SWT.DROP_DOWN); cbFamilyId.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); + + Integer fid = configManager.getResultConfig().familyId; + if(fid != null) { + cbFamilyId.setText(Integer.toString(fid)); + } + cbFamilyId.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent e) { try { setFamilyId(Integer.parseInt(cbFamilyId.getText())); - System.out.println("set family id to '" + configManager.getResultConfig().geeklistId + "'"); + System.out.println("set family id to '" + configManager.getResultConfig().familyId + "'"); } catch (NumberFormatException ex) { MessageDialog.openError(parent.getShell(), "Input error", "FamilyId must be a whole number."); @@ -67,6 +77,15 @@ public class FamilySourceFilter { // nothing } }); + + confLabel = new StyledText(parent, SWT.MULTI | SWT.READ_ONLY); + confLabel.setText(""); + confLabel.setWordWrap(true); + confLabel.setBounds(10,10,100,100); + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gd.horizontalSpan = 2; + confLabel.setLayoutData(gd); + parent.layout(); } @@ -78,4 +97,13 @@ public class FamilySourceFilter { System.out.println("setFamilyId: eventBroker is null."); } } + + @Inject + @Optional + private void subscribeTopicGeeklistInfo + (@UIEventTopic(EventConstants.TOPIC_FAMILY_INFO) + String familyInfo) { + confLabel.setText(familyInfo); + confLabel.redraw(); + } } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/GeeklistSourceFilter.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/GeeklistSourceFilter.java index 4aa45d1..a4fcbea 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/GeeklistSourceFilter.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/GeeklistSourceFilter.java @@ -40,6 +40,10 @@ public class GeeklistSourceFilter { lblGeeklist.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); Combo cbGeeklistId = new Combo(parent, SWT.DROP_DOWN); + Integer gid = configManager.getResultConfig().geeklistId; + if(gid != null) { + cbGeeklistId.setText(Integer.toString(gid)); + } cbGeeklistId.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); cbGeeklistId.addSelectionListener(new SelectionAdapter() { public void widgetDefaultSelected(SelectionEvent e) { @@ -72,7 +76,7 @@ public class GeeklistSourceFilter { } }); - confLabel = new StyledText(parent, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY); + confLabel = new StyledText(parent, SWT.MULTI | SWT.READ_ONLY); confLabel.setText(""); confLabel.setWordWrap(true); confLabel.setBounds(10,10,100,100); @@ -88,7 +92,6 @@ public class GeeklistSourceFilter { public void setGeeklistId(Integer geeklistId) { if(eventBroker != null) { eventBroker.post(EventConstants.TOPIC_GEEKLIST_CHANGED, geeklistId); - //confLabel.setText("Geeklist #" + geeklistId); } else { System.out.println("setGeeklistId: eventBroker is null."); } @@ -100,5 +103,6 @@ public class GeeklistSourceFilter { (@UIEventTopic(EventConstants.TOPIC_GEEKLIST_INFO) String geeklistInfo) { confLabel.setText(geeklistInfo); + confLabel.redraw(); } } diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/RankSourceFilter.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/RankSourceFilter.java index d0364f5..ce1f384 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/RankSourceFilter.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/RankSourceFilter.java @@ -1,14 +1,24 @@ package xyz.veronie.bgg.ui.filters; +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import xyz.veronie.bgg.result.ResultConfigManager; + +@Creatable public class RankSourceFilter { - public static void create(Composite parent, int style) { + @Inject private IEventBroker eventBroker; + @Inject private ResultConfigManager configManager; + + public void create(Composite parent, int style) { GridLayout filterLayout = new GridLayout(2, false); parent.setLayout(filterLayout); diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/SearchSourceFilter.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/SearchSourceFilter.java index 7cdaaab..c799383 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/SearchSourceFilter.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/SearchSourceFilter.java @@ -1,14 +1,24 @@ package xyz.veronie.bgg.ui.filters; +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import xyz.veronie.bgg.result.ResultConfigManager; + +@Creatable public class SearchSourceFilter { - public static void create(Composite parent, int style) { + @Inject private IEventBroker eventBroker; + @Inject private ResultConfigManager configManager; + + public void create(Composite parent, int style) { GridLayout filterLayout = new GridLayout(2, false); parent.setLayout(filterLayout); diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/YearSourceFilter.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/YearSourceFilter.java index c7ece46..286d4d8 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/YearSourceFilter.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/filters/YearSourceFilter.java @@ -1,14 +1,24 @@ package xyz.veronie.bgg.ui.filters; +import javax.inject.Inject; + +import org.eclipse.e4.core.di.annotations.Creatable; +import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; +import xyz.veronie.bgg.result.ResultConfigManager; + +@Creatable public class YearSourceFilter { - public static void create(Composite parent, int style) { + @Inject private IEventBroker eventBroker; + @Inject private ResultConfigManager configManager; + + public void create(Composite parent, int style) { GridLayout filterLayout = new GridLayout(2, false); parent.setLayout(filterLayout); diff --git a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/LoadFromBggPart.java b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/LoadFromBggPart.java index 6124116..7a450b6 100644 --- a/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/LoadFromBggPart.java +++ b/xyz.veronie.bgg.ui/src/xyz/veronie/bgg/ui/parts/LoadFromBggPart.java @@ -58,6 +58,10 @@ public class LoadFromBggPart { @Inject private BggUserSourceFilter bggUserSourceFilter; @Inject private GeeklistSourceFilter geeklistSourceFilter; @Inject private FamilySourceFilter familySourceFilter; + @Inject private AgeSourceFilter ageSourceFilter; + @Inject private RankSourceFilter rankSourceFilter; + @Inject private YearSourceFilter yearSourceFilter; + @Inject private SearchSourceFilter searchSourceFilter; @Inject private BggApi bggApi; @PostConstruct @@ -171,8 +175,7 @@ public class LoadFromBggPart { eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching " + selection.getFirstElement().toString() + " '" + user + "'..."); try { ArrayList thingMetas = bggApi.getThingsForUser(user); - ThingProvider.INSTANCE.setThingMetas(thingMetas); - eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); + useThingsOnResult(thingMetas); } catch(IllegalArgumentException ex) { MessageDialog.openError(main.getShell(), "", ex.getMessage()); @@ -188,8 +191,7 @@ public class LoadFromBggPart { eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching for geeklist id '" + geeklistId + "'"); try { ArrayList thingMetas = bggApi.getThingsForGeeklist(geeklistId); - ThingProvider.INSTANCE.setThingMetas(thingMetas); - eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); + useThingsOnResult(thingMetas); } catch(IllegalArgumentException ex) { MessageDialog.openError(main.getShell(), "", ex.getMessage()); @@ -204,8 +206,7 @@ public class LoadFromBggPart { eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching for family id '" + familyId + "'"); try { ArrayList thingMetas = bggApi.getThingsForFamily(familyId); - ThingProvider.INSTANCE.setThingMetas(thingMetas); - eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); + useThingsOnResult(thingMetas); } catch(IllegalArgumentException ex) { MessageDialog.openError(main.getShell(), "", ex.getMessage()); @@ -213,6 +214,25 @@ public class LoadFromBggPart { } } } + + private void useThingsOnResult(ArrayList thingMetas) { + switch(configManager.getResultConfig().action) { + case REP: + ThingProvider.INSTANCE.replaceThingMetas(thingMetas); + break; + case ADD: + ThingProvider.INSTANCE.addThingMetas(thingMetas); + break; + case SUB: + ThingProvider.INSTANCE.subtractThingMetas(thingMetas); + break; + case AND: + ThingProvider.INSTANCE.intersectThingMetas(thingMetas); + break; + } + eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); + eventBroker.send(EventConstants.TOPIC_STATUS, "Fetched " + Integer.toString(thingMetas.size()) + " things."); + } }); @@ -284,16 +304,16 @@ public class LoadFromBggPart { familySourceFilter.create(parent, SWT.FILL); break; case RANK: - RankSourceFilter.create(parent, SWT.FILL); + rankSourceFilter.create(parent, SWT.FILL); break; case YEAR: - YearSourceFilter.create(parent, SWT.FILL); + yearSourceFilter.create(parent, SWT.FILL); break; case AGE: - AgeSourceFilter.create(parent, SWT.FILL); + ageSourceFilter.create(parent, SWT.FILL); break; case SEARCH: - SearchSourceFilter.create(parent, SWT.FILL); + searchSourceFilter.create(parent, SWT.FILL); break; default: System.out.println("construct " + elem + " (not implemented yet, try another one)");