// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.dialogs.changeset; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.BorderLayout; import java.awt.Component; import java.awt.FlowLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Collections; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JToolBar; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.downloadtasks.ChangesetHeaderDownloadTask; import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler; import org.openstreetmap.josm.data.osm.Changeset; import org.openstreetmap.josm.io.OnlineResource; import org.openstreetmap.josm.tools.ImageProvider; /** * The panel which displays the public discussion around a changeset in a scrollable table. * * It listens to property change events for {@link ChangesetCacheManagerModel#CHANGESET_IN_DETAIL_VIEW_PROP} * and updates its view accordingly. * * @since 7704 */ public class ChangesetDiscussionPanel extends JPanel implements PropertyChangeListener { private final UpdateChangesetDiscussionAction actUpdateChangesets = new UpdateChangesetDiscussionAction(); private final ChangesetDiscussionTableModel model = new ChangesetDiscussionTableModel(); private JTable table; private transient Changeset current; protected JPanel buildActionButtonPanel() { JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT)); JToolBar tb = new JToolBar(JToolBar.VERTICAL); tb.setFloatable(false); // -- changeset discussion update tb.add(actUpdateChangesets); actUpdateChangesets.initProperties(current); pnl.add(tb); return pnl; } /** * Updates the current changeset discussion from the OSM server */ class UpdateChangesetDiscussionAction extends AbstractAction { UpdateChangesetDiscussionAction() { putValue(NAME, tr("Update changeset discussion")); new ImageProvider("dialogs/changeset", "updatechangesetcontent").getResource().attachImageIcon(this); putValue(SHORT_DESCRIPTION, tr("Update the changeset discussion from the OSM server")); } @Override public void actionPerformed(ActionEvent evt) { if (current == null) return; ChangesetHeaderDownloadTask task = new ChangesetHeaderDownloadTask( ChangesetDiscussionPanel.this, Collections.singleton(current.getId()), true /* include discussion */ ); Main.worker.submit(new PostDownloadHandler(task, task.download())); } public void initProperties(Changeset cs) { setEnabled(cs != null && !Main.isOffline(OnlineResource.OSM_API)); } } /** * Constructs a new {@code ChangesetDiscussionPanel}. */ public ChangesetDiscussionPanel() { build(); } protected void setCurrentChangeset(Changeset cs) { current = cs; if (cs == null) { clearView(); } else { updateView(cs); } actUpdateChangesets.initProperties(current); if (cs != null && cs.getDiscussion().size() < cs.getCommentsCount()) { actUpdateChangesets.actionPerformed(null); } } protected final void build() { setLayout(new BorderLayout()); setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); add(buildActionButtonPanel(), BorderLayout.WEST); add(buildDiscussionPanel(), BorderLayout.CENTER); } private Component buildDiscussionPanel() { JPanel pnl = new JPanel(new BorderLayout()); table = new JTable(model, new ChangesetDiscussionTableColumnModel()); table.getColumnModel().getColumn(2).addPropertyChangeListener(evt -> { if ("width".equals(evt.getPropertyName())) { updateRowHeights(); } }); pnl.add(new JScrollPane(table), BorderLayout.CENTER); return pnl; } protected void clearView() { model.populate(null); } protected void updateView(Changeset cs) { model.populate(cs.getDiscussion()); updateRowHeights(); } protected void updateRowHeights() { int intercellWidth = table.getIntercellSpacing().width; int colWidth = table.getColumnModel().getColumn(2).getWidth(); // Update row heights for (int row = 0; row < table.getRowCount(); row++) { int rowHeight = table.getRowHeight(); Component comp = table.prepareRenderer(table.getCellRenderer(row, 2), row, 2); // constrain width of component comp.setBounds(new Rectangle(0, 0, colWidth - intercellWidth, Integer.MAX_VALUE)); rowHeight = Math.max(rowHeight, comp.getPreferredSize().height); table.setRowHeight(row, rowHeight); } } /* ---------------------------------------------------------------------------- */ /* interface PropertyChangeListener */ /* ---------------------------------------------------------------------------- */ @Override public void propertyChange(PropertyChangeEvent evt) { if (!evt.getPropertyName().equals(ChangesetCacheManagerModel.CHANGESET_IN_DETAIL_VIEW_PROP)) return; setCurrentChangeset((Changeset) evt.getNewValue()); } }