Skip to content

Instantly share code, notes, and snippets.

@johnbeard
Created December 6, 2014 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnbeard/9968d9647b4d48412a22 to your computer and use it in GitHub Desktop.
Save johnbeard/9968d9647b4d48412a22 to your computer and use it in GitHub Desktop.
Move exact patch
diff --git a/bitmaps_png/CMakeLists.txt b/bitmaps_png/CMakeLists.txt
index 152b1ab..3fde247 100644
--- a/bitmaps_png/CMakeLists.txt
+++ b/bitmaps_png/CMakeLists.txt
@@ -216,6 +216,9 @@ set( BMAPS_MID
drag_track_segment
drc_off
drc
+ duplicate_line
+ duplicate_pad
+ duplicate_text
edges_sketch
edit_comp_footprint
edit_component
diff --git a/bitmaps_png/cpp_26/duplicate_line.cpp b/bitmaps_png/cpp_26/duplicate_line.cpp
new file mode 100644
index 0000000..658feb7
--- /dev/null
+++ b/bitmaps_png/cpp_26/duplicate_line.cpp
@@ -0,0 +1,38 @@
+
+/* 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, 0x01, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0x63, 0xf8, 0xff, 0xff, 0x3f,
+ 0x03, 0x3d, 0x30, 0xc3, 0xa8, 0x45, 0x14, 0x59, 0xc4, 0x30, 0x8b, 0xc1, 0x9e, 0x61, 0x36, 0xc3,
+ 0x0a, 0x9a, 0x60, 0xa0, 0xd9, 0xc8, 0x16, 0x25, 0x00, 0x05, 0xff, 0xd3, 0x04, 0x03, 0xcd, 0x46,
+ 0xb6, 0xc8, 0x00, 0x28, 0xd8, 0x40, 0x13, 0x0c, 0x34, 0x9b, 0xac, 0x38, 0xda, 0xc4, 0xc0, 0x30,
+ 0x6f, 0x39, 0x03, 0x83, 0x39, 0xcd, 0x12, 0xc3, 0x32, 0x06, 0x06, 0x8d, 0x1d, 0x1c, 0x1c, 0x1f,
+ 0x37, 0x32, 0x30, 0xbc, 0xa1, 0x59, 0xaa, 0x5b, 0xc5, 0xc0, 0xc0, 0x76, 0x4c, 0x49, 0xe9, 0xdb,
+ 0x11, 0x69, 0xe9, 0x6f, 0x4b, 0x18, 0x18, 0xf8, 0x68, 0x66, 0xd1, 0x76, 0x46, 0xc6, 0x23, 0x6f,
+ 0xe2, 0x62, 0xff, 0x6f, 0x65, 0x60, 0xd8, 0x4b, 0xd3, 0x7c, 0x74, 0x42, 0x46, 0xe6, 0xf5, 0xdb,
+ 0xd8, 0x98, 0xff, 0x6b, 0x18, 0x18, 0xba, 0x69, 0x6a, 0xd1, 0x7e, 0x5e, 0xde, 0xc7, 0x3f, 0x32,
+ 0x32, 0xfe, 0x1f, 0xe2, 0xe3, 0x7b, 0x49, 0x53, 0x8b, 0xb6, 0x31, 0x30, 0xac, 0xfb, 0xe0, 0xe9,
+ 0xf1, 0xff, 0xb9, 0x9b, 0xdb, 0xbf, 0x1d, 0x4c, 0x4c, 0x93, 0x67, 0x32, 0x30, 0x88, 0x00, 0x7d,
+ 0x37, 0x99, 0xea, 0x16, 0x35, 0x30, 0x30, 0xb0, 0x9c, 0xd6, 0xd5, 0xfd, 0xf6, 0xdb, 0xc2, 0xfc,
+ 0xff, 0x35, 0x4b, 0xcb, 0x3f, 0x27, 0x14, 0x14, 0xbe, 0x1e, 0xe0, 0x27, 0xcd, 0x77, 0x44, 0x2b,
+ 0x04, 0xfa, 0xaa, 0xf1, 0xa5, 0xbb, 0xfb, 0xbf, 0xdf, 0x26, 0x26, 0xff, 0x7f, 0x44, 0x84, 0xff,
+ 0x3f, 0x22, 0x26, 0xf6, 0x9c, 0x26, 0x16, 0xed, 0x66, 0x65, 0xdd, 0xfd, 0xd8, 0xc7, 0xe7, 0xdf,
+ 0x5f, 0x29, 0xa9, 0xff, 0x7f, 0xb4, 0xb5, 0xfe, 0x1f, 0x15, 0x17, 0xa3, 0xbe, 0x8f, 0x80, 0x79,
+ 0xc7, 0x62, 0x27, 0x27, 0xe7, 0xb3, 0xb3, 0x9a, 0x9a, 0x5f, 0x6f, 0xd9, 0xd9, 0xfe, 0x7d, 0xe3,
+ 0xeb, 0xf3, 0xff, 0xa8, 0xa8, 0xe8, 0x2b, 0xd2, 0x4b, 0xef, 0x55, 0x0c, 0xcc, 0x0c, 0xf3, 0x19,
+ 0x38, 0x88, 0xc1, 0x0d, 0xda, 0x0c, 0x72, 0x0b, 0xb9, 0x18, 0x6a, 0x57, 0x70, 0x32, 0x4c, 0x22,
+ 0x4a, 0xcf, 0x24, 0x06, 0x76, 0xfa, 0x94, 0xde, 0xb3, 0x19, 0x5e, 0x0c, 0x80, 0x45, 0x53, 0x19,
+ 0x78, 0x18, 0xa6, 0x33, 0x28, 0xd0, 0x04, 0xcf, 0x63, 0x90, 0x1d, 0x6d, 0x9c, 0x0c, 0x0d, 0x8b,
+ 0x00, 0xd8, 0x9d, 0x80, 0xfa, 0xbc, 0xd9, 0x5d, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
+ 0x44, 0xae, 0x42, 0x60, 0x82,
+};
+
+const BITMAP_OPAQUE duplicate_line_xpm[1] = {{ png, sizeof( png ), "duplicate_line_xpm" }};
+
+//EOF
diff --git a/bitmaps_png/cpp_26/duplicate_pad.cpp b/bitmaps_png/cpp_26/duplicate_pad.cpp
new file mode 100644
index 0000000..790c652
--- /dev/null
+++ b/bitmaps_png/cpp_26/duplicate_pad.cpp
@@ -0,0 +1,61 @@
+
+/* 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, 0x02, 0xc4, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xad, 0x95, 0x4b, 0x6c, 0x8c,
+ 0x51, 0x14, 0xc7, 0x7f, 0xd4, 0xa3, 0x41, 0x25, 0xa2, 0x2d, 0x83, 0x78, 0x34, 0x48, 0x25, 0x82,
+ 0x09, 0x8d, 0x04, 0x09, 0x8b, 0xaa, 0xda, 0x50, 0x16, 0x95, 0x94, 0x8d, 0xb0, 0xb0, 0xb5, 0x60,
+ 0x69, 0xfe, 0x77, 0x10, 0xaf, 0x1d, 0x1b, 0x12, 0xd2, 0x0d, 0x45, 0x55, 0x24, 0x53, 0xd4, 0x23,
+ 0xa5, 0x19, 0x15, 0x23, 0xf5, 0x8e, 0x4a, 0x55, 0x1a, 0xa3, 0x94, 0x7a, 0xa4, 0x5a, 0x5a, 0xd3,
+ 0xe9, 0x63, 0x3e, 0x0b, 0xb7, 0xf1, 0x09, 0x4d, 0x3e, 0xd3, 0x59, 0x9c, 0xcd, 0xbd, 0xe7, 0x3b,
+ 0xbf, 0x7b, 0xce, 0xf9, 0x9f, 0xf3, 0xe1, 0x38, 0x0e, 0xff, 0x32, 0x44, 0x0e, 0xa2, 0x18, 0xc3,
+ 0x56, 0x82, 0x2c, 0xa4, 0x9c, 0xb4, 0xc1, 0x7c, 0xbd, 0xd8, 0xdf, 0x07, 0xfb, 0x99, 0x84, 0xb8,
+ 0x8c, 0xe8, 0x47, 0x7c, 0xc2, 0xf0, 0x1e, 0x43, 0x37, 0xe2, 0x25, 0x41, 0x16, 0xa7, 0x04, 0xc4,
+ 0x01, 0x26, 0x20, 0x3e, 0x62, 0x88, 0x22, 0xaa, 0x10, 0x21, 0x6b, 0x95, 0x88, 0x17, 0x88, 0x38,
+ 0x62, 0xd9, 0xd0, 0x41, 0x86, 0x32, 0xc4, 0x5b, 0x1b, 0xbc, 0x1a, 0x43, 0x23, 0xa2, 0x89, 0x00,
+ 0x77, 0xed, 0x59, 0x3d, 0x22, 0x8a, 0x48, 0x4f, 0x1a, 0x84, 0x48, 0xc7, 0xd0, 0x87, 0xa8, 0xb6,
+ 0xd9, 0x74, 0x23, 0x2e, 0x21, 0x8e, 0x21, 0x62, 0x04, 0xb8, 0x47, 0x80, 0x4a, 0x44, 0x7b, 0xe9,
+ 0x18, 0xea, 0xcb, 0x87, 0x0d, 0xeb, 0xbf, 0xe1, 0xf3, 0x25, 0x1e, 0xfb, 0x17, 0xc5, 0x6f, 0x8e,
+ 0x1d, 0xfb, 0xec, 0x1c, 0xcc, 0xf5, 0x06, 0x0a, 0x92, 0x87, 0xe8, 0xb2, 0x2f, 0x7f, 0x8e, 0xb8,
+ 0xeb, 0x7a, 0x84, 0x10, 0xcd, 0xf6, 0x2e, 0x8a, 0x61, 0x97, 0xe3, 0x38, 0x94, 0x43, 0x49, 0x64,
+ 0xda, 0xd4, 0xce, 0x8e, 0xed, 0xdb, 0x9c, 0xda, 0x19, 0xd3, 0xdb, 0xbc, 0x82, 0xfc, 0x88, 0x98,
+ 0x0d, 0xf6, 0x0c, 0xf1, 0xc8, 0x05, 0x3a, 0x6c, 0x4b, 0x16, 0x42, 0xbc, 0xc1, 0xb0, 0x73, 0xe0,
+ 0xee, 0x04, 0x64, 0x3e, 0xcf, 0xcb, 0xeb, 0xf9, 0x52, 0xb4, 0x3e, 0x11, 0x82, 0xa3, 0x5e, 0x4a,
+ 0x37, 0x0a, 0xd1, 0x8b, 0xa8, 0x41, 0x5c, 0x45, 0x74, 0x61, 0xa8, 0x41, 0x9c, 0xb1, 0x22, 0xa8,
+ 0xb5, 0x6a, 0xfc, 0x4e, 0x90, 0x95, 0xee, 0x20, 0x91, 0xac, 0xac, 0x0f, 0xf1, 0x92, 0x12, 0x27,
+ 0x9c, 0x99, 0xd9, 0xe2, 0x4d, 0x0c, 0xe2, 0x38, 0xe2, 0x83, 0x7d, 0xf9, 0x35, 0xdb, 0xfc, 0x97,
+ 0x88, 0x5b, 0x88, 0x10, 0x86, 0x06, 0xab, 0xbe, 0x11, 0xee, 0xef, 0x6a, 0x27, 0x4e, 0x8c, 0xf6,
+ 0xac, 0xce, 0x77, 0xea, 0xe6, 0xcd, 0x6b, 0xf7, 0x0a, 0x1a, 0x87, 0x78, 0x8d, 0x68, 0xb1, 0xa2,
+ 0xf8, 0x25, 0xef, 0x00, 0x55, 0x88, 0x57, 0x88, 0x1f, 0x04, 0xf1, 0x0f, 0xf8, 0x97, 0xc2, 0x9c,
+ 0x32, 0xc8, 0xbd, 0x93, 0x9d, 0xdd, 0xd2, 0xbb, 0x62, 0xb9, 0xf3, 0xd4, 0xef, 0x8f, 0x79, 0x1f,
+ 0xd8, 0x43, 0x64, 0x20, 0x4a, 0x11, 0x09, 0x44, 0x3b, 0xe2, 0x33, 0x22, 0x81, 0x21, 0x82, 0x98,
+ 0xed, 0xf6, 0x3d, 0x0f, 0x5b, 0xc2, 0x39, 0xb3, 0xfa, 0x9b, 0xd7, 0xad, 0x4b, 0xf4, 0x2e, 0x59,
+ 0xec, 0xb4, 0x6e, 0xdc, 0x90, 0xa8, 0xcb, 0xcd, 0x8d, 0x57, 0xf0, 0xbb, 0xbf, 0x83, 0x82, 0x5c,
+ 0xd9, 0x8d, 0x47, 0xe4, 0x23, 0x8a, 0x10, 0x53, 0x06, 0xf3, 0xbb, 0x3e, 0x72, 0x64, 0xf8, 0x6b,
+ 0x61, 0xa1, 0xe3, 0xa4, 0xa5, 0x39, 0xb1, 0x82, 0x02, 0x27, 0xec, 0xf3, 0x7d, 0x3b, 0x0d, 0xe3,
+ 0x3d, 0x83, 0x3c, 0x1b, 0x0c, 0x0f, 0x4f, 0x9e, 0xd4, 0xf6, 0x63, 0x53, 0xb1, 0x13, 0xc9, 0xc9,
+ 0x89, 0x9d, 0x81, 0x19, 0x9e, 0x4a, 0x97, 0x8c, 0x95, 0x41, 0xee, 0xb5, 0x8c, 0x8c, 0xd8, 0x59,
+ 0x58, 0xea, 0xb9, 0x47, 0xff, 0xb5, 0x56, 0x44, 0x11, 0x86, 0x0a, 0x0c, 0xd1, 0xe1, 0x7b, 0xa8,
+ 0x47, 0x9c, 0x44, 0xcc, 0x4f, 0x19, 0x88, 0xa3, 0x8c, 0x46, 0x5c, 0xb0, 0x9b, 0xa4, 0x01, 0x11,
+ 0x41, 0x3c, 0x40, 0x34, 0xd9, 0x4d, 0xbf, 0x3b, 0x35, 0x20, 0x71, 0xd0, 0xaa, 0xf1, 0xba, 0x1d,
+ 0x81, 0x1b, 0x76, 0x04, 0x42, 0x88, 0x30, 0x22, 0x86, 0x61, 0xcd, 0x90, 0x40, 0x88, 0x99, 0x88,
+ 0x38, 0x01, 0x6e, 0xdb, 0xa1, 0x7e, 0x83, 0xe8, 0xb3, 0x99, 0x34, 0x58, 0xd8, 0x13, 0x44, 0xf3,
+ 0x50, 0x41, 0x25, 0x88, 0x56, 0x1b, 0xb0, 0x01, 0x71, 0x8f, 0xfd, 0xf8, 0x10, 0x0b, 0x10, 0x1d,
+ 0x76, 0x55, 0x5d, 0xb1, 0x73, 0x38, 0x65, 0x28, 0x20, 0xd9, 0x1f, 0x63, 0xc8, 0xae, 0xab, 0x1d,
+ 0xae, 0xbb, 0x0a, 0xbb, 0x41, 0x42, 0x16, 0xba, 0x2a, 0x79, 0x90, 0x61, 0xb3, 0xe7, 0x8c, 0xf6,
+ 0x31, 0x35, 0x79, 0xd0, 0x5e, 0x66, 0x21, 0x7a, 0x5c, 0x3d, 0x7a, 0x67, 0x7f, 0x98, 0x71, 0x44,
+ 0xa3, 0xab, 0x47, 0xef, 0x52, 0xa1, 0xba, 0x23, 0x1e, 0x54, 0xb7, 0x36, 0x75, 0x73, 0x64, 0xe8,
+ 0xb4, 0xe5, 0xbb, 0x4f, 0x80, 0x87, 0x29, 0x9f, 0xa3, 0x3f, 0x36, 0x83, 0xb8, 0x68, 0x25, 0x5e,
+ 0x8f, 0x38, 0x95, 0xd2, 0xcd, 0x90, 0x8c, 0xfd, 0x04, 0xc8, 0x94, 0x24, 0x31, 0x6a, 0x1a, 0x22,
+ 0xc6, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+};
+
+const BITMAP_OPAQUE duplicate_pad_xpm[1] = {{ png, sizeof( png ), "duplicate_pad_xpm" }};
+
+//EOF
diff --git a/bitmaps_png/cpp_26/duplicate_text.cpp b/bitmaps_png/cpp_26/duplicate_text.cpp
new file mode 100644
index 0000000..bcf83ca
--- /dev/null
+++ b/bitmaps_png/cpp_26/duplicate_text.cpp
@@ -0,0 +1,55 @@
+
+/* 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, 0x02, 0x66, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0xd6, 0x5d, 0x48, 0x53,
+ 0x61, 0x1c, 0xc7, 0xf1, 0xef, 0xd9, 0xa4, 0x12, 0x2f, 0x46, 0xea, 0xca, 0x8d, 0xbc, 0x28, 0x21,
+ 0x76, 0x93, 0xe0, 0x5b, 0x2e, 0xb6, 0x84, 0x68, 0x7a, 0x17, 0x09, 0xb1, 0x79, 0x51, 0xa0, 0x41,
+ 0x59, 0x17, 0x76, 0x51, 0xd4, 0x55, 0x04, 0xad, 0x3b, 0x51, 0xc1, 0x52, 0xa6, 0xc7, 0x33, 0xb2,
+ 0xbc, 0x08, 0x67, 0x45, 0x42, 0x6f, 0x16, 0x34, 0x0c, 0xb4, 0xab, 0x60, 0xbd, 0xa0, 0x88, 0x45,
+ 0x68, 0x5d, 0xc5, 0x50, 0x58, 0x12, 0x9b, 0xba, 0xf6, 0x74, 0x71, 0x46, 0x73, 0xe3, 0x6c, 0xbe,
+ 0x6c, 0xdd, 0x44, 0x17, 0x3f, 0x38, 0xe7, 0x79, 0x1e, 0x9e, 0xcf, 0xf9, 0x9f, 0xf3, 0x9c, 0xe7,
+ 0x1c, 0x60, 0x44, 0x0f, 0x83, 0x3b, 0x36, 0x9e, 0xeb, 0x79, 0x42, 0x08, 0x36, 0x1b, 0x60, 0xa0,
+ 0x05, 0x14, 0xb1, 0xf1, 0x74, 0xdc, 0x05, 0x0c, 0x59, 0x40, 0xed, 0x41, 0x68, 0x0b, 0xc0, 0xa5,
+ 0x8f, 0xc9, 0x13, 0x5f, 0xfb, 0xa2, 0xb6, 0xbb, 0xe7, 0xd5, 0xf3, 0xb6, 0x00, 0x60, 0xdf, 0x22,
+ 0xe4, 0x59, 0x00, 0x93, 0x17, 0x70, 0x42, 0x6d, 0x7d, 0x32, 0x54, 0xff, 0x04, 0x38, 0x02, 0x85,
+ 0x56, 0xe8, 0xfc, 0xbc, 0x9d, 0xd6, 0xf7, 0xb7, 0x61, 0x6c, 0xc2, 0x68, 0x0c, 0x7d, 0xa8, 0x3d,
+ 0x18, 0x9d, 0xb2, 0xdb, 0x57, 0x26, 0xcd, 0xe6, 0x1f, 0x23, 0x50, 0xb5, 0x0e, 0x24, 0x1b, 0x60,
+ 0x7f, 0x13, 0x70, 0x1a, 0xd0, 0x83, 0x6c, 0xd2, 0x80, 0x4a, 0x00, 0x09, 0x2e, 0x16, 0xde, 0x60,
+ 0xdb, 0x9b, 0x51, 0x98, 0x1b, 0x83, 0xd7, 0x2f, 0x25, 0x29, 0xf0, 0xd6, 0x62, 0x09, 0x2f, 0x9d,
+ 0x6b, 0x15, 0xef, 0xca, 0x0f, 0xac, 0x8c, 0xc2, 0xb1, 0xb4, 0x50, 0x5c, 0x93, 0x00, 0x49, 0x3d,
+ 0x1e, 0x2c, 0xd1, 0x82, 0xd6, 0x5c, 0xd9, 0x9f, 0xb1, 0x42, 0x08, 0xee, 0xc1, 0xee, 0x80, 0xc5,
+ 0x12, 0x89, 0x34, 0xb9, 0xc4, 0x44, 0x69, 0xe9, 0x62, 0x46, 0x28, 0xb9, 0xc4, 0xcc, 0x90, 0x56,
+ 0x9e, 0xc2, 0x70, 0xc8, 0x71, 0x54, 0x7c, 0x6d, 0x68, 0x88, 0x3d, 0x82, 0x53, 0x42, 0x08, 0x04,
+ 0xe8, 0x72, 0x0e, 0xc9, 0x50, 0x3c, 0x5b, 0x57, 0xb7, 0xba, 0x62, 0xb3, 0x09, 0xbf, 0xd1, 0x18,
+ 0x1e, 0x2f, 0x2a, 0x5a, 0x7a, 0x00, 0x77, 0x72, 0x0a, 0xdd, 0x07, 0xa7, 0x3f, 0x3f, 0xff, 0xd3,
+ 0xcc, 0x61, 0x7b, 0x74, 0xb5, 0xb2, 0x42, 0x44, 0x5c, 0x4e, 0x31, 0x75, 0xc8, 0xba, 0x3a, 0x04,
+ 0xbb, 0x72, 0x0a, 0x0d, 0xc1, 0x5e, 0xbf, 0xc1, 0xf0, 0x3d, 0xd8, 0x78, 0x3c, 0xf6, 0xcb, 0x64,
+ 0x12, 0xcb, 0x76, 0x9b, 0x78, 0x55, 0x50, 0x30, 0xf7, 0x57, 0x9e, 0x91, 0x10, 0x82, 0xe7, 0x3a,
+ 0x9d, 0x6f, 0xba, 0xa6, 0x26, 0x3a, 0xef, 0x70, 0xc4, 0x7c, 0xd0, 0x98, 0x11, 0x02, 0xb9, 0x0c,
+ 0x94, 0xc9, 0x64, 0xa8, 0x3b, 0x04, 0x6d, 0xce, 0xb5, 0x2b, 0x2d, 0x5d, 0x1e, 0x82, 0xf5, 0xb1,
+ 0x24, 0x4d, 0xaf, 0xbb, 0xea, 0x60, 0xe0, 0x05, 0xf4, 0x2d, 0x42, 0xcf, 0xcf, 0xe4, 0xdc, 0x5a,
+ 0x02, 0x2a, 0xe3, 0x63, 0x86, 0x40, 0x19, 0xdf, 0x78, 0x7a, 0x8b, 0x34, 0x20, 0x24, 0xe0, 0x0c,
+ 0x70, 0x5e, 0x23, 0x27, 0xd5, 0x7e, 0x65, 0x26, 0x51, 0x69, 0xd7, 0x02, 0x78, 0xc2, 0x89, 0xea,
+ 0xe5, 0xa8, 0xda, 0xd6, 0xb5, 0x90, 0x68, 0xdb, 0xd3, 0x01, 0x48, 0x5a, 0x5b, 0x85, 0x94, 0x2e,
+ 0x6a, 0xbf, 0x32, 0x03, 0xee, 0x6f, 0x90, 0xd7, 0x0d, 0xb4, 0xc0, 0x55, 0x7f, 0x62, 0xd2, 0xf6,
+ 0x20, 0xe0, 0x06, 0x9a, 0xe1, 0xf2, 0x33, 0xb5, 0xcd, 0xdc, 0xa3, 0x09, 0xad, 0xbf, 0x39, 0xca,
+ 0xcd, 0x50, 0xdc, 0xaf, 0xee, 0x7f, 0x48, 0x20, 0xcb, 0x29, 0x50, 0x0b, 0xa0, 0x03, 0xa7, 0x1e,
+ 0x2e, 0xf4, 0x42, 0x41, 0xe7, 0x96, 0xa0, 0x78, 0xd5, 0x65, 0x89, 0x0a, 0x07, 0xfa, 0x35, 0xa0,
+ 0x78, 0x1f, 0x3a, 0x60, 0x9f, 0xe6, 0xf2, 0xde, 0x3c, 0x9a, 0x1e, 0xca, 0xf8, 0x1e, 0xfd, 0x87,
+ 0xfe, 0x2d, 0x08, 0x94, 0x72, 0xf0, 0xce, 0x26, 0xa0, 0xbe, 0x65, 0x38, 0x71, 0x93, 0x94, 0x6f,
+ 0x51, 0x56, 0x10, 0x28, 0x56, 0x50, 0x96, 0xb5, 0xff, 0x94, 0xae, 0x74, 0xa4, 0x56, 0x95, 0x05,
+ 0xe4, 0xd9, 0x09, 0xae, 0xb3, 0x50, 0x3d, 0xac, 0xa6, 0xca, 0xa7, 0xa6, 0x7a, 0x18, 0x4a, 0xbd,
+ 0x40, 0x45, 0x0e, 0x6f, 0x5d, 0xfa, 0xed, 0x2a, 0xb5, 0xa2, 0xdf, 0x48, 0x9c, 0x8c, 0x49, 0x7d,
+ 0x06, 0x01, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
+};
+
+const BITMAP_OPAQUE duplicate_text_xpm[1] = {{ png, sizeof( png ), "duplicate_text_xpm" }};
+
+//EOF
diff --git a/bitmaps_png/sources/duplicate_line.svg b/bitmaps_png/sources/duplicate_line.svg
new file mode 100644
index 0000000..008fbda
--- /dev/null
+++ b/bitmaps_png/sources/duplicate_line.svg
@@ -0,0 +1,112 @@
+<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="48"
+ width="48"
+ version="1.1"
+ id="svg18859"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="duplicate_line.svg">
+ <metadata
+ id="metadata18886">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </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="1598"
+ inkscape:window-height="822"
+ id="namedview18884"
+ showgrid="true"
+ inkscape:object-nodes="true"
+ inkscape:zoom="1"
+ inkscape:cx="35.46823"
+ inkscape:cy="23.822388"
+ inkscape:window-x="0"
+ inkscape:window-y="28"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg18859">
+ <inkscape:grid
+ type="xygrid"
+ id="grid18921" />
+ </sodipodi:namedview>
+ <defs
+ id="defs18861">
+ <filter
+ id="a"
+ height="1.7323"
+ width="1.0709"
+ color-interpolation-filters="sRGB"
+ y="-.36615"
+ x="-.035434">
+ <feGaussianBlur
+ stdDeviation="0.22884615"
+ id="feGaussianBlur18864" />
+ </filter>
+ </defs>
+ <g
+ transform="matrix(0.92443,0,0,1,69.35,-27.982)"
+ id="g18878">
+ <rect
+ height="4.0000014"
+ width="45.433399"
+ y="35.981998"
+ x="-71.773956"
+ id="rect18882"
+ style="fill:#009b00"
+ ry="0" />
+ </g>
+ <g
+ id="g18103"
+ transform="matrix(-0.84365944,0.53687872,0.53687872,0.84365944,42.368689,-4.5433546)">
+ <path
+ id="path8556"
+ style="fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:0.85800409"
+ d="M 36.506057,17.56816 C 36.910935,7.6470615 34.020827,5.0938325 25.186951,5.7985708 c 8.692315,2.0573826 8.141898,4.4370302 7.441561,11.3327012 l -3.252691,-0.40484 4.396086,7.027225 5.890838,-5.831425 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ d="M 36.506057,17.56816 C 36.910935,7.6470615 34.020827,5.0938325 25.186951,5.7985708 c 8.692315,2.0573826 8.141898,4.4370302 7.441561,11.3327012 l -3.252691,-0.40484 4.396086,7.027225 5.890838,-5.831425 z"
+ style="fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:0.85800409"
+ id="path17320" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.5;color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+ d="m 27.986752,6.1256701 c 0,0 1.569237,0.4810082 2.872625,1.2805797 1.772651,1.0874442 2.447581,2.7046222 2.54877,4.6726602 0.09267,1.802444 -0.267776,3.805528 -0.439395,5.51484 l -2.750001,-0.343751 3.625,5.8125 4.90625,-4.843749 -2.71875,-0.25 c 0.0768,-0.629345 0.276965,-2.601414 -0.03125,-5 C 35.818999,11.560155 35.483522,10.084066 34.71875,8.9062498 33.340936,6.784295 31.126944,6.1998687 27.986752,6.1256701 z m 5.731999,3.1243297 c 0.04746,0.069968 0.111279,0.1141538 0.156251,0.1875 0.62017,1.0114792 0.954912,2.3326022 1.125,3.6562502 0.340173,2.647296 0,5.21875 0,5.21875 l -0.09375,0.53125 1.625001,0.156251 -2.5,2.5 -1.843751,-2.999999 1.687501,0.218753 0.03125,-0.53125 c 0.140664,-1.715785 0.578869,-3.952065 0.46875,-6.09375 -0.05059,-0.983973 -0.271304,-1.952817 -0.656251,-2.8437552 z"
+ id="path17324"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscccccssccsscccccccsc" />
+ </g>
+ <g
+ id="g18915"
+ transform="matrix(0.92443,0,0,1,69.865087,-0.5470009)">
+ <rect
+ id="rect18919"
+ x="-72.331154"
+ y="35.547001"
+ width="46.515152"
+ height="4"
+ style="fill:#009b00" />
+ </g>
+</svg>
diff --git a/bitmaps_png/sources/duplicate_pad.svg b/bitmaps_png/sources/duplicate_pad.svg
new file mode 100644
index 0000000..c486f54
--- /dev/null
+++ b/bitmaps_png/sources/duplicate_pad.svg
@@ -0,0 +1,216 @@
+<?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"
+ id="svg8431"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="move_pad.svg">
+ <metadata
+ id="metadata8454">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </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="1598"
+ inkscape:window-height="822"
+ id="namedview8452"
+ showgrid="true"
+ inkscape:zoom="11.313708"
+ inkscape:cx="31.011361"
+ inkscape:cy="21.904167"
+ inkscape:window-x="0"
+ inkscape:window-y="28"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg8431">
+ <inkscape:grid
+ type="xygrid"
+ id="grid8552" />
+ </sodipodi:namedview>
+ <defs
+ id="defs8433">
+ <filter
+ id="a"
+ height="1.2769"
+ width="1.2769"
+ color-interpolation-filters="sRGB"
+ y="-.13847"
+ x="-.13847">
+ <feGaussianBlur
+ stdDeviation="0.11539203"
+ id="feGaussianBlur8436" />
+ </filter>
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="42.5"
+ x2="31.5"
+ y1="35.75"
+ x1="33"
+ id="linearGradient2246"
+ xlink:href="#linearGradient2240"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientUnits="userSpaceOnUse"
+ y2="42.5"
+ x2="31.5"
+ y1="35.75"
+ x1="33"
+ id="linearGradient2238"
+ xlink:href="#linearGradient2232"
+ inkscape:collect="always" />
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-0.01290127,1.685197,1.713082,0.01311475,-1.041499,-10.11571)"
+ r="19.0625"
+ fy="11.132236"
+ fx="16.563837"
+ cy="11.132236"
+ cx="16.563837"
+ id="radialGradient4997"
+ xlink:href="#linearGradient4991"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="12.583769"
+ x2="12.624337"
+ y1="11.39502"
+ x1="17.060806"
+ gradientTransform="matrix(0,-1.171926,1.171926,0,1.782801,54.10111)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient1764"
+ xlink:href="#linearGradient2187"
+ inkscape:collect="always" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient2187">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop2189" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop2191" />
+ </linearGradient>
+ <radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.536723,0,16.87306)"
+ r="15.644737"
+ fy="36.421127"
+ fx="24.837126"
+ cy="36.421127"
+ cx="24.837126"
+ id="radialGradient8668"
+ xlink:href="#linearGradient8662"
+ inkscape:collect="always" />
+ <linearGradient
+ id="linearGradient8662"
+ inkscape:collect="always">
+ <stop
+ id="stop8664"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop8666"
+ offset="1"
+ style="stop-color:#000000;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4991"
+ inkscape:collect="always">
+ <stop
+ id="stop4993"
+ offset="0"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ <stop
+ id="stop4995"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2232"
+ inkscape:collect="always">
+ <stop
+ id="stop2234"
+ offset="0"
+ style="stop-color:#788600;stop-opacity:1;" />
+ <stop
+ id="stop2236"
+ offset="1"
+ style="stop-color:#788600;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2240"
+ inkscape:collect="always">
+ <stop
+ id="stop2242"
+ offset="0"
+ style="stop-color:#99b00b;stop-opacity:1;" />
+ <stop
+ id="stop2244"
+ offset="1"
+ style="stop-color:#99b00b;stop-opacity:0;" />
+ </linearGradient>
+ <inkscape:perspective
+ id="perspective31"
+ inkscape:persp3d-origin="24 : 16 : 1"
+ inkscape:vp_z="48 : 24 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 24 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <path
+ inkscape:connector-curvature="0"
+ id="path3763"
+ d="m 15,2.03125 c -4.95522,0 -8.96875,4.0135285 -8.96875,8.96875 0,4.955221 4.01353,8.96875 8.96875,8.96875 4.955222,0 8.96875,-4.013529 8.96875,-8.96875 C 23.96875,6.0447785 19.955222,2.03125 15,2.03125 z M 15,7 c 2.209139,0 4,1.7908611 4,4 0,2.209139 -1.790861,4 -4,4 -2.209139,0 -4,-1.790861 -4,-4 0,-2.2091389 1.790861,-4 4,-4 z"
+ style="fill:#008000;fill-opacity:0.69803922;stroke:#008000;stroke-width:2.05555582;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#008000;fill-opacity:0.69803922;stroke:#008000;stroke-width:2.05555582;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 32.996528,27.034722 c -4.95522,0 -8.96875,4.013529 -8.96875,8.96875 0,4.955221 4.01353,8.968749 8.96875,8.968749 4.955223,0 8.968751,-4.013528 8.968751,-8.968749 0,-4.955221 -4.013528,-8.96875 -8.968751,-8.96875 z m 0,4.96875 c 2.209139,0 4.000001,1.790861 4.000001,4 0,2.209139 -1.790862,4 -4.000001,4 -2.209139,0 -4,-1.790861 -4,-4 0,-2.209139 1.790861,-4 4,-4 z"
+ id="path9686" />
+ <g
+ id="g18103"
+ transform="matrix(0.99803029,-0.06273388,0.06273388,0.99803029,-1.1234672,3.8010369)">
+ <path
+ id="path8556"
+ style="fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:0.85800409"
+ d="M 36.506057,17.56816 C 36.910935,7.6470615 34.020827,5.0938325 25.186951,5.7985708 c 8.692315,2.0573826 8.141898,4.4370302 7.441561,11.3327012 l -3.252691,-0.40484 4.396086,7.027225 5.890838,-5.831425 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ d="M 36.506057,17.56816 C 36.910935,7.6470615 34.020827,5.0938325 25.186951,5.7985708 c 8.692315,2.0573826 8.141898,4.4370302 7.441561,11.3327012 l -3.252691,-0.40484 4.396086,7.027225 5.890838,-5.831425 z"
+ style="fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:0.85800409"
+ id="path17320" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.5;color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+ d="m 27.986752,6.1256701 c 0,0 1.569237,0.4810082 2.872625,1.2805797 1.772651,1.0874442 2.447581,2.7046222 2.54877,4.6726602 0.09267,1.802444 -0.267776,3.805528 -0.439395,5.51484 l -2.750001,-0.343751 3.625,5.8125 4.90625,-4.843749 -2.71875,-0.25 c 0.0768,-0.629345 0.276965,-2.601414 -0.03125,-5 C 35.818999,11.560155 35.483522,10.084066 34.71875,8.9062498 33.340936,6.784295 31.126944,6.1998687 27.986752,6.1256701 z m 5.731999,3.1243297 c 0.04746,0.069968 0.111279,0.1141538 0.156251,0.1875 0.62017,1.0114792 0.954912,2.3326022 1.125,3.6562502 0.340173,2.647296 0,5.21875 0,5.21875 l -0.09375,0.53125 1.625001,0.156251 -2.5,2.5 -1.843751,-2.999999 1.687501,0.218753 0.03125,-0.53125 c 0.140664,-1.715785 0.578869,-3.952065 0.46875,-6.09375 -0.05059,-0.983973 -0.271304,-1.952817 -0.656251,-2.8437552 z"
+ id="path17324"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscccccssccsscccccccsc" />
+ </g>
+</svg>
diff --git a/bitmaps_png/sources/duplicate_text.svg b/bitmaps_png/sources/duplicate_text.svg
new file mode 100644
index 0000000..66686fe
--- /dev/null
+++ b/bitmaps_png/sources/duplicate_text.svg
@@ -0,0 +1,112 @@
+<?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:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="48"
+ width="48"
+ version="1.1"
+ id="svg18970"
+ inkscape:version="0.48.4 r9939"
+ sodipodi:docname="move_text.svg">
+ <metadata
+ id="metadata18987">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </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="1598"
+ inkscape:window-height="822"
+ id="namedview18985"
+ showgrid="false"
+ inkscape:zoom="9.8333333"
+ inkscape:cx="34.662396"
+ inkscape:cy="28.541287"
+ inkscape:window-x="0"
+ inkscape:window-y="28"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg18970" />
+ <defs
+ id="defs18972">
+ <filter
+ id="a"
+ color-interpolation-filters="sRGB">
+ <feGaussianBlur
+ stdDeviation="1.1026007"
+ id="feGaussianBlur18975" />
+ </filter>
+ </defs>
+ <g
+ id="g19003"
+ transform="matrix(1.1098933,0,0,1.075965,-4.1387372,-2.1944157)"
+ style="fill-rule:evenodd">
+ <path
+ id="path19005"
+ transform="matrix(0.47197,0,0,0.5148,61.766,17.137)"
+ d="m -77.169,14.171 h 42.073 v 10.622 h -3.0052 l -4.5079,-5.3112 h -7.5131 v 27.884 l 6.0105,3.9834 v 2.6556 h -24.042 v -2.6556 l 6.0105,-3.9834 v -27.884 h -7.5131 l -4.5079,5.3112 h -3.0052 V 14.171 z"
+ inkscape:connector-curvature="0"
+ style="opacity:0.57422001;filter:url(#a)" />
+ <path
+ id="path19007"
+ d="m 23.926,23.066 h 19.858 v 5.4684 h -1.418 l -2.128,-2.734 h -3.546 v 14.355 l 2.8368,2.0506 v 1.3671 h -11.347 v -1.367 l 2.8368,-2.0506 v -14.355 h -3.546 l -2.128,2.734 h -1.418 v -5.468 z"
+ inkscape:connector-curvature="0"
+ style="fill:#00009b" />
+ </g>
+ <g
+ style="fill-rule:evenodd"
+ transform="matrix(1.1098933,0,0,1.075965,-25.392974,-23.041873)"
+ id="g19009">
+ <path
+ style="opacity:0.57422001;filter:url(#a)"
+ inkscape:connector-curvature="0"
+ d="m -77.169,14.171 h 42.073 v 10.622 h -3.0052 l -4.5079,-5.3112 h -7.5131 v 27.884 l 6.0105,3.9834 v 2.6556 h -24.042 v -2.6556 l 6.0105,-3.9834 v -27.884 h -7.5131 l -4.5079,5.3112 h -3.0052 V 14.171 z"
+ transform="matrix(0.47197,0,0,0.5148,61.766,17.137)"
+ id="path19011" />
+ <path
+ style="fill:#00009b"
+ inkscape:connector-curvature="0"
+ d="m 23.926,23.066 h 19.858 v 5.4684 h -1.418 l -2.128,-2.734 h -3.546 v 14.355 l 2.8368,2.0506 v 1.3671 h -11.347 v -1.367 l 2.8368,-2.0506 v -14.355 h -3.546 l -2.128,2.734 h -1.418 v -5.468 z"
+ id="path19013" />
+ </g>
+ <g
+ id="g18103"
+ transform="matrix(0.92021476,-0.39141384,0.39141384,0.92021476,-2.5098229,12.530381)">
+ <path
+ id="path8556"
+ style="fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:0.85800409"
+ d="M 36.506057,17.56816 C 36.910935,7.6470615 34.020827,5.0938325 25.186951,5.7985708 c 8.692315,2.0573826 8.141898,4.4370302 7.441561,11.3327012 l -3.252691,-0.40484 4.396086,7.027225 5.890838,-5.831425 z"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ d="M 36.506057,17.56816 C 36.910935,7.6470615 34.020827,5.0938325 25.186951,5.7985708 c 8.692315,2.0573826 8.141898,4.4370302 7.441561,11.3327012 l -3.252691,-0.40484 4.396086,7.027225 5.890838,-5.831425 z"
+ style="fill:#ff0000;fill-opacity:1;stroke:#a40000;stroke-width:0.85800409"
+ id="path17320" />
+ <path
+ style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.5;color:#000000;fill:#eeeeec;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+ d="m 27.986752,6.1256701 c 0,0 1.569237,0.4810082 2.872625,1.2805797 1.772651,1.0874442 2.447581,2.7046222 2.54877,4.6726602 0.09267,1.802444 -0.267776,3.805528 -0.439395,5.51484 l -2.750001,-0.343751 3.625,5.8125 4.90625,-4.843749 -2.71875,-0.25 c 0.0768,-0.629345 0.276965,-2.601414 -0.03125,-5 C 35.818999,11.560155 35.483522,10.084066 34.71875,8.9062498 33.340936,6.784295 31.126944,6.1998687 27.986752,6.1256701 z m 5.731999,3.1243297 c 0.04746,0.069968 0.111279,0.1141538 0.156251,0.1875 0.62017,1.0114792 0.954912,2.3326022 1.125,3.6562502 0.340173,2.647296 0,5.21875 0,5.21875 l -0.09375,0.53125 1.625001,0.156251 -2.5,2.5 -1.843751,-2.999999 1.687501,0.218753 0.03125,-0.53125 c 0.140664,-1.715785 0.578869,-3.952065 0.46875,-6.09375 -0.05059,-0.983973 -0.271304,-1.952817 -0.656251,-2.8437552 z"
+ id="path17324"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="csscccccssccsscccccccsc" />
+ </g>
+</svg>
diff --git a/common/block_commande.cpp b/common/block_commande.cpp
index 990fa6c..73e5223 100644
--- a/common/block_commande.cpp
+++ b/common/block_commande.cpp
@@ -64,6 +64,7 @@ void BLOCK_SELECTOR::SetMessageBlock( EDA_DRAW_FRAME* frame )
case BLOCK_MOVE: // Move
case BLOCK_PRESELECT_MOVE: // Move with preselection list
+ case BLOCK_MOVE_EXACT:
msg = _( "Block Move" );
break;
diff --git a/common/tool/tool_manager.cpp b/common/tool/tool_manager.cpp
index f3705d8..d3201ef 100644
--- a/common/tool/tool_manager.cpp
+++ b/common/tool/tool_manager.cpp
@@ -195,7 +195,8 @@ private:
TOOL_MANAGER::TOOL_MANAGER() :
- m_model( NULL ), m_view( NULL ), m_viewControls( NULL ), m_editFrame( NULL )
+ m_model( NULL ), m_view( NULL ), m_viewControls( NULL ), m_editFrame( NULL ),
+ m_undoInhibit( false )
{
m_actionMgr = new ACTION_MANAGER( this );
@@ -710,3 +711,23 @@ bool TOOL_MANAGER::isActive( TOOL_BASE* aTool )
// Just check if the tool is on the active tools stack
return std::find( m_activeTools.begin(), m_activeTools.end(), aTool->GetId() ) != m_activeTools.end();
}
+
+
+void TOOL_MANAGER::IncUndoInhibit()
+{
+ m_undoInhibit++;
+}
+
+
+void TOOL_MANAGER::DecUndoInhibit()
+{
+ m_undoInhibit--;
+
+ wxASSERT_MSG( m_undoInhibit >= 0, wxT( "Undo inhibit count decremented past zero" ) );
+}
+
+
+bool TOOL_MANAGER::IsUndoInhibited() const
+{
+ return m_undoInhibit > 0;
+}
diff --git a/include/bitmaps.h b/include/bitmaps.h
index 8b00575..56cf642 100644
--- a/include/bitmaps.h
+++ b/include/bitmaps.h
@@ -169,6 +169,9 @@ EXTERN_BITMAP( drag_segment_withslope_xpm )
EXTERN_BITMAP( drag_track_segment_xpm )
EXTERN_BITMAP( drc_off_xpm )
EXTERN_BITMAP( drc_xpm )
+EXTERN_BITMAP( duplicate_line_xpm )
+EXTERN_BITMAP( duplicate_pad_xpm )
+EXTERN_BITMAP( duplicate_text_xpm )
EXTERN_BITMAP( edges_sketch_xpm )
EXTERN_BITMAP( edit_comp_footprint_xpm )
EXTERN_BITMAP( edit_component_xpm )
diff --git a/include/block_commande.h b/include/block_commande.h
index cf2c140..8d2b94f 100644
--- a/include/block_commande.h
+++ b/include/block_commande.h
@@ -62,6 +62,7 @@ typedef enum {
BLOCK_ZOOM,
BLOCK_ABORT,
BLOCK_PRESELECT_MOVE,
+ BLOCK_MOVE_EXACT,
BLOCK_SELECT_ITEMS_ONLY,
BLOCK_MIRROR_X,
BLOCK_MIRROR_Y
diff --git a/include/class_board_item.h b/include/class_board_item.h
index 19e3f9a..4ce3ade 100644
--- a/include/class_board_item.h
+++ b/include/class_board_item.h
@@ -89,6 +89,16 @@ public:
virtual const wxPoint& GetPosition() const = 0;
+ /**
+ * Function GetCentre()
+ *
+ * @return centre point of the item
+ *
+ * This defaults to the same point as returned by GetPosition(), unless
+ * overridden
+ */
+ virtual const wxPoint GetCenter() const { return GetPosition(); }
+
virtual void SetPosition( const wxPoint& aPos ) = 0;
/**
diff --git a/include/id.h b/include/id.h
index d37c814..32ea99c 100644
--- a/include/id.h
+++ b/include/id.h
@@ -158,6 +158,7 @@ enum main_id
ID_POPUP_CANCEL_CURRENT_COMMAND,
ID_POPUP_CLOSE_CURRENT_TOOL,
ID_POPUP_MOVE_BLOCK,
+ ID_POPUP_MOVE_BLOCK_EXACT,
ID_POPUP_DRAG_BLOCK,
ID_POPUP_COPY_BLOCK,
ID_POPUP_ROTATE_BLOCK,
diff --git a/include/tool/tool_manager.h b/include/tool/tool_manager.h
index 3805fe8..2323919 100644
--- a/include/tool/tool_manager.h
+++ b/include/tool/tool_manager.h
@@ -301,6 +301,29 @@ public:
return actionList;
}
+ /**
+ * Increments the undo inhibit counter. This will indicate that tools
+ * should not create an undo point, as another tool is doing it already,
+ * and considers that its operation is atomic, even if it calls another one
+ * (for example a duplicate calls a move)
+ */
+ void IncUndoInhibit();
+
+ /**
+ * Decrements the inhibit counter. An assert is raised if the counter drops
+ * below zero
+ */
+ void DecUndoInhibit();
+
+ /**
+ * Report if the tool manager has been told at least once that undo
+ * points should not be created. This can be ignored if the undo point
+ * is still required.
+ *
+ * @return true if undo are inhibited
+ */
+ bool IsUndoInhibited() const;
+
private:
struct TOOL_STATE;
typedef std::pair<TOOL_EVENT_LIST, TOOL_STATE_FUNC> TRANSITION;
@@ -428,6 +451,9 @@ private:
/// Flag saying if the currently processed event should be passed to other tools.
bool m_passEvent;
+
+ /// Counter of undo inhibitions. When zero, undo is not inhibited
+ int m_undoInhibit;
};
#endif
diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt
index 494b373..6638468 100644
--- a/pcbnew/CMakeLists.txt
+++ b/pcbnew/CMakeLists.txt
@@ -102,6 +102,8 @@ set( PCBNEW_DIALOGS
dialogs/dialog_pcb_text_properties_base.cpp
dialogs/dialog_pns_settings.cpp
dialogs/dialog_pns_settings_base.cpp
+ dialogs/dialog_move_exact.cpp
+ dialogs/dialog_move_exact_base.cpp
dialogs/dialog_non_copper_zones_properties.cpp
dialogs/dialog_non_copper_zones_properties_base.cpp
dialogs/dialog_pad_properties.cpp
diff --git a/pcbnew/block_module_editor.cpp b/pcbnew/block_module_editor.cpp
index 2898af9..d510ed7 100644
--- a/pcbnew/block_module_editor.cpp
+++ b/pcbnew/block_module_editor.cpp
@@ -53,14 +53,19 @@
#include <class_dimension.h>
#include <class_edge_mod.h>
+#include "dialogs/dialog_move_exact.h"
+
#define BLOCK_COLOR BROWN
// Functions defined here, but used also in other files
-// These 2 functions are used in modedit to rotate or mirror the whole footprint
+// These 3 functions are used in modedit to rotate or mirror the whole footprint
// so they are called with force_all = true
void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
+void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
+ const wxPoint& translation, double rotation,
+ bool force_all = false );
// Local functions:
static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
@@ -166,6 +171,29 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
break;
+ case BLOCK_MOVE_EXACT:
+ {
+ itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
+
+ if ( itemsCount )
+ {
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+
+ if( ret == DIALOG_MOVE_EXACT::MOVE_OK )
+ {
+ SaveCopyInUndoList( currentModule, UR_MODEDIT );
+ const wxPoint blockCentre = GetScreen()->m_BlockLocate.Centre();
+ MoveMarkedItemsExactly( currentModule, blockCentre, translation, rotation );
+ }
+ }
+ }
+ break;
+
case BLOCK_PRESELECT_MOVE: // Move with preselection list
nextcmd = true;
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
@@ -706,6 +734,77 @@ void ClearMarkItems( MODULE* module )
}
+void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre, const wxPoint& translation,
+ double rotation, bool force_all )
+{
+ if( module == NULL )
+ return;
+
+ if( module->Reference().IsSelected() || force_all )
+ {
+ module->Reference().RotateTransformWithModule( centre, rotation );
+ module->Reference().MoveTransformWithModule( translation );
+ }
+
+ if( module->Value().IsSelected() || force_all )
+ {
+ module->Value().RotateTransformWithModule( centre, rotation );
+ module->Value().MoveTransformWithModule( translation );
+ }
+
+ D_PAD* pad = module->Pads();
+
+ for( ; pad != NULL; pad = pad->Next() )
+ {
+ if( !pad->IsSelected() && !force_all )
+ continue;
+
+ // rotate about centre point,
+ wxPoint newPos = pad->GetPosition();
+ RotatePoint( &newPos, centre, rotation );
+
+ // shift and update
+ newPos += translation;
+ pad->SetPosition( newPos );
+ pad->SetPos0( newPos );
+
+ // finally apply rotation to the pad itself
+ pad->Rotate( newPos, rotation );
+ }
+
+ EDA_ITEM* item = module->GraphicalItems();
+
+ for( ; item != NULL; item = item->Next() )
+ {
+ if( !item->IsSelected() && !force_all )
+ continue;
+
+ switch( item->Type() )
+ {
+ case PCB_MODULE_TEXT_T:
+ {
+ TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
+
+ text->RotateTransformWithModule( centre, rotation );
+ text->MoveTransformWithModule( translation );
+ break;
+ }
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* em = static_cast<EDGE_MODULE*>( item );
+ em->Rotate( centre, rotation );
+ em->Move( translation );
+ break;
+ }
+ default:
+ ;
+ }
+ }
+
+ ClearMarkItems( module );
+}
+
+
/* Mark items inside rect.
* Items are inside rect when an end point is inside rect
*/
diff --git a/pcbnew/class_drawsegment.cpp b/pcbnew/class_drawsegment.cpp
index ed043ad..1fa1e5d 100644
--- a/pcbnew/class_drawsegment.cpp
+++ b/pcbnew/class_drawsegment.cpp
@@ -94,10 +94,43 @@ void DRAWSEGMENT::Copy( DRAWSEGMENT* source )
void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
{
- RotatePoint( &m_Start, aRotCentre, aAngle );
- RotatePoint( &m_End, aRotCentre, aAngle );
-}
+ switch ( m_Shape )
+ {
+ case S_ARC:
+ case S_SEGMENT:
+ case S_CIRCLE:
+ // these can all be done by just rotating the start and end points
+ RotatePoint( &m_Start, aRotCentre, aAngle);
+ RotatePoint( &m_End, aRotCentre, aAngle);
+ break;
+
+ case S_POLYGON:
+
+ for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
+ {
+ RotatePoint( &m_PolyPoints[ii], aRotCentre, aAngle);
+ }
+ break;
+
+ case S_CURVE:
+
+ RotatePoint( &m_Start, aRotCentre, aAngle);
+ RotatePoint( &m_End, aRotCentre, aAngle);
+ for (unsigned int ii = 0; ii < m_BezierPoints.size(); ii++ )
+ {
+ RotatePoint( &m_BezierPoints[ii], aRotCentre, aAngle);
+ }
+ break;
+
+ case S_RECT:
+ default:
+ // un-handled edge transform
+ wxASSERT_MSG( false, wxT( "DRAWSEGMENT::Rotate not implemented for "
+ + ShowShape( m_Shape ) ) );
+ break;
+ }
+};
void DRAWSEGMENT::Flip( const wxPoint& aCentre )
{
@@ -112,6 +145,37 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre )
SetLayer( FlipLayer( GetLayer() ) );
}
+const wxPoint DRAWSEGMENT::GetCenter() const
+{
+ wxPoint c;
+
+ switch( m_Shape )
+ {
+ case S_ARC:
+ case S_CIRCLE:
+ c = m_Start;
+ break;
+
+ case S_SEGMENT:
+ // midpoint of the line
+ c = ( GetStart() + GetEnd() ) / 2;
+ break;
+
+ case S_POLYGON:
+ case S_RECT:
+ case S_CURVE:
+ c = GetBoundingBox().Centre();
+ break;
+
+ default:
+ wxASSERT_MSG( false, "DRAWSEGMENT::GetCentre not implemented for shape"
+ + ShowShape( GetShape() ) );
+ break;
+ }
+
+ return c;
+}
+
const wxPoint DRAWSEGMENT::GetArcEnd() const
{
wxPoint endPoint; // start of arc
diff --git a/pcbnew/class_drawsegment.h b/pcbnew/class_drawsegment.h
index 8e1e220..bcd2f90 100644
--- a/pcbnew/class_drawsegment.h
+++ b/pcbnew/class_drawsegment.h
@@ -117,7 +117,7 @@ public:
// m_Start, m_End, and m_Angle.
// No Set...() function for these attributes.
- const wxPoint& GetCenter() const { return m_Start; }
+ const wxPoint GetCenter() const; //override
const wxPoint& GetArcStart() const { return m_End; }
const wxPoint GetArcEnd() const;
diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp
index 523b019..d0982bf 100644
--- a/pcbnew/class_module.cpp
+++ b/pcbnew/class_module.cpp
@@ -1112,3 +1112,97 @@ void MODULE::SetOrientation( double newangle )
CalculateBoundingBox();
}
+BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* item )
+{
+ BOARD_ITEM* new_item = NULL;
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ {
+ D_PAD* new_pad = new D_PAD( *static_cast<const D_PAD*>( item ) );
+
+ // Take the next available pad number
+ new_pad->IncrementPadName( true, true );
+
+ Pads().PushBack( new_pad );
+ new_item = new_pad;
+ break;
+ }
+ case PCB_MODULE_TEXT_T:
+ {
+ const TEXTE_MODULE* old_text = static_cast<const TEXTE_MODULE*>( item );
+
+ // do not duplicate value or reference fields
+ // (there can only be one of each)
+ if( old_text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS )
+ {
+ TEXTE_MODULE* new_text = new TEXTE_MODULE( *old_text );
+
+ GraphicalItems().PushBack( new_text );
+ new_item = new_text;
+ }
+ break;
+ }
+ case PCB_MODULE_EDGE_T:
+ {
+ EDGE_MODULE* new_edge = new EDGE_MODULE(
+ *static_cast<const EDGE_MODULE*>(item) );
+
+ GraphicalItems().PushBack( new_edge );
+ new_item = new_edge;
+ break;
+ }
+ default:
+ // Un-handled item for duplication
+ wxASSERT_MSG( false, "Duplication not supported for items of class "
+ + item->GetClass() );
+ break;
+ }
+
+ return new_item;
+}
+
+wxString MODULE::GetNextPadName( bool aFillSequenceGaps ) const
+{
+ std::set<int> usedNumbers;
+
+ // Create a set of used pad numbers
+ for( D_PAD* pad = Pads(); pad; pad = pad->Next() )
+ {
+ wxString padName = pad->GetPadName();
+ int padNumber = 0;
+ int base = 1;
+
+ // Trim and extract the trailing numeric part
+ while( padName.Len() && padName.Last() >= '0' && padName.Last() <= '9' )
+ {
+ padNumber += ( padName.Last() - '0' ) * base;
+ padName.RemoveLast();
+ base *= 10;
+ }
+
+ usedNumbers.insert( padNumber );
+ }
+
+ // By default go to the end of the sequence
+ int candidate = *usedNumbers.end();
+
+ // Filling in gaps in pad numbering
+ if( aFillSequenceGaps )
+ {
+ // start at the beginning
+ candidate = *usedNumbers.begin();
+
+ for( std::set<int>::iterator it = usedNumbers.begin(),
+ itEnd = usedNumbers.end(); it != itEnd; ++it )
+ {
+ if( *it - candidate > 1 )
+ break;
+
+ candidate = *it;
+ }
+ }
+
+ return wxString::Format( wxT( "%i" ), ++candidate );
+}
diff --git a/pcbnew/class_module.h b/pcbnew/class_module.h
index a34e610..25df78b 100644
--- a/pcbnew/class_module.h
+++ b/pcbnew/class_module.h
@@ -441,6 +441,16 @@ public:
*/
unsigned GetPadCount( INCLUDE_NPTH_T aIncludeNPTH = INCLUDE_NPTH ) const;
+ /**
+ * Function GetNextPadName
+ * returns the next available pad name in the module
+ *
+ * @param aFillSequenceGaps true if the numbering should "fill in" gaps in
+ * the sequence, else return the highest value + 1
+ * @return the next available pad name
+ */
+ wxString GetNextPadName( bool aFillSequenceGaps ) const;
+
double GetArea() const { return m_Surface; }
time_t GetLink() const { return m_Link; }
@@ -452,6 +462,8 @@ public:
int GetPlacementCost90() const { return m_CntRot90; }
void SetPlacementCost90( int aCost ) { m_CntRot90 = aCost; }
+ BOARD_ITEM* DuplicateAndAddItem( const BOARD_ITEM* item );
+
/**
* Function Add3DModel
* adds \a a3DModel definition to the end of the 3D model list.
diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp
index 1250007..07c2470 100644
--- a/pcbnew/class_pad.cpp
+++ b/pcbnew/class_pad.cpp
@@ -408,6 +408,16 @@ void D_PAD::SetPadName( const wxString& name )
}
+void D_PAD::IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps )
+{
+ bool skip = aSkipUnconnectable
+ && ( GetAttribute() == PAD_HOLE_NOT_PLATED );
+
+ if( !skip )
+ SetPadName(GetParent()->GetNextPadName( aFillSequenceGaps ));
+}
+
+
void D_PAD::Copy( D_PAD* source )
{
if( source == NULL )
diff --git a/pcbnew/class_pad.h b/pcbnew/class_pad.h
index 7fc41f8..65472cb 100644
--- a/pcbnew/class_pad.h
+++ b/pcbnew/class_pad.h
@@ -103,6 +103,16 @@ public:
void SetPadName( const wxString& name ); // Change pad name
const wxString GetPadName() const;
+ /**
+ * Function IncrementPadName
+ *
+ * Increments the pad name to the next available name in the module.
+ *
+ * @param aSkipUnconnectable skips any pads that are not connectable (for
+ * example NPTH)
+ */
+ void IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps );
+
bool PadNameEqual( const D_PAD* other ) const
{
return m_NumPadName == other->m_NumPadName; // hide tricks behind sensible API
diff --git a/pcbnew/dialogs/dialog_move_exact.cpp b/pcbnew/dialogs/dialog_move_exact.cpp
new file mode 100644
index 0000000..10b70f9
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact.cpp
@@ -0,0 +1,188 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 John Beard, john.j.beard@gmail.com
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.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 <wxPcbStruct.h>
+#include <base_units.h>
+
+#include <module_editor_frame.h>
+
+#include "dialog_move_exact.h"
+
+// initialise statics
+DIALOG_MOVE_EXACT::MOVE_EXACT_OPTIONS DIALOG_MOVE_EXACT::m_options;
+
+DIALOG_MOVE_EXACT::DIALOG_MOVE_EXACT( PCB_BASE_FRAME* aParent,
+ wxPoint& translation, double& rotation ):
+ DIALOG_MOVE_EXACT_BASE( aParent ),
+ m_translation( translation ),
+ m_rotation( rotation )
+{
+ // set the unit labels
+ m_xUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ // rotation is always degrees
+ m_rotUnit->SetLabelText( _( "deg" ) );
+
+ // tabbing goes through the entries in sequence
+ m_yEntry->MoveAfterInTabOrder( m_xEntry );
+ m_rotEntry->MoveAfterInTabOrder( m_yEntry );
+
+ // and set up the entries according to the saved options
+ m_polarCoords->SetValue( m_options.polarCoords );
+ m_xEntry->SetValue( wxString::FromDouble( m_options.entry1 ) );
+ m_yEntry->SetValue( wxString::FromDouble( m_options.entry2 ) );
+ m_rotEntry->SetValue( wxString::FromDouble( m_options.entryRotation ) );
+}
+
+DIALOG_MOVE_EXACT::~DIALOG_MOVE_EXACT()
+{
+}
+
+/*!
+ * Convert a given Cartesian point into a polar representation.
+ *
+ * Linear units are not considered, the answer is in the same units as given
+ * Angle is returned in degrees
+ */
+void DIALOG_MOVE_EXACT::ToPolarDeg( double x, double y, double& r, double& q )
+{
+ // convert to polar coordinates
+ r = hypot ( x, y );
+
+ q = ( r != 0) ? RAD2DEG( atan2( y, x ) ) : 0;
+}
+
+bool DIALOG_MOVE_EXACT::GetTranslationInIU ( wxPoint& val, bool polar )
+{
+ // entries in user units
+ double ent1, ent2;
+ bool ok = m_xEntry->GetValue().ToDouble( &ent1 );
+ ok = ok && m_yEntry->GetValue().ToDouble( &ent2 );
+
+ if( !ok )
+ return false;
+
+ if( polar )
+ {
+ val.x = From_User_Unit( g_UserUnit, ent1 * cos( DEG2RAD( ent2 ) ) );
+ val.y = From_User_Unit( g_UserUnit, ent1 * sin( DEG2RAD( ent2 ) ) );
+ }
+ else
+ {
+ // direct read
+ val.x = From_User_Unit( g_UserUnit, ent1 );
+ val.y = From_User_Unit( g_UserUnit, ent2 );
+ }
+
+ return true;
+}
+
+void DIALOG_MOVE_EXACT::OnPolarChanged( wxCommandEvent& event )
+{
+ bool newPolar = m_polarCoords->IsChecked();
+ wxPoint val;
+
+ // get the value as previously stored
+ bool ok = GetTranslationInIU( val, !newPolar );
+
+ // invalid entries - bail out
+ if( !ok )
+ return;
+
+ if( m_polarCoords->IsChecked() )
+ {
+ // convert to polar coordinates
+ double r, q;
+ ToPolarDeg( val.x, val.y, r, q);
+
+ PutValueInLocalUnits( *m_xEntry, round( r / 10.0) * 10 );
+ m_xLabel->SetLabelText( wxT( "r:" ) );
+
+ m_yEntry->SetValue( wxString::FromDouble( q ) );
+ m_yLabel->SetLabelText( wxT( "\u03b8:" ) ); // theta
+
+ m_yUnit->SetLabelText( _( "deg" ) );
+ }
+ else
+ {
+ // vector is already in Cartesian, so just render out
+
+ // note - round off the last decimal place (10nm) to prevent
+ // rounding causing errors when round-tripping
+ PutValueInLocalUnits( *m_xEntry, round( val.x / 10.0) * 10 );
+ m_xLabel->SetLabelText( wxT( "x:" ) );
+
+ PutValueInLocalUnits( *m_yEntry, round( val.y / 10.0) * 10 );
+ m_yLabel->SetLabelText( wxT( "y:" ) );
+
+ m_yUnit->SetLabelText( GetAbbreviatedUnitsLabel( g_UserUnit ) );
+ }
+}
+
+void DIALOG_MOVE_EXACT::OnClear( wxCommandEvent& event )
+{
+ wxObject* obj = event.GetEventObject();
+ wxTextCtrl* entry = NULL;
+
+ if( obj == m_clearX )
+ {
+ entry = m_xEntry;
+ }
+ else if( obj == m_clearY )
+ {
+ entry = m_yEntry;
+ }
+ else if( obj == m_clearRot )
+ {
+ entry = m_rotEntry;
+ }
+
+ if( entry )
+ entry->SetValue( "0" );
+}
+
+void DIALOG_MOVE_EXACT::OnCancelClick( wxCommandEvent& event )
+{
+ EndModal( MOVE_ABORT );
+}
+void DIALOG_MOVE_EXACT::OnOkClick( wxCommandEvent& event )
+{
+ bool ok = m_rotEntry->GetValue().ToDouble( &m_rotation );
+ m_rotation *= 10.0f;
+
+ // for the output, we only deliver a Cartesian vector
+ ok = ok && GetTranslationInIU( m_translation, m_polarCoords->IsChecked() );
+
+ if( ok )
+ {
+ // save the settings
+ m_options.polarCoords = m_polarCoords->GetValue();
+ m_xEntry->GetValue().ToDouble( &m_options.entry1 );
+ m_yEntry->GetValue().ToDouble( &m_options.entry2 );
+ m_rotEntry->GetValue().ToDouble( &m_options.entryRotation );
+
+ EndModal( MOVE_OK );
+ }
+}
+
diff --git a/pcbnew/dialogs/dialog_move_exact.fbp b/pcbnew/dialogs/dialog_move_exact.fbp
new file mode 100644
index 0000000..c04c67e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact.fbp
@@ -0,0 +1,1281 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<wxFormBuilder_Project>
+ <FileVersion major="1" minor="13" />
+ <object class="Project" expanded="1">
+ <property name="class_decoration"></property>
+ <property name="code_generation">C++</property>
+ <property name="disconnect_events">1</property>
+ <property name="disconnect_mode">source_name</property>
+ <property name="disconnect_php_events">0</property>
+ <property name="disconnect_python_events">0</property>
+ <property name="embedded_files_path">res</property>
+ <property name="encoding">UTF-8</property>
+ <property name="event_generation">connect</property>
+ <property name="file">dialog_move_exact_base</property>
+ <property name="first_id">1000</property>
+ <property name="help_provider">none</property>
+ <property name="internationalize">1</property>
+ <property name="name">DIALOG_MOVE_EXACT_BASE</property>
+ <property name="namespace"></property>
+ <property name="path">.</property>
+ <property name="precompiled_header"></property>
+ <property name="relative_path">1</property>
+ <property name="skip_lua_events">1</property>
+ <property name="skip_php_events">1</property>
+ <property name="skip_python_events">1</property>
+ <property name="ui_table">UI</property>
+ <property name="use_enum">0</property>
+ <property name="use_microsoft_bom">0</property>
+ <object class="Dialog" expanded="1">
+ <property name="aui_managed">0</property>
+ <property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
+ <property name="bg"></property>
+ <property name="center"></property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="enabled">1</property>
+ <property name="event_handler">impl_virtual</property>
+ <property name="extra_style"></property>
+ <property name="fg"></property>
+ <property name="font"></property>
+ <property name="hidden">0</property>
+ <property name="id">wxID_ANY</property>
+ <property name="maximum_size"></property>
+ <property name="minimum_size">-1,-1</property>
+ <property name="name">DIALOG_MOVE_EXACT_BASE</property>
+ <property name="pos"></property>
+ <property name="size">-1,-1</property>
+ <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
+ <property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
+ <property name="title">Move item</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnActivate"></event>
+ <event name="OnActivateApp"></event>
+ <event name="OnAuiFindManager"></event>
+ <event name="OnAuiPaneButton"></event>
+ <event name="OnAuiPaneClose"></event>
+ <event name="OnAuiPaneMaximize"></event>
+ <event name="OnAuiPaneRestore"></event>
+ <event name="OnAuiRender"></event>
+ <event name="OnChar"></event>
+ <event name="OnClose">OnClose</event>
+ <event name="OnEnterWindow"></event>
+ <event name="OnEraseBackground"></event>
+ <event name="OnHibernate"></event>
+ <event name="OnIconize"></event>
+ <event name="OnIdle"></event>
+ <event name="OnInitDialog"></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 class="wxBoxSizer" expanded="1">
+ <property name="minimum_size"></property>
+ <property name="name">bMainSizer</property>
+ <property name="orient">wxVERTICAL</property>
+ <property name="permission">none</property>
+ <object class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxCheckBox" expanded="0">
+ <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">Polar coordinates</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_polarCoords</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">OnPolarChanged</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">5</property>
+ <property name="flag">wxEXPAND</property>
+ <property name="proportion">1</property>
+ <object class="wxFlexGridSizer" expanded="1">
+ <property name="cols">4</property>
+ <property name="flexible_direction">wxBOTH</property>
+ <property name="growablecols">1</property>
+ <property name="growablerows"></property>
+ <property name="hgap">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">fgSizer2</property>
+ <property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
+ <property name="permission">none</property>
+ <property name="rows">0</property>
+ <property name="vgap">0</property>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <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="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">x:</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_xLabel</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">-1,-1</property>
+ <property name="style"></property>
+ <property name="subclass"></property>
+ <property name="toolbar_pane">0</property>
+ <property name="tooltip"></property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <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="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="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></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_xEntry</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="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></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="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" 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="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">mm</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_xUnit</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="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapButton" 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="bitmap">Load From Art Provider; wxART_DELETE; wxART_BUTTON</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="disabled"></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="focus"></property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="hover"></property>
+ <property name="id">wxID_CLEAR</property>
+ <property name="label">Clear</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_clearX</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="selected"></property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_AUTODRAW</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="OnButtonClick">OnClear</event>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <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="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">y:</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_yLabel</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="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <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="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="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></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_yEntry</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="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></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="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" 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="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">mm</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_yUnit</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="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapButton" 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="bitmap">Load From Art Provider; wxART_DELETE; wxART_BUTTON</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="disabled"></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="focus"></property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="hover"></property>
+ <property name="id">wxID_CLEAR</property>
+ <property name="label">Clear</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_clearY</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="selected"></property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_AUTODRAW</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="OnButtonClick">OnClear</event>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" expanded="0">
+ <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="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">Rotate:</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_rotLabel</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="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxTextCtrl" expanded="0">
+ <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="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="max_size"></property>
+ <property name="maximize_button">0</property>
+ <property name="maximum_size"></property>
+ <property name="maxlength"></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_rotEntry</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="value">0</property>
+ <property name="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <event name="OnChar"></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="OnText"></event>
+ <event name="OnTextEnter"></event>
+ <event name="OnTextMaxLen"></event>
+ <event name="OnTextURL"></event>
+ <event name="OnUpdateUI"></event>
+ </object>
+ </object>
+ <object class="sizeritem" expanded="1">
+ <property name="border">5</property>
+ <property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxStaticText" 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="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">deg</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_rotUnit</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="window_extra_style"></property>
+ <property name="window_name"></property>
+ <property name="window_style"></property>
+ <property name="wrap">-1</property>
+ <event name="OnChar"></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">5</property>
+ <property name="flag">wxALL</property>
+ <property name="proportion">0</property>
+ <object class="wxBitmapButton" 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="bitmap">Load From Art Provider; wxART_DELETE; wxART_BUTTON</property>
+ <property name="caption"></property>
+ <property name="caption_visible">1</property>
+ <property name="center_pane">0</property>
+ <property name="close_button">1</property>
+ <property name="context_help"></property>
+ <property name="context_menu">1</property>
+ <property name="default">0</property>
+ <property name="default_pane">0</property>
+ <property name="disabled"></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="focus"></property>
+ <property name="font"></property>
+ <property name="gripper">0</property>
+ <property name="hidden">0</property>
+ <property name="hover"></property>
+ <property name="id">wxID_CLEAR</property>
+ <property name="label">Clear</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_clearRot</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="selected"></property>
+ <property name="show">1</property>
+ <property name="size"></property>
+ <property name="style">wxBU_AUTODRAW</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="OnButtonClick">OnClear</event>
+ <event name="OnChar"></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 class="sizeritem" expanded="0">
+ <property name="border">5</property>
+ <property name="flag">wxALL|wxEXPAND</property>
+ <property name="proportion">0</property>
+ <object class="wxStdDialogButtonSizer" expanded="0">
+ <property name="Apply">0</property>
+ <property name="Cancel">1</property>
+ <property name="ContextHelp">0</property>
+ <property name="Help">0</property>
+ <property name="No">0</property>
+ <property name="OK">1</property>
+ <property name="Save">0</property>
+ <property name="Yes">0</property>
+ <property name="minimum_size"></property>
+ <property name="name">m_stdButtons</property>
+ <property name="permission">protected</property>
+ <event name="OnApplyButtonClick"></event>
+ <event name="OnCancelButtonClick">OnCancelClick</event>
+ <event name="OnContextHelpButtonClick"></event>
+ <event name="OnHelpButtonClick"></event>
+ <event name="OnNoButtonClick"></event>
+ <event name="OnOKButtonClick">OnOkClick</event>
+ <event name="OnSaveButtonClick"></event>
+ <event name="OnYesButtonClick"></event>
+ </object>
+ </object>
+ </object>
+ </object>
+ </object>
+</wxFormBuilder_Project>
diff --git a/pcbnew/dialogs/dialog_move_exact.h b/pcbnew/dialogs/dialog_move_exact.h
new file mode 100644
index 0000000..37c7e9e
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact.h
@@ -0,0 +1,86 @@
+/*
+ * This program source code file is part of KiCad, a free EDA CAD application.
+ *
+ * Copyright (C) 2014 John Beard, john.j.beard@gmail.com
+ * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.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
+ */
+
+#ifndef __DIALOG_MOVE_EXACT__
+#define __DIALOG_MOVE_EXACT__
+
+// Include the wxFormBuider header base:
+#include <vector>
+#include <dialog_move_exact_base.h>
+
+class DIALOG_MOVE_EXACT : public DIALOG_MOVE_EXACT_BASE
+{
+private:
+
+ wxPoint& m_translation;
+ double& m_rotation;
+
+public:
+
+ enum MOVE_EDIT_T
+ {
+ MOVE_ABORT, ///< if not changed or error
+ MOVE_OK, ///< if successfully changed
+ };
+
+ /**
+ * Persistent dialog options
+ */
+ struct MOVE_EXACT_OPTIONS
+ {
+ bool polarCoords;
+ double entry1;
+ double entry2;
+ double entryRotation;
+
+ MOVE_EXACT_OPTIONS():
+ polarCoords(false),
+ entry1(0),
+ entry2(0),
+ entryRotation(0)
+ {
+ }
+ };
+
+ // Constructor and destructor
+ DIALOG_MOVE_EXACT( PCB_BASE_FRAME* aParent, wxPoint& translation,
+ double& rotation );
+ ~DIALOG_MOVE_EXACT();
+
+ // persistent settings
+ static MOVE_EXACT_OPTIONS m_options;
+
+private:
+
+ void OnPolarChanged( wxCommandEvent& event );
+ void OnClear( wxCommandEvent& event );
+
+ void OnCancelClick( wxCommandEvent& event );
+ void OnOkClick( wxCommandEvent& event );
+
+ void ToPolarDeg( double x, double y, double& r, double& q );
+ bool GetTranslationInIU ( wxPoint& val, bool polar );
+};
+
+#endif // __DIALOG_MOVE_EXACT__
diff --git a/pcbnew/dialogs/dialog_move_exact_base.cpp b/pcbnew/dialogs/dialog_move_exact_base.cpp
new file mode 100644
index 0000000..74255b8
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact_base.cpp
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "dialog_move_exact_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+DIALOG_MOVE_EXACT_BASE::DIALOG_MOVE_EXACT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
+{
+ this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
+
+ wxBoxSizer* bMainSizer;
+ bMainSizer = new wxBoxSizer( wxVERTICAL );
+
+ m_polarCoords = new wxCheckBox( this, wxID_ANY, _("Polar coordinates"), wxDefaultPosition, wxDefaultSize, 0 );
+ bMainSizer->Add( m_polarCoords, 0, wxALL|wxEXPAND, 5 );
+
+ wxFlexGridSizer* fgSizer2;
+ fgSizer2 = new wxFlexGridSizer( 0, 4, 0, 0 );
+ fgSizer2->AddGrowableCol( 1 );
+ fgSizer2->SetFlexibleDirection( wxBOTH );
+ fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_xLabel = new wxStaticText( this, wxID_ANY, _("x:"), wxDefaultPosition, wxSize( -1,-1 ), 0 );
+ m_xLabel->Wrap( -1 );
+ fgSizer2->Add( m_xLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_xEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer2->Add( m_xEntry, 0, wxALL|wxEXPAND, 5 );
+
+ m_xUnit = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_xUnit->Wrap( -1 );
+ fgSizer2->Add( m_xUnit, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT|wxALL, 5 );
+
+ m_clearX = new wxBitmapButton( this, wxID_CLEAR, wxArtProvider::GetBitmap( wxART_DELETE, wxART_BUTTON ), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
+ fgSizer2->Add( m_clearX, 0, wxALL, 5 );
+
+ m_yLabel = new wxStaticText( this, wxID_ANY, _("y:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_yLabel->Wrap( -1 );
+ fgSizer2->Add( m_yLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_yEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer2->Add( m_yEntry, 0, wxALL|wxEXPAND, 5 );
+
+ m_yUnit = new wxStaticText( this, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_yUnit->Wrap( -1 );
+ fgSizer2->Add( m_yUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_clearY = new wxBitmapButton( this, wxID_CLEAR, wxArtProvider::GetBitmap( wxART_DELETE, wxART_BUTTON ), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
+ fgSizer2->Add( m_clearY, 0, wxALL, 5 );
+
+ m_rotLabel = new wxStaticText( this, wxID_ANY, _("Rotate:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_rotLabel->Wrap( -1 );
+ fgSizer2->Add( m_rotLabel, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_rotEntry = new wxTextCtrl( this, wxID_ANY, _("0"), wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer2->Add( m_rotEntry, 0, wxALL|wxEXPAND, 5 );
+
+ m_rotUnit = new wxStaticText( this, wxID_ANY, _("deg"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_rotUnit->Wrap( -1 );
+ fgSizer2->Add( m_rotUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_clearRot = new wxBitmapButton( this, wxID_CLEAR, wxArtProvider::GetBitmap( wxART_DELETE, wxART_BUTTON ), wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW );
+ fgSizer2->Add( m_clearRot, 0, wxALL, 5 );
+
+
+ bMainSizer->Add( fgSizer2, 1, wxEXPAND, 5 );
+
+ m_stdButtons = new wxStdDialogButtonSizer();
+ m_stdButtonsOK = new wxButton( this, wxID_OK );
+ m_stdButtons->AddButton( m_stdButtonsOK );
+ m_stdButtonsCancel = new wxButton( this, wxID_CANCEL );
+ m_stdButtons->AddButton( m_stdButtonsCancel );
+ m_stdButtons->Realize();
+
+ bMainSizer->Add( m_stdButtons, 0, wxALL|wxEXPAND, 5 );
+
+
+ this->SetSizer( bMainSizer );
+ this->Layout();
+ bMainSizer->Fit( this );
+
+ // Connect Events
+ this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_MOVE_EXACT_BASE::OnClose ) );
+ m_polarCoords->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnPolarChanged ), NULL, this );
+ m_clearX->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_clearY->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_clearRot->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_stdButtonsCancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnCancelClick ), NULL, this );
+ m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnOkClick ), NULL, this );
+}
+
+DIALOG_MOVE_EXACT_BASE::~DIALOG_MOVE_EXACT_BASE()
+{
+ // Disconnect Events
+ this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_MOVE_EXACT_BASE::OnClose ) );
+ m_polarCoords->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnPolarChanged ), NULL, this );
+ m_clearX->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_clearY->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_clearRot->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnClear ), NULL, this );
+ m_stdButtonsCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnCancelClick ), NULL, this );
+ m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_MOVE_EXACT_BASE::OnOkClick ), NULL, this );
+
+}
diff --git a/pcbnew/dialogs/dialog_move_exact_base.h b/pcbnew/dialogs/dialog_move_exact_base.h
new file mode 100644
index 0000000..9544e48
--- /dev/null
+++ b/pcbnew/dialogs/dialog_move_exact_base.h
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version Jun 6 2014)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO "NOT" EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef __DIALOG_MOVE_EXACT_BASE_H__
+#define __DIALOG_MOVE_EXACT_BASE_H__
+
+#include <wx/artprov.h>
+#include <wx/xrc/xmlres.h>
+#include <wx/intl.h>
+class DIALOG_SHIM;
+
+#include "dialog_shim.h"
+#include <wx/string.h>
+#include <wx/checkbox.h>
+#include <wx/gdicmn.h>
+#include <wx/font.h>
+#include <wx/colour.h>
+#include <wx/settings.h>
+#include <wx/stattext.h>
+#include <wx/textctrl.h>
+#include <wx/bitmap.h>
+#include <wx/image.h>
+#include <wx/icon.h>
+#include <wx/bmpbuttn.h>
+#include <wx/button.h>
+#include <wx/sizer.h>
+#include <wx/dialog.h>
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class DIALOG_MOVE_EXACT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class DIALOG_MOVE_EXACT_BASE : public DIALOG_SHIM
+{
+ private:
+
+ protected:
+ wxCheckBox* m_polarCoords;
+ wxStaticText* m_xLabel;
+ wxTextCtrl* m_xEntry;
+ wxStaticText* m_xUnit;
+ wxBitmapButton* m_clearX;
+ wxStaticText* m_yLabel;
+ wxTextCtrl* m_yEntry;
+ wxStaticText* m_yUnit;
+ wxBitmapButton* m_clearY;
+ wxStaticText* m_rotLabel;
+ wxTextCtrl* m_rotEntry;
+ wxStaticText* m_rotUnit;
+ wxBitmapButton* m_clearRot;
+ wxStdDialogButtonSizer* m_stdButtons;
+ wxButton* m_stdButtonsOK;
+ wxButton* m_stdButtonsCancel;
+
+ // Virtual event handlers, overide them in your derived class
+ virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
+ virtual void OnPolarChanged( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnClear( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
+ virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ DIALOG_MOVE_EXACT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Move item"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
+ ~DIALOG_MOVE_EXACT_BASE();
+
+};
+
+#endif //__DIALOG_MOVE_EXACT_BASE_H__
diff --git a/pcbnew/hotkeys.cpp b/pcbnew/hotkeys.cpp
index 1cfb3b4..4e7447d 100644
--- a/pcbnew/hotkeys.cpp
+++ b/pcbnew/hotkeys.cpp
@@ -108,6 +108,8 @@ static EDA_HOTKEY HkEditBoardItem( wxT( "Edit Item" ), HK_EDIT_ITEM, 'E' );
static EDA_HOTKEY HkFlipItem( wxT( "Flip Item" ), HK_FLIP_ITEM, 'F' );
static EDA_HOTKEY HkRotateItem( wxT( "Rotate Item" ), HK_ROTATE_ITEM, 'R' );
static EDA_HOTKEY HkMoveItem( wxT( "Move Item" ), HK_MOVE_ITEM, 'M' );
+static EDA_HOTKEY HkMoveItemExact( wxT( "Move Item Exactly" ), HK_MOVE_ITEM_EXACT, 'M' + GR_KB_CTRL );
+static EDA_HOTKEY HkDuplicateItem( wxT( "Duplicate Item" ), HK_DUPLICATE_ITEM, 'D' + GR_KB_CTRL );
static EDA_HOTKEY HkCopyItem( wxT( "Copy Item" ), HK_COPY_ITEM, 'C' );
static EDA_HOTKEY HkDragFootprint( wxT( "Drag Footprint" ), HK_DRAG_ITEM, 'G' );
static EDA_HOTKEY HkGetAndMoveFootprint( wxT( "Get and Move Footprint" ), HK_GET_AND_MOVE_FOOTPRINT, 'T' );
@@ -295,6 +297,7 @@ EDA_HOTKEY* board_edit_Hotkey_List[] =
// List of hotkey descriptors for the module editor
EDA_HOTKEY* module_edit_Hotkey_List[] = {
&HkMoveItem, &HkRotateItem, &HkEditBoardItem,
+ &HkMoveItemExact, &HkDuplicateItem,
&HkDelete,
&HkSaveModule,
NULL
diff --git a/pcbnew/hotkeys.h b/pcbnew/hotkeys.h
index b3bd3c1..50f00de 100644
--- a/pcbnew/hotkeys.h
+++ b/pcbnew/hotkeys.h
@@ -41,6 +41,7 @@ enum hotkey_id_commnand {
HK_FLIP_ITEM,
HK_COPY_ITEM,
HK_MOVE_ITEM,
+ HK_MOVE_ITEM_EXACT,
HK_DRAG_ITEM,
HK_GET_AND_MOVE_FOOTPRINT,
HK_LOCK_UNLOCK_FOOTPRINT,
@@ -60,6 +61,7 @@ enum hotkey_id_commnand {
HK_SWITCH_TRACK_DISPLAY_MODE,
HK_FIND_ITEM,
HK_EDIT_ITEM,
+ HK_DUPLICATE_ITEM,
HK_PLACE_ITEM,
HK_SWITCH_TRACK_WIDTH_TO_NEXT,
HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS,
diff --git a/pcbnew/hotkeys_board_editor.cpp b/pcbnew/hotkeys_board_editor.cpp
index 3be8c52..9ac2940 100644
--- a/pcbnew/hotkeys_board_editor.cpp
+++ b/pcbnew/hotkeys_board_editor.cpp
@@ -888,7 +888,6 @@ bool PCB_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
return false;
}
-
bool PCB_EDIT_FRAME::OnHotkeyPlaceItem( wxDC* aDC )
{
BOARD_ITEM* item = GetCurItem();
diff --git a/pcbnew/hotkeys_module_editor.cpp b/pcbnew/hotkeys_module_editor.cpp
index 918d8a4..0236334 100644
--- a/pcbnew/hotkeys_module_editor.cpp
+++ b/pcbnew/hotkeys_module_editor.cpp
@@ -152,31 +152,83 @@ bool FOOTPRINT_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPos
OnHotkeyMoveItem( HK_MOVE_ITEM );
break;
+ case HK_MOVE_ITEM_EXACT:
+ if ( blockActive )
+ {
+ cmd.SetId( ID_POPUP_MOVE_BLOCK_EXACT );
+ GetEventHandler()->ProcessEvent( cmd );
+ }
+ else
+ {
+ OnHotkeyMoveItemExact();
+ }
+ break;
+
case HK_ROTATE_ITEM:
OnHotkeyRotateItem( HK_ROTATE_ITEM );
break;
+
+ case HK_DUPLICATE_ITEM:
+ OnHotkeyDuplicateItem();
+ break;
}
return true;
}
-bool FOOTPRINT_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
+BOARD_ITEM* FOOTPRINT_EDIT_FRAME::PrepareItemForHotkey( bool failIfCurrentlyEdited )
{
BOARD_ITEM* item = GetCurItem();
bool itemCurrentlyEdited = item && item->GetFlags();
bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE;
- if( itemCurrentlyEdited || blockActive )
- return false;
+ if ( failIfCurrentlyEdited )
+ {
+ if( itemCurrentlyEdited || blockActive )
+ return NULL;
+
+ item = ModeditLocateAndDisplay();
+ }
+ else
+ {
+ if( blockActive )
+ return NULL;
+
+ if( !itemCurrentlyEdited )
+ item = ModeditLocateAndDisplay();
+ }
+
+ // set item if we can, but don't clear if not
+ if( item )
+ SetCurItem( item );
+
+ return item;
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::PostCommandMenuEvent( int evt_type )
+{
+ if( evt_type != 0 )
+ {
+ wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
+ evt.SetEventObject( this );
+ evt.SetId( evt_type );
+ wxPostEvent( this, evt );
+ return true;
+ }
+
+ return false;
+}
- item = ModeditLocateAndDisplay();
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
if( item == NULL )
return false;
- SetCurItem( item );
-
int evt_type = 0; // Used to post a wxCommandEvent on demand
switch( item->Type() )
@@ -209,35 +261,17 @@ bool FOOTPRINT_EDIT_FRAME::OnHotkeyEditItem( int aIdCommand )
break;
}
- if( evt_type != 0 )
- {
- wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
- evt.SetEventObject( this );
- evt.SetId( evt_type );
- wxPostEvent( this, evt );
- return true;
- }
-
- return false;
+ return PostCommandMenuEvent( evt_type );
}
bool FOOTPRINT_EDIT_FRAME::OnHotkeyDeleteItem( int aIdCommand )
{
- BOARD_ITEM* item = GetCurItem();
- bool itemCurrentlyEdited = item && item->GetFlags();
- bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE;
-
- if( itemCurrentlyEdited || blockActive )
- return false;
-
- item = ModeditLocateAndDisplay();
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
if( item == NULL )
return false;
- SetCurItem( item );
-
int evt_type = 0; // Used to post a wxCommandEvent on demand
switch( item->Type() )
@@ -264,35 +298,17 @@ bool FOOTPRINT_EDIT_FRAME::OnHotkeyDeleteItem( int aIdCommand )
break;
}
- if( evt_type != 0 )
- {
- wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
- evt.SetEventObject( this );
- evt.SetId( evt_type );
- wxPostEvent( this, evt );
- return true;
- }
-
- return false;
+ return PostCommandMenuEvent( evt_type );
}
bool FOOTPRINT_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
{
- BOARD_ITEM* item = GetCurItem();
- bool itemCurrentlyEdited = item && item->GetFlags();
- bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE;
-
- if( itemCurrentlyEdited || blockActive )
- return false;
-
- item = ModeditLocateAndDisplay();
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
if( item == NULL )
return false;
- SetCurItem( item );
-
int evt_type = 0; // Used to post a wxCommandEvent on demand
switch( item->Type() )
@@ -319,36 +335,65 @@ bool FOOTPRINT_EDIT_FRAME::OnHotkeyMoveItem( int aIdCommand )
break;
}
- if( evt_type != 0 )
+ return PostCommandMenuEvent( evt_type );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyMoveItemExact()
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( false );
+
+ if( item == NULL )
+ return false;
+
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
{
- wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
- evt.SetEventObject( this );
- evt.SetId( evt_type );
- wxPostEvent( this, evt );
- return true;
+ case PCB_PAD_T:
+ case PCB_MODULE_EDGE_T:
+ case PCB_MODULE_TEXT_T:
+ evt_type = ID_POPUP_PCB_MOVE_EXACT;
+ break;
+ default:
+ break;
}
- return false;
+ return PostCommandMenuEvent( evt_type );
}
-
-bool FOOTPRINT_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand )
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyDuplicateItem()
{
- BOARD_ITEM* item = GetCurItem();
- bool itemCurrentlyEdited = item && item->GetFlags();
- int evt_type = 0; // Used to post a wxCommandEvent on demand
- bool blockActive = GetScreen()->m_BlockLocate.GetCommand() != BLOCK_IDLE;
+ BOARD_ITEM* item = PrepareItemForHotkey( true );
- if( blockActive )
+ if( item == NULL )
return false;
- if( !itemCurrentlyEdited )
- item = ModeditLocateAndDisplay();
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
+
+ switch( item->Type() )
+ {
+ case PCB_PAD_T:
+ case PCB_MODULE_EDGE_T:
+ case PCB_MODULE_TEXT_T:
+ evt_type = ID_POPUP_PCB_DUPLICATE_ITEM;
+ break;
+ default:
+ break;
+ }
+
+ return PostCommandMenuEvent( evt_type );
+}
+
+
+bool FOOTPRINT_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand )
+{
+ BOARD_ITEM* item = PrepareItemForHotkey( false );
if( item == NULL )
return false;
- SetCurItem( item );
+ int evt_type = 0; // Used to post a wxCommandEvent on demand
switch( item->Type() )
{
@@ -362,14 +407,5 @@ bool FOOTPRINT_EDIT_FRAME::OnHotkeyRotateItem( int aIdCommand )
break;
}
- if( evt_type != 0 )
- {
- wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED );
- evt.SetEventObject( this );
- evt.SetId( evt_type );
- wxPostEvent( this, evt );
- return true;
- }
-
- return false;
+ return PostCommandMenuEvent( evt_type );
}
diff --git a/pcbnew/modedit.cpp b/pcbnew/modedit.cpp
index 6455891..071b537 100644
--- a/pcbnew/modedit.cpp
+++ b/pcbnew/modedit.cpp
@@ -54,6 +54,7 @@
#include <tool/tool_manager.h>
#include <dialog_edit_module_for_Modedit.h>
+#include <dialog_move_exact.h>
#include <wildcards_and_files_ext.h>
#include <menus_helpers.h>
#include <footprint_wizard_frame.h>
@@ -63,11 +64,13 @@
// Functions defined in block_module_editor, but used here
-// These 2 functions are used in modedit to rotate or mirror the whole footprint
+// These 3 functions are used in modedit to rotate or mirror the whole footprint
// so they are called with force_all = true
void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
-
+void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
+ const wxPoint& translation, double rotation,
+ bool force_all = false );
BOARD_ITEM* FOOTPRINT_EDIT_FRAME::ModeditLocateAndDisplay( int aHotKeyCode )
{
@@ -637,6 +640,69 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
m_canvas->MoveCursorToCrossHair();
break;
+ case ID_POPUP_PCB_DUPLICATE_ITEM:
+ {
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+ MODULE* module = static_cast<MODULE*>( item->GetParent() );
+
+ int move_cmd = 0;
+
+ BOARD_ITEM* new_item = module->DuplicateAndAddItem( item );
+
+ if( new_item )
+ {
+ switch( new_item->Type() )
+ {
+ case PCB_PAD_T:
+ move_cmd = ID_POPUP_PCB_MOVE_PAD_REQUEST;
+ break;
+ case PCB_MODULE_TEXT_T:
+ move_cmd = ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST;
+ break;
+ case PCB_MODULE_EDGE_T:
+ move_cmd = ID_POPUP_PCB_MOVE_EDGE;
+ break;
+ }
+
+ SetMsgPanel( new_item );
+ SetCurItem( new_item );
+
+ m_canvas->MoveCursorToCrossHair();
+ }
+
+ if ( move_cmd )
+ {
+ // pick up the item and start moving
+ PostCommandMenuEvent( move_cmd );
+ }
+ }
+ break;
+
+ case ID_POPUP_PCB_MOVE_EXACT:
+ {
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == DIALOG_MOVE_EXACT::MOVE_OK )
+ {
+ SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
+
+ BOARD_ITEM* item = GetScreen()->GetCurItem();
+
+ item->Move( translation );
+ item->Rotate( item->GetPosition(), rotation );
+ m_canvas->Refresh();
+ }
+
+ m_canvas->MoveCursorToCrossHair();
+ }
+ break;
+
case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
m_canvas->MoveCursorToCrossHair();
@@ -736,6 +802,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MODEDIT_MODULE_ROTATE:
case ID_MODEDIT_MODULE_MIRROR:
+ case ID_MODEDIT_MODULE_MOVE_EXACT:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
Transform( (MODULE*) GetScreen()->GetCurItem(), id );
redraw = true;
@@ -800,6 +867,12 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
HandleBlockEnd( &dc );
break;
+ case ID_POPUP_MOVE_BLOCK_EXACT:
+ GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE_EXACT );
+ GetScreen()->m_BlockLocate.SetMessageBlock( this );
+ HandleBlockEnd( &dc );
+ break;
+
case ID_GEN_IMPORT_DXF_FILE:
InvokeDXFDialogModuleImport( this, GetBoard()->m_Modules );
m_canvas->Refresh();
@@ -828,6 +901,22 @@ void FOOTPRINT_EDIT_FRAME::Transform( MODULE* module, int transform )
MirrorMarkedItems( module, wxPoint(0,0), true );
break;
+ case ID_MODEDIT_MODULE_MOVE_EXACT:
+ {
+ wxPoint translation;
+ double rotation = 0;
+
+ DIALOG_MOVE_EXACT dialog( this, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == DIALOG_MOVE_EXACT::MOVE_OK )
+ {
+ MoveMarkedItemsExactly( module, wxPoint(0, 0),
+ translation, rotation, true );
+ }
+ }
+ break;
+
default:
DisplayInfoMessage( this, wxT( "Not available" ) );
break;
diff --git a/pcbnew/modedit_onclick.cpp b/pcbnew/modedit_onclick.cpp
index edb29d0..b3944de 100644
--- a/pcbnew/modedit_onclick.cpp
+++ b/pcbnew/modedit_onclick.cpp
@@ -173,7 +173,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
// so deselect the active tool
SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );
SetCurItem( NULL );
- m_canvas->Refresh();
+ m_canvas->Refresh();
}
break;
@@ -260,6 +260,11 @@ bool FOOTPRINT_EDIT_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMen
AddMenuItem( PopMenu, ID_POPUP_DELETE_BLOCK,
_( "Delete Block (shift+ctrl + drag mouse)" ),
KiBitmap( delete_xpm ) );
+
+ msg = AddHotkeyName( _("Move Block Exactly" ),
+ g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_MOVE_BLOCK_EXACT,
+ msg, KiBitmap( move_xpm ) );
}
else
{
@@ -286,10 +291,14 @@ bool FOOTPRINT_EDIT_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMen
KiBitmap( rotate_module_ccw_xpm ) );
AddMenuItem( transform_choice, ID_MODEDIT_MODULE_MIRROR, _( "Mirror" ),
KiBitmap( mirror_footprint_axisY_xpm ) );
+ AddMenuItem( transform_choice, ID_MODEDIT_MODULE_MOVE_EXACT, _( "Move Exactly" ),
+ KiBitmap( move_module_xpm ) );
+
msg = AddHotkeyName( _( "Edit Footprint" ), g_Module_Editor_Hokeys_Descr, HK_EDIT_ITEM );
AddMenuItem( PopMenu, ID_POPUP_PCB_EDIT_MODULE_PRMS, msg, KiBitmap( edit_module_xpm ) );
AddMenuItem( PopMenu, transform_choice, ID_MODEDIT_TRANSFORM_MODULE,
_( "Transform Footprint" ), KiBitmap( edit_xpm ) );
+
break;
}
@@ -309,6 +318,12 @@ bool FOOTPRINT_EDIT_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMen
msg = AddHotkeyName( _("Delete Pad" ), g_Module_Editor_Hokeys_Descr, HK_DELETE );
AddMenuItem( PopMenu, ID_POPUP_PCB_DELETE_PAD, msg, KiBitmap( delete_pad_xpm ) );
+ msg = AddHotkeyName( _( "Duplicate Pad" ), g_Module_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_pad_xpm ) );
+
+ msg = AddHotkeyName( _("Move Pad Exactly" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_pad_xpm ) );
+
if( !flags )
{
PopMenu->AppendSeparator();
@@ -331,6 +346,26 @@ bool FOOTPRINT_EDIT_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMen
HK_ROTATE_ITEM );
AddMenuItem( PopMenu, ID_POPUP_PCB_ROTATE_TEXTMODULE, msg, KiBitmap( rotate_field_xpm ) );
+ {
+ // do not show option to duplicate value or reference fields
+ // (there can only be one of each)
+
+ const MODULE* module = static_cast<MODULE*>( item->GetParent() );
+ const TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
+
+ if ( &module->Reference() != text
+ && &module->Value() != text )
+ {
+ msg = AddHotkeyName( _( "Duplicate Text" ),
+ g_Module_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM,
+ msg, KiBitmap( duplicate_text_xpm ) );
+ }
+ }
+
+ msg = AddHotkeyName( _("Move Text Exactly" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_field_xpm ) );
+
if( !flags )
{
msg = AddHotkeyName( _("Edit Text" ), g_Module_Editor_Hokeys_Descr,
@@ -359,6 +394,12 @@ bool FOOTPRINT_EDIT_FRAME::OnRightClick( const wxPoint& MousePos, wxMenu* PopMen
AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EDGE, msg, KiBitmap( move_line_xpm ) );
}
+ msg = AddHotkeyName( _( "Duplicate Edge" ), g_Module_Editor_Hokeys_Descr, HK_DUPLICATE_ITEM );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_DUPLICATE_ITEM, msg, KiBitmap( duplicate_line_xpm ) );
+
+ msg = AddHotkeyName( _("Move Edge Exactly" ), g_Module_Editor_Hokeys_Descr, HK_MOVE_ITEM_EXACT );
+ AddMenuItem( PopMenu, ID_POPUP_PCB_MOVE_EXACT, msg, KiBitmap( move_line_xpm ) );
+
if( ( flags & (IS_NEW | IS_MOVED) ) == IS_MOVED )
AddMenuItem( PopMenu, ID_POPUP_PCB_PLACE_EDGE, _( "Place edge" ),
KiBitmap( checked_ok_xpm ) );
diff --git a/pcbnew/module_editor_frame.h b/pcbnew/module_editor_frame.h
index caf9518..a72b7dc 100644
--- a/pcbnew/module_editor_frame.h
+++ b/pcbnew/module_editor_frame.h
@@ -126,10 +126,15 @@ public:
*/
bool OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition, EDA_ITEM* aItem = NULL );
+ BOARD_ITEM* PrepareItemForHotkey( bool failIfCurrentlyEdited );
+ bool PostCommandMenuEvent( int evt_type );
+
bool OnHotkeyEditItem( int aIdCommand );
bool OnHotkeyDeleteItem( int aIdCommand );
bool OnHotkeyMoveItem( int aIdCommand );
+ bool OnHotkeyMoveItemExact();
bool OnHotkeyRotateItem( int aIdCommand );
+ bool OnHotkeyDuplicateItem();
/**
* Function Show3D_Frame
diff --git a/pcbnew/moduleframe.cpp b/pcbnew/moduleframe.cpp
index 319c221..8560394 100644
--- a/pcbnew/moduleframe.cpp
+++ b/pcbnew/moduleframe.cpp
@@ -132,6 +132,7 @@ BEGIN_EVENT_TABLE( FOOTPRINT_EDIT_FRAME, PCB_BASE_FRAME )
// Module transformations
EVT_MENU( ID_MODEDIT_MODULE_ROTATE, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_MENU( ID_MODEDIT_MODULE_MIRROR, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
+ EVT_MENU( ID_MODEDIT_MODULE_MOVE_EXACT, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
EVT_MENU( ID_PCB_PAD_SETUP, FOOTPRINT_EDIT_FRAME::Process_Special_Functions )
diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h
index 1aceb0d..e29a025 100644
--- a/pcbnew/pcbnew_id.h
+++ b/pcbnew/pcbnew_id.h
@@ -61,6 +61,8 @@ enum pcbnew_ids
ID_POPUP_PCB_ROTATE_PAD,
ID_POPUP_PCB_MOVE_PAD_REQUEST,
ID_POPUP_PCB_DRAG_PAD_REQUEST,
+ ID_POPUP_PCB_DUPLICATE_ITEM,
+ ID_POPUP_PCB_MOVE_EXACT,
ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST,
ID_POPUP_PCB_ROTATE_TEXTMODULE,
@@ -346,6 +348,7 @@ enum pcbnew_ids
ID_MODEDIT_TRANSFORM_MODULE,
ID_MODEDIT_MODULE_ROTATE,
ID_MODEDIT_MODULE_MIRROR,
+ ID_MODEDIT_MODULE_MOVE_EXACT,
ID_MODEDIT_IMPORT_PART,
ID_MODEDIT_EXPORT_PART,
ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART,
diff --git a/pcbnew/tools/common_actions.cpp b/pcbnew/tools/common_actions.cpp
index 456a021..8ba00ce 100644
--- a/pcbnew/tools/common_actions.cpp
+++ b/pcbnew/tools/common_actions.cpp
@@ -64,6 +64,14 @@ TOOL_ACTION COMMON_ACTIONS::editActivate( "pcbnew.InteractiveEdit",
AS_GLOBAL, 'M',
"Move", "Moves the selected item(s)", AF_ACTIVATE );
+TOOL_ACTION COMMON_ACTIONS::duplicate( "pcbnew.InteractiveEdit.duplicate",
+ AS_GLOBAL, MD_CTRL + int( 'D' ),
+ "Duplicate", "Duplicates the selected item(s)" );
+
+TOOL_ACTION COMMON_ACTIONS::moveExact( "pcbnew.InteractiveEdit.moveExact",
+ AS_GLOBAL, MD_CTRL + int( 'M' ),
+ "Move Exactly...", "Moves the selected item(s) by an exact amount" );
+
TOOL_ACTION COMMON_ACTIONS::rotate( "pcbnew.InteractiveEdit.rotate",
AS_GLOBAL, 'R',
"Rotate", "Rotates selected item(s)" );
diff --git a/pcbnew/tools/common_actions.h b/pcbnew/tools/common_actions.h
index 366f444..497b1a9 100644
--- a/pcbnew/tools/common_actions.h
+++ b/pcbnew/tools/common_actions.h
@@ -65,6 +65,12 @@ public:
/// Activation of the edit tool
static TOOL_ACTION properties;
+ /// Activation of the exact move tool
+ static TOOL_ACTION moveExact;
+
+ /// Activation of the duplication tool
+ static TOOL_ACTION duplicate;
+
/// Deleting a BOARD_ITEM
static TOOL_ACTION remove;
diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp
index be76326..b1d0553 100644
--- a/pcbnew/tools/edit_tool.cpp
+++ b/pcbnew/tools/edit_tool.cpp
@@ -42,6 +42,8 @@
#include "selection_tool.h"
#include "edit_tool.h"
+#include <dialogs/dialog_move_exact.h>
+
EDIT_TOOL::EDIT_TOOL() :
TOOL_INTERACTIVE( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ), m_editModules( false )
{
@@ -71,6 +73,7 @@ bool EDIT_TOOL::Init()
m_selectionTool->AddMenuItem( COMMON_ACTIONS::flip, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::remove, SELECTION_CONDITIONS::NotEmpty );
m_selectionTool->AddMenuItem( COMMON_ACTIONS::properties, SELECTION_CONDITIONS::NotEmpty );
+ m_selectionTool->AddMenuItem( COMMON_ACTIONS::moveExact, SELECTION_CONDITIONS::NotEmpty );
m_offset.x = 0;
m_offset.y = 0;
@@ -110,6 +113,12 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent )
controls->SetSnapping( true );
controls->ForceCursorPosition( false );
+ // cumulative translation
+ wxPoint totalMovement( 0, 0 );
+
+ // make sure nothing is inhibiting undo points
+ bool inhibitUndo = m_toolMgr->IsUndoInhibited();
+
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
@@ -145,6 +154,37 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent )
break; // exit the loop, as there is no further processing for removed items
}
+ else if( evt->IsAction( &COMMON_ACTIONS::duplicate ) )
+ {
+ // On duplicate, stop moving this item
+ // The duplicate tool should then select the new item and start
+ // a new move procedure
+ break;
+ }
+ else if( evt->IsAction( &COMMON_ACTIONS::moveExact ) )
+ {
+ // Can't do this, because the selection will then contain
+ // stale pointers and it will all go horribly wrong...
+ //editFrame->RestoreCopyFromUndoList( dummy );
+ //
+ // So, instead, reset the position manually
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+ item->SetPosition( item->GetPosition() - totalMovement );
+
+ // and what about flipping and rotation?
+ // for now, they won't be undone, but maybe that is how
+ // it should be, so you can flip and move exact in the
+ // same action?
+ }
+
+ // This causes a double event, so we will get the dialogue
+ // correctly, somehow - why does Rotate not?
+ //MoveExact( aEvent );
+ break; // exit the loop - we move exactly, so we have
+ // finished moving
+ }
}
else if( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
@@ -156,6 +196,8 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent )
wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) -
selection.Item<BOARD_ITEM>( 0 )->GetPosition();
+ totalMovement += movement;
+
// Drag items to the current cursor position
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
selection.Item<BOARD_ITEM>( i )->Move( movement + m_offset );
@@ -168,8 +210,11 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent )
break;
// Save items, so changes can be undone
- editFrame->OnModify();
- editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ if ( !inhibitUndo )
+ {
+ editFrame->OnModify();
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ }
if( selection.Size() == 1 )
{
@@ -195,6 +240,7 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent )
controls->SetAutoPan( true );
m_dragging = true;
+ m_toolMgr->IncUndoInhibit();
}
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
@@ -203,9 +249,14 @@ int EDIT_TOOL::Main( TOOL_EVENT& aEvent )
else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
break; // Finish
+
}
+ if ( m_dragging )
+ m_toolMgr->DecUndoInhibit();
+
m_dragging = false;
+
m_offset.x = 0;
m_offset.y = 0;
@@ -324,7 +375,8 @@ int EDIT_TOOL::Rotate( TOOL_EVENT& aEvent )
wxPoint rotatePoint = getModificationPoint( selection );
- if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag
+ // If it is being dragged, then it is already saved with UR_CHANGED flag
+ if( !m_toolMgr->IsUndoInhibited() )
{
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_ROTATED, rotatePoint );
@@ -378,7 +430,7 @@ int EDIT_TOOL::Flip( TOOL_EVENT& aEvent )
wxPoint flipPoint = getModificationPoint( selection );
- if( !m_dragging ) // If it is being dragged, then it is already saved with UR_CHANGED flag
+ if( !m_toolMgr->IsUndoInhibited() ) // If it is being dragged, then it is already saved with UR_CHANGED flag
{
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_FLIPPED, flipPoint );
@@ -532,6 +584,67 @@ void EDIT_TOOL::remove( BOARD_ITEM* aItem )
}
+int EDIT_TOOL::MoveExact( TOOL_EVENT& aEvent )
+{
+ const SELECTION& selection = m_selectionTool->GetSelection();
+
+ // Shall the selection be cleared at the end?
+ bool unselect = selection.Empty();
+
+ if( !makeSelection( selection ) || m_selectionTool->CheckLock() )
+ {
+ setTransitions();
+
+ return 0;
+ }
+
+ wxPoint translation;
+ double rotation = 0;
+
+ PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
+
+ DIALOG_MOVE_EXACT dialog( editFrame, translation, rotation );
+ int ret = dialog.ShowModal();
+
+ if( ret == DIALOG_MOVE_EXACT::MOVE_OK )
+ {
+ if( !m_toolMgr->IsUndoInhibited() )
+ {
+ editFrame->OnModify();
+ // record an action of move and rotate
+ editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
+ }
+
+ for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ item->Move( translation );
+ item->Rotate( item->GetPosition(), rotation );
+
+ if( !m_dragging )
+ item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ }
+
+ updateRatsnest( m_dragging );
+
+ if( m_dragging )
+ selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
+ else
+ getModel<BOARD>()->GetRatsnest()->Recalculate();
+
+ if( unselect )
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
+
+ m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
+ }
+
+ setTransitions();
+
+ return 0;
+}
+
+
void EDIT_TOOL::setTransitions()
{
Go( &EDIT_TOOL::Main, COMMON_ACTIONS::editActivate.MakeEvent() );
@@ -539,6 +652,7 @@ void EDIT_TOOL::setTransitions()
Go( &EDIT_TOOL::Flip, COMMON_ACTIONS::flip.MakeEvent() );
Go( &EDIT_TOOL::Remove, COMMON_ACTIONS::remove.MakeEvent() );
Go( &EDIT_TOOL::Properties, COMMON_ACTIONS::properties.MakeEvent() );
+ Go( &EDIT_TOOL::MoveExact, COMMON_ACTIONS::moveExact.MakeEvent() );
}
diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h
index a3386b3..c2859eb 100644
--- a/pcbnew/tools/edit_tool.h
+++ b/pcbnew/tools/edit_tool.h
@@ -92,6 +92,20 @@ public:
int Remove( TOOL_EVENT& aEvent );
/**
+ * Function Duplicate()
+ *
+ * Duplicates a component and starts a move action
+ */
+ int Duplicate( TOOL_EVENT& aEvent );
+
+ /**
+ * Function MoveExact()
+ *
+ * Invokes a dialog box to allow moving of the item by an exact amount.
+ */
+ int MoveExact( TOOL_EVENT& aEvent );
+
+ /**
* Function EditModules()
*
* Toggles edit module mode. When enabled, one may select parts of modules individually
@@ -123,6 +137,7 @@ private:
///> Removes and frees a single BOARD_ITEM.
void remove( BOARD_ITEM* aItem );
+
///> Sets up handlers for various events.
void setTransitions();
diff --git a/pcbnew/tools/module_tools.cpp b/pcbnew/tools/module_tools.cpp
index 54b9f52..b5bce88 100644
--- a/pcbnew/tools/module_tools.cpp
+++ b/pcbnew/tools/module_tools.cpp
@@ -74,6 +74,7 @@ bool MODULE_TOOLS::Init()
}
selectionTool->AddMenuItem( COMMON_ACTIONS::enumeratePads );
+ selectionTool->AddMenuItem( COMMON_ACTIONS::duplicate );
setTransitions();
@@ -81,44 +82,6 @@ bool MODULE_TOOLS::Init()
}
-static wxString getNextPadName( MODULE* aModule )
-{
- std::set<int> usedNumbers;
-
- // Create a set of used pad numbers
- for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() )
- {
- wxString padName = pad->GetPadName();
- int padNumber = 0;
- int base = 1;
-
- // Trim and extract the trailing numeric part
- while( padName.Len() && padName.Last() >= '0' && padName.Last() <= '9' )
- {
- padNumber += ( padName.Last() - '0' ) * base;
- padName.RemoveLast();
- base *= 10;
- }
-
- usedNumbers.insert( padNumber );
- }
-
- int candidate = *usedNumbers.begin();
-
- // Look for a gap in pad numbering
- for( std::set<int>::iterator it = usedNumbers.begin(),
- itEnd = usedNumbers.end(); it != itEnd; ++it )
- {
- if( *it - candidate > 1 )
- break;
-
- candidate = *it;
- }
-
- return wxString::Format( wxT( "%i" ), ++candidate );
-}
-
-
int MODULE_TOOLS::PlacePad( TOOL_EVENT& aEvent )
{
m_frame->SetToolID( ID_MODEDIT_PAD_TOOL, wxCURSOR_PENCIL, _( "Add pads" ) );
@@ -189,14 +152,8 @@ int MODULE_TOOLS::PlacePad( TOOL_EVENT& aEvent )
// ( pad position for module orient, 0, and relative to the module position)
pad->SetLocalCoord();
- /* NPTH pads take empty pad number (since they can't be connected),
- * other pads get incremented from the last one edited */
- wxString padName;
-
- if( pad->GetAttribute() != PAD_HOLE_NOT_PLATED )
- padName = getNextPadName( module );
-
- pad->SetPadName( padName );
+ // Take the next available pad number
+ pad->IncrementPadName( true, true );
// Handle the view aspect
preview.Remove( pad );
@@ -532,6 +489,76 @@ int MODULE_TOOLS::PasteItems( TOOL_EVENT& aEvent )
return 0;
}
+int MODULE_TOOLS::DuplicateItems ( TOOL_EVENT& aEvent )
+{
+ MODULE* module = m_board->m_Modules;
+ assert( module );
+
+ // first, check if we have a selection, or try to get one
+ SELECTION_TOOL* selTool = m_toolMgr->GetTool<SELECTION_TOOL>();
+
+ if( selTool->GetSelection().Empty() )
+ {
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true );
+ }
+
+ const SELECTION& selection = selTool->GetSelection();
+
+ // if we don't have a selection by now, this tool can't do anything
+ if( selection.Empty() || selTool->CheckLock() )
+ {
+ setTransitions();
+ return 0;
+ }
+
+ // we have a selection to work on now, so start the tool process
+
+ m_frame->OnModify();
+ m_frame->SaveCopyInUndoList( module, UR_MODEDIT );
+
+ // prevent other tools making undo points while the duplicate is going on
+ // so that if you cancel, you don't get a duplicate object hiding over
+ // the original
+ m_toolMgr->IncUndoInhibit();
+
+ for( int i = 0; i < selection.Size(); ++i )
+ {
+ BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
+
+ if( item )
+ {
+ // Unselect the item, so we won't pick it up again
+ // Do this first, so a single-item duplicate will correctly call
+ // SetCurItem and show the item properties
+ m_toolMgr->RunAction( COMMON_ACTIONS::unselectItem, true, item );
+
+ BOARD_ITEM* new_item = module->DuplicateAndAddItem( item );
+
+ if( new_item )
+ {
+ m_view->Add( new_item );
+
+ // Select the new item, so we can pick it up
+ m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, new_item );
+ }
+ }
+ }
+
+ m_frame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
+ selection.Size() ) );
+
+ // pick up the selected item(s) and start moving
+ // this works well for "dropping" copies around
+ m_toolMgr->RunAction( COMMON_ACTIONS::editActivate, true );
+
+ // and re-enable undos
+ m_toolMgr->DecUndoInhibit();
+
+ setTransitions();
+
+ return 0;
+}
+
int MODULE_TOOLS::ModuleTextOutlines( TOOL_EVENT& aEvent )
{
@@ -608,6 +635,7 @@ void MODULE_TOOLS::setTransitions()
Go( &MODULE_TOOLS::EnumeratePads, COMMON_ACTIONS::enumeratePads.MakeEvent() );
Go( &MODULE_TOOLS::CopyItems, COMMON_ACTIONS::copyItems.MakeEvent() );
Go( &MODULE_TOOLS::PasteItems, COMMON_ACTIONS::pasteItems.MakeEvent() );
+ Go( &MODULE_TOOLS::DuplicateItems, COMMON_ACTIONS::duplicate.MakeEvent() );
Go( &MODULE_TOOLS::ModuleTextOutlines, COMMON_ACTIONS::moduleTextOutlines.MakeEvent() );
Go( &MODULE_TOOLS::ModuleEdgeOutlines, COMMON_ACTIONS::moduleEdgeOutlines.MakeEvent() );
}
diff --git a/pcbnew/tools/module_tools.h b/pcbnew/tools/module_tools.h
index 71d83ac..3e9ef10 100644
--- a/pcbnew/tools/module_tools.h
+++ b/pcbnew/tools/module_tools.h
@@ -77,6 +77,9 @@ public:
*/
int PasteItems( TOOL_EVENT& aEvent );
+
+ int DuplicateItems ( TOOL_EVENT& aEvent );
+
/**
* Function ModuleTextOutlines()
*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment