Index: src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 2021)
+++ src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(working copy)
@@ -464,12 +464,19 @@
                     }
                     if(s.size() > max)
                     {
-                        if(1 != new ExtendedDialog(Main.parent, tr("Move elements"),
-                                tr("You did move more than {0} elements. "
-                                        + "Moving a large number of elements is often an error.\n"
-                                        + "Really move them?", max),
-                                        new String[] {tr("Move them"), tr("Undo move")},
-                                        new String[] {"reorder.png", "cancel.png"}).getValue())
+                        ExtendedDialog ed = new ExtendedDialog(
+                                Main.parent,
+                                tr("Move elements"),
+                                new String[] {tr("Move them"), tr("Undo move")});
+                        ed.setButtonIcons(new String[] {"reorder.png", "cancel.png"});
+                        ed.setContent(tr("You moved more than {0} elements. "
+                                + "Moving a large number of elements is often an error.\n"
+                                + "Really move them?", max));
+                        ed.toggleEnable("movedManyElements");
+                        ed.setToggleCheckboxText(tr("Always move and don't show dialog again"));
+                        ed.showDialog();
+
+                        if(ed.getValue() != 1 && ed.getValue() != ExtendedDialog.DialogNotShown)
                         {
                             Main.main.undoRedo.undo();
                         }
Index: src/org/openstreetmap/josm/gui/ExtendedDialog.java
===================================================================
--- src/org/openstreetmap/josm/gui/ExtendedDialog.java	(revision 2021)
+++ src/org/openstreetmap/josm/gui/ExtendedDialog.java	(working copy)
@@ -1,5 +1,7 @@
 package org.openstreetmap.josm.gui;
 
+import static org.openstreetmap.josm.tools.I18n.tr;
+
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.GridBagLayout;
@@ -10,6 +12,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.JButton;
+import javax.swing.JCheckBox;
 import javax.swing.JComponent;
 import javax.swing.JDialog;
 import javax.swing.JOptionPane;
@@ -18,20 +21,65 @@
 import javax.swing.JScrollPane;
 import javax.swing.KeyStroke;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
 
 
 public class ExtendedDialog extends JDialog {
     private int result = 0;
+    public static final int DialogNotShown = -99;
+    public static final int DialogClosedOtherwise = 0;
+    private boolean toggleable = false;
+    private String togglePref = "";
+    private String toggleCheckboxText = tr("Do not show again");
+    private JCheckBox toggleCheckbox = null;
     private Component parent;
+    private Component content;
     private final String[] bTexts;
+    private String[] bIcons;
 
     // For easy access when inherited
     protected Object contentConstraints = GBC.eol().anchor(GBC.CENTER).fill(GBC.HORIZONTAL).insets(5,10,5,0);
     protected ArrayList<JButton> buttons = new ArrayList<JButton>();
 
     /**
+     * This method sets up the most basic options for the dialog. Add all more
+     * advanced features with dedicated methods.
+     * Possible features:
+     * <ul>
+     *   <li><code>setButtonIcons</code></li>
+     *   <li><code>setContent</code></li>
+     *   <li><code>toggleEnable</code></li>
+     *   <li><code>toggleDisable</code></li>
+     *   <li><code>setToggleCheckboxText</code></li>
+     * </ul>
+     * 
+     * When done, call <code>showDialog</code> to display it. You can receive
+     * the user's choice using <code>getValue</code>. Have a look at this function
+     * for possible return values.
+     * 
+     * @param parent       The parent element that will be used for position and maximum size
+     * @param title        The text that will be shown in the window titlebar
+     * @param buttonTexts  String Array of the text that will appear on the buttons. The first button is the default one.
+     */
+    public ExtendedDialog(Component parent, String title, String[] buttonTexts) {
+        super(JOptionPane.getFrameForComponent(parent), title, true);
+        this.parent = parent;
+        bTexts = buttonTexts;
+    }
+
+    /**
+     * Same as above but lets you define if the dialog should be modal.
+     */
+    public ExtendedDialog(Component parent, String title, String[] buttonTexts,
+            boolean modal) {
+        super(JOptionPane.getFrameForComponent(parent), title, modal);
+        this.parent = parent;
+        bTexts = buttonTexts;
+    }
+
+    /**
      * Sets up the dialog. The first button is always the default.
      * @param parent The parent element that will be used for position and maximum size
      * @param title The text that will be shown in the window titlebar
@@ -39,49 +87,104 @@
      * @param buttonTexts The labels that will be displayed on the buttons
      * @param buttonIcons The path to the icons that will be displayed on the buttons. Path is relative to JOSM's image directory. File extensions need to be included. If a button should not have an icon pass null.
      */
-    public ExtendedDialog(Component parent, String title, Component content, String[] buttonTexts, String[] buttonIcons) {
+    @Deprecated public ExtendedDialog(Component parent, String title, Component content,
+            String[] buttonTexts, String[] buttonIcons) {
         super(JOptionPane.getFrameForComponent(parent), title, true /* modal */);
         this.parent = parent;
         bTexts = buttonTexts;
-        setupDialog(content, buttonIcons);
+        this.content = content;
+        this.bIcons = buttonIcons;
+        setupDialog();
         setVisible(true);
     }
 
-    public ExtendedDialog(Component parent, String title, Component content, String[] buttonTexts) {
+    @Deprecated public ExtendedDialog(Component parent, String title, Component content,
+            String[] buttonTexts) {
         this(parent, title, content, buttonTexts, null);
     }
 
     /**
      * Sets up the dialog and displays the given message in a breakable label
      */
-    public ExtendedDialog(Component parent, String title, String message, String[] buttonTexts, String[] buttonIcons) {
-        super(JOptionPane.getFrameForComponent(parent), title, true);
+    @Deprecated public ExtendedDialog(Component parent, String title, String message,
+            String[] buttonTexts, String[] buttonIcons) {
+        this(parent, title, string2label(message), buttonTexts, buttonIcons);
+    }
 
-        JMultilineLabel lbl = new JMultilineLabel(message);
-        // Make it not wider than 2/3 of the screen
-        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
-        lbl.setMaxWidth(Math.round(screenSize.width*2/3));
+    @Deprecated public ExtendedDialog(Component parent, String title, String message,
+            String[] buttonTexts) {
+        this(parent, title, message, buttonTexts, null);
+    }
 
-        this.parent = parent;
-        bTexts = buttonTexts;
-        setupDialog(lbl, buttonIcons);
-        setVisible(true);
+    /**
+     * Allows decorating the buttons with icons. Expects an String[] with paths
+     * to images relative to JOSM/images.
+     * @param buttonIcons
+     */
+    public void setButtonIcons(String[] buttonIcons) {
+        this.bIcons = buttonIcons;
     }
 
-    public ExtendedDialog(Component parent, String title, String message, String[] buttonTexts) {
-        this(parent, title, message, buttonTexts, null);
+    /**
+     * Sets the content that will be displayed in the message dialog.
+     * 
+     * Note that depending on your other settings more UI elements may appear.
+     * The content is played on top of the other elements though.
+     * 
+     * @param content Any element that can be displayed in the message dialog
+     */
+    public void setContent(Component content) {
+        this.content = content;
     }
 
     /**
-     * Constructor that doesn't make the dialog visible immediately. Intended for when inheriting.
+     * Sets the message that will be displayed. The String will be automatically
+     * wrapped if it is too long.
+     * 
+     * Note that depending on your other settings more UI elements may appear.
+     * The content is played on top of the other elements though.
+     * 
+     * @param message The text that should be shown to the user
      */
-    public ExtendedDialog(Component parent, String title, String[] buttonTexts, boolean modal) {
-        super(JOptionPane.getFrameForComponent(parent), title, modal);
-        this.parent = parent;
-        bTexts = buttonTexts;
+    public void setContent(String message) {
+        setContent(string2label(message));
+    }
+
+
+
+    /**
+     * Show the dialog to the user. Call this after you have set all options
+     * for the dialog. You can retrieve the result using <code>getValue</code>
+     */
+    public void showDialog() {
+        // Check if the user has set the dialog to not be shown again
+        if(toggleCheckState(togglePref)) {
+            result = ExtendedDialog.DialogNotShown;
+            return;
+        }
+
+        setupDialog();
+        setVisible(true);
+        toggleSaveState();
+    }
+
+    /**
+     * @return int * The selected button. The count starts with 1.
+     *             * A return value of ExtendedDialog.DialogClosedOtherwise means the dialog has been closed otherwise.
+     *             * A return value of ExtendedDialog.DialogNotShown means the
+     *               dialog has been toggled off in the past
+     */
+    public int getValue() {
+        return result;
     }
 
-    protected void setupDialog(Component content, String[] buttonIcons) {
+    @Deprecated protected void setupDialog(Component content, String[] buttonIcons) {
+        this.setContent(content);
+        this.setButtonIcons(buttonIcons);
+        this.setupDialog();
+    }
+
+    protected void setupDialog() {
         setupEscListener();
 
         JButton button;
@@ -95,8 +198,8 @@
             };
 
             button = new JButton(action);
-            if(buttonIcons != null && buttonIcons[i] != null) {
-                button.setIcon(ImageProvider.get(buttonIcons[i]));
+            if(bIcons != null && bIcons[i] != null) {
+                button.setIcon(ImageProvider.get(bIcons[i]));
             }
 
             if(i == 0) {
@@ -108,6 +211,14 @@
 
         JPanel cp = new JPanel(new GridBagLayout());
         cp.add(content, contentConstraints);
+
+        if(toggleable) {
+            toggleCheckbox = new JCheckBox(toggleCheckboxText);
+            boolean showDialog = Main.pref.getBoolean("message."+ togglePref, true);
+            toggleCheckbox.setSelected(!showDialog);
+            cp.add(toggleCheckbox, GBC.eol().anchor(GBC.LINE_START).insets(5,5,5,5));
+        }
+
         cp.add(buttonsPanel, GBC.eol().anchor(GBC.CENTER).insets(5,5,5,5));
 
         JScrollPane pane = new JScrollPane(cp);
@@ -140,14 +251,6 @@
     }
 
     /**
-     * @return int The selected button. The count starts with 1.
-     *             A return value of 0 means the dialog has been closed otherwise.
-     */
-    public int getValue() {
-        return result;
-    }
-
-    /**
      * This gets performed whenever a button is clicked or activated
      * @param evt the button event
      */
@@ -187,7 +290,7 @@
                 // 0 means that the dialog has been closed otherwise.
                 // We need to set it to zero again, in case the dialog has been re-used
                 // and the result differs from its default value
-                result = 0;
+                result = ExtendedDialog.DialogClosedOtherwise;
                 setVisible(false);
             }
         };
@@ -204,4 +307,73 @@
             toFront();
         }
     }
+
+    /**
+     * Calling this will offer the user a "Do not show again" checkbox for the
+     * dialog. Default is to not offer the choice; the dialog will be shown
+     * every time. If the dialog is not shown due to the previous choice of the
+     * user, the result <code>ExtendedDialog.DialogNotShown</code> is returned
+     * @param togglePref  The preference to save the checkbox state to
+     */
+    public void toggleEnable(String togglePref) {
+        this.toggleable = true;
+        this.togglePref = togglePref;
+    }
+
+    /**
+     * Call this if you "accidentally" called toggleEnable. This doesn't need
+     * to be called for every dialog, as it's the default anyway.
+     */
+    public void toggleDisable() {
+        this.toggleable = false;
+    }
+
+    /**
+     * Overwrites the default "Don't show again" text of the toggle checkbox
+     * if you want to give more information. Only has an effect if
+     * <code>toggleEnable</code> is set.
+     * @param text
+     */
+    public void setToggleCheckboxText(String text) {
+        this.toggleCheckboxText = text;
+    }
+
+    /**
+     * This function returns true if the dialog has been set to "do not show again"
+     * @return true if dialog should not be shown again
+     */
+    private boolean toggleCheckState(String togglePref) {
+        toggleable = togglePref != null && !togglePref.equals("");
+
+        // No identifier given, so return false (= show the dialog)
+        if(!toggleable)
+            return false;
+
+        this.togglePref = togglePref;
+        // The pref is true, if the dialog should be shown.
+        return !(Main.pref.getBoolean("message."+ togglePref, true));
+    }
+
+    /**
+     * This function checks the state of the "Do not show again" checkbox and
+     * writes the corresponding pref
+     */
+    private void toggleSaveState() {
+        if(!toggleable || toggleCheckbox == null)
+            return;
+        Main.pref.put("message."+ togglePref, !toggleCheckbox.isSelected());
+    }
+
+    /**
+     * Convenience function that converts a given string into a JMultilineLabel
+     * @param msg
+     * @return JMultilineLabel
+     */
+    private static JMultilineLabel string2label(String msg) {
+        JMultilineLabel lbl = new JMultilineLabel(msg);
+        // Make it not wider than 2/3 of the screen
+        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+        lbl.setMaxWidth(Math.round(screenSize.width*2/3));
+        return lbl;
+    }
 }
\ No newline at end of file
