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