| @@ -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); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -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 | |||
| @@ -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<ThingMetaData>(); | |||
| } | |||
| public void setThingMetas(ArrayList<ThingMetaData> metas) { | |||
| public void replaceThingMetas(ArrayList<ThingMetaData> metas) { | |||
| this.thingMetas = metas; | |||
| } | |||
| public void addThingMetas(ArrayList<ThingMetaData> metas) { | |||
| this.thingMetas.addAll(metas); | |||
| } | |||
| public static Predicate<ThingMetaData> thingEqual(ThingMetaData other) | |||
| { | |||
| return p -> p.getId() == other.getId(); | |||
| } | |||
| public void subtractThingMetas(ArrayList<ThingMetaData> metas) { | |||
| for(ThingMetaData tmd : metas) { | |||
| this.thingMetas.removeIf(thingEqual(tmd)); | |||
| } | |||
| } | |||
| public void intersectThingMetas(ArrayList<ThingMetaData> metas) { | |||
| List<ThingMetaData> cpMetas = new ArrayList<ThingMetaData>(this.thingMetas); | |||
| this.thingMetas.clear(); | |||
| for(ThingMetaData tmd : metas) { | |||
| for(ThingMetaData thisTmd : cpMetas) { | |||
| if(tmd.getId() == thisTmd.getId()) { | |||
| this.thingMetas.add(tmd); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| public List<ThingMetaData> getThingMetas() { | |||
| return thingMetas; | |||
| } | |||
| @@ -24,4 +24,6 @@ public interface EventConstants { | |||
| String TOPIC_GEEKLIST_INFO = "INFO/GEEKLIST"; | |||
| String TOPIC_FAMILY_INFO = "INFO/FAMILY"; | |||
| } | |||
| @@ -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); | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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(); | |||
| } | |||
| } | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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); | |||
| @@ -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<ThingMetaData> 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<ThingMetaData> 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<ThingMetaData> 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<ThingMetaData> 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)"); | |||