001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.dialogs.changeset; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.BorderLayout; 007import java.awt.Component; 008import java.awt.FlowLayout; 009import java.awt.event.ActionEvent; 010import java.beans.PropertyChangeEvent; 011import java.beans.PropertyChangeListener; 012import java.util.Collections; 013 014import javax.swing.AbstractAction; 015import javax.swing.BorderFactory; 016import javax.swing.JPanel; 017import javax.swing.JScrollPane; 018import javax.swing.JTable; 019import javax.swing.JToolBar; 020 021import org.openstreetmap.josm.Main; 022import org.openstreetmap.josm.data.osm.Changeset; 023import org.openstreetmap.josm.io.OnlineResource; 024 025/** 026 * The panel which displays the public discussion around a changeset in a scrollable table. 027 * 028 * It listens to property change events for {@link ChangesetCacheManagerModel#CHANGESET_IN_DETAIL_VIEW_PROP} 029 * and updates its view accordingly. 030 * 031 * @since 7704 032 */ 033public class ChangesetDiscussionPanel extends JPanel implements PropertyChangeListener { 034 035 private final UpdateChangesetDiscussionAction actUpdateChangesets = new UpdateChangesetDiscussionAction(); 036 037 private final ChangesetDiscussionTableModel model = new ChangesetDiscussionTableModel(); 038 039 private JTable table; 040 041 private Changeset current = null; 042 043 protected JPanel buildActionButtonPanel() { 044 JPanel pnl = new JPanel(new FlowLayout(FlowLayout.LEFT)); 045 046 JToolBar tb = new JToolBar(JToolBar.VERTICAL); 047 tb.setFloatable(false); 048 049 // -- changeset discussion update 050 tb.add(actUpdateChangesets); 051 actUpdateChangesets.initProperties(current); 052 053 pnl.add(tb); 054 return pnl; 055 } 056 057 /** 058 * Updates the current changeset discussion from the OSM server 059 */ 060 class UpdateChangesetDiscussionAction extends AbstractAction { 061 public UpdateChangesetDiscussionAction() { 062 putValue(NAME, tr("Update changeset discussion")); 063 putValue(SMALL_ICON, ChangesetCacheManager.UPDATE_CONTENT_ICON); 064 putValue(SHORT_DESCRIPTION, tr("Update the changeset discussion from the OSM server")); 065 } 066 067 @Override 068 public void actionPerformed(ActionEvent evt) { 069 if (current == null) return; 070 Main.worker.submit( 071 new ChangesetHeaderDownloadTask( 072 ChangesetDiscussionPanel.this, 073 Collections.singleton(current.getId()), 074 true /* include discussion */ 075 ) 076 ); 077 } 078 079 public void initProperties(Changeset cs) { 080 setEnabled(cs != null && !Main.isOffline(OnlineResource.OSM_API)); 081 } 082 } 083 084 /** 085 * Constructs a new {@code ChangesetDiscussionPanel}. 086 */ 087 public ChangesetDiscussionPanel() { 088 build(); 089 } 090 091 protected void setCurrentChangeset(Changeset cs) { 092 current = cs; 093 if (cs == null) { 094 clearView(); 095 } else { 096 updateView(cs); 097 } 098 actUpdateChangesets.initProperties(current); 099 if (cs != null && cs.getDiscussion().size() < cs.getCommentsCount()) { 100 actUpdateChangesets.actionPerformed(null); 101 } 102 } 103 104 protected final void build() { 105 setLayout(new BorderLayout()); 106 setBorder(BorderFactory.createEmptyBorder(3,3,3,3)); 107 add(buildActionButtonPanel(), BorderLayout.WEST); 108 add(buildDiscussionPanel(), BorderLayout.CENTER); 109 } 110 111 private Component buildDiscussionPanel() { 112 JPanel pnl = new JPanel(new BorderLayout()); 113 table = new JTable(model, new ChangesetDiscussionTableColumnModel()); 114 pnl.add(new JScrollPane(table), BorderLayout.CENTER); 115 return pnl; 116 } 117 118 protected void clearView() { 119 model.populate(null); 120 } 121 122 protected void updateView(Changeset cs) { 123 model.populate(cs.getDiscussion()); 124 // Update row heights 125 for (int row = 0; row < table.getRowCount(); row++) { 126 int rowHeight = table.getRowHeight(); 127 128 Component comp = table.prepareRenderer(table.getCellRenderer(row, 2), row, 2); 129 rowHeight = Math.max(rowHeight, comp.getPreferredSize().height); 130 131 table.setRowHeight(row, rowHeight); 132 } 133 } 134 135 /* ---------------------------------------------------------------------------- */ 136 /* interface PropertyChangeListener */ 137 /* ---------------------------------------------------------------------------- */ 138 @Override 139 public void propertyChange(PropertyChangeEvent evt) { 140 if (! evt.getPropertyName().equals(ChangesetCacheManagerModel.CHANGESET_IN_DETAIL_VIEW_PROP)) 141 return; 142 setCurrentChangeset((Changeset)evt.getNewValue()); 143 } 144}