← Back to team overview

kicad-developers team mailing list archive

Eeschema field autoplacing: second rev

 

Here's the second revision of my Eeschema field autoplacing tool. The 
following changes have been made:

- Autoplace understands text justification
- Optional rejustification of fields (fields at the side are left- or 
  right-aligned; fields at the top and bottom are center-aligned)
- Smarter field location selector is aware of hidden pins

A few tweaks to existing features have been made as well.

Components by default are made with autoplaced fields when placed from 
the library. Autoplace is repeated automatically when the component is 
rotated or flipped or when relevant properties of fields (justification, 
hidden vs visible) are changed. Moving a field manually sets the 
component to non-autoplaced; pressing O over the component or 
right-clicking and choosing Autoplace Fields resets it. Copied 
components retain the autoplace status of the source.

This is quite helpful when making complicated schematics with many 
rotated parts. Try it out!

--
Chris

diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt
index 8cc642a..410b895 100644
--- a/bitmaps_png/CMakeLists.txt
+++ b/bitmaps_png/CMakeLists.txt
@@ -160,6 +160,7 @@ set( BMAPS_MID
     auto_associe
     auto_delete_track
     auto_track_width
+    autoplace_fields
     axis3d_back
     axis3d_bottom
     axis3d_front
diff --git a/bitmaps_png/cpp_26/autoplace_fields.cpp b/bitmaps_png/cpp_26/autoplace_fields.cpp
new file mode 100644
index 0000000..dda674b
--- /dev/null
+++ b/bitmaps_png/cpp_26/autoplace_fields.cpp
@@ -0,0 +1,79 @@
+
+/* Do not modify this file, it was automatically generated by the
+ * PNG2cpp CMake script, using a *.png file as input.
+ */
+
+#include <bitmaps.h>
+
+static const unsigned char png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
+ 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
+ 0xce, 0x00, 0x00, 0x03, 0xe2, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xb5, 0x95, 0x5b, 0x4c, 0x1c,
+ 0x55, 0x18, 0xc7, 0x17, 0x86, 0x65, 0x59, 0x96, 0xe5, 0xb6, 0x96, 0x94, 0x70, 0x09, 0x5a, 0x1e,
+ 0xec, 0x83, 0x24, 0x0a, 0x18, 0xa5, 0xd4, 0x27, 0x6d, 0xc0, 0x5b, 0x63, 0x43, 0x13, 0x1a, 0x23,
+ 0xd1, 0x90, 0xa6, 0x11, 0x1e, 0x2a, 0x0f, 0x5a, 0x48, 0x37, 0xb0, 0x4b, 0x40, 0x36, 0x43, 0x9b,
+ 0x46, 0xc1, 0xe0, 0x72, 0xe9, 0x83, 0xc5, 0x18, 0x78, 0x30, 0x36, 0x28, 0x89, 0xed, 0x43, 0xfb,
+ 0xd2, 0x9a, 0x1a, 0x74, 0x37, 0x69, 0x6d, 0x61, 0x4b, 0x69, 0xa1, 0x5c, 0xbb, 0x4b, 0x8a, 0x54,
+ 0xd7, 0x86, 0x86, 0xfe, 0xfd, 0x9f, 0x99, 0xb3, 0x66, 0x84, 0x96, 0xd4, 0xb8, 0x7b, 0x92, 0x5f,
+ 0x32, 0x33, 0x67, 0xe6, 0xfc, 0xce, 0xf9, 0xbe, 0xef, 0x9c, 0x31, 0x99, 0xfe, 0x7b, 0xeb, 0x24,
+ 0x35, 0xc4, 0x4e, 0x86, 0xc9, 0x0b, 0xe4, 0x25, 0x79, 0x2d, 0x70, 0x93, 0x78, 0x53, 0x14, 0x9a,
+ 0x9f, 0x1c, 0x27, 0x0e, 0x02, 0xf2, 0x26, 0x29, 0x26, 0x5e, 0xc9, 0x6f, 0xa4, 0x2b, 0x56, 0xa2,
+ 0x44, 0x92, 0x21, 0x19, 0x20, 0x17, 0x63, 0x25, 0xda, 0x2f, 0xaf, 0x05, 0x2b, 0x64, 0x57, 0x34,
+ 0x44, 0x2d, 0x64, 0x51, 0x0a, 0xa7, 0x48, 0x8e, 0x41, 0xb4, 0x4b, 0xde, 0x47, 0xad, 0x7d, 0x40,
+ 0x3a, 0x0c, 0x83, 0x3e, 0x47, 0x3c, 0xc4, 0xfc, 0x24, 0x1f, 0xd7, 0x3f, 0xe6, 0xc5, 0x83, 0x86,
+ 0x44, 0x3b, 0x49, 0x25, 0x69, 0x95, 0x7d, 0x75, 0x52, 0x9a, 0x46, 0xbe, 0x94, 0xef, 0x08, 0xe9,
+ 0xeb, 0x86, 0x6f, 0xde, 0xdb, 0x38, 0x60, 0xd0, 0x6c, 0x36, 0x07, 0x12, 0x12, 0x12, 0x36, 0xc6,
+ 0xf7, 0x23, 0x59, 0xb6, 0x33, 0xe4, 0x27, 0xe2, 0x22, 0xb3, 0xb2, 0xef, 0x47, 0xd9, 0xd7, 0x5c,
+ 0x58, 0x58, 0x88, 0x92, 0x92, 0x12, 0x11, 0xbe, 0x33, 0x64, 0x9f, 0x7c, 0x3e, 0x46, 0xd6, 0x37,
+ 0x89, 0x28, 0x41, 0x5c, 0x5c, 0x1c, 0xd2, 0xd3, 0xd3, 0xbf, 0xe7, 0x7d, 0xa6, 0xa1, 0x6f, 0x9b,
+ 0x4c, 0xf2, 0xbb, 0x52, 0xf4, 0x17, 0xf9, 0x8e, 0x2c, 0xc9, 0x01, 0x4f, 0xcd, 0xce, 0xce, 0x62,
+ 0x6d, 0x6d, 0x0d, 0x79, 0x79, 0x79, 0x01, 0xf9, 0x8d, 0x42, 0xbe, 0x26, 0x67, 0x37, 0x89, 0xda,
+ 0xda, 0xda, 0x71, 0xe2, 0xc4, 0x67, 0xb0, 0xdb, 0xed, 0x48, 0x4a, 0x4a, 0xfa, 0x33, 0x39, 0x39,
+ 0xf9, 0xa0, 0xec, 0xeb, 0x26, 0x3e, 0xb9, 0x11, 0x45, 0xe8, 0x3e, 0x97, 0x4c, 0x4b, 0xd1, 0x57,
+ 0xe3, 0xe3, 0xe3, 0x58, 0x5d, 0x5d, 0x45, 0x76, 0x76, 0xf6, 0x04, 0xef, 0x2d, 0x64, 0x88, 0x7c,
+ 0x4b, 0x92, 0x36, 0x89, 0x3c, 0x1e, 0x15, 0xf7, 0xef, 0x03, 0x93, 0x93, 0x73, 0x38, 0x70, 0xa0,
+ 0x46, 0x5b, 0x1d, 0xa5, 0xa2, 0xba, 0x1e, 0x90, 0x57, 0x1f, 0x91, 0xbf, 0x48, 0xe8, 0x3e, 0x76,
+ 0x38, 0x1c, 0xc8, 0xcd, 0xcd, 0x15, 0xa1, 0x3b, 0x25, 0xee, 0xc9, 0x43, 0xf2, 0x2b, 0xf9, 0x39,
+ 0xf2, 0xf2, 0x4e, 0x72, 0x8c, 0x84, 0x3a, 0x3a, 0x54, 0x84, 0xc3, 0xe0, 0xcc, 0x80, 0xbb, 0x77,
+ 0x81, 0xd3, 0xa7, 0xcf, 0xa3, 0xa0, 0x60, 0x07, 0xe2, 0xe3, 0xe3, 0xd7, 0x53, 0x53, 0x53, 0x5b,
+ 0x65, 0x38, 0x8c, 0x4d, 0x94, 0xf5, 0xdb, 0xc4, 0x4a, 0x3e, 0x21, 0x47, 0x48, 0x3e, 0x79, 0x59,
+ 0x5e, 0x1f, 0x91, 0xcf, 0xf9, 0x34, 0x3f, 0xff, 0x35, 0x9b, 0xcd, 0xe6, 0x57, 0x14, 0xe5, 0xf7,
+ 0xf6, 0x76, 0x15, 0xf7, 0xee, 0xe9, 0x92, 0x50, 0x08, 0x58, 0x5a, 0x02, 0xa6, 0xa7, 0x1f, 0xc0,
+ 0xe3, 0xf1, 0x22, 0x23, 0xc3, 0x01, 0xca, 0x66, 0x58, 0x30, 0x25, 0x52, 0x62, 0x95, 0xe7, 0xdc,
+ 0x33, 0x4f, 0xb4, 0x21, 0x7a, 0x7b, 0x7b, 0x2b, 0xfb, 0xfa, 0xfa, 0x90, 0x92, 0x92, 0x82, 0xb6,
+ 0x36, 0x15, 0x2b, 0x2b, 0xc0, 0xf2, 0xb2, 0x2e, 0x99, 0x9f, 0x07, 0x6e, 0xdf, 0x06, 0x6e, 0xde,
+ 0x04, 0xc6, 0xc6, 0x42, 0xa8, 0xa9, 0x39, 0x0c, 0x16, 0xcc, 0x43, 0x4e, 0xec, 0x07, 0x7e, 0x3a,
+ 0x6f, 0x38, 0x0d, 0xbe, 0x79, 0xc4, 0x6a, 0xff, 0xdd, 0x86, 0x87, 0x87, 0x95, 0xc1, 0xc1, 0xc1,
+ 0x54, 0xe6, 0x23, 0xd4, 0xda, 0xaa, 0x6a, 0x92, 0x3b, 0x77, 0x80, 0x85, 0x05, 0x5d, 0x72, 0xeb,
+ 0x16, 0x70, 0xe3, 0x06, 0x30, 0x31, 0x01, 0x5c, 0xbd, 0x0a, 0x0c, 0x0d, 0x8d, 0xc1, 0x66, 0xb3,
+ 0x63, 0xf7, 0xee, 0x57, 0xe0, 0xf7, 0x4f, 0xe3, 0xe4, 0xc9, 0x51, 0x28, 0x4a, 0x02, 0x4a, 0x4b,
+ 0x4b, 0x7d, 0x69, 0x69, 0x69, 0x55, 0xf2, 0x48, 0x7a, 0x6a, 0x2b, 0x67, 0xd0, 0xed, 0x56, 0x11,
+ 0x0c, 0xea, 0x12, 0x56, 0x2b, 0xc3, 0xa6, 0x4b, 0x02, 0x01, 0xe0, 0xda, 0x35, 0xe0, 0xf2, 0x65,
+ 0x70, 0x70, 0x20, 0x33, 0x33, 0x0b, 0x4e, 0xe7, 0xa7, 0x98, 0x9a, 0x02, 0x7c, 0x3e, 0x70, 0x3b,
+ 0x6c, 0x83, 0x61, 0x75, 0x82, 0x3d, 0x5b, 0x8a, 0x5a, 0x5a, 0x54, 0x2c, 0x2e, 0x02, 0x73, 0x73,
+ 0xba, 0x44, 0x0c, 0x74, 0xfd, 0xba, 0x2e, 0xb9, 0x72, 0x05, 0xb8, 0x74, 0x29, 0x8c, 0x43, 0x87,
+ 0x5c, 0x2c, 0x0e, 0x05, 0x59, 0x59, 0xd9, 0x68, 0x6a, 0xfa, 0x02, 0x7b, 0xf7, 0x7e, 0xa8, 0x55,
+ 0x67, 0x63, 0x63, 0x23, 0x98, 0x86, 0x30, 0x81, 0x48, 0x05, 0x19, 0xdc, 0x28, 0x10, 0xb1, 0x4d,
+ 0x11, 0xa2, 0xe6, 0x66, 0x55, 0x93, 0xcc, 0xcc, 0xe8, 0x79, 0x11, 0x12, 0x6e, 0x0f, 0x4d, 0xd2,
+ 0xd5, 0x35, 0x82, 0x9c, 0x9c, 0xa7, 0x29, 0xc8, 0x42, 0x7d, 0x7d, 0x3d, 0xca, 0xca, 0xca, 0xc4,
+ 0xc6, 0xe6, 0xb3, 0x1c, 0xd4, 0xd6, 0xd6, 0x6a, 0x83, 0xf7, 0xf7, 0xf7, 0x5f, 0x24, 0x6f, 0x49,
+ 0x9e, 0xdf, 0x28, 0x7a, 0x43, 0x2e, 0x77, 0xd9, 0xe9, 0x54, 0xff, 0x91, 0x4c, 0x4e, 0xea, 0x92,
+ 0xd1, 0xd1, 0x00, 0xca, 0xcb, 0x2b, 0x99, 0x07, 0x05, 0x15, 0x15, 0x15, 0xe8, 0xe9, 0xe9, 0x89,
+ 0xcc, 0xf8, 0x02, 0x39, 0x27, 0xaf, 0x05, 0x53, 0x64, 0xe7, 0x63, 0xe3, 0xd5, 0xd0, 0xd0, 0xb0,
+ 0xa7, 0xae, 0xae, 0xce, 0x67, 0xb5, 0x5a, 0xd7, 0x8e, 0x1e, 0x55, 0xb5, 0xe4, 0x0b, 0x89, 0xdf,
+ 0xff, 0x07, 0x67, 0xee, 0x42, 0x62, 0xa2, 0x05, 0xe2, 0x1c, 0x73, 0xbb, 0xdd, 0x91, 0x01, 0x57,
+ 0x18, 0x9e, 0xc3, 0x2e, 0x97, 0x4b, 0xfb, 0x5d, 0x7b, 0xbd, 0xde, 0x1d, 0x62, 0xf6, 0x2c, 0xaa,
+ 0xc4, 0x2d, 0xab, 0x4e, 0xcc, 0x82, 0x2f, 0x1e, 0xb7, 0x58, 0x2c, 0xe1, 0xa6, 0x26, 0x55, 0x4b,
+ 0xbe, 0xd7, 0x3b, 0x82, 0xed, 0xdb, 0xf3, 0xc0, 0x23, 0x08, 0xd5, 0xd5, 0xd5, 0x30, 0xc4, 0x7d,
+ 0x84, 0xe4, 0xfe, 0xdf, 0x7f, 0x4c, 0xb0, 0xaa, 0xea, 0x7d, 0x14, 0x17, 0x97, 0x6b, 0x95, 0x53,
+ 0x54, 0x54, 0x84, 0xce, 0xce, 0xce, 0x88, 0x60, 0x8e, 0xec, 0x8b, 0xd6, 0xcf, 0x2c, 0x28, 0x04,
+ 0x22, 0xc1, 0x0c, 0x65, 0x44, 0xb0, 0x4e, 0xbc, 0x03, 0x03, 0x03, 0xf6, 0x68, 0xfe, 0x35, 0x17,
+ 0xb8, 0x8a, 0x5f, 0xba, 0xbb, 0xbb, 0x35, 0x09, 0xc3, 0xe5, 0x67, 0x48, 0x5f, 0x34, 0xc5, 0xa0,
+ 0x3d, 0x4b, 0xc1, 0x31, 0x12, 0x26, 0x2e, 0x26, 0xd9, 0x6c, 0x8a, 0x55, 0xe3, 0x2a, 0xde, 0x61,
+ 0xf9, 0x16, 0xc4, 0x62, 0xec, 0xbf, 0x01, 0x96, 0xa8, 0x5c, 0xe1, 0x12, 0x7e, 0x2a, 0x61, 0x00,
+ 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+};
+
+const BITMAP_OPAQUE autoplace_fields_xpm[1] = {{ png, sizeof( png ), "autoplace_fields_xpm" }};
+
+//EOF
diff --git a/bitmaps_png/sources/autoplace_fields.svg b/bitmaps_png/sources/autoplace_fields.svg
new file mode 100644
index 0000000..a7f6728
--- /dev/null
+++ b/bitmaps_png/sources/autoplace_fields.svg
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   height="48"
+   width="48"
+   version="1.1"
+   viewBox="0 0 48 48"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="autoplace_fields.svg">
+  <metadata
+     id="metadata151">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1676"
+     inkscape:window-height="994"
+     id="namedview149"
+     showgrid="false"
+     inkscape:zoom="6.9532167"
+     inkscape:cx="19.533569"
+     inkscape:cy="26.564532"
+     inkscape:window-x="0"
+     inkscape:window-y="54"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <defs
+     id="defs4">
+    <linearGradient
+       id="a">
+      <stop
+         stop-color="#fff"
+         offset="0"
+         id="stop7" />
+      <stop
+         stop-color="#babaff"
+         offset="1"
+         id="stop9" />
+    </linearGradient>
+    <linearGradient
+       id="j"
+       y2="10.441"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       x2="12.136"
+       gradientTransform="matrix(2.2734557,0,0,2.6193664,-58.250764,5.4148976)"
+       y1="1.9828"
+       x1="3.4673" />
+    <linearGradient
+       id="b"
+       y2="7.8438"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       x2="12.922"
+       y1="6.0625"
+       x1="11.078"
+       gradientTransform="matrix(2.5619,0,0,2.3244,-58.266136,5.4148976)" />
+    <linearGradient
+       id="k"
+       y2="14.691"
+       gradientUnits="userSpaceOnUse"
+       x2="30.432"
+       gradientTransform="translate(6.3922,12.185)"
+       y1="12.338"
+       x1="28.079">
+      <stop
+         stop-color="#fcaf3e"
+         offset="0"
+         id="stop14" />
+      <stop
+         stop-color="#ce5c00"
+         offset="1"
+         id="stop16" />
+    </linearGradient>
+    <linearGradient
+       id="l"
+       y2="22.119"
+       gradientUnits="userSpaceOnUse"
+       x2="22.81"
+       gradientTransform="translate(6.3922,12.185)"
+       y1="21.481"
+       x1="23.448">
+      <stop
+         stop-color="#ce5c00"
+         offset="0"
+         id="stop19" />
+      <stop
+         stop-color="#ce5c00"
+         offset="1"
+         id="stop21" />
+    </linearGradient>
+    <linearGradient
+       id="m"
+       y2="32.714"
+       gradientUnits="userSpaceOnUse"
+       x2="25.485"
+       y1="34.39"
+       x1="26.379">
+      <stop
+         stop-color="#e9b96e"
+         offset="0"
+         id="stop24" />
+      <stop
+         stop-color="#fff"
+         offset="1"
+         id="stop26" />
+    </linearGradient>
+    <radialGradient
+       id="p"
+       gradientUnits="userSpaceOnUse"
+       cy="128"
+       cx="-138.84"
+       gradientTransform="matrix(.35473 -.34328 .35696 .34544 130.15 -71.026)"
+       r="9.1267">
+      <stop
+         stop-color="#f9a9a9"
+         offset="0"
+         id="stop29" />
+      <stop
+         stop-color="#ab5f5f"
+         offset="1"
+         id="stop31" />
+    </radialGradient>
+    <linearGradient
+       id="n"
+       y2="134.25"
+       gradientUnits="userSpaceOnUse"
+       x2="-158.75"
+       gradientTransform="matrix(.20949 -.20274 .20949 .20274 129.28 -31.999)"
+       y1="115.94"
+       x1="-158.75">
+      <stop
+         stop-color="#ddd"
+         offset="0"
+         id="stop34" />
+      <stop
+         stop-color="#fff"
+         offset=".34468"
+         id="stop36" />
+      <stop
+         stop-color="#737373"
+         offset=".72695"
+         id="stop38" />
+      <stop
+         stop-color="#bbb"
+         offset="1"
+         id="stop40" />
+    </linearGradient>
+    <linearGradient
+       id="o"
+       y2="10.441"
+       xlink:href="#a"
+       gradientUnits="userSpaceOnUse"
+       x2="12.136"
+       gradientTransform="matrix(2.246184,0,0,2.7037,-1.2081619,11.548735)"
+       y1="1.9828"
+       x1="3.4673" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#a"
+       id="linearGradient3479"
+       gradientUnits="userSpaceOnUse"
+       x1="11.078"
+       y1="6.0625"
+       x2="12.922"
+       y2="7.8438"
+       gradientTransform="matrix(2.531196,0,0,2.3993,-1.2229579,11.548735)" />
+  </defs>
+  <g
+     id="g4323">
+    <g
+       transform="matrix(2.531196,0,0,2.3993,-13.87883,-17.842265)"
+       id="g107"
+       style="fill:#9b9b9b">
+      <path
+         d="m 8,13.25 0,14 10.5,-7 -10.5,-7 z"
+         id="path109"
+         inkscape:connector-curvature="0"
+         style="fill-rule:evenodd" />
+      <rect
+         y="17.25"
+         width="1.9942"
+         x="6.0057998"
+         height="1"
+         id="rect111" />
+      <rect
+         y="22.25"
+         width="2"
+         x="6"
+         height="1"
+         id="rect113" />
+      <path
+         d="m 14.5,6.5 a 1.5,1.5 0 1 1 -3,0 1.5,1.5 0 1 1 3,0 z"
+         transform="matrix(1.3333,0,0,1.3333,0.66664,11.583)"
+         id="path115"
+         inkscape:connector-curvature="0" />
+      <rect
+         y="19.75"
+         width="2.4942"
+         x="19.506001"
+         height="1"
+         id="rect117" />
+    </g>
+    <rect
+       transform="matrix(-1.754568e-7,1,-1,-4.4663889e-8,0,0)"
+       height="2.5311959"
+       width="2.3993001"
+       y="-8.9018316"
+       x="16.347736"
+       id="rect119"
+       style="fill:#ffffff" />
+    <path
+       d="m 3.8394341,11.548735 0,33.591 26.5766399,-16.795 -26.5766399,-16.796 z"
+       id="path121"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <rect
+       y="21.146734"
+       width="2.5311959"
+       x="1.3082383"
+       height="2.3993001"
+       id="rect123" />
+    <rect
+       y="33.143135"
+       width="2.5311959"
+       x="1.3082383"
+       height="2.3993001"
+       id="rect125" />
+    <path
+       d="m 6.3853181,16.347735 0,23.993 20.2499999,-11.996 -20.2499999,-11.997 z"
+       id="path127"
+       style="fill:url(#o);fill-rule:evenodd"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 34.213624,28.344885 a 5.062338,4.79865 0 0 1 -10.124676,0 5.062338,4.79865 0 1 1 10.124676,0 z"
+       id="path129"
+       inkscape:connector-curvature="0" />
+    <path
+       d="m 31.68259,28.343835 a 2.531196,2.3993 0 0 1 -5.062392,0 2.531196,2.3993 0 1 1 5.062392,0 z"
+       id="path131"
+       style="fill:url(#linearGradient3479)"
+       inkscape:connector-curvature="0" />
+    <rect
+       y="27.144733"
+       width="6.3132482"
+       x="32.962929"
+       height="2.3993001"
+       id="rect133" />
+    <path
+       d="m 22.49337,0.60054242 0,7.19799968 2.531196,2.3992999 2.531196,0 2.531196,-2.3992999 0,-7.19799968 -2.531196,0 0,7.19799968 -2.531196,0 0,-7.19799968 -2.53152,0 z"
+       id="path135"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       d="m 32.61729,0.60054242 5.062392,0 2.531196,2.39929998 0,2.3993 -2.531196,2.3992997 -2.531196,0 0,2.3992999 -2.53044,0 0,-4.7986996 5.062392,0 0,-2.3993 -5.06196,0 0,-2.39929998 z"
+       id="path147"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       d="m 15.393889,11.860171 6.40475,0 0,2.3244 -3.84285,6.990866 -2.5619,0 3.84285,-6.9732 -3.84285,0 0,-2.342995 z"
+       id="path75"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       d="m 39.731939,11.860171 0,2.3244 3.84285,0 0,1.1622 -3.84285,3.4866 0,2.3244 6.40475,0 0,-2.3244 -3.84285,0 3.84285,-3.4866 0,-2.3244 -1.28095,-1.179842 -5.1238,0.01767 z"
+       id="path77"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       d="m 32.046239,14.312413 0.01947,4.520958 1.261505,2.3244 3.84285,0 1.300395,-2.452242 0,-4.6488 -1.300395,-2.196488 -3.84285,0 -1.28095,2.452242 z"
+       id="path79"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+    <path
+       d="m 33.327189,15.346771 1.28095,-1.1622 1.28095,0 1.28095,1.1622 0,2.3244 -1.28095,1.1622 -1.28095,0 -1.28095,-1.1622 0,-2.3244 z"
+       id="path81"
+       inkscape:connector-curvature="0"
+       style="fill:#ffffff;fill-rule:evenodd" />
+    <path
+       d="m 23.079589,11.860171 0,5.811 5.1238,0 0,3.4866 2.5619,0 0,-9.2976 -2.5619,0 0,3.4866 -2.5619,0 0,-3.4866 -2.5619,0 z"
+       id="path83"
+       inkscape:connector-curvature="0"
+       style="fill-rule:evenodd" />
+  </g>
+</svg>
diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt
index 0982735..5cba4f1 100644
--- a/eeschema/CMakeLists.txt
+++ b/eeschema/CMakeLists.txt
@@ -75,6 +75,7 @@ set( EESCHEMA_DLGS
     )
 
 set( EESCHEMA_SRCS
+    autoplace_fields.cpp
     annotate.cpp
     backanno.cpp
     block.cpp
diff --git a/eeschema/autoplace_fields.cpp b/eeschema/autoplace_fields.cpp
new file mode 100644
index 0000000..11ab31d
--- /dev/null
+++ b/eeschema/autoplace_fields.cpp
@@ -0,0 +1,359 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2015 Chris Pavlina <pavlina.chris@xxxxxxxxx>
+ * Copyright (C) 2015 KiCad Developers, see change_log.txt for contributors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, you may find one here:
+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ * or you may search the http://www.gnu.org website for the version 2 license,
+ * or you may write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ */
+
+#include <schframe.h>
+#include <hotkeys_basic.h>
+#include <sch_component.h>
+#include <lib_pin.h>
+#include <class_drawpanel.h>
+#include <class_libentry.h>
+#include <eeschema_config.h>
+#include <kiface_i.h>
+#include <boost/foreach.hpp>
+#include <vector>
+#include <algorithm>
+
+#define FIELD_V_SPACING 100
+#define HORIZ_PADDING 50
+
+enum component_side {
+    SIDE_TOP, SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT
+};
+
+
+/**
+ * Function round_n
+ * Round up/down to the nearest multiple of n
+ */
+template<typename T> T round_n( const T& value, const T& n, bool aRoundUp )
+{
+    if( value % n )
+        return n * (value / n + (aRoundUp ? 1 : 0));
+    else
+        return value;
+}
+
+
+/**
+ * Function get_pin_side
+ * Return the side that a pin is on.
+ */
+static enum component_side get_pin_side( SCH_COMPONENT* aComponent, LIB_PIN* aPin )
+{
+    int pin_orient = aPin->PinDrawOrient( aComponent->GetTransform() );
+    switch( pin_orient )
+    {
+    case PIN_RIGHT:
+        return SIDE_LEFT;
+    case PIN_LEFT:
+        return SIDE_RIGHT;
+    case PIN_UP:
+        return SIDE_BOTTOM;
+    case PIN_DOWN:
+        return SIDE_TOP;
+    default:
+        wxFAIL_MSG( "Invalid pin orientation" );
+        return SIDE_LEFT;
+    }
+}
+
+
+/**
+ * Function pins_on_side
+ * Count the number of pins on a side of the component
+ */
+static unsigned pins_on_side( SCH_COMPONENT* aComponent, enum component_side aSide )
+{
+    unsigned pin_count = 0;
+
+    std::vector<LIB_PIN*> pins;
+    aComponent->GetPins( pins );
+
+    BOOST_FOREACH( LIB_PIN* each_pin, pins )
+    {
+        if( !each_pin->IsVisible() )
+            continue;
+        if( get_pin_side( aComponent, each_pin ) == aSide )
+            ++pin_count;
+    }
+
+    return pin_count;
+}
+
+
+// Used for iteration
+struct side {
+    enum component_side side_name;
+    unsigned side_pins;
+};
+
+
+/**
+ * Function populate_preferred_sides
+ * Populate a list with the preferred field sides for the component, in
+ * decreasing order of preference.
+ */
+static void populate_preferred_sides( std::vector<struct side>& aSides,
+                                      SCH_COMPONENT* aComponent )
+{
+    struct side sides[] = {
+        { SIDE_RIGHT,   pins_on_side( aComponent, SIDE_RIGHT ) },
+        { SIDE_TOP,     pins_on_side( aComponent, SIDE_TOP ) },
+        { SIDE_LEFT,    pins_on_side( aComponent, SIDE_LEFT ) },
+        { SIDE_BOTTOM,  pins_on_side( aComponent, SIDE_BOTTOM ) },
+    };
+
+    int orient = aComponent->GetOrientation();
+    int orient_angle = orient & 0xff; // enum is a bitmask
+
+    // If the component is horizontally mirrored, swap left and right
+    if( ( orient & CMP_MIRROR_X ) && ( orient_angle == CMP_ORIENT_0 || orient_angle == CMP_ORIENT_180 ) )
+    {
+        std::swap( sides[0], sides[2] );
+    }
+
+    // If the component is very long, swap H and V
+    EDA_RECT body_box = aComponent->GetBodyBoundingBox();
+    if( double( body_box.GetWidth() ) / double( body_box.GetHeight() ) > 3.0 )
+    {
+        std::swap( sides[0], sides[1] );
+        std::swap( sides[1], sides[3] );
+    }
+
+    BOOST_FOREACH( struct side& each_side, sides )
+    {
+        aSides.push_back( each_side );
+    }
+}
+
+
+/**
+ * Function choose_side_for_component
+ * Look where a component's pins are to pick a side to put the fields on
+ */
+static enum component_side choose_side_for_fields( SCH_COMPONENT* aComponent )
+{
+    std::vector<struct side> sides;
+    populate_preferred_sides( sides, aComponent );
+
+
+    BOOST_FOREACH( struct side& each_side, sides )
+    {
+        if( !each_side.side_pins ) return each_side.side_name;
+    }
+
+    unsigned min_pins = (unsigned)(-1);
+    enum component_side min_side = SIDE_RIGHT;
+
+    BOOST_REVERSE_FOREACH( struct side& each_side, sides )
+    {
+        if( each_side.side_pins < min_pins )
+        {
+            min_pins = each_side.side_pins;
+            min_side = each_side.side_name;
+        }
+    }
+
+    return min_side;
+}
+
+
+void SCH_EDIT_FRAME::OnAutoplaceFields( wxCommandEvent& aEvent )
+{
+    SCH_SCREEN* screen = GetScreen();
+    SCH_ITEM* item = screen->GetCurItem();
+
+    // Get the item under cursor if we're not currently moving something
+    if( !item )
+    {
+        if( aEvent.GetInt() == 0 )
+            return;
+
+        EDA_HOTKEY_CLIENT_DATA* data;
+        data = dynamic_cast<EDA_HOTKEY_CLIENT_DATA*>( aEvent.GetClientObject() );
+        wxCHECK_RET( data, wxT( "Invalid hot key client object." ) );
+        item = LocateAndShowItem( data->GetPosition(),
+                SCH_COLLECTOR::MovableItems, aEvent.GetInt() );
+        if( !item || item->GetFlags() )
+            return;
+    }
+
+    if( item->Type() != SCH_COMPONENT_T )
+        return;
+
+    if( !item->IsNew() )
+        SaveCopyInUndoList( item, UR_CHANGED );
+
+    SCH_COMPONENT *component = dynamic_cast<SCH_COMPONENT*>( item );
+
+    component->AutoplaceFields();
+
+    GetCanvas()->Refresh();
+}
+
+
+/**
+ * Function place_field_horiz
+ * Place a field horizontally, taking into account the field width and
+ * justification.
+ *
+ * @param aField - the field to place.
+ * @param aFieldBox - box in which fields will be placed
+ * @param aRoundUp - whether to round horizontal coordinate up (else round down)
+ *
+ * @return Correct field horizontal position
+ */
+static int place_field_horiz( SCH_FIELD *aField, const EDA_RECT &aFieldBox, bool aRoundUp )
+{
+    EDA_TEXT_HJUSTIFY_T field_hjust = aField->GetHorizJustify();
+    bool flipped = aField->IsHorizJustifyFlipped();
+    if( flipped && field_hjust == GR_TEXT_HJUSTIFY_LEFT )
+        field_hjust = GR_TEXT_HJUSTIFY_RIGHT;
+    else if( flipped && field_hjust == GR_TEXT_HJUSTIFY_RIGHT )
+        field_hjust = GR_TEXT_HJUSTIFY_LEFT;
+
+    int field_xcoord;
+
+    switch( field_hjust )
+    {
+    case GR_TEXT_HJUSTIFY_LEFT:
+        field_xcoord = aFieldBox.GetLeft();
+        break;
+    case GR_TEXT_HJUSTIFY_CENTER:
+        field_xcoord = aFieldBox.GetCenter().x;
+        break;
+    case GR_TEXT_HJUSTIFY_RIGHT:
+        field_xcoord = aFieldBox.GetRight();
+        break;
+    default:
+        wxFAIL_MSG( "Unexpected value for SCH_FIELD::GetHorizJustify()" );
+        field_xcoord = aFieldBox.GetCenter().x; // Most are centered
+    }
+
+    return round_n( field_xcoord, 50, aRoundUp );
+}
+
+
+void SCH_COMPONENT::AutoplaceFields()
+{
+    // Do not autoplace on power symbols
+    if( PART_SPTR part = m_part.lock() )
+        if( part->IsPower() ) return;
+
+    // Gather information
+    EDA_RECT body_box = GetBodyBoundingBox();
+    std::vector<SCH_FIELD*> fields;
+    GetFields( fields, /* aVisibleOnly */ true );
+
+    bool allow_rejustify = true;
+    Kiface().KifaceSettings()->Read( AUTOPLACE_JUSTIFY_KEY, &allow_rejustify, true );
+
+    int max_field_width = 0;
+    for( size_t field_idx = 0; field_idx < fields.size(); ++field_idx )
+    {
+        if( GetTransform().y1 )
+            fields[field_idx]->SetOrientation( TEXT_ORIENT_VERT );
+        else
+            fields[field_idx]->SetOrientation( TEXT_ORIENT_HORIZ );
+
+        int field_width = fields[field_idx]->GetBoundingBox().GetWidth();
+        if( field_width > max_field_width )
+            max_field_width = field_width;
+    }
+
+    // Determine which side the fields will be placed on
+    enum component_side field_side = choose_side_for_fields( this );
+
+    // Compute the box into which fields will go
+    wxSize fbox_size( max_field_width, FIELD_V_SPACING * (fields.size() - 1) );
+    wxPoint fbox_pos;
+    bool h_round_up;
+
+    switch( field_side )
+    {
+    case SIDE_RIGHT:
+        fbox_pos.x = body_box.GetRight() + HORIZ_PADDING;
+        fbox_pos.y = round_n( body_box.GetCenter().y - fbox_size.GetHeight()/2, 50, false );
+        h_round_up = true;
+        break;
+    case SIDE_BOTTOM:
+        fbox_pos.x = body_box.GetLeft() + (body_box.GetWidth() - fbox_size.GetWidth()) / 2;
+        fbox_pos.y = round_n( body_box.GetBottom() + 25, 50, true );
+        h_round_up = true;
+        break;
+    case SIDE_LEFT:
+        fbox_pos.x = body_box.GetLeft() - fbox_size.GetWidth() - HORIZ_PADDING;
+        fbox_pos.y = round_n( body_box.GetCenter().y - fbox_size.GetHeight()/2, 50, false );
+        h_round_up = false;
+        break;
+    case SIDE_TOP:
+        fbox_pos.x = body_box.GetLeft() + (body_box.GetWidth() - fbox_size.GetWidth()) / 2;
+        fbox_pos.y = round_n( body_box.GetTop() - fbox_size.GetHeight() - 25, 50, false );
+        h_round_up = true;
+        break;
+    default:
+        wxFAIL_MSG( "Bad enum component_side value" );
+        fbox_pos.x = body_box.GetRight();
+        fbox_pos.y = round_n( body_box.GetCenter().y - fbox_size.GetHeight()/2, 50, false );
+        h_round_up = true;
+    }
+
+    EDA_RECT field_box( fbox_pos, fbox_size );
+
+    // Move the fields
+    for( size_t field_idx = 0; field_idx < fields.size(); ++field_idx )
+    {
+        wxPoint pos;
+        SCH_FIELD* field = fields[field_idx];
+
+        // Set field justification
+        // Justification is set twice to allow IsHorizJustifyFlipped() to work correctly.
+        if( allow_rejustify )
+        {
+            switch( field_side )
+            {
+            case SIDE_LEFT:
+                field->SetHorizJustify( GR_TEXT_HJUSTIFY_RIGHT );
+                field->SetHorizJustify( field->IsHorizJustifyFlipped()
+                        ? GR_TEXT_HJUSTIFY_LEFT : GR_TEXT_HJUSTIFY_RIGHT );
+                break;
+            case SIDE_RIGHT:
+                field->SetHorizJustify( GR_TEXT_HJUSTIFY_LEFT );
+                field->SetHorizJustify( field->IsHorizJustifyFlipped()
+                        ? GR_TEXT_HJUSTIFY_RIGHT : GR_TEXT_HJUSTIFY_LEFT );
+                break;
+            case SIDE_TOP:
+            case SIDE_BOTTOM:
+                field->SetHorizJustify( GR_TEXT_HJUSTIFY_CENTER );
+                break;
+            }
+        }
+
+        pos.x = place_field_horiz( field, field_box, h_round_up );
+        pos.y = field_box.GetY() + (FIELD_V_SPACING * field_idx);
+        field->SetPosition( pos );
+    }
+
+    m_fieldsAutoplaced = true;
+}
diff --git a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
index c5a6020..6dc6f76 100644
--- a/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
+++ b/eeschema/dialogs/dialog_edit_component_in_schematic.cpp
@@ -159,6 +159,9 @@ void SCH_EDIT_FRAME::EditComponent( SCH_COMPONENT* aComponent )
     int ret = dlg->ShowQuasiModal();
     (void) ret;     // not used. Make coverity and static analysers quiet.
 
+    if( m_autoplaceFields && aComponent->GetFieldsAutoplaced() )
+        aComponent->AutoplaceFields();
+
     m_canvas->SetIgnoreMouseEvents( false );
     m_canvas->MoveCursorToCrossHair();
     dlg->Destroy();
diff --git a/eeschema/dialogs/dialog_edit_one_field.cpp b/eeschema/dialogs/dialog_edit_one_field.cpp
index d3439da..65dd01b 100644
--- a/eeschema/dialogs/dialog_edit_one_field.cpp
+++ b/eeschema/dialogs/dialog_edit_one_field.cpp
@@ -298,6 +298,22 @@ void DIALOG_SCH_EDIT_ONE_FIELD::TransfertDataToField( bool aIncludeText )
 
     m_field->SetItalic( ( m_TextShapeOpt->GetSelection() & 1 ) != 0 );
     m_field->SetBold( ( m_TextShapeOpt->GetSelection() & 2 ) != 0 );
+
+    // Because field autoplace can change justification, check whether this has
+    // been changed, and clear the autoplace flag if so.
+    EDA_TEXT_HJUSTIFY_T old_hjust = m_field->GetHorizJustify();
+    EDA_TEXT_VJUSTIFY_T old_vjust = m_field->GetVertJustify();
+
+    if( old_hjust != m_textHjustify || old_vjust != m_textVjustify )
+    {
+        EDA_ITEM *parent = m_field->GetParent();
+        if( parent->Type() == SCH_COMPONENT_T )
+        {
+            SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( parent );
+            component->ClearFieldsAutoplaced();
+        }
+    }
+
     m_field->SetHorizJustify( m_textHjustify );
     m_field->SetVertJustify( m_textVjustify );
 }
diff --git a/eeschema/dialogs/dialog_eeschema_options.h b/eeschema/dialogs/dialog_eeschema_options.h
index 4c08fe3..03f2653 100644
--- a/eeschema/dialogs/dialog_eeschema_options.h
+++ b/eeschema/dialogs/dialog_eeschema_options.h
@@ -428,6 +428,30 @@ public:
     bool GetShowPageLimits( void ) { return m_checkPageLimits->GetValue(); }
 
     /**
+     * Function
+     * Set the AutoplaceFields setting in the dialog
+     */
+    void SetAutoplaceFields( bool enable ) { m_checkAutoplaceFields->SetValue( enable ); }
+
+    /**
+     * Function
+     * Return the current AutoplaceFields setting from the dialog
+     */
+    bool GetAutoplaceFields() { return m_checkAutoplaceFields->GetValue(); }
+
+    /**
+     * Function
+     * Set the AutoplaceJustify setting in the dialog
+     */
+    void SetAutoplaceJustify( bool enable ) { m_checkAutoplaceJustify->SetValue( enable ); }
+
+    /**
+     * Function
+     * Return the current AutoplaceJustify setting from the dialog
+     */
+    bool GetAutoplaceJustify() { return m_checkAutoplaceJustify->GetValue(); }
+
+    /**
      * Function SetTemplateFields
      * Set the template field data in the dialog
      *
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.cpp b/eeschema/dialogs/dialog_eeschema_options_base.cpp
index a9a5d06..691a098 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.cpp
+++ b/eeschema/dialogs/dialog_eeschema_options_base.cpp
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Mar  9 2015)
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -203,6 +203,12 @@ DIALOG_EESCHEMA_OPTIONS_BASE::DIALOG_EESCHEMA_OPTIONS_BASE( wxWindow* parent, wx
 	m_checkPageLimits = new wxCheckBox( m_panel1, wxID_ANY, _("Show p&age limits"), wxDefaultPosition, wxDefaultSize, 0 );
 	bSizer2->Add( m_checkPageLimits, 0, wxALL|wxEXPAND, 3 );
 	
+	m_checkAutoplaceFields = new wxCheckBox( m_panel1, wxID_ANY, _("Automatically place component fields"), wxDefaultPosition, wxDefaultSize, 0 );
+	bSizer2->Add( m_checkAutoplaceFields, 0, wxALL, 3 );
+	
+	m_checkAutoplaceJustify = new wxCheckBox( m_panel1, wxID_ANY, _("Allow field autoplace to change justification"), wxDefaultPosition, wxDefaultSize, 0 );
+	bSizer2->Add( m_checkAutoplaceJustify, 0, wxALL, 3 );
+	
 	
 	bSizer3->Add( bSizer2, 0, wxEXPAND, 0 );
 	
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.fbp b/eeschema/dialogs/dialog_eeschema_options_base.fbp
index a7b2188..0ab31e9 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.fbp
+++ b/eeschema/dialogs/dialog_eeschema_options_base.fbp
@@ -2619,7 +2619,7 @@
                                                         <property name="border">0</property>
                                                         <property name="flag">wxEXPAND</property>
                                                         <property name="proportion">0</property>
-                                                        <object class="wxBoxSizer" expanded="0">
+                                                        <object class="wxBoxSizer" expanded="1">
                                                             <property name="minimum_size"></property>
                                                             <property name="name">bSizer2</property>
                                                             <property name="orient">wxVERTICAL</property>
@@ -3409,6 +3409,182 @@
                                                                     <event name="OnUpdateUI"></event>
                                                                 </object>
                                                             </object>
+                                                            <object class="sizeritem" expanded="1">
+                                                                <property name="border">3</property>
+                                                                <property name="flag">wxALL</property>
+                                                                <property name="proportion">0</property>
+                                                                <object class="wxCheckBox" expanded="1">
+                                                                    <property name="BottomDockable">1</property>
+                                                                    <property name="LeftDockable">1</property>
+                                                                    <property name="RightDockable">1</property>
+                                                                    <property name="TopDockable">1</property>
+                                                                    <property name="aui_layer"></property>
+                                                                    <property name="aui_name"></property>
+                                                                    <property name="aui_position"></property>
+                                                                    <property name="aui_row"></property>
+                                                                    <property name="best_size"></property>
+                                                                    <property name="bg"></property>
+                                                                    <property name="caption"></property>
+                                                                    <property name="caption_visible">1</property>
+                                                                    <property name="center_pane">0</property>
+                                                                    <property name="checked">0</property>
+                                                                    <property name="close_button">1</property>
+                                                                    <property name="context_help"></property>
+                                                                    <property name="context_menu">1</property>
+                                                                    <property name="default_pane">0</property>
+                                                                    <property name="dock">Dock</property>
+                                                                    <property name="dock_fixed">0</property>
+                                                                    <property name="docking">Left</property>
+                                                                    <property name="enabled">1</property>
+                                                                    <property name="fg"></property>
+                                                                    <property name="floatable">1</property>
+                                                                    <property name="font"></property>
+                                                                    <property name="gripper">0</property>
+                                                                    <property name="hidden">0</property>
+                                                                    <property name="id">wxID_ANY</property>
+                                                                    <property name="label">Automatically place component fields</property>
+                                                                    <property name="max_size"></property>
+                                                                    <property name="maximize_button">0</property>
+                                                                    <property name="maximum_size"></property>
+                                                                    <property name="min_size"></property>
+                                                                    <property name="minimize_button">0</property>
+                                                                    <property name="minimum_size"></property>
+                                                                    <property name="moveable">1</property>
+                                                                    <property name="name">m_checkAutoplaceFields</property>
+                                                                    <property name="pane_border">1</property>
+                                                                    <property name="pane_position"></property>
+                                                                    <property name="pane_size"></property>
+                                                                    <property name="permission">protected</property>
+                                                                    <property name="pin_button">1</property>
+                                                                    <property name="pos"></property>
+                                                                    <property name="resize">Resizable</property>
+                                                                    <property name="show">1</property>
+                                                                    <property name="size"></property>
+                                                                    <property name="style"></property>
+                                                                    <property name="subclass"></property>
+                                                                    <property name="toolbar_pane">0</property>
+                                                                    <property name="tooltip"></property>
+                                                                    <property name="validator_data_type"></property>
+                                                                    <property name="validator_style">wxFILTER_NONE</property>
+                                                                    <property name="validator_type">wxDefaultValidator</property>
+                                                                    <property name="validator_variable"></property>
+                                                                    <property name="window_extra_style"></property>
+                                                                    <property name="window_name"></property>
+                                                                    <property name="window_style"></property>
+                                                                    <event name="OnChar"></event>
+                                                                    <event name="OnCheckBox"></event>
+                                                                    <event name="OnEnterWindow"></event>
+                                                                    <event name="OnEraseBackground"></event>
+                                                                    <event name="OnKeyDown"></event>
+                                                                    <event name="OnKeyUp"></event>
+                                                                    <event name="OnKillFocus"></event>
+                                                                    <event name="OnLeaveWindow"></event>
+                                                                    <event name="OnLeftDClick"></event>
+                                                                    <event name="OnLeftDown"></event>
+                                                                    <event name="OnLeftUp"></event>
+                                                                    <event name="OnMiddleDClick"></event>
+                                                                    <event name="OnMiddleDown"></event>
+                                                                    <event name="OnMiddleUp"></event>
+                                                                    <event name="OnMotion"></event>
+                                                                    <event name="OnMouseEvents"></event>
+                                                                    <event name="OnMouseWheel"></event>
+                                                                    <event name="OnPaint"></event>
+                                                                    <event name="OnRightDClick"></event>
+                                                                    <event name="OnRightDown"></event>
+                                                                    <event name="OnRightUp"></event>
+                                                                    <event name="OnSetFocus"></event>
+                                                                    <event name="OnSize"></event>
+                                                                    <event name="OnUpdateUI"></event>
+                                                                </object>
+                                                            </object>
+                                                            <object class="sizeritem" expanded="1">
+                                                                <property name="border">3</property>
+                                                                <property name="flag">wxALL</property>
+                                                                <property name="proportion">0</property>
+                                                                <object class="wxCheckBox" expanded="1">
+                                                                    <property name="BottomDockable">1</property>
+                                                                    <property name="LeftDockable">1</property>
+                                                                    <property name="RightDockable">1</property>
+                                                                    <property name="TopDockable">1</property>
+                                                                    <property name="aui_layer"></property>
+                                                                    <property name="aui_name"></property>
+                                                                    <property name="aui_position"></property>
+                                                                    <property name="aui_row"></property>
+                                                                    <property name="best_size"></property>
+                                                                    <property name="bg"></property>
+                                                                    <property name="caption"></property>
+                                                                    <property name="caption_visible">1</property>
+                                                                    <property name="center_pane">0</property>
+                                                                    <property name="checked">0</property>
+                                                                    <property name="close_button">1</property>
+                                                                    <property name="context_help"></property>
+                                                                    <property name="context_menu">1</property>
+                                                                    <property name="default_pane">0</property>
+                                                                    <property name="dock">Dock</property>
+                                                                    <property name="dock_fixed">0</property>
+                                                                    <property name="docking">Left</property>
+                                                                    <property name="enabled">1</property>
+                                                                    <property name="fg"></property>
+                                                                    <property name="floatable">1</property>
+                                                                    <property name="font"></property>
+                                                                    <property name="gripper">0</property>
+                                                                    <property name="hidden">0</property>
+                                                                    <property name="id">wxID_ANY</property>
+                                                                    <property name="label">Allow field autoplace to change justification</property>
+                                                                    <property name="max_size"></property>
+                                                                    <property name="maximize_button">0</property>
+                                                                    <property name="maximum_size"></property>
+                                                                    <property name="min_size"></property>
+                                                                    <property name="minimize_button">0</property>
+                                                                    <property name="minimum_size"></property>
+                                                                    <property name="moveable">1</property>
+                                                                    <property name="name">m_checkAutoplaceJustify</property>
+                                                                    <property name="pane_border">1</property>
+                                                                    <property name="pane_position"></property>
+                                                                    <property name="pane_size"></property>
+                                                                    <property name="permission">protected</property>
+                                                                    <property name="pin_button">1</property>
+                                                                    <property name="pos"></property>
+                                                                    <property name="resize">Resizable</property>
+                                                                    <property name="show">1</property>
+                                                                    <property name="size"></property>
+                                                                    <property name="style"></property>
+                                                                    <property name="subclass"></property>
+                                                                    <property name="toolbar_pane">0</property>
+                                                                    <property name="tooltip"></property>
+                                                                    <property name="validator_data_type"></property>
+                                                                    <property name="validator_style">wxFILTER_NONE</property>
+                                                                    <property name="validator_type">wxDefaultValidator</property>
+                                                                    <property name="validator_variable"></property>
+                                                                    <property name="window_extra_style"></property>
+                                                                    <property name="window_name"></property>
+                                                                    <property name="window_style"></property>
+                                                                    <event name="OnChar"></event>
+                                                                    <event name="OnCheckBox"></event>
+                                                                    <event name="OnEnterWindow"></event>
+                                                                    <event name="OnEraseBackground"></event>
+                                                                    <event name="OnKeyDown"></event>
+                                                                    <event name="OnKeyUp"></event>
+                                                                    <event name="OnKillFocus"></event>
+                                                                    <event name="OnLeaveWindow"></event>
+                                                                    <event name="OnLeftDClick"></event>
+                                                                    <event name="OnLeftDown"></event>
+                                                                    <event name="OnLeftUp"></event>
+                                                                    <event name="OnMiddleDClick"></event>
+                                                                    <event name="OnMiddleDown"></event>
+                                                                    <event name="OnMiddleUp"></event>
+                                                                    <event name="OnMotion"></event>
+                                                                    <event name="OnMouseEvents"></event>
+                                                                    <event name="OnMouseWheel"></event>
+                                                                    <event name="OnPaint"></event>
+                                                                    <event name="OnRightDClick"></event>
+                                                                    <event name="OnRightDown"></event>
+                                                                    <event name="OnRightUp"></event>
+                                                                    <event name="OnSetFocus"></event>
+                                                                    <event name="OnSize"></event>
+                                                                    <event name="OnUpdateUI"></event>
+                                                                </object>
+                                                            </object>
                                                         </object>
                                                     </object>
                                                 </object>
diff --git a/eeschema/dialogs/dialog_eeschema_options_base.h b/eeschema/dialogs/dialog_eeschema_options_base.h
index a1f3e3b..ffd30bd 100644
--- a/eeschema/dialogs/dialog_eeschema_options_base.h
+++ b/eeschema/dialogs/dialog_eeschema_options_base.h
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////
-// C++ code generated with wxFormBuilder (version Mar  9 2015)
+// C++ code generated with wxFormBuilder (version Mar 13 2015)
 // http://www.wxformbuilder.org/
 //
 // PLEASE DO "NOT" EDIT THIS FILE!
@@ -106,6 +106,8 @@ class DIALOG_EESCHEMA_OPTIONS_BASE : public DIALOG_SHIM
 		wxCheckBox* m_checkAutoPan;
 		wxCheckBox* m_checkHVOrientation;
 		wxCheckBox* m_checkPageLimits;
+		wxCheckBox* m_checkAutoplaceFields;
+		wxCheckBox* m_checkAutoplaceJustify;
 		wxPanel* m_panel2;
 		wxListView* templateFieldListCtrl;
 		wxStaticText* fieldNameLabel;
diff --git a/eeschema/edit_component_in_schematic.cpp b/eeschema/edit_component_in_schematic.cpp
index 3b9104a..19fa77f 100644
--- a/eeschema/edit_component_in_schematic.cpp
+++ b/eeschema/edit_component_in_schematic.cpp
@@ -137,6 +137,10 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField )
     {
         dlg.TransfertDataToField( /* aIncludeText = */ !( fieldNdx == VALUE && part->IsPower() ) );
         OnModify();
+
+        if( m_autoplaceFields && component->GetFieldsAutoplaced() )
+            component->AutoplaceFields();
+
         m_canvas->Refresh();
     }
 
diff --git a/eeschema/eeschema_config.cpp b/eeschema/eeschema_config.cpp
index 81a9838..eb1a7ab 100644
--- a/eeschema/eeschema_config.cpp
+++ b/eeschema/eeschema_config.cpp
@@ -335,6 +335,8 @@ void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event )
     dlg.SetEnableAutoPan( m_canvas->GetEnableAutoPan() );
     dlg.SetEnableHVBusOrientation( GetForceHVLines() );
     dlg.SetShowPageLimits( m_showPageLimits );
+    dlg.SetAutoplaceFields( m_autoplaceFields );
+    dlg.SetAutoplaceJustify( m_autoplaceJustify );
     dlg.Layout();
     dlg.Fit();
     dlg.SetMinSize( dlg.GetSize() );
@@ -382,6 +384,8 @@ void SCH_EDIT_FRAME::OnPreferencesOptions( wxCommandEvent& event )
     m_canvas->SetEnableAutoPan( dlg.GetEnableAutoPan() );
     SetForceHVLines( dlg.GetEnableHVBusOrientation() );
     m_showPageLimits = dlg.GetShowPageLimits();
+    m_autoplaceFields = dlg.GetAutoplaceFields();
+    m_autoplaceJustify = dlg.GetAutoplaceJustify();
 
     // Delete all template fieldnames and then restore them using the template field data from
     // the options dialog
@@ -502,6 +506,8 @@ void SCH_EDIT_FRAME::SaveProjectSettings( bool aAskForSave )
 }
 
 
+static const wxChar AutoplaceFieldsEntry[] =        wxT( "AutoplaceFields" );
+static const wxChar AutoplaceJustifyEntry[] =       AUTOPLACE_JUSTIFY_KEY;
 static const wxChar DefaultBusWidthEntry[] =        wxT( "DefaultBusWidth" );
 static const wxChar DefaultDrawLineWidthEntry[] =   wxT( "DefaultDrawLineWidth" );
 static const wxChar ShowHiddenPinsEntry[] =         wxT( "ShowHiddenPins" );
@@ -585,6 +591,8 @@ void SCH_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg )
     SetDefaultLineThickness( aCfg->Read( DefaultDrawLineWidthEntry, DEFAULTDRAWLINETHICKNESS ) );
     aCfg->Read( ShowHiddenPinsEntry, &m_showAllPins, false );
     aCfg->Read( HorzVertLinesOnlyEntry, &m_forceHVLines, true );
+    aCfg->Read( AutoplaceFieldsEntry, &m_autoplaceFields, true );
+    aCfg->Read( AutoplaceJustifyEntry, &m_autoplaceJustify, true );
 
     // Load print preview window session settings.
     aCfg->Read( PreviewFramePositionXEntry, &tmp, -1 );
@@ -675,6 +683,8 @@ void SCH_EDIT_FRAME::SaveSettings( wxConfigBase* aCfg )
     aCfg->Write( DefaultDrawLineWidthEntry, (long) GetDefaultLineThickness() );
     aCfg->Write( ShowHiddenPinsEntry, m_showAllPins );
     aCfg->Write( HorzVertLinesOnlyEntry, GetForceHVLines() );
+    aCfg->Write( AutoplaceFieldsEntry, m_autoplaceFields );
+    aCfg->Write( AutoplaceJustifyEntry, m_autoplaceJustify );
 
     // Save print preview window session settings.
     aCfg->Write( PreviewFramePositionXEntry, m_previewPosition.x );
diff --git a/eeschema/eeschema_config.h b/eeschema/eeschema_config.h
index e93160b..f517ac1 100644
--- a/eeschema/eeschema_config.h
+++ b/eeschema/eeschema_config.h
@@ -10,4 +10,7 @@
 // a key to read write in user config the visibility of the rescue library dialog
 #define RESCUE_NEVER_SHOW_KEY wxT("RescueNeverShow")
 
+// define autoplace key here to avoid having to take the long trip to get at the SCH_EDIT_FRAME
+#define AUTOPLACE_JUSTIFY_KEY wxT("AutoplaceJustify")
+
 #endif      // EESCHEMA_CONFIG_H
diff --git a/eeschema/eeschema_id.h b/eeschema/eeschema_id.h
index 98c3282..b193282 100644
--- a/eeschema/eeschema_id.h
+++ b/eeschema/eeschema_id.h
@@ -168,6 +168,8 @@ enum id_eeschema_frm
     ID_SCH_MOVE_ITEM,
     ID_SCH_DRAG_ITEM,
 
+    ID_AUTOPLACE_FIELDS,
+
     // Schematic editor commmands.  These are command IDs that are generated by multiple
     // events (menus, toolbar, context menu, etc.) that result in the same event handler.
     ID_CANCEL_CURRENT_COMMAND,
diff --git a/eeschema/getpart.cpp b/eeschema/getpart.cpp
index 8c8db7e..ce5104b 100644
--- a/eeschema/getpart.cpp
+++ b/eeschema/getpart.cpp
@@ -242,6 +242,9 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( wxDC*           aDC,
     SetMsgPanel( items );
     component->Draw( m_canvas, aDC, wxPoint( 0, 0 ), g_XorMode );
     component->SetFlags( IS_NEW );
+
+    if( m_autoplaceFields ) component->AutoplaceFields();
+
     PrepareMoveItem( (SCH_ITEM*) component, aDC );
 
     return component;
@@ -268,27 +271,8 @@ void SCH_EDIT_FRAME::OrientComponent( COMPONENT_ORIENTATION_T aOrientation )
 
     INSTALL_UNBUFFERED_DC( dc, m_canvas );
 
-    // Erase the previous component in it's current orientation.
-
-    m_canvas->CrossHairOff( &dc );
-
-    if( component->GetFlags() )
-        component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
-    else
-    {
-        component->SetFlags( IS_MOVED );    // do not redraw the component
-        m_canvas->RefreshDrawingRect( component->GetBoundingBox() );
-        component->ClearFlags( IS_MOVED );
-    }
-
     component->SetOrientation( aOrientation );
 
-    /* Redraw the component in the new position. */
-    if( component->GetFlags() )
-        component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), g_XorMode );
-    else
-        component->Draw( m_canvas, &dc, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
-
     m_canvas->CrossHairOn( &dc );
     GetScreen()->TestDanglingEnds( m_canvas, &dc );
     OnModify();
diff --git a/eeschema/hotkeys.cpp b/eeschema/hotkeys.cpp
index e5a6c37..45396f0 100644
--- a/eeschema/hotkeys.cpp
+++ b/eeschema/hotkeys.cpp
@@ -217,6 +217,10 @@ static EDA_HOTKEY HkSaveLib( _HKI( "Save Library" ), HK_SAVE_LIB, 'S' + GR_KB_CT
 static EDA_HOTKEY HkSaveSchematic( _HKI( "Save Schematic" ), HK_SAVE_SCH, 'S' + GR_KB_CTRL );
 static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' + GR_KB_CTRL );
 
+// Autoplace fields
+static EDA_HOTKEY HkAutoplaceFields( _HKI( "Autoplace Fields" ), HK_AUTOPLACE_FIELDS, 'O',
+                                        ID_AUTOPLACE_FIELDS );
+
 // List of common hotkey descriptors
 static EDA_HOTKEY* common_Hotkey_List[] =
 {
@@ -290,6 +294,7 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
     &HkAddGraphicPolyLine,
     &HkAddGraphicText,
     &HkLeaveSheet,
+    &HkAutoplaceFields,
     NULL
 };
 
@@ -576,6 +581,7 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
     case HK_ORIENT_NORMAL_COMPONENT:        // Orient 0, no mirror (Component)
     case HK_ROTATE:                         // Rotate schematic item.
     case HK_EDIT_COMPONENT_WITH_LIBEDIT:    // Call Libedit and load the current component
+    case HK_AUTOPLACE_FIELDS:               // Autoplace all fields around component
         {
             // force a new item search on hot keys at current position,
             // if there is no currently edited item,
diff --git a/eeschema/hotkeys.h b/eeschema/hotkeys.h
index 433a15a..ce47446 100644
--- a/eeschema/hotkeys.h
+++ b/eeschema/hotkeys.h
@@ -77,7 +77,8 @@ enum hotkey_id_commnand {
     HK_LOAD_SCH,
     HK_LEFT_CLICK,
     HK_LEFT_DCLICK,
-    HK_LEAVE_SHEET
+    HK_LEAVE_SHEET,
+    HK_AUTOPLACE_FIELDS,
 };
 
 // List of hotkey descriptors for Eeschema
diff --git a/eeschema/lib_pin.cpp b/eeschema/lib_pin.cpp
index c4dd914..9d28a92 100644
--- a/eeschema/lib_pin.cpp
+++ b/eeschema/lib_pin.cpp
@@ -2002,7 +2002,7 @@ void LIB_PIN::GetMsgPanelInfo( MSG_PANEL_ITEMS& aList )
 }
 
 
-const EDA_RECT LIB_PIN::GetBoundingBox() const
+const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles ) const
 {
     LIB_PART*      entry = (LIB_PART*     ) m_Parent;
     EDA_RECT       bbox;
@@ -2013,6 +2013,8 @@ const EDA_RECT LIB_PIN::GetBoundingBox() const
     bool           showNum = m_number != 0;
     int            minsizeV = TARGET_PIN_RADIUS;
 
+    if( !aIncludeInvisibles && !IsVisible() )
+        showName = false;
 
     if( entry )
     {
diff --git a/eeschema/lib_pin.h b/eeschema/lib_pin.h
index 5fa0ad8..0362935 100644
--- a/eeschema/lib_pin.h
+++ b/eeschema/lib_pin.h
@@ -149,7 +149,14 @@ public:
 
     bool Matches( wxFindReplaceData& aSearchData, void* aAuxData, wxPoint* aFindLocation );
 
-    const EDA_RECT GetBoundingBox() const;    // Virtual
+    const EDA_RECT GetBoundingBox() const { return GetBoundingBox( false ); }
+
+    /**
+     * Function GetBoundingBox
+     * @param aIncludeInvisibles - if false, do not include labels for invisible pins
+     *      in the calculation.
+     */
+    const EDA_RECT GetBoundingBox( bool aIncludeInvisibles ) const;
 
     /**
      * Function PinEndPoint
@@ -383,7 +390,7 @@ public:
      *
      * @return True if draw object is visible otherwise false.
      */
-    bool IsVisible() { return ( m_attributes & PIN_INVISIBLE ) == 0; }
+    bool IsVisible() const { return ( m_attributes & PIN_INVISIBLE ) == 0; }
 
     int GetPenSize() const;
 
diff --git a/eeschema/onrightclick.cpp b/eeschema/onrightclick.cpp
index 047dfa7..269e342 100644
--- a/eeschema/onrightclick.cpp
+++ b/eeschema/onrightclick.cpp
@@ -394,6 +394,9 @@ void AddMenusForComponent( wxMenu* PopMenu, SCH_COMPONENT* Component, PART_LIBS*
         AddMenuItem( PopMenu, ID_POPUP_SCH_DELETE_CMP, msg, KiBitmap( delete_xpm ) );
     }
 
+    msg = AddHotkeyName( _( "Autoplace Fields" ), g_Schematic_Hokeys_Descr, HK_AUTOPLACE_FIELDS );
+    AddMenuItem( PopMenu, ID_AUTOPLACE_FIELDS, msg, KiBitmap( autoplace_fields_xpm ) );
+
     if( libEntry && !libEntry->GetDocFileName().IsEmpty() )
         AddMenuItem( PopMenu, ID_POPUP_SCH_DISPLAYDOC_CMP, _( "Doc" ), KiBitmap( datasheet_xpm ) );
 }
diff --git a/eeschema/sch_component.cpp b/eeschema/sch_component.cpp
index 6a3f639..52eb1e9 100644
--- a/eeschema/sch_component.cpp
+++ b/eeschema/sch_component.cpp
@@ -217,6 +217,7 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
     }
 
     m_isDangling = aComponent.m_isDangling;
+    m_fieldsAutoplaced = aComponent.m_fieldsAutoplaced;
 }
 
 
@@ -660,6 +661,16 @@ SCH_FIELD* SCH_COMPONENT::GetField( int aFieldNdx ) const
 }
 
 
+void SCH_COMPONENT::GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly )
+{
+    BOOST_FOREACH( SCH_FIELD& each_field, m_Fields )
+    {
+        if( !aVisibleOnly || ( each_field.IsVisible() && !each_field.IsVoid() ) )
+            aVector.push_back( &each_field );
+    }
+}
+
+
 SCH_FIELD* SCH_COMPONENT::AddField( const SCH_FIELD& aField )
 {
     int newNdx = m_Fields.size();
@@ -691,6 +702,17 @@ LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number )
 }
 
 
+void SCH_COMPONENT::GetPins( std::vector<LIB_PIN*>& aPinsList )
+{
+    if( PART_SPTR part = m_part.lock() )
+    {
+        part->GetPins( aPinsList, m_unit, m_convert );
+    }
+    else
+        wxFAIL_MSG( "Could not obtain PART_SPTR lock" );
+}
+
+
 void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
 {
     wxCHECK_RET( (aItem != NULL) && (aItem->Type() == SCH_COMPONENT_T),
diff --git a/eeschema/sch_component.h b/eeschema/sch_component.h
index c6049c8..483bd1d 100644
--- a/eeschema/sch_component.h
+++ b/eeschema/sch_component.h
@@ -82,6 +82,8 @@ class SCH_COMPONENT : public SCH_ITEM
 
     std::vector<bool> m_isDangling; ///< One isDangling per pin
 
+    bool        m_fieldsAutoplaced; ///< true if fields have not been moved since last autoplace
+
     /**
      * A temporary sheet path is required to generate the correct reference designator string
      * in complex heirarchies.  Hopefully this is only a temporary hack to decouple schematic
@@ -100,8 +102,6 @@ class SCH_COMPONENT : public SCH_ITEM
 
     void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
 
-    EDA_RECT GetBodyBoundingBox() const;
-
 public:
     SCH_COMPONENT( const wxPoint& pos = wxPoint( 0, 0 ), SCH_ITEM* aParent = NULL );
 
@@ -255,6 +255,13 @@ public:
 
     const EDA_RECT GetBoundingBox() const;    // Virtual
 
+    /**
+     * Function GetBodyBoundingBox
+     * Return a bounding box for the component body but not the fields.
+     */
+    EDA_RECT GetBodyBoundingBox() const;
+
+
     //-----<Fields>-----------------------------------------------------------
 
     /**
@@ -266,6 +273,14 @@ public:
     SCH_FIELD* GetField( int aFieldNdx ) const;
 
     /**
+     * Function GetFields
+     * populates a std::vector with SCH_FIELDs.
+     * @param aVector - vector to populate.
+     * @param aVisibleOnly - if true, only get fields that are visible and contain text.
+     */
+    void GetFields( std::vector<SCH_FIELD*>& aVector, bool aVisibleOnly );
+
+    /**
      * Function AddField
      * adds a field to the component.  The field is copied as it is put into
      * the component.
@@ -284,9 +299,6 @@ public:
     {
         m_Fields = aFields;     // vector copying, length is changed possibly
     }
-
-    //-----</Fields>----------------------------------------------------------
-
     /**
      * Function GetFieldCount
      * returns the number of fields in this component.
@@ -294,6 +306,27 @@ public:
     int GetFieldCount() const { return (int) m_Fields.size(); }
 
     /**
+     * Function GetFieldsAutoplaced
+     * returns whether the fields are autoplaced.
+     */
+    bool GetFieldsAutoplaced() const { return m_fieldsAutoplaced; }
+
+    /**
+     * Function ClearFieldsAutoplaced
+     * Set fields autoplaced flag false.
+     */
+    void ClearFieldsAutoplaced() { m_fieldsAutoplaced = false; }
+
+    /**
+     * Function AutoplaceFields
+     * Automatically orient all the fields in the component.
+     */
+    void AutoplaceFields();
+
+    //-----</Fields>----------------------------------------------------------
+
+
+    /**
      * Function GetPin
      * finds a component pin by number.
      *
@@ -303,6 +336,12 @@ public:
     LIB_PIN* GetPin( const wxString& number );
 
     /**
+     * Function GetPins
+     * populate a vector with all the pins.
+     */
+    void GetPins( std::vector<LIB_PIN*>& aPinsList );
+
+    /**
      * Virtual function, from the base class SCH_ITEM::Draw
      */
     void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
diff --git a/eeschema/sch_field.cpp b/eeschema/sch_field.cpp
index a2b2775..ed3f01b 100644
--- a/eeschema/sch_field.cpp
+++ b/eeschema/sch_field.cpp
@@ -303,6 +303,23 @@ const EDA_RECT SCH_FIELD::GetBoundingBox() const
 }
 
 
+bool SCH_FIELD::IsHorizJustifyFlipped() const
+{
+    wxPoint render_center = GetBoundingBox().Centre();
+    wxPoint pos = GetPosition();
+
+    switch( GetHorizJustify() )
+    {
+    case GR_TEXT_HJUSTIFY_LEFT:
+        return render_center.x < pos.x;
+    case GR_TEXT_HJUSTIFY_RIGHT:
+        return render_center.x > pos.x;
+    default:
+        return false;
+    }
+}
+
+
 bool SCH_FIELD::Save( FILE* aFile ) const
 {
     char hjustify = 'C';
diff --git a/eeschema/sch_field.h b/eeschema/sch_field.h
index 8b458bc..814876a 100644
--- a/eeschema/sch_field.h
+++ b/eeschema/sch_field.h
@@ -103,6 +103,13 @@ public:
     const EDA_RECT GetBoundingBox() const;    // Virtual
 
     /**
+     * Function IsHorizJustifyFlipped
+     * Returns whether the field will be rendered with the horizontal justification
+     * inverted due to rotation or mirroring of the parent.
+     */
+    bool IsHorizJustifyFlipped() const;
+
+    /**
      * Function IsVoid
      * returns true if the field is either empty or holds "~".
      */
@@ -131,7 +138,7 @@ public:
      */
     bool IsVisible() const
     {
-        return (m_Attributs & TEXT_NO_VISIBLE) == 0 ? true : false;
+        return !( m_Attributs & TEXT_NO_VISIBLE );
     }
 
     void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
diff --git a/eeschema/schedit.cpp b/eeschema/schedit.cpp
index 8fa7da3..f1b7652 100644
--- a/eeschema/schedit.cpp
+++ b/eeschema/schedit.cpp
@@ -756,6 +756,13 @@ void SCH_EDIT_FRAME::PrepareMoveItem( SCH_ITEM* aItem, wxDC* aDC )
             SetUndoItem( aItem );
     }
 
+    if( aItem->Type() == SCH_FIELD_T && aItem->GetParent()->Type() == SCH_COMPONENT_T )
+    {
+        // Now that we're moving a field, they're no longer autoplaced.
+        SCH_COMPONENT *parent = dynamic_cast<SCH_COMPONENT*>( aItem->GetParent() );
+        parent->ClearFieldsAutoplaced();
+    }
+
     aItem->SetFlags( IS_MOVED );
 
     // For some items, moving the cursor to anchor is not good
@@ -817,14 +824,22 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
     switch( item->Type() )
     {
     case SCH_COMPONENT_T:
-        if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
-            OrientComponent( CMP_ROTATE_CLOCKWISE );
-        else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
-            OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
-        else
-            wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );
+        {
+            SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( item );
+            if( aEvent.GetId() == ID_SCH_ROTATE_CLOCKWISE )
+                OrientComponent( CMP_ROTATE_CLOCKWISE );
+            else if( aEvent.GetId() == ID_SCH_ROTATE_COUNTERCLOCKWISE )
+                OrientComponent( CMP_ROTATE_COUNTERCLOCKWISE );
+            else
+                wxFAIL_MSG( wxT( "Unknown rotate item command ID." ) );
+
+            if( m_autoplaceFields && component->GetFieldsAutoplaced() ) {
+                component->AutoplaceFields();
+            }
+            m_canvas->Refresh();
 
-        break;
+            break;
+        }
 
     case SCH_TEXT_T:
     case SCH_LABEL_T:
@@ -837,6 +852,12 @@ void SCH_EDIT_FRAME::OnRotate( wxCommandEvent& aEvent )
     case SCH_FIELD_T:
         m_canvas->MoveCursorToCrossHair();
         RotateField( (SCH_FIELD*) item, &dc );
+        if( item->GetParent()->Type() == SCH_COMPONENT_T )
+        {
+            // Now that we're moving a field, they're no longer autoplaced.
+            SCH_COMPONENT *parent = dynamic_cast<SCH_COMPONENT*>( item->GetParent() );
+            parent->ClearFieldsAutoplaced();
+        }
         break;
 
     case SCH_BITMAP_T:
@@ -1118,16 +1139,24 @@ void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
     switch( item->Type() )
     {
     case SCH_COMPONENT_T:
-        if( aEvent.GetId() == ID_SCH_MIRROR_X )
-            OrientComponent( CMP_MIRROR_X );
-        else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
-            OrientComponent( CMP_MIRROR_Y );
-        else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL )
-            OrientComponent( CMP_NORMAL );
-        else
-            wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) );
+        {
+            SCH_COMPONENT *component = dynamic_cast<SCH_COMPONENT*>( item );
+            if( aEvent.GetId() == ID_SCH_MIRROR_X )
+                OrientComponent( CMP_MIRROR_X );
+            else if( aEvent.GetId() == ID_SCH_MIRROR_Y )
+                OrientComponent( CMP_MIRROR_Y );
+            else if( aEvent.GetId() == ID_SCH_ORIENT_NORMAL )
+                OrientComponent( CMP_NORMAL );
+            else
+                wxFAIL_MSG( wxT( "Invalid orient schematic component command ID." ) );
+
+            if( m_autoplaceFields && component->GetFieldsAutoplaced() ) {
+                component->AutoplaceFields();
+            }
+            m_canvas->Refresh();
 
-        break;
+            break;
+        }
 
     case SCH_BITMAP_T:
         if( aEvent.GetId() == ID_SCH_MIRROR_X )
diff --git a/eeschema/schframe.cpp b/eeschema/schframe.cpp
index 769d6cd..7ee2506 100644
--- a/eeschema/schframe.cpp
+++ b/eeschema/schframe.cpp
@@ -266,6 +266,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
     EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
     EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile )
     EVT_TOOL( ID_SCH_MOVE_ITEM, SCH_EDIT_FRAME::OnMoveItem )
+    EVT_TOOL( ID_AUTOPLACE_FIELDS, SCH_EDIT_FRAME::OnAutoplaceFields )
     EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
     EVT_MENU( wxID_INDEX, EDA_DRAW_FRAME::GetKicadHelp )
     EVT_MENU( wxID_ABOUT, EDA_BASE_FRAME::GetKicadAbout )
diff --git a/eeschema/schframe.h b/eeschema/schframe.h
index 9f55bb1..1cbf8f6 100644
--- a/eeschema/schframe.h
+++ b/eeschema/schframe.h
@@ -146,6 +146,9 @@ private:
 
     bool                    m_forceHVLines;       ///< force H or V directions for wires, bus, line
 
+    bool                    m_autoplaceFields;    ///< automatically place component fields
+    bool                    m_autoplaceJustify;   ///< allow autoplace to change justification
+
     /// An index to the last find item in the found items list #m_foundItems.
     int         m_foundItemIndex;
 
@@ -765,6 +768,12 @@ public:
 private:
 
     /**
+     * Function OnAutoplaceFields
+     * handles the #ID_AUTOPLACE_FIELDS event.
+     */
+    void OnAutoplaceFields( wxCommandEvent& aEvent );
+
+    /**
      * Function OnMoveItem
      * handles the #ID_SCH_MOVE_ITEM event used to move schematic itams.
      */
diff --git a/include/bitmaps.h b/include/bitmaps.h
index 25b3751..c077afb 100644
--- a/include/bitmaps.h
+++ b/include/bitmaps.h
@@ -111,6 +111,7 @@ EXTERN_BITMAP( array_zone_xpm )
 EXTERN_BITMAP( auto_associe_xpm )
 EXTERN_BITMAP( auto_delete_track_xpm )
 EXTERN_BITMAP( auto_track_width_xpm )
+EXTERN_BITMAP( autoplace_fields_xpm )
 EXTERN_BITMAP( axis3d_back_xpm )
 EXTERN_BITMAP( axis3d_bottom_xpm )
 EXTERN_BITMAP( axis3d_front_xpm )
diff --git a/include/class_eda_rect.h b/include/class_eda_rect.h
index d12b424..ae1424f 100644
--- a/include/class_eda_rect.h
+++ b/include/class_eda_rect.h
@@ -103,8 +103,12 @@ public:
     int GetHeight() const { return m_Size.y; }
     int GetRight() const { return m_Pos.x + m_Size.x; }
     int GetLeft() const { return m_Pos.x; }
+    int GetTop() const { return m_Pos.y; }
     int GetBottom() const { return m_Pos.y + m_Size.y; }    // Y axis from top to bottom
 
+    wxPoint GetCenter() const { return wxPoint( m_Pos.x + m_Size.x / 2,
+                                                m_Pos.y + m_Size.y / 2 ); }
+
     void SetOrigin( const wxPoint& pos ) { m_Pos = pos; }
     void SetOrigin( int x, int y ) { m_Pos.x = x; m_Pos.y = y; }
     void SetSize( const wxSize& size ) { m_Size = size; }

Follow ups