Added a File menu with save, load, import.pull/3/head
| @@ -7,7 +7,13 @@ | |||
| <tags>View</tags> | |||
| </children> | |||
| </children> | |||
| <mainMenu xmi:id="_wtXeQEs0EeqGDvPDavxXPQ" elementId="org.eclipse.ui.main.menu"/> | |||
| <mainMenu xmi:id="_FagzMHBjEeuk7d_98DxC5A" elementId="org.eclipse.ui.main.menu"> | |||
| <children xsi:type="menu:Menu" xmi:id="_Lvh0gHBjEeuk7d_98DxC5A" elementId="xyz.veronie.bgg.ui.menu.file" label="File" mnemonics="F"> | |||
| <children xsi:type="menu:HandledMenuItem" xmi:id="_2_HOsHBkEeuk7d_98DxC5A" elementId="xyz.veronie.bgg.ui.handledmenuitem.save" label="Save..." iconURI="platform:/plugin/xyz.veronie.bgg.ui/icons/noun_Save_16x16.png" tooltip="Save the currently displayed thing list to the internal storage" command="_lA5t8F9TEeuvNqpgCDWpdQ"/> | |||
| <children xsi:type="menu:HandledMenuItem" xmi:id="_T6z-cHBkEeuk7d_98DxC5A" elementId="xyz.veronie.bgg.ui.handledmenuitem.loadlist" label="Load..." iconURI="platform:/plugin/xyz.veronie.bgg.ui/icons/noun_open_16x16.png" tooltip="Load a thing list from the internal storage" command="_qyrHAG3zEeuCP7xCflu8WA"/> | |||
| <children xsi:type="menu:HandledMenuItem" xmi:id="_RRC8UHBjEeuk7d_98DxC5A" elementId="xyz.veronie.bgg.ui.handledmenuitem.importresult" label="Import..." iconURI="platform:/plugin/xyz.veronie.bgg.ui/icons/noun_import_16x16.png" tooltip="Import a result.txt file written by bgg1tool int the thing list" mnemonics="" command="_rkauIG7REeutwMlAyj2x8w"/> | |||
| </children> | |||
| </mainMenu> | |||
| <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> | |||
| @@ -15,9 +21,12 @@ | |||
| <children xsi:type="menu:ToolBar" xmi:id="_AX9yMIucEeqEpr8WQZMuMQ" elementId="xyz.veronie.bgg.ui.toolbar.testbar"/> | |||
| </trimBars> | |||
| </children> | |||
| <handlers xmi:id="_a0tuEGAUEeuNUoCJDLJTzQ" elementId="xyz.veronie.bgg.ui.handler.save" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.HandleSaveGamelist" command="_lA5t8F9TEeuvNqpgCDWpdQ"/> | |||
| <handlers xmi:id="_xJXjUG3zEeuCP7xCflu8WA" elementId="xyz.veronie.bgg.ui.handler.load" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.HandleLoadGamelist" command="_qyrHAG3zEeuCP7xCflu8WA"/> | |||
| <handlers xmi:id="_a0tuEGAUEeuNUoCJDLJTzQ" elementId="xyz.veronie.bgg.ui.handler.save" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.SaveGamelistHandler" command="_lA5t8F9TEeuvNqpgCDWpdQ"/> | |||
| <handlers xmi:id="_xJXjUG3zEeuCP7xCflu8WA" elementId="xyz.veronie.bgg.ui.handler.load" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.LoadGamelistHandler" command="_qyrHAG3zEeuCP7xCflu8WA"/> | |||
| <handlers xmi:id="_y97SUG7REeutwMlAyj2x8w" elementId="xyz.veronie.bgg.ui.handler.importResultTxt" contributionURI="bundleclass://xyz.veronie.bgg.ui/xyz.veronie.bgg.ui.handlers.ImportResultTxtHandler" command="_rkauIG7REeutwMlAyj2x8w"/> | |||
| <menuContributions xmi:id="_AitwEHBeEeuk7d_98DxC5A" elementId="xyz.veronie.bgg.ui.menucontribution.gamelists" accessibilityPhrase="Game Lists" positionInParent="0"> | |||
| <children xsi:type="menu:HandledMenuItem" xmi:id="_JvwHYHBeEeuk7d_98DxC5A" elementId="importResult" label="Import..." tooltip="Import thing list from bgg1tool result.txt file" command="_rkauIG7REeutwMlAyj2x8w"/> | |||
| </menuContributions> | |||
| <commands xmi:id="_lA5t8F9TEeuvNqpgCDWpdQ" elementId="xyz.veronie.bgg.ui.command.save" commandName="Save" description="save game list"/> | |||
| <commands xmi:id="_qyrHAG3zEeuCP7xCflu8WA" elementId="xyz.veronie.bgg.ui.command.load" commandName="Load" description="load game list"/> | |||
| <commands xmi:id="_rkauIG7REeutwMlAyj2x8w" elementId="xyz.veronie.bgg.ui.command.importResultTxt" commandName="ImportResultTxt" description="Import result.txt from bgg1tool"/> | |||
| @@ -2,18 +2,6 @@ | |||
| <?eclipse version="3.4"?> | |||
| <plugin> | |||
| <extension | |||
| id="anotherproduct" | |||
| point="org.eclipse.core.runtime.products"> | |||
| <product | |||
| name="BggToolAnother" | |||
| application="org.eclipse.e4.ui.workbench.swt.E4Application"> | |||
| <property | |||
| name="appName" | |||
| value="BggToolAnother"> | |||
| </property> | |||
| </product> | |||
| </extension> | |||
| <extension | |||
| id="bggtoolanother" | |||
| point="org.eclipse.core.runtime.products"> | |||
| @@ -173,7 +173,7 @@ public class SqliteController { | |||
| PreparedStatement thingStatement = connection | |||
| .prepareStatement("INSERT OR REPLACE INTO Thing VALUES (?, ?, ?, ?, ?, ?);"); | |||
| PreparedStatement listToThingStatement = connection | |||
| .prepareStatement("INSERT INTO ThingListToThing VALUES (?, ?);"); | |||
| .prepareStatement("INSERT OR IGNORE INTO ThingListToThing VALUES (?, ?);"); | |||
| for (Thing thing : things) { | |||
| ThingMetaData metaData = thing.getMetaData(); | |||
| @@ -11,8 +11,8 @@ import java.net.URL; | |||
| import java.net.URLEncoder; | |||
| import java.util.ArrayList; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import java.util.Map.Entry; | |||
| import java.util.Set; | |||
| import javax.inject.Inject; | |||
| import javax.xml.parsers.DocumentBuilder; | |||
| @@ -63,7 +63,7 @@ public class BggApi { | |||
| } | |||
| /// retrieve a list of things from BGG with the given ids | |||
| public ArrayList<Thing> getThings(List<Integer> ids) { | |||
| public ArrayList<Thing> getThings(Set<Integer> ids) { | |||
| StringBuilder urlStr = new StringBuilder(); | |||
| urlStr.append(BASE_URL + "thing?id="); | |||
| @@ -99,10 +99,9 @@ public class ThingProvider { | |||
| } | |||
| /// store things as a new list | |||
| public void storeThings(List<Thing> importThings, String listName) throws SQLException { | |||
| public void importList(List<Thing> importThings, String listName) { | |||
| if(importThings != null && !importThings.isEmpty()) { | |||
| this.things = importThings; | |||
| localDbAdapterService.storeThingList(importThings, listName); | |||
| } | |||
| } | |||
| @@ -2,13 +2,6 @@ package xyz.veronie.bgg.ui.dialogs; | |||
| import java.util.List; | |||
| import javax.inject.Inject; | |||
| import org.eclipse.core.commands.ParameterizedCommand; | |||
| import org.eclipse.e4.core.commands.ECommandService; | |||
| import org.eclipse.e4.core.commands.EHandlerService; | |||
| import org.eclipse.e4.core.di.annotations.Optional; | |||
| import org.eclipse.e4.ui.di.UIEventTopic; | |||
| import org.eclipse.jface.dialogs.Dialog; | |||
| import org.eclipse.jface.dialogs.IDialogConstants; | |||
| import org.eclipse.jface.viewers.ArrayContentProvider; | |||
| @@ -24,7 +17,6 @@ import org.eclipse.swt.events.MouseEvent; | |||
| import org.eclipse.swt.graphics.Point; | |||
| 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.Control; | |||
| import org.eclipse.swt.widgets.Label; | |||
| @@ -33,32 +25,23 @@ import org.eclipse.swt.widgets.Table; | |||
| import org.eclipse.swt.widgets.TableColumn; | |||
| import org.eclipse.wb.swt.SWTResourceManager; | |||
| import xyz.veronie.bgg.types.EventConstants; | |||
| import xyz.veronie.bgg.ui.helpers.BatColors; | |||
| @SuppressWarnings("restriction") | |||
| public class LoadGameListDialog extends Dialog { | |||
| private String selectedName; | |||
| private List<String> thingLists; | |||
| private ECommandService commandService; | |||
| private EHandlerService handlerService; | |||
| /** | |||
| * Create the dialog. | |||
| * @param parentShell | |||
| * @param handlerService | |||
| * @param commandService | |||
| */ | |||
| public LoadGameListDialog(Shell parentShell, List<String> thingLists, | |||
| ECommandService commandService, EHandlerService handlerService) | |||
| public LoadGameListDialog(Shell parentShell, List<String> thingLists) | |||
| { | |||
| super(parentShell); | |||
| this.thingLists = thingLists; | |||
| this.commandService = commandService; | |||
| this.handlerService = handlerService; | |||
| setShellStyle(SWT.BORDER | SWT.RESIZE | SWT.APPLICATION_MODAL); | |||
| } | |||
| @@ -137,18 +120,7 @@ public class LoadGameListDialog extends Dialog { | |||
| Composite otherActionsComposite = new Composite(container, SWT.NONE); | |||
| otherActionsComposite.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); | |||
| otherActionsComposite.setLayout(new GridLayout(1, false)); | |||
| Button btnImport = new Button(otherActionsComposite, SWT.NONE); | |||
| btnImport.addMouseListener(new MouseAdapter() { | |||
| @Override | |||
| public void mouseUp(MouseEvent e) { | |||
| importFromBggTool1Result(); | |||
| } | |||
| }); | |||
| btnImport.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); | |||
| btnImport.setBounds(0, 0, 75, 25); | |||
| btnImport.setText("Import from bgg1tool result.txt..."); | |||
| return container; | |||
| } | |||
| @@ -157,15 +129,7 @@ public class LoadGameListDialog extends Dialog { | |||
| this.setReturnCode(OK); | |||
| this.close(); | |||
| } | |||
| private void importFromBggTool1Result() { | |||
| ParameterizedCommand cmd = | |||
| commandService.createCommand("xyz.veronie.bgg.ui.command.importResultTxt", null); | |||
| if (handlerService.canExecute(cmd)){ | |||
| handlerService.executeHandler(cmd); | |||
| } | |||
| closeDialogOk(); | |||
| } | |||
| /** | |||
| * Create contents of the button bar. | |||
| @@ -191,14 +155,4 @@ public class LoadGameListDialog extends Dialog { | |||
| return selectedName; | |||
| } | |||
| // TODO: is not called | |||
| @Inject | |||
| @Optional | |||
| private void subscribeTopicThingsSaved | |||
| (@UIEventTopic(EventConstants.TOPIC_RESULT_CHANGED) | |||
| String listName) { | |||
| System.out.println("LoadGameListDialog: TOPIC_RESULT_CHANGED"); | |||
| closeDialogOk(); | |||
| } | |||
| } | |||
| @@ -5,14 +5,14 @@ import java.io.BufferedReader; | |||
| import java.io.FileNotFoundException; | |||
| import java.io.FileReader; | |||
| import java.io.IOException; | |||
| import java.sql.SQLException; | |||
| import java.util.ArrayList; | |||
| import java.util.HashSet; | |||
| import java.util.List; | |||
| import java.util.Set; | |||
| import org.eclipse.core.runtime.Path; | |||
| import org.eclipse.e4.core.di.annotations.CanExecute; | |||
| import org.eclipse.e4.core.di.annotations.Execute; | |||
| import org.eclipse.e4.core.services.events.IEventBroker; | |||
| import org.eclipse.jface.dialogs.Dialog; | |||
| import org.eclipse.swt.SWT; | |||
| import org.eclipse.swt.widgets.FileDialog; | |||
| import org.eclipse.swt.widgets.MessageBox; | |||
| @@ -22,7 +22,6 @@ import xyz.veronie.bgg.result.BggApi; | |||
| import xyz.veronie.bgg.result.Thing; | |||
| import xyz.veronie.bgg.result.ThingProvider; | |||
| import xyz.veronie.bgg.types.EventConstants; | |||
| import xyz.veronie.bgg.ui.dialogs.SaveGameListDialog; | |||
| public class ImportResultTxtHandler { | |||
| @@ -40,51 +39,43 @@ public class ImportResultTxtHandler { | |||
| String resultPath = dialog.open(); | |||
| if(resultPath != null && !resultPath.isEmpty()) { | |||
| List<Integer> thingIds = parseResultTxtIds(resultPath); | |||
| Set<Integer> thingIds = parseResultTxtIds(resultPath); | |||
| if(thingIds != null && !thingIds.isEmpty()) { | |||
| SaveGameListDialog saveDialog = new SaveGameListDialog(shell); | |||
| saveDialog.open(); | |||
| int returnCode = saveDialog.getReturnCode(); | |||
| if(returnCode == Dialog.OK) { | |||
| String listName = saveDialog.getEntryText(); | |||
| try { | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching entries from BGG..."); | |||
| List<Thing> things = bggApi.getThings(thingIds); | |||
| thingProvider.storeThings(things, listName); | |||
| eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, listName); | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetched " + Integer.toString(things.size()) + " things."); | |||
| } catch (SQLException e) { | |||
| MessageBox msgErrorBox = new MessageBox(shell, SWT.ICON_ERROR | SWT.OK); | |||
| msgErrorBox.setMessage("Could not save imported result.txt as game list."); | |||
| msgErrorBox.open(); | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| String listName = new Path(resultPath).lastSegment() + " (unsaved)"; | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetching entries from BGG..."); | |||
| List<Thing> things = bggApi.getThings(thingIds); | |||
| thingProvider.importList(things, listName); | |||
| eventBroker.send(EventConstants.TOPIC_RESULT_CHANGED, listName); | |||
| eventBroker.send(EventConstants.TOPIC_STATUS, "Fetched " + Integer.toString(things.size()) + " things."); | |||
| } | |||
| } | |||
| } | |||
| private List<Integer> parseResultTxtIds(String resultPath) { | |||
| private Set<Integer> parseResultTxtIds(String resultPath) { | |||
| FileReader input = null; | |||
| String myLine = null; | |||
| int lineNo = 0; | |||
| int errNo = 0; | |||
| int lineNo = 0; // count overall lines | |||
| int errNo = 0; // count unparsable lines | |||
| int dupNo = 0; // count duplicates | |||
| try { | |||
| input = new FileReader(resultPath); | |||
| BufferedReader bufferedReader = new BufferedReader(input); | |||
| List<Integer> ids = new ArrayList<Integer>(); | |||
| Set<Integer> ids = new HashSet<Integer>(); | |||
| while ( (myLine = bufferedReader.readLine()) != null) | |||
| { | |||
| lineNo++; | |||
| String[] tokens = myLine.split(","); | |||
| if(tokens.length > 1) { | |||
| if(tokens.length > 0) { | |||
| if(tokens[0].equals("id")) continue; // header line | |||
| try { | |||
| ids.add(Integer.parseInt(tokens[0])); | |||
| lineNo++; | |||
| boolean exists = !ids.add(Integer.parseInt(tokens[0])); | |||
| if(exists) { | |||
| System.out.println("DEBUG: duplicate id: " + tokens[0]); | |||
| dupNo++; | |||
| } | |||
| } | |||
| catch (NumberFormatException e) { | |||
| errNo++; | |||
| @@ -99,13 +90,15 @@ public class ImportResultTxtHandler { | |||
| if(ids != null) { | |||
| MessageBox msgBox = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK); | |||
| StringBuilder msg = new StringBuilder(); | |||
| msg.append("Parsing successful. Found ").append(Integer.toString(lineNo)).append(" things."); | |||
| int thingsNo = lineNo - errNo - dupNo - 1; | |||
| msg.append("Parsing successful. Found ").append(Integer.toString(thingsNo)).append(" things."); | |||
| if(errNo > 0) { | |||
| msg.append("Skipped ").append(Integer.toString(errNo)).append(" line(s).\n\r"); | |||
| } else { | |||
| msg.append("\n\r"); | |||
| msg.append("\n\rSkipped ").append(Integer.toString(errNo)).append(" line(s)."); | |||
| } | |||
| if(dupNo > 0) { | |||
| msg.append("\n\r").append(Integer.toString(dupNo)).append(" duplicate ids"); | |||
| } | |||
| msg.append("Next, you will be asked to save the imported list as a new game list."); | |||
| msg.append("\n\r"); | |||
| msgBox.setMessage(msg.toString()); | |||
| msgBox.open(); | |||
| } | |||
| @@ -21,7 +21,7 @@ import xyz.veronie.bgg.types.EventConstants; | |||
| import xyz.veronie.bgg.ui.dialogs.LoadGameListDialog; | |||
| @SuppressWarnings("restriction") | |||
| public class HandleLoadGamelist { | |||
| public class LoadGamelistHandler { | |||
| @Inject | |||
| ThingProvider thingProvider; | |||
| @@ -39,7 +39,7 @@ public class HandleLoadGamelist { | |||
| return; | |||
| } | |||
| LoadGameListDialog loadDialog = new LoadGameListDialog(shell, thingLists, commandService, handlerService); | |||
| LoadGameListDialog loadDialog = new LoadGameListDialog(shell, thingLists); | |||
| loadDialog.open(); | |||
| int returnCode = loadDialog.getReturnCode(); | |||
| @@ -15,19 +15,18 @@ import xyz.veronie.bgg.result.ThingProvider; | |||
| import xyz.veronie.bgg.types.EventConstants; | |||
| import xyz.veronie.bgg.ui.dialogs.SaveGameListDialog; | |||
| public class HandleSaveGamelist { | |||
| public class SaveGamelistHandler { | |||
| @Inject | |||
| ThingProvider thingProvider; | |||
| public HandleSaveGamelist() { | |||
| public SaveGamelistHandler() { | |||
| } | |||
| @Execute | |||
| public void execute(Shell shell, IEventBroker eventBroker) { | |||
| // TODO: disable save if list is empty | |||
| if(thingProvider.numberOfThings() == 0) { | |||
| MessageBox msgBox = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK); | |||
| msgBox.setMessage("To save an empty game list would be like drawing from an empty deck."); | |||
| @@ -35,6 +34,7 @@ public class HandleSaveGamelist { | |||
| return; | |||
| } | |||
| // TODO: handle existing name | |||
| SaveGameListDialog saveDialog = new SaveGameListDialog(shell); | |||
| saveDialog.open(); | |||
| @@ -55,6 +55,7 @@ import xyz.veronie.bgg.ui.helpers.BatLayouts; | |||
| // TODO: Display selection details on game | |||
| // TODO: cache family/geeklist descriptions | |||
| // TODO: allow different screen scalings | |||
| // TODO: handle existing name | |||
| @SuppressWarnings("restriction") | |||
| public class BatMain { | |||