package xyz.veronie.bgg.ui.parts; import java.util.List; import javax.annotation.PostConstruct; 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.core.services.events.IEventBroker; import org.eclipse.e4.ui.di.UIEventTopic; import org.eclipse.e4.ui.model.application.MApplication; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.workbench.modeling.EModelService; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TableViewerColumn; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.graphics.Image; 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.Label; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.wb.swt.ResourceManager; import org.eclipse.wb.swt.SWTResourceManager; import xyz.veronie.bgg.result.Thing; import xyz.veronie.bgg.result.ThingProvider; import xyz.veronie.bgg.types.EventConstants; import xyz.veronie.bgg.ui.helpers.BatColors; import xyz.veronie.bgg.ui.helpers.BatLayouts; // TODO: import result.txt from bggtool // TODO: image sizes in result table // TODO: fix encoding // TODO: fetch details from BGG // TODO: export to results.txt format // TODO: generate PDF with nandeck // TODO: handle thing list overwrite // 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 { private static final String UNNAMED_LIST = "(unsaved list)"; private Table tableGameList; private TableViewer tableViewer; @Inject private ThingProvider thingProvider; @Inject private IEventBroker eventBroker; private Label lblResultStatus; private Button btnSave; private Button btnUndo; private Button btnExport; private Label lblListName; @Inject public BatMain() {} @PostConstruct public void postConstruct(Composite parent, MApplication application, EPartService partService, EModelService modelService, ECommandService commandService, EHandlerService handlerService) { parent.setBackground(BatColors.getBackgroundColor()); parent.setBackgroundMode(SWT.INHERIT_FORCE); parent.setLayout(new GridLayout(1, false)); Composite main = new Composite(parent, SWT.NONE); GridData gd_main = new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1); gd_main.minimumHeight = 192; gd_main.minimumWidth = 348; main.setLayoutData(gd_main); GridLayout gl_main = new GridLayout(1, false); BatLayouts.applyStandardSpacing(gl_main); main.setLayout(gl_main); Composite buttonRow = new Composite(main, SWT.NONE); GridLayout gl_buttonRow = new GridLayout(5, false); BatLayouts.applyStandardSpacing(gl_buttonRow); buttonRow.setLayout(gl_buttonRow); buttonRow.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false, 1, 1)); Button btnFetch = new Button(buttonRow, SWT.NONE); btnFetch.addMouseListener(new MouseAdapter() { @Override public void mouseUp(MouseEvent e) { List parts = modelService.findElements(application, "xyz.veronie.bgg.ui.part.fetch", MPart.class); if(parts != null && parts.size() >= 1) { MPart fetchPart = parts.get(0); // partService.showPart(fetchPart, PartState.CREATE); fetchPart.setVisible(true); partService.showPart(fetchPart, PartState.ACTIVATE); // modelService.detach(fetchPart, x, y, width, height); } } }); btnFetch.setToolTipText("Fetch games from BGG"); btnFetch.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Download_60x60.png")); btnSave = new Button(buttonRow, SWT.NONE); btnSave.addMouseListener(new MouseAdapter() { @Override public void mouseUp(MouseEvent e) { ParameterizedCommand cmd = commandService.createCommand("xyz.veronie.bgg.ui.command.save", null); if (handlerService.canExecute(cmd)){ handlerService.executeHandler(cmd); } } }); btnSave.setToolTipText("Save list of games"); btnSave.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Save_60x60.png")); btnSave.setEnabled(false); Button btnLoad = new Button(buttonRow, SWT.NONE); btnLoad.addMouseListener(new MouseAdapter() { @Override public void mouseUp(MouseEvent e) { ParameterizedCommand cmd = commandService.createCommand("xyz.veronie.bgg.ui.command.load", null); if (handlerService.canExecute(cmd)){ handlerService.executeHandler(cmd); } } }); btnLoad.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_open_60x60.png")); btnLoad.setToolTipText("Load list of games"); btnUndo = new Button(buttonRow, SWT.NONE); btnUndo.setToolTipText("Undo game list operation"); btnUndo.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/noun_Undo_60x60.png")); btnUndo.setEnabled(false); btnExport = new Button(buttonRow, SWT.NONE); btnExport.setImage(ResourceManager.getPluginImage("xyz.veronie.bgg.ui", "icons/export_nandeck_60x60.png")); btnExport.setToolTipText("Export for nanDeck"); btnExport.setEnabled(false); Composite centerComposite = new Composite(main, SWT.NONE); GridLayout gl_centerComposite = new GridLayout(1, false); BatLayouts.applyStandardSpacing(gl_centerComposite); centerComposite.setLayout(gl_centerComposite); centerComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); lblListName = new Label(centerComposite, SWT.NONE); lblListName.setText(UNNAMED_LIST); lblListName.setFont(SWTResourceManager.getFont("Segoe UI", 11, SWT.NORMAL)); lblListName.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1)); Composite tableComposite = new Composite(centerComposite, SWT.NONE); tableComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE)); GridLayout gl_tableComposite = new GridLayout(1, false); BatLayouts.applyZeroSpacing(gl_tableComposite); tableComposite.setLayout(gl_tableComposite); tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1)); tableViewer = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI); tableGameList = tableViewer.getTable(); tableGameList.setLinesVisible(true); tableGameList.setHeaderVisible(true); GridData gd_tableGameList = new GridData(SWT.LEFT, SWT.FILL, true, true, 1, 1); gd_tableGameList.heightHint = 466; tableGameList.setLayoutData(gd_tableGameList); tableGameList.setFont(SWTResourceManager.getFont("Segoe UI", 10, SWT.NORMAL)); createColumns(tableViewer); tableViewer.setContentProvider(new ArrayContentProvider()); // Get the content for the viewer, setInput will call getElements in the // contentProvider tableViewer.setInput(thingProvider.getThings()); // make the selection available to other views // TODO: getSite().setSelectionProvider(viewer); // Set the sorter for the table tableViewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = tableViewer.getStructuredSelection(); Thing thing = (Thing)selection.getFirstElement(); eventBroker.send(EventConstants.TOPIC_THING_SELECTION, thing); } }); Composite statusRow = new Composite(main, SWT.NONE); statusRow.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1)); GridLayout gl_statusRow = new GridLayout(1, false); BatLayouts.applyStandardSpacing(gl_statusRow); statusRow.setLayout(gl_statusRow); lblResultStatus = new Label(statusRow, SWT.NONE); lblResultStatus.setText("0 items"); } public TableViewer getViewer() { return tableViewer; } // This will create the columns for the table private void createColumns(final TableViewer viewer) { TableViewerColumn colThumbnail = createTableViewerColumn(Thing.ThumbHeader, 120, 0); colThumbnail.setLabelProvider(new ColumnLabelProvider() { @Override public Image getImage(Object element) { Thing t = (Thing) element; Image img = t.getThumbnail(); return img; } @Override public String getText(Object element) { return ""; } }); TableViewerColumn colName = createTableViewerColumn(Thing.NameHeader, 400, 1); colName.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { Thing t = (Thing) element; return t.getField((int)colName.getColumn().getData()); } }); // https://stackoverflow.com/questions/12641354/putting-an-image-in-to-a-jface-table-cell-is-causing-gap-for-image-to-appear-in TableViewerColumn colId = createTableViewerColumn(Thing.IdHeader, 100, 2); colId.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { Thing t = (Thing) element; return t.getField((int)colId.getColumn().getData()); } }); } private TableViewerColumn createTableViewerColumn(String title, int bound, final int colNumber) { final TableViewerColumn viewerColumn = new TableViewerColumn(tableViewer, SWT.NONE); final TableColumn column = viewerColumn.getColumn(); column.setText(title); column.setWidth(bound); column.setAlignment(SWT.LEFT); column.setResizable(true); column.setMoveable(true); column.setData(colNumber); return viewerColumn; } /** * Passing the focus request to the viewer's control. */ public void setFocus() { tableViewer.getControl().setFocus(); } @Inject @Optional private void subscribeTopicResultChanged (@UIEventTopic(EventConstants.TOPIC_RESULT_CHANGED) String listName) { System.out.println("TOPIC_RESULT_CHANGED"); List things = thingProvider.getThings(); tableViewer.setInput(things); for (TableColumn column : tableViewer.getTable().getColumns()) { column.pack(); } tableViewer.refresh(true); if(things != null) { if(!things.isEmpty()) { tableViewer.getTable().setTopIndex(0); } btnSave.setEnabled(things.size() != 0); btnExport.setEnabled(things.size() != 0); lblResultStatus.setText(Integer.toString(things.size()) + " items"); lblResultStatus.redraw(); lblResultStatus.getParent().layout(); if(listName != null && !listName.isEmpty()) { lblListName.setText("\"" + listName + "\""); } else { lblListName.setText(UNNAMED_LIST); } } } @Inject @Optional private void subscribeTopicThingsSaved (@UIEventTopic(EventConstants.TOPIC_THINGS_SAVED) String listName) { System.out.println("TOPIC_THINGS_SAVED for game list '" + listName + "'."); btnSave.setEnabled(false); lblListName.setText(listName); // TODO: implement undo } }