Skip to content

Commit

Permalink
Display the statements of a Wikidata item in the WikidataInfoToggleDi…
Browse files Browse the repository at this point in the history
…alog
  • Loading branch information
floscher committed Aug 8, 2018
1 parent c41e6a5 commit d0bf68b
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 77 deletions.
2 changes: 1 addition & 1 deletion src/main/java/org/wikipedia/Caches.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public final class Caches {
public static final CacheAccess<String, String> API_RESPONSES = JCSCacheManager.getCache(
"api",
1,
1_000,
10_000,
new File(Config.getDirs().getCacheDirectory(false), "plugin/wikipedia").getAbsolutePath()
);

Expand Down
30 changes: 30 additions & 0 deletions src/main/java/org/wikipedia/gui/ProgressJPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.wikipedia.gui;

import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class ProgressJPanel extends JPanel {
private final JProgressBar PROGRESS_BAR = new JProgressBar();

ProgressJPanel() {
setLayout(new BorderLayout());
PROGRESS_BAR.setStringPainted(true);
}

protected synchronized void showProgress(final String message) {
if (!isAncestorOf(PROGRESS_BAR)) {
add(PROGRESS_BAR, BorderLayout.NORTH);
}
PROGRESS_BAR.setIndeterminate(true);
PROGRESS_BAR.setString(message);
revalidate();
repaint();
}

protected synchronized void hideProgress() {
remove(PROGRESS_BAR);
revalidate();
repaint();
}
}
53 changes: 53 additions & 0 deletions src/main/java/org/wikipedia/gui/WikidataInfoClaimPanel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.wikipedia.gui;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.io.IOException;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.tools.I18n;
import org.wikipedia.WikipediaPlugin;
import org.wikipedia.api.ApiQueryClient;
import org.wikipedia.api.wikidata_action.WikidataActionApiQuery;
import org.wikipedia.api.wikidata_action.json.WbgetclaimsResult;

class WikidataInfoClaimPanel extends ProgressJPanel {

private final JPanel mainPanel;
private String qIdBeingDownloaded;

WikidataInfoClaimPanel() {
super();
this.mainPanel = new JPanel();
add(new JScrollPane(mainPanel), BorderLayout.CENTER);
}

void downloadStatementsFor(final String qId) {
this.qIdBeingDownloaded = qId;
new Thread(() -> {
try {
mainPanel.removeAll();
showProgress(I18n.tr("Download statements for {0}…", qId));
final WbgetclaimsResult result = ApiQueryClient.query(WikidataActionApiQuery.wbgetclaims(qId));
if (qIdBeingDownloaded != null && qIdBeingDownloaded.equals(qId)) {
synchronized (mainPanel) {
mainPanel.removeAll();
mainPanel.setLayout(new GridLayout(result.getClaims().size(), 1));
result.getClaims().forEach(claim -> {
final WbgetclaimsResult.Claim.MainSnak.DataValue value = claim.getMainSnak().getDataValue(); // nullable
mainPanel.add(new StatementPanel(claim.getMainSnak().getProperty(), value == null ? I18n.tr("Unknown datatype!") : value.toString()));
});
hideProgress();
}
}
} catch (IOException e) {
new Notification(I18n.tr("Failed to download statements for Wikidata item {0}!", qId))
.setIcon(WikipediaPlugin.W_IMAGE.get())
.show();
}
hideProgress();
}).start();

}
}
84 changes: 40 additions & 44 deletions src/main/java/org/wikipedia/gui/WikidataInfoLabelPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.tools.I18n;
import org.openstreetmap.josm.tools.Logging;
import org.openstreetmap.josm.tools.Pair;
import org.wikipedia.WikipediaPlugin;
import org.wikipedia.api.ApiQueryClient;
Expand All @@ -22,42 +23,18 @@
/**
* Panel displaying the labels for a Wikidata item
*/
class WikidataInfoLabelPanel extends JPanel {

private static final JProgressBar downloadProgress = new JProgressBar();
class WikidataInfoLabelPanel extends ProgressJPanel {
private final LabelTableModel tableModel = new LabelTableModel(this);

static {
downloadProgress.setStringPainted(true);
}
private final JTable table = new JTable(tableModel);

WikidataInfoLabelPanel() {
setLayout(new BorderLayout());
add(new JTable(tableModel), BorderLayout.CENTER);
}

void clear() {
tableModel.clear();
add(new JScrollPane(table), BorderLayout.CENTER);
}

void downloadLabelsFor(final String qId) {
tableModel.downloadLabelsFor(qId);
}

private synchronized void showDownloadProgress(final String qId) {
if (!isAncestorOf(downloadProgress)) {
add(downloadProgress, BorderLayout.NORTH);
}
downloadProgress.setIndeterminate(true);
downloadProgress.setString(I18n.tr("Download labels for {0}…", qId));
revalidate();
}

private synchronized void hideDownloadProgress() {
remove(downloadProgress);
revalidate();
}

private static class LabelTableModel extends AbstractTableModel {
private final WikidataInfoLabelPanel parent;
private String qIdBeingDownloaded;
Expand All @@ -67,36 +44,40 @@ private static class LabelTableModel extends AbstractTableModel {
this.parent = parent;
}

void clear() {
this.valueMap.clear();
}

void downloadLabelsFor(final String qId) {
synchronized (valueMap) {
qIdBeingDownloaded = qId;
parent.showDownloadProgress(qId);
}
qIdBeingDownloaded = qId;

new Thread(() -> {
try {
parent.showProgress(I18n.tr("Download labels for {0}…", qId));
valueMap.clear();
parent.table.revalidate();
parent.revalidate();
parent.repaint();
final Map<String, WbgetentitiesResult.Entity.Label> newValues = ApiQueryClient.query(WikidataActionApiQuery.wbgetentitiesLabels(qId));
final Map<String, String> languages = new HashMap<>();
try {
languages.putAll(ApiQueryClient.query(WikidataActionApiQuery.queryLanguages()));
} catch (IOException e) {
Logging.warn("Could not download language names! Only the language codes are displayed.", e);
}
synchronized (valueMap) {
if (qIdBeingDownloaded != null && qIdBeingDownloaded.equals(qId)) {
valueMap.clear();
valueMap.addAll(
newValues.entrySet().stream()
.map(it -> Pair.create(it.getValue(), it.getKey()))
newValues.values().stream()
.map(it -> Pair.create(it, languages.containsKey(it.getLangCode()) ? languages.get(it.getLangCode()) : it.getLangCode()))
.sorted(Comparator.comparing(it -> it.a.getLangCode()))
.collect(Collectors.toList())
);
parent.table.revalidate();
}
}
} catch (IOException e) {
new Notification(I18n.tr("Failed to download labels for {0}!", qId)).setIcon(WikipediaPlugin.W_IMAGE.get()).show();
}
parent.hideDownloadProgress();
parent.hideProgress();
}).start();

}

@Override
Expand All @@ -106,17 +87,32 @@ public int getRowCount() {

@Override
public int getColumnCount() {
return 2;
return 3;
}

@Override
public Object getValueAt(int rowIndex, int columnIndex) {
return columnIndex == 0 ? valueMap.get(rowIndex).a : valueMap.get(rowIndex).b;
switch (columnIndex) {
case 0: return valueMap.get(rowIndex).a.getLangCode();
case 1: return valueMap.get(rowIndex).b;
case 2:
default: return valueMap.get(rowIndex).a.getValue();
}
}

@Override
public String getColumnName(int column) {
return column == 0 ? "language" : "label";
switch (column) {
case 0: return I18n.tr("language code");
case 1: return I18n.tr("language");
case 2:
default: return I18n.tr("label");
}
}

@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex == 3;
}
}
}
47 changes: 15 additions & 32 deletions src/main/java/org/wikipedia/gui/WikidataInfoToggleDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.Collections;
import java.util.Map;
Expand All @@ -20,7 +17,6 @@
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import org.openstreetmap.josm.data.osm.DataSelectionListener;
import org.openstreetmap.josm.data.osm.DataSet;
Expand All @@ -30,14 +26,16 @@
import org.openstreetmap.josm.gui.MainApplication;
import org.openstreetmap.josm.gui.Notification;
import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
import org.openstreetmap.josm.tools.GBC;
import org.openstreetmap.josm.tools.I18n;
import org.openstreetmap.josm.tools.OpenBrowser;
import org.wikipedia.WikipediaPlugin;
import org.wikipedia.data.WikidataEntry;
import org.wikipedia.data.WikipediaEntry;
import org.wikipedia.tools.OsmPrimitiveUtil;

/**
* Toggle dialog that displays infos about the currently selected Wikidata item.
*/
public class WikidataInfoToggleDialog extends ToggleDialog {
private static final Logger L = Logger.getLogger(WikidataInfoToggleDialog.class.getName());
private static final String EMPTY_STRING = "";
Expand All @@ -56,7 +54,7 @@ public class WikidataInfoToggleDialog extends ToggleDialog {

private final JTabbedPane tabs = new JTabbedPane();
private final WikidataInfoLabelPanel labelTab = new WikidataInfoLabelPanel();
private final JPanel statementTab = new JPanel();
private final WikidataInfoClaimPanel statementTab = new WikidataInfoClaimPanel();
private final JPanel linkTab = new JPanel();
private final JButton webLinkButton = new JButton();

Expand Down Expand Up @@ -98,25 +96,6 @@ public WikidataInfoToggleDialog(final WikipediaToggleDialog wikiDialog) {
infoPanel.add(basicInfoPanel, BorderLayout.NORTH);
infoPanel.add(tabs, BorderLayout.CENTER);

// Set up statement tab
statementTab.setLayout(new GridBagLayout());
final GridBagConstraints constraints = new GridBagConstraints();
constraints.anchor = GridBagConstraints.NORTH;
constraints.gridx = 0;
constraints.gridy = 0;
constraints.insets = new Insets(1, 1, 1, 1);
constraints.fill = GridBagConstraints.BOTH;
// At the moment only dummy content
constraints.weightx = 1;
statementTab.add(new StatementPanel("instance of", "example", "dummy content"), constraints);
constraints.gridy++;
statementTab.add(new StatementPanel("start date", "42"), constraints);
constraints.gridy++;
statementTab.add(new StatementPanel("architect", "John Doe"), constraints);
constraints.gridy++;
constraints.weighty = 1;
statementTab.add(GBC.glue(0, 0), constraints);

linkTab.add(webLinkButton);

tabs.add(I18n.tr("Statements"), statementTab);
Expand All @@ -126,7 +105,6 @@ public WikidataInfoToggleDialog(final WikipediaToggleDialog wikiDialog) {
// Set up listeners
this.wikiDialog.list.addListSelectionListener(event -> updateDisplayedItem());
MainApplication.getLayerManager().addAndFireActiveLayerChangeListener(event -> {
System.out.println("Fire active layer change");
final DataSet previous = event.getPreviousDataSet();
final DataSet current = event.getSource().getActiveDataSet();
if (previous != null) {
Expand Down Expand Up @@ -173,7 +151,9 @@ private void updateDisplayedItem() {
}
} else if (wdTagsInDataset.size() >= 2) {
// More than one OSM object with valid wikidata=* tag is selected
final String itemList = wdTagsInDataset.entrySet().stream().map(it -> it.getKey() + " (" + it.getValue() + "×)").collect(Collectors.joining(", "));
final String itemList = wdTagsInDataset.entrySet().stream()
.map(it -> it.getKey() + " (" + it.getValue() + "×)")
.collect(Collectors.joining(", "));
displayMessage(itemList, I18n.tr("More than one OSM object is selected: {0}", itemList));
} else { // size == 1
// An OSM object or multiple OSM objects with exactly one valid wikidata=* tag (multiple tags with same value count as one)
Expand All @@ -182,36 +162,39 @@ private void updateDisplayedItem() {
}
}

private void displayItem(final String qId, final String label, final String description) {
private synchronized void displayItem(final String qId, final String label, final String description) {
if (qId != null && !qId.equals(getDisplayedItem())) {
mainPanel.removeAll();
setTitle(qId);
nameLabel.setText(label);
descriptionLabel.setText(description);
setDisplayedItem(qId);

labelTab.clear();
labelTab.downloadLabelsFor(qId);

statementTab.downloadStatementsFor(qId);

webLinkButton.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
final String uri = "https://www.wikidata.org/wiki/" + qId;
final String error = OpenBrowser.displayUrl(uri);
if (error != null) {
new Notification(I18n.tr("Can't open website {0} in browser! Error message: {1}", uri, error)).setIcon(WikipediaPlugin.W_IMAGE.get()).show();
new Notification(I18n.tr("Can't open website {0} in browser! Error message: {1}", uri, error))
.setIcon(WikipediaPlugin.W_IMAGE.get())
.show();
}
}
});
webLinkButton.setText(I18n.tr("Open item {0} in browser", qId));

mainPanel.add(new JScrollPane(infoPanel));
mainPanel.add(infoPanel);
mainPanel.revalidate();
mainPanel.repaint();
}
}

private void displayMessage(final String title, final String message) {
private synchronized void displayMessage(final String title, final String message) {
mainPanel.removeAll();
setTitle(title);
setDisplayedItem(null);
Expand Down

0 comments on commit d0bf68b

Please sign in to comment.