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