| @@ -6,9 +6,7 @@ | |||
| <children xsi:type="basic:PartSashContainer" xmi:id="_4NsHQEqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partsashcontainer.bggload"> | |||
| <children xsi:type="basic:PartStack" xmi:id="_7KNiwEqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partstack.bggloadconf" containerData="1400"> | |||
| <children xsi:type="basic:Part" xmi:id="_9ocfwEqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.part.resultconfig" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.LoadFromBggPart" label="Prepare"/> | |||
| </children> | |||
| <children xsi:type="basic:PartStack" xmi:id="_7hQw0EqTEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partstack.bggresult" containerData="600"> | |||
| <children xsi:type="basic:Part" xmi:id="_-Mdy0EqTEeqT5sxfmvJ5Tg" elementId="de.wt.bgg.ui.part.gamesconfig" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.LoadThingDetailsPart" label="Load game details"/> | |||
| <children xsi:type="basic:Part" xmi:id="_-Mdy0EqTEeqT5sxfmvJ5Tg" elementId="de.wt.bgg.ui.part.gamesconfig" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.LoadThingDetailsPart" label="Download games"/> | |||
| </children> | |||
| </children> | |||
| <children xsi:type="basic:PartSashContainer" xmi:id="_AF1vQEqUEeqT5sxfmvJ5Tg" elementId="xyz.veronie.bgg.ui.partsashcontainer.gamelist"> | |||
| @@ -20,10 +18,8 @@ | |||
| </children> | |||
| </children> | |||
| <mainMenu xmi:id="_wtXeQEs0EeqGDvPDavxXPQ" elementId="org.eclipse.ui.main.menu"/> | |||
| <trimBars xmi:id="_1nq0UFu3Eeq4377K74W4EQ" elementId="xyz.veronie.bgg.ui.status" side="Bottom"> | |||
| <children xsi:type="menu:ToolBar" xmi:id="_JFF2UFu4Eeq4377K74W4EQ" elementId="xyz.veronie.bgg.ui.toolbar.0"> | |||
| <children xsi:type="menu:ToolControl" xmi:id="_xUKiUFu4Eeq4377K74W4EQ" elementId="xyz.veronie.bgg.ui.toolcontrol.status" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.StatusBar"/> | |||
| </children> | |||
| <trimBars xmi:id="_I6MLEFv-EeqNgfoocONcgg" elementId="xyz.veronie.bgg.ui.trimbar.bottom" side="Bottom"> | |||
| <children xsi:type="menu:ToolControl" xmi:id="_JQ6B8Fv-EeqNgfoocONcgg" elementId="xyz.veronie.bgg.ui.toolcontrol.status" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.parts.StatusBar"/> | |||
| </trimBars> | |||
| </children> | |||
| <addons xmi:id="_Lw_ZsUqSEeqT5sxfmvJ5Tg" elementId="org.eclipse.e4.core.commands.service" contributionURI="bundleclass://org.eclipse.e4.core.commands/org.eclipse.e4.core.commands.CommandServiceAddon"/> | |||
| @@ -3,8 +3,6 @@ Bundle-ManifestVersion: 2 | |||
| Bundle-Name: Secondtry | |||
| Bundle-SymbolicName: xyz.veronie.bgg.ui;singleton:=true | |||
| Bundle-Version: 1.0.0.qualifier | |||
| Automatic-Module-Name: de.wt.secondtry | |||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||
| Require-Bundle: org.eclipse.core.runtime, | |||
| org.eclipse.swt, | |||
| org.eclipse.e4.core.di, | |||
| @@ -16,5 +14,8 @@ Require-Bundle: org.eclipse.core.runtime, | |||
| org.eclipse.e4.core.services, | |||
| org.eclipse.osgi.services, | |||
| javax.inject | |||
| Import-Package: org.eclipse.e4.ui.model.application.descriptor.basic, | |||
| Automatic-Module-Name: de.wt.secondtry | |||
| Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | |||
| Import-Package: javax.inject;version="1.0.0", | |||
| org.eclipse.e4.ui.model.application.descriptor.basic, | |||
| org.eclipse.e4.ui.model.application.ui.basic | |||
| @@ -19,6 +19,7 @@ import javax.xml.parsers.DocumentBuilderFactory; | |||
| import javax.xml.parsers.ParserConfigurationException; | |||
| import org.eclipse.e4.core.di.annotations.Creatable; | |||
| import org.eclipse.e4.core.services.events.IEventBroker; | |||
| import org.w3c.dom.Document; | |||
| import org.w3c.dom.Element; | |||
| import org.w3c.dom.Node; | |||
| @@ -26,6 +27,7 @@ import org.w3c.dom.NodeList; | |||
| import org.xml.sax.InputSource; | |||
| import org.xml.sax.SAXException; | |||
| import xyz.veronie.bgg.types.EventConstants; | |||
| import xyz.veronie.bgg.types.FilterFlagState; | |||
| import xyz.veronie.bgg.types.Subtype; | |||
| import xyz.veronie.bgg.types.UserFlag; | |||
| @@ -34,6 +36,7 @@ import xyz.veronie.bgg.types.UserFlag; | |||
| public class BggApi { | |||
| @Inject private ResultConfigManager configManager; | |||
| @Inject private IEventBroker eventBroker; | |||
| public static String BASE_URL = "https://www.boardgamegeek.com/xmlapi2/"; | |||
| public static String USER = "user"; | |||
| @@ -44,7 +47,7 @@ public class BggApi { | |||
| private static int RETRIES = 5; | |||
| public ArrayList<ThingMetaData> getThingsForUser(String user) { | |||
| public ArrayList<ThingMetaData> getThingsForUser(String user) throws IllegalArgumentException { | |||
| ResultConfig resultConfig = configManager.getResultConfig(); | |||
| StringBuilder urlStr = new StringBuilder(); | |||
| @@ -81,7 +84,7 @@ public class BggApi { | |||
| } | |||
| public ArrayList<ThingMetaData> getThingsForGeeklist(int geeklistId) { | |||
| public ArrayList<ThingMetaData> getThingsForGeeklist(int geeklistId) throws IllegalArgumentException { | |||
| ResultConfig resultConfig = configManager.getResultConfig(); | |||
| StringBuilder urlStr = new StringBuilder(); | |||
| @@ -90,9 +93,17 @@ public class BggApi { | |||
| return getThings(urlStr.toString()); | |||
| } | |||
| public ArrayList<ThingMetaData> getThingsForFamily(int familyId) throws IllegalArgumentException { | |||
| ResultConfig resultConfig = configManager.getResultConfig(); | |||
| StringBuilder urlStr = new StringBuilder(); | |||
| urlStr.append(BASE_URL + FAMILY + "?id=" + String.valueOf(resultConfig.familyId)); | |||
| return getThings(urlStr.toString()); | |||
| } | |||
| private ArrayList<ThingMetaData> getThings(String urlString) { | |||
| private ArrayList<ThingMetaData> getThings(String urlString) throws IllegalArgumentException { | |||
| System.out.println("URL: " + urlString); | |||
| try { | |||
| @@ -105,10 +116,10 @@ public class BggApi { | |||
| int status = con.getResponseCode(); | |||
| if(status == HttpURLConnection.HTTP_ACCEPTED) { | |||
| Thread.sleep(2000); | |||
| System.out.println("Waiting for server to prepare result..."); | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Waiting for server to prepare result..."); | |||
| } | |||
| else if(status != HttpURLConnection.HTTP_OK) { | |||
| System.out.println("Http Response: " + status); | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Http Response: " + status); | |||
| con.disconnect(); | |||
| return null; | |||
| } else { | |||
| @@ -131,13 +142,13 @@ public class BggApi { | |||
| ++retry; | |||
| } while (retry < RETRIES); | |||
| } | |||
| catch (MalformedURLException e) { | |||
| System.out.println("[ERROR] Malformed URL: " + urlString); | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "[ERROR] Malformed URL: " + urlString); | |||
| e.printStackTrace(); | |||
| } catch (IOException e) { | |||
| System.out.println("[ERROR] Could not open connection for URL: " + urlString); | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "[ERROR] Could not open connection for URL: " + urlString); | |||
| e.printStackTrace(); | |||
| } catch (InterruptedException e) { | |||
| // this will not happen, but we have to catch it anyways... | |||
| @@ -149,7 +160,7 @@ public class BggApi { | |||
| private ArrayList<ThingMetaData> parseThingMetas(String content) { | |||
| private ArrayList<ThingMetaData> parseThingMetas(String content) throws IllegalArgumentException { | |||
| ArrayList<ThingMetaData> metas = new ArrayList<ThingMetaData>(); | |||
| DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |||
| @@ -161,6 +172,8 @@ public class BggApi { | |||
| Document doc = builder.parse(is); | |||
| Element root = doc.getDocumentElement(); | |||
| checkForErrors(doc); | |||
| // BGG XMLAPI2 | |||
| if(root.getTagName() == "items") { | |||
| NodeList nList = doc.getElementsByTagName("item"); | |||
| @@ -180,8 +193,21 @@ public class BggApi { | |||
| } | |||
| } | |||
| } | |||
| // for geeklist result (XMLAPI) | |||
| // for geeklist result | |||
| else if(root.getTagName() == "geeklist") { | |||
| StringBuilder gInfo = new StringBuilder(); | |||
| NodeList nListTitle = doc.getElementsByTagName("title"); | |||
| if(nListTitle.getLength() > 0) { | |||
| gInfo.append(nListTitle.item(0).getTextContent() + "\r\n"); | |||
| } | |||
| NodeList nListDesc = doc.getElementsByTagName("description"); | |||
| if(nListDesc.getLength() > 0) { | |||
| gInfo.append(nListDesc.item(0).getTextContent()); | |||
| } | |||
| eventBroker.send(EventConstants.TOPIC_GEEKLIST_INFO, gInfo.toString()); | |||
| NodeList nList = doc.getElementsByTagName("item"); | |||
| for(int i = 0; i < nList.getLength(); i++) { | |||
| Node nNode = nList.item(i); | |||
| @@ -211,6 +237,19 @@ public class BggApi { | |||
| return null; | |||
| } | |||
| private void checkForErrors(Document doc) throws IllegalArgumentException { | |||
| NodeList nList = doc.getElementsByTagName("error"); | |||
| if(nList.getLength() > 0) { | |||
| Element el = (Element)nList.item(0); | |||
| String val = getValue(el, "message"); | |||
| if(val.equals("")) { | |||
| val = el.getAttribute("message"); | |||
| } | |||
| throw new IllegalArgumentException(val); | |||
| } | |||
| } | |||
| private String getValue(Element eElement, String key) { | |||
| Node node = eElement.getElementsByTagName(key).item(0); | |||
| if(node == null) { | |||
| @@ -22,4 +22,6 @@ public interface EventConstants { | |||
| String TOPIC_STATUS = "STATUS"; | |||
| String TOPIC_GEEKLIST_INFO = "INFO/GEEKLIST"; | |||
| } | |||
| @@ -117,6 +117,8 @@ public class BggUserSourceFilter { | |||
| makeFilter(parent, UserFlag.PLAYED); | |||
| parent.pack(); | |||
| parent.getParent().pack(); | |||
| parent.layout(); | |||
| } | |||
| @@ -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; | |||
| @@ -26,7 +29,7 @@ public class GeeklistSourceFilter { | |||
| @Inject private IEventBroker eventBroker; | |||
| @Inject private ResultConfigManager configManager; | |||
| private Label confLabel; | |||
| private StyledText confLabel; | |||
| public void create(Composite parent, int style) { | |||
| GridLayout filterLayout = new GridLayout(2, false); | |||
| @@ -69,21 +72,33 @@ public class GeeklistSourceFilter { | |||
| } | |||
| }); | |||
| confLabel = new Label(parent, SWT.LEFT); | |||
| confLabel = new StyledText(parent, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY); | |||
| confLabel.setText(""); | |||
| GridData gd = new GridData(SWT.FILL, SWT.FILL, false, false); | |||
| 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.pack(); | |||
| parent.getParent().pack(); | |||
| parent.layout(); | |||
| } | |||
| public void setGeeklistId(Integer geeklistId) { | |||
| if(eventBroker != null) { | |||
| eventBroker.post(EventConstants.TOPIC_GEEKLIST_CHANGED, geeklistId); | |||
| confLabel.setText("Geeklist #" + geeklistId); | |||
| //confLabel.setText("Geeklist #" + geeklistId); | |||
| } else { | |||
| System.out.println("setGeeklistId: eventBroker is null."); | |||
| } | |||
| } | |||
| @Inject | |||
| @Optional | |||
| private void subscribeTopicGeeklistInfo | |||
| (@UIEventTopic(EventConstants.TOPIC_GEEKLIST_INFO) | |||
| String geeklistInfo) { | |||
| confLabel.setText(geeklistInfo); | |||
| } | |||
| } | |||
| @@ -157,22 +157,26 @@ public class LoadFromBggPart { | |||
| btDownload.addSelectionListener(new SelectionAdapter() { | |||
| @Override | |||
| public void widgetSelected(SelectionEvent e) { | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching " + 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 = resultConfig.user; | |||
| if(user == null || user.isEmpty()) { | |||
| MessageDialog.openError(main.getShell(), "", "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, ""); | |||
| 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, ""); | |||
| } | |||
| catch(IllegalArgumentException ex) { | |||
| MessageDialog.openError(main.getShell(), "", ex.getMessage()); | |||
| } | |||
| } | |||
| } else if(selection.getFirstElement() == SourceFilter.GEEKLIST) { | |||
| @@ -181,21 +185,31 @@ public class LoadFromBggPart { | |||
| MessageDialog.openError(main.getShell(), "", "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, ""); | |||
| 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, ""); | |||
| } | |||
| catch(IllegalArgumentException ex) { | |||
| MessageDialog.openError(main.getShell(), "", ex.getMessage()); | |||
| } | |||
| } | |||
| } else if(selection.getFirstElement() == SourceFilter.FAMILY) { | |||
| Integer familyId = resultConfig.familyId; | |||
| if(familyId == null) { | |||
| System.out.println("Please enter a family id."); | |||
| MessageDialog.openError(main.getShell(), "", "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, ""); | |||
| 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, ""); | |||
| } | |||
| catch(IllegalArgumentException ex) { | |||
| MessageDialog.openError(main.getShell(), "", ex.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -4,16 +4,26 @@ package xyz.veronie.bgg.ui.parts; | |||
| import javax.annotation.PostConstruct; | |||
| import javax.inject.Inject; | |||
| import org.eclipse.e4.core.di.annotations.Creatable; | |||
| import org.eclipse.e4.core.di.annotations.Optional; | |||
| import org.eclipse.e4.ui.di.UIEventTopic; | |||
| import org.eclipse.jface.resource.ColorDescriptor; | |||
| import org.eclipse.jface.resource.DeviceResourceException; | |||
| import org.eclipse.jface.resource.JFaceResources; | |||
| import org.eclipse.jface.resource.LocalResourceManager; | |||
| import org.eclipse.jface.resource.ResourceManager; | |||
| import org.eclipse.swt.SWT; | |||
| import org.eclipse.swt.graphics.Color; | |||
| import org.eclipse.swt.graphics.Device; | |||
| import org.eclipse.swt.graphics.RGB; | |||
| import org.eclipse.swt.layout.FillLayout; | |||
| 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.types.EventConstants; | |||
| @Creatable | |||
| public class StatusBar { | |||
| private Label statusLabel; | |||
| @@ -22,9 +32,15 @@ public class StatusBar { | |||
| @PostConstruct | |||
| public void createControls(Composite parent) { | |||
| main = new Composite(parent, SWT.FILL); | |||
| main.setLayout(new GridLayout()); | |||
| statusLabel = new Label(main, SWT.FILL); | |||
| statusLabel.setText("ASDF"); | |||
| statusLabel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); | |||
| // create the manager and bind to a widget | |||
| ResourceManager resManager = | |||
| new LocalResourceManager(JFaceResources.getResources(), statusLabel); | |||
| statusLabel.setBackground(resManager.createColor(new RGB(255,255,0))); | |||
| } | |||
| @@ -34,7 +50,8 @@ public class StatusBar { | |||
| (@UIEventTopic(EventConstants.TOPIC_STATUS) | |||
| String text) { | |||
| statusLabel.setText(text); | |||
| main.layout(); | |||
| statusLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT, true); | |||
| statusLabel.getParent().pack(); | |||
| System.out.println("Status: " + text); | |||
| } | |||
| } | |||