001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.io;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005import static org.openstreetmap.josm.tools.I18n.trn;
006
007import java.awt.BorderLayout;
008import java.beans.PropertyChangeEvent;
009import java.beans.PropertyChangeListener;
010
011import javax.swing.BorderFactory;
012import javax.swing.JLabel;
013import javax.swing.JPanel;
014import javax.swing.event.HyperlinkEvent;
015import javax.swing.event.HyperlinkListener;
016
017import org.openstreetmap.josm.data.osm.Changeset;
018import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
019import org.openstreetmap.josm.io.OsmApi;
020import org.openstreetmap.josm.tools.ImageProvider;
021
022// FIXME this class should extend HtmlPanel instead (duplicated code in here)
023public class UploadParameterSummaryPanel extends JPanel implements HyperlinkListener, PropertyChangeListener {
024    private transient UploadStrategySpecification spec = new UploadStrategySpecification();
025    private int numObjects;
026    private JMultilineLabel jepMessage;
027    private JLabel lblWarning;
028
029    private transient Changeset selectedChangeset;
030    private boolean closeChangesetAfterNextUpload;
031    private transient ConfigurationParameterRequestHandler configHandler;
032
033    /**
034     * Constructs a new {@code UploadParameterSummaryPanel}.
035     */
036    public UploadParameterSummaryPanel() {
037        build();
038        updateSummary();
039    }
040
041    protected String buildChangesetSummary() {
042        StringBuilder msg = new StringBuilder(96);
043        if (selectedChangeset == null || selectedChangeset.isNew()) {
044            msg.append(tr("Objects are uploaded to a <strong>new changeset</strong>."));
045        } else {
046            String uploadComment = selectedChangeset.get("comment") == null ?
047                    "" : selectedChangeset.get("comment");
048            msg.append(tr("Objects are uploaded to the <strong>open changeset</strong> {0} with upload comment ''{1}''.",
049                    selectedChangeset.getId(),
050                    uploadComment
051            ));
052        }
053        msg.append(' ');
054        if (closeChangesetAfterNextUpload) {
055            msg.append(tr("The changeset is going to be <strong>closed</strong> after this upload"));
056        } else {
057            msg.append(tr("The changeset is <strong>left open</strong> after this upload"));
058        }
059        msg.append(" (<a href=\"urn:changeset-configuration\">").append(tr("configure changeset")).append("</a>)");
060        return msg.toString();
061    }
062
063    protected String buildStrategySummary() {
064        if (spec == null)
065            return "";
066        // check whether we can use one changeset only or whether we have to use multiple changesets
067        //
068        boolean useOneChangeset = true;
069        int maxChunkSize = OsmApi.getOsmApi().getCapabilities().getMaxChangesetSize();
070        if (maxChunkSize > 0 && numObjects > maxChunkSize) {
071            useOneChangeset = false;
072        }
073
074        int numRequests = spec.getNumRequests(numObjects);
075        String msg = null;
076        if (useOneChangeset) {
077            lblWarning.setVisible(false);
078            if (numRequests == 0) {
079                msg = trn(
080                        "Uploading <strong>{0} object</strong> to <strong>1 changeset</strong>",
081                        "Uploading <strong>{0} objects</strong> to <strong>1 changeset</strong>",
082                        numObjects, numObjects
083                );
084            } else if (numRequests == 1) {
085                msg = trn(
086                        "Uploading <strong>{0} object</strong> to <strong>1 changeset</strong> using <strong>1 request</strong>",
087                        "Uploading <strong>{0} objects</strong> to <strong>1 changeset</strong> using <strong>1 request</strong>",
088                        numObjects, numObjects
089                );
090            } else if (numRequests > 1) {
091                msg = tr("Uploading <strong>{0} objects</strong> to <strong>1 changeset</strong> using <strong>{1} requests</strong>",
092                        numObjects, numRequests);
093            }
094            msg = msg + " (<a href=\"urn:advanced-configuration\">" + tr("advanced configuration") + "</a>)";
095        } else {
096            lblWarning.setVisible(true);
097            if (numRequests == 0) {
098                msg = tr("{0} objects exceed the max. allowed {1} objects in a changeset on the server ''{2}''. " +
099                        "Please <a href=\"urn:advanced-configuration\">configure</a> how to proceed with <strong>multiple changesets</strong>",
100                        numObjects, maxChunkSize, OsmApi.getOsmApi().getBaseUrl());
101            } else if (numRequests > 1) {
102                msg = tr("Uploading <strong>{0} objects</strong> to <strong>multiple changesets</strong> using <strong>{1} requests</strong>",
103                        numObjects, numRequests);
104                msg = msg + " (<a href=\"urn:advanced-configuration\">" + tr("advanced configuration") + "</a>)";
105            }
106        }
107        return msg;
108    }
109
110    protected void build() {
111        jepMessage = new JMultilineLabel("");
112        jepMessage.addHyperlinkListener(this);
113
114        setLayout(new BorderLayout());
115        add(jepMessage, BorderLayout.CENTER);
116        lblWarning = new JLabel("");
117        lblWarning.setVisible(false);
118        lblWarning.setIcon(ImageProvider.get("warning-small"));
119        lblWarning.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
120        JPanel pnl = new JPanel(new BorderLayout());
121        pnl.add(lblWarning, BorderLayout.NORTH);
122        add(pnl, BorderLayout.WEST);
123    }
124
125    public void setConfigurationParameterRequestListener(ConfigurationParameterRequestHandler handler) {
126        this.configHandler = handler;
127    }
128
129    public void setUploadStrategySpecification(UploadStrategySpecification spec) {
130        this.spec = spec;
131        updateSummary();
132    }
133
134    public void setNumObjects(int numObjects) {
135        this.numObjects = numObjects;
136        updateSummary();
137    }
138
139    public void setCloseChangesetAfterNextUpload(boolean value) {
140        this.closeChangesetAfterNextUpload = value;
141        updateSummary();
142    }
143
144    protected void updateSummary() {
145        StringBuilder sb = new StringBuilder(32);
146        sb.append("<html>")
147          .append(buildStrategySummary())
148          .append("<br><br>")
149          .append(buildChangesetSummary())
150          .append("</html>");
151        jepMessage.setText(sb.toString());
152    }
153
154    /* --------------------------------------------------------------------- */
155    /* Interface HyperlinkListener
156    /* --------------------------------------------------------------------- */
157    @Override
158    public void hyperlinkUpdate(HyperlinkEvent e) {
159        if (HyperlinkEvent.EventType.ACTIVATED.equals(e.getEventType())) {
160            String desc = e.getDescription();
161            if (desc == null || configHandler == null)
162                return;
163            if ("urn:changeset-configuration".equals(desc)) {
164                configHandler.handleChangesetConfigurationRequest();
165            } else if ("urn:advanced-configuration".equals(desc)) {
166                configHandler.handleUploadStrategyConfigurationRequest();
167            }
168        }
169    }
170
171    /* --------------------------------------------------------------------- */
172    /* Interface PropertyChangeListener
173    /* --------------------------------------------------------------------- */
174    @Override
175    public void propertyChange(PropertyChangeEvent evt) {
176        if (evt.getPropertyName().equals(ChangesetManagementPanel.SELECTED_CHANGESET_PROP)) {
177            selectedChangeset = (Changeset) evt.getNewValue();
178            updateSummary();
179        } else if (evt.getPropertyName().equals(ChangesetManagementPanel.CLOSE_CHANGESET_AFTER_UPLOAD)) {
180            closeChangesetAfterNextUpload = (Boolean) evt.getNewValue();
181            updateSummary();
182        } else if (evt.getPropertyName().equals(UploadedObjectsSummaryPanel.NUM_OBJECTS_TO_UPLOAD_PROP)) {
183            numObjects = (Integer) evt.getNewValue();
184            updateSummary();
185        } else if (evt.getPropertyName().equals(UploadStrategySelectionPanel.UPLOAD_STRATEGY_SPECIFICATION_PROP)) {
186            this.spec = (UploadStrategySpecification) evt.getNewValue();
187            updateSummary();
188        }
189    }
190}