User collection results are shown in result table. Basic infrastructure for geeklist id and family id (TODO).pull/2/head
@@ -0,0 +1,224 @@ | |||
package xyz.veronie.bgg.result; | |||
import java.io.BufferedReader; | |||
import java.io.IOException; | |||
import java.io.InputStreamReader; | |||
import java.io.StringReader; | |||
import java.io.UnsupportedEncodingException; | |||
import java.net.HttpURLConnection; | |||
import java.net.MalformedURLException; | |||
import java.net.URL; | |||
import java.net.URLEncoder; | |||
import java.util.ArrayList; | |||
import java.util.Iterator; | |||
import java.util.Map.Entry; | |||
import javax.inject.Inject; | |||
import javax.xml.parsers.DocumentBuilder; | |||
import javax.xml.parsers.DocumentBuilderFactory; | |||
import javax.xml.parsers.ParserConfigurationException; | |||
import org.eclipse.e4.core.di.annotations.Creatable; | |||
import org.w3c.dom.Document; | |||
import org.w3c.dom.Element; | |||
import org.w3c.dom.Node; | |||
import org.w3c.dom.NodeList; | |||
import org.xml.sax.InputSource; | |||
import org.xml.sax.SAXException; | |||
import xyz.veronie.bgg.types.FilterFlagState; | |||
import xyz.veronie.bgg.types.Subtype; | |||
import xyz.veronie.bgg.types.UserFlag; | |||
@Creatable | |||
public class BggApi { | |||
@Inject private ResultConfigManager configManager; | |||
public static String BASE_URL = "https://www.boardgamegeek.com/xmlapi2/"; | |||
public static String USER = "user"; | |||
public static String COLLECTION = "collection"; | |||
public static String SEARCH = "search"; | |||
public static String FAMILY = "family"; | |||
public static String GEEKLIST = "geeklist"; | |||
private static int RETRIES = 5; | |||
public ArrayList<ThingMetaData> getThingsForUser(String user) { | |||
ResultConfig resultConfig = configManager.getResultConfig(); | |||
StringBuilder urlStr = new StringBuilder(); | |||
urlStr.append(BASE_URL + COLLECTION | |||
+ "?username=" + resultConfig.user | |||
+ "&subtype=" + resultConfig.subtype.toApiString() + "&"); | |||
if(resultConfig.subtype == Subtype.BOARDGAME) { | |||
urlStr.append("excludesubtype=" + Subtype.BGEXPANSION.toApiString() + "&"); | |||
} | |||
Iterator<Entry<UserFlag, FilterFlagState>> ufIterator | |||
= resultConfig.userFlags.entrySet().iterator(); | |||
try { | |||
while(ufIterator.hasNext()) { | |||
Entry<UserFlag, FilterFlagState> elem = ufIterator.next(); | |||
String apiString = elem.getKey().toApiString(); | |||
FilterFlagState state = elem.getValue(); | |||
if(state == FilterFlagState.IS) { | |||
urlStr.append(URLEncoder.encode(apiString, "UTF-8")); | |||
urlStr.append("=1&"); | |||
} else if (state == FilterFlagState.ISNOT) { | |||
urlStr.append(URLEncoder.encode(apiString, "UTF-8")); | |||
urlStr.append("=0&"); | |||
} | |||
} | |||
} | |||
catch (UnsupportedEncodingException e) { | |||
e.printStackTrace(); | |||
return null; | |||
} | |||
return getThings(urlStr.toString()); | |||
} | |||
public ArrayList<ThingMetaData> getThingsForGeeklist(int geeklistId) { | |||
ResultConfig resultConfig = configManager.getResultConfig(); | |||
StringBuilder urlStr = new StringBuilder(); | |||
urlStr.append(BASE_URL + GEEKLIST + "/" + String.valueOf(resultConfig.geeklistId)); | |||
return getThings(urlStr.toString()); | |||
} | |||
private ArrayList<ThingMetaData> getThings(String urlString) { | |||
System.out.println("URL: " + urlString); | |||
try { | |||
int retry = 0; | |||
do { | |||
// send a GET request and check for ok... | |||
URL url = new URL(urlString); | |||
HttpURLConnection con = (HttpURLConnection) url.openConnection(); | |||
con.setRequestMethod("GET"); | |||
int status = con.getResponseCode(); | |||
if(status == HttpURLConnection.HTTP_ACCEPTED) { | |||
Thread.sleep(2000); | |||
System.out.println("Waiting for server to prepare result..."); | |||
} | |||
else if(status != HttpURLConnection.HTTP_OK) { | |||
System.out.println("Http Response: " + status); | |||
con.disconnect(); | |||
return null; | |||
} else { | |||
// HTTP_OK, go on... | |||
BufferedReader in = new BufferedReader( | |||
new InputStreamReader(con.getInputStream())); | |||
String inputLine; | |||
StringBuffer content = new StringBuffer(); | |||
while ((inputLine = in.readLine()) != null) { | |||
content.append(inputLine); | |||
} | |||
in.close(); | |||
con.disconnect(); | |||
// do something with the content | |||
System.out.println(content.toString()); | |||
ArrayList<ThingMetaData> output = parseThingMetas(content.toString()); | |||
return output; | |||
} | |||
++retry; | |||
} while (retry < RETRIES); | |||
} | |||
catch (MalformedURLException e) { | |||
System.out.println("[ERROR] Malformed URL: " + urlString); | |||
e.printStackTrace(); | |||
} catch (IOException e) { | |||
System.out.println("[ERROR] Could not open connection for URL: " + urlString); | |||
e.printStackTrace(); | |||
} catch (InterruptedException e) { | |||
// this will not happen, but we have to catch it anyways... | |||
e.printStackTrace(); | |||
} | |||
return null; | |||
} | |||
private ArrayList<ThingMetaData> parseThingMetas(String content) { | |||
ArrayList<ThingMetaData> metas = new ArrayList<ThingMetaData>(); | |||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |||
try { | |||
DocumentBuilder builder = factory.newDocumentBuilder(); | |||
InputSource is = new InputSource(new StringReader(content)); | |||
is.setEncoding("UTF-8"); | |||
Document doc = builder.parse(is); | |||
Element root = doc.getDocumentElement(); | |||
// BGG XMLAPI2 | |||
if(root.getTagName() == "items") { | |||
NodeList nList = doc.getElementsByTagName("item"); | |||
for(int i = 0; i < nList.getLength(); i++) { | |||
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); | |||
} | |||
} | |||
} | |||
// for geeklist result (XMLAPI) | |||
else if(root.getTagName() == "geeklist") { | |||
NodeList nList = doc.getElementsByTagName("item"); | |||
for(int i = 0; i < nList.getLength(); i++) { | |||
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); | |||
} | |||
} | |||
} | |||
return metas; | |||
} catch (ParserConfigurationException e) { | |||
e.printStackTrace(); | |||
} catch (SAXException e) { | |||
e.printStackTrace(); | |||
} catch (IOException e) { | |||
e.printStackTrace(); | |||
} | |||
return null; | |||
} | |||
private String getValue(Element eElement, String key) { | |||
Node node = eElement.getElementsByTagName(key).item(0); | |||
if(node == null) { | |||
return ""; | |||
} else { | |||
return node.getTextContent(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,5 @@ | |||
package xyz.veronie.bgg.result; | |||
public class BggFamily { | |||
} |
@@ -15,15 +15,7 @@ public class ResultConfig { | |||
public SourceFilter source = SourceFilter.BGG_USER; | |||
public ResultAction action = ResultAction.ADD; | |||
public HashMap<Subtype,Boolean> subTypes = new HashMap<Subtype,Boolean>() { | |||
private static final long serialVersionUID = -8718858283141976457L; | |||
{ | |||
for (Subtype st : Subtype.values()) { | |||
put(st, false); | |||
} | |||
put(Subtype.BOARDGAME, true); | |||
}}; | |||
public Subtype subtype = Subtype.BOARDGAME; | |||
// bgg user filter settings | |||
public String user = ""; | |||
@@ -11,7 +11,7 @@ import org.eclipse.e4.ui.di.UIEventTopic; | |||
import xyz.veronie.bgg.types.EventConstants; | |||
import xyz.veronie.bgg.types.ResultAction; | |||
import xyz.veronie.bgg.types.SourceFilter; | |||
import xyz.veronie.bgg.types.SubtypeEvent; | |||
import xyz.veronie.bgg.types.Subtype; | |||
import xyz.veronie.bgg.types.UserFlagEvent; | |||
@@ -43,9 +43,9 @@ public class ResultConfigManager { | |||
@Optional | |||
private void subscribeTopicSubtypesChanged | |||
(@UIEventTopic(EventConstants.TOPIC_SUBTYPE_CHANGED) | |||
SubtypeEvent se) { | |||
getResultConfig().subTypes.put(se.subtype, se.checked); | |||
System.out.println("TOPIC_SUBTYPE_CHANGED: " + (se.checked?"[x] ":"[ ] ") + se.subtype); | |||
Subtype subtype) { | |||
getResultConfig().subtype = subtype; | |||
System.out.println("TOPIC_SUBTYPE_CHANGED: " + subtype); | |||
} | |||
@Inject | |||
@@ -75,7 +75,25 @@ public class ResultConfigManager { | |||
getResultConfig().action = action; | |||
System.out.println("TOPIC_ACTION_CHANGED: action = " + action); | |||
} | |||
@Inject | |||
@Optional | |||
private void subscribeTopicResultGeeklistChanged | |||
(@UIEventTopic(EventConstants.TOPIC_GEEKLIST_CHANGED) | |||
Integer id) { | |||
getResultConfig().geeklistId = id; | |||
System.out.println("TOPIC_GEEKLIST_CHANGED: geeklistId = " + id); | |||
} | |||
@Inject | |||
@Optional | |||
private void subscribeTopicResultFamilyChanged | |||
(@UIEventTopic(EventConstants.TOPIC_FAMILY_CHANGED) | |||
Integer id) { | |||
getResultConfig().familyId = id; | |||
System.out.println("TOPIC_FAMILY_CHANGED: geeklistId = " + id); | |||
} | |||
public ResultConfig getResultConfig() { | |||
return resultConfig; | |||
} | |||
@@ -3,25 +3,32 @@ package xyz.veronie.bgg.result; | |||
import java.beans.PropertyChangeListener; | |||
import java.beans.PropertyChangeSupport; | |||
public class ThingMetaData { | |||
private int id; | |||
private Integer rating; | |||
private String name; | |||
private String imgURL; | |||
private String thumbURL; | |||
private String comment; | |||
private Integer otherId; // ??? | |||
private String username; | |||
private Integer numPlays; | |||
private static String[] titles = { "Id", "Name", "Image", "Thumb", "comment", "# plays"}; | |||
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); | |||
public ThingMetaData(int id, Integer rating, String imgURL, String thumbURL, String comment, Integer otherId, String username) { | |||
public ThingMetaData(int id, String name, | |||
String imgURL, String thumURL, | |||
String comment, Integer numPlays) { | |||
this.setId(id); | |||
this.setRating(rating); | |||
this.setName(name); | |||
this.setImgURL(imgURL); | |||
this.setThumbURL(thumbURL); | |||
this.setThumbURL(thumURL); | |||
this.setComment(comment); | |||
this.setOtherId(otherId); | |||
this.setUsername(username); | |||
this.setNumPlays(numPlays); | |||
} | |||
public static String[] getTitles() { | |||
return titles; | |||
} | |||
public void addPropertyChangeListener(String propertyName, | |||
@@ -32,6 +39,42 @@ public class ThingMetaData { | |||
public void removePropertyChangeListener(PropertyChangeListener listener) { | |||
propertyChangeSupport.removePropertyChangeListener(listener); | |||
} | |||
/// get field at idx, order of titles | |||
public String getField(int idx) { | |||
if(idx >= titles.length) { | |||
} | |||
String returnStr; | |||
switch(idx) { | |||
case 0: | |||
returnStr = String.valueOf(this.id); | |||
break; | |||
case 1: | |||
returnStr = this.name; | |||
break; | |||
case 2: | |||
returnStr = this.imgURL; | |||
break; | |||
case 3: | |||
returnStr = this.thumbURL; | |||
break; | |||
case 4: | |||
returnStr = this.comment; | |||
break; | |||
case 5: | |||
returnStr = String.valueOf(this.numPlays); | |||
break; | |||
default: | |||
throw new ArrayIndexOutOfBoundsException( | |||
"idx " + String.valueOf(idx) + " must be in [0," + (titles.length-1) + "]"); | |||
} | |||
return returnStr; | |||
} | |||
public int getId() { | |||
return id; | |||
@@ -42,15 +85,16 @@ public class ThingMetaData { | |||
this.id = id); | |||
} | |||
public Integer getRating() { | |||
return rating; | |||
public String getName() { | |||
return name; | |||
} | |||
public void setRating(Integer rating) { | |||
propertyChangeSupport.firePropertyChange("rating", this.rating, | |||
this.rating = rating); | |||
public void setName(String name) { | |||
propertyChangeSupport.firePropertyChange("name", this.name, | |||
this.name = name); | |||
} | |||
public String getImgURL() { | |||
return imgURL; | |||
} | |||
@@ -63,44 +107,34 @@ public class ThingMetaData { | |||
public String getThumbURL() { | |||
return thumbURL; | |||
} | |||
public void setThumbURL(String thumbURL) { | |||
propertyChangeSupport.firePropertyChange("thumb", this.thumbURL, | |||
this.thumbURL = thumbURL); | |||
} | |||
public String getComment() { | |||
return comment; | |||
public int getNumPlays() { | |||
return numPlays; | |||
} | |||
public void setComment(String comment) { | |||
propertyChangeSupport.firePropertyChange("comment", this.comment, | |||
this.comment = comment); | |||
public void setNumPlays(Integer numPlays) { | |||
this.numPlays = numPlays; | |||
} | |||
public Integer getOtherId() { | |||
return otherId; | |||
} | |||
public void setOtherId(Integer otherId) { | |||
propertyChangeSupport.firePropertyChange("otherId", this.otherId, | |||
this.otherId = otherId); | |||
public String getComment() { | |||
return comment; | |||
} | |||
public String getUsername() { | |||
return username; | |||
public void setComment(String comment) { | |||
propertyChangeSupport.firePropertyChange("comment", this.comment, | |||
this.comment = comment); | |||
} | |||
public void setUsername(String username) { | |||
propertyChangeSupport.firePropertyChange("username", this.username, | |||
this.username = username); | |||
} | |||
@Override | |||
public String toString() { | |||
return String.valueOf(id); | |||
} | |||
} | |||
@@ -10,17 +10,10 @@ public enum ThingProvider { | |||
private ThingProvider() { | |||
thingMetas = new ArrayList<ThingMetaData>(); | |||
// TODO: retrieve data from BGG | |||
// ...and iterate: | |||
thingMetas.add(new ThingMetaData( | |||
286053, | |||
null, | |||
"https://cf.geekdo-images.com/original/img/vKBCxo7d6maBDC_X9nmC5MWzIC8=/0x0/pic4880614.jpg", | |||
"https://cf.geekdo-images.com/thumb/img/gpeB-GrXrknzAqFKEky1JOvcY4w=/fit-in/200x150/pic4880614.jpg", | |||
"", | |||
65212097, | |||
"veronie")); | |||
} | |||
public void setThingMetas(ArrayList<ThingMetaData> metas) { | |||
this.thingMetas = metas; | |||
} | |||
public List<ThingMetaData> getThingMetas() { | |||
@@ -1,6 +0,0 @@ | |||
package xyz.veronie.bgg.types; | |||
/// This class contains and handles the result table for BGG things | |||
public class BggResult { | |||
} |
@@ -2,7 +2,7 @@ package xyz.veronie.bgg.types; | |||
public interface EventConstants { | |||
String TOPIC_CONFIG_CHANGED = "CONFIG_CHANGED/*"; | |||
String TOPIC_CONFIG_CHANGED = "CONFIG_CHANGED"; | |||
String TOPIC_SOURCE_CHANGED = "CONFIG_CHANGED/FILTER"; | |||
@@ -16,4 +16,9 @@ public interface EventConstants { | |||
String TOPIC_GEEKLIST_CHANGED = "CONFIG_CHANGED/GEEKLIST"; | |||
String TOPIC_FAMILY_CHANGED = "CONFIG_CHANGED/FAMILY"; | |||
String TOPIC_RESULT_CHANGED = "RESULT_CHANGED"; | |||
} |
@@ -20,9 +20,10 @@ public enum Subtype { | |||
public String toString() { | |||
return this.name; | |||
} | |||
/// return the string used in BGG XMLAPI2 to identify the thingtype | |||
public String toSubtypeString() { | |||
public String toApiString() { | |||
return this.thingTypeString; | |||
} | |||
} |
@@ -1,6 +0,0 @@ | |||
package xyz.veronie.bgg.types; | |||
public class SubtypeEvent { | |||
public Subtype subtype; | |||
public Boolean checked; | |||
} |
@@ -2,23 +2,42 @@ package xyz.veronie.bgg.types; | |||
public enum UserFlag { | |||
OWN("owned"), | |||
PREVIOUSLY_OWNED("previously owned"), | |||
FOR_TRADE("for trade"), | |||
WANTED("wanted"), | |||
WTP("want to play"), | |||
WTB("want to buy"), | |||
WISHLIST("on wishlist"), | |||
PREORDERED("preordered"); | |||
OWN("owned", "own"), | |||
PREVIOUSLY_OWNED("previously owned", "prevowned"), | |||
TRADE("for trade", "trade"), | |||
WANT("wanted", "want"), | |||
WTP("want to play", "wanttoplay"), | |||
WTB("want to buy", "wanttobuy"), | |||
WISHLIST("on wishlist", "wishlist"), | |||
PREORDERED("pre-ordered", "preordered"), | |||
RATED("rated", "rated"), | |||
PLAYED("played", "played"), | |||
COMMENT("commented", "comment"); | |||
// MINRATING("min rating", "minrating"), | |||
// MAXRATING("max rating", "rating"), | |||
// MIN_BGG_RATING("min BGG rating", "minbggrating"), | |||
// MAX_BGG_RATING("max BGG rating", "bggrating"), | |||
// MIN_PLAYS("min plays", "minplays"), | |||
// MAX_PLAYS("max plays, "maxplays"), | |||
// MODIFIED_SINCE("modified since", "modifiedsince"); | |||
private String flag; | |||
private String apiString; | |||
private UserFlag(String flag) { | |||
private UserFlag(String flag, String apiString) { | |||
this.flag = flag; | |||
this.apiString = apiString; | |||
} | |||
@Override | |||
public String toString() { | |||
return this.flag; | |||
} | |||
public String toApiString() { | |||
return this.apiString; | |||
} | |||
} |
@@ -106,12 +106,17 @@ public class BggUserSourceFilter { | |||
makeFilter(parent, UserFlag.PREVIOUSLY_OWNED); | |||
makeFilter(parent, UserFlag.WTB); | |||
makeFilter(parent, UserFlag.FOR_TRADE); | |||
makeFilter(parent, UserFlag.TRADE); | |||
makeFilter(parent, UserFlag.WISHLIST); | |||
makeFilter(parent, UserFlag.WANTED); | |||
makeFilter(parent, UserFlag.WANT); | |||
makeFilter(parent, UserFlag.PREORDERED); | |||
makeFilter(parent, UserFlag.RATED); | |||
makeFilter(parent, UserFlag.COMMENT); | |||
makeFilter(parent, UserFlag.PLAYED); | |||
parent.layout(); | |||
} | |||
@@ -1,5 +1,10 @@ | |||
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.jface.dialogs.MessageDialog; | |||
import org.eclipse.swt.SWT; | |||
import org.eclipse.swt.events.FocusEvent; | |||
import org.eclipse.swt.events.FocusListener; | |||
@@ -11,11 +16,17 @@ import org.eclipse.swt.widgets.Combo; | |||
import org.eclipse.swt.widgets.Composite; | |||
import org.eclipse.swt.widgets.Label; | |||
import xyz.veronie.bgg.result.ResultConfigManager; | |||
import xyz.veronie.bgg.types.EventConstants; | |||
/// These are the controls to retrieve thing IDs for a given family ID | |||
@Creatable | |||
public class FamilySourceFilter { | |||
private static int familyId; | |||
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); | |||
@@ -27,16 +38,28 @@ public class FamilySourceFilter { | |||
cbFamilyId.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |||
cbFamilyId.addSelectionListener(new SelectionAdapter() { | |||
public void widgetDefaultSelected(SelectionEvent e) { | |||
setFamilyId(Integer.getInteger(cbFamilyId.getText())); | |||
System.out.println("set geeklist id to '" + getFamilyId() + "'"); | |||
try { | |||
setFamilyId(Integer.parseInt(cbFamilyId.getText())); | |||
System.out.println("set family id to '" + configManager.getResultConfig().geeklistId + "'"); | |||
} | |||
catch (NumberFormatException ex) { | |||
MessageDialog.openError(parent.getShell(), "Input error", "FamilyId must be a whole number."); | |||
} | |||
System.out.println("set family id to '" + configManager.getResultConfig().familyId + "'"); | |||
} | |||
}); | |||
cbFamilyId.addFocusListener(new FocusListener() { | |||
@Override | |||
public void focusLost(FocusEvent e) { | |||
setFamilyId(Integer.getInteger(cbFamilyId.getText())); | |||
System.out.println("set geeklist id to '" + getFamilyId() + "'"); | |||
try { | |||
setFamilyId(Integer.parseInt(cbFamilyId.getText())); | |||
System.out.println("set family id to '" + configManager.getResultConfig().geeklistId + "'"); | |||
} | |||
catch (NumberFormatException ex) { | |||
MessageDialog.openError(parent.getShell(), "Input error", "FamilyId must be a whole number."); | |||
} | |||
System.out.println("set family id to '" + configManager.getResultConfig().familyId + "'"); | |||
} | |||
@Override | |||
@@ -47,11 +70,12 @@ public class FamilySourceFilter { | |||
parent.layout(); | |||
} | |||
public static int getFamilyId() { | |||
return familyId; | |||
} | |||
public static void setFamilyId(int familyId) { | |||
FamilySourceFilter.familyId = familyId; | |||
public void setFamilyId(int familyId) { | |||
if(eventBroker != null) { | |||
eventBroker.post(EventConstants.TOPIC_FAMILY_CHANGED, familyId); | |||
} else { | |||
System.out.println("setFamilyId: eventBroker is null."); | |||
} | |||
} | |||
} |
@@ -4,6 +4,7 @@ import javax.inject.Inject; | |||
import org.eclipse.e4.core.di.annotations.Creatable; | |||
import org.eclipse.e4.core.services.events.IEventBroker; | |||
import org.eclipse.jface.dialogs.MessageDialog; | |||
import org.eclipse.swt.SWT; | |||
import org.eclipse.swt.events.FocusEvent; | |||
import org.eclipse.swt.events.FocusListener; | |||
@@ -23,7 +24,7 @@ import xyz.veronie.bgg.types.EventConstants; | |||
public class GeeklistSourceFilter { | |||
@Inject private IEventBroker eventBroker; | |||
@Inject ResultConfigManager configManager; | |||
@Inject private ResultConfigManager configManager; | |||
public void create(Composite parent, int style) { | |||
GridLayout filterLayout = new GridLayout(2, false); | |||
@@ -37,16 +38,27 @@ public class GeeklistSourceFilter { | |||
cbGeeklistId.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |||
cbGeeklistId.addSelectionListener(new SelectionAdapter() { | |||
public void widgetDefaultSelected(SelectionEvent e) { | |||
setGeeklistId(Integer.getInteger(cbGeeklistId.getText())); | |||
System.out.println("set geeklist id to '" + configManager.getResultConfig().geeklistId + "'"); | |||
try { | |||
setGeeklistId(Integer.parseInt(cbGeeklistId.getText())); | |||
System.out.println("set geeklist id to '" + configManager.getResultConfig().geeklistId + "'"); | |||
} | |||
catch (NumberFormatException ex) { | |||
MessageDialog.openError(parent.getShell(), "Input error", "GeeklistId must be a whole number."); | |||
} | |||
} | |||
}); | |||
cbGeeklistId.addFocusListener(new FocusListener() { | |||
@Override | |||
public void focusLost(FocusEvent e) { | |||
setGeeklistId(Integer.getInteger(cbGeeklistId.getText())); | |||
System.out.println("set geeklist id to '" + configManager.getResultConfig().geeklistId + "'"); | |||
try { | |||
setGeeklistId(Integer.parseInt(cbGeeklistId.getText())); | |||
System.out.println("set geeklist id to '" + configManager.getResultConfig().geeklistId + "'"); | |||
} | |||
catch (NumberFormatException ex) { | |||
MessageDialog.openError(parent.getShell(), "Input error", "GeeklistId must be a whole number."); | |||
} | |||
} | |||
@Override | |||
@@ -1,54 +0,0 @@ | |||
package xyz.veronie.bgg.ui.filters; | |||
import java.util.HashMap; | |||
import org.eclipse.e4.core.services.events.IEventBroker; | |||
import org.eclipse.swt.SWT; | |||
import org.eclipse.swt.events.SelectionAdapter; | |||
import org.eclipse.swt.events.SelectionEvent; | |||
import org.eclipse.swt.layout.GridData; | |||
import org.eclipse.swt.layout.GridLayout; | |||
import org.eclipse.swt.widgets.Button; | |||
import org.eclipse.swt.widgets.Composite; | |||
import org.eclipse.swt.widgets.Group; | |||
import xyz.veronie.bgg.result.ResultConfigManager; | |||
import xyz.veronie.bgg.types.EventConstants; | |||
import xyz.veronie.bgg.types.Subtype; | |||
import xyz.veronie.bgg.types.SubtypeEvent; | |||
public class SubtypeGroup { | |||
private HashMap<Subtype, Button> buttons; | |||
public void create(Composite parent, IEventBroker eventBroker, ResultConfigManager configManager) { | |||
Group gSubtype = new Group(parent, SWT.LEFT); | |||
gSubtype.setText("Subtypes"); | |||
gSubtype.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); | |||
gSubtype.setLayout(new GridLayout(1, false)); | |||
buttons = new HashMap<Subtype, Button>(); | |||
for (Subtype st : Subtype.values()) { | |||
Button bb = new Button(gSubtype, SWT.CHECK); | |||
bb.setText(st.toString()); | |||
bb.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false)); | |||
// init | |||
HashMap<Subtype, Boolean> configuredTypes = configManager.getResultConfig().subTypes; | |||
bb.setSelection(configuredTypes.get(st)); | |||
bb.addSelectionListener(new SelectionAdapter() | |||
{ | |||
@Override | |||
public void widgetSelected(SelectionEvent e) | |||
{ | |||
SubtypeEvent stEvent = new SubtypeEvent(); | |||
stEvent.subtype = st; | |||
stEvent.checked = bb.getSelection(); | |||
eventBroker.send(EventConstants.TOPIC_SUBTYPE_CHANGED, stEvent); | |||
} | |||
}); | |||
buttons.put(st, bb); | |||
} | |||
} | |||
} |
@@ -1,7 +1,10 @@ | |||
package xyz.veronie.bgg.ui.parts; | |||
import javax.annotation.PostConstruct; | |||
import javax.inject.Inject; | |||
import org.eclipse.e4.core.di.annotations.Optional; | |||
import org.eclipse.e4.ui.di.UIEventTopic; | |||
import org.eclipse.jface.viewers.ArrayContentProvider; | |||
import org.eclipse.jface.viewers.ColumnLabelProvider; | |||
import org.eclipse.jface.viewers.TableViewer; | |||
@@ -15,10 +18,11 @@ import org.eclipse.swt.widgets.TableColumn; | |||
import xyz.veronie.bgg.result.ThingMetaData; | |||
import xyz.veronie.bgg.result.ThingProvider; | |||
import xyz.veronie.bgg.types.EventConstants; | |||
public class BggResultPart { | |||
private TableViewer viewer; | |||
@PostConstruct | |||
public void createControls(Composite parent) { | |||
Composite main = new Composite(parent, SWT.FILL); | |||
@@ -61,79 +65,19 @@ public class BggResultPart { | |||
// This will create the columns for the table | |||
private void createColumns(final Composite parent, final TableViewer viewer) { | |||
String[] titles = { "Id", "Rating", "Image", "Thumb", "comment", "other Id", "User name" }; | |||
int[] bounds = { 100, 100, 100, 100, 100, 100, 100 }; | |||
// First column id | |||
TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0], 0); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return String.valueOf(t.getId()); | |||
} | |||
}); | |||
// Second column rating | |||
col = createTableViewerColumn(titles[1], bounds[1], 1); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return String.valueOf(t.getRating()); | |||
} | |||
}); | |||
// now img url | |||
col = createTableViewerColumn(titles[2], bounds[2], 2); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return t.getImgURL(); | |||
} | |||
}); | |||
// thumb url | |||
col = createTableViewerColumn(titles[3], bounds[3], 3); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return t.getThumbURL(); | |||
} | |||
}); | |||
String[] titles = ThingMetaData.getTitles(); | |||
int[] bounds = { 100, 100, 100, 100, 100, 100 }; | |||
// comment | |||
col = createTableViewerColumn(titles[4], bounds[4], 4); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return t.getComment(); | |||
} | |||
}); | |||
// other id | |||
col = createTableViewerColumn(titles[5], bounds[5], 5); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return String.valueOf(t.getOtherId()); | |||
} | |||
}); | |||
// username | |||
col = createTableViewerColumn(titles[6], bounds[6], 6); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return String.valueOf(t.getUsername()); | |||
} | |||
}); | |||
for(int i = 0; i < titles.length; ++i) { | |||
TableViewerColumn col = createTableViewerColumn(titles[i], bounds[i], i); | |||
col.setLabelProvider(new ColumnLabelProvider() { | |||
@Override | |||
public String getText(Object element) { | |||
ThingMetaData t = (ThingMetaData) element; | |||
return t.getField((int)col.getColumn().getData()); | |||
} | |||
}); | |||
} | |||
} | |||
private TableViewerColumn createTableViewerColumn(String title, int bound, final int colNumber) { | |||
@@ -144,6 +88,7 @@ public class BggResultPart { | |||
column.setWidth(bound); | |||
column.setResizable(true); | |||
column.setMoveable(true); | |||
column.setData(colNumber); | |||
return viewerColumn; | |||
} | |||
@@ -154,5 +99,16 @@ public class BggResultPart { | |||
public void setFocus() { | |||
viewer.getControl().setFocus(); | |||
} | |||
@Inject | |||
@Optional | |||
private void subscribeTopicResultChanged | |||
(@UIEventTopic(EventConstants.TOPIC_RESULT_CHANGED) | |||
String empty) { | |||
System.out.println("TOPIC_RESULT_CHANGED"); | |||
viewer.setInput(ThingProvider.INSTANCE.getThingMetas()); | |||
viewer.refresh(); | |||
} | |||
} | |||
@@ -1,6 +1,6 @@ | |||
package xyz.veronie.bgg.ui.parts; | |||
import java.util.Arrays; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
import javax.annotation.PostConstruct; | |||
@@ -26,17 +26,21 @@ import org.eclipse.swt.widgets.Display; | |||
import org.eclipse.swt.widgets.Group; | |||
import org.eclipse.swt.widgets.Label; | |||
import xyz.veronie.bgg.result.BggApi; | |||
import xyz.veronie.bgg.result.ResultConfig; | |||
import xyz.veronie.bgg.result.ResultConfigManager; | |||
import xyz.veronie.bgg.result.ThingMetaData; | |||
import xyz.veronie.bgg.result.ThingProvider; | |||
import xyz.veronie.bgg.types.EventConstants; | |||
import xyz.veronie.bgg.types.ResultAction; | |||
import xyz.veronie.bgg.types.SourceFilter; | |||
import xyz.veronie.bgg.types.Subtype; | |||
import xyz.veronie.bgg.ui.filters.AgeSourceFilter; | |||
import xyz.veronie.bgg.ui.filters.BggUserSourceFilter; | |||
import xyz.veronie.bgg.ui.filters.FamilySourceFilter; | |||
import xyz.veronie.bgg.ui.filters.GeeklistSourceFilter; | |||
import xyz.veronie.bgg.ui.filters.RankSourceFilter; | |||
import xyz.veronie.bgg.ui.filters.SearchSourceFilter; | |||
import xyz.veronie.bgg.ui.filters.SubtypeGroup; | |||
import xyz.veronie.bgg.ui.filters.YearSourceFilter; | |||
@@ -53,6 +57,8 @@ public class LoadFromBggPart { | |||
// inject all source filter composites | |||
@Inject private BggUserSourceFilter bggUserSourceFilter; | |||
@Inject private GeeklistSourceFilter geeklistSourceFilter; | |||
@Inject private FamilySourceFilter familySourceFilter; | |||
@Inject private BggApi bggApi; | |||
@PostConstruct | |||
public void createControls(Composite parent) { | |||
@@ -80,9 +86,10 @@ public class LoadFromBggPart { | |||
ComboViewer cbSource = new ComboViewer(dlConfigGroup, SWT.READ_ONLY); | |||
cbSource.setContentProvider(ArrayContentProvider.getInstance()); | |||
List<SourceFilter> sources = Arrays.asList(new SourceFilter[] { | |||
SourceFilter.BGG_USER, SourceFilter.GEEKLIST, SourceFilter.FAMILY, | |||
SourceFilter.RANK, SourceFilter.YEAR, SourceFilter.AGE, SourceFilter.SEARCH }); | |||
List<SourceFilter> sources = new ArrayList<SourceFilter>(); | |||
for(SourceFilter sf : SourceFilter.values()) { | |||
sources.add(sf); | |||
} | |||
cbSource.setInput(sources); | |||
// TODO: implement all the sources | |||
@@ -90,14 +97,27 @@ public class LoadFromBggPart { | |||
// listener is configured further below | |||
// choose the bgg sub-site | |||
// choose the thing sub-type | |||
Label lblSubtype = new Label(dlConfigGroup, SWT.LEFT); | |||
lblSubtype.setText("Subtypes: "); | |||
lblSubtype.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, false, false)); | |||
SubtypeGroup gSubtypes = new SubtypeGroup(); | |||
gSubtypes.create(dlConfigGroup, eventBroker, configManager); | |||
ComboViewer cbSubtypes = new ComboViewer(dlConfigGroup, SWT.READ_ONLY); | |||
cbSubtypes.setContentProvider(ArrayContentProvider.getInstance()); | |||
List<Subtype> subtypes = new ArrayList<Subtype>(); | |||
for (Subtype st : Subtype.values()) { | |||
subtypes.add(st); | |||
} | |||
cbSubtypes.setInput(subtypes); | |||
cbSubtypes.setSelection(new StructuredSelection(configManager.getResultConfig().subtype)); | |||
cbSubtypes.addSelectionChangedListener(new ISelectionChangedListener() { | |||
@Override | |||
public void selectionChanged(SelectionChangedEvent event) { | |||
IStructuredSelection selection = (IStructuredSelection) event.getSelection(); | |||
eventBroker.send(EventConstants.TOPIC_SUBTYPE_CHANGED, selection.getFirstElement()); | |||
} | |||
}); | |||
// choose action on result list | |||
Label lblAct = new Label(dlConfigGroup, SWT.LEFT); | |||
lblAct.setText("Action on result: "); | |||
@@ -105,13 +125,13 @@ public class LoadFromBggPart { | |||
ComboViewer cbAct = new ComboViewer(dlConfigGroup, SWT.READ_ONLY); | |||
cbAct.setContentProvider(ArrayContentProvider.getInstance()); | |||
List<ResultAction> actions = Arrays.asList(new ResultAction[] { | |||
ResultAction.ADD, ResultAction.REP, ResultAction.SUB, | |||
ResultAction.AND, ResultAction.MIS }); | |||
List<ResultAction> actions = new ArrayList<ResultAction>(); | |||
for(ResultAction act : ResultAction.values()) { | |||
actions.add(act); | |||
} | |||
cbAct.setInput(actions); | |||
cbAct.setSelection(new StructuredSelection(configManager.getResultConfig().action)); | |||
cbAct.addSelectionChangedListener(new ISelectionChangedListener() { | |||
@Override | |||
public void selectionChanged(SelectionChangedEvent event) { | |||
IStructuredSelection selection = (IStructuredSelection) event.getSelection(); | |||
@@ -156,21 +176,45 @@ public class LoadFromBggPart { | |||
@Override | |||
public void widgetSelected(SelectionEvent e) { | |||
System.out.println("Downloading " + cbSource.getSelection().toString()); | |||
ResultConfig resultConfig = configManager.getResultConfig(); | |||
IStructuredSelection selection = (IStructuredSelection) cbSource.getSelection(); | |||
if(selection.size() == 0) return; | |||
if(selection.getFirstElement() == SourceFilter.BGG_USER) { | |||
String user = configManager.getResultConfig().user; | |||
String user = resultConfig.user; | |||
if(user == null || user.isEmpty()) { | |||
System.out.println("Please enter a user name."); | |||
return; | |||
} else { | |||
System.out.println("...for user '" + user + "'"); | |||
ArrayList<ThingMetaData> thingMetas = bggApi.getThingsForUser(user); | |||
ThingProvider.INSTANCE.setThingMetas(thingMetas); | |||
eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); | |||
} | |||
System.out.println("...for user '" + user + "'"); | |||
} else if(selection.getFirstElement() == SourceFilter.GEEKLIST) { | |||
System.out.println("...for geeklist id '" + configManager.getResultConfig().geeklistId + "'"); | |||
Integer geeklistId = resultConfig.geeklistId; | |||
if(geeklistId == null) { | |||
System.out.println("Please enter a geeklist id."); | |||
return; | |||
} else { | |||
System.out.println("...for geeklist id '" + geeklistId + "'"); | |||
ArrayList<ThingMetaData> thingMetas = bggApi.getThingsForGeeklist(geeklistId); | |||
ThingProvider.INSTANCE.setThingMetas(thingMetas); | |||
eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); | |||
} | |||
} else if(selection.getFirstElement() == SourceFilter.FAMILY) { | |||
System.out.println("...for family id '" + FamilySourceFilter.getFamilyId() + "'"); | |||
Integer familyId = resultConfig.familyId; | |||
if(familyId == null) { | |||
System.out.println("Please enter a family id."); | |||
return; | |||
} else { | |||
System.out.println("...for family id '" + familyId + "'"); | |||
//ArrayList<ThingMetaData> thingMetas = bggApi.getThingsForFamily(familyId); | |||
//ThingProvider.INSTANCE.setThingMetas(thingMetas); | |||
//eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, ""); | |||
} | |||
} | |||
} | |||
}); | |||
@@ -202,7 +246,7 @@ public class LoadFromBggPart { | |||
break; | |||
case FAMILY: | |||
System.out.println("construct " + elem); | |||
FamilySourceFilter.create(parent, SWT.FILL); | |||
familySourceFilter.create(parent, SWT.FILL); | |||
break; | |||
case RANK: | |||
RankSourceFilter.create(parent, SWT.FILL); | |||