Index: trunk/src/org/openstreetmap/josm/actions/UploadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/actions/UploadAction.java	(revision 2319)
@@ -633,5 +633,6 @@
                 // we tried to delete an already deleted primitive.
                 //
-                System.out.println(tr("Warning: primitive ''{0}'' is already deleted on the server. Skipping this primitive and retrying to upload.", p.getDisplayName(DefaultNameFormatter.getInstance())));
+                System.out.println(tr("Warning: object ''{0}'' is already deleted on the server. Skipping this object and retrying to upload.", p.getDisplayName(DefaultNameFormatter.getInstance())));
+                monitor.appendLogMessage(tr("Object ''{0}'' is already deleted. Skipping object in upload.",p.getDisplayName(DefaultNameFormatter.getInstance())));
                 processedPrimitives.addAll(writer.getProcessedPrimitives());
                 processedPrimitives.add(p);
@@ -648,12 +649,10 @@
             writer = new OsmServerWriter();
             try {
-                //
                 while(true) {
                     try {
-                        ProgressMonitor monitor = progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false);
-                        writer.uploadOsm(layer.data.version, toUpload, changeset, monitor);
+                        getProgressMonitor().subTask(tr("Uploading {0} objects ...", toUpload.size()));
+                        writer.uploadOsm(layer.data.version, toUpload, changeset, getProgressMonitor().createSubTaskMonitor(1, false));
                         processedPrimitives.addAll(writer.getProcessedPrimitives());
-                        // if we get here we've successfully uploaded the data. We
-                        // can exit the loop.
+                        // if we get here we've successfully uploaded the data. Exit the loop.
                         //
                         break;
@@ -672,5 +671,5 @@
             } catch (Exception e) {
                 if (uploadCancelled) {
-                    System.out.println("Ignoring exception caught because upload is cancelled. Exception is: " + e.toString());
+                    System.out.println(tr("Ignoring caught exception because upload is canceled. Exception is: {0}", e.toString()));
                     return;
                 }
Index: trunk/src/org/openstreetmap/josm/gui/PleaseWaitDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/PleaseWaitDialog.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/gui/PleaseWaitDialog.java	(revision 2319)
@@ -2,7 +2,10 @@
 package org.openstreetmap.josm.gui;
 
-import java.awt.Dialog;
-import java.awt.Frame;
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.event.ActionListener;
 import java.awt.event.ComponentEvent;
 import java.awt.event.ComponentListener;
@@ -13,11 +16,14 @@
 import javax.swing.JDialog;
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JProgressBar;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
 import javax.swing.UIManager;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.GBC;
-import org.openstreetmap.josm.tools.I18n;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 public class PleaseWaitDialog extends JDialog {
@@ -28,5 +34,8 @@
     private final JLabel customText = new JLabel("");
     public final BoundedRangeModel progress = progressBar.getModel();
-    public final JButton cancel = new JButton(I18n.tr("Cancel"));
+    private  JButton btnCancel;
+    /** the text area and the scroll pane for the log */
+    private JTextArea taLog = new JTextArea(5,50);
+    private  JScrollPane spLog;
 
     private void initDialog() {
@@ -37,9 +46,17 @@
         pane.add(customText, GBC.eol().fill(GBC.HORIZONTAL));
         pane.add(progressBar, GBC.eop().fill(GBC.HORIZONTAL));
-        pane.add(cancel, GBC.eol().anchor(GBC.CENTER));
+        btnCancel = new JButton(tr("Cancel"));
+        btnCancel.setIcon(ImageProvider.get("cancel"));
+        btnCancel.setToolTipText(tr("Click to cancel the current operation"));
+        pane.add(btnCancel, GBC.eol().anchor(GBC.CENTER));
+        GridBagConstraints gc = GBC.eol().fill(GBC.BOTH);
+        gc.weighty = 1.0;
+        gc.weightx = 1.0;
+        pane.add(spLog = new JScrollPane(taLog), gc);
+        spLog.setVisible(false);
         setContentPane(pane);
         //setSize(Main.pref.getInteger("progressdialog.size",600),100);
         setCustomText("");
-        setLocationRelativeTo(Main.parent);
+        setLocationRelativeTo(getParent());
         addComponentListener(new ComponentListener() {
             public void componentHidden(ComponentEvent e) {}
@@ -55,11 +72,6 @@
     }
 
-    public PleaseWaitDialog(Frame parent) {
-        super(parent, true);
-        initDialog();
-    }
-
-    public PleaseWaitDialog(Dialog parent) {
-        super(parent, true);
+    public PleaseWaitDialog(Component parent) {
+        super(JOptionPane.getFrameForComponent(parent), true);
         initDialog();
     }
@@ -70,4 +82,10 @@
     }
 
+    protected void adjustLayout() {
+        invalidate();
+        pack();
+        setSize(Main.pref.getInteger("progressdialog.size", 600), getSize().height);
+    }
+
     /**
      * Sets a custom text line below currentAction. Can be used to display additional information
@@ -75,13 +93,59 @@
      */
     public void setCustomText(String text) {
-        if(text.length() == 0) {
+        if(text == null || text.trim().length() == 0) {
             customText.setVisible(false);
-            setSize(Main.pref.getInteger("progressdialog.size", 600), 100);
+            adjustLayout();
             return;
         }
+        if (!customText.isVisible()) {
+            customText.setVisible(true);
+            adjustLayout();
+        }
+        customText.setText(text);
+    }
 
-        customText.setVisible(true);
-        customText.setText(text);
-        setSize(Main.pref.getInteger("progressdialog.size", 600), 120);
+    /**
+     * Appends a log message to the progress dialog. If the log area isn't visible yet
+     * it becomes visible. The height of the progress dialog is slightly increased too.
+     * 
+     * @param message the message to append to the log. Ignore if null or white space only.
+     */
+    public void appendLogMessage(String message) {
+        if (message == null || message.trim().length() ==0 )
+            return;
+        if (!spLog.isVisible()) {
+            spLog.setVisible(true);
+            taLog.setVisible(true);
+            adjustLayout();
+        }
+        taLog.append(message);
+        taLog.append("\n");
+        spLog.getVerticalScrollBar().setValue(spLog.getVerticalScrollBar().getMaximum());
+    }
+
+    /**
+     * Sets whether the cancel button is enabled or not
+     * 
+     * @param enabled true, if the cancel button is enabled; false otherwise
+     */
+    public void setCancelEnabled(boolean enabled) {
+        btnCancel.setEnabled(enabled);
+    }
+
+    /**
+     * Installs a callback for the cancel button. If callback is null, all action listeners
+     * are removed from the cancel button.
+     * 
+     * @param callback the cancel callback
+     */
+    public void setCancelCallback(ActionListener callback) {
+        if (callback == null) {
+            ActionListener[] listeners = btnCancel.getActionListeners();
+            for (ActionListener l: listeners) {
+                btnCancel.removeActionListener(l);
+            }
+        } else {
+            btnCancel.addActionListener(callback);
+        }
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/gui/PleaseWaitRunnable.java	(revision 2319)
@@ -39,6 +39,7 @@
     /**
      * Create the runnable object with a given message for the user.
-     * @param title Message for user
-     * @param ignoreException If true, exception will be propaged to calling code. If false then
+     * 
+     * @param title message for the user
+     * @param ignoreException If true, exception will be propagated to calling code. If false then
      * exception will be thrown directly in EDT. When this runnable is executed using executor framework
      * then use false unless you read result of task (because exception will get lost if you don't)
@@ -52,5 +53,4 @@
         this.progressMonitor = progressMonitor == null?new PleaseWaitProgressMonitor(title):progressMonitor;
         this.ignoreException = ignoreException;
-        this.progressMonitor.addCancelListener(this);
     }
 
@@ -58,4 +58,5 @@
         try {
             try {
+                progressMonitor.addCancelListener(this);
                 progressMonitor.beginTask(title);
                 try {
@@ -90,4 +91,8 @@
             } finally {
                 progressMonitor.finishTask();
+                progressMonitor.removeCancelListener(this);
+                if (progressMonitor instanceof PleaseWaitProgressMonitor) {
+                    ((PleaseWaitProgressMonitor)progressMonitor).close();
+                }
             }
         } catch (final Throwable e) {
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 2319)
@@ -359,14 +359,4 @@
                 }
             });
-            addMouseListener(
-                    new MouseAdapter() {
-                        @Override
-                        public void mouseEntered(MouseEvent e) {
-                            super.mouseEntered(e);
-                            System.out.println("requesting focus ...");
-                            requestFocusInWindow();
-                        }
-                    }
-            );
 
             String bounds = Main.pref.get(preferencePrefix+".bounds",null);
Index: trunk/src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/gui/progress/AbstractProgressMonitor.java	(revision 2319)
@@ -60,7 +60,6 @@
     protected void checkState(State... expectedStates) {
         for (State s:expectedStates) {
-            if (s == state) {
+            if (s == state)
                 return;
-            }
         }
         throw new ProgressException("Expected states are %s but current state is %s", Arrays.asList(expectedStates).toString(), state);
@@ -154,4 +153,11 @@
             resetState();
         }
+    }
+
+    /**
+     * Default implementation is empty. Override in subclasses to display the log messages.
+     */
+    public void appendLogMessage(String message) {
+        // do nothing
     }
 
@@ -327,7 +333,6 @@
     private Request getRequest(AbstractProgressMonitor child) {
         for (Request request:requests) {
-            if (request.originator == child) {
+            if (request.originator == child)
                 return request;
-            }
         }
         throw new ProgressException("Subtask %s not found", child);
Index: trunk/src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java	(revision 2319)
@@ -60,4 +60,7 @@
     }
 
+    public void appendLogMessage(String message) {
+    }
+
     public void setSilent(boolean value) {
     }
Index: trunk/src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/gui/progress/PleaseWaitProgressMonitor.java	(revision 2319)
@@ -1,6 +1,4 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.progress;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.awt.Dialog;
@@ -13,5 +11,4 @@
 import java.awt.event.WindowEvent;
 import java.awt.event.WindowListener;
-import java.lang.reflect.InvocationTargetException;
 
 import javax.swing.JOptionPane;
@@ -35,5 +32,5 @@
 
     public PleaseWaitProgressMonitor(String windowTitle) {
-        this(JOptionPane.getFrameForComponent(Main.map));
+        this(JOptionPane.getFrameForComponent(Main.parent));
         this.windowTitle = windowTitle;
     }
@@ -53,27 +50,6 @@
         @Override public void windowClosing(WindowEvent e) {
             cancel();
-            closeDialog();
         }
     };
-
-    private void closeDialog() {
-        try {
-            Runnable runnable = new Runnable(){
-                public void run() {
-                }
-            };
-
-            // make sure, this is called in the dispatcher thread ASAP
-            if (EventQueue.isDispatchThread()) {
-                runnable.run();
-            } else {
-                EventQueue.invokeAndWait(runnable);
-            }
-
-        } catch (InterruptedException e) {
-        } catch (InvocationTargetException e) {
-            throw new RuntimeException(e);
-        }
-    }
 
     private void doInEDT(Runnable runnable) {
@@ -85,8 +61,8 @@
         doInEDT(new Runnable() {
             public void run() {
-                if (dialogParent instanceof Frame) {
-                    dialog = new PleaseWaitDialog((Frame)dialogParent);
-                } else if (dialogParent instanceof Dialog) {
-                    dialog = new PleaseWaitDialog((Dialog)dialogParent);
+                if (dialogParent instanceof Frame && dialog == null) {
+                    dialog = new PleaseWaitDialog(dialogParent);
+                } else if (dialogParent instanceof Dialog && dialog == null) {
+                    dialog = new PleaseWaitDialog(dialogParent);
                 } else
                     throw new ProgressException("PleaseWaitDialog parent must be either Frame or Dialog");
@@ -95,7 +71,7 @@
                     dialog.setTitle(windowTitle);
                 }
-                dialog.cancel.setEnabled(true);
+                dialog.setCancelEnabled(true);
+                dialog.setCancelCallback(cancelListener);
                 dialog.setCustomText("");
-                dialog.cancel.addActionListener(cancelListener);
                 dialog.addWindowListener(windowListener);
                 dialog.progress.setMaximum(PROGRESS_BAR_MAX);
@@ -107,21 +83,5 @@
     @Override
     public void doFinishTask() {
-        doInEDT(new Runnable() {
-            public void run() {
-                if (dialog != null) {
-                    dialog.setVisible(false);
-                    dialog.dispose();
-                    dialog.removeWindowListener(windowListener);
-                    dialog.cancel.removeActionListener(cancelListener);
-                    if (getErrorMessage() != null) {
-                        JOptionPane.showMessageDialog(
-                                Main.parent, getErrorMessage(),
-                                tr("Error"),
-                                JOptionPane.ERROR_MESSAGE);
-                    }
-                    dialog = null;
-                }
-            }
-        });
+        // do nothing
     }
 
@@ -164,5 +124,5 @@
             public void run() {
                 if (value && dialog.progress.getValue() == 0) {
-                    // Enable only if progress is at the begging. Doing intermediate progress in the middle
+                    // Enable only if progress is at the beginning. Doing intermediate progress in the middle
                     // will hide already reached progress
                     dialog.setIndeterminate(true);
@@ -179,3 +139,19 @@
     }
 
+    @Override
+    public void appendLogMessage(final String message) {
+        doInEDT(new Runnable() {
+            public void run() {
+                dialog.appendLogMessage(message);
+            }
+        });
+    }
+
+    public void close() {
+        dialog.setVisible(false);
+        dialog.setCancelCallback(null);
+        dialog.removeWindowListener(windowListener);
+        dialog.dispose();
+        dialog = null;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/progress/ProgressMonitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/progress/ProgressMonitor.java	(revision 2318)
+++ trunk/src/org/openstreetmap/josm/gui/progress/ProgressMonitor.java	(revision 2319)
@@ -123,3 +123,10 @@
     void setErrorMessage(String message);
     String getErrorMessage();
+
+    /**
+     * Appends a message to the log managed by the progress monitor.
+     * 
+     * @param message the log message. Ignored if null or white space only.
+     */
+    void appendLogMessage(String message);
 }
