Ticket #2782: progress.patch

File progress.patch, 162.5 KB (added by jttt, 17 years ago)
  • src/org/openstreetmap/josm/io/BoundingBoxDownloader.java

     
    77import java.io.InputStream;
    88
    99import org.openstreetmap.josm.Main;
    10 import org.openstreetmap.josm.data.osm.DataSet;
    1110import org.openstreetmap.josm.data.gpx.GpxData;
     11import org.openstreetmap.josm.data.osm.DataSet;
     12import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1213import org.xml.sax.SAXException;
    1314
    1415
     
    3839     *      contain only one list, since the server cannot distinguish between
    3940     *      ways.
    4041     */
    41     public GpxData parseRawGps() throws IOException, SAXException {
    42         Main.pleaseWaitDlg.progress.setValue(0);
    43         Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
     42    public GpxData parseRawGps(ProgressMonitor progressMonitor) throws IOException, SAXException {
     43        progressMonitor.beginTask("", 1);
    4444        try {
     45            progressMonitor.indeterminateSubTask(tr("Contacting OSM Server..."));
    4546            String url = "trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=";
    4647
    4748            boolean done = false;
    4849            GpxData result = null;
    4950            for (int i = 0;!done;++i) {
    50                 Main.pleaseWaitDlg.currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
    51                 InputStream in = getInputStream(url+i, Main.pleaseWaitDlg);
     51                progressMonitor.subTask(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
     52                InputStream in = getInputStream(url+i, progressMonitor.createSubTaskMonitor(1, true));
    5253                if (in == null) {
    5354                    break;
    5455                }
     56                progressMonitor.setTicks(0);
    5557                GpxData currentGpx = new GpxReader(in, null).data;
    5658                if (result == null) {
    5759                    result = currentGpx;
     
    8284            if (e instanceof RuntimeException)
    8385                throw (RuntimeException)e;
    8486            throw new RuntimeException(e);
     87        } finally {
     88            progressMonitor.finishTask();
    8589        }
    8690    }
    8791
     
    9094     * @return A data set containing all data retrieved from that url
    9195     */
    9296    @Override
    93     public DataSet parseOsm() throws OsmTransferException {
     97    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
     98        progressMonitor.beginTask(tr("Contacting OSM Server..."), 10);
    9499        try {
    95             Main.pleaseWaitDlg.progress.setValue(0);
    96             Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
    97             Main.pleaseWaitDlg.setIndeterminate(true);
    98             final InputStream in = getInputStream("map?bbox="+lon1+","+lat1+","+lon2+","+lat2, Main.pleaseWaitDlg);
    99             Main.pleaseWaitDlg.setIndeterminate(false);
     100            progressMonitor.indeterminateSubTask(null);
     101            final InputStream in = getInputStream("map?bbox="+lon1+","+lat1+","+lon2+","+lat2, progressMonitor.createSubTaskMonitor(9, false));
    100102            if (in == null)
    101103                return null;
    102             Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
    103             final DataSet data = OsmReader.parseDataSet(in,Main.pleaseWaitDlg);
     104            final DataSet data = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
    104105            in.close();
    105106            activeConnection = null;
    106107            return data;
     
    116117            if (cancel)
    117118                return null;
    118119            throw new OsmTransferException(e);
     120        } finally {
     121            progressMonitor.finishTask();
    119122        }
    120123    }
    121124}
  • src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.io.IOException;
    76import java.io.InputStream;
    87import java.net.HttpURLConnection;
    98import java.util.Collection;
     
    1312import java.util.Set;
    1413import java.util.logging.Logger;
    1514
    16 import org.openstreetmap.josm.Main;
    1715import org.openstreetmap.josm.data.osm.DataSet;
    1816import org.openstreetmap.josm.data.osm.Node;
    1917import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    2220import org.openstreetmap.josm.data.osm.RelationMember;
    2321import org.openstreetmap.josm.data.osm.Way;
    2422import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
    25 import org.xml.sax.SAXException;
     23import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     24import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2625
    2726/**
    2827 * Retrieves a set of {@see OsmPrimitive}s from an OSM server using the so called
    2928 * Multi Fetch API.
    30  * 
     29 *
    3130 * Usage:
    3231 * <pre>
    3332 *    MultiFetchServerObjectReader reader = MultiFetchServerObjectReader()
     
    4140 *       System.out.println("There are skipped ways: " + reader.getMissingPrimitives());
    4241 *    }
    4342 * </pre>
    44  * 
     43 *
    4544 *
    4645 */
    4746public class MultiFetchServerObjectReader extends OsmServerReader{
     
    5251     * this leads to a max. request URL of ~  1600 Bytes ((7 digits +  1 Seperator) * 200),
    5352     * which should be safe according to the
    5453     * <a href="http://www.boutell.com/newfaq/misc/urllength.html">WWW FAQ</a>.
    55      * 
     54     *
    5655     */
    5756    static private int MAX_IDS_PER_REQUEST = 200;
    5857
     
    7877    /**
    7978     * remembers an {@see OsmPrimitive}'s id and its type. The id will
    8079     * later be fetched as part of a Multi Get request.
    81      * 
     80     *
    8281     * Ignore the id if it id <= 0.
    83      * 
     82     *
    8483     * @param id  the id
    8584     * @param type  the type
    8685     */
     
    9998     * remembers an {@see OsmPrimitive}'s id. <code>ds</code> must include
    10099     * an {@see OsmPrimitive} with id=<code>id</code>. The id will
    101100     * later we fetched as part of a Multi Get request.
    102      * 
     101     *
    103102     * Ignore the id if it id <= 0.
    104      * 
     103     *
    105104     * @param ds  the dataset (must not be null)
    106105     * @param id  the id
    107106     * @exception IllegalArgumentException thrown, if ds is null
     
    122121    /**
    123122     * appends a list of  ids to the list of ids which will be fetched from the server. ds must
    124123     * include an {@see OsmPrimitive} for each id in ids.
    125      * 
     124     *
    126125     * id is ignored if id <= 0.
    127      * 
     126     *
    128127     * @param ds  the dataset
    129128     * @param ids  the list of ids
    130129     * @return this
    131      * 
     130     *
    132131     */
    133132    public MultiFetchServerObjectReader append(DataSet ds, long ... ids)  {
    134133        if (ids == null) return this;
     
    141140    /**
    142141     * appends a collection of  ids to the list of ids which will be fetched from the server. ds must
    143142     * include an {@see OsmPrimitive} for each id in ids.
    144      * 
     143     *
    145144     * id is ignored if id <= 0.
    146      * 
     145     *
    147146     * @param ds  the dataset
    148147     * @param ids  the collection of ids
    149148     * @return this
    150      * 
     149     *
    151150     */
    152151    public MultiFetchServerObjectReader append(DataSet ds, Collection<Long> ids) {
    153152        if (ids == null) return null;
     
    162161     *
    163162     * @param node  the node (ignored, if null)
    164163     * @return this
    165      * 
     164     *
    166165     */
    167166    public MultiFetchServerObjectReader append(Node node) {
    168167        if (node == null) return this;
     
    176175     *
    177176     * @param way the way (ignored, if null)
    178177     * @return this
    179      * 
     178     *
    180179     */
    181180    public MultiFetchServerObjectReader append(Way way) {
    182181        if (way == null) return this;
     
    195194     *
    196195     * @param relation  the relation (ignored, if null)
    197196     * @return this
    198      * 
     197     *
    199198     */
    200199    public MultiFetchServerObjectReader append(Relation relation) {
    201200        if (relation == null) return this;
     
    224223     *
    225224     * @param primitives  the list of primitives (ignored, if null)
    226225     * @return this
    227      * 
     226     *
    228227     * @see #append(Node)
    229228     * @see #append(Way)
    230229     * @see #append(Relation)
    231      * 
     230     *
    232231     */
    233232    public MultiFetchServerObjectReader append(Collection<OsmPrimitive> primitives) {
    234233        if (primitives == null) return this;
     
    241240    /**
    242241     * extracts a subset of max {@see #MAX_IDS_PER_REQUEST} ids from <code>ids</code> and
    243242     * replies the subset. The extracted subset is removed from <code>ids</code>.
    244      * 
     243     *
    245244     * @param ids a set of ids
    246245     * @return the subset of ids
    247246     */
     
    266265    /**
    267266     * builds the Multi Get request string for a set of ids and a given
    268267     * {@see OsmPrimitiveType}.
    269      * 
     268     *
    270269     * @param type the type
    271270     * @param idPackage  the package of ids
    272271     * @return the request string
     
    289288    /**
    290289     * builds the Multi Get request string for a single id and a given
    291290     * {@see OsmPrimitiveType}.
    292      * 
     291     *
    293292     * @param type the type
    294293     * @param id the id
    295294     * @return the request string
     
    305304    /**
    306305     * invokes a Multi Get for a set of ids and a given {@see OsmPrimitiveType}.
    307306     * The retrieved primitives are merged to {@see #outputDataSet}.
    308      * 
     307     *
    309308     * @param type the type
    310309     * @param pkg the package of ids
    311310     * @exception OsmTransferException thrown if an error occurs while communicating with the API server
    312      * 
     311     *
    313312     */
    314     protected void multiGetIdPackage(OsmPrimitiveType type, Set<Long> pkg) throws OsmTransferException {
     313    protected void multiGetIdPackage(OsmPrimitiveType type, Set<Long> pkg, ProgressMonitor progressMonitor) throws OsmTransferException {
    315314        String request = buildRequestString(type, pkg);
    316         final InputStream in = getInputStream(request, Main.pleaseWaitDlg);
     315        final InputStream in = getInputStream(request, NullProgressMonitor.INSTANCE);
    317316        if (in == null) return;
    318         Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
     317        progressMonitor.subTask(tr("Downloading OSM data..."));
    319318        try {
    320             final OsmReader osm = OsmReader.parseDataSetOsm(in, Main.pleaseWaitDlg);
     319            final OsmReader osm = OsmReader.parseDataSetOsm(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    321320            merge(osm.getDs());
    322321        } catch(Exception e) {
    323322            throw new OsmTransferException(e);
     
    327326    /**
    328327     * invokes a Multi Get for a single id and a given {@see OsmPrimitiveType}.
    329328     * The retrieved primitive is merged to {@see #outputDataSet}.
    330      * 
     329     *
    331330     * @param type the type
    332331     * @param id the id
    333332     * @exception OsmTransferException thrown if an error occurs while communicating with the API server
    334      * 
     333     *
    335334     */
    336     protected void singleGetId(OsmPrimitiveType type, long id) throws OsmTransferException {
     335    protected void singleGetId(OsmPrimitiveType type, long id, ProgressMonitor progressMonitor) throws OsmTransferException {
    337336        String request = buildRequestString(type, id);
    338         final InputStream in = getInputStream(request, Main.pleaseWaitDlg);
     337        final InputStream in = getInputStream(request, NullProgressMonitor.INSTANCE);
    339338        if (in == null)
    340339            return;
    341         Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
     340        progressMonitor.subTask(tr("Downloading OSM data..."));
    342341        try {
    343             final OsmReader osm = OsmReader.parseDataSetOsm(in,Main.pleaseWaitDlg);
     342            final OsmReader osm = OsmReader.parseDataSetOsm(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    344343            merge(osm.getDs());
    345344        } catch(Exception e) {
    346345            throw new OsmTransferException(e);
     
    350349    /**
    351350     * invokes a sequence of Multi Gets for individual ids in a set of ids and a given {@see OsmPrimitiveType}.
    352351     * The retrieved primitives are merged to {@see #outputDataSet}.
    353      * 
     352     *
    354353     * This method is used if one of the ids in pkg doesn't exist (the server replies with return code 404).
    355354     * If the set is fetched with this method it is possible to find out which of the ids doesn't exist.
    356355     * Unfortunatelly, the server does not provide an error header or an error body for a 404 reply.
    357      * 
     356     *
    358357     * @param type the type
    359358     * @param pkg the set of ids
    360359     * @exception OsmTransferException thrown if an error occurs while communicating with the API server
    361      * 
     360     *
    362361     */
    363     protected void singleGetIdPackage(OsmPrimitiveType type, Set<Long> pkg) throws OsmTransferException {
     362    protected void singleGetIdPackage(OsmPrimitiveType type, Set<Long> pkg, ProgressMonitor progressMonitor) throws OsmTransferException {
    364363        for (long id : pkg) {
    365364            try {
    366                 singleGetId(type, id);
     365                singleGetId(type, id, progressMonitor);
    367366            } catch(OsmApiException e) {
    368367                if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
    369368                    logger.warning(tr("Server replied with response code 404 for id {0}. Skipping.", Long.toString(id)));
     
    377376
    378377    /**
    379378     * merges the dataset <code>from</code> to {@see #outputDataSet}.
    380      * 
     379     *
    381380     * @param from the other dataset
    382      * 
     381     *
    383382     */
    384383    protected void merge(DataSet from) {
    385384        final MergeVisitor visitor = new MergeVisitor(outputDataSet,from);
     
    388387
    389388    /**
    390389     * fetches a set of ids of a given {@see OsmPrimitiveType} from the server
    391      * 
     390     *
    392391     * @param ids the set of ids
    393392     * @param type the  type
    394393     * @exception OsmTransferException thrown if an error occurs while communicating with the API server
    395394     */
    396     protected void fetchPrimitives(Set<Long> ids, OsmPrimitiveType type) throws OsmTransferException{
     395    protected void fetchPrimitives(Set<Long> ids, OsmPrimitiveType type, ProgressMonitor progressMonitor) throws OsmTransferException{
    397396        Set<Long> toFetch = new HashSet<Long>(ids);
    398397        toFetch.addAll(ids);
    399398        while(! toFetch.isEmpty()) {
    400399            Set<Long> pkg = extractIdPackage(toFetch);
    401400            try {
    402                 multiGetIdPackage(type, pkg);
     401                multiGetIdPackage(type, pkg, progressMonitor);
    403402            } catch(OsmApiException e) {
    404403                if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
    405404                    logger.warning(tr("Server replied with response code 404, retrying with an individual request for each primitive"));
    406                     singleGetIdPackage(type, pkg);
     405                    singleGetIdPackage(type, pkg, progressMonitor);
    407406                } else
    408407                    throw e;
    409408            }
     
    416415     * In contrast to a simple Get for a node, a way, or a relation, a Multi Get always replies
    417416     * the latest version of the primitive (if any), even if the primitive is not visible (i.e. if
    418417     * visible==false).
    419      * 
     418     *
    420419     * Invoke {@see #getMissingPrimitives()} to get a list of primitives which have not been
    421420     * found on  the server (the server response code was 404)
    422      * 
     421     *
    423422     * Invoke {@see #getSkippedWay()} to get a list of ways which this reader could not build from
    424423     * the fetched data because the ways refer to nodes which don't exist on the server.
    425      * 
     424     *
    426425     * @return the parsed data
    427426     * @exception OsmTransferException thrown if an error occurs while communicating with the API server
    428427     * @see #getMissingPrimitives()
    429428     * @see #getSkippedWays()
    430      * 
     429     *
    431430
    432431     */
    433432    @Override
    434     public DataSet parseOsm() throws OsmTransferException {
    435         missingPrimitives = new HashSet<Long>();
     433    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
     434        progressMonitor.beginTask("");
     435        try {
     436            missingPrimitives = new HashSet<Long>();
    436437
    437         fetchPrimitives(nodes,OsmPrimitiveType.NODE);
    438         fetchPrimitives(ways,OsmPrimitiveType.WAY);
    439         fetchPrimitives(relations,OsmPrimitiveType.RELATION);
    440         return outputDataSet;
     438            fetchPrimitives(nodes,OsmPrimitiveType.NODE, progressMonitor);
     439            fetchPrimitives(ways,OsmPrimitiveType.WAY, progressMonitor);
     440            fetchPrimitives(relations,OsmPrimitiveType.RELATION, progressMonitor);
     441            return outputDataSet;
     442        } finally {
     443            progressMonitor.finishTask();
     444        }
    441445    }
    442446
    443447    /**
    444448     * replies the set of ids of all primitives for which a fetch request to the
    445449     * server was submitted but which are not available from the server (the server
    446450     * replied a return code of 404)
    447      * 
     451     *
    448452     * @return the set of ids of missing primitives
    449453     */
    450454    public Set<Long> getMissingPrimitives() {
  • src/org/openstreetmap/josm/io/OsmServerLocationReader.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.io.IOException;
    76import java.io.InputStream;
    87
    9 import org.openstreetmap.josm.Main;
    108import org.openstreetmap.josm.data.osm.DataSet;
    11 import org.xml.sax.SAXException;
     9import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1210
    1311public class OsmServerLocationReader extends OsmServerReader {
    1412
     
    2220     * Method to download OSM files from somewhere
    2321     */
    2422    @Override
    25     public DataSet parseOsm() throws OsmTransferException {
     23    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
    2624        InputStream in = null;
     25        progressMonitor.beginTask(tr("Contacting Server...", 10));
    2726        try {
    28             Main.pleaseWaitDlg.progress.setValue(0);
    29             Main.pleaseWaitDlg.currentAction.setText(tr("Contacting Server..."));
    30 
    31             in = getInputStreamRaw(url, Main.pleaseWaitDlg);
     27            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
    3228            if (in == null)
    3329                return null;
    34             Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
    35             return OsmReader.parseDataSet(in, Main.pleaseWaitDlg);
     30            progressMonitor.subTask(tr("Downloading OSM data..."));
     31            return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
    3632        } catch(OsmTransferException e) {
    3733            throw e;
    3834        } catch (Exception e) {
     
    4036                return null;
    4137            throw new OsmTransferException(e);
    4238        } finally {
     39            progressMonitor.finishTask();
    4340            try {
    4441                if (in != null) {
    4542                    in.close();
  • src/org/openstreetmap/josm/io/OsmServerObjectReader.java

     
    66import java.io.IOException;
    77import java.io.InputStream;
    88
    9 import org.openstreetmap.josm.Main;
    109import org.openstreetmap.josm.data.osm.DataSet;
    1110import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     11import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1212import org.xml.sax.SAXException;
    1313
    1414public class OsmServerObjectReader extends OsmServerReader {
     
    2929     * @throws IOException
    3030     */
    3131    @Override
    32     public DataSet parseOsm() throws OsmTransferException {
     32    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
     33        progressMonitor.beginTask("", 1);
    3334        try {
    34             Main.pleaseWaitDlg.progress.setValue(0);
    35             Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
     35            progressMonitor.subTask(tr("Downloading OSM data..."));
    3636            StringBuffer sb = new StringBuffer();
    3737            sb.append(type.getAPIName());
    3838            sb.append("/");
     
    4141                sb.append("/full");
    4242            }
    4343
    44             final InputStream in = getInputStream(sb.toString(), Main.pleaseWaitDlg);
     44            final InputStream in = getInputStream(sb.toString(), progressMonitor.createSubTaskMonitor(1, true));
    4545            if (in == null)
    4646                return null;
    47             Main.pleaseWaitDlg.currentAction.setText(tr("Downloading OSM data..."));
    48             final OsmReader osm = OsmReader.parseDataSetOsm(in,Main.pleaseWaitDlg);
     47            final OsmReader osm = OsmReader.parseDataSetOsm(in, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    4948            final DataSet data = osm.getDs();
    5049
    5150            in.close();
     
    6362            if (cancel)
    6463                return null;
    6564            throw new OsmTransferException(e);
     65        } finally {
     66            progressMonitor.finishTask();
    6667        }
    6768    }
    6869
  • src/org/openstreetmap/josm/io/OsmConnection.java

     
    1010import java.net.PasswordAuthentication;
    1111import java.nio.ByteBuffer;
    1212import java.nio.CharBuffer;
     13import java.nio.charset.CharacterCodingException;
    1314import java.nio.charset.Charset;
    1415import java.nio.charset.CharsetEncoder;
    15 import java.nio.charset.CharacterCodingException;
    1616
    1717import javax.swing.JCheckBox;
    1818import javax.swing.JLabel;
     
    125125    }
    126126
    127127    public void cancel() {
    128         Main.pleaseWaitDlg.currentAction.setText(tr("Aborting..."));
     128        //TODO
     129        //Main.pleaseWaitDlg.currentAction.setText(tr("Aborting..."));
    129130        cancel = true;
    130131        if (activeConnection != null) {
    131132            activeConnection.setConnectTimeout(100);
  • src/org/openstreetmap/josm/io/OsmReader.java

     
    1515import java.util.Map.Entry;
    1616import java.util.logging.Logger;
    1717
    18 import javax.swing.SwingUtilities;
    1918import javax.xml.parsers.ParserConfigurationException;
    2019import javax.xml.parsers.SAXParserFactory;
    2120
     
    3029import org.openstreetmap.josm.data.osm.User;
    3130import org.openstreetmap.josm.data.osm.Way;
    3231import org.openstreetmap.josm.data.osm.visitor.AddVisitor;
    33 import org.openstreetmap.josm.gui.PleaseWaitDialog;
     32import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3433import org.openstreetmap.josm.tools.DateUtils;
    3534import org.xml.sax.Attributes;
    3635import org.xml.sax.InputSource;
     
    6968
    7069    /**
    7170     * constructor (for private use only)
    72      * 
    73      * @see #parseDataSet(InputStream, DataSet, PleaseWaitDialog)
    74      * @see #parseDataSetOsm(InputStream, DataSet, PleaseWaitDialog)
     71     *
     72     * @see #parseDataSet(InputStream, DataSet, ProgressMonitor)
     73     * @see #parseDataSetOsm(InputStream, DataSet, ProgressMonitor)
    7574     */
    7675    private OsmReader() {
    7776    }
     
    453452     *      the Reference is not found here, Main.ds is searched and a copy of the
    454453     *  element found there is returned.
    455454     */
    456     public static DataSet parseDataSet(InputStream source, PleaseWaitDialog pleaseWaitDlg) throws SAXException, IOException {
    457         return parseDataSetOsm(source, pleaseWaitDlg).ds;
     455    public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws SAXException, IOException {
     456        return parseDataSetOsm(source, progressMonitor).ds;
    458457    }
    459458
    460     public static OsmReader parseDataSetOsm(InputStream source, final PleaseWaitDialog pleaseWaitDlg) throws SAXException, IOException {
     459    public static OsmReader parseDataSetOsm(InputStream source, ProgressMonitor progressMonitor) throws SAXException, IOException {
    461460        OsmReader osm = new OsmReader();
    462461
    463462        // phase 1: Parse nodes and read in raw ways
     
    469468            throw new SAXException(e1);
    470469        }
    471470
    472         SwingUtilities.invokeLater(
    473                 new Runnable() {
    474                     public void run() {
    475                         pleaseWaitDlg.currentAction.setText(tr("Prepare OSM data..."));
    476                         pleaseWaitDlg.setIndeterminate(true);
    477                     }
    478                 }
    479         );
    480 
    481         for (Node n : osm.nodes.values()) {
    482             osm.adder.visit(n);
    483         }
    484 
     471        progressMonitor.beginTask(tr("Prepare OSM data...", 2));
    485472        try {
    486             osm.createWays();
    487             osm.createRelations();
    488         } catch (NumberFormatException e) {
    489             e.printStackTrace();
    490             throw new SAXException(tr("Ill-formed node id"));
    491         }
     473            for (Node n : osm.nodes.values()) {
     474                osm.adder.visit(n);
     475            }
     476
     477            progressMonitor.worked(1);
    492478
    493         // clear all negative ids (new to this file)
    494         for (OsmPrimitive o : osm.ds.allPrimitives())
    495             if (o.id < 0) {
    496                 o.id = 0;
     479            try {
     480                osm.createWays();
     481                osm.createRelations();
     482            } catch (NumberFormatException e) {
     483                e.printStackTrace();
     484                throw new SAXException(tr("Ill-formed node id"));
    497485            }
    498486
    499         SwingUtilities.invokeLater(
    500                 new Runnable() {
    501                     public void run() {
    502                         pleaseWaitDlg.setIndeterminate(false);
    503                         pleaseWaitDlg.progress.setValue(0);
    504                     }
     487            // clear all negative ids (new to this file)
     488            for (OsmPrimitive o : osm.ds.allPrimitives())
     489                if (o.id < 0) {
     490                    o.id = 0;
    505491                }
    506         );
    507492
    508         return osm;
     493            return osm;
     494        } finally {
     495            progressMonitor.finishTask();
     496        }
    509497    }
    510498}
  • src/org/openstreetmap/josm/io/ProgressInputStream.java

     
    77import java.io.InputStream;
    88import java.net.URLConnection;
    99
    10 import org.openstreetmap.josm.gui.PleaseWaitDialog;
     10import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     11import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1112
    1213/**
    1314 * Read from an other reader and increment an progress counter while on the way.
     
    1819    private final InputStream in;
    1920    private int readSoFar = 0;
    2021    private int lastDialogUpdate = 0;
     22    private boolean sizeKnown;
    2123    private final URLConnection connection;
    22     private PleaseWaitDialog pleaseWaitDlg;
     24    private final ProgressMonitor progressMonitor;
    2325
    24     public ProgressInputStream(URLConnection con, PleaseWaitDialog pleaseWaitDlg) throws OsmTransferException {
     26    public ProgressInputStream(URLConnection con, ProgressMonitor progressMonitor) throws OsmTransferException {
    2527        this.connection = con;
     28        if (progressMonitor == null) {
     29            progressMonitor = NullProgressMonitor.INSTANCE;
     30        }
     31        this.progressMonitor = progressMonitor;
     32        progressMonitor.beginTask(tr("Contacting OSM Server..."), 1);
     33        progressMonitor.indeterminateSubTask(null);
    2634
    2735        try {
    2836            this.in = con.getInputStream();
     
    3240            throw new OsmTransferException(e);
    3341        }
    3442
    35         int contentLength = con.getContentLength();
    36         this.pleaseWaitDlg = pleaseWaitDlg;
    37         if (pleaseWaitDlg == null)
    38             return;
    39         if (contentLength > 0) {
    40             pleaseWaitDlg.progress.setMaximum(contentLength);
    41         } else {
    42             pleaseWaitDlg.progress.setMaximum(0);
     43        updateSize();
     44        if (!sizeKnown) {
     45            progressMonitor.indeterminateSubTask(tr("Downloading OSM data..."));
    4346        }
    44         pleaseWaitDlg.progress.setValue(0);
    4547    }
    4648
    4749    @Override public void close() throws IOException {
    4850        in.close();
     51        progressMonitor.finishTask();
    4952    }
    5053
    5154    @Override public int read(byte[] b, int off, int len) throws IOException {
    5255        int read = in.read(b, off, len);
    5356        if (read != -1) {
    5457            advanceTicker(read);
     58        } else {
     59            progressMonitor.finishTask();
    5560        }
    5661        return read;
    5762    }
     
    6065        int read = in.read();
    6166        if (read != -1) {
    6267            advanceTicker(1);
     68        } else {
     69            progressMonitor.finishTask();
    6370        }
    6471        return read;
    6572    }
     
    6976     * @param amount
    7077     */
    7178    private void advanceTicker(int amount) {
    72         if (pleaseWaitDlg == null)
    73             return;
    74 
    75         if (pleaseWaitDlg.progress.getMaximum() == 0 && connection.getContentLength() != -1) {
    76             pleaseWaitDlg.progress.setMaximum(connection.getContentLength());
    77         }
    78 
    7979        readSoFar += amount;
     80        updateSize();
    8081
    8182        if (readSoFar / 1024 != lastDialogUpdate) {
    8283            lastDialogUpdate++;
    83             String progStr = " "+readSoFar/1024+"/";
    84             progStr += (pleaseWaitDlg.progress.getMaximum()==0) ? "??? KB" : (pleaseWaitDlg.progress.getMaximum()/1024)+" KB";
    85             pleaseWaitDlg.progress.setValue(readSoFar);
    86 
    87             String cur = pleaseWaitDlg.currentAction.getText();
    88             int i = cur.indexOf(' ');
    89             if (i != -1) {
    90                 cur = cur.substring(0, i) + progStr;
     84            if (sizeKnown) {
     85                progressMonitor.setExtraText(readSoFar/1024 + " KB");
     86                progressMonitor.setTicks(readSoFar);
    9187            } else {
    92                 cur += progStr;
     88                progressMonitor.setExtraText("??? KB");
    9389            }
    94             pleaseWaitDlg.currentAction.setText(cur);
     90        }
     91    }
     92
     93    private void updateSize() {
     94        if (!sizeKnown && connection.getContentLength() > 0) {
     95            sizeKnown = true;
     96            progressMonitor.subTask(tr("Downloading OSM data..."));
     97            progressMonitor.setTicksCount(connection.getContentLength());
    9598        }
    9699    }
    97100}
  • src/org/openstreetmap/josm/io/OsmApi.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.awt.EventQueue;
    76import java.io.BufferedReader;
    87import java.io.BufferedWriter;
    98import java.io.IOException;
     
    3130import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3231import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    3332import org.openstreetmap.josm.data.osm.visitor.CreateOsmChangeVisitor;
     33import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3434import org.xml.sax.Attributes;
    3535import org.xml.sax.InputSource;
    3636import org.xml.sax.SAXException;
     
    278278     * @param comment the "commit comment" for the new changeset
    279279     * @throws OsmTransferException signifying a non-200 return code, or connection errors
    280280     */
    281     public void createChangeset(String comment) throws OsmTransferException {
    282         changeset = new Changeset();
    283         notifyStatusMessage(tr("Opening changeset..."));
    284         Properties sysProp = System.getProperties();
    285         Object ua = sysProp.get("http.agent");
    286         changeset.put("created_by", (ua == null) ? "JOSM" : ua.toString());
    287         changeset.put("comment", comment);
    288         createPrimitive(changeset);
     281    public void createChangeset(String comment, ProgressMonitor progressMonitor) throws OsmTransferException {
     282        progressMonitor.beginTask((tr("Opening changeset...")));
     283        try {
     284            changeset = new Changeset();
     285            Properties sysProp = System.getProperties();
     286            Object ua = sysProp.get("http.agent");
     287            changeset.put("created_by", (ua == null) ? "JOSM" : ua.toString());
     288            changeset.put("comment", comment);
     289            createPrimitive(changeset);
     290        } finally {
     291            progressMonitor.finishTask();
     292        }
    289293    }
    290294
    291295    /**
     
    293297     *
    294298     * @throws OsmTransferException if something goes wrong.
    295299     */
    296     public void stopChangeset() throws OsmTransferException {
    297         initialize();
    298         notifyStatusMessage(tr("Closing changeset..."));
    299         sendRequest("PUT", "changeset" + "/" + changeset.id + "/close", null);
    300         changeset = null;
     300    public void stopChangeset(ProgressMonitor progressMonitor) throws OsmTransferException {
     301        progressMonitor.beginTask(tr("Closing changeset..."));
     302        try {
     303            initialize();
     304            sendRequest("PUT", "changeset" + "/" + changeset.id + "/close", null);
     305            changeset = null;
     306        } finally {
     307            progressMonitor.finishTask();
     308        }
    301309    }
    302310
    303311    /**
     
    307315     * @return list of processed primitives
    308316     * @throws OsmTransferException if something is wrong
    309317     */
    310     public Collection<OsmPrimitive> uploadDiff(final Collection<OsmPrimitive> list) throws OsmTransferException {
     318    public Collection<OsmPrimitive> uploadDiff(final Collection<OsmPrimitive> list, ProgressMonitor progressMonitor) throws OsmTransferException {
    311319
    312         if (changeset == null)
    313             throw new OsmTransferException(tr("No changeset present for diff upload"));
     320        progressMonitor.beginTask("", list.size() * 2);
     321        try {
     322            if (changeset == null)
     323                throw new OsmTransferException(tr("No changeset present for diff upload"));
    314324
    315         initialize();
    316         final ArrayList<OsmPrimitive> processed = new ArrayList<OsmPrimitive>();
     325            initialize();
     326            final ArrayList<OsmPrimitive> processed = new ArrayList<OsmPrimitive>();
    317327
    318         CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset, OsmApi.this);
     328            CreateOsmChangeVisitor duv = new CreateOsmChangeVisitor(changeset, OsmApi.this);
    319329
    320         notifyStatusMessage(tr("Preparing..."));
    321         for (OsmPrimitive osm : list) {
    322             osm.visit(duv);
    323             notifyRelativeProgress(1);
    324         }
    325         notifyStatusMessage(tr("Uploading..."));
    326         setAutoProgressIndication(true);
     330            progressMonitor.subTask(tr("Preparing..."));
     331            for (OsmPrimitive osm : list) {
     332                osm.visit(duv);
     333                progressMonitor.worked(1);
     334            }
     335            progressMonitor.indeterminateSubTask(tr("Uploading..."));
    327336
    328         String diff = duv.getDocument();
    329         try {
    330             String diffresult = sendRequest("POST", "changeset/" + changeset.id + "/upload", diff);
    331             DiffResultReader.parseDiffResult(diffresult, list, processed, duv.getNewIdMap(), Main.pleaseWaitDlg);
    332         } catch(OsmTransferException e) {
    333             throw e;
    334         } catch(Exception e) {
    335             throw new OsmTransferException(e);
     337            String diff = duv.getDocument();
     338            try {
     339                String diffresult = sendRequest("POST", "changeset/" + changeset.id + "/upload", diff);
     340                DiffResultReader.parseDiffResult(diffresult, list, processed, duv.getNewIdMap(),
     341                        progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
     342            } catch(OsmTransferException e) {
     343                throw e;
     344            } catch(Exception e) {
     345                throw new OsmTransferException(e);
     346            }
     347
     348            return processed;
    336349        } finally {
    337             setAutoProgressIndication(false);
     350            progressMonitor.finishTask();
    338351        }
    339 
    340         return processed;
    341352    }
    342353
    343354
     
    467478    }
    468479
    469480    /**
    470      * notifies any listeners about the current state of this API. Currently just
    471      * displays the message in the global progress dialog, see {@see Main#pleaseWaitDlg}
    472      *
    473      * @param message a status message.
    474      */
    475     protected void notifyStatusMessage(String message) {
    476         Main.pleaseWaitDlg.currentAction.setText(message);
    477     }
    478 
    479     /**
    480      * notifies any listeners about the current about a relative progress. Currently just
    481      * increments the progress monitor in the in the global progress dialog, see {@see Main#pleaseWaitDlg}
    482      *
    483      * @param int the delta
    484      */
    485     protected void notifyRelativeProgress(int delta) {
    486         int current= Main.pleaseWaitDlg.progress.getValue();
    487         Main.pleaseWaitDlg.progress.setValue(current + delta);
    488     }
    489 
    490 
    491     protected void setAutoProgressIndication(final boolean enabled) {
    492         EventQueue.invokeLater(
    493                 new Runnable() {
    494                     public void run() {
    495                         Main.pleaseWaitDlg.setIndeterminate(enabled);
    496                     }
    497                 }
    498         );
    499     }
    500 
    501     /**
    502481     * returns the API capabilities; null, if the API is not initialized yet
    503      * 
     482     *
    504483     * @return the API capabilities
    505484     */
    506485    public Capabilities getCapabilities() {
  • src/org/openstreetmap/josm/io/OsmServerReader.java

     
    1313import java.util.zip.Inflater;
    1414import java.util.zip.InflaterInputStream;
    1515
    16 import javax.swing.JOptionPane;
    17 
    1816import org.openstreetmap.josm.Main;
    1917import org.openstreetmap.josm.data.osm.DataSet;
    20 import org.openstreetmap.josm.gui.PleaseWaitDialog;
     18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2119
    2220/**
    2321 * This DataReader reads directly from the REST API of the osm server.
     
    3937     * @param pleaseWaitDlg
    4038     * @return An reader reading the input stream (servers answer) or <code>null</code>.
    4139     */
    42     protected InputStream getInputStream(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws OsmTransferException  {
     40    protected InputStream getInputStream(String urlStr, ProgressMonitor progressMonitor) throws OsmTransferException  {
    4341        api.initialize();
    4442        urlStr = api.getBaseUrl() + urlStr;
    45         return getInputStreamRaw(urlStr, pleaseWaitDlg);
     43        return getInputStreamRaw(urlStr, progressMonitor);
    4644    }
    4745
    48     protected InputStream getInputStreamRaw(String urlStr, PleaseWaitDialog pleaseWaitDlg) throws OsmTransferException {
     46    protected InputStream getInputStreamRaw(String urlStr, ProgressMonitor progressMonitor) throws OsmTransferException {
    4947        URL url = null;
    5048        try {
    5149            url = new URL(urlStr);
     
    9694            }
    9795
    9896            String encoding = activeConnection.getContentEncoding();
    99             InputStream inputStream = new ProgressInputStream(activeConnection, pleaseWaitDlg);
     97            InputStream inputStream = new ProgressInputStream(activeConnection, progressMonitor);
    10098            if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
    10199                inputStream = new GZIPInputStream(inputStream);
    102100            }
     
    113111        }
    114112    }
    115113
    116     public abstract DataSet parseOsm() throws OsmTransferException;
     114    public abstract DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException;
    117115
    118116}
  • src/org/openstreetmap/josm/io/OsmServerBackreferenceReader.java

     
    77import java.util.ArrayList;
    88import java.util.Collection;
    99
    10 import org.openstreetmap.josm.Main;
    1110import org.openstreetmap.josm.data.osm.DataSet;
    1211import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1312import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    1413import org.openstreetmap.josm.data.osm.Relation;
    1514import org.openstreetmap.josm.data.osm.Way;
    1615import org.openstreetmap.josm.data.osm.visitor.MergeVisitor;
     16import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1717
    1818/**
    1919 * OsmServerBackreferenceReader fetches the primitives from the OSM server which
    2020 * refer to a specific primitive. For a {@see Node}, ways and relations are retrieved
    2121 * which refer to the node. For a {@see Way} or a {@see Relation}, only relations are
    2222 * read.
    23  * 
     23 *
    2424 * OsmServerBackreferenceReader uses the API calls <code>[node|way|relation]/#id/relations</code>
    2525 * and  <code>node/#id/ways</code> to retrieve the referring primitives. The default behaviour
    2626 * of these calls is to reply incomplete primitives only.
    27  * 
     27 *
    2828 * If you set {@see #setReadFull(boolean)} to true this reader uses a {@see MultiFetchServerObjectReader}
    2929 * to complete incomplete primitives.
    30  * 
     30 *
    3131 *
    3232 */
    3333public class OsmServerBackreferenceReader extends OsmServerReader {
     
    4141
    4242    /**
    4343     * constructor
    44      * 
     44     *
    4545     * @param primitive  the primitive to be read. Must not be null. primitive.id > 0 expected
    46      * 
     46     *
    4747     * @exception IllegalArgumentException thrown if primitive is null
    4848     * @exception IllegalArgumentException thrown if primitive.id <= 0
    4949     */
     
    5959
    6060    /**
    6161     * constructor
    62      * 
     62     *
    6363     * @param id  the id of the primitive. > 0 expected
    6464     * @param type the type of the primitive. Must not be null.
    65      * 
     65     *
    6666     * @exception IllegalArgumentException thrown if id <= 0
    6767     * @exception IllegalArgumentException thrown if type is null
    68      * 
     68     *
    6969     */
    7070    public OsmServerBackreferenceReader(long id, OsmPrimitiveType type) throws IllegalArgumentException   {
    7171        if (id <= 0)
     
    7979
    8080    /**
    8181     * constructor
    82      * 
     82     *
    8383     * @param id  the id of the primitive. > 0 expected
    8484     * @param type the type of the primitive. Must not be null.
    8585     * @param readFull true, if referers should be read fully (i.e. including their immediate children)
    86      * 
     86     *
    8787     */
    8888    public OsmServerBackreferenceReader(OsmPrimitive primitive, boolean readFull) {
    8989        this(primitive);
     
    9292
    9393    /**
    9494     * constructor
    95      * 
     95     *
    9696     * @param primitive the primitive whose referers are to be read
    9797     * @param readFull true, if referers should be read fully (i.e. including their immediate children)
    98      * 
     98     *
    9999     * @exception IllegalArgumentException thrown if id <= 0
    100100     * @exception IllegalArgumentException thrown if type is null
    101      * 
     101     *
    102102     */
    103103    public OsmServerBackreferenceReader(long id, OsmPrimitiveType type, boolean readFull) throws IllegalArgumentException  {
    104104        this(id, type);
     
    107107
    108108    /**
    109109     * Replies true if this reader also reads immediate children of referring primitives
    110      * 
     110     *
    111111     * @return true if this reader also reads immediate children of referring primitives
    112112     */
    113113    public boolean isReadFull() {
     
    116116
    117117    /**
    118118     * Set true if this reader should reads immediate children of referring primitives too. False, otherweise.
    119      * 
     119     *
    120120     * @param readFull true if this reader should reads immediate children of referring primitives too. False, otherweise.
    121121     */
    122122    public void setReadFull(boolean readFull) {
     
    125125
    126126    /**
    127127     * Reads referring ways from the API server and replies them in a {@see DataSet}
    128      * 
     128     *
    129129     * @return the data set
    130130     * @throws OsmTransferException
    131131     */
    132     protected DataSet getReferringWays() throws OsmTransferException {
     132    protected DataSet getReferringWays(ProgressMonitor progressMonitor) throws OsmTransferException {
    133133        InputStream in = null;
     134        progressMonitor.beginTask(null, 2);
    134135        try {
    135             Main.pleaseWaitDlg.progress.setValue(0);
    136             Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
     136            progressMonitor.indeterminateSubTask(tr("Contacting OSM Server..."));
    137137            StringBuffer sb = new StringBuffer();
    138138            sb.append(primitiveType.getAPIName())
    139139            .append("/").append(id).append("/ways");
    140140
    141             in = getInputStream(sb.toString(), Main.pleaseWaitDlg);
     141            in = getInputStream(sb.toString(), progressMonitor.createSubTaskMonitor(1, true));
    142142            if (in == null)
    143143                return null;
    144             Main.pleaseWaitDlg.currentAction.setText(tr("Downloading referring ways ..."));
    145             return OsmReader.parseDataSet(in,Main.pleaseWaitDlg);
     144            progressMonitor.subTask(tr("Downloading referring ways ..."));
     145            return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, true));
    146146        } catch(OsmTransferException e) {
    147147            throw e;
    148148        } catch (Exception e) {
     
    150150                return null;
    151151            throw new OsmTransferException(e);
    152152        } finally {
     153            progressMonitor.finishTask();
    153154            if (in != null) {
    154155                try {
    155156                    in.close();
     
    161162    /**
    162163
    163164     * Reads referring relations from the API server and replies them in a {@see DataSet}
    164      * 
     165     *
    165166     * @return the data set
    166167     * @throws OsmTransferException
    167168     */
    168     protected DataSet getReferringRelations() throws OsmTransferException {
     169    protected DataSet getReferringRelations(ProgressMonitor progressMonitor) throws OsmTransferException {
    169170        InputStream in = null;
     171        progressMonitor.beginTask(null, 2);
    170172        try {
    171             Main.pleaseWaitDlg.progress.setValue(0);
    172             Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
     173            progressMonitor.subTask(tr("Contacting OSM Server..."));
    173174            StringBuffer sb = new StringBuffer();
    174175            sb.append(primitiveType.getAPIName())
    175176            .append("/").append(id).append("/relations");
    176177
    177             in = getInputStream(sb.toString(), Main.pleaseWaitDlg);
     178            in = getInputStream(sb.toString(), progressMonitor.createSubTaskMonitor(1, true));
    178179            if (in == null)
    179180                return null;
    180             Main.pleaseWaitDlg.currentAction.setText(tr("Downloading referring relations ..."));
    181             return OsmReader.parseDataSet(in,Main.pleaseWaitDlg);
     181            progressMonitor.subTask(tr("Downloading referring relations ..."));
     182            return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, true));
    182183        } catch(OsmTransferException e) {
    183184            throw e;
    184185        } catch (Exception e) {
     
    186187                return null;
    187188            throw new OsmTransferException(e);
    188189        } finally {
     190            progressMonitor.finishTask();
    189191            if (in != null) {
    190192                try {
    191193                    in.close();
     
    199201     * Scans a dataset for incomplete primitives. Depending on the configuration of this reader
    200202     * incomplete primitives are read from the server with an individual <tt>/api/0.6/[way,relation]/#id/full</tt>
    201203     * request.
    202      * 
     204     *
    203205     * <ul>
    204206     *   <li>if this reader reads referers for an {@see Node}, referring ways are always
    205207     *     read individually from the server</li>
    206208     *   <li>if this reader reads referers for an {@see Way} or a {@see Relation}, referring relations
    207209     *    are only read fully if {@see #setReadFull(boolean)} is set to true.</li>
    208210     * </ul>
    209      * 
     211     *
    210212     * The method replies the modified dataset.
    211      * 
     213     *
    212214     * @param ds the original dataset
    213215     * @return the modified dataset
    214216     * @throws OsmTransferException thrown if an exception occurs.
    215217     */
    216     protected DataSet readIncompletePrimitives(DataSet ds) throws OsmTransferException {
    217         Collection<Way> waysToCheck = new ArrayList<Way>(ds.ways);
    218         if (isReadFull() ||primitiveType.equals(OsmPrimitiveType.NODE)) {
    219             for (Way way: waysToCheck) {
    220                 if (way.id > 0 && way.incomplete) {
    221                     OsmServerObjectReader reader = new OsmServerObjectReader(way.id, OsmPrimitiveType.from(way), true /* read full */);
    222                     DataSet wayDs = reader.parseOsm();
    223                     MergeVisitor visitor = new MergeVisitor(ds, wayDs);
    224                     visitor.merge();
     218    protected DataSet readIncompletePrimitives(DataSet ds, ProgressMonitor progressMonitor) throws OsmTransferException {
     219        progressMonitor.beginTask(null, 2);
     220        try {
     221            Collection<Way> waysToCheck = new ArrayList<Way>(ds.ways);
     222            if (isReadFull() ||primitiveType.equals(OsmPrimitiveType.NODE)) {
     223                for (Way way: waysToCheck) {
     224                    if (way.id > 0 && way.incomplete) {
     225                        OsmServerObjectReader reader = new OsmServerObjectReader(way.id, OsmPrimitiveType.from(way), true /* read full */);
     226                        DataSet wayDs = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
     227                        MergeVisitor visitor = new MergeVisitor(ds, wayDs);
     228                        visitor.merge();
     229                    }
    225230                }
    226231            }
    227         }
    228         if (isReadFull()) {
    229             Collection<Relation> relationsToCheck  = new ArrayList<Relation>(ds.relations);
    230             for (Relation relation: relationsToCheck) {
    231                 if (relation.id > 0 && relation.incomplete) {
    232                     OsmServerObjectReader reader = new OsmServerObjectReader(relation.id, OsmPrimitiveType.from(relation), true /* read full */);
    233                     DataSet wayDs = reader.parseOsm();
    234                     MergeVisitor visitor = new MergeVisitor(ds, wayDs);
    235                     visitor.merge();
     232            if (isReadFull()) {
     233                Collection<Relation> relationsToCheck  = new ArrayList<Relation>(ds.relations);
     234                for (Relation relation: relationsToCheck) {
     235                    if (relation.id > 0 && relation.incomplete) {
     236                        OsmServerObjectReader reader = new OsmServerObjectReader(relation.id, OsmPrimitiveType.from(relation), true /* read full */);
     237                        DataSet wayDs = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
     238                        MergeVisitor visitor = new MergeVisitor(ds, wayDs);
     239                        visitor.merge();
     240                    }
    236241                }
    237242            }
     243            return ds;
     244        } finally {
     245            progressMonitor.finishTask();
    238246        }
    239         return ds;
    240247    }
    241248
    242249    /**
    243250     * Reads the referring primitives from the OSM server, parses them and
    244251     * replies them as {@see DataSet}
    245      * 
     252     *
    246253     * @return the dataset with the referring primitives
    247254     * @exception OsmTransferException thrown if an error occurs while communicating with the server
    248255     */
    249256    @Override
    250     public DataSet parseOsm() throws OsmTransferException {
    251         DataSet ret = new DataSet();
    252         if (primitiveType.equals(OsmPrimitiveType.NODE)) {
    253             DataSet ds = getReferringWays();
     257    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
     258        progressMonitor.beginTask(null, 3);
     259        try {
     260            DataSet ret = new DataSet();
     261            if (primitiveType.equals(OsmPrimitiveType.NODE)) {
     262                DataSet ds = getReferringWays(progressMonitor.createSubTaskMonitor(1, false));
     263                MergeVisitor visitor = new MergeVisitor(ret,ds);
     264                visitor.merge();
     265                ret = visitor.getMyDataSet();
     266            }
     267            DataSet ds = getReferringRelations(progressMonitor.createSubTaskMonitor(1, false));
    254268            MergeVisitor visitor = new MergeVisitor(ret,ds);
    255269            visitor.merge();
    256270            ret = visitor.getMyDataSet();
     271            readIncompletePrimitives(ret, progressMonitor.createSubTaskMonitor(1, false));
     272            return ret;
     273        } finally {
     274            progressMonitor.finishTask();
    257275        }
    258         DataSet ds = getReferringRelations();
    259         MergeVisitor visitor = new MergeVisitor(ret,ds);
    260         visitor.merge();
    261         ret = visitor.getMyDataSet();
    262         readIncompletePrimitives(ret);
    263         return ret;
    264276    }
    265277}
  • src/org/openstreetmap/josm/io/OsmImporter.java

     
    1010import java.io.IOException;
    1111import java.io.InputStream;
    1212
    13 import javax.swing.JOptionPane;
    14 
    1513import org.openstreetmap.josm.Main;
    1614import org.openstreetmap.josm.actions.ExtensionFileFilter;
    1715import org.openstreetmap.josm.data.osm.DataSet;
    1816import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     17import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    1918import org.xml.sax.SAXException;
    2019
    2120public class OsmImporter extends FileImporter {
     
    4544    }
    4645
    4746    protected void importData(InputStream in, File associatedFile) throws SAXException, IOException {
    48         OsmReader osm = OsmReader.parseDataSetOsm(in,Main.pleaseWaitDlg);
     47        OsmReader osm = OsmReader.parseDataSetOsm(in, NullProgressMonitor.INSTANCE);
    4948        DataSet dataSet = osm.getDs();
    5049        OsmDataLayer layer = new OsmDataLayer(dataSet, associatedFile.getName(), associatedFile);
    5150        Main.main.addLayer(layer);
  • src/org/openstreetmap/josm/io/OsmServerWriter.java

     
    1212import org.openstreetmap.josm.actions.UploadAction;
    1313import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1414import org.openstreetmap.josm.data.osm.visitor.NameVisitor;
     15import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1516
    1617/**
    1718 * Class that uploads all changes to the osm server.
     
    8081     * @param apiVersion version of the data set
    8182     * @param primitives list of objects to send
    8283     */
    83     public void uploadOsm(String apiVersion, Collection<OsmPrimitive> primitives) throws OsmTransferException {
     84    public void uploadOsm(String apiVersion, Collection<OsmPrimitive> primitives, ProgressMonitor progressMonitor) throws OsmTransferException {
    8485        processed = new LinkedList<OsmPrimitive>();
    8586
    8687        api.initialize();
    8788
    88         Main.pleaseWaitDlg.progress.setMaximum(primitives.size());
    89         Main.pleaseWaitDlg.progress.setValue(0);
     89        progressMonitor.beginTask("");
    9090
    91         // check whether we can use changeset
    92         //
    93         boolean canUseChangeset = api.hasChangesetSupport();
    94         boolean useChangeset = Main.pref.getBoolean("osm-server.atomic-upload", apiVersion.compareTo("0.6")>=0);
    95         if (useChangeset && ! canUseChangeset) {
    96             System.out.println(tr("WARNING: preference ''{0}'' or api version ''{1}'' of dataset requires to use changesets, but API is not able to handle them. Ignoring changesets.", "osm-server.atomic-upload", apiVersion));
    97             useChangeset = false;
    98         }
     91        try {
    9992
    100         if (useChangeset) {
    101             // upload everything in one changeset
     93            // check whether we can use changeset
    10294            //
    103             try {
    104                 api.createChangeset(getChangesetComment());
    105                 processed.addAll(api.uploadDiff(primitives));
    106             } catch(OsmTransferException e) {
    107                 throw e;
    108             } finally {
     95            boolean canUseChangeset = api.hasChangesetSupport();
     96            boolean useChangeset = Main.pref.getBoolean("osm-server.atomic-upload", apiVersion.compareTo("0.6")>=0);
     97            if (useChangeset && ! canUseChangeset) {
     98                System.out.println(tr("WARNING: preference ''{0}'' or api version ''{1}'' of dataset requires to use changesets, but API is not able to handle them. Ignoring changesets.", "osm-server.atomic-upload", apiVersion));
     99                useChangeset = false;
     100            }
     101
     102            if (useChangeset) {
     103                // upload everything in one changeset
     104                //
    109105                try {
    110                     if (canUseChangeset) {
    111                         api.stopChangeset();
     106                    api.createChangeset(getChangesetComment(), progressMonitor.createSubTaskMonitor(0, false));
     107                    processed.addAll(api.uploadDiff(primitives, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)));
     108                } catch(OsmTransferException e) {
     109                    throw e;
     110                } finally {
     111                    try {
     112                        if (canUseChangeset) {
     113                            api.stopChangeset(progressMonitor.createSubTaskMonitor(0, false));
     114                        }
     115                    } catch (Exception ee) {
     116                        ee.printStackTrace();
     117                        // ignore nested exception
    112118                    }
    113                 } catch (Exception ee) {
    114                     ee.printStackTrace();
    115                     // ignore nested exception
    116119                }
    117             }
    118         } else {
    119             // upload changes individually (90% of code is for the status display...)
    120             //
    121             api.createChangeset(getChangesetComment());
    122             NameVisitor v = new NameVisitor();
    123             uploadStartTime = System.currentTimeMillis();
    124             for (OsmPrimitive osm : primitives) {
    125                 osm.visit(v);
    126                 int progress = Main.pleaseWaitDlg.progress.getValue();
    127                 String time_left_str = timeLeft(progress, primitives.size());
    128                 Main.pleaseWaitDlg.currentAction.setText(
    129                         tr("{0}% ({1}/{2}), {3} left. Uploading {4}: {5} (id: {6})",
    130                                 Math.round(100.0*progress/primitives.size()), progress,
    131                                 primitives.size(), time_left_str, tr(v.className), v.name, osm.id));
    132                 makeApiRequest(osm);
    133                 processed.add(osm);
    134                 Main.pleaseWaitDlg.progress.setValue(progress+1);
     120            } else {
     121                // upload changes individually (90% of code is for the status display...)
     122                //
     123                progressMonitor.setTicksCount(primitives.size());
     124                api.createChangeset(getChangesetComment(), progressMonitor.createSubTaskMonitor(0, false));
     125                NameVisitor v = new NameVisitor();
     126                uploadStartTime = System.currentTimeMillis();
     127                for (OsmPrimitive osm : primitives) {
     128                    osm.visit(v);
     129                    int progress = progressMonitor.getTicks();
     130                    String time_left_str = timeLeft(progress, primitives.size());
     131                    progressMonitor.subTask(
     132                            tr("{0}% ({1}/{2}), {3} left. Uploading {4}: {5} (id: {6})",
     133                                    Math.round(100.0*progress/primitives.size()), progress,
     134                                    primitives.size(), time_left_str, tr(v.className), v.name, osm.id));
     135                    makeApiRequest(osm);
     136                    processed.add(osm);
     137                    progressMonitor.worked(1);
     138                }
     139                api.stopChangeset(progressMonitor.createSubTaskMonitor(0, false));
    135140            }
    136             api.stopChangeset();
     141        } finally {
     142            progressMonitor.finishTask();
    137143        }
    138144    }
    139145
  • src/org/openstreetmap/josm/io/DiffResultReader.java

     
    1717import org.openstreetmap.josm.data.osm.Relation;
    1818import org.openstreetmap.josm.data.osm.Way;
    1919import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    20 import org.openstreetmap.josm.gui.PleaseWaitDialog;
     20import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2121import org.xml.sax.Attributes;
    2222import org.xml.sax.InputSource;
    2323import org.xml.sax.SAXException;
     
    6363    /**
    6464     * Parse the given input source and return the dataset.
    6565     */
    66     public static void parseDiffResult(String source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, PleaseWaitDialog pleaseWaitDlg)
     66    public static void parseDiffResult(String source, Collection<OsmPrimitive> osm, Collection<OsmPrimitive> processed, Map<OsmPrimitive,Long> newIdMap, ProgressMonitor progressMonitor)
    6767    throws SAXException, IOException {
    6868
    69        DiffResultReader drr = new DiffResultReader();
    70        drr.processed = processed;
    71        drr.newIdMap = newIdMap;
    72        InputSource inputSource = new InputSource(new StringReader(source));
    73        try {
    74            SAXParserFactory.newInstance().newSAXParser().parse(inputSource, drr.new Parser());
    75        } catch (ParserConfigurationException e1) {
    76            e1.printStackTrace(); // broken SAXException chaining
    77            throw new SAXException(e1);
    78        }
     69        progressMonitor.beginTask(tr("Preparing data..."));
     70        try {
    7971
    80        if (pleaseWaitDlg != null) {
    81            pleaseWaitDlg.progress.setValue(0);
    82            pleaseWaitDlg.currentAction.setText(tr("Preparing data..."));
    83        }
     72            DiffResultReader drr = new DiffResultReader();
     73            drr.processed = processed;
     74            drr.newIdMap = newIdMap;
     75            InputSource inputSource = new InputSource(new StringReader(source));
     76            try {
     77                SAXParserFactory.newInstance().newSAXParser().parse(inputSource, drr.new Parser());
     78            } catch (ParserConfigurationException e1) {
     79                e1.printStackTrace(); // broken SAXException chaining
     80                throw new SAXException(e1);
     81            }
    8482
    85        for (OsmPrimitive p : osm) {
    86            //System.out.println("old: "+ p);
    87            p.visit(drr);
    88            //System.out.println("new: "+ p);
    89            //System.out.println("");
    90        }
     83            for (OsmPrimitive p : osm) {
     84                //System.out.println("old: "+ p);
     85                p.visit(drr);
     86                //System.out.println("new: "+ p);
     87                //System.out.println("");
     88            }
     89        } finally {
     90            progressMonitor.finishTask();
     91        }
    9192    }
    9293
    9394    public void visit(Node n) {
  • src/org/openstreetmap/josm/io/OsmServerHistoryReader.java

     
    66import java.io.IOException;
    77import java.io.InputStream;
    88
    9 import org.openstreetmap.josm.Main;
    109import org.openstreetmap.josm.data.osm.DataSet;
    1110import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    1211import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
     12import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1313import org.xml.sax.SAXException;
    1414
    1515import sun.reflect.generics.reflectiveObjects.NotImplementedException;
    1616
    1717/**
    1818 * Reads the history of an {@see OsmPrimitive} from the OSM API server.
    19  * 
     19 *
    2020 */
    2121public class OsmServerHistoryReader extends OsmServerReader {
    2222
     
    2525
    2626    /**
    2727     * constructor
    28      * 
     28     *
    2929     * @param type the type of the primitive whose history is to be fetched from the server.
    3030     *   Must not be null.
    3131     * @param id the id of the primitive
    32      * 
     32     *
    3333     *  @exception IllegalArgumentException thrown, if type is null
    3434     */
    3535    public OsmServerHistoryReader(OsmPrimitiveType type, long id) throws IllegalArgumentException {
     
    4343
    4444    /**
    4545     * don't use - not implemented!
    46      * 
     46     *
    4747     * @exception NotImplementedException
    4848     */
    4949    @Override
    50     public DataSet parseOsm() throws OsmTransferException {
     50    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
    5151        throw new NotImplementedException();
    5252    }
    5353
    5454    /**
    5555     * Fetches the history from the OSM API and parses it
    56      * 
     56     *
    5757     * @return the data set with the parsed history data
    5858     * @throws OsmTransferException thrown, if an exception occurs
    5959     */
    60     public HistoryDataSet parseHistory() throws OsmTransferException {
     60    public HistoryDataSet parseHistory(ProgressMonitor progressMonitor) throws OsmTransferException {
    6161        InputStream in = null;
     62        progressMonitor.beginTask("");
    6263        try {
    63             Main.pleaseWaitDlg.progress.setValue(0);
    64             Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
     64            progressMonitor.indeterminateSubTask(tr("Contacting OSM Server..."));
    6565            StringBuffer sb = new StringBuffer();
    6666            sb.append(primitiveType.getAPIName())
    6767            .append("/").append(id).append("/history");
    6868
    69             in = getInputStream(sb.toString(), Main.pleaseWaitDlg);
     69            in = getInputStream(sb.toString(), progressMonitor.createSubTaskMonitor(1, true));
    7070            if (in == null)
    7171                return null;
    72             Main.pleaseWaitDlg.currentAction.setText(tr("Downloading history..."));
     72            progressMonitor.indeterminateSubTask(tr("Downloading history..."));
    7373            final OsmHistoryReader reader = new OsmHistoryReader(in);
    74             HistoryDataSet data = reader.parse(Main.pleaseWaitDlg);
     74            HistoryDataSet data = reader.parse(progressMonitor.createSubTaskMonitor(1, true));
    7575            return data;
    7676        } catch(OsmTransferException e) {
    7777            throw e;
     
    8080                return null;
    8181            throw new OsmTransferException(e);
    8282        } finally {
     83            progressMonitor.finishTask();
    8384            if (in != null) {
    8485                try {
    8586                    in.close();
  • src/org/openstreetmap/josm/io/OsmHistoryReader.java

     
    1717import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
    1818import org.openstreetmap.josm.data.osm.history.HistoryRelation;
    1919import org.openstreetmap.josm.data.osm.history.HistoryWay;
    20 import org.openstreetmap.josm.gui.PleaseWaitDialog;
     20import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2121import org.openstreetmap.josm.tools.DateUtils;
    2222import org.xml.sax.Attributes;
    2323import org.xml.sax.InputSource;
     
    3131 * It is slightly different from {@see OsmReader} because we don't build an internal graph of
    3232 * {@see OsmPrimitive}s. We use objects derived from {@see HistoryOsmPrimitive} instead and we
    3333 * keep the data in a dedicated {@see HistoryDataSet}.
    34  * 
     34 *
    3535 */
    3636public class OsmHistoryReader {
    3737
     
    209209        data = new HistoryDataSet();
    210210    }
    211211
    212     public HistoryDataSet parse(PleaseWaitDialog dialog) throws SAXException, IOException {
     212    public HistoryDataSet parse(ProgressMonitor progressMonitor) throws SAXException, IOException {
    213213        InputSource inputSource = new InputSource(new InputStreamReader(in, "UTF-8"));
    214         dialog.currentAction.setText("Parsing OSM history data ...");
     214        progressMonitor.beginTask(tr("Parsing OSM history data ..."));
    215215        try {
    216216            SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new Parser());
    217217        } catch (ParserConfigurationException e1) {
    218218            e1.printStackTrace(); // broken SAXException chaining
    219219            throw new SAXException(e1);
     220        } finally {
     221            progressMonitor.finishTask();
    220222        }
    221223        return data;
    222224    }
  • src/org/openstreetmap/josm/actions/UploadAction.java

     
    3030import org.openstreetmap.josm.gui.historycombobox.SuggestingJHistoryComboBox;
    3131import org.openstreetmap.josm.gui.layer.Layer;
    3232import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
     33import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3334import org.openstreetmap.josm.io.OsmApi;
    3435import org.openstreetmap.josm.io.OsmApiException;
    3536import org.openstreetmap.josm.io.OsmApiInitializationException;
     
    160161
    161162    /**
    162163     * Refreshes the enabled state
    163      * 
     164     *
    164165     */
    165166    protected void refreshEnabled() {
    166167        setEnabled(Main.main != null
     
    229230
    230231            @Override protected void realRun() throws SAXException, IOException {
    231232                try {
    232                     server.uploadOsm(Main.ds.version, all);
     233                    server.uploadOsm(Main.ds.version, all, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    233234                    Main.main.createOrGetEditLayer().cleanData(server.processed, !add.isEmpty());
    234235                } catch (Exception sxe) {
    235236                    if (uploadCancelled) {
  • src/org/openstreetmap/josm/actions/DownloadAction.java

     
    5959                for (DownloadTask task : dialog.downloadTasks) {
    6060                    Main.pref.put("download."+task.getPreferencesSuffix(), task.getCheckBox().isSelected());
    6161                    if (task.getCheckBox().isSelected()) {
    62                         task.download(this, dialog.minlat, dialog.minlon, dialog.maxlat, dialog.maxlon);
     62                        task.download(this, dialog.minlat, dialog.minlon, dialog.maxlat, dialog.maxlon, null);
    6363                        finish = true;
    6464                    }
    6565                }
  • src/org/openstreetmap/josm/actions/UpdateSelectionAction.java

     
    33
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    6 import java.awt.EventQueue;
    76import java.awt.event.ActionEvent;
    87import java.awt.event.KeyEvent;
    98import java.io.IOException;
     
    2019import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    2120import org.openstreetmap.josm.gui.layer.Layer;
    2221import org.openstreetmap.josm.gui.layer.Layer.LayerChangeListener;
     22import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     23import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2324import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
    2425import org.openstreetmap.josm.io.OsmApi;
    2526import org.openstreetmap.josm.io.OsmTransferException;
     
    2829
    2930/**
    3031 * This action synchronizes a set of primitives with their state on the server.
    31  * 
     32 *
    3233 *
    3334 */
    3435public class UpdateSelectionAction extends JosmAction implements SelectionChangedListener, LayerChangeListener {
    3536
    3637    /**
    3738     * handle an exception thrown because a primitive was deleted on the server
    38      * 
     39     *
    3940     * @param id the primitive id
    4041     */
    4142    protected void handlePrimitiveGoneException(long id) {
     
    4344        reader.append(Main.main.createOrGetEditLayer().data,id);
    4445        DataSet ds = null;
    4546        try {
    46             ds = reader.parseOsm();
     47            ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
    4748        } catch(Exception e) {
    4849            handleUpdateException(e);
    4950            return;
     
    5455
    5556    /**
    5657     * handle an exception thrown during updating a primitive
    57      * 
     58     *
    5859     * @param id the id of the primitive
    5960     * @param e the exception
    6061     */
     
    7172    /**
    7273     * handles an exception case: primitive with id <code>id</code> is not in the current
    7374     * data set
    74      * 
     75     *
    7576     * @param id the primitive id
    7677     */
    7778    protected void handleMissingPrimitive(long id) {
     
    8687    /**
    8788     * Updates the data for for the {@see OsmPrimitive}s in <code>selection</code>
    8889     * with the data currently kept on the server.
    89      * 
     90     *
    9091     * @param selection a collection of {@see OsmPrimitive}s to update
    91      * 
     92     *
    9293     */
    9394    public void updatePrimitives(final Collection<OsmPrimitive> selection) {
    9495
     
    101102            private boolean cancelled;
    102103            Exception lastException;
    103104
    104             protected void setIndeterminateEnabled(final boolean enabled) {
    105                 EventQueue.invokeLater(
    106                         new Runnable() {
    107                             public void run() {
    108                                 Main.pleaseWaitDlg.setIndeterminate(enabled);
    109                             }
    110                         }
    111                 );
    112             }
    113 
    114105            public UpdatePrimitiveTask() {
    115106                super("Update primitives", false /* don't ignore exception*/);
    116107                cancelled = false;
     
    150141
    151142            @Override
    152143            protected void realRun() throws SAXException, IOException, OsmTransferException {
    153                 setIndeterminateEnabled(true);
     144                progressMonitor.indeterminateSubTask("");
    154145                try {
    155146                    MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
    156147                    reader.append(selection);
    157                     ds = reader.parseOsm();
     148                    ds = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    158149                } catch(Exception e) {
    159150                    if (cancelled)
    160151                        return;
    161152                    lastException = e;
    162                 } finally {
    163                     setIndeterminateEnabled(false);
    164153                }
    165154            }
    166155        }
     
    171160    /**
    172161     * Updates the data for for the {@see OsmPrimitive}s with id <code>id</code>
    173162     * with the data currently kept on the server.
    174      * 
     163     *
    175164     * @param id  the id of a primitive in the {@see DataSet} of the current edit layser
    176      * 
     165     *
    177166     */
    178167    public void updatePrimitive(long id) {
    179168        OsmPrimitive primitive = Main.map.mapView.getEditLayer().data.getPrimitiveById(id);
     
    201190
    202191    /**
    203192     * Refreshes the enabled state
    204      * 
     193     *
    205194     */
    206195    protected void refreshEnabled() {
    207196        setEnabled(Main.main != null
  • src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java

     
    1515import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    1616import org.openstreetmap.josm.gui.layer.GpxLayer;
    1717import org.openstreetmap.josm.gui.layer.Layer;
     18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    1819import org.openstreetmap.josm.io.BoundingBoxDownloader;
    1920import org.xml.sax.SAXException;
    2021
     
    2526        private BoundingBoxDownloader reader;
    2627        private GpxData rawData;
    2728        private final boolean newLayer;
    28         private String msg = "";
    2929
    30         public Task(boolean newLayer, BoundingBoxDownloader reader, boolean silent, String msg) {
     30        public Task(boolean newLayer, BoundingBoxDownloader reader, ProgressMonitor progressMonitor) {
    3131            super(tr("Downloading GPS data"));
    32             this.msg = msg;
    3332            this.reader = reader;
    3433            this.newLayer = newLayer;
    35             this.silent = silent;
    3634        }
    3735
    3836        @Override public void realRun() throws IOException, SAXException {
    39             Main.pleaseWaitDlg.setCustomText(msg);
    40             rawData = reader.parseRawGps();
     37            rawData = reader.parseRawGps(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    4138        }
    4239
    4340        @Override protected void finish() {
     
    5148                Main.main.addLayer(layer);
    5249            else
    5350                x.mergeFrom(layer);
    54 
    55             Main.pleaseWaitDlg.setCustomText("");
    5651        }
    5752
    5853        private Layer findMergeLayer() {
     
    7166        @Override protected void cancel() {
    7267            if (reader != null)
    7368                reader.cancel();
    74             Main.pleaseWaitDlg.cancel.setEnabled(false);
    7569        }
    7670    }
    7771
    7872    private JCheckBox checkBox = new JCheckBox(tr("Raw GPS data"));
    7973
    8074    public void download(DownloadAction action, double minlat, double minlon,
    81             double maxlat, double maxlon) {
    82         download(action, minlat, minlon, maxlat, maxlon, false, "");
    83     }
    84 
    85     public void download(DownloadAction action, double minlat, double minlon,
    86             double maxlat, double maxlon, boolean silent, String message) {
     75            double maxlat, double maxlon, ProgressMonitor progressMonitor) {
    8776        Task t = new Task(action.dialog.newLayer.isSelected(),
    88                 new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon),
    89                 silent,
    90                 message);
     77                new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon), progressMonitor);
    9178        // We need submit instead of execute so we can wait for it to finish and get the error
    9279        // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
    9380        task = Main.worker.submit(t, t);
     
    115102
    116103        try {
    117104            Task t = task.get();
    118             return t.errorMessage == null
     105            return t.getProgressMonitor().getErrorMessage() == null
    119106                ? ""
    120                 : t.errorMessage;
     107                : t.getProgressMonitor().getErrorMessage();
    121108        } catch (Exception e) {
    122109            return "";
    123110        }
  • src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java

     
    1717import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    1818import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    1919import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     20import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     21import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2022import org.openstreetmap.josm.io.BoundingBoxDownloader;
    2123import org.openstreetmap.josm.io.OsmServerLocationReader;
    2224import org.openstreetmap.josm.io.OsmServerReader;
     
    3739        private OsmServerReader reader;
    3840        private DataSet dataSet;
    3941        private boolean newLayer;
    40         private String msg = "";
    4142
    42         public Task(boolean newLayer, OsmServerReader reader, boolean silent, String msg) {
    43             super(tr("Downloading data"));
    44             this.msg = msg;
     43        public Task(boolean newLayer, OsmServerReader reader, ProgressMonitor progressMonitor) {
     44            super(tr("Downloading data"), progressMonitor, false);
    4545            this.reader = reader;
    4646            this.newLayer = newLayer;
    47             this.silent = silent;
    4847        }
    4948
    5049        @Override public void realRun() throws IOException, SAXException, OsmTransferException {
    51             Main.pleaseWaitDlg.setCustomText(msg);
    52             dataSet = reader.parseOsm();
     50            dataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    5351        }
    5452
    5553        @Override protected void finish() {
    5654            if (dataSet == null)
    5755                return; // user canceled download or error occurred
    5856            if (dataSet.allPrimitives().isEmpty()) {
    59                 // If silent is set to true, we don't want to see information messages
    60                 if(!silent) {
    61                     errorMessage = tr("No data imported.");
    62                 }
     57                progressMonitor.setErrorMessage(tr("No data imported."));
    6358                // need to synthesize a download bounds lest the visual indication of downloaded
    6459                // area doesn't work
    6560                dataSet.dataSources.add(new DataSource(currentBounds, "OpenStreetMap server"));
     
    7166            } else {
    7267                Main.main.createOrGetEditLayer().mergeFrom(dataSet);
    7368            }
    74 
    75             Main.pleaseWaitDlg.setCustomText("");
    7669        }
    7770
    7871        @Override protected void cancel() {
    7972            if (reader != null) {
    8073                reader.cancel();
    8174            }
    82             Main.pleaseWaitDlg.cancel.setEnabled(false);
    8375        }
    8476    }
    8577    private JCheckBox checkBox = new JCheckBox(tr("OpenStreetMap data"), true);
     
    9385    }
    9486
    9587    public void download(DownloadAction action, double minlat, double minlon,
    96             double maxlat, double maxlon, boolean silent, String message) {
     88            double maxlat, double maxlon, ProgressMonitor progressMonitor) {
    9789        // Swap min and max if user has specified them the wrong way round
    9890        // (easy to do if you are crossing 0, for example)
    9991        // FIXME should perhaps be done in download dialog?
     
    108100        && (action.dialog == null || action.dialog.newLayer.isSelected());
    109101
    110102        Task t = new Task(newLayer,
    111                 new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon),
    112                 silent,
    113                 message);
     103                new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon), progressMonitor);
    114104        currentBounds = new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon));
    115105        // We need submit instead of execute so we can wait for it to finish and get the error
    116106        // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
    117107        task = Main.worker.submit(t, t);
    118108    }
    119109
    120     public void download(DownloadAction action, double minlat, double minlon,
    121             double maxlat, double maxlon) {
    122         download(action, minlat, minlon, maxlat, maxlon, false, "");
    123     }
    124 
    125110    /**
    126111     * Loads a given URL from the OSM Server
    127112     * @param True if the data should be saved to a new layer
     
    130115    public void loadUrl(boolean new_layer, String url) {
    131116        Task t = new Task(new_layer,
    132117                new OsmServerLocationReader(url),
    133                 false,
    134         "");
     118                NullProgressMonitor.INSTANCE);
    135119        task = Main.worker.submit(t, t);
    136120    }
    137121
     
    153137
    154138        try {
    155139            Task t = task.get();
    156             return t.errorMessage == null
     140            return t.getProgressMonitor().getErrorMessage() == null
    157141            ? ""
    158                     : t.errorMessage;
     142                    : t.getProgressMonitor().getErrorMessage();
    159143        } catch (Exception e) {
    160144            return "";
    161145        }
  • src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java

     
    2222import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    2323import org.openstreetmap.josm.gui.layer.Layer;
    2424import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     25import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
     26import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2527
    2628/**
    2729 * This class encapsulates the downloading of several bounding boxes that would otherwise be too
     
    3234 */
    3335public class DownloadOsmTaskList implements Runnable {
    3436    private List<DownloadTask> osmTasks = new LinkedList<DownloadTask>();
     37    private ProgressMonitor progressMonitor;
    3538
    3639    /**
    3740     * Downloads a list of areas from the OSM Server
    3841     * @param newLayer Set to true if all areas should be put into a single new layer
    3942     * @param The List of Rectangle2D to download
    4043     */
    41     public void download(boolean newLayer, List<Rectangle2D> rects) {
     44    public void download(boolean newLayer, List<Rectangle2D> rects, ProgressMonitor progressMonitor) {
     45        this.progressMonitor = progressMonitor;
    4246        if(newLayer) {
    4347            Layer l = new OsmDataLayer(new DataSet(), OsmDataLayer.createNewName(), null);
    4448            Main.main.addLayer(l);
    4549            Main.map.mapView.setActiveLayer(l);
    4650        }
    4751
    48         int i = 0;
    49         for(Rectangle2D td : rects) {
    50             i++;
    51             DownloadTask dt = new DownloadOsmTask();
    52             dt.download(null, td.getMinY(), td.getMinX(), td.getMaxY(), td.getMaxX(), true,
    53                     tr("Download {0} of {1} ({2} left)", i, rects.size(), rects.size()-i));
    54             osmTasks.add(dt);
     52        progressMonitor.beginTask(null, rects.size());
     53        try {
     54            int i = 0;
     55            for(Rectangle2D td : rects) {
     56                i++;
     57                DownloadTask dt = new DownloadOsmTask();
     58                ProgressMonitor childProgress = progressMonitor.createSubTaskMonitor(1, false);
     59                childProgress.setSilent(true);
     60                childProgress.setCustomText(tr("Download {0} of {1} ({2} left)", i, rects.size(), rects.size()-i));
     61                dt.download(null, td.getMinY(), td.getMinX(), td.getMaxY(), td.getMaxX(), childProgress);
     62                osmTasks.add(dt);
     63            }
     64        } finally {
     65            // If we try to get the error message now the download task will never have been started
     66            // and we'd be stuck in a classical dead lock. Instead attach this to the worker and once
     67            // run() gets called all downloadTasks have finished and we can grab the error messages.
     68            Main.worker.execute(this);
    5569        }
    56 
    57         // If we try to get the error message now the download task will never have been started
    58         // and we'd be stuck in a classical dead lock. Instead attach this to the worker and once
    59         // run() gets called all downloadTasks have finished and we can grab the error messages.
    60         Main.worker.execute(this);
    6170    }
    6271
    6372    /**
     
    7180            rects.add(a.getBounds2D());
    7281        }
    7382
    74         download(newLayer, rects);
     83        download(newLayer, rects, NullProgressMonitor.INSTANCE);
    7584    }
    7685
    7786    /**
    7887     * Grabs and displays the error messages after all download threads have finished.
    7988     */
    8089    public void run() {
     90        progressMonitor.finishTask();
    8191        String errors = "";
    8292
    8393        for(DownloadTask dt : osmTasks) {
     
    108118    /**
    109119     * Updates the local state of a set of primitives (given by a set of primitive
    110120     * ids) with the state currently held on the server.
    111      * 
     121     *
    112122     * @param potentiallyDeleted a set of ids to check update from the server
    113123     */
    114124    protected void updatePotentiallyDeletedPrimitives(Set<Long> potentiallyDeleted) {
     
    134144     * deleted on the server. First prompts the user whether he wants to check
    135145     * the current state on the server. If yes, retrieves the current state on the server
    136146     * and checks whether the primitives are indeed deleted on the server.
    137      * 
     147     *
    138148     * @param potentiallyDeleted a set of primitives (given by their ids)
    139149     */
    140150    protected void handlePotentiallyDeletedPrimitives(Set<Long> potentiallyDeleted) {
     
    176186    /**
    177187     * replies true, if the primitive with id <code>id</code> was downloaded into the
    178188     * dataset <code>ds</code>
    179      * 
     189     *
    180190     * @param id the id
    181191     * @param ds the dataset
    182192     * @return true, if the primitive with id <code>id</code> was downloaded into the
     
    190200    /**
    191201     * replies true, if the primitive with id <code>id</code> was downloaded into the
    192202     * dataset of one of the download tasks
    193      * 
     203     *
    194204     * @param id the id
    195205     * @return true, if the primitive with id <code>id</code> was downloaded into the
    196206     * dataset of one of the download tasks
    197      * 
     207     *
    198208     */
    199209    public boolean wasDownloaded(long id) {
    200210        for (DownloadTask task : osmTasks) {
     
    208218
    209219    /**
    210220     * Replies the set of primitive ids which have been downloaded by this task list
    211      * 
     221     *
    212222     * @return the set of primitive ids which have been downloaded by this task list
    213223     */
    214224    public Set<Long> getDownloadedIds() {
  • src/org/openstreetmap/josm/actions/search/SelectionWebsiteLoader.java

     
    3838        this.url = u;
    3939    }
    4040    @Override protected void realRun() {
    41         Main.pleaseWaitDlg.currentAction.setText(tr("Contact {0}...", url.getHost()));
     41        progressMonitor.setTicksCount(2);
    4242        sel = mode != SearchAction.SearchMode.remove ? new LinkedList<OsmPrimitive>() : Main.ds.allNonDeletedPrimitives();
    4343        try {
    4444            URLConnection con = url.openConnection();
    45             InputStream in = new ProgressInputStream(con, Main.pleaseWaitDlg);
    46             Main.pleaseWaitDlg.currentAction.setText(tr("Downloading..."));
     45            progressMonitor.subTask(tr("Contact {0}...", url.getHost()));
     46            InputStream in = new ProgressInputStream(con, progressMonitor.createSubTaskMonitor(1, true));
     47            progressMonitor.subTask(tr("Downloading..."));
    4748            Map<Long, String> ids = idReader.parseIds(in);
    4849            for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives()) {
    4950                if (ids.containsKey(osm.id) && osm.getClass().getName().toLowerCase().endsWith(ids.get(osm.id))) {
     
    5455                    }
    5556                }
    5657            }
     58            progressMonitor.worked(1);
    5759        } catch (IOException e) {
    5860            e.printStackTrace();
    5961            JOptionPane.showMessageDialog(Main.parent, tr("Could not read from URL: \"{0}\"",url));
  • src/org/openstreetmap/josm/Main.java

     
    1212import java.net.URI;
    1313import java.net.URISyntaxException;
    1414import java.util.Collection;
    15 import java.util.Locale;
    1615import java.util.Map;
    1716import java.util.StringTokenizer;
    1817import java.util.concurrent.ExecutorService;
     
    4140import org.openstreetmap.josm.gui.GettingStarted;
    4241import org.openstreetmap.josm.gui.MainMenu;
    4342import org.openstreetmap.josm.gui.MapFrame;
    44 import org.openstreetmap.josm.gui.PleaseWaitDialog;
    4543import org.openstreetmap.josm.gui.SplashScreen;
    4644import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    4745import org.openstreetmap.josm.gui.layer.Layer;
     
    9896    /**
    9997     * The dialog that gets displayed during background task execution.
    10098     */
    101     public static PleaseWaitDialog pleaseWaitDlg;
     99    //public static PleaseWaitDialog pleaseWaitDlg;
    102100
    103101    /**
    104102     * True, when in applet mode
     
    229227     * Replies the current edit layer. Creates one if no {@see OsmDataLayer}
    230228     * exists. Replies null, if the currently active layer isn't an instance
    231229     * of {@see OsmDataLayer}.
    232      * 
     230     *
    233231     * @return the current edit layer
    234232     */
    235233    public final OsmDataLayer createOrGetEditLayer() {
     
    241239
    242240    /**
    243241     * Replies true if this map view has an edit layer
    244      * 
     242     *
    245243     * @return true if this map view has an edit layer
    246244     */
    247245    public boolean hasEditLayer() {
     
    351349        if (bounds == null) {
    352350            bounds = !args.containsKey("no-maximize") ? new Rectangle(0,0,screenDimension.width,screenDimension.height) : new Rectangle(1000,740);
    353351        }
    354 
    355         // preinitialize a wait dialog for all early downloads (e.g. via command line)
    356         pleaseWaitDlg = new PleaseWaitDialog(null);
    357352    }
    358353
    359354    public void postConstructorProcessCmdLine(Map<String, Collection<String>> args) {
    360         // initialize the pleaseWaitDialog with the application as parent to handle focus stuff
    361         pleaseWaitDlg = new PleaseWaitDialog(parent);
    362 
    363355        if (args.containsKey("download")) {
    364356            for (String s : args.get("download")) {
    365357                downloadFromParamString(false, s);
     
    425417            } else {
    426418                //DownloadTask osmTask = main.menu.download.downloadTasks.get(0);
    427419                DownloadTask osmTask = new DownloadOsmTask();
    428                 osmTask.download(main.menu.download, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon());
     420                osmTask.download(main.menu.download, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon(), null);
    429421            }
    430422            return;
    431423        }
     
    443435        if (st.countTokens() == 4) {
    444436            try {
    445437                DownloadTask task = rawGps ? new DownloadGpsTask() : new DownloadOsmTask();
    446                 task.download(main.menu.download, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()));
     438                task.download(main.menu.download, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), null);
    447439                return;
    448440            } catch (final NumberFormatException e) {
    449441            }
  • src/org/openstreetmap/josm/plugins/PluginDownloader.java

     
    4848        }
    4949
    5050        @Override protected void finish() {
    51             Main.pleaseWaitDlg.setVisible(false);
    5251            if (errors.length() > 0)
    5352                JOptionPane.showMessageDialog(Main.parent, tr("There were problems with the following plugins:\n\n {0}",errors));
    5453            else
     
    5958            File pluginDir = Main.pref.getPluginsDirFile();
    6059            if (!pluginDir.exists())
    6160                pluginDir.mkdirs();
    62             Main.pleaseWaitDlg.progress.setMaximum(toUpdate.size());
    63             int progressValue = 0;
     61            progressMonitor.setTicksCount(toUpdate.size());
    6462            for (PluginInformation d : toUpdate) {
    65                 Main.pleaseWaitDlg.progress.setValue(progressValue++);
    66                 Main.pleaseWaitDlg.currentAction.setText(tr("Downloading Plugin {0}...", d.name));
     63                progressMonitor.subTask(tr("Downloading Plugin {0}...", d.name));
     64                progressMonitor.worked(1);
    6765                File pluginFile = new File(pluginDir, d.name + ".jar.new");
    6866                if(download(d, pluginFile))
    6967                    count++;
  • src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java

     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.awt.EventQueue;
    7 import java.awt.event.ActionEvent;
    8 import java.awt.event.ActionListener;
    9 import java.awt.event.WindowAdapter;
    10 import java.awt.event.WindowEvent;
    11 import java.awt.event.WindowListener;
    127import java.io.FileNotFoundException;
    138import java.io.IOException;
    14 import java.lang.reflect.InvocationTargetException;
    159
    16 import javax.swing.JOptionPane;
    1710import javax.swing.SwingUtilities;
    1811
    19 import org.openstreetmap.josm.Main;
     12import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
     13import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     14import org.openstreetmap.josm.gui.progress.ProgressMonitor.CancelListener;
    2015import org.openstreetmap.josm.io.OsmTransferException;
    2116import org.xml.sax.SAXException;
    2217
     
    2621 *
    2722 * @author Imi
    2823 */
    29 public abstract class PleaseWaitRunnable implements Runnable {
    30     public boolean silent = false;
    31     public String errorMessage;
     24public abstract class PleaseWaitRunnable implements Runnable, CancelListener {
    3225
    33     private boolean closeDialogCalled = false;
    3426    private boolean cancelled = false;
    3527    private boolean ignoreException;
    36 
    3728    private final String title;
    3829
    39     private ActionListener cancelListener = new ActionListener(){
    40         public void actionPerformed(ActionEvent e) {
    41             if (!cancelled) {
    42                 cancelled = true;
    43                 cancel();
    44             }
    45         }
    46     };
    47 
    48     private WindowListener windowListener = new WindowAdapter(){
    49         @Override public void windowClosing(WindowEvent e) {
    50             if (!closeDialogCalled) {
    51                 if (!cancelled) {
    52                     cancelled = true;
    53                     cancel();
    54                 }
    55                 closeDialog();
    56             }
    57         }
    58     };
     30    protected final ProgressMonitor progressMonitor;
    5931
    6032    /**
    6133     * Create the runnable object with a given message for the user.
     
    7244     * then use false unless you read result of task (because exception will get lost if you don't)
    7345     */
    7446    public PleaseWaitRunnable(String title, boolean ignoreException) {
    75         this.title = title;
    76         this.ignoreException = ignoreException;
     47        this(title, new PleaseWaitProgressMonitor(), ignoreException);
    7748    }
    7849
    79     private void prepareDialog() {
    80         // reset dialog state
    81         errorMessage = null;
    82         closeDialogCalled = false;
    83 
    84         Main.pleaseWaitDlg.setTitle(title);
    85         Main.pleaseWaitDlg.cancel.setEnabled(true);
    86         Main.pleaseWaitDlg.setCustomText("");
    87         Main.pleaseWaitDlg.cancel.addActionListener(cancelListener);
    88         Main.pleaseWaitDlg.addWindowListener(windowListener);
    89         Main.pleaseWaitDlg.setVisible(true);
     50    public PleaseWaitRunnable(String title, ProgressMonitor progressMonitor, boolean ignoreException) {
     51        this.title = title;
     52        this.progressMonitor = progressMonitor == null?new PleaseWaitProgressMonitor():progressMonitor;
     53        this.ignoreException = ignoreException;
     54        this.progressMonitor.addCancelListener(this);
    9055    }
    9156
    9257    private void doRealRun() {
    9358        try {
    9459            try {
    95                 realRun();
     60                progressMonitor.beginTask(title);
     61                try {
     62                    realRun();
     63                } finally {
     64                    if (EventQueue.isDispatchThread()) {
     65                        finish();
     66                    } else {
     67                        EventQueue.invokeAndWait(new Runnable() {
     68                            public void run() {
     69                                finish();
     70                            }
     71                        });
     72                    }
     73                }
    9674            } catch (SAXException x) {
    9775                x.printStackTrace();
    98                 errorMessage = tr("Error while parsing")+": "+x.getMessage();
     76                progressMonitor.setErrorMessage(tr("Error while parsing")+": "+x.getMessage());
    9977            } catch (FileNotFoundException x) {
    10078                x.printStackTrace();
    101                 errorMessage = tr("File not found")+": "+x.getMessage();
     79                progressMonitor.setErrorMessage(tr("File not found")+": "+x.getMessage());
    10280            } catch (IOException x) {
    10381                x.printStackTrace();
    104                 errorMessage = x.getMessage();
     82                progressMonitor.setErrorMessage(x.getMessage());
    10583            } catch(OsmTransferException x) {
    10684                x.printStackTrace();
    10785                if (x.getCause() != null) {
    108                     errorMessage = x.getCause().getMessage();
     86                    progressMonitor.setErrorMessage(x.getCause().getMessage());
    10987                } else {
    110                     errorMessage = x.getMessage();
     88                    progressMonitor.setErrorMessage(x.getMessage());
    11189                }
    11290            } finally {
    113                 closeDialog();
     91                progressMonitor.finishTask();
    11492            }
    11593        } catch (final Throwable e) {
    11694            if (!ignoreException) {
     
    134112                    doRealRun();
    135113                }
    136114            }).start();
    137             prepareDialog();
    138115        } else {
    139             EventQueue.invokeLater(new Runnable() {
    140                 public void run() {
    141                     prepareDialog();
    142                 }
    143             });
    144116            doRealRun();
    145117        }
    146118    }
    147119
     120    public void operationCanceled() {
     121        cancel();
     122    }
     123
    148124    /**
    149125     * User pressed cancel button.
    150126     */
     
    163139     */
    164140    protected abstract void finish();
    165141
    166     /**
    167      * Close the dialog. Usually called from worker thread.
    168      */
    169     public void closeDialog() {
    170         if (closeDialogCalled)
    171             return;
    172         closeDialogCalled  = true;
    173         try {
    174             Runnable runnable = new Runnable(){
    175                 public void run() {
    176                     try {
    177                         finish();
    178                     } finally {
    179                         Main.pleaseWaitDlg.setVisible(false);
    180                         Main.pleaseWaitDlg.dispose();
    181                         Main.pleaseWaitDlg.removeWindowListener(windowListener);
    182                         Main.pleaseWaitDlg.cancel.removeActionListener(cancelListener);
    183                     }
    184                     if (errorMessage != null && !silent) {
    185                         JOptionPane.showMessageDialog(Main.parent, errorMessage);
    186                     }
    187                 }
    188             };
    189 
    190             // make sure, this is called in the dispatcher thread ASAP
    191             if (EventQueue.isDispatchThread()) {
    192                 runnable.run();
    193             } else {
    194                 EventQueue.invokeAndWait(runnable);
    195             }
    196 
    197         } catch (InterruptedException e) {
    198         } catch (InvocationTargetException e) {
    199             throw new RuntimeException(e);
    200         }
     142    public ProgressMonitor getProgressMonitor() {
     143        return progressMonitor;
    201144    }
    202145}
  • src/org/openstreetmap/josm/gui/download/DownloadDialog.java

     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.awt.Color;
     7import java.awt.Font;
     8import java.awt.GridBagLayout;
     9import java.awt.Toolkit;
    710import java.awt.datatransfer.DataFlavor;
    811import java.awt.datatransfer.Transferable;
    912import java.awt.event.ActionEvent;
    1013import java.awt.event.InputEvent;
    1114import java.awt.event.KeyEvent;
    12 import java.awt.Font;
    13 import java.awt.GridBagLayout;
    14 import java.awt.Toolkit;
    1515import java.util.ArrayList;
    1616import java.util.List;
    1717
     
    2929import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
    3030import org.openstreetmap.josm.data.Bounds;
    3131import org.openstreetmap.josm.gui.MapView;
     32import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3233import org.openstreetmap.josm.plugins.PluginHandler;
    3334import org.openstreetmap.josm.tools.GBC;
    3435import org.openstreetmap.josm.tools.OsmUrlToBounds;
     
    5051
    5152    public interface DownloadTask {
    5253        /**
    53          * Execute the download using the given bounding box
     54         * Execute the download using the given bounding box. Set silent on progressMonitor
     55         * if no error messages should be popped up.
    5456         */
    5557        void download(DownloadAction action, double minlat, double minlon,
    56                 double maxlat, double maxlon);
    57 
    58         /**
    59          * Execute the download using the given bounding box. Set silent to true if no error
    60          * messages should be popped up. Message can be used to display an additional text below
    61          * the default description.
    62          */
    63         void download(DownloadAction action, double minlat, double minlon,
    64                 double maxlat, double maxlon, boolean silent, String message);
     58                double maxlat, double maxlon, ProgressMonitor progressMonitor);
    6559
    6660        /**
    6761         * Execute the download using the given URL
  • src/org/openstreetmap/josm/gui/conflict/properties/PropertiesMergeModel.java

     
    66
    77import java.beans.PropertyChangeListener;
    88import java.beans.PropertyChangeSupport;
    9 import java.io.IOException;
    10 import java.net.HttpURLConnection;
    119import java.util.ArrayList;
    1210import java.util.HashMap;
    1311import java.util.List;
    1412import java.util.Observable;
    1513
    1614import javax.swing.JOptionPane;
    17 import javax.swing.text.html.HTML;
    1815
    1916import org.openstreetmap.josm.Main;
    2017import org.openstreetmap.josm.command.Command;
     
    2623import org.openstreetmap.josm.data.osm.DataSet;
    2724import org.openstreetmap.josm.data.osm.Node;
    2825import org.openstreetmap.josm.data.osm.OsmPrimitive;
    29 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    3026import org.openstreetmap.josm.data.osm.Relation;
    3127import org.openstreetmap.josm.data.osm.RelationMember;
    3228import org.openstreetmap.josm.data.osm.Way;
    33 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    3429import org.openstreetmap.josm.gui.conflict.MergeDecisionType;
    35 import org.openstreetmap.josm.gui.conflict.properties.PropertiesMerger.KeepMyVisibleStateAction;
     30import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    3631import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
    37 import org.openstreetmap.josm.io.OsmApi;
    38 import org.openstreetmap.josm.io.OsmApiException;
    39 import org.openstreetmap.josm.io.OsmServerObjectReader;
    4032import org.openstreetmap.josm.io.OsmTransferException;
    41 import org.xml.sax.SAXException;
    4233
    4334/**
    4435 * This is the model for resolving conflicts in the properties of the
     
    282273    /**
    283274     * replies the merged visible state; null, if the merge decision is
    284275     * {@see MergeDecisionType#UNDECIDED}.
    285      * 
     276     *
    286277     * @return the merged visible state
    287278     */
    288279    public Boolean getMergedVisibleState() {
     
    298289    /**
    299290     * decides the conflict between two deleted states
    300291     * @param decision the decision (must not be null)
    301      * 
     292     *
    302293     * @throws IllegalArgumentException thrown, if decision is null
    303294     */
    304295    public void decideDeletedStateConflict(MergeDecisionType decision) throws IllegalArgumentException{
     
    313304    /**
    314305     * decides the conflict between two visible states
    315306     * @param decision the decision (must not be null)
    316      * 
     307     *
    317308     * @throws IllegalArgumentException thrown, if decision is null
    318309     */
    319310    public void decideVisibleStateConflict(MergeDecisionType decision) throws IllegalArgumentException {
     
    418409    }
    419410
    420411    /**
    421      * 
     412     *
    422413     * @param id
    423414     */
    424415    protected void handleExceptionWhileBuildingCommand(Exception e) {
     
    439430    /**
    440431     * User has decided to keep his local version of a primitive which had been deleted
    441432     * on the server
    442      * 
     433     *
    443434     * @param id the primitive id
    444435     */
    445436    protected UndeletePrimitivesCommand createUndeletePrimitiveCommand(OsmPrimitive my) throws OsmTransferException {
     
    456447     * doesn't offer a call for "undeleting" a node. We therefore create
    457448     * a clone of the node which we flag as new. On the next upload the
    458449     * server will assign the node a new id.
    459      * 
     450     *
    460451     * @param node the node to undelete
    461452     */
    462453    protected UndeletePrimitivesCommand  createUndeleteNodeCommand(Node node) {
     
    466457    /**
    467458     * displays a confirmation message. The user has to confirm that additional dependent
    468459     * nodes should be undeleted too.
    469      * 
     460     *
    470461     * @param way  the way
    471462     * @param dependent a list of dependent nodes which have to be undelete too
    472463     * @return true, if the user confirms; false, otherwise
     
    531522
    532523    /**
    533524     * Creates the undelete command for a way which is already deleted on the server.
    534      * 
     525     *
    535526     * This method also checks whether there are additional nodes referred to by
    536527     * this way which are deleted on the server too.
    537      * 
     528     *
    538529     * @param way the way to undelete
    539530     * @return the undelete command
    540531     * @see #createUndeleteNodeCommand(Node)
     
    549540        }
    550541        MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
    551542        reader.append(candidates.values());
    552         DataSet ds = reader.parseOsm();
     543        DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
    553544
    554545        ArrayList<OsmPrimitive> toDelete = new ArrayList<OsmPrimitive>();
    555546        for (OsmPrimitive their : ds.allPrimitives()) {
     
    568559
    569560    /**
    570561     * Creates an undelete command for a relation which is already deleted on the server.
    571      * 
     562     *
    572563     * This method  checks whether there are additional primitives referred to by
    573564     * this relation which are already deleted on the server.
    574      * 
     565     *
    575566     * @param r the relation
    576567     * @return the undelete command
    577568     * @see #createUndeleteNodeCommand(Node)
     
    587578
    588579        MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
    589580        reader.append(candidates.values());
    590         DataSet ds = reader.parseOsm();
     581        DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
    591582
    592583        ArrayList<OsmPrimitive> toDelete = new ArrayList<OsmPrimitive>();
    593584        for (OsmPrimitive their : ds.allPrimitives()) {
  • src/org/openstreetmap/josm/gui/PleaseWaitDialog.java

     
    11// License: GPL. Copyright 2007 by Immanuel Scholz and others
    22package org.openstreetmap.josm.gui;
    33
    4 import java.awt.Component;
     4import java.awt.Dialog;
     5import java.awt.Frame;
    56import java.awt.GridBagLayout;
    67import java.awt.event.ComponentEvent;
    78import java.awt.event.ComponentListener;
     
    1112import javax.swing.JButton;
    1213import javax.swing.JDialog;
    1314import javax.swing.JLabel;
    14 import javax.swing.JOptionPane;
    1515import javax.swing.JPanel;
    1616import javax.swing.JProgressBar;
    1717import javax.swing.UIManager;
     
    2424
    2525    private final JProgressBar progressBar = new JProgressBar();
    2626
    27     public final JLabel currentAction = new JLabel(I18n.tr("Contacting the OSM server..."));
     27    public final JLabel currentAction = new JLabel("");
    2828    private final JLabel customText = new JLabel("");
    2929    public final BoundedRangeModel progress = progressBar.getModel();
    3030    public final JButton cancel = new JButton(I18n.tr("Cancel"));
    3131
    32     public PleaseWaitDialog(Component parent) {
    33         super(JOptionPane.getFrameForComponent(parent), true);
     32    private void initDialog() {
    3433        setLayout(new GridBagLayout());
    3534        JPanel pane = new JPanel(new GridBagLayout());
    3635        pane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
     
    5453        });
    5554    }
    5655
     56    public PleaseWaitDialog(Frame parent) {
     57        super(parent, true);
     58        initDialog();
     59    }
     60
     61    public PleaseWaitDialog(Dialog parent) {
     62        super(parent, true);
     63        initDialog();
     64    }
     65
    5766    public void setIndeterminate(boolean newValue) {
    5867        UIManager.put("ProgressBar.cycleTime", UIManager.getInt("ProgressBar.repaintInterval") * 100);
    5968        progressBar.setIndeterminate(newValue);
  • src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4import java.util.Arrays;
     5import java.util.Iterator;
     6import java.util.LinkedList;
     7import java.util.Queue;
     8
     9
     10public abstract class AbstractProgressMonitor implements ProgressMonitor {
     11
     12    private static class Request {
     13        AbstractProgressMonitor originator;
     14        int childTicks;
     15        double currentValue;
     16
     17        String title;
     18        String customText;
     19        String extraText;
     20        Boolean intermediate;
     21    }
     22
     23    private final CancelHandler cancelHandler;
     24
     25    protected enum State {INIT, IN_TASK, IN_SUBTASK, FINISHED}
     26
     27    protected State state = State.INIT;
     28
     29    int ticksCount;
     30    int ticks;
     31    private int childTicks;
     32
     33    private String taskTitle;
     34    private String customText;
     35    private String extraText;
     36    private String shownTitle;
     37    private String shownCustomText;
     38    private boolean intermediateTask;
     39
     40    private Queue<Request> requests = new LinkedList<Request>();
     41    private AbstractProgressMonitor currentChild;
     42    private Request requestedState = new Request();
     43
     44    private boolean silent;
     45    private String errorMessage;
     46
     47    protected abstract void doBeginTask();
     48    protected abstract void doFinishTask();
     49    protected abstract void doSetIntermediate(boolean value);
     50    protected abstract void doSetTitle(String title);
     51    protected abstract void doSetCustomText(String title);
     52    protected abstract void doSetErrorMessage(String message);
     53
     54    protected AbstractProgressMonitor(CancelHandler cancelHandler) {
     55        this.cancelHandler = cancelHandler;
     56    }
     57
     58    protected void checkState(State... expectedStates) {
     59        for (State s:expectedStates) {
     60            if (s == state) {
     61                return;
     62            }
     63        }
     64        throw new ProgressException("Expected states are %s but current state is %s", Arrays.asList(expectedStates).toString(), state);
     65    }
     66
     67    /*=======
     68     * Tasks
     69     =======*/
     70
     71    public void beginTask(String title) {
     72        beginTask(title, DEFAULT_TICKS);
     73    }
     74
     75    public synchronized void beginTask(final String title, int ticks) {
     76        this.taskTitle = title;
     77        checkState(State.INIT);
     78        state = State.IN_TASK;
     79        doBeginTask();
     80        setTicksCount(ticks);
     81        resetState();
     82    }
     83
     84    public synchronized void finishTask() {
     85        if (state != State.FINISHED) {
     86
     87            if (state == State.IN_SUBTASK) {
     88                // Make sure the subtask didn't start yet (once task start it must be finished)
     89                boolean broken = currentChild.state != State.INIT;
     90                for (Request request:requests) {
     91                    broken = broken | request.originator.state != State.INIT;
     92                }
     93                if (broken) {
     94                    throw new ProgressException("Cannot call finishTask when there are unfinished tasks");
     95                } else {
     96                    state = State.IN_TASK;
     97                }
     98            }
     99
     100            checkState(State.IN_TASK);
     101            state = State.FINISHED;
     102            doFinishTask();
     103        }
     104    }
     105
     106    public synchronized void invalidate() {
     107        checkState(State.INIT);
     108        state = State.FINISHED;
     109        doFinishTask();
     110    }
     111
     112    public synchronized void subTask(final String title) {
     113        if (state == State.IN_SUBTASK) {
     114            if (title != null) {
     115                requestedState.title = title;
     116            }
     117            requestedState.intermediate = false;
     118        } else {
     119            checkState(State.IN_TASK);
     120            if (title != null) {
     121                this.taskTitle = title;
     122                resetState();
     123            }
     124            this.intermediateTask = false;
     125            doSetIntermediate(false);
     126        }
     127    }
     128
     129    public synchronized void indeterminateSubTask(String title) {
     130        if (state == State.IN_SUBTASK) {
     131            if (title != null) {
     132                requestedState.title = title;
     133            }
     134            requestedState.intermediate = true;
     135        } else {
     136            checkState(State.IN_TASK);
     137            if (title != null) {
     138                this.taskTitle = title;
     139                resetState();
     140            }
     141            this.intermediateTask = true;
     142            doSetIntermediate(true);
     143        }
     144    }
     145
     146    public synchronized void setCustomText(String text) {
     147        if (state == State.IN_SUBTASK) {
     148            requestedState.customText = text;
     149        } else {
     150            this.customText = text;
     151            resetState();
     152        }
     153    }
     154
     155    public synchronized void setExtraText(String text) {
     156        if (state == State.IN_SUBTASK) {
     157            requestedState.extraText = text;
     158        } else {
     159            this.extraText = text;
     160            resetState();
     161        }
     162    }
     163
     164    private void resetState() {
     165        String newTitle;
     166        if (extraText != null) {
     167            newTitle = taskTitle + " " + extraText;
     168        } else {
     169            newTitle = taskTitle;
     170        }
     171
     172        if (newTitle == null?shownTitle != null:!newTitle.equals(shownTitle)) {
     173            shownTitle = newTitle;
     174            doSetTitle(shownTitle);
     175        }
     176
     177        if (customText == null?shownCustomText != null:!customText.equals(shownCustomText)) {
     178            shownCustomText = customText;
     179            doSetCustomText(shownCustomText);
     180        }
     181        doSetIntermediate(intermediateTask);
     182    }
     183
     184    public void cancel() {
     185        cancelHandler.cancel();
     186    }
     187
     188    public boolean isCancelled() {
     189        return cancelHandler.isCanceled();
     190    }
     191
     192    public void addCancelListener(CancelListener listener) {
     193        cancelHandler.addCancelListener(listener);
     194    }
     195
     196    public void removeCancelListener(CancelListener listener) {
     197        cancelHandler.removeCancelListener(listener);
     198    }
     199
     200    /*=================
     201     * Ticks handling
     202    ==================*/
     203
     204    abstract void updateProgress(double value);
     205
     206    public synchronized void setTicks(int ticks) {
     207        if (ticks >= ticksCount) {
     208            ticks = ticksCount - 1;
     209        }
     210        this.ticks = ticks;
     211        internalUpdateProgress(0);
     212    }
     213
     214    public synchronized void setTicksCount(int ticks) {
     215        this.ticksCount = ticks;
     216        internalUpdateProgress(0);
     217    }
     218
     219    public void worked(int ticks) {
     220        if (ticks == ALL_TICKS) {
     221            setTicks(this.ticksCount - 1);
     222        } else {
     223            setTicks(this.ticks + ticks);
     224        }
     225    }
     226
     227    private void internalUpdateProgress(double childProgress) {
     228        if (childProgress > 1) {
     229            childProgress = 1;
     230        }
     231        checkState(State.IN_TASK, State.IN_SUBTASK);
     232        updateProgress(ticksCount == 0?0:(ticks + childProgress * childTicks) / ticksCount);
     233    }
     234
     235    public synchronized int getTicks() {
     236        return ticks;
     237    }
     238
     239    /*==========
     240     * Subtasks
     241     ==========*/
     242
     243    public synchronized ProgressMonitor createSubTaskMonitor(int ticks, boolean internal) {
     244        if (ticks == ALL_TICKS) {
     245            ticks = ticksCount - this.ticks;
     246        }
     247
     248        if (state == State.IN_SUBTASK) {
     249            Request request = new Request();
     250            request.originator = new ChildProgress(this, cancelHandler, internal);
     251            request.childTicks = ticks;
     252            requests.add(request);
     253            return request.originator;
     254        } else {
     255            checkState(State.IN_TASK);
     256            state = State.IN_SUBTASK;
     257            this.childTicks = ticks;
     258            currentChild = new ChildProgress(this, cancelHandler, internal);
     259            return currentChild;
     260        }
     261    }
     262
     263    private void applyChildRequest(Request request) {
     264        if (request.customText != null) {
     265            doSetCustomText(request.customText);
     266        }
     267
     268        if (request.title != null) {
     269            doSetTitle(request.title);
     270        }
     271
     272        if (request.intermediate != null) {
     273            doSetIntermediate(request.intermediate);
     274        }
     275
     276        internalUpdateProgress(request.currentValue);
     277    }
     278
     279    private void applyThisRequest(Request request) {
     280        if (request.customText != null) {
     281            this.customText = request.customText;
     282        }
     283
     284        if (request.title != null) {
     285            this.taskTitle = request.title;
     286        }
     287
     288        if (request.intermediate != null) {
     289            this.intermediateTask = request.intermediate;
     290        }
     291
     292        if (request.extraText != null) {
     293            this.extraText = request.extraText;
     294        }
     295
     296        resetState();
     297    }
     298
     299    protected synchronized void childFinished(AbstractProgressMonitor child) {
     300        checkState(State.IN_SUBTASK);
     301        if (currentChild == child) {
     302            setTicks(ticks + childTicks);
     303            if (requests.isEmpty()) {
     304                state = State.IN_TASK;
     305                applyThisRequest(requestedState);
     306                requestedState = new Request();
     307            } else {
     308                Request newChild = requests.poll();
     309                currentChild = newChild.originator;
     310                childTicks = newChild.childTicks;
     311                applyChildRequest(newChild);
     312            }
     313        } else {
     314            Iterator<Request> it = requests.iterator();
     315            while (it.hasNext()) {
     316                if (it.next().originator == child) {
     317                    it.remove();
     318                    return;
     319                }
     320            }
     321            throw new ProgressException("Subtask %s not found", child);
     322        }
     323    }
     324
     325    private Request getRequest(AbstractProgressMonitor child) {
     326        for (Request request:requests) {
     327            if (request.originator == child) {
     328                return request;
     329            }
     330        }
     331        throw new ProgressException("Subtask %s not found", child);
     332    }
     333
     334    protected synchronized void childSetProgress(AbstractProgressMonitor child, double value) {
     335        checkState(State.IN_SUBTASK);
     336        if (currentChild == child) {
     337            internalUpdateProgress(value);
     338        } else {
     339            getRequest(child).currentValue = value;
     340        }
     341    }
     342
     343    protected synchronized void childSetTitle(AbstractProgressMonitor child, String title) {
     344        checkState(State.IN_SUBTASK);
     345        if (currentChild == child) {
     346            doSetTitle(title);
     347        } else {
     348            getRequest(child).title = title;
     349        }
     350    }
     351
     352    protected synchronized void childSetCustomText(AbstractProgressMonitor child, String customText) {
     353        checkState(State.IN_SUBTASK);
     354        if (currentChild == child) {
     355            doSetCustomText(customText);
     356        } else {
     357            getRequest(child).customText = customText;
     358        }
     359    }
     360
     361    protected synchronized void childSetIntermediate(AbstractProgressMonitor child, boolean value) {
     362        checkState(State.IN_SUBTASK);
     363        if (currentChild == child) {
     364            doSetIntermediate(value);
     365        } else {
     366            getRequest(child).intermediate = value;
     367        }
     368    }
     369
     370    /*======================
     371     * Silent/error message
     372     ======================*/
     373    public synchronized void setSilent(boolean value) {
     374        this.silent = value;
     375    }
     376
     377    public synchronized void setErrorMessage(String message) {
     378        this.errorMessage = message;
     379        if (!silent) {
     380            doSetErrorMessage(message);
     381        }
     382    }
     383
     384    public synchronized String getErrorMessage() {
     385        return errorMessage;
     386    }
     387
     388}
  • src/org/openstreetmap/josm/gui/progress/ProgressException.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4public class ProgressException extends RuntimeException {
     5
     6    public ProgressException(String message, Object... args) {
     7        super(String.format(message, args));
     8    }
     9
     10}
  • src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/ProgressException.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4import java.awt.Dialog;
     5import java.awt.EventQueue;
     6import java.awt.Frame;
     7import java.awt.Window;
     8import java.awt.event.ActionEvent;
     9import java.awt.event.ActionListener;
     10import java.awt.event.WindowAdapter;
     11import java.awt.event.WindowEvent;
     12import java.awt.event.WindowListener;
     13import java.lang.reflect.InvocationTargetException;
     14
     15import javax.swing.JOptionPane;
     16
     17import org.openstreetmap.josm.Main;
     18import org.openstreetmap.josm.gui.PleaseWaitDialog;
     19
     20
     21public class PleaseWaitProgressMonitor extends AbstractProgressMonitor {
     22
     23    private static final int PROGRESS_BAR_MAX = 100;
     24    private final Window dialogParent;
     25
     26    private PleaseWaitDialog dialog;
     27
     28    public PleaseWaitProgressMonitor() {
     29        this(JOptionPane.getFrameForComponent(Main.map));
     30    }
     31
     32    public PleaseWaitProgressMonitor(Window dialogParent) {
     33        super(new CancelHandler());
     34        this.dialogParent = dialogParent;
     35    }
     36
     37    private ActionListener cancelListener = new ActionListener(){
     38        public void actionPerformed(ActionEvent e) {
     39            cancel();
     40        }
     41    };
     42
     43    private WindowListener windowListener = new WindowAdapter(){
     44        @Override public void windowClosing(WindowEvent e) {
     45            cancel();
     46            closeDialog();
     47        }
     48    };
     49
     50    private void closeDialog() {
     51        try {
     52            Runnable runnable = new Runnable(){
     53                public void run() {
     54                }
     55            };
     56
     57            // make sure, this is called in the dispatcher thread ASAP
     58            if (EventQueue.isDispatchThread()) {
     59                runnable.run();
     60            } else {
     61                EventQueue.invokeAndWait(runnable);
     62            }
     63
     64        } catch (InterruptedException e) {
     65        } catch (InvocationTargetException e) {
     66            throw new RuntimeException(e);
     67        }
     68    }
     69
     70    private void doInEDT(Runnable runnable) {
     71        EventQueue.invokeLater(runnable);
     72    }
     73
     74    public void doBeginTask() {
     75        doInEDT(new Runnable() {
     76            public void run() {
     77                if (dialogParent instanceof Frame) {
     78                    dialog = new PleaseWaitDialog((Frame)dialogParent);
     79                } else if (dialogParent instanceof Dialog) {
     80                    dialog = new PleaseWaitDialog((Dialog)dialogParent);
     81                } else {
     82                    throw new ProgressException("PleaseWaitDialog parent must be either Frame or Dialog");
     83                }
     84
     85                dialog.cancel.setEnabled(true);
     86                dialog.setCustomText("");
     87                dialog.cancel.addActionListener(cancelListener);
     88                dialog.addWindowListener(windowListener);
     89                dialog.progress.setMaximum(PROGRESS_BAR_MAX);
     90                dialog.setVisible(true);
     91            }
     92        });
     93    }
     94
     95    public void doFinishTask() {
     96        doInEDT(new Runnable() {
     97            public void run() {
     98                if (dialog != null) {
     99                    dialog.setVisible(false);
     100                    dialog.dispose();
     101                    dialog.removeWindowListener(windowListener);
     102                    dialog.cancel.removeActionListener(cancelListener);
     103                    if (getErrorMessage() != null) {
     104                        JOptionPane.showMessageDialog(Main.parent, getErrorMessage());
     105                    }
     106                    dialog = null;
     107                }
     108            }
     109        });
     110    }
     111
     112    public void worked(int ticks) {
     113        this.ticks += ticks;
     114        updateProgress(0);
     115    }
     116
     117    protected void updateProgress(final double progressValue) {
     118        doInEDT(new Runnable() {
     119            public void run() {
     120                dialog.progress.setValue((int)(progressValue * PROGRESS_BAR_MAX));
     121            }
     122        });
     123    }
     124
     125    @Override
     126    protected void doSetCustomText(final String title) {
     127        checkState(State.IN_TASK, State.IN_SUBTASK);
     128        doInEDT(new Runnable() {
     129            public void run() {
     130                dialog.setCustomText(title);
     131            }
     132        });
     133    }
     134
     135    @Override
     136    protected void doSetTitle(final String title) {
     137        checkState(State.IN_TASK, State.IN_SUBTASK);
     138        doInEDT(new Runnable() {
     139            public void run() {
     140                dialog.currentAction.setText(title);
     141            }
     142        });
     143    }
     144
     145    @Override
     146    protected void doSetIntermediate(final boolean value) {
     147        doInEDT(new Runnable() {
     148            public void run() {
     149                if (value && dialog.progress.getValue() == 0) {
     150                    // Enable only if progress is at the begging. Doing intermediate progress in the middle
     151                    // will hide already reached progress
     152                    dialog.setIndeterminate(true);
     153                } else {
     154                    dialog.setIndeterminate(false);
     155                }
     156            }
     157        });
     158    }
     159
     160    @Override
     161    protected void doSetErrorMessage(String message) {
     162        // Do nothing
     163    }
     164
     165}
  • src/org/openstreetmap/josm/gui/progress/ProgressMonitor.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4/**
     5 * Typical usecase is:
     6 * <pre>
     7 *   monitor.beginTask()
     8 *   try {
     9 *     .. do some work
     10 *     monitor.worked()
     11 *     monitor.subTask()/monitor.intermediateTask()
     12 *     .. do some work
     13 *     monitor.worked()
     14 *   } finally {
     15 *     monitor.finishTask();
     16 *   }
     17 * </pre>
     18 *
     19 * {@link #subTask(String)} and {@link #indeterminateSubTask(String)} has nothing to do with logical
     20 * structure of the work, they just show task title to the user.
     21 *
     22 * If task consists of multiple tasks then {@link #createSubTaskMonitor(int, boolean)} may be used. It
     23 * will create new ProgressMonitor, then can be passed to the subtask. Subtask doesn't know whether
     24 * it runs standalono or as a part of other task. Progressbar will be updated so that total progress is
     25 * shown, not just progress of the subtask
     26 *
     27 * All ProgressMonitor implemenenatations should be thread safe.
     28 *
     29 */
     30public interface ProgressMonitor {
     31
     32    public interface CancelListener {
     33        void operationCanceled();
     34    }
     35
     36    public final int DEFAULT_TICKS = 100;
     37
     38    /**
     39     * Can be used with {@link #worked(int)} and {@link #createSubTaskMonitor(int, boolean)} to
     40     * express that the task should use all remaining ticks
     41     */
     42    public final int ALL_TICKS = -1;
     43
     44    void beginTask(String title);
     45
     46    /**
     47     * Starts this progress monitor. Must be called excatly once
     48     * @param title
     49     * @param ticks
     50     */
     51    void beginTask(String title, int ticks);
     52    /**
     53     * Finish this progress monitor, close the dialog or inform the parent progress monitor
     54     * that it can continue with other tasks. Must be called at least once (if called multiply times
     55     * then futher calls are ignored)
     56     */
     57    void finishTask();
     58    /**
     59     * Can be used if method receive ProgressMonitor but it's not interested progress monitoring.
     60     * Basically replaces {@link #beginTask(String)} and {@link #finishTask()}
     61     */
     62    void invalidate();
     63
     64    /**
     65     *
     66     * @param ticks Number of total work units
     67     */
     68    void setTicksCount(int ticks);
     69    /**
     70     *
     71     * @param ticks Number of work units already done
     72     */
     73    void setTicks(int ticks);
     74    int getTicks();
     75    /**
     76     * Increase number of already done work units by ticks
     77     * @param ticks
     78     */
     79    void worked(int ticks);
     80
     81    /**
     82     * Subtask that will show progress runing back and forworth
     83     * @param title Can be null, in that case task title is not changed
     84     */
     85    void indeterminateSubTask(String title);
     86    /**
     87     * Normal subtask
     88     * @param title Can be null, in that case task title is not changed
     89     */
     90    void subTask(String title);
     91    /**
     92     * Shows additonal text
     93     */
     94    void setCustomText(String text);
     95    /**
     96     * Show extra text after normal task title. Hack for ProgressInputStream to show number of kB
     97     * already downloaded
     98     * @param text
     99     */
     100    void setExtraText(String text);
     101
     102    /**
     103     * Creates subtasks monitor.
     104     * @param ticks Number of work units that should be done when subtask finishes
     105     * @param internal If true then subtask can't modify task title/custom text
     106     * @return
     107     */
     108    ProgressMonitor createSubTaskMonitor(int ticks, boolean internal);
     109
     110    boolean isCancelled();
     111    void cancel();
     112    void addCancelListener(CancelListener listener);
     113    void removeCancelListener(CancelListener listener);
     114
     115    void setSilent(boolean value);
     116    void setErrorMessage(String message);
     117    String getErrorMessage();
     118}
  • src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/ProgressMonitor.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4
     5public class NullProgressMonitor implements ProgressMonitor {
     6
     7    public static final ProgressMonitor INSTANCE = new NullProgressMonitor();
     8
     9    private NullProgressMonitor() {
     10
     11    }
     12
     13    public void addCancelListener(CancelListener listener) {
     14    }
     15
     16    public void beginTask(String title) {
     17    }
     18
     19    public void beginTask(String title, int ticks) {
     20    }
     21
     22    public void cancel() {
     23    }
     24
     25    public ProgressMonitor createSubTaskMonitor(int ticks, boolean internal) {
     26        return INSTANCE;
     27    }
     28
     29    public void finishTask() {
     30    }
     31
     32    public String getErrorMessage() {
     33        return null;
     34    }
     35
     36    public int getTicks() {
     37        return 0;
     38    }
     39
     40    public void indeterminateSubTask(String title) {
     41    }
     42
     43    public void invalidate() {
     44    }
     45
     46    public boolean isCancelled() {
     47        return false;
     48    }
     49
     50    public void removeCancelListener(CancelListener listener) {
     51    }
     52
     53    public void setCustomText(String text) {
     54    }
     55
     56    public void setErrorMessage(String message) {
     57    }
     58
     59    public void setExtraText(String text) {
     60    }
     61
     62    public void setSilent(boolean value) {
     63    }
     64
     65    public void setTicks(int ticks) {
     66    }
     67
     68    public void setTicksCount(int ticks) {
     69    }
     70
     71    public void subTask(String title) {
     72    }
     73
     74    public void worked(int ticks) {
     75    }
     76}
  • src/org/openstreetmap/josm/gui/progress/StackableProgress.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4public interface StackableProgress {
     5    public void setChildProgress(double value);
     6    public void setSubTaskName(String value);
     7}
  • src/org/openstreetmap/josm/gui/progress/CancelHandler.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/StackableProgress.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4import java.util.ArrayList;
     5import java.util.List;
     6
     7import org.openstreetmap.josm.gui.progress.ProgressMonitor.CancelListener;
     8
     9public class CancelHandler {
     10
     11    private boolean isCanceled;
     12    private List<CancelListener> listeners = new ArrayList<CancelListener>();
     13
     14    public synchronized void cancel() {
     15        if (!isCanceled) {
     16            isCanceled = true;
     17            for (CancelListener listener:listeners) {
     18                listener.operationCanceled();
     19            }
     20        }
     21    }
     22
     23    public synchronized boolean isCanceled() {
     24        return isCanceled;
     25    }
     26
     27    public synchronized void addCancelListener(CancelListener listener) {
     28        listeners.add(listener);
     29    }
     30
     31    public synchronized void removeCancelListener(CancelListener listener) {
     32        listeners.remove(listener);
     33    }
     34
     35}
  • src/org/openstreetmap/josm/gui/progress/ChildProgress.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/CancelHandler.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.progress;
     3
     4class ChildProgress extends AbstractProgressMonitor {
     5
     6    private final AbstractProgressMonitor parent;
     7    private final boolean internal;
     8
     9    public ChildProgress(AbstractProgressMonitor parent, CancelHandler cancelHandler, boolean internal) {
     10        super(cancelHandler);
     11        this.parent = parent;
     12        this.internal = internal;
     13    }
     14
     15    @Override
     16    void updateProgress(double value) {
     17        parent.childSetProgress(this, value);
     18    }
     19
     20    @Override
     21    protected void doBeginTask() {
     22    }
     23
     24    @Override
     25    protected void doSetCustomText(String title) {
     26        if (!internal) {
     27            parent.childSetCustomText(this, title);
     28        }
     29    }
     30
     31    @Override
     32    protected void doSetTitle(String title) {
     33        if (!internal) {
     34            parent.childSetTitle(this, title);
     35        }
     36    }
     37
     38    @Override
     39    protected void doSetIntermediate(boolean value) {
     40        if (!internal) {
     41            parent.childSetIntermediate(this, value);
     42        }
     43    }
     44
     45    @Override
     46    protected void doSetErrorMessage(String message) {
     47        parent.setErrorMessage(message);
     48    }
     49
     50    @Override
     51    protected void doFinishTask() {
     52        parent.childFinished(this);
     53    }
     54}
  • src/org/openstreetmap/josm/gui/dialogs/relation/ReferringRelationsBrowser.java

    Property changes on: src/org/openstreetmap/josm/gui/progress/ChildProgress.java
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    
     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.awt.BorderLayout;
    7 import java.awt.EventQueue;
     7import java.awt.Dialog;
    88import java.awt.FlowLayout;
    99import java.awt.event.ActionEvent;
    1010import java.awt.event.MouseAdapter;
     
    1313import java.util.ArrayList;
    1414
    1515import javax.swing.AbstractAction;
    16 import javax.swing.JButton;
    1716import javax.swing.JCheckBox;
    1817import javax.swing.JDialog;
    1918import javax.swing.JLabel;
     
    3635import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    3736import org.openstreetmap.josm.gui.SideButton;
    3837import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     38import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
    3939import org.openstreetmap.josm.io.OsmApi;
    4040import org.openstreetmap.josm.io.OsmServerBackreferenceReader;
    4141import org.openstreetmap.josm.io.OsmTransferException;
     
    4444
    4545/**
    4646 * This is browser for a list of relations which refer to another relations
    47  * 
     47 *
    4848 *
    4949 */
    5050public class ReferringRelationsBrowser extends JPanel {
     
    5555    private OsmDataLayer layer;
    5656    private JCheckBox cbReadFull;
    5757    private EditAction editAction;
     58    private final GenericRelationEditor relationEditor;
    5859
    5960    /**
    6061     * build the GUI
     
    8283        add(pnl, BorderLayout.SOUTH);
    8384    }
    8485
    85     public ReferringRelationsBrowser(OsmDataLayer layer, ReferringRelationsBrowserModel model) {
     86    public ReferringRelationsBrowser(OsmDataLayer layer, ReferringRelationsBrowserModel model, GenericRelationEditor relationEditor) {
     87        this.relationEditor = relationEditor;
    8688        this.model = model;
    8789        this.layer = layer;
    8890        build();
     
    110112
    111113        public void actionPerformed(ActionEvent e) {
    112114            boolean full = cbReadFull.isSelected();
    113             ReloadTask task = new ReloadTask(full);
     115            ReloadTask task = new ReloadTask(full, relationEditor);
    114116            Main.worker.submit(task);
    115117        }
    116118
     
    129131
    130132    /**
    131133     * Action for editing the currently selected relation
    132      * 
     134     *
    133135     */
    134136    class EditAction extends AbstractAction implements ListSelectionListener {
    135137        public EditAction() {
     
    180182        private DataSet referrers;
    181183        private boolean full;
    182184
    183         protected void setIndeterminateEnabled(final boolean enabled) {
    184             EventQueue.invokeLater(
    185                     new Runnable() {
    186                         public void run() {
    187                             Main.pleaseWaitDlg.setIndeterminate(enabled);
    188                         }
    189                     }
    190             );
    191         }
    192 
    193         public ReloadTask(boolean full) {
    194             super(tr("Download referring relations"), false /* don't ignore exception */);
     185        public ReloadTask(boolean full, Dialog parent) {
     186            super(tr("Download referring relations"), new PleaseWaitProgressMonitor(parent), false /* don't ignore exception */);
    195187            referrers = null;
    196188        }
    197189        @Override
     
    236228        @Override
    237229        protected void realRun() throws SAXException, IOException, OsmTransferException {
    238230            try {
    239                 Main.pleaseWaitDlg.setAlwaysOnTop(true);
    240                 Main.pleaseWaitDlg.toFront();
    241                 setIndeterminateEnabled(true);
     231                progressMonitor.indeterminateSubTask(null);
    242232                OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(model.getRelation(), full);
    243                 referrers = reader.parseOsm();
     233                referrers = reader.parseOsm(progressMonitor.createSubTaskMonitor(1, false));
    244234                if (referrers != null) {
    245235                    final MergeVisitor visitor = new MergeVisitor(getLayer().data, referrers);
    246236                    visitor.merge();
     
    269259                                    visitor.getConflicts().size()),
    270260                                    JOptionPane.WARNING_MESSAGE
    271261                    );
    272                     JDialog dialog = op.createDialog(Main.pleaseWaitDlg, tr("Conflicts in data"));
     262                    JDialog dialog = op.createDialog(ReferringRelationsBrowser.this, tr("Conflicts in data"));
    273263                    dialog.setAlwaysOnTop(true);
    274264                    dialog.setModal(true);
    275265                    dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
     
    281271                    return;
    282272                }
    283273                lastException = e;
    284             } finally {
    285                 Main.pleaseWaitDlg.setAlwaysOnTop(false);
    286                 setIndeterminateEnabled(false);
    287274            }
    288275        }
    289276    }
  • src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java

     
    33import static org.openstreetmap.josm.tools.I18n.tr;
    44
    55import java.awt.BorderLayout;
     6import java.awt.Dialog;
    67import java.awt.Dimension;
    7 import java.awt.EventQueue;
    88import java.awt.FlowLayout;
    99import java.awt.GridBagConstraints;
    1010import java.awt.GridBagLayout;
     
    5959import org.openstreetmap.josm.gui.dialogs.relation.ac.AutoCompletionCache;
    6060import org.openstreetmap.josm.gui.dialogs.relation.ac.AutoCompletionList;
    6161import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     62import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
     63import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    6264import org.openstreetmap.josm.io.OsmApi;
    6365import org.openstreetmap.josm.io.OsmServerObjectReader;
    6466import org.openstreetmap.josm.io.OsmTransferException;
     
    149151        JTabbedPane tabbedPane = new JTabbedPane();
    150152        tabbedPane.add(tr("Tags and Members"), pnl);
    151153        if (relation != null && relation.id > 0) {
    152             tabbedPane.add(tr("Parent Relations"), new ReferringRelationsBrowser(getLayer(), referrerModel));
     154            tabbedPane.add(tr("Parent Relations"), new ReferringRelationsBrowser(getLayer(), referrerModel, this));
    153155        }
    154156
    155157        getContentPane().add(tabbedPane,BorderLayout.CENTER);
     
    165167
    166168    /**
    167169     * builds the panel with the OK and  the Cancel button
    168      * 
     170     *
    169171     * @return the panel with the OK and  the Cancel button
    170172     */
    171173    protected JPanel buildOkCancelButtonPanel() {
     
    180182
    181183    /**
    182184     * build the panel with the buttons on the left
    183      * 
     185     *
    184186     * @return
    185187     */
    186188    protected JPanel buildTagEditorControlPanel() {
     
    219221
    220222    /**
    221223     * builds the panel with the tag editor
    222      * 
     224     *
    223225     * @return the panel with the tag editor
    224226     */
    225227    protected JPanel buildTagEditorPanel() {
     
    286288
    287289    /**
    288290     * builds the panel for the relation member editor
    289      * 
     291     *
    290292     * @return the panel for the relation member editor
    291293     */
    292294    protected JPanel buildMemberEditorPanel() {
     
    384386
    385387    /**
    386388     * builds the panel with the table displaying the currently selected primitives
    387      * 
     389     *
    388390     * @return
    389391     */
    390392    protected JPanel buildSelectionTablePanel() {
     
    400402    /**
    401403     * builds the {@see JSplitPane} which divides the editor in an upper and a lower
    402404     * half
    403      * 
     405     *
    404406     * @return the split panel
    405407     */
    406408    protected JSplitPane buildSplitPane() {
     
    414416
    415417    /**
    416418     * build the panel with the buttons on the left
    417      * 
     419     *
    418420     * @return
    419421     */
    420422    protected JPanel buildLeftButtonPanel() {
     
    458460
    459461    /**
    460462     * build the panel with the buttons for adding or removing the current selection
    461      * 
     463     *
    462464     * @return
    463465     */
    464466    protected JPanel buildSelectionControlButtonPanel() {
     
    575577                        ),
    576578                        JOptionPane.WARNING_MESSAGE
    577579                );
    578                 JDialog dialog = op.createDialog(Main.pleaseWaitDlg, tr("Conflict created"));
     580                JDialog dialog = op.createDialog(this, tr("Conflict created"));
    579581                dialog.setAlwaysOnTop(true);
    580582                dialog.setModal(true);
    581583                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
     
    603605    private void downloadRelationMembers() {
    604606        if (!memberTableModel.hasIncompleteMembers())
    605607            return;
    606         Main.worker.submit(new DownloadTask());
     608        Main.worker.submit(new DownloadTask(this));
    607609    }
    608610
    609611    @Override
     
    980982
    981983    /**
    982984     * Action for editing the currently selected relation
    983      * 
     985     *
    984986     *
    985987     */
    986988    class EditAction extends AbstractAction implements ListSelectionListener {
     
    10131015
    10141016    /**
    10151017     * The asynchronous task for downloading relation members.
    1016      * 
     1018     *
    10171019     *
    10181020     */
    10191021    class DownloadTask extends PleaseWaitRunnable {
    10201022        private boolean cancelled;
     1023        private int conflictsCount;
    10211024        private Exception lastException;
    10221025
    1023         public DownloadTask() {
    1024             super(tr("Download relation members"), false /* don't ignore exception */);
     1026        public DownloadTask(Dialog parent) {
     1027            super(tr("Download relation members"), new PleaseWaitProgressMonitor(parent), false /* don't ignore exception */);
    10251028        }
    10261029        @Override
    10271030        protected void cancel() {
     
    10461049        protected void finish() {
    10471050            if (cancelled) return;
    10481051            memberTableModel.updateMemberReferences(getLayer().data);
    1049             if (lastException == null) return;
    1050             showLastException();
     1052            if (lastException != null) {
     1053                showLastException();
     1054            }
     1055
     1056            if (conflictsCount > 0) {
     1057                JOptionPane op = new JOptionPane(
     1058                        tr("There were {0} conflicts during import.",
     1059                                conflictsCount),
     1060                                JOptionPane.WARNING_MESSAGE
     1061                );
     1062                JDialog dialog = op.createDialog(GenericRelationEditor.this, tr("Conflicts in data"));
     1063                dialog.setAlwaysOnTop(true);
     1064                dialog.setModal(true);
     1065                dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
     1066                dialog.setVisible(true);
     1067            }
    10511068        }
    10521069
    10531070        @Override
    10541071        protected void realRun() throws SAXException, IOException, OsmTransferException {
    10551072            try {
    1056                 SwingUtilities.invokeLater(
    1057                         new Runnable() {
    1058                             public void run() {
    1059                                 Main.pleaseWaitDlg.setAlwaysOnTop(true);
    1060                                 Main.pleaseWaitDlg.toFront();
    1061                                 Main.pleaseWaitDlg.setIndeterminate(true);
    1062                             }
    1063                         }
    1064                 );
     1073                progressMonitor.indeterminateSubTask("");
    10651074                OsmServerObjectReader reader = new OsmServerObjectReader(getRelation().id, OsmPrimitiveType.RELATION, true);
    1066                 DataSet dataSet = reader.parseOsm();
     1075                DataSet dataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
    10671076                if (dataSet != null) {
    10681077                    final MergeVisitor visitor = new MergeVisitor(getLayer().data, dataSet);
    10691078                    visitor.merge();
     
    10831092                                }
    10841093                            }
    10851094                    );
    1086                     if (visitor.getConflicts().isEmpty())
    1087                         return;
    1088                     getLayer().getConflicts().add(visitor.getConflicts());
    1089                     JOptionPane op = new JOptionPane(
    1090                             tr("There were {0} conflicts during import.",
    1091                                     visitor.getConflicts().size()),
    1092                                     JOptionPane.WARNING_MESSAGE
    1093                     );
    1094                     JDialog dialog = op.createDialog(Main.pleaseWaitDlg, tr("Conflicts in data"));
    1095                     dialog.setAlwaysOnTop(true);
    1096                     dialog.setModal(true);
    1097                     dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
    1098                     dialog.setVisible(true);
     1095                    if (!visitor.getConflicts().isEmpty()) {
     1096                        getLayer().getConflicts().add(visitor.getConflicts());
     1097                        conflictsCount = visitor.getConflicts().size();
     1098                    }
    10991099                }
    11001100            } catch(Exception e) {
    11011101                if (cancelled) {
     
    11031103                    return;
    11041104                }
    11051105                lastException = e;
    1106             } finally {
    1107                 SwingUtilities.invokeLater(
    1108                         new Runnable() {
    1109                             public void run() {
    1110                                 Main.pleaseWaitDlg.setAlwaysOnTop(false);
    1111                                 Main.pleaseWaitDlg.setIndeterminate(false);
    1112                             }
    1113                         }
    1114                 );
    11151106            }
    11161107        }
    11171108    }
  • src/org/openstreetmap/josm/gui/dialogs/HistoryDialog.java

     
    2727import javax.swing.JScrollPane;
    2828import javax.swing.JTable;
    2929import javax.swing.ListSelectionModel;
    30 import javax.swing.SwingUtilities;
    3130import javax.swing.event.ListSelectionEvent;
    3231import javax.swing.event.ListSelectionListener;
    3332import javax.swing.table.DefaultTableCellRenderer;
     
    8685    /**
    8786     * unregisters a {@see HistoryBrowserDialog}
    8887     * @param id the id of the primitive whose history dialog is to be unregistered
    89      * 
     88     *
    9089     */
    9190    public static void unregisterHistoryBrowserDialog(long id) {
    9291        if (historyBrowserDialogs == null)
     
    9796    /**
    9897     * replies the history dialog for the primitive with id <code>id</code>; null, if
    9998     * no such {@see HistoryBrowserDialog} is currently showing
    100      * 
     99     *
    101100     * @param id the id of the primitive
    102101     * @return the dialog; null, if no such dialog is showing
    103102     */
     
    118117
    119118    /**
    120119     * builds the row with the command buttons
    121      * 
     120     *
    122121     * @return the rows with the command buttons
    123122     */
    124123    protected JPanel buildButtonRow() {
     
    208207
    209208    /**
    210209     * shows the {@see HistoryBrowserDialog} for a given {@see History}
    211      * 
     210     *
    212211     * @param h the history. Must not be null.
    213212     * @exception IllegalArgumentException thrown, if h is null
    214213     */
     
    224223
    225224    /**
    226225     * invoked after the asynchronous {@see HistoryLoadTask} is finished.
    227      * 
     226     *
    228227     * @param task the task which is calling back.
    229228     */
    230229    protected void postRefresh(HistoryLoadTask task) {
     
    260259
    261260    /**
    262261     * The table model with the history items
    263      * 
     262     *
    264263     */
    265264    class HistoryItemDataModel extends DefaultTableModel implements SelectionChangedListener{
    266265        private ArrayList<History> data;
     
    396395            postRefresh(this);
    397396        }
    398397
    399         /**
    400          * update the title of the {@see PleaseWaitDialog} with information about
    401          * which primitive is currently loaded
    402          *
    403          * @param primitive the primitive to be loaded
    404          */
    405         protected void notifyStartLoadingHistory(final OsmPrimitive primitive) {
    406             SwingUtilities.invokeLater(
    407                     new Runnable() {
    408                         public void run() {
    409                             Main.pleaseWaitDlg.setTitle(
    410                                     tr("Loading history for {0} with id {1}",
    411                                             OsmPrimitiveType.from(primitive).getLocalizedDisplayNameSingular(),
    412                                             Long.toString(primitive.id)
    413                                     )
    414                             );
    415                         }
    416                     }
    417             );
    418         }
    419 
    420         /**
    421          * enables/disables interminate progress indication in the {@see PleaseWaitDialog}
    422          *
    423          * @param enabled true, if interminate progress indication is to enabled; false, otherwise
    424          */
    425         protected void setInterminateEnabled(final boolean enabled) {
    426             SwingUtilities.invokeLater(
    427                     new Runnable() {
    428                         public void run() {
    429                             Main.pleaseWaitDlg.setIndeterminate(enabled);
    430                         }
    431                     }
    432             );
    433         }
    434 
    435398        @Override
    436399        protected void realRun() throws SAXException, IOException, OsmTransferException {
    437400            Collection<OsmPrimitive> selection = Main.ds.getSelected();
    438401            Iterator<OsmPrimitive> it = selection.iterator();
    439             setInterminateEnabled(true);
    440402            try {
    441403                while(it.hasNext()) {
    442404                    OsmPrimitive primitive = it.next();
     
    446408                    if (primitive.id == 0) {
    447409                        continue;
    448410                    }
    449                     notifyStartLoadingHistory(primitive);
     411                    progressMonitor.indeterminateSubTask(tr("Loading history for {0} with id {1}",
     412                            OsmPrimitiveType.from(primitive).getLocalizedDisplayNameSingular(),
     413                            Long.toString(primitive.id)));
    450414                    OsmServerHistoryReader reader = null;
    451415                    HistoryDataSet ds = null;
    452416                    try {
    453417                        reader = new OsmServerHistoryReader(OsmPrimitiveType.from(primitive), primitive.id);
    454                         ds = reader.parseHistory();
     418                        ds = reader.parseHistory(progressMonitor.createSubTaskMonitor(1, false));
    455419                    } catch(OsmTransferException e) {
    456420                        if (cancelled)
    457421                            return;
     
    462426            } catch(OsmTransferException e) {
    463427                lastException = e;
    464428                return;
    465             } finally {
    466                 setInterminateEnabled(false);
    467429            }
    468430        }
    469431
  • src/org/openstreetmap/josm/gui/layer/GpxLayer.java

     
    5050import org.openstreetmap.josm.data.coor.EastNorth;
    5151import org.openstreetmap.josm.data.coor.LatLon;
    5252import org.openstreetmap.josm.data.gpx.GpxData;
    53 import org.openstreetmap.josm.data.gpx.GpxRoute;
    5453import org.openstreetmap.josm.data.gpx.GpxTrack;
    5554import org.openstreetmap.josm.data.gpx.WayPoint;
    5655import org.openstreetmap.josm.data.osm.DataSet;
     
    6261import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    6362import org.openstreetmap.josm.gui.layer.markerlayer.AudioMarker;
    6463import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
     64import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
    6565import org.openstreetmap.josm.tools.AudioUtil;
    6666import org.openstreetmap.josm.tools.DateUtils;
    6767import org.openstreetmap.josm.tools.DontShowAgainInfo;
     
    841841                    JOptionPane.OK_CANCEL_OPTION) == JOptionPane.CANCEL_OPTION)
    842842                return;
    843843
    844             new DownloadOsmTaskList().download(false, toDownload);
     844            new DownloadOsmTaskList().download(false, toDownload, new PleaseWaitProgressMonitor());
    845845        }
    846846    }
    847847
  • src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java

     
    269269    }
    270270
    271271    private static final class Loader extends PleaseWaitRunnable {
    272         boolean cancelled = false;
    273272        private GeoImageLayer layer;
    274273        private final Collection<File> files;
    275274        private final GpxLayer gpxLayer;
     
    279278            this.gpxLayer = gpxLayer;
    280279        }
    281280        @Override protected void realRun() throws IOException {
    282             Main.pleaseWaitDlg.currentAction.setText(tr("Read GPX..."));
     281            progressMonitor.subTask(tr("Read GPX..."));
    283282            LinkedList<TimedPoint> gps = new LinkedList<TimedPoint>();
    284283
    285284            // Extract dates and locations from GPX input
     
    302301            }
    303302
    304303            if (gps.isEmpty()) {
    305                 errorMessage = tr("No images with readable timestamps found.");
     304                progressMonitor.setErrorMessage(tr("No images with readable timestamps found."));
    306305                return;
    307306            }
    308307
    309308            // read the image files
    310309            ArrayList<ImageEntry> data = new ArrayList<ImageEntry>(files.size());
    311             int i = 0;
    312             Main.pleaseWaitDlg.progress.setMaximum(files.size());
     310            progressMonitor.setTicksCount(files.size());
    313311            for (File f : files) {
    314                 if (cancelled)
     312                if (progressMonitor.isCancelled())
    315313                    break;
    316                 Main.pleaseWaitDlg.currentAction.setText(tr("Reading {0}...",f.getName()));
    317                 Main.pleaseWaitDlg.progress.setValue(i++);
     314                progressMonitor.subTask(tr("Reading {0}...",f.getName()));
    318315
    319316                ImageEntry e = new ImageEntry(f);
    320317                try {
     
    326323                    continue;
    327324
    328325                data.add(e);
     326                progressMonitor.worked(1);
    329327            }
    330328            layer = new GeoImageLayer(data, gps);
    331329            layer.calculatePosition();
     
    334332            if (layer != null)
    335333                Main.main.addLayer(layer);
    336334        }
    337         @Override protected void cancel() {cancelled = true;}
     335        @Override
     336        protected void cancel() {
     337
     338        }
    338339    }
    339340
    340341    public ArrayList<ImageEntry> data;