Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/CalibrationLayer.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/CalibrationLayer.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/CalibrationLayer.java	(revision 29377)
@@ -87,30 +87,11 @@
     @Override
     public String getToolTipText() {
-        return "A calibration " + getGeometryType() + " by " + obj.getAuthor();
+        return "A " + (obj.isDeprecated() ? "deprecated " : "") + "calibration " + OffsetInfoAction.getGeometryType(obj)
+                + " by " + obj.getAuthor();
     }
 
     @Override
     public Object getInfoComponent() {
-        String info = "A calibration " + getGeometryType() + "\n"
-                + "Created by " + obj.getAuthor() + " on " + ImageryOffsetTools.DATE_FORMAT.format(obj.getDate()) + "\n"
-                + "Description: " + obj.getDescription();
-        if( obj.isDeprecated() ) {
-            info += "\nThis geometry was marked obsolete\n"
-                    + "by " + obj.getAbandonAuthor() + " on " + ImageryOffsetTools.DATE_FORMAT.format(obj.getAbandonDate()) + "\n"
-                    + "Reason: " + obj.getAbandonReason();
-        }
-        return info;
-    }
-
-    private String getGeometryType() {
-        int n = obj.getGeometry().length;
-        if( n == 1 )
-            return "point";
-        else if( n > 1 && !obj.getGeometry()[0].equals(obj.getGeometry()[n-1]) )
-            return "path";
-        else if( n > 1 && obj.getGeometry()[0].equals(obj.getGeometry()[n-1]) )
-            return "polygon";
-        else
-            return "geometry";
+        return OffsetInfoAction.getInformationObject(obj);
     }
 
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/DeprecateOffsetAction.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/DeprecateOffsetAction.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/DeprecateOffsetAction.java	(revision 29377)
@@ -30,6 +30,8 @@
             return;
         
+        String desc = offset instanceof ImageryOffset ? "imagery offset is wrong"
+                : "calibration geometry is aligned badly";
         if( JOptionPane.showConfirmDialog(Main.parent,
-                tr("Warning: deprecation is irreversible"), // todo: expand
+                tr("Warning: deprecation is basically irreversible!\nAre you sure this " + desc + "?"),
                 ImageryOffsetTools.DIALOG_TITLE, JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) != JOptionPane.YES_OPTION ) {
             return;
@@ -46,20 +48,8 @@
 
         String message = "Please enter the reason why you mark this "
-                + (offset instanceof ImageryOffset ? "imagery offset" : "calibraion object") + " as deprecated:";
-        String reason = null;
-        boolean iterated = false;
-        while( reason == null ) {
-            reason = JOptionPane.showInputDialog(Main.parent, message, ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE);
-            if( reason == null || reason.length() == 0 ) {
-                return;
-            }
-            if( reason.length() < 3 || reason.length() > 200 ) {
-                reason = null;
-                if( !iterated ) {
-                    message = message + "\n" + tr("Reason text should be 3 to 200 letters long.");
-                    iterated = true;
-                }
-            }
-        }
+                + (offset instanceof ImageryOffset ? "imagery offset" : "calibraion geometry") + " as deprecated:";
+        String reason = StoreImageryOffsetAction.queryDescription(message);
+        if( reason == null )
+            return;
         
         try {
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/GetImageryOffsetAction.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/GetImageryOffsetAction.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/GetImageryOffsetAction.java	(revision 29377)
@@ -71,5 +71,5 @@
                 clayer.panToCenter();
                 if( !Main.pref.getBoolean("iodb.calibration.message", false) ) {
-                    JOptionPane.showMessageDialog(Main.parent, // todo: update text
+                    JOptionPane.showMessageDialog(Main.parent,
                             tr("A layer has been added with a calibration geometry. Hide data layers,\n"
                             + "find the corresponding feature on the imagery layer and move it accordingly."),
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetPlugin.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetPlugin.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetPlugin.java	(revision 29377)
@@ -1,7 +1,10 @@
 package iodb;
 
+import java.awt.event.KeyEvent;
+import javax.swing.JMenu;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.plugins.Plugin;
 import org.openstreetmap.josm.plugins.PluginInformation;
+import static org.openstreetmap.josm.tools.I18n.marktr;
 
 /**
@@ -20,8 +23,7 @@
         storeAction = new StoreImageryOffsetAction();
         
-        // todo: correct menu
-        Main.main.menu.viewMenu.addSeparator();
-        Main.main.menu.viewMenu.add(getAction);
-        Main.main.menu.viewMenu.add(storeAction);
+        JMenu offsetMenu = Main.main.menu.addMenu(marktr("Offset"), KeyEvent.VK_O, 6, "help");
+        offsetMenu.add(getAction);
+        offsetMenu.add(storeAction);
 
         // todo: add a button on toolbar
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetTools.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetTools.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/ImageryOffsetTools.java	(revision 29377)
@@ -19,5 +19,4 @@
 public class ImageryOffsetTools {
     public static final String DIALOG_TITLE = tr("Imagery Offset");
-    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
     
     public static ImageryLayer getTopImageryLayer() {
@@ -42,5 +41,5 @@
         Projection proj = Main.getProjection();
         EastNorth offsetCenter = proj.latlon2eastNorth(center);
-        EastNorth centerOffset = offsetCenter.add(-layer.getDx(), -layer.getDy()); // todo: add or substract?
+        EastNorth centerOffset = offsetCenter.add(-layer.getDx(), -layer.getDy());
         LatLon offsetLL = proj.eastNorth2latlon(centerOffset);
         return offsetLL;
@@ -48,8 +47,17 @@
     
     public static void applyLayerOffset( ImageryLayer layer, ImageryOffset offset ) {
+        double[] dxy = calculateOffset(offset);
+        layer.setOffset(dxy[0], dxy[1]);
+    }
+
+    /**
+     * Calculate dx and dy for imagery offset.
+     * @return [dx, dy]
+     */
+    public static double[] calculateOffset( ImageryOffset offset ) {
         Projection proj = Main.getProjection();
         EastNorth center = proj.latlon2eastNorth(offset.getPosition());
         EastNorth offsetPos = proj.latlon2eastNorth(offset.getImageryPos());
-        layer.setOffset(center.getX() - offsetPos.getX(), center.getY() - offsetPos.getY());
+        return new double[] { center.getX() - offsetPos.getX(), center.getY() - offsetPos.getY() };
     }
     
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialog.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialog.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialog.java	(revision 29377)
@@ -22,4 +22,5 @@
     protected static final String PREF_CALIBRATION = "iodb.show.calibration";
     protected static final String PREF_DEPRECATED = "iodb.show.deprecated";
+    private static final int MAX_OFFSETS = Main.main.pref.getInteger("iodb.max.offsets", 5);
 
     private List<ImageryOffsetBase> offsets;
@@ -42,6 +43,5 @@
         Box dialog = new Box(BoxLayout.Y_AXIS);
         updateButtonPanel();
-        // todo: calibration objects and deprecated offsets button
-        final JCheckBox calibrationBox = new JCheckBox(tr("Hide calibration geometries"));
+        final JCheckBox calibrationBox = new JCheckBox(tr("Calibration geometries"));
         calibrationBox.setSelected(Main.pref.getBoolean(PREF_CALIBRATION, true));
         calibrationBox.addActionListener(new ActionListener() {
@@ -51,5 +51,5 @@
             }
         });
-        final JCheckBox deprecatedBox = new JCheckBox(tr("Show deprecated offsets"));
+        final JCheckBox deprecatedBox = new JCheckBox(tr("Deprecated offsets"));
         deprecatedBox.setSelected(Main.pref.getBoolean(PREF_DEPRECATED, false));
         deprecatedBox.addActionListener(new ActionListener() {
@@ -92,4 +92,5 @@
             buttonPanel.add(button);
         }
+//        buttonPanel.setMinimumSize(buttonPanel.getPreferredSize());
         pack();
     }
@@ -105,4 +106,6 @@
                 continue;
             filteredOffsets.add(offset);
+            if( filteredOffsets.size() >= MAX_OFFSETS )
+                break;
         }
         return filteredOffsets;
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialogButton.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialogButton.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetDialogButton.java	(revision 29377)
@@ -1,5 +1,12 @@
 package iodb;
 
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
 import javax.swing.JButton;
+import org.openstreetmap.josm.gui.layer.ImageryLayer;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -11,8 +18,21 @@
     
     private ImageryOffsetBase offset;
+    private double offsetLength;
+    private double distance;
+    private double direction;
 
     public OffsetDialogButton( ImageryOffsetBase offset ) {
-        super(offset.getDescription() + " (" + Math.round(offset.getPosition().greatCircleDistance(ImageryOffsetTools.getMapCenter())) + " m)");
+        super();
+        // todo: fix layout
+        setMinimumSize(new Dimension(500, 80));
+        setMaximumSize(new Dimension(500, 140));
+        setText("<html>"
+                + Math.round(offset.getPosition().greatCircleDistance(ImageryOffsetTools.getMapCenter())) + " m: "
+                + offset.getDescription() + "</html>");
+        setIcon(new OffsetIcon(offset));
         this.offset = offset;
+
+        offsetLength = offset instanceof ImageryOffset ? getLengthAndDirection((ImageryOffset)offset)[0] : 0.0;
+        // todo: layout, info, map distance and direction
     }
 
@@ -20,4 +40,51 @@
         return offset;
     }
-    
+
+/*    @Override
+    public Dimension getPreferredSize() {
+        return new Dimension(500, super.getPreferredSize().height);
+    }*/
+
+    private double[] getLengthAndDirection( ImageryOffset offset ) {
+        ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer();
+        double[] dxy = layer == null ? new double[] {0.0, 0.0} : new double[] {layer.getDx(), layer.getDy()};
+        return OffsetInfoAction.getLengthAndDirection((ImageryOffset)offset, dxy[0], dxy[1]);
+    }
+
+    class OffsetIcon implements Icon {
+        private boolean isDeprecated;
+        private boolean isCalibration;
+        private double direction;
+        private double length;
+        private ImageIcon background;
+
+        public OffsetIcon( ImageryOffsetBase offset ) {
+            isDeprecated = offset.isDeprecated();
+            isCalibration = offset instanceof CalibrationObject;
+            if( offset instanceof ImageryOffset ) {
+                background = ImageProvider.get("offset");
+                ImageryLayer layer = ImageryOffsetTools.getTopImageryLayer();
+                double[] dxy = layer == null ? new double[] {0.0, 0.0} : new double[] { layer.getDx(), layer.getDy() };
+                double[] ld = OffsetInfoAction.getLengthAndDirection((ImageryOffset)offset, dxy[0], dxy[1]);
+                length = ld[0];
+                direction = ld[1];
+            } else {
+                background = ImageProvider.get("calibration");
+            }
+        }
+
+        public void paintIcon( Component c, Graphics g, int x, int y ) {
+            background.paintIcon(c, g, x, y);
+            // todo: draw an arrow
+            // todo: apply deprecation
+        }
+
+        public int getIconWidth() {
+            return background.getIconWidth();
+        }
+
+        public int getIconHeight() {
+            return background.getIconHeight();
+        }
+    }
 }
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetInfoAction.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetInfoAction.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/OffsetInfoAction.java	(revision 29377)
@@ -2,7 +2,9 @@
 
 import java.awt.event.ActionEvent;
+import java.text.SimpleDateFormat;
 import javax.swing.AbstractAction;
 import javax.swing.JOptionPane;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.LatLon;
 import static org.openstreetmap.josm.tools.I18n.tr;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -14,15 +16,67 @@
  */
 public class OffsetInfoAction extends AbstractAction {
-    private ImageryOffsetBase offset;
+    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
+
+    private Object info;
     
     public OffsetInfoAction( ImageryOffsetBase offset ) {
         super(tr("Offset Information"));
-        putValue(SMALL_ICON, ImageProvider.get("dialogs", "delete"));
-        this.offset = offset;
+        putValue(SMALL_ICON, ImageProvider.get("info"));
+        if( offset != null )
+            this.info = getInformationObject(offset);
         setEnabled(offset != null);
     }
 
     public void actionPerformed(ActionEvent e) {
-        JOptionPane.showMessageDialog(Main.parent, "TODO", ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE);
+        JOptionPane.showMessageDialog(Main.parent, info, ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE);
+    }
+
+    public static Object getInformationObject( ImageryOffsetBase offset ) {
+        StringBuilder sb = new StringBuilder();
+        if( offset instanceof ImageryOffset ) {
+            double[] ld = getLengthAndDirection((ImageryOffset)offset);
+            sb.append(tr("An imagery offset of {0} m to {1}", ld[0], explainDirection(ld[1]))).append('\n');
+            sb.append("Imagery ID: ").append(((ImageryOffset)offset).getImagery());
+        } else
+            sb.append(tr("A calibration {0}", getGeometryType((CalibrationObject)offset)));
+        sb.append("\n\nCreated by ").append(offset.getAuthor());
+        sb.append(" on ").append(DATE_FORMAT.format(offset.getDate())).append("\n");
+        sb.append("Description: ").append(offset.getDescription());
+        if( offset.isDeprecated() ) {
+            sb.append("\n\nThis geometry was marked obsolete\n");
+            sb.append("by ").append(offset.getAbandonAuthor());
+            sb.append(" on ").append(DATE_FORMAT.format(offset.getAbandonDate())).append("\n");
+            sb.append("Reason: ").append(offset.getAbandonReason());
+        }
+        return sb.toString();
+    }
+
+    public static String getGeometryType( CalibrationObject obj ) {
+        if( obj.getGeometry() == null )
+            return tr("nothing");
+        int n = obj.getGeometry().length;
+        if( n == 1 )
+            return tr("point");
+        else if( n > 1 && !obj.getGeometry()[0].equals(obj.getGeometry()[n - 1]) )
+            return tr("path ({0} nodes)", n);
+        else if( n > 1 && obj.getGeometry()[0].equals(obj.getGeometry()[n - 1]) )
+            return tr("polygon ({0} nodes)", n - 1);
+        else
+            return "geometry";
+    }
+
+    public static double[] getLengthAndDirection( ImageryOffset offset ) {
+        return getLengthAndDirection(offset, 0.0, 0.0);
+    }
+
+    public static double[] getLengthAndDirection( ImageryOffset offset, double dx, double dy ) {
+        double length = 0.0;
+        double direction = 0.0;
+        // todo: calculate length and angular direction
+        return new double[] { length, direction };
+    }
+
+    public static String explainDirection( double dir ) {
+        return "nowhere"; // todo
     }
 }
Index: /applications/editors/josm/plugins/imagery_offset_db/src/iodb/StoreImageryOffsetAction.java
===================================================================
--- /applications/editors/josm/plugins/imagery_offset_db/src/iodb/StoreImageryOffsetAction.java	(revision 29376)
+++ /applications/editors/josm/plugins/imagery_offset_db/src/iodb/StoreImageryOffsetAction.java	(revision 29377)
@@ -47,5 +47,5 @@
             OsmPrimitive selection = selectedObjects.iterator().next();
             if( (selection instanceof Node || selection instanceof Way) && !selection.isIncomplete() && !selection.isReferredByWays(1) ) {
-                String[] options = new String[] {tr("Store calibration geometry"), tr("Store imagery offset"), tr("Cancel")};
+                String[] options = new String[] {tr("Store calibration geometry"), tr("Store imagery offset")};
                 int result = JOptionPane.showOptionDialog(Main.parent,
                         tr("The selected object can be used as a calibration geometry. What do you intend to do?"),
@@ -59,5 +59,5 @@
         }
 
-        Object message = "";
+        Object message;
         LatLon center = ImageryOffsetTools.getMapCenter();
         ImageryOffsetBase offsetObj;
@@ -76,23 +76,11 @@
             // register calibration object
             offsetObj = new CalibrationObject(calibration);
-            message = "You are registering a calibration geometry. It should be the most precisely positioned object,\n"
-                    + "with clearly visible boundaries on various satellite imagery.\n"
-                    + "Please describe a region where this object is located.";
+            message = "You are registering a calibration geometry. It should be the most precisely positioned object, with\n"
+                    + "clearly visible boundaries on various satellite imagery. Please describe this object and its whereabouts.";
         }
+        String description = queryDescription(message);
+        if( description == null )
+            return;
         offsetObj.setBasicInfo(center, userName, null, null);
-        String description = null;
-        boolean iterated = false;
-        while( description == null ) {
-            description = JOptionPane.showInputDialog(Main.parent, message, ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE);
-            if( description == null || description.length() == 0 )
-                return;
-            if( description.length() < 3 || description.length() > 200 ) {
-                description = null;
-                if( !iterated ) {
-                    message = message + "\n" + tr("Description should be 3 to 200 letters long.");
-                    iterated = true;
-                }
-            }
-        }
         offsetObj.setDescription(description);
 
@@ -116,4 +104,25 @@
     }
 
+    public static String queryDescription( Object message ) {
+        String reason = null;
+        boolean iterated = false;
+        boolean ok = false;
+        while( !ok ) {
+            Object result = JOptionPane.showInputDialog(Main.parent, message, ImageryOffsetTools.DIALOG_TITLE, JOptionPane.PLAIN_MESSAGE, null, null, reason);
+            if( result == null || result.toString().length() == 0 ) {
+                return null;
+            }
+            reason = result.toString();
+            if( reason.length() < 3 || reason.length() > 200 ) {
+                if( !iterated ) {
+                    message = message + "\n" + tr("This string should be 3 to 200 letters long.");
+                    iterated = true;
+                }
+            } else
+                ok = true;
+        }
+        return reason;
+    }
+
     @Override
     protected void updateEnabledState() {
