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