Commit 863c1b48 authored by Miguel Angel Ajo's avatar Miguel Angel Ajo

Merged with testing

parents 2a9b8df8 5a6c088b
...@@ -48,37 +48,30 @@ E6) Start initial work for changing component library file format to use Dick's ...@@ -48,37 +48,30 @@ E6) Start initial work for changing component library file format to use Dick's
PCBNew PCBNew
------ ------
* Make the zone hit testing be done in screen coordinates, not internal units. *) Make the zone hit testing be done in screen coordinates, not internal units.
See the @todos in class_zone.cpp See the @todos in class_zone.cpp. A fixed distance in internal units becomes
a variable distance based on zoom factor, leading to inconsistent results at
various zoom factors. I believe that a fixed distance in pixels might make
for a friendlier UI.
*) Check that the new load visibility BOARD settings is properly setting the toolbar
Dick's Peronal TODO Items (Last Update: 24-April-2012)
-----------------------------------------------------
1) Work through some scroll, pan, zoom overflows in PCBNEW's nanometer build mode.
It is thought that if we can constrain the virtual IU space to within
INT_MIN to INT_MAX then a whole host of other problems will go away. Most
of the evil is in EDA_DRAW_FRAME::AdjustScrollBars() which assumes the
virtual IU space is infinite. This function triggers a movement of the
viewport within the virtual IU space and also a change in size of the virtual
IU space. Once this happens, you can end up thinking there are problems in
functions like EDA_DRAW_PANE::DrawCrossHair(), but this may be an artifact
of having traveled outside a limited virtual IU space.
2) Check that the new load visibility BOARD settings is properly setting the toolbar
buttons like show grid or ratsnest. Add PCB_EDIT_FRAME::SetVisibleElements() so buttons like show grid or ratsnest. Add PCB_EDIT_FRAME::SetVisibleElements() so
toolbar crap is not known to a BOARD. toolbar crap is not known to a BOARD.
3) Finish removing global access requirements from KICAD_PLUGIN, so that: *) Finish removing global access requirements from PLUGINs, so that:
*) a BOARD is a fully self contained document description. *) a BOARD is a fully self contained document description.
*) plugin developers do not have to access globals, since a plugin could *) plugin developers do not have to access globals, since a plugin could
very well be a dynamically loaded DLL/DSO. very well be a dynamically loaded DLL/DSO in the future.
One final problem remains with BASE_SCREEN's grid origin, easy solution is to One final problem remains is the BASE_SCREEN's grid origin. An easy
move just that one field into the BOARD. solution is to move just that one field into the BOARD.
*) Add ::Footprint*() functions to EAGLE_PLUGIN, so that Eagle footprint libraries
can be used in situ.
*) Add a library table for Pcbnew like that in the sweet library and get rid of the
damn search path strategy. This will enable concurrent usage of various types
of PLUGIN::Footprint*() functions. At least LEGACY and KICAD are both needed
concurrently.
4) Do an EAGLE XML import PCBNEW PLUGIN, and possibly add export support to it.
This is PLUGIN::Load() and maybe PLUGIN::Save().
5) Get back to the SWEET work.
...@@ -109,6 +109,8 @@ set( BMAPS_SMALL ...@@ -109,6 +109,8 @@ set( BMAPS_SMALL
pintype_opencoll pintype_opencoll
pintype_openemit pintype_openemit
pintype_noconnect pintype_noconnect
tree_nosel
tree_sel
) )
# image basenames that go into the toolbar sized destinations, i.e. 26x26 # image basenames that go into the toolbar sized destinations, i.e. 26x26
...@@ -127,6 +129,7 @@ set( BMAPS_MID ...@@ -127,6 +129,7 @@ set( BMAPS_MID
add_hierar_pin add_hierar_pin
add_hierarchical_subsheet add_hierarchical_subsheet
add_junction add_junction
add_keepout_area
add_line2bus add_line2bus
add_line_label add_line_label
add_line add_line
...@@ -473,8 +476,6 @@ set( BMAPS_MID ...@@ -473,8 +476,6 @@ set( BMAPS_MID
track_sketch track_sketch
track_unlocked track_unlocked
transistor transistor
tree_nosel
tree_sel
undelete undelete
undo undo
unit_inch unit_inch
......
/* 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, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff,
0x61, 0x00, 0x00, 0x02, 0xb0, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x8d, 0x93, 0x5f, 0x48, 0x53,
0x51, 0x1c, 0xc7, 0x45, 0xa7, 0x25, 0x61, 0x26, 0xb6, 0xfc, 0x93, 0x88, 0x92, 0xa9, 0x60, 0x11,
0xf4, 0x22, 0xfd, 0x7b, 0xe8, 0x21, 0xea, 0x2d, 0xf2, 0x25, 0xa8, 0x27, 0x03, 0x85, 0x88, 0xd0,
0xd5, 0x9a, 0x48, 0x77, 0x76, 0x23, 0x14, 0xb7, 0x74, 0x9b, 0xcb, 0x35, 0x77, 0xe7, 0xbd, 0x57,
0xaf, 0x05, 0x35, 0x88, 0x56, 0xd6, 0x96, 0x63, 0x81, 0xf3, 0xc6, 0xc0, 0x6a, 0x43, 0x27, 0xcb,
0x6d, 0xa0, 0xb8, 0xd9, 0x9d, 0x9b, 0xdb, 0xfc, 0x13, 0xb8, 0xb5, 0x72, 0x3b, 0x9d, 0x2b, 0x53,
0xdc, 0x34, 0xea, 0xe1, 0xc3, 0xb9, 0x70, 0xee, 0xf7, 0x7b, 0x7e, 0xbf, 0x73, 0xbe, 0xbf, 0x34,
0x00, 0x40, 0xda, 0x76, 0x50, 0x14, 0x4d, 0x57, 0xa9, 0x5a, 0x72, 0xe5, 0xf2, 0xdb, 0x7b, 0x52,
0xf7, 0x76, 0x63, 0xeb, 0x83, 0x24, 0xd1, 0x42, 0x92, 0x14, 0x4a, 0x29, 0x02, 0xf1, 0x93, 0x84,
0x70, 0x99, 0xc4, 0x85, 0x5e, 0x92, 0x44, 0x9e, 0xa9, 0xd5, 0x48, 0xf9, 0x3f, 0x0d, 0x28, 0x0a,
0x3d, 0x04, 0x45, 0x06, 0x63, 0x67, 0xc3, 0x77, 0xa6, 0xfe, 0x6c, 0xd4, 0x7b, 0xad, 0x36, 0xea,
0xa9, 0x3f, 0x17, 0x99, 0xe4, 0x5f, 0x59, 0x26, 0x08, 0xa1, 0x19, 0x9a, 0x57, 0x4b, 0x64, 0x5d,
0xbc, 0x7e, 0x1c, 0xa3, 0xbb, 0xa5, 0xe2, 0x1b, 0x3b, 0x0c, 0x48, 0x1c, 0x11, 0x8e, 0x35, 0x5d,
0x76, 0xcf, 0x9e, 0x3f, 0xf2, 0x2b, 0x50, 0x96, 0x09, 0x36, 0x99, 0x3b, 0x7d, 0x78, 0x7d, 0xf4,
0x6e, 0xdd, 0x8c, 0xba, 0xbf, 0xc7, 0x69, 0xff, 0x66, 0x8f, 0x98, 0xc6, 0x46, 0x43, 0xa2, 0xae,
0x8e, 0xba, 0x24, 0x03, 0x8d, 0x46, 0x93, 0x31, 0x80, 0x23, 0x83, 0xe6, 0x4b, 0x35, 0xab, 0x73,
0xa5, 0x1c, 0x90, 0x0a, 0x7d, 0xe1, 0x58, 0xd8, 0x60, 0xd0, 0x45, 0x7c, 0x3e, 0x1f, 0x90, 0xf7,
0x4a, 0xdf, 0x6e, 0x0a, 0x3b, 0x44, 0x8f, 0xea, 0x05, 0x02, 0x41, 0xce, 0xc6, 0xa5, 0xb1, 0xbd,
0xeb, 0x4f, 0x95, 0xaf, 0xda, 0x4b, 0x38, 0x20, 0x15, 0x43, 0x6d, 0x59, 0xf8, 0xa3, 0x51, 0x1f,
0xf6, 0xfb, 0xfd, 0x40, 0xd9, 0xa7, 0xb0, 0xb2, 0xa2, 0xc7, 0xdd, 0xa2, 0x66, 0xfd, 0x88, 0x2e,
0x2c, 0x16, 0xb7, 0x37, 0x6d, 0xb8, 0x11, 0x04, 0x72, 0x13, 0x3f, 0x53, 0xe9, 0xa4, 0x4b, 0xb2,
0xe2, 0x9f, 0x8b, 0x33, 0xc0, 0x26, 0xe3, 0xc5, 0x1c, 0x40, 0x9c, 0x2c, 0x0d, 0xbc, 0x78, 0xf9,
0x7c, 0x29, 0x18, 0x0c, 0x02, 0xdb, 0x94, 0x2d, 0xa6, 0x1d, 0xd6, 0x7a, 0x69, 0xda, 0xf4, 0xc3,
0x62, 0xb1, 0xac, 0x77, 0x76, 0x76, 0x34, 0x6c, 0x18, 0x0c, 0x0d, 0xa1, 0x15, 0xb8, 0xec, 0x4e,
0x83, 0xa4, 0xe2, 0xe0, 0xbc, 0xb6, 0x28, 0x0b, 0x18, 0x0a, 0x39, 0x40, 0x5f, 0x98, 0x19, 0x97,
0x55, 0x72, 0x19, 0xec, 0xa9, 0xd4, 0xbd, 0x18, 0x58, 0x8c, 0xb1, 0x06, 0x0e, 0x87, 0x03, 0x30,
0x0c, 0x03, 0x2c, 0x56, 0xcb, 0x6f, 0x95, 0xba, 0x6f, 0x0a, 0x56, 0xcf, 0xd9, 0xba, 0x0c, 0x8a,
0x42, 0xca, 0x65, 0xf7, 0xae, 0x5f, 0x7d, 0x50, 0x5b, 0xd5, 0x83, 0x54, 0x14, 0xbc, 0x41, 0x2a,
0x8b, 0xde, 0x63, 0x58, 0xef, 0xd7, 0xf9, 0x79, 0xcf, 0x7a, 0x34, 0x1a, 0x05, 0xb3, 0xb3, 0x33,
0x31, 0xf8, 0x0a, 0x93, 0x0a, 0xa5, 0x1c, 0x53, 0x28, 0x9f, 0xdc, 0x6f, 0x6c, 0x6c, 0xcc, 0x4c,
0xca, 0x01, 0x0b, 0x1b, 0x1e, 0x82, 0x68, 0xe5, 0x8e, 0x8f, 0x7f, 0x38, 0x81, 0xa9, 0x95, 0xc3,
0x2e, 0x97, 0xf3, 0xe7, 0xda, 0xda, 0x1a, 0x58, 0xf0, 0x2d, 0xc4, 0x70, 0x02, 0xa3, 0x57, 0x56,
0x56, 0xd8, 0x4c, 0xec, 0x87, 0xec, 0x85, 0x14, 0x40, 0xf2, 0x76, 0x0d, 0x87, 0x1a, 0x57, 0x11,
0x56, 0xab, 0x25, 0x1c, 0x0a, 0x85, 0x00, 0xe3, 0x65, 0x62, 0x03, 0x83, 0xb8, 0x19, 0x96, 0x9b,
0x95, 0x10, 0x97, 0x42, 0x32, 0x12, 0x06, 0xf9, 0x3b, 0xc4, 0x32, 0xb9, 0xa4, 0x8d, 0xfe, 0x44,
0xaf, 0x7a, 0x3c, 0x1e, 0xe0, 0x76, 0xbb, 0xe3, 0x83, 0xd4, 0xc0, 0x17, 0xf8, 0x84, 0xc7, 0xe1,
0x5e, 0x0d, 0xa4, 0x2a, 0xf1, 0x1f, 0x77, 0x47, 0x94, 0x59, 0x60, 0xca, 0x6e, 0x19, 0x8c, 0x23,
0x4b, 0xd3, 0xd3, 0xd3, 0xc0, 0xe5, 0x72, 0x41, 0x31, 0x61, 0xa5, 0x28, 0x6a, 0x5f, 0xca, 0x21,
0x6c, 0xf9, 0x79, 0x90, 0xec, 0x24, 0x03, 0x14, 0x6d, 0xad, 0x7e, 0xad, 0x7d, 0x15, 0x34, 0x9b,
0xcd, 0x60, 0x62, 0x72, 0x02, 0x50, 0x43, 0xa4, 0xcd, 0x31, 0xe7, 0x60, 0x7b, 0xce, 0x87, 0x14,
0x43, 0x38, 0x89, 0x35, 0x37, 0xb1, 0x1e, 0x48, 0x32, 0x78, 0xd8, 0xde, 0x76, 0x51, 0xa7, 0x7b,
0x17, 0x35, 0x99, 0x46, 0xe3, 0xb0, 0x67, 0x2b, 0x9f, 0xcf, 0xdf, 0x7e, 0x72, 0x0e, 0xe4, 0x28,
0x24, 0xfd, 0xaf, 0xd3, 0xc8, 0x22, 0x12, 0xb5, 0xb7, 0xc0, 0xa1, 0x91, 0xf0, 0x78, 0xbc, 0xec,
0xff, 0x19, 0x65, 0x96, 0x3f, 0xa1, 0x97, 0xae, 0x1c, 0xfc, 0x3f, 0x7e, 0xea, 0x00, 0x00, 0x00,
0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE tree_nosel_xpm[1] = {{ png, sizeof( png ), "tree_nosel_xpm" }};
//EOF
/* 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, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff,
0x61, 0x00, 0x00, 0x02, 0x4a, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x63, 0xf8, 0xff, 0xff, 0x3f,
0x03, 0x32, 0x9e, 0x37, 0xaf, 0x52, 0x74, 0xee, 0xdc, 0x1a, 0xf5, 0x99, 0x33, 0x1b, 0x44, 0xd0,
0xe5, 0xb0, 0x61, 0x38, 0x03, 0xa4, 0x69, 0xc1, 0xbc, 0xba, 0x65, 0x33, 0x56, 0x14, 0xbe, 0x9f,
0xb9, 0xac, 0xe8, 0xfd, 0xfc, 0x79, 0xb5, 0xaf, 0x80, 0x78, 0xc3, 0xbc, 0x79, 0x0d, 0x4a, 0x04,
0x0d, 0x98, 0x3f, 0xbf, 0x41, 0x01, 0xa8, 0xf9, 0x70, 0xc1, 0x61, 0xfb, 0x57, 0xee, 0x57, 0x84,
0x7f, 0xb9, 0x5c, 0x12, 0xfc, 0xed, 0x7d, 0x45, 0xec, 0x67, 0xd2, 0x19, 0xfd, 0x0f, 0xf3, 0xe6,
0xd5, 0x1e, 0xeb, 0xe9, 0x6b, 0x2e, 0x5d, 0xb0, 0x68, 0xde, 0xb1, 0xce, 0xce, 0xb6, 0x10, 0xac,
0x06, 0x2c, 0x98, 0x57, 0xdb, 0x1c, 0xb1, 0x4f, 0xf7, 0x85, 0xc9, 0x01, 0x8e, 0x3f, 0x1a, 0xbb,
0x19, 0xfe, 0xc3, 0xb0, 0xe9, 0x7e, 0xae, 0x3f, 0xb5, 0x4b, 0xd3, 0xdf, 0x9c, 0x3a, 0x7d, 0xe2,
0xe7, 0xee, 0x3d, 0xbb, 0x5e, 0x34, 0x37, 0xd7, 0x68, 0x82, 0xd4, 0x37, 0x34, 0x34, 0xf0, 0xc0,
0x0d, 0x98, 0x34, 0x29, 0x97, 0x7d, 0xf6, 0xfc, 0xca, 0x25, 0x56, 0x9b, 0x44, 0x3f, 0xa9, 0x6d,
0x62, 0xf8, 0x8f, 0x8e, 0x67, 0x6d, 0x9c, 0xf8, 0xe7, 0xed, 0xdb, 0xb7, 0xff, 0x17, 0x2f, 0x59,
0x78, 0x0c, 0xac, 0x81, 0x81, 0x81, 0x71, 0xf6, 0xdc, 0x59, 0xa7, 0xa6, 0x4c, 0x9b, 0x38, 0x0d,
0xcc, 0x07, 0x9a, 0xc6, 0x32, 0x67, 0x5e, 0x55, 0x9f, 0xfe, 0x02, 0xe1, 0x8f, 0x2a, 0x2b, 0x19,
0xfe, 0xa3, 0xe3, 0xfe, 0xa5, 0xed, 0xbf, 0x3f, 0x7c, 0xf8, 0xf0, 0x7f, 0xff, 0xfe, 0x7d, 0xaf,
0xa6, 0x4e, 0x9f, 0x3c, 0x7f, 0xf2, 0x94, 0x09, 0xbb, 0x2e, 0x5d, 0xba, 0xf8, 0x73, 0xc1, 0xc2,
0x79, 0xc7, 0xe1, 0x5e, 0x00, 0xfa, 0x33, 0xc5, 0xa4, 0x5b, 0xf9, 0xb2, 0xe2, 0x1c, 0x96, 0xbf,
0x4a, 0x0b, 0x19, 0xfe, 0xc3, 0xf1, 0x7c, 0xc6, 0xff, 0xe1, 0x5d, 0x7e, 0x2f, 0x6f, 0xdf, 0xbe,
0xfd, 0xf7, 0xd1, 0xa3, 0x47, 0xff, 0x5f, 0xbe, 0x7c, 0xf9, 0x1f, 0x44, 0x03, 0x0d, 0xf8, 0xdd,
0xdb, 0xdf, 0xdd, 0x8a, 0x12, 0x88, 0x93, 0x67, 0x94, 0x24, 0xca, 0x97, 0x4a, 0xde, 0x93, 0xe9,
0xe0, 0xf8, 0x25, 0xdb, 0xc7, 0xf2, 0x5f, 0xb6, 0x8b, 0xfd, 0xa7, 0x56, 0x99, 0xea, 0x8d, 0x35,
0xeb, 0x57, 0xbe, 0x7e, 0xf6, 0xec, 0xd9, 0xff, 0x3b, 0x77, 0xee, 0xfc, 0xdf, 0xba, 0x6d, 0xf3,
0xd3, 0xb5, 0xeb, 0x56, 0x5f, 0x9f, 0x30, 0xa9, 0xa7, 0x2b, 0x34, 0x34, 0x94, 0x19, 0x25, 0x1a,
0xe7, 0xcd, 0xab, 0x96, 0x6d, 0x99, 0x94, 0xe5, 0xeb, 0x55, 0xe8, 0x56, 0xa8, 0x9f, 0xa5, 0x3f,
0xd1, 0x28, 0xcb, 0xa8, 0x6f, 0xee, 0x82, 0x99, 0xe7, 0x1f, 0x3f, 0x7e, 0xfc, 0xff, 0xd5, 0xab,
0x57, 0xff, 0xb7, 0x6d, 0xdf, 0xfa, 0xb4, 0xa6, 0xb9, 0x46, 0x1d, 0x67, 0x3a, 0x00, 0xe1, 0x99,
0x33, 0xd3, 0x58, 0xe7, 0xcc, 0x69, 0x10, 0x5a, 0xb4, 0xa8, 0x41, 0x6c, 0xd2, 0xa4, 0x9e, 0xe6,
0xcb, 0x97, 0x2f, 0x7d, 0x03, 0x39, 0xfb, 0xc2, 0xc5, 0xf3, 0x1f, 0xfa, 0x26, 0xf6, 0xa6, 0xe2,
0x4d, 0x48, 0xc8, 0xb8, 0xa1, 0xb5, 0x41, 0x67, 0xd7, 0xae, 0x1d, 0xcf, 0x9f, 0x3c, 0x79, 0xf2,
0xff, 0xc1, 0x83, 0xfb, 0x7f, 0x66, 0xcf, 0x99, 0xbe, 0x92, 0x60, 0x4a, 0x84, 0xe1, 0xdc, 0xdc,
0x5c, 0xf6, 0xc5, 0x8b, 0x17, 0x5c, 0x06, 0xf9, 0x19, 0x64, 0xc0, 0x92, 0x65, 0x8b, 0x2e, 0x02,
0x63, 0x8a, 0x8d, 0x68, 0x03, 0xa6, 0x4c, 0x9b, 0xb4, 0xec, 0xc2, 0x85, 0xf3, 0x7f, 0xee, 0xdd,
0xbb, 0xf7, 0x7f, 0xcb, 0xd6, 0x4d, 0x8f, 0x1b, 0x1a, 0x2a, 0x14, 0x88, 0xca, 0x0b, 0x20, 0xdc,
0xdc, 0xdc, 0xe0, 0xb2, 0x7d, 0xfb, 0xd6, 0x4f, 0x67, 0xcf, 0x9e, 0xfd, 0x7f, 0xe8, 0xf0, 0xa1,
0x77, 0x3d, 0xfd, 0x9d, 0x31, 0x44, 0x67, 0x26, 0x10, 0x6e, 0xef, 0x6c, 0x2d, 0xda, 0xb3, 0x77,
0xcf, 0x9f, 0xfd, 0x07, 0xf6, 0xfd, 0x9a, 0x3e, 0x73, 0xca, 0x3c, 0x92, 0x72, 0x23, 0x34, 0x8d,
0x33, 0xf5, 0xf4, 0x75, 0xd5, 0xf7, 0x4d, 0xe8, 0x2e, 0x22, 0x46, 0x33, 0x08, 0x03, 0x00, 0xa3,
0x36, 0xa6, 0x81, 0xc6, 0x70, 0x96, 0x32, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE tree_sel_xpm[1] = {{ png, sizeof( png ), "tree_sel_xpm" }};
//EOF
/* 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, 0x04, 0x0b, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xbd, 0xd6, 0x5f, 0x4c, 0x53,
0x57, 0x1c, 0x07, 0xf0, 0x5b, 0x4a, 0x59, 0x41, 0x18, 0xcc, 0x44, 0xd4, 0x42, 0x81, 0xd2, 0xd6,
0x21, 0xd3, 0x0d, 0xc7, 0xc0, 0xc4, 0xd0, 0x0c, 0x1a, 0x61, 0xe8, 0x58, 0x04, 0x16, 0x15, 0x87,
0x32, 0x08, 0x43, 0x83, 0xcc, 0x4c, 0x37, 0x56, 0xa0, 0x02, 0x86, 0xe0, 0xa4, 0x30, 0x81, 0xc1,
0x1c, 0x6a, 0x41, 0xf9, 0x53, 0x6a, 0xe5, 0x6f, 0x0b, 0x88, 0x80, 0xe0, 0xda, 0x52, 0xda, 0x42,
0xf4, 0x61, 0xcf, 0x4b, 0x7c, 0x59, 0x32, 0x93, 0xbd, 0x2c, 0xf1, 0xdf, 0x93, 0x8c, 0xef, 0x7a,
0x6f, 0xd3, 0xd3, 0x15, 0xda, 0x72, 0xb7, 0x87, 0x3d, 0x7c, 0xdb, 0xdb, 0x7b, 0xcf, 0xf9, 0x7d,
0xee, 0x39, 0x3d, 0xf7, 0x0f, 0x05, 0x80, 0xfa, 0x3f, 0xc2, 0x7c, 0xc4, 0xbe, 0x1d, 0xf4, 0x4b,
0x94, 0x24, 0xe0, 0x35, 0x9d, 0xb4, 0x0c, 0xce, 0x6a, 0xe1, 0x29, 0xce, 0x5a, 0x45, 0x05, 0xb5,
0x76, 0xfe, 0x3c, 0x85, 0xa2, 0x62, 0xce, 0x5a, 0xd6, 0x61, 0xce, 0x5f, 0xd1, 0x52, 0xe7, 0xf1,
0xff, 0x90, 0x17, 0x04, 0x12, 0xef, 0x09, 0x7d, 0xd2, 0xa0, 0x56, 0xe1, 0x72, 0x6b, 0x2a, 0x6a,
0xaa, 0x29, 0xaf, 0x69, 0xb8, 0x22, 0x85, 0xfa, 0x7e, 0x3f, 0x7a, 0x8d, 0x73, 0xac, 0x73, 0x7d,
0x7a, 0x0c, 0x51, 0x52, 0xee, 0x6b, 0x0f, 0xe8, 0x92, 0x6a, 0x3d, 0xc2, 0xc1, 0xc5, 0xda, 0x10,
0x8f, 0x7d, 0x8d, 0xcd, 0x89, 0xd0, 0x2d, 0x5b, 0x70, 0x77, 0xc5, 0xca, 0x2a, 0x34, 0xe6, 0x01,
0xa5, 0x65, 0xf0, 0x9f, 0xba, 0x8a, 0x29, 0x6b, 0xb8, 0x68, 0xef, 0x2d, 0xc2, 0x80, 0x71, 0xd4,
0xd1, 0x78, 0x09, 0x3d, 0xd3, 0xd7, 0x50, 0xdf, 0x10, 0x49, 0x30, 0x65, 0xf7, 0x51, 0xd4, 0x4c,
0xb4, 0x42, 0x61, 0x68, 0xc1, 0x80, 0xed, 0xe7, 0x7f, 0x07, 0xe5, 0x1d, 0xe3, 0xfd, 0xe9, 0x2a,
0xa4, 0xea, 0x90, 0x6d, 0xe8, 0xd0, 0x35, 0x5c, 0x43, 0xa0, 0xfc, 0x2a, 0x0a, 0x5c, 0x85, 0x33,
0x1f, 0xb4, 0x1d, 0x80, 0x76, 0x79, 0x91, 0x3d, 0x54, 0x52, 0xca, 0x7d, 0xe5, 0x2a, 0x74, 0xd3,
0xd0, 0xb4, 0xa1, 0xc3, 0x1d, 0xc7, 0x99, 0x2b, 0x95, 0x3c, 0xe6, 0xf8, 0x99, 0x6a, 0x37, 0x44,
0x47, 0xf6, 0x63, 0x16, 0x74, 0x8e, 0x91, 0xb3, 0x82, 0x0a, 0x0a, 0x03, 0x9f, 0xb9, 0xa0, 0x1f,
0xfa, 0x4a, 0x36, 0x74, 0x18, 0x5c, 0x9c, 0x22, 0x23, 0x3a, 0xb9, 0x0e, 0xa2, 0x93, 0x7d, 0x33,
0x9f, 0x1d, 0x74, 0xf0, 0xd0, 0x1b, 0x7f, 0xd4, 0x56, 0x52, 0x68, 0xfa, 0x82, 0x83, 0xba, 0x4b,
0x6f, 0x41, 0x63, 0x9e, 0x20, 0x8d, 0x75, 0x76, 0x13, 0x5a, 0xba, 0xb2, 0x09, 0x54, 0xd6, 0x24,
0xc5, 0xc7, 0xea, 0x63, 0x4c, 0xc2, 0x6b, 0xc3, 0x09, 0xf6, 0xe9, 0xed, 0xe2, 0xcd, 0x21, 0xc9,
0xde, 0xd0, 0x27, 0x5a, 0xf9, 0x56, 0x98, 0xb7, 0x71, 0x61, 0xd8, 0xcb, 0x45, 0xc7, 0x09, 0x2e,
0x9a, 0x3b, 0xe5, 0x68, 0xeb, 0x39, 0x8e, 0xba, 0xfa, 0x70, 0xf7, 0x42, 0x70, 0x4c, 0x5f, 0xdf,
0x82, 0x96, 0x14, 0xba, 0x7a, 0xa7, 0x15, 0x29, 0xc5, 0x7c, 0x82, 0x15, 0x0d, 0x9e, 0xf3, 0x0f,
0xe5, 0x8a, 0x42, 0x7e, 0xb7, 0x08, 0x22, 0x61, 0x8e, 0x0c, 0x62, 0x30, 0x3a, 0x33, 0x62, 0x2e,
0x5a, 0x4a, 0x38, 0x1e, 0xcb, 0xbb, 0x53, 0x53, 0xce, 0x14, 0x98, 0xe8, 0xbe, 0x01, 0x53, 0xce,
0x61, 0x2c, 0x8b, 0xe2, 0x60, 0x16, 0xee, 0x40, 0xe1, 0x47, 0x3c, 0x06, 0x0a, 0x54, 0x70, 0x50,
0x3e, 0xa4, 0xf4, 0x0d, 0xc9, 0xa4, 0x21, 0xbf, 0x8d, 0xe6, 0xe5, 0xc0, 0x26, 0x15, 0xc3, 0xb2,
0x63, 0x0b, 0xc1, 0x4c, 0x91, 0x5c, 0xdc, 0xca, 0x0a, 0x40, 0x7d, 0x7d, 0x04, 0x6e, 0x8c, 0x37,
0x62, 0xb2, 0xb3, 0x1d, 0x66, 0x79, 0x3a, 0x03, 0xd0, 0x59, 0x4c, 0xff, 0x10, 0xe3, 0x43, 0x5a,
0x5c, 0x18, 0x6b, 0x44, 0x60, 0x55, 0x00, 0x83, 0xf1, 0x1c, 0xdf, 0x95, 0xfa, 0x2b, 0xde, 0x21,
0xfa, 0x82, 0x6d, 0x1e, 0x54, 0x63, 0x78, 0x61, 0x0e, 0x33, 0xca, 0x2a, 0x2c, 0xbd, 0x93, 0x00,
0xab, 0x70, 0x3b, 0xac, 0xd1, 0xdb, 0x60, 0x8b, 0x11, 0xc0, 0x94, 0x99, 0x81, 0x87, 0xc7, 0x8f,
0x12, 0xc0, 0x2e, 0x11, 0x63, 0x56, 0xf1, 0x0d, 0x86, 0x6c, 0xee, 0xa5, 0x7d, 0xfa, 0xae, 0x82,
0x4c, 0x21, 0xbf, 0x9a, 0x87, 0xba, 0xa9, 0x0e, 0xdf, 0x90, 0xab, 0xd3, 0xc8, 0x83, 0xfb, 0xee,
0xc2, 0x31, 0x42, 0x3c, 0x0a, 0x0b, 0x73, 0x24, 0x14, 0xcb, 0xb1, 0x31, 0x58, 0x7a, 0x7f, 0x1f,
0xc6, 0x47, 0x74, 0x5e, 0x57, 0xd9, 0x89, 0xfe, 0x33, 0x04, 0xdb, 0xa2, 0x0c, 0x46, 0xbd, 0xa1,
0xd3, 0x3f, 0xe4, 0xca, 0x6c, 0xe5, 0xd7, 0x0c, 0xf2, 0x98, 0xcf, 0x67, 0xf2, 0x28, 0x22, 0x02,
0xfa, 0x81, 0x5e, 0xbf, 0x77, 0x83, 0x4f, 0xba, 0x0b, 0x08, 0xf6, 0xe6, 0xc5, 0x30, 0x6c, 0x4f,
0x0e, 0x58, 0xf5, 0x0b, 0xdd, 0x53, 0x7d, 0x07, 0xbb, 0x54, 0x82, 0x95, 0xe8, 0x28, 0x3c, 0x0e,
0x09, 0x61, 0xb2, 0x22, 0x8c, 0x86, 0xf9, 0xa0, 0x1c, 0x43, 0x56, 0xb3, 0x4f, 0x88, 0xbe, 0x78,
0xd3, 0x7f, 0x3a, 0x44, 0xb0, 0xa0, 0x2f, 0x69, 0xc2, 0x07, 0x34, 0x79, 0xad, 0xc3, 0x31, 0x6d,
0x22, 0xf7, 0x7f, 0xe2, 0x00, 0xed, 0x12, 0x09, 0xf9, 0x3d, 0x5f, 0x56, 0xea, 0x77, 0x54, 0xf4,
0x6d, 0x29, 0xa5, 0x3d, 0xcd, 0x89, 0x55, 0xfa, 0x80, 0xe8, 0xf9, 0xb7, 0xed, 0x4e, 0x20, 0x45,
0x6d, 0x89, 0xbb, 0x31, 0xae, 0xd3, 0x40, 0xaf, 0xed, 0x67, 0xb6, 0x5d, 0xfb, 0xa7, 0xda, 0xbe,
0xf7, 0x8b, 0x69, 0x6c, 0x46, 0x24, 0xaa, 0xde, 0x05, 0xf7, 0x5b, 0x2f, 0x10, 0xbd, 0xea, 0x96,
0x52, 0x53, 0x48, 0x31, 0x3a, 0xf7, 0xae, 0x36, 0x93, 0xce, 0x7a, 0x4d, 0x1f, 0x39, 0x09, 0x6b,
0xd2, 0x7b, 0x18, 0x36, 0x2d, 0xf8, 0xc5, 0xba, 0xe6, 0xf5, 0xe0, 0x9f, 0xe6, 0xac, 0x6d, 0x80,
0x16, 0x8a, 0x8b, 0x3c, 0x10, 0x63, 0xee, 0x91, 0x0d, 0x9d, 0x0d, 0xbd, 0x3d, 0xb0, 0xc7, 0x3b,
0xa7, 0x75, 0xee, 0xdc, 0xd9, 0x4d, 0x1f, 0x13, 0x3b, 0xf7, 0xac, 0x5b, 0x75, 0xd7, 0x2f, 0xd7,
0x7a, 0xfc, 0x2f, 0xf4, 0x99, 0x8f, 0x4e, 0x4f, 0x7a, 0x2d, 0xf0, 0xa0, 0xa2, 0x9c, 0x5c, 0x4f,
0x63, 0x86, 0x51, 0xf6, 0x8f, 0x09, 0xa9, 0x03, 0x9a, 0x4b, 0x4e, 0xf2, 0x18, 0xcd, 0x4c, 0xb5,
0xc2, 0x67, 0x81, 0xa1, 0x45, 0x23, 0x2c, 0xfb, 0x53, 0x9d, 0xa3, 0xce, 0x3b, 0xc2, 0x1e, 0xca,
0x8f, 0x0b, 0x7e, 0x6a, 0x89, 0x12, 0xfc, 0x63, 0x01, 0x24, 0x62, 0xd8, 0x38, 0xef, 0x77, 0x5a,
0x0c, 0xb7, 0xd4, 0xa4, 0xbd, 0xbe, 0xff, 0x36, 0x3b, 0x88, 0x9e, 0xba, 0x81, 0xb3, 0xa5, 0xb0,
0x8b, 0xe3, 0x99, 0x8e, 0xb3, 0x17, 0xbe, 0x62, 0xf5, 0x4e, 0xb0, 0xf0, 0xf9, 0x29, 0xa6, 0xfd,
0xc3, 0xcf, 0x0a, 0xd8, 0x41, 0xa2, 0xc4, 0xe0, 0x5f, 0x93, 0x64, 0xb1, 0x2f, 0x4f, 0xa6, 0xc4,
0xbe, 0x1c, 0xd9, 0x1a, 0xba, 0x2a, 0x4f, 0xdf, 0xf5, 0x7c, 0x7f, 0x66, 0xc2, 0xb3, 0xcd, 0x92,
0x2d, 0x93, 0xbc, 0xa0, 0xdb, 0x97, 0xed, 0x13, 0xbe, 0xf2, 0x76, 0x3c, 0x55, 0xbe, 0xeb, 0x39,
0xfd, 0xca, 0x45, 0x20, 0x81, 0x98, 0x3a, 0xb0, 0x53, 0x4c, 0x65, 0xd3, 0x49, 0x8e, 0xa3, 0x72,
0x5d, 0xdb, 0x6c, 0x22, 0x8d, 0xa7, 0x72, 0xfc, 0x1d, 0x17, 0x88, 0xa8, 0x4c, 0xda, 0xf8, 0x1b,
0x60, 0x76, 0x60, 0xa1, 0x4e, 0x22, 0xae, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44,
0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE add_keepout_area_xpm[1] = {{ png, sizeof( png ), "add_keepout_area_xpm" }};
//EOF
/* 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, 0x05, 0x39, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xbd, 0x96, 0x7b, 0x4c, 0x53,
0x57, 0x1c, 0xc7, 0x71, 0x80, 0x20, 0x2c, 0xf3, 0x3d, 0x61, 0x20, 0x28, 0xe8, 0xa6, 0x6e, 0x6c,
0x73, 0x31, 0x8b, 0x0b, 0x7b, 0x28, 0x3e, 0x82, 0x4b, 0x96, 0xfd, 0xb1, 0xb9, 0x30, 0xb3, 0xb9,
0xb9, 0x87, 0x9a, 0x65, 0x4e, 0x54, 0x14, 0xa1, 0xb7, 0xf5, 0xd2, 0x96, 0xb6, 0x14, 0x2a, 0xd1,
0x81, 0x58, 0x68, 0xef, 0x6d, 0xe9, 0x40, 0x29, 0xaf, 0xa1, 0x08, 0x91, 0xc7, 0x98, 0x4f, 0x8c,
0x0e, 0xc9, 0x14, 0xb0, 0x16, 0xa4, 0x22, 0xb6, 0x80, 0xa0, 0xd0, 0x27, 0x4f, 0xf9, 0xed, 0x9c,
0xe6, 0x62, 0xee, 0x98, 0x14, 0x96, 0x99, 0xfd, 0xf1, 0xcd, 0xed, 0x4d, 0x7f, 0xe7, 0xf7, 0x39,
0xf7, 0xf7, 0x3a, 0xc7, 0x0d, 0x00, 0xdc, 0xfe, 0x0f, 0x4d, 0xf8, 0x07, 0x4d, 0x93, 0x8b, 0x68,
0x25, 0xf1, 0x3d, 0x4d, 0x73, 0xf7, 0xd2, 0x34, 0x71, 0x48, 0x45, 0xf1, 0xb6, 0x51, 0x54, 0xdc,
0xfc, 0x67, 0x06, 0xd2, 0x28, 0x89, 0x57, 0x28, 0x8a, 0x2b, 0x57, 0x51, 0xdc, 0x6e, 0x9a, 0xe2,
0xf6, 0x22, 0x3d, 0x62, 0xa9, 0x07, 0x81, 0x4b, 0xd1, 0x26, 0x96, 0xfd, 0x27, 0x10, 0x72, 0xf0,
0x26, 0x02, 0x34, 0xa9, 0x15, 0x44, 0xdb, 0x79, 0xe9, 0x8e, 0x9e, 0x07, 0x7b, 0x22, 0x87, 0xcd,
0x3f, 0x6d, 0x18, 0xb5, 0x20, 0x75, 0xed, 0xd9, 0x34, 0x74, 0x4d, 0xf8, 0x55, 0xef, 0x2f, 0x59,
0x71, 0x6d, 0x08, 0xd8, 0xa0, 0xa6, 0x88, 0xf5, 0xec, 0xb5, 0x71, 0x64, 0xdc, 0x0a, 0x0e, 0x19,
0xfb, 0xfe, 0xa4, 0x20, 0x95, 0x8a, 0x08, 0x45, 0x0e, 0xce, 0xe7, 0x1c, 0x8f, 0x6d, 0x34, 0xec,
0x5c, 0x3f, 0xd8, 0xf9, 0xc9, 0xca, 0x11, 0x73, 0xd8, 0x2c, 0xb0, 0x86, 0x4c, 0x07, 0xeb, 0x62,
0x4f, 0x30, 0x87, 0xcd, 0x84, 0x07, 0x1f, 0x2e, 0x1b, 0x35, 0xec, 0x88, 0x18, 0x2a, 0x48, 0x8f,
0x69, 0xa2, 0x29, 0x5e, 0x7d, 0xb6, 0x92, 0x5c, 0x25, 0x14, 0x91, 0x3c, 0x89, 0x34, 0xd1, 0x9c,
0xad, 0x51, 0x99, 0x8f, 0xcb, 0x8f, 0xd9, 0xb9, 0x24, 0x67, 0xaf, 0x4b, 0x10, 0xad, 0xe4, 0xca,
0xd4, 0x59, 0xf1, 0x17, 0x6f, 0x6c, 0xfb, 0xc0, 0xd1, 0x1e, 0x1e, 0x38, 0xda, 0xb3, 0xc8, 0x13,
0x9e, 0x26, 0xe3, 0xaa, 0x05, 0xd0, 0xb8, 0x35, 0x7c, 0x48, 0xad, 0xe0, 0x5c, 0x48, 0x91, 0x91,
0x8d, 0x05, 0x45, 0xf9, 0x8e, 0xf6, 0xf6, 0x76, 0xd0, 0xdd, 0xd6, 0x81, 0x2c, 0x35, 0xb9, 0x8f,
0x20, 0x0e, 0x2c, 0x9f, 0x10, 0xa4, 0x50, 0x90, 0x73, 0x50, 0x5e, 0x4a, 0x4e, 0xf1, 0xbe, 0xac,
0xbb, 0xb9, 0x61, 0xd9, 0x90, 0x31, 0x18, 0x39, 0x74, 0xa1, 0x9b, 0x11, 0x4b, 0x46, 0xb4, 0xfb,
0xb7, 0x18, 0xd4, 0xd9, 0xca, 0x91, 0xde, 0xde, 0x5e, 0xc0, 0xa0, 0xb4, 0xf4, 0xa3, 0x76, 0x1e,
0x2f, 0x7e, 0x83, 0xcb, 0xd0, 0xa9, 0x94, 0xc4, 0x46, 0x14, 0xb6, 0x9c, 0xca, 0x4f, 0x57, 0x77,
0x35, 0xad, 0x98, 0x09, 0x86, 0x20, 0x8f, 0x27, 0x6a, 0x7d, 0x8a, 0x6e, 0x2f, 0xf5, 0x05, 0x6a,
0x67, 0xd4, 0xc0, 0xf5, 0xfa, 0xba, 0xc7, 0x7d, 0x7d, 0x7d, 0x70, 0xe7, 0x4e, 0x0b, 0x08, 0x45,
0x09, 0xf5, 0xe3, 0x9d, 0x93, 0x7c, 0xee, 0x11, 0x04, 0xdf, 0xf4, 0x04, 0x44, 0x51, 0x44, 0x04,
0x2a, 0xdf, 0x63, 0xa7, 0x37, 0x86, 0x3d, 0xba, 0x11, 0xe2, 0x03, 0xba, 0x40, 0x0f, 0x97, 0x6a,
0x0c, 0xf6, 0x82, 0xb4, 0xdd, 0xdf, 0x8e, 0xe8, 0xf5, 0x3a, 0xc0, 0xa0, 0xe6, 0xe6, 0x66, 0x10,
0x24, 0x92, 0x37, 0xdd, 0xdc, 0xdc, 0xa6, 0x8d, 0x41, 0x12, 0x04, 0xbc, 0xd8, 0xdc, 0x13, 0x39,
0xb6, 0x24, 0xa9, 0x78, 0x80, 0x05, 0x22, 0xdf, 0x42, 0x65, 0x2b, 0xce, 0x8d, 0x58, 0x6e, 0xbc,
0xbc, 0xd8, 0x17, 0xfe, 0x0c, 0xf0, 0x70, 0xa9, 0xab, 0xc1, 0xde, 0x20, 0xff, 0xf8, 0x3d, 0xeb,
0x99, 0xb2, 0x92, 0x21, 0x8b, 0xc5, 0x02, 0x46, 0xa3, 0x11, 0x4a, 0x4e, 0x15, 0xdb, 0x85, 0xe2,
0x84, 0x53, 0x1c, 0x92, 0xb3, 0x1a, 0x7d, 0xc5, 0x3e, 0x79, 0x66, 0x86, 0xe5, 0xfe, 0xfd, 0xfb,
0x70, 0x38, 0x35, 0xd9, 0xb1, 0x79, 0xf3, 0x66, 0x77, 0x27, 0x48, 0xad, 0xe6, 0x04, 0xa0, 0x62,
0x38, 0x98, 0x19, 0xb5, 0xb6, 0x24, 0x77, 0xf9, 0xbc, 0xc1, 0x6b, 0x2f, 0xb9, 0x03, 0xd6, 0xd5,
0x09, 0x54, 0xb4, 0x74, 0xd6, 0x70, 0x5a, 0xd4, 0xba, 0x1a, 0x89, 0x54, 0xf4, 0x18, 0x83, 0x4c,
0x26, 0x13, 0xb4, 0xb6, 0xb6, 0xc2, 0xa5, 0x4b, 0x17, 0x06, 0x0a, 0x8a, 0xf3, 0xcd, 0x55, 0x55,
0x15, 0xfd, 0xfa, 0x66, 0x3d, 0xb4, 0xb5, 0xb5, 0x81, 0x48, 0x22, 0x70, 0x6c, 0xdf, 0xbe, 0xdd,
0x93, 0xd5, 0x43, 0xbc, 0x8f, 0x14, 0x19, 0x07, 0x7e, 0x4c, 0x79, 0xf9, 0xc5, 0xbe, 0x92, 0x40,
0xef, 0xd1, 0x8b, 0xfe, 0xee, 0x30, 0x5e, 0x17, 0x90, 0x4e, 0x07, 0x78, 0x81, 0xf4, 0xb5, 0x85,
0xb6, 0xa4, 0x24, 0xc1, 0xa3, 0x5b, 0xb7, 0x9a, 0x9c, 0xa0, 0x8e, 0x8e, 0x0e, 0x67, 0xf8, 0xcc,
0x66, 0x33, 0x74, 0x76, 0x76, 0xa2, 0x9c, 0xdd, 0x01, 0x83, 0xc1, 0x00, 0x95, 0x95, 0x67, 0x07,
0xf8, 0xc2, 0x43, 0xe9, 0x7f, 0x2b, 0x6f, 0xb5, 0x5a, 0x34, 0x17, 0x85, 0x6f, 0xcb, 0xcf, 0xfb,
0xbf, 0xd8, 0x4d, 0x06, 0xcd, 0xee, 0x91, 0xfb, 0xcf, 0x18, 0x3e, 0xe3, 0xe7, 0x01, 0xd5, 0x7e,
0xee, 0x4e, 0x95, 0xa3, 0xdf, 0x72, 0x7f, 0x9f, 0x61, 0x5e, 0xf0, 0x5c, 0x8b, 0x58, 0x44, 0x9a,
0xea, 0xeb, 0xaf, 0x8f, 0x0c, 0x0e, 0x0e, 0xc2, 0x18, 0xa8, 0xa5, 0xa5, 0x05, 0x4c, 0x1d, 0x26,
0xb8, 0x77, 0xef, 0x1e, 0xe8, 0x74, 0x3a, 0x28, 0xfe, 0xb5, 0xd0, 0xce, 0x4f, 0x24, 0x9b, 0x63,
0x62, 0x62, 0x7c, 0x9f, 0x36, 0x19, 0xfc, 0x68, 0x05, 0x11, 0x99, 0xc1, 0xdf, 0xf9, 0x59, 0xdc,
0xab, 0x41, 0xf9, 0xfb, 0xe6, 0xfa, 0xf4, 0xec, 0x9d, 0xed, 0xe5, 0x88, 0x9e, 0xe5, 0x35, 0x10,
0x8d, 0x9e, 0xfc, 0x77, 0xdf, 0xa8, 0x12, 0x27, 0xf2, 0x74, 0xb5, 0xb5, 0x97, 0x86, 0xfb, 0xfb,
0xfb, 0x01, 0x83, 0xac, 0x56, 0xab, 0xb3, 0xbc, 0xb3, 0x94, 0x99, 0xd6, 0x94, 0xc3, 0xd2, 0x5b,
0xd2, 0x14, 0x49, 0x8b, 0x24, 0x29, 0xb1, 0x39, 0x51, 0xcc, 0xff, 0x06, 0xe7, 0x66, 0xc2, 0x59,
0x97, 0x9d, 0x1d, 0xe3, 0xab, 0x50, 0x70, 0x57, 0xaa, 0x54, 0xdc, 0x70, 0xac, 0x23, 0xc4, 0xd7,
0x91, 0x59, 0xa9, 0xd1, 0x6b, 0x34, 0x1a, 0xc1, 0x9a, 0x64, 0x99, 0xe8, 0x8f, 0xdf, 0x7e, 0xaf,
0x1e, 0xb4, 0xdb, 0xed, 0xe0, 0x70, 0x38, 0x9c, 0xa0, 0x87, 0x0f, 0x1f, 0x02, 0x45, 0x2b, 0xec,
0x85, 0xc5, 0xf9, 0x02, 0xb4, 0x7e, 0x1e, 0xe3, 0x07, 0x57, 0x5f, 0xc8, 0x94, 0xa6, 0xb7, 0x56,
0x4b, 0x4e, 0x97, 0xcb, 0xc9, 0x79, 0x57, 0xae, 0x94, 0xbf, 0xde, 0xd8, 0x78, 0xf9, 0x6d, 0xd9,
0xe1, 0xa4, 0xf2, 0xf2, 0xf2, 0x33, 0xfd, 0x38, 0x0f, 0x36, 0x9b, 0xcd, 0x09, 0xb2, 0x58, 0xcc,
0x90, 0xad, 0xa1, 0xac, 0xbc, 0x04, 0xce, 0xe7, 0x8c, 0xf3, 0x75, 0x2c, 0x1f, 0x78, 0xd2, 0x2f,
0x61, 0x80, 0x2f, 0x4c, 0x65, 0xf2, 0x2e, 0xe5, 0x0b, 0xc9, 0xd4, 0xe2, 0x92, 0x22, 0x7b, 0x57,
0x57, 0x97, 0xb3, 0x6f, 0x30, 0x08, 0x3f, 0x35, 0x39, 0x6a, 0x1b, 0x6a, 0xca, 0xad, 0x2c, 0xdb,
0xb5, 0x48, 0xee, 0xac, 0x77, 0x0c, 0x7f, 0x1e, 0xc3, 0x26, 0x05, 0xc9, 0x52, 0xa5, 0x49, 0x79,
0xda, 0x13, 0x0e, 0x9c, 0x64, 0x0c, 0xc2, 0x23, 0x07, 0xeb, 0x64, 0x5e, 0x0e, 0x4e, 0xf6, 0x77,
0xe3, 0xec, 0xd9, 0x13, 0x3d, 0x10, 0x29, 0x98, 0xf9, 0x32, 0x4f, 0x97, 0x10, 0xb4, 0xdb, 0x1f,
0xd4, 0x1a, 0x95, 0x1d, 0x97, 0x2e, 0x06, 0xe1, 0xd2, 0xed, 0xee, 0xee, 0x86, 0x13, 0x79, 0xb9,
0x36, 0xb5, 0x86, 0x96, 0x21, 0x9b, 0x70, 0xa4, 0x19, 0x48, 0x41, 0x48, 0x91, 0x48, 0x0b, 0x58,
0xeb, 0x43, 0xa7, 0x94, 0x23, 0x2e, 0x19, 0x1f, 0xa5, 0xa4, 0xb2, 0x6c, 0x0d, 0x0d, 0x0d, 0x30,
0x06, 0x32, 0x9a, 0x8c, 0x90, 0xa7, 0x3d, 0x69, 0x43, 0xa1, 0x8c, 0x66, 0xec, 0xbc, 0x91, 0xde,
0x61, 0x72, 0xc1, 0x5e, 0x8f, 0xe1, 0x0b, 0x27, 0x05, 0x11, 0xe4, 0xc1, 0xc8, 0xe3, 0x99, 0xe9,
0xb6, 0xba, 0xba, 0x3a, 0x18, 0x03, 0xdd, 0xbd, 0x7b, 0x17, 0xf2, 0x0b, 0xb5, 0x0e, 0x04, 0x39,
0x80, 0x6c, 0x9e, 0x73, 0x11, 0x09, 0x1f, 0xe6, 0x89, 0xe1, 0x5e, 0x13, 0x82, 0xb8, 0xdc, 0xd8,
0xb0, 0xb4, 0x63, 0x47, 0xad, 0xb5, 0xb5, 0xb5, 0x30, 0x06, 0xd2, 0xeb, 0xf5, 0x50, 0x88, 0xce,
0x1d, 0x91, 0x84, 0x9f, 0x80, 0x6c, 0xf0, 0x31, 0xbe, 0x98, 0xa9, 0x26, 0x3f, 0x26, 0xe1, 0xee,
0x4c, 0x3e, 0xb0, 0xf3, 0x00, 0xc6, 0x66, 0x3e, 0xbb, 0xc4, 0xff, 0x01, 0xe2, 0x0b, 0x0e, 0xe5,
0x54, 0x57, 0x57, 0x8e, 0x96, 0x96, 0x96, 0x42, 0x4d, 0x4d, 0x8d, 0x13, 0x84, 0x7a, 0xc4, 0x26,
0x91, 0x0a, 0xc5, 0x0c, 0x60, 0x1a, 0xcb, 0x7e, 0x0e, 0xd3, 0x3b, 0x0b, 0x99, 0x30, 0xb2, 0x7d,
0x2d, 0x70, 0x19, 0x3a, 0x54, 0x49, 0x74, 0x45, 0xc5, 0xd9, 0xc7, 0x65, 0x65, 0x65, 0x70, 0xee,
0xdc, 0x39, 0x04, 0x29, 0xb0, 0xa3, 0x70, 0x25, 0x4f, 0x10, 0xa6, 0xb1, 0xc6, 0x0c, 0xfd, 0xd7,
0xb7, 0x20, 0x92, 0x3c, 0xb8, 0x24, 0x59, 0x26, 0xb6, 0x16, 0x14, 0x68, 0xad, 0x19, 0xf2, 0x74,
0x2b, 0x3a, 0x57, 0x38, 0x93, 0x38, 0xf1, 0x1f, 0xbf, 0xfb, 0x29, 0xdf, 0xeb, 0x76, 0xed, 0xda,
0xe5, 0x85, 0x0a, 0x62, 0x7d, 0x7c, 0x7c, 0xbc, 0xff, 0xb3, 0xba, 0x40, 0xfe, 0x05, 0xa3, 0x0e,
0x44, 0xc1, 0xe1, 0x8b, 0x0f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
0x60, 0x82,
};
const BITMAP_OPAQUE tree_nosel_xpm[1] = {{ png, sizeof( png ), "tree_nosel_xpm" }};
//EOF
/* 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, 0x04, 0x83, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xbd, 0x96, 0x7b, 0x4c, 0x5b,
0x75, 0x14, 0xc7, 0x2f, 0x8f, 0x6c, 0xea, 0x5c, 0x9c, 0x65, 0x4c, 0x98, 0xa0, 0x22, 0x2e, 0x28,
0x53, 0x8c, 0x9b, 0xba, 0xcd, 0x10, 0x13, 0x67, 0xcc, 0x36, 0x1d, 0x71, 0x92, 0xe0, 0xe3, 0x9f,
0x65, 0x71, 0x11, 0x13, 0x32, 0xa2, 0x8b, 0x90, 0x42, 0xdb, 0x5b, 0x7e, 0x40, 0x4b, 0x69, 0x79,
0x8f, 0x81, 0x1b, 0xa5, 0xf7, 0xb6, 0x8d, 0x80, 0xbc, 0x84, 0x86, 0xcd, 0x61, 0xa1, 0x10, 0x60,
0x66, 0x93, 0x8d, 0x42, 0x99, 0x19, 0x30, 0x28, 0x8f, 0x8e, 0x95, 0x16, 0xcb, 0x08, 0xe5, 0xe1,
0x18, 0x2d, 0xc7, 0xdf, 0xaf, 0xc4, 0x05, 0xe6, 0xc0, 0x09, 0xcc, 0x3f, 0xbe, 0xb9, 0xe9, 0x6d,
0x7b, 0x3e, 0x39, 0xe7, 0x7b, 0xce, 0xf9, 0xfd, 0x28, 0x00, 0xa0, 0xfe, 0x0f, 0x2d, 0xfb, 0x05,
0xc3, 0x08, 0xf6, 0x33, 0x8c, 0x30, 0x05, 0x3f, 0xf3, 0x59, 0x86, 0x2e, 0x62, 0x59, 0x41, 0x82,
0xba, 0x10, 0xbd, 0xba, 0x6e, 0x20, 0x02, 0x60, 0x59, 0xfa, 0x17, 0x1c, 0xdc, 0x26, 0x57, 0xc7,
0x8f, 0xe5, 0x97, 0x7d, 0x73, 0xfb, 0x54, 0x55, 0xd4, 0x38, 0xc3, 0x0a, 0x6c, 0xe4, 0x1d, 0xcb,
0x08, 0x7f, 0x55, 0x2a, 0xe9, 0x9d, 0x6b, 0x02, 0x61, 0xc8, 0x61, 0x1c, 0xac, 0x2f, 0xb7, 0x22,
0xca, 0x14, 0x79, 0xfd, 0xb5, 0xa9, 0x70, 0xdb, 0x16, 0xe7, 0x11, 0x33, 0xc7, 0xf1, 0xf1, 0x2d,
0x8e, 0x23, 0xfc, 0x0f, 0x8e, 0xf3, 0x2b, 0xfc, 0x2e, 0xbf, 0xe4, 0xe4, 0x20, 0xa3, 0x10, 0x5c,
0x63, 0x59, 0x74, 0x90, 0xfc, 0x07, 0xa1, 0x58, 0x1f, 0x01, 0x8a, 0x0f, 0x47, 0x08, 0x79, 0x3e,
0x14, 0x88, 0x61, 0xf8, 0xef, 0x28, 0x19, 0xc1, 0x15, 0x69, 0xd5, 0xb1, 0x1b, 0x1f, 0x19, 0x39,
0x8e, 0x3d, 0xfa, 0x8d, 0xf3, 0xc1, 0xcd, 0x14, 0xbc, 0xd2, 0xb4, 0xa0, 0xe0, 0x66, 0x37, 0xd8,
0xdb, 0xbe, 0x71, 0x3e, 0xec, 0x86, 0xf7, 0x5c, 0x66, 0x65, 0xe4, 0x75, 0xb9, 0x5c, 0xd0, 0x29,
0x91, 0x26, 0xb7, 0x9d, 0x29, 0xc8, 0xb7, 0x97, 0x57, 0x96, 0xde, 0x41, 0xc9, 0x74, 0xcd, 0x43,
0x81, 0x94, 0x0c, 0x2d, 0x3f, 0x55, 0x14, 0x7d, 0xe9, 0x03, 0xbd, 0xd7, 0x5c, 0x48, 0x93, 0x07,
0xbc, 0x5c, 0x4f, 0x2d, 0x55, 0xdd, 0x82, 0x5e, 0x6f, 0xf2, 0x84, 0x43, 0x97, 0x9f, 0x9d, 0x4d,
0xcf, 0x4a, 0x99, 0xe9, 0x30, 0xb4, 0xcf, 0x9b, 0x4c, 0x26, 0x60, 0xd8, 0x42, 0x3b, 0x1f, 0xf1,
0xdf, 0xfc, 0x57, 0x90, 0x5c, 0x8e, 0xfc, 0x18, 0x86, 0xd6, 0x1c, 0xaf, 0x09, 0xed, 0xde, 0x55,
0xff, 0x84, 0x33, 0xe8, 0x67, 0x0a, 0x56, 0xd2, 0x71, 0xe6, 0x88, 0xf3, 0xb7, 0xd6, 0x4b, 0xf3,
0xa3, 0xa3, 0xa3, 0x70, 0xf1, 0x62, 0x8b, 0x43, 0x24, 0x46, 0x67, 0x17, 0x07, 0xe5, 0x72, 0xb9,
0x4f, 0xa1, 0x44, 0x41, 0x31, 0x42, 0x71, 0x2f, 0x2c, 0x01, 0xe1, 0x8e, 0xfa, 0x90, 0x55, 0x08,
0xd4, 0xa1, 0xd5, 0xbe, 0xf6, 0x20, 0x8d, 0x07, 0xec, 0xd0, 0x50, 0x2b, 0xea, 0xe4, 0xe9, 0x48,
0x30, 0x9b, 0xcd, 0x60, 0xb3, 0xd9, 0xa0, 0xb9, 0xa5, 0xc9, 0x49, 0xd3, 0x71, 0x27, 0x16, 0x83,
0x92, 0x44, 0xa8, 0xe2, 0xdc, 0xf9, 0x1a, 0x87, 0x44, 0x2a, 0x6a, 0x59, 0x02, 0x52, 0x29, 0x84,
0xef, 0xe1, 0xd2, 0xe5, 0xee, 0x56, 0xfb, 0xd8, 0x77, 0x94, 0xbb, 0xc3, 0x4b, 0x15, 0xd4, 0xf2,
0x2a, 0xa7, 0x20, 0x36, 0xeb, 0x04, 0x98, 0x47, 0xcc, 0x30, 0x3e, 0x3e, 0x0e, 0x9d, 0xd7, 0x0c,
0x20, 0x96, 0x24, 0x19, 0x69, 0x9a, 0xbb, 0x33, 0x22, 0x22, 0xc2, 0x83, 0x46, 0xbc, 0x63, 0x4a,
0x35, 0x6b, 0x1f, 0x1e, 0x1e, 0x86, 0x54, 0x59, 0x8a, 0x6d, 0x09, 0x08, 0xb7, 0xeb, 0x6e, 0x3c,
0x33, 0xa2, 0x5d, 0x79, 0xfe, 0xe6, 0x40, 0xb5, 0x27, 0x04, 0x96, 0x50, 0x10, 0x58, 0xbc, 0xbc,
0x42, 0xf3, 0x82, 0xa0, 0xac, 0xfa, 0x47, 0xa7, 0xdd, 0x6e, 0x87, 0x91, 0x91, 0x11, 0xe8, 0xec,
0x34, 0x60, 0x9f, 0xe4, 0x13, 0x99, 0xd9, 0x19, 0x13, 0x15, 0x95, 0xa5, 0x13, 0xdd, 0x3d, 0xdd,
0x30, 0x30, 0x30, 0x00, 0x12, 0xa9, 0xf8, 0xf6, 0x7d, 0xa5, 0x43, 0x3e, 0xb8, 0x74, 0xb1, 0x9f,
0x65, 0xef, 0x2f, 0x09, 0x48, 0xdb, 0x72, 0xe7, 0x45, 0x15, 0x05, 0x2b, 0x29, 0x40, 0xea, 0x35,
0x93, 0x2c, 0x41, 0xd3, 0x56, 0xab, 0x05, 0xac, 0x56, 0x2b, 0x18, 0x8d, 0x46, 0x18, 0x1b, 0x1b,
0x03, 0xe2, 0xd9, 0xe0, 0xe0, 0x20, 0xf4, 0xf7, 0xf7, 0x43, 0x63, 0xa3, 0x6e, 0x2e, 0x49, 0x94,
0x20, 0xfd, 0x47, 0xd7, 0x61, 0x9f, 0x0e, 0x32, 0x85, 0x82, 0xaf, 0x9f, 0x8f, 0xf3, 0xb5, 0xf8,
0xa7, 0x3f, 0xee, 0x08, 0x28, 0xc4, 0x01, 0x1f, 0x20, 0x3f, 0xf1, 0xe6, 0xd9, 0x4f, 0x84, 0x61,
0x96, 0x0b, 0xb5, 0xe7, 0x67, 0x49, 0xe0, 0xde, 0xde, 0x5e, 0x57, 0x70, 0xe2, 0x19, 0xf9, 0xdc,
0xd7, 0xd7, 0x0b, 0xd5, 0x9a, 0x9f, 0xa6, 0x71, 0x39, 0x3b, 0xf1, 0x6c, 0x71, 0x1e, 0x00, 0x42,
0x5b, 0x58, 0x56, 0x18, 0x21, 0x3e, 0x1d, 0xfd, 0xa5, 0x6f, 0x94, 0x9f, 0x71, 0x5b, 0xcc, 0xd3,
0x7f, 0x6e, 0x97, 0x6e, 0x80, 0xe7, 0x72, 0xdd, 0xc0, 0x3f, 0xdb, 0x1d, 0xb6, 0xa7, 0x6e, 0x80,
0xad, 0xd1, 0x5e, 0xd3, 0x21, 0xd1, 0x21, 0x83, 0xdf, 0x17, 0xe4, 0x4d, 0x93, 0x0c, 0x2c, 0x16,
0x0b, 0x74, 0x77, 0x77, 0xbb, 0x82, 0xcb, 0x15, 0x67, 0xa7, 0x72, 0x72, 0x32, 0x2d, 0xb2, 0x34,
0x89, 0x01, 0x37, 0xc3, 0xb7, 0x14, 0x45, 0xb9, 0x2d, 0xbb, 0x19, 0x0a, 0x0b, 0x11, 0x47, 0xa9,
0x14, 0xbe, 0x9f, 0x77, 0x86, 0x1b, 0xb6, 0x2f, 0x6a, 0x4f, 0x9a, 0xf7, 0x51, 0x7f, 0xc3, 0xa6,
0x4f, 0x9f, 0xb1, 0x6f, 0xfe, 0xc2, 0xc7, 0xb6, 0xf5, 0xa8, 0xdf, 0xef, 0x87, 0x63, 0x0f, 0xd0,
0x69, 0x19, 0x12, 0xcb, 0xcd, 0x9b, 0x26, 0x20, 0x66, 0x93, 0xb2, 0x11, 0x98, 0x52, 0xa5, 0x98,
0x14, 0x0a, 0x79, 0x07, 0xfe, 0xd3, 0xae, 0xc3, 0x99, 0x3d, 0xc6, 0x30, 0xf1, 0xc1, 0xf8, 0xb9,
0x57, 0xa5, 0xa0, 0xf7, 0x2d, 0x56, 0xaa, 0x34, 0xe9, 0x5c, 0x6b, 0xeb, 0xe5, 0xbb, 0xa4, 0x4c,
0x24, 0x23, 0xd2, 0xde, 0x0d, 0x0d, 0xf5, 0x33, 0xc9, 0x62, 0x24, 0x5b, 0xf5, 0xf6, 0x2e, 0x2b,
0x8b, 0xf0, 0x20, 0xe5, 0xc4, 0x50, 0x6f, 0x92, 0xa9, 0x58, 0x22, 0xfc, 0xbc, 0xb4, 0xac, 0x78,
0x92, 0x64, 0x41, 0x00, 0x0b, 0x65, 0xeb, 0x72, 0x48, 0x65, 0x29, 0x57, 0xb0, 0x17, 0xee, 0xab,
0x06, 0x2d, 0x16, 0x8f, 0xc7, 0xf3, 0xcd, 0xce, 0xcd, 0x1a, 0x33, 0x99, 0x86, 0x5c, 0xa6, 0x13,
0x88, 0xd9, 0x7c, 0x0b, 0xb2, 0x72, 0x32, 0x6c, 0x08, 0xc5, 0x6c, 0x5b, 0xd3, 0x79, 0x74, 0xef,
0x07, 0xd8, 0x54, 0x3c, 0xe1, 0x57, 0x3b, 0x3a, 0xda, 0xe7, 0x87, 0x86, 0x86, 0xee, 0x6d, 0x04,
0xa5, 0x8a, 0x99, 0xe4, 0x23, 0xee, 0xbb, 0x6b, 0x3e, 0xf8, 0xfe, 0x56, 0x62, 0xb2, 0x30, 0x01,
0xb7, 0xf2, 0x34, 0x99, 0x15, 0xb2, 0x40, 0x49, 0x36, 0x5a, 0x6d, 0xed, 0x14, 0xee, 0x2c, 0xe1,
0xba, 0x9c, 0xb0, 0x44, 0x78, 0x87, 0xbd, 0xa5, 0x60, 0xe5, 0xf6, 0x9e, 0x9e, 0x1e, 0xdc, 0xc2,
0x7d, 0x2e, 0x90, 0x5e, 0xdf, 0x36, 0x27, 0x91, 0x89, 0x5b, 0xee, 0x6f, 0xdf, 0x55, 0x83, 0xb0,
0xc1, 0x4f, 0xa6, 0x67, 0xca, 0x46, 0xda, 0xda, 0xae, 0x42, 0x57, 0x57, 0x97, 0x6b, 0xfa, 0xb1,
0xf9, 0x90, 0x99, 0x95, 0x66, 0x5d, 0x3c, 0x88, 0x6b, 0x06, 0xa5, 0x48, 0x92, 0x35, 0x3a, 0x5d,
0xdd, 0x9c, 0x5e, 0xaf, 0x77, 0x0d, 0x25, 0xd9, 0x00, 0x0c, 0x53, 0x40, 0xce, 0x9d, 0xb7, 0xd7,
0xed, 0x72, 0xc2, 0xe7, 0xf3, 0xfd, 0x95, 0x4a, 0xc5, 0x84, 0x4e, 0xa7, 0x83, 0xba, 0xba, 0x3a,
0x30, 0x18, 0x0c, 0xa0, 0xd1, 0x54, 0x4d, 0x61, 0xbf, 0xbe, 0x5b, 0xd7, 0x5b, 0x10, 0xf6, 0xe6,
0x0d, 0x56, 0xa5, 0x98, 0xd0, 0x6a, 0xb5, 0x50, 0x5b, 0x5b, 0x0b, 0x0d, 0x8d, 0xf5, 0x77, 0x53,
0x52, 0x45, 0xda, 0x47, 0x72, 0xdd, 0x12, 0x89, 0x13, 0xd5, 0x2c, 0xce, 0xea, 0x87, 0x22, 0xb5,
0x5d, 0x92, 0x2a, 0xba, 0x10, 0x13, 0x13, 0xb3, 0xe9, 0x91, 0x80, 0x48, 0x57, 0x91, 0x1b, 0x0e,
0x0f, 0xf1, 0x42, 0xd6, 0xe3, 0x02, 0xf9, 0x17, 0x7f, 0x4e, 0x23, 0x68, 0x48, 0x3d, 0x71, 0xa9,
0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE tree_sel_xpm[1] = {{ png, sizeof( png ), "tree_sel_xpm" }};
//EOF
<?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="26"
width="26"
version="1.1"
id="svg2"
inkscape:version="0.48.1 "
sodipodi:docname="add_keepout_area.svg">
<metadata
id="metadata14">
<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 />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs12">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3165"
id="linearGradient3147"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0243903,0,0,1.0355608,-35.845375,-31.825111)"
x1="10"
y1="2.5"
x2="15.409858"
y2="21.491209" />
<linearGradient
id="linearGradient3165">
<stop
id="stop5217"
offset="0"
style="stop-color:#f48e86;stop-opacity:0.99607843;" />
<stop
style="stop-color:#bf2c21;stop-opacity:0.99607843;"
offset="0.5"
id="stop5223" />
<stop
style="stop-color:#48130f;stop-opacity:0.99607843;"
offset="1"
id="stop5221" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3165"
id="linearGradient3149"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0243903,0,0,1.0355608,-35.33318,-31.825111)"
x1="9.5"
y1="2.5"
x2="14.909858"
y2="21.491209" />
<linearGradient
id="linearGradient8262">
<stop
style="stop-color:#f68273;stop-opacity:1;"
offset="0"
id="stop8264" />
<stop
id="stop8266"
offset="0.5"
style="stop-color:#cd2923;stop-opacity:1;" />
<stop
style="stop-color:#8c0000;stop-opacity:1"
offset="1"
id="stop8268" />
</linearGradient>
<linearGradient
y2="21.491209"
x2="14.909858"
y1="2.5"
x1="9.5"
gradientTransform="matrix(1.0243903,0,0,1.0355608,-35.33318,-31.825111)"
gradientUnits="userSpaceOnUse"
id="linearGradient8273"
xlink:href="#linearGradient3165"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3165"
id="linearGradient5212"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.96823216,0,0,0.98360286,21.081824,17.367375)"
x1="9.5"
y1="2.5"
x2="14.909858"
y2="21.491209" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3165"
id="linearGradient5215"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.96823216,0,0,0.98360286,21.903889,16.869782)"
x1="10"
y1="2.5"
x2="15.409858"
y2="21.491209" />
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1280"
inkscape:window-height="968"
id="namedview10"
showgrid="true"
inkscape:snap-grids="false"
inkscape:snap-to-guides="false"
inkscape:zoom="31.197274"
inkscape:cx="12.755157"
inkscape:cy="13.257277"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid2822"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<rect
style="fill:#a8c9c5;fill-opacity:1;stroke:#1a2200;stroke-width:1.04457009;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="rect3767"
width="22.751417"
height="23.217913"
x="1.7035706"
y="1.551699" />
<path
d="m 11.388353,4.7619742 3.570662,-0.080905 10.013099,10.7534978 c 0.05305,1.027595 -0.0071,1.109722 0.04199,3.98885 L 14.971765,8.5777429 l -3.583953,-0.01462 -0.01801,-2.0063721 0.01856,-1.7947794 z"
id="path6"
style="fill:#037600;fill-opacity:1"
sodipodi:nodetypes="cccccccc"
inkscape:connector-curvature="0" />
<path
d="M 7.1933422,1.0463663 C 3.8459678,0.99480061 1.2607574,3.4092055 1.2343849,6.6456504 1.212037,9.3663522 3.7139513,12.43648 7.1669697,12.476979 10.355862,12.51438 12.921899,9.9848585 12.914948,6.6972161 12.90832,3.5634848 10.382485,0.99480061 7.1933422,1.0463663 z M 7.1405977,3.8886568 C 8.9745023,3.8628747 10.089243,5.3767725 10.097572,6.6456504 10.108967,8.3791437 8.6844134,9.6131959 7.1142253,9.5831254 5.4124574,9.5505334 4.2062509,8.276423 4.1836256,6.7487817 4.1598941,5.1194121 5.4120948,3.8886568 7.1405976,3.8886568 z"
id="path8"
style="fill:#797800;fill-opacity:1"
sodipodi:nodetypes="csssccsssc"
inkscape:connector-curvature="0" />
<g
id="g3004"
transform="matrix(0.82726961,0,0,0.80467364,-17.473303,-6.3485938)"
style="fill:#cd0404;fill-opacity:1">
<path
inkscape:connector-curvature="0"
style="opacity:0.85321099;fill:#cd0404;fill-opacity:1;fill-rule:evenodd;stroke:none"
d="m 40.727806,39.169139 c 0,0 -5.138993,-13.201066 -18.02601,-17.485067 l 2.088731,-3.121414 c 12.777976,4.18237 17.994777,19.284892 17.994777,19.284892 z"
id="path3006"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
style="opacity:0.85321099;fill:#cd0404;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 22.933897,35.970958 3.852963,3.290103 C 32.515122,24.39248 42.867046,20.959903 42.867046,20.959903 l -1.890358,-1.119465 c 0,0 -11.064955,2.012207 -18.042791,16.13052 z"
id="path3008"
sodipodi:nodetypes="ccccc" />
</g>
</svg>
...@@ -188,7 +188,7 @@ double From_User_Unit( EDA_UNITS_T aUnit, double aValue ) ...@@ -188,7 +188,7 @@ double From_User_Unit( EDA_UNITS_T aUnit, double aValue )
int ReturnValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue ) int ReturnValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue )
{ {
int Value; double value;
double dtmp = 0; double dtmp = 0;
// Acquire the 'right' decimal point separator // Acquire the 'right' decimal point separator
...@@ -239,9 +239,9 @@ int ReturnValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue ) ...@@ -239,9 +239,9 @@ int ReturnValueFromString( EDA_UNITS_T aUnits, const wxString& aTextValue )
dtmp /= 1000; dtmp /= 1000;
} }
Value = From_User_Unit( aUnits, dtmp ); value = From_User_Unit( aUnits, dtmp );
return Value; return KiROUND( value );
} }
......
...@@ -250,12 +250,14 @@ void PAGE_INFO::SetPortrait( bool isPortrait ) ...@@ -250,12 +250,14 @@ void PAGE_INFO::SetPortrait( bool isPortrait )
static int clampWidth( int aWidthInMils ) static int clampWidth( int aWidthInMils )
{ {
/* was giving EESCHEMA single component SVG plotter grief /* was giving EESCHEMA single component SVG plotter grief
However a minimal test is made to avoid values that crashes Kicad
if( aWidthInMils < 4000 ) // 4" is about a baseball card if( aWidthInMils < 4000 ) // 4" is about a baseball card
aWidthInMils = 4000; aWidthInMils = 4000;
else if( aWidthInMils > 44000 ) //44" is plotter size else if( aWidthInMils > 44000 ) //44" is plotter size
aWidthInMils = 44000; aWidthInMils = 44000;
*/ */
if( aWidthInMils < 10 )
aWidthInMils = 10;
return aWidthInMils; return aWidthInMils;
} }
...@@ -264,11 +266,14 @@ static int clampHeight( int aHeightInMils ) ...@@ -264,11 +266,14 @@ static int clampHeight( int aHeightInMils )
{ {
/* was giving EESCHEMA single component SVG plotter grief /* was giving EESCHEMA single component SVG plotter grief
clamping is best done at the UI, i.e. dialog, levels clamping is best done at the UI, i.e. dialog, levels
However a minimal test is made to avoid values that crashes Kicad
if( aHeightInMils < 4000 ) if( aHeightInMils < 4000 )
aHeightInMils = 4000; aHeightInMils = 4000;
else if( aHeightInMils > 44000 ) else if( aHeightInMils > 44000 )
aHeightInMils = 44000; aHeightInMils = 44000;
*/ */
if( aHeightInMils < 10 )
aHeightInMils = 10;
return aHeightInMils; return aHeightInMils;
} }
...@@ -316,18 +321,17 @@ void PAGE_INFO::SetHeightMils( int aHeightInMils ) ...@@ -316,18 +321,17 @@ void PAGE_INFO::SetHeightMils( int aHeightInMils )
void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const void PAGE_INFO::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControlBits ) const
throw( IO_ERROR ) throw( IO_ERROR )
{ {
// If page is A3 landscape, then it is assumed to be the default and is not written.
if( !IsDefault() )
{
aFormatter->Print( aNestLevel, "(page %s", aFormatter->Quotew( GetType() ).c_str() ); aFormatter->Print( aNestLevel, "(page %s", aFormatter->Quotew( GetType() ).c_str() );
// The page dimensions are only required for user defined page sizes. // The page dimensions are only required for user defined page sizes.
// Internally, the page size is in mils
if( GetType() == PAGE_INFO::Custom ) if( GetType() == PAGE_INFO::Custom )
aFormatter->Print( aNestLevel, " %d %d", GetWidthIU(), GetHeightIU() ); aFormatter->Print( 0, " %g %g",
GetCustomWidthMils() * 25.4 / 1000.0,
GetCustomHeightMils() * 25.4 / 1000.0 );
if( IsCustom() && IsPortrait() ) if( IsCustom() && IsPortrait() )
aFormatter->Print( aNestLevel, " portrait" ); aFormatter->Print( 0, " portrait" );
aFormatter->Print( aNestLevel, ")\n" ); aFormatter->Print( 0, ")\n" );
}
} }
...@@ -274,27 +274,35 @@ void GERBER_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill, ...@@ -274,27 +274,35 @@ void GERBER_PLOTTER::Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
} }
void GERBER_PLOTTER::Circle( const wxPoint& aCentre, int aDiameter, FILL_T aFill, void GERBER_PLOTTER::Circle( const wxPoint& aCenter, int aDiameter, FILL_T aFill,
int aWidth ) int aWidth )
{
Arc( aCenter, 0, 3600, aDiameter / 2, aFill, aWidth );
}
void GERBER_PLOTTER::Arc( const wxPoint& aCenter, int aStAngle, int aEndAngle,
int aRadius, FILL_T aFill, int aWidth )
{ {
wxASSERT( outputFile ); wxASSERT( outputFile );
wxPoint start, end; wxPoint start, end;
double radius = aDiameter / 2; start.x = aCenter.x + KiROUND( aRadius*cos( DEG2RAD( aStAngle/10.0 ) ) );
const int delta = 3600 / 32; /* increment (in 0.1 degrees) to draw circles */ start.y = aCenter.y - KiROUND( aRadius*sin( DEG2RAD( aStAngle/10.0 ) ) );
start.x = aCentre.x + KiROUND( radius );
start.y = aCentre.y;
SetCurrentLineWidth( aWidth ); SetCurrentLineWidth( aWidth );
MoveTo( start ); MoveTo( start );
end.x = aCenter.x + KiROUND( aRadius*cos( DEG2RAD( aEndAngle/10.0 ) ) );
for( int ii = delta; ii < 3600; ii += delta ) end.y = aCenter.y - KiROUND( aRadius*sin( DEG2RAD( aEndAngle/10.0 ) ) );
{ DPOINT devEnd = userToDeviceCoordinates( end );
end.x = aCentre.x + (int) ( radius * cos( DEG2RAD( ii / 10.0 ) ) ); DPOINT devCenter = userToDeviceCoordinates( aCenter - start );
end.y = aCentre.y + (int) ( radius * sin( DEG2RAD( ii / 10.0 ) ) ); fprintf( outputFile, "G75*\n" ); // Multiquadrant mode
LineTo( end );
} if( aStAngle < aEndAngle )
fprintf( outputFile, "G03" );
FinishTo( start ); else
fprintf( outputFile, "G02" );
fprintf( outputFile, "X%dY%dI%dJ%dD01*\n", int( devEnd.x ), int( devEnd.y ),
int( devCenter.x ), int( devCenter.y ) );
fprintf( outputFile, "G74*\nG01*\n" ); // Back to single quadrant and linear interp.
} }
......
...@@ -624,8 +624,8 @@ void DIALOG_PAGES_SETTINGS::UpdatePageLayoutExample() ...@@ -624,8 +624,8 @@ void DIALOG_PAGES_SETTINGS::UpdatePageLayoutExample()
// Prepare DC. // Prepare DC.
wxSize example_size( lyWidth, lyHeight ); wxSize example_size( lyWidth, lyHeight );
wxMemoryDC memDC; wxMemoryDC memDC;
memDC.SetClippingRegion( wxPoint( 0, 0 ), example_size );
memDC.SelectObject( *m_page_bitmap ); memDC.SelectObject( *m_page_bitmap );
memDC.SetClippingRegion( wxPoint( 0, 0 ), example_size );
memDC.Clear(); memDC.Clear();
memDC.SetUserScale( scaleW, scaleH ); memDC.SetUserScale( scaleW, scaleH );
......
...@@ -344,12 +344,12 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl ...@@ -344,12 +344,12 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
{ {
if( !IsDefaultFormatting() ) if( !IsDefaultFormatting() )
{ {
aFormatter->Print( aNestLevel+1, "(effects\n" ); aFormatter->Print( aNestLevel+1, "(effects" );
if( ( m_Size.x != DEFAULT_SIZE_TEXT ) || ( m_Size.y != DEFAULT_SIZE_TEXT ) || m_Bold if( ( m_Size.x != DEFAULT_SIZE_TEXT ) || ( m_Size.y != DEFAULT_SIZE_TEXT ) || m_Bold
|| m_Italic ) || m_Italic )
{ {
aFormatter->Print( aNestLevel+2, "(font" ); aFormatter->Print( 0, " (font" );
// Add font support here at some point in the future. // Add font support here at some point in the future.
...@@ -366,13 +366,13 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl ...@@ -366,13 +366,13 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
if( IsItalic() ) if( IsItalic() )
aFormatter->Print( 0, " italic" ); aFormatter->Print( 0, " italic" );
aFormatter->Print( 0, ")\n"); aFormatter->Print( 0, ")");
} }
if( m_Mirror || ( m_HJustify != GR_TEXT_HJUSTIFY_CENTER ) if( m_Mirror || ( m_HJustify != GR_TEXT_HJUSTIFY_CENTER )
|| ( m_VJustify != GR_TEXT_VJUSTIFY_CENTER ) ) || ( m_VJustify != GR_TEXT_VJUSTIFY_CENTER ) )
{ {
aFormatter->Print( aNestLevel+2, "(justify"); aFormatter->Print( 0, " (justify");
if( m_HJustify != GR_TEXT_HJUSTIFY_CENTER ) if( m_HJustify != GR_TEXT_HJUSTIFY_CENTER )
aFormatter->Print( 0, (m_HJustify == GR_TEXT_HJUSTIFY_LEFT) ? " left" : " right" ); aFormatter->Print( 0, (m_HJustify == GR_TEXT_HJUSTIFY_LEFT) ? " left" : " right" );
...@@ -383,13 +383,13 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl ...@@ -383,13 +383,13 @@ void EDA_TEXT::Format( OUTPUTFORMATTER* aFormatter, int aNestLevel, int aControl
if( m_Mirror ) if( m_Mirror )
aFormatter->Print( 0, " mirror" ); aFormatter->Print( 0, " mirror" );
aFormatter->Print( 0, ")\n" ); aFormatter->Print( 0, ")" );
} }
// As of now the only place this is used is in Eeschema to hide or show the text. // As of now the only place this is used is in Eeschema to hide or show the text.
if( m_Attributs ) if( m_Attributs )
aFormatter->Print( aNestLevel+2, "hide\n" ); aFormatter->Print( 0, " hide" );
aFormatter->Print( aNestLevel+1, ")\n" ); aFormatter->Print( 0, ")\n" );
} }
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
# These are the keywords for the Pcbnew s-expression file format. # These are the keywords for the Pcbnew s-expression file format.
add_net add_net
allowed
angle angle
arc arc
arc_segments arc_segments
...@@ -48,6 +49,7 @@ comment ...@@ -48,6 +49,7 @@ comment
company company
connect connect
connect_pads connect_pads
copperpour
crossbar crossbar
date date
descr descr
...@@ -84,6 +86,7 @@ hatch ...@@ -84,6 +86,7 @@ hatch
hide hide
italic italic
justify justify
keepout
kicad_pcb kicad_pcb
last_trace_width last_trace_width
layer layer
...@@ -107,10 +110,12 @@ nets ...@@ -107,10 +110,12 @@ nets
no no
no_connects no_connects
none none
not_allowed
np_thru_hole np_thru_hole
offset offset
oval oval
pad pad
pads
pad_drill pad_drill
pad_size pad_size
pad_to_mask_clearance pad_to_mask_clearance
...@@ -164,6 +169,7 @@ trace_clearance ...@@ -164,6 +169,7 @@ trace_clearance
trapezoid trapezoid
thru thru
thru_hole thru_hole
thru_hole_only
tstamp tstamp
user user
user_trace_width user_trace_width
...@@ -177,6 +183,7 @@ uvias_allowed ...@@ -177,6 +183,7 @@ uvias_allowed
value value
version version
via via
vias
via_dia via_dia
via_drill via_drill
via_min_drill via_min_drill
...@@ -193,4 +200,5 @@ zone ...@@ -193,4 +200,5 @@ zone
zone_45_only zone_45_only
zone_clearance zone_clearance
zone_connect zone_connect
zone_type
zones zones
...@@ -50,10 +50,10 @@ ...@@ -50,10 +50,10 @@
static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC ); static void AbortCreateNewLine( EDA_DRAW_PANEL* Panel, wxDC* DC );
static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos ); static void ComputeBreakPoint( SCH_LINE* segment, const wxPoint& new_pos );
static DLIST< SCH_ITEM > s_wires; static DLIST< SCH_ITEM > s_wires; // when creating a new set of wires,
static DLIST< SCH_ITEM > s_oldWires; // stores here the new wires.
static DLIST< SCH_ITEM > s_oldWires; // when creating a new set of wires,
static wxPoint s_startPoint; // stores here the old wires (for undo command)
/** /**
...@@ -125,7 +125,6 @@ void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type ) ...@@ -125,7 +125,6 @@ void SCH_EDIT_FRAME::BeginSegment( wxDC* DC, int type )
if( !segment ) /* first point : Create first wire or bus */ if( !segment ) /* first point : Create first wire or bus */
{ {
s_startPoint = cursorpos;
GetScreen()->ExtractWires( s_oldWires, true ); GetScreen()->ExtractWires( s_oldWires, true );
GetScreen()->SchematicCleanUp( m_canvas ); GetScreen()->SchematicCleanUp( m_canvas );
...@@ -228,50 +227,40 @@ void SCH_EDIT_FRAME::EndSegment( wxDC* DC ) ...@@ -228,50 +227,40 @@ void SCH_EDIT_FRAME::EndSegment( wxDC* DC )
wxCHECK_RET( item->Type() == SCH_LINE_T, wxT( "Unexpected object type in wire list." ) ); wxCHECK_RET( item->Type() == SCH_LINE_T, wxT( "Unexpected object type in wire list." ) );
segment = (SCH_LINE*) item; segment = (SCH_LINE*) item;
item = item->Next();
if( segment->IsNull() ) if( segment->IsNull() )
{ delete s_wires.Remove( segment );
wxLogDebug( wxT( "Removing null segment: " ) + segment->GetSelectMenuText() );
SCH_ITEM* previousSegment = item->Back();
delete s_wires.Remove( item );
if( previousSegment == NULL )
item = s_wires.begin();
else
item = previousSegment;
wxLogDebug( wxT( "Segment count after removal: %d" ), s_wires.GetCount() );
}
item = item->Next();
} }
if( s_wires.GetCount() == 0 ) if( s_wires.GetCount() == 0 )
return; return;
// Get the last non-null wire. // Get the last non-null wire (this is the last created segment).
m_itemToRepeat = segment = (SCH_LINE*) s_wires.GetLast(); m_itemToRepeat = segment = (SCH_LINE*) s_wires.GetLast();
screen->SetCurItem( NULL ); screen->SetCurItem( NULL );
m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false ); m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
// store the terminal point of this last segment: a junction could be needed
// (the last wire could be merged/deleted/modified, and lost)
wxPoint endpoint = segment->GetEndPoint();
// store the starting point of this first segment: a junction could be needed
SCH_LINE* firstsegment = (SCH_LINE*) s_wires.GetFirst();
wxPoint startPoint = firstsegment->GetStartPoint();
screen->Append( s_wires ); screen->Append( s_wires );
// Correct and remove segments that need merged. // Correct and remove segments that need to be merged.
screen->SchematicCleanUp( NULL, DC ); screen->SchematicCleanUp( NULL, DC );
// A junction may be needed to connect the last segment. If the last segment was // A junction could be needed to connect the end point of the last created segment.
// removed by a cleanup, a junction may be needed to connect the segment's end point if( screen->IsJunctionNeeded( endpoint ) )
// which is also the same as the previous segment's start point. screen->Append( AddJunction( DC, endpoint ) );
if( screen->IsJunctionNeeded( segment->GetEndPoint() ) )
screen->Append( AddJunction( DC, segment->GetEndPoint() ) ); // A junction could be needed to connect the start point of the set of new created wires
else if( screen->IsJunctionNeeded( segment->GetStartPoint() ) ) if( screen->IsJunctionNeeded( startPoint ) )
screen->Append( AddJunction( DC, segment->GetStartPoint() ) ); screen->Append( AddJunction( DC, startPoint ) );
// Automatically place a junction on the start point if necessary because the cleanup
// can suppress intermediate points by merging wire segments.
if( screen->IsJunctionNeeded( s_startPoint ) )
screen->Append( AddJunction( DC, s_startPoint ) );
m_canvas->Refresh(); m_canvas->Refresh();
......
...@@ -149,6 +149,14 @@ void DIALOG_PRINT_USING_PRINTER::OnInitDialog( wxInitDialogEvent& event ) ...@@ -149,6 +149,14 @@ void DIALOG_PRINT_USING_PRINTER::OnInitDialog( wxInitDialogEvent& event )
m_buttonPrint->SetDefault(); m_buttonPrint->SetDefault();
} }
void DIALOG_PRINT_USING_PRINTER::GetPrintOptions()
{
SCH_EDIT_FRAME* parent = GetParent();
parent->SetPrintMonochrome( m_checkMonochrome->IsChecked() );
parent->SetPrintSheetReference( m_checkReference->IsChecked() );
}
void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event ) void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
{ {
...@@ -160,8 +168,7 @@ void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event ) ...@@ -160,8 +168,7 @@ void DIALOG_PRINT_USING_PRINTER::OnCloseWindow( wxCloseEvent& event )
parent->SetPrintDialogSize( GetSize() ); parent->SetPrintDialogSize( GetSize() );
} }
parent->SetPrintMonochrome( m_checkMonochrome->IsChecked() ); GetPrintOptions();
parent->SetPrintSheetReference( m_checkReference->IsChecked() );
EndDialog( wxID_CANCEL ); EndDialog( wxID_CANCEL );
} }
...@@ -187,8 +194,7 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event ) ...@@ -187,8 +194,7 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintPreview( wxCommandEvent& event )
{ {
SCH_EDIT_FRAME* parent = GetParent(); SCH_EDIT_FRAME* parent = GetParent();
parent->SetPrintMonochrome( m_checkMonochrome->IsChecked() ); GetPrintOptions();
parent->SetPrintSheetReference( m_checkReference->IsChecked() );
// Pass two printout objects: for preview, and possible printing. // Pass two printout objects: for preview, and possible printing.
wxString title = _( "Preview" ); wxString title = _( "Preview" );
...@@ -216,8 +222,7 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event ) ...@@ -216,8 +222,7 @@ void DIALOG_PRINT_USING_PRINTER::OnPrintButtonClick( wxCommandEvent& event )
{ {
SCH_EDIT_FRAME* parent = GetParent(); SCH_EDIT_FRAME* parent = GetParent();
parent->SetPrintMonochrome( m_checkMonochrome->IsChecked() ); GetPrintOptions();
parent->SetPrintSheetReference( m_checkReference->IsChecked() );
wxPrintDialogData printDialogData( parent->GetPageSetupData().GetPrintData() ); wxPrintDialogData printDialogData( parent->GetPageSetupData().GetPrintData() );
printDialogData.SetMaxPage( g_RootSheet->CountSheets() ); printDialogData.SetMaxPage( g_RootSheet->CountSheets() );
......
...@@ -26,6 +26,8 @@ private: ...@@ -26,6 +26,8 @@ private:
void OnPrintPreview( wxCommandEvent& event ); void OnPrintPreview( wxCommandEvent& event );
void OnPrintButtonClick( wxCommandEvent& event ); void OnPrintButtonClick( wxCommandEvent& event );
void OnButtonCancelClick( wxCommandEvent& event ){ Close(); } void OnButtonCancelClick( wxCommandEvent& event ){ Close(); }
void GetPrintOptions();
}; };
......
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008) // C++ code generated with wxFormBuilder (version Mar 17 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -19,16 +19,22 @@ DIALOG_PRINT_USING_PRINTER_BASE::DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* pare ...@@ -19,16 +19,22 @@ DIALOG_PRINT_USING_PRINTER_BASE::DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* pare
wxBoxSizer* bleftSizer; wxBoxSizer* bleftSizer;
bleftSizer = new wxBoxSizer( wxVERTICAL ); bleftSizer = new wxBoxSizer( wxVERTICAL );
m_staticText1 = new wxStaticText( this, wxID_ANY, _("Print options:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText1->Wrap( -1 );
m_staticText1->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 70, 90, 92, false, wxEmptyString ) );
bleftSizer->Add( m_staticText1, 0, wxTOP|wxRIGHT, 5 );
m_checkReference = new wxCheckBox( this, wxID_ANY, _("Print sheet &reference and title block"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkReference = new wxCheckBox( this, wxID_ANY, _("Print sheet &reference and title block"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkReference->SetValue(true); m_checkReference->SetValue(true);
m_checkReference->SetToolTip( _("Print (or not) the Frame references.") ); m_checkReference->SetToolTip( _("Print (or not) the Frame references.") );
bleftSizer->Add( m_checkReference, 0, wxALL, 5 ); bleftSizer->Add( m_checkReference, 0, wxALL, 10 );
m_checkMonochrome = new wxCheckBox( this, wxID_ANY, _("Print in &black and white only"), wxDefaultPosition, wxDefaultSize, 0 ); m_checkMonochrome = new wxCheckBox( this, wxID_ANY, _("Print in &black and white only"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkMonochrome->SetValue(true);
bleftSizer->Add( m_checkMonochrome, 0, wxBOTTOM|wxRIGHT|wxLEFT, 10 );
bleftSizer->Add( m_checkMonochrome, 0, wxALL, 5 );
bMainSizer->Add( bleftSizer, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 12 ); bMainSizer->Add( bleftSizer, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxTOP, 12 );
...@@ -47,11 +53,12 @@ DIALOG_PRINT_USING_PRINTER_BASE::DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* pare ...@@ -47,11 +53,12 @@ DIALOG_PRINT_USING_PRINTER_BASE::DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* pare
m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 ); m_buttonQuit = new wxButton( this, wxID_CANCEL, _("Close"), wxDefaultPosition, wxDefaultSize, 0 );
bbuttonsSizer->Add( m_buttonQuit, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 ); bbuttonsSizer->Add( m_buttonQuit, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxEXPAND, 5 );
bMainSizer->Add( bbuttonsSizer, 0, wxALL, 12 ); bMainSizer->Add( bbuttonsSizer, 0, wxALL, 12 );
this->SetSizer( bMainSizer ); this->SetSizer( bMainSizer );
this->Layout(); this->Layout();
bMainSizer->Fit( this );
// Connect Events // Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnCloseWindow ) ); this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnCloseWindow ) );
...@@ -71,4 +78,5 @@ DIALOG_PRINT_USING_PRINTER_BASE::~DIALOG_PRINT_USING_PRINTER_BASE() ...@@ -71,4 +78,5 @@ DIALOG_PRINT_USING_PRINTER_BASE::~DIALOG_PRINT_USING_PRINTER_BASE()
m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintPreview ), NULL, this ); m_buttonPreview->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintPreview ), NULL, this );
m_buttonPrint->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintButtonClick ), NULL, this ); m_buttonPrint->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnPrintButtonClick ), NULL, this );
m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnButtonCancelClick ), NULL, this ); m_buttonQuit->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_PRINT_USING_PRINTER_BASE::OnButtonCancelClick ), NULL, this );
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008) // C++ code generated with wxFormBuilder (version Mar 17 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_print_using_printer_base__ #ifndef __DIALOG_PRINT_USING_PRINTER_BASE_H__
#define __dialog_print_using_printer_base__ #define __DIALOG_PRINT_USING_PRINTER_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h> #include <wx/intl.h>
#include <wx/string.h> #include <wx/string.h>
#include <wx/checkbox.h> #include <wx/stattext.h>
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include <wx/font.h> #include <wx/font.h>
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/checkbox.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/button.h> #include <wx/button.h>
#include <wx/dialog.h> #include <wx/dialog.h>
...@@ -30,6 +32,7 @@ class DIALOG_PRINT_USING_PRINTER_BASE : public wxDialog ...@@ -30,6 +32,7 @@ class DIALOG_PRINT_USING_PRINTER_BASE : public wxDialog
private: private:
protected: protected:
wxStaticText* m_staticText1;
wxCheckBox* m_checkReference; wxCheckBox* m_checkReference;
wxCheckBox* m_checkMonochrome; wxCheckBox* m_checkMonochrome;
wxButton* m_buttonPageSetup; wxButton* m_buttonPageSetup;
...@@ -38,18 +41,19 @@ class DIALOG_PRINT_USING_PRINTER_BASE : public wxDialog ...@@ -38,18 +41,19 @@ class DIALOG_PRINT_USING_PRINTER_BASE : public wxDialog
wxButton* m_buttonQuit; wxButton* m_buttonQuit;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnCloseWindow( wxCloseEvent& event ){ event.Skip(); } virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
virtual void OnInitDialog( wxInitDialogEvent& event ){ event.Skip(); } virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnPageSetup( wxCommandEvent& event ){ event.Skip(); } virtual void OnPageSetup( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPrintPreview( wxCommandEvent& event ){ event.Skip(); } virtual void OnPrintPreview( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPrintButtonClick( wxCommandEvent& event ){ event.Skip(); } virtual void OnPrintButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnButtonCancelClick( wxCommandEvent& event ){ event.Skip(); } virtual void OnButtonCancelClick( wxCommandEvent& event ) { event.Skip(); }
public: public:
DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Print"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_PRINT_USING_PRINTER_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Print"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 388,185 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_PRINT_USING_PRINTER_BASE(); ~DIALOG_PRINT_USING_PRINTER_BASE();
}; };
#endif //__dialog_print_using_printer_base__ #endif //__DIALOG_PRINT_USING_PRINTER_BASE_H__
...@@ -85,9 +85,12 @@ HIERARCHY_TREE::HIERARCHY_TREE( HIERARCHY_NAVIG_DLG* parent ) : ...@@ -85,9 +85,12 @@ HIERARCHY_TREE::HIERARCHY_TREE( HIERARCHY_NAVIG_DLG* parent ) :
m_Parent = parent; m_Parent = parent;
// Make an image list containing small icons // Make an image list containing small icons
imageList = new wxImageList( 16, 15, true, 2 ); // All icons are expected having the same size.
wxBitmap tree_nosel_bm( KiBitmap( tree_nosel_xpm ) );
imageList = new wxImageList( tree_nosel_bm.GetWidth(),
tree_nosel_bm.GetHeight(), true, 2 );
imageList->Add( KiBitmap( tree_nosel_xpm ) ); imageList->Add( tree_nosel_bm );
imageList->Add( KiBitmap( tree_sel_xpm ) ); imageList->Add( KiBitmap( tree_sel_xpm ) );
AssignImageList( imageList ); AssignImageList( imageList );
...@@ -147,36 +150,31 @@ HIERARCHY_NAVIG_DLG::HIERARCHY_NAVIG_DLG( SCH_EDIT_FRAME* parent, wxDC* DC, cons ...@@ -147,36 +150,31 @@ HIERARCHY_NAVIG_DLG::HIERARCHY_NAVIG_DLG( SCH_EDIT_FRAME* parent, wxDC* DC, cons
cellule = m_Tree->AddRoot( _( "Root" ), 0, 1 ); cellule = m_Tree->AddRoot( _( "Root" ), 0, 1 );
m_Tree->SetItemBold( cellule, true ); m_Tree->SetItemBold( cellule, true );
SCH_SHEET_PATH list; SCH_SHEET_PATH list;
list.Push( g_RootSheet ); list.Push( g_RootSheet );
m_Tree->SetItemData( cellule, new TreeItemData( list ) ); m_Tree->SetItemData( cellule, new TreeItemData( list ) );
wxRect itemrect;
#ifdef __UNIX__
itemrect.SetWidth( 100 );
itemrect.SetHeight( 20 );
#else
m_Tree->GetBoundingRect( cellule, itemrect );
#endif
m_TreeSize.x = itemrect.GetWidth() + 10;
m_TreeSize.y = 20;
if( m_Parent->GetCurrentSheet().Last() == g_RootSheet ) if( m_Parent->GetCurrentSheet().Last() == g_RootSheet )
m_Tree->SelectItem( cellule ); //root. m_Tree->SelectItem( cellule ); //root.
maxposx = 15; maxposx = 15;
BuildSheetsTree( &list, &cellule ); BuildSheetsTree( &list, &cellule );
if( m_nbsheets > 1 )
{
m_Tree->Expand( cellule ); m_Tree->Expand( cellule );
wxRect itemrect;
m_Tree->GetBoundingRect( cellule, itemrect );
// Set dialog window size to be large enough
m_TreeSize.x = itemrect.GetWidth() + 20;
m_TreeSize.x = max( m_TreeSize.x, 250 );
// Readjust the size of the frame to an optimal value. // Readjust the size of the frame to an optimal value.
m_TreeSize.y += m_nbsheets * itemrect.GetHeight(); m_TreeSize.y = m_nbsheets * itemrect.GetHeight();
m_TreeSize.x = MIN( m_TreeSize.x, 250 ); m_TreeSize.y += 10;
m_TreeSize.y = MIN( m_TreeSize.y, 350 );
SetClientSize( m_TreeSize ); SetClientSize( m_TreeSize );
}
} }
......
...@@ -62,6 +62,7 @@ EXTERN_BITMAP( add_hierarchical_label_xpm ) ...@@ -62,6 +62,7 @@ EXTERN_BITMAP( add_hierarchical_label_xpm )
EXTERN_BITMAP( add_hierarchical_subsheet_xpm ) EXTERN_BITMAP( add_hierarchical_subsheet_xpm )
EXTERN_BITMAP( add_hierar_pin_xpm ) EXTERN_BITMAP( add_hierar_pin_xpm )
EXTERN_BITMAP( add_junction_xpm ) EXTERN_BITMAP( add_junction_xpm )
EXTERN_BITMAP( add_keepout_area_xpm )
EXTERN_BITMAP( add_line2bus_xpm ) EXTERN_BITMAP( add_line2bus_xpm )
EXTERN_BITMAP( add_line_label_xpm ) EXTERN_BITMAP( add_line_label_xpm )
EXTERN_BITMAP( add_line_xpm ) EXTERN_BITMAP( add_line_xpm )
......
...@@ -679,6 +679,8 @@ public: ...@@ -679,6 +679,8 @@ public:
int width = -1 ); int width = -1 );
virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill, virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
int width = -1 ); int width = -1 );
virtual void Arc( const wxPoint& aCenter, int aStAngle, int aEndAngle, int aRadius,
FILL_T aFill, int aWidth = -1 );
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = -1); FILL_T aFill, int aWidth = -1);
......
...@@ -439,6 +439,13 @@ public: ...@@ -439,6 +439,13 @@ public:
bool OnHotkeyEditItem( int aIdCommand ); bool OnHotkeyEditItem( int aIdCommand );
/**
* Function OnHotkeyCopyItem
* returns the copy event id for copyable items.
* @return Event id of a suitable copy event, zero when no copyable item found.
*/
int OnHotkeyCopyItem();
/** /**
* Function OnHotkeyMoveItem * Function OnHotkeyMoveItem
* Moves or drag the item (footprint, track, text .. ) found under the mouse cursor * Moves or drag the item (footprint, track, text .. ) found under the mouse cursor
...@@ -911,9 +918,9 @@ public: ...@@ -911,9 +918,9 @@ public:
// Handling texts on the board // Handling texts on the board
void Rotate_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC ); void Rotate_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
void FlipTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC ); void FlipTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC );
TEXTE_PCB* Create_Texte_Pcb( wxDC* DC ); TEXTE_PCB* CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText = NULL );
void Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC ); void Delete_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
void StartMoveTextePcb( TEXTE_PCB* TextePcb, wxDC* DC ); void StartMoveTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC, bool aErase = true );
void Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC ); void Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC );
void InstallTextPCBOptionsFrame( TEXTE_PCB* TextPCB, wxDC* DC ); void InstallTextPCBOptionsFrame( TEXTE_PCB* TextPCB, wxDC* DC );
......
...@@ -74,6 +74,8 @@ set(PCBNEW_DIALOGS ...@@ -74,6 +74,8 @@ set(PCBNEW_DIALOGS
dialogs/dialog_graphic_item_properties_for_Modedit.cpp dialogs/dialog_graphic_item_properties_for_Modedit.cpp
dialogs/dialog_global_deletion.cpp dialogs/dialog_global_deletion.cpp
dialogs/dialog_global_deletion_base.cpp dialogs/dialog_global_deletion_base.cpp
dialogs/dialog_keepout_area_properties.cpp
dialogs/dialog_keepout_area_properties_base.cpp
dialogs/dialog_layers_setup.cpp dialogs/dialog_layers_setup.cpp
dialogs/dialog_layers_setup_base.cpp dialogs/dialog_layers_setup_base.cpp
dialogs/dialog_netlist.cpp dialogs/dialog_netlist.cpp
......
...@@ -440,7 +440,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard() ...@@ -440,7 +440,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard()
m_messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW ); m_messagePanel->SetMessage( 14, _( "Cells." ), msg, YELLOW );
/* Choose the number of board sides. */ /* Choose the number of board sides. */
Nb_Sides = TWO_SIDES; RoutingMatrix.m_RoutingLayersCount = 2;
RoutingMatrix.InitRoutingMatrix(); RoutingMatrix.InitRoutingMatrix();
...@@ -450,7 +450,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard() ...@@ -450,7 +450,7 @@ int PCB_EDIT_FRAME::GenPlaceBoard()
Route_Layer_BOTTOM = LAYER_N_FRONT; Route_Layer_BOTTOM = LAYER_N_FRONT;
if( Nb_Sides == TWO_SIDES ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
Route_Layer_BOTTOM = LAYER_N_BACK; Route_Layer_BOTTOM = LAYER_N_BACK;
Route_Layer_TOP = LAYER_N_FRONT; Route_Layer_TOP = LAYER_N_FRONT;
...@@ -618,7 +618,7 @@ int PCB_EDIT_FRAME::GetOptimalModulePlacement( MODULE* aModule, wxDC* aDC ) ...@@ -618,7 +618,7 @@ int PCB_EDIT_FRAME::GetOptimalModulePlacement( MODULE* aModule, wxDC* aDC )
*/ */
TstOtherSide = false; TstOtherSide = false;
if( Nb_Sides == TWO_SIDES ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
{ {
D_PAD* Pad; D_PAD* Pad;
int otherLayerMask = LAYER_BACK; int otherLayerMask = LAYER_BACK;
...@@ -967,7 +967,7 @@ void CreateKeepOutRectangle( int ux0, int uy0, int ux1, int uy1, ...@@ -967,7 +967,7 @@ void CreateKeepOutRectangle( int ux0, int uy0, int ux1, int uy1,
if( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) ) if( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) )
trace = 1; /* Trace on bottom layer. */ trace = 1; /* Trace on bottom layer. */
if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && Nb_Sides ) if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && RoutingMatrix.m_RoutingLayersCount )
trace |= 2; /* Trace on top layer. */ trace |= 2; /* Trace on top layer. */
if( trace == 0 ) if( trace == 0 )
......
...@@ -47,12 +47,6 @@ ...@@ -47,12 +47,6 @@
#include <autorout.h> #include <autorout.h>
int Nb_Sides; /* Number of layer for autorouting (0 or 1) */
int OpenNodes; /* total number of nodes opened */
int ClosNodes; /* total number of nodes closed */
int MoveNodes; /* total number of nodes moved */
int MaxNodes; /* maximum number of nodes opened at one time */
MATRIX_ROUTING_HEAD RoutingMatrix; // routing matrix (grid) to route 2-sided boards MATRIX_ROUTING_HEAD RoutingMatrix; // routing matrix (grid) to route 2-sided boards
/* init board, route traces*/ /* init board, route traces*/
...@@ -175,10 +169,10 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode ) ...@@ -175,10 +169,10 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
m_messagePanel->EraseMsgBox(); m_messagePanel->EraseMsgBox();
/* Map the board */ /* Map the board */
Nb_Sides = ONE_SIDE; RoutingMatrix.m_RoutingLayersCount = 1;
if( Route_Layer_TOP != Route_Layer_BOTTOM ) if( Route_Layer_TOP != Route_Layer_BOTTOM )
Nb_Sides = TWO_SIDES; RoutingMatrix.m_RoutingLayersCount = 2;
if( RoutingMatrix.InitRoutingMatrix() < 0 ) if( RoutingMatrix.InitRoutingMatrix() < 0 )
{ {
...@@ -195,10 +189,7 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode ) ...@@ -195,10 +189,7 @@ void PCB_EDIT_FRAME::Autoroute( wxDC* DC, int mode )
// DisplayRoutingMatrix( m_canvas, DC ); // DisplayRoutingMatrix( m_canvas, DC );
if( Nb_Sides == TWO_SIDES ) Solve( DC, RoutingMatrix.m_RoutingLayersCount );
Solve( DC, TWO_SIDES ); /* double face */
else
Solve( DC, ONE_SIDE ); /* simple face */
/* Free memory. */ /* Free memory. */
FreeQueue(); FreeQueue();
...@@ -249,7 +240,7 @@ void DisplayRoutingMatrix( EDA_DRAW_PANEL* panel, wxDC* DC ) ...@@ -249,7 +240,7 @@ void DisplayRoutingMatrix( EDA_DRAW_PANEL* panel, wxDC* DC )
if( dcell0 & HOLE ) if( dcell0 & HOLE )
color = GREEN; color = GREEN;
// if( Nb_Sides ) // if( RoutingMatrix.m_RoutingLayersCount )
// dcell1 = GetCell( row, col, TOP ); // dcell1 = GetCell( row, col, TOP );
if( dcell1 & HOLE ) if( dcell1 & HOLE )
......
...@@ -46,7 +46,8 @@ class BOARD; ...@@ -46,7 +46,8 @@ class BOARD;
/* Autorouter commands. */ /* Autorouter commands. */
enum CommandOpt { enum AUTOPLACEROUTE_OPTIONS
{
PLACE_ALL, PLACE_ALL,
PLACE_OUT_OF_BOARD, PLACE_OUT_OF_BOARD,
PLACE_INCREMENTAL, PLACE_INCREMENTAL,
...@@ -58,13 +59,7 @@ enum CommandOpt { ...@@ -58,13 +59,7 @@ enum CommandOpt {
ROUTE_PAD ROUTE_PAD
}; };
#define MAX_ROUTING_LAYERS_COUNT 2
#define ONE_SIDE 0
#define TWO_SIDES 1
#define MAX_SIDES_COUNT 2
extern int Nb_Sides; /* Number of layers for autorouting (0 or 1) */
#define FORCE_PADS 1 /* Force placement of pads for any Netcode */ #define FORCE_PADS 1 /* Force placement of pads for any Netcode */
...@@ -88,20 +83,23 @@ typedef char DIR_CELL; ...@@ -88,20 +83,23 @@ typedef char DIR_CELL;
class MATRIX_ROUTING_HEAD class MATRIX_ROUTING_HEAD
{ {
public: public:
MATRIX_CELL* m_BoardSide[MAX_SIDES_COUNT]; // the image map of 2 board sides MATRIX_CELL* m_BoardSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides
DIST_CELL* m_DistSide[MAX_SIDES_COUNT]; // the image map of 2 board sides: distance to DIST_CELL* m_DistSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// cells // distance to cells
DIR_CELL* m_DirSide[MAX_SIDES_COUNT]; // the image map of 2 board sides: pointers back to DIR_CELL* m_DirSide[MAX_ROUTING_LAYERS_COUNT]; // the image map of 2 board sides:
// source // pointers back to source
bool m_InitMatrixDone; bool m_InitMatrixDone;
int m_Layers; // Layer count (1 2 ) int m_RoutingLayersCount; // Number of layers for autorouting (0 or 1)
int m_GridRouting; // Size of grid for autoplace/autoroute int m_GridRouting; // Size of grid for autoplace/autoroute
EDA_RECT m_BrdBox; // Actual board bounding box EDA_RECT m_BrdBox; // Actual board bounding box
int m_Nrows, m_Ncols; // Matrix size int m_Nrows, m_Ncols; // Matrix size
int m_MemSize; // Memory requirement, just for statistics int m_MemSize; // Memory requirement, just for statistics
int m_RouteCount; // Number of routes int m_RouteCount; // Number of routes
private: private:
void (MATRIX_ROUTING_HEAD::* m_opWriteCell)( int aRow, int aCol, int aSide, MATRIX_CELL aCell); // a pointeur to the current selected cell op // a pointer to the current selected cell operation
void (MATRIX_ROUTING_HEAD::* m_opWriteCell)( int aRow, int aCol,
int aSide, MATRIX_CELL aCell);
public: public:
MATRIX_ROUTING_HEAD(); MATRIX_ROUTING_HEAD();
...@@ -114,7 +112,7 @@ public: ...@@ -114,7 +112,7 @@ public:
/** /**
* function GetBrdCoordOrigin * function GetBrdCoordOrigin
* @returns the board coordinate corresponding to the * @return the board coordinate corresponding to the
* routing matrix origin ( board coordinate offset ) * routing matrix origin ( board coordinate offset )
*/ */
wxPoint GetBrdCoordOrigin() wxPoint GetBrdCoordOrigin()
...@@ -156,6 +154,12 @@ public: ...@@ -156,6 +154,12 @@ public:
void SetDist( int aRow, int aCol, int aSide, DIST_CELL ); void SetDist( int aRow, int aCol, int aSide, DIST_CELL );
int GetDir( int aRow, int aCol, int aSide ); int GetDir( int aRow, int aCol, int aSide );
void SetDir( int aRow, int aCol, int aSide, int aDir); void SetDir( int aRow, int aCol, int aSide, int aDir);
// calculate distance (with penalty) of a trace through a cell
int CalcDist(int x,int y,int z ,int side );
// calculate approximate distance (manhattan distance)
int GetApxDist( int r1, int c1, int r2, int c2 );
}; };
extern MATRIX_ROUTING_HEAD RoutingMatrix; /* 2-sided board */ extern MATRIX_ROUTING_HEAD RoutingMatrix; /* 2-sided board */
...@@ -220,10 +224,6 @@ int SetWork( int, int, int , int, int, RATSNEST_ITEM *, int ); ...@@ -220,10 +224,6 @@ int SetWork( int, int, int , int, int, RATSNEST_ITEM *, int );
void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** ); void GetWork( int *, int *, int *, int *, int *, RATSNEST_ITEM ** );
void SortWork(); /* order the work items; shortest first */ void SortWork(); /* order the work items; shortest first */
/* DIST.CPP */
int GetApxDist( int r1, int c1, int r2, int c2 );
int CalcDist(int x,int y,int z ,int side );
/* routing_matrix.cpp */ /* routing_matrix.cpp */
int Build_Work( BOARD * Pcb ); int Build_Work( BOARD * Pcb );
void PlaceCells( BOARD * Pcb, int net_code, int flag = 0 ); void PlaceCells( BOARD * Pcb, int net_code, int flag = 0 );
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
/* calculate approximate distance (manhattan distance) /* calculate approximate distance (manhattan distance)
*/ */
int GetApxDist( int r1, int c1, int r2, int c2 ) int MATRIX_ROUTING_HEAD::GetApxDist( int r1, int c1, int r2, int c2 )
{ {
int d1, d2; /* row and column deltas */ int d1, d2; /* row and column deltas */
...@@ -135,7 +135,7 @@ static int dir_penalty_BOTTOM[10][10] = ...@@ -135,7 +135,7 @@ static int dir_penalty_BOTTOM[10][10] =
/* calculate distance (with penalty) of a trace through a cell /* calculate distance (with penalty) of a trace through a cell
*/ */
int CalcDist(int x,int y,int z ,int side ) int MATRIX_ROUTING_HEAD::CalcDist(int x,int y,int z ,int side )
{ {
int adjust, ldist; int adjust, ldist;
...@@ -158,7 +158,7 @@ int CalcDist(int x,int y,int z ,int side ) ...@@ -158,7 +158,7 @@ int CalcDist(int x,int y,int z ,int side )
ldist = dist[x-1][y-1] + penalty[x-1][y-1] + adjust; ldist = dist[x-1][y-1] + penalty[x-1][y-1] + adjust;
if( Nb_Sides ) if( m_RouteCount > 1 )
{ {
if( side == BOTTOM ) if( side == BOTTOM )
ldist += dir_penalty_TOP[x-1][y-1]; ldist += dir_penalty_TOP[x-1][y-1];
......
...@@ -71,14 +71,14 @@ static void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, int layer, ...@@ -71,14 +71,14 @@ static void TraceCircle( int ux0, int uy0, int ux1, int uy1, int lg, int layer,
if( layer < 0 ) \ if( layer < 0 ) \
{ \ { \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \ RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( Nb_Sides ) \ if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \ RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \ } \
else \ else \
{ \ { \
if( layer == Route_Layer_BOTTOM ) \ if( layer == Route_Layer_BOTTOM ) \
RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \ RoutingMatrix.WriteCell( dy, dx, BOTTOM, color ); \
if( Nb_Sides ) \ if( RoutingMatrix.m_RoutingLayersCount > 1 ) \
if( layer == Route_Layer_TOP ) \ if( layer == Route_Layer_TOP ) \
RoutingMatrix.WriteCell( dy, dx, TOP, color ); \ RoutingMatrix.WriteCell( dy, dx, TOP, color ); \
} \ } \
...@@ -156,7 +156,7 @@ void TraceFilledCircle( int cx, int cy, int radius, ...@@ -156,7 +156,7 @@ void TraceFilledCircle( int cx, int cy, int radius,
trace = 1; // Trace on BOTTOM trace = 1; // Trace on BOTTOM
if( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) if( aLayerMask & GetLayerMask( Route_Layer_TOP ) )
if( Nb_Sides ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP trace |= 2; // Trace on TOP
if( trace == 0 ) if( trace == 0 )
...@@ -475,7 +475,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1, ...@@ -475,7 +475,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
if( ( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) ) ) if( ( aLayerMask & GetLayerMask( Route_Layer_BOTTOM ) ) )
trace = 1; // Trace on BOTTOM trace = 1; // Trace on BOTTOM
if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && Nb_Sides ) if( ( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) && RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP trace |= 2; // Trace on TOP
if( trace == 0 ) if( trace == 0 )
...@@ -542,7 +542,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1, ...@@ -542,7 +542,7 @@ void TraceFilledRectangle( int ux0, int uy0, int ux1, int uy1,
if( aLayerMask & GetLayerMask( Route_Layer_TOP ) ) if( aLayerMask & GetLayerMask( Route_Layer_TOP ) )
{ {
if( Nb_Sides ) if( RoutingMatrix.m_RoutingLayersCount > 1 )
trace |= 2; // Trace on TOP trace |= 2; // Trace on TOP
} }
......
...@@ -46,6 +46,23 @@ ...@@ -46,6 +46,23 @@
#include <class_pcb_text.h> #include <class_pcb_text.h>
MATRIX_ROUTING_HEAD::MATRIX_ROUTING_HEAD()
{
m_BoardSide[0] = m_BoardSide[1] = NULL;
m_DistSide[0] = m_DistSide[1] = NULL;
m_DirSide[0] = m_DirSide[1] = NULL;
m_InitMatrixDone = false;
m_Nrows = m_Ncols = 0;
m_MemSize = 0;
m_RoutingLayersCount = 1;
}
MATRIX_ROUTING_HEAD::~MATRIX_ROUTING_HEAD()
{
}
bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly ) bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnly )
{ {
aPcb->ComputeBoundingBox( aUseBoardEdgesOnly ); aPcb->ComputeBoundingBox( aUseBoardEdgesOnly );
...@@ -80,22 +97,6 @@ bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnl ...@@ -80,22 +97,6 @@ bool MATRIX_ROUTING_HEAD::ComputeMatrixSize( BOARD* aPcb, bool aUseBoardEdgesOnl
} }
MATRIX_ROUTING_HEAD::MATRIX_ROUTING_HEAD()
{
m_BoardSide[0] = m_BoardSide[1] = NULL;
m_DistSide[0] = m_DistSide[1] = NULL;
m_DirSide[0] = m_DirSide[1] = NULL;
m_InitMatrixDone = false;
m_Layers = MAX_SIDES_COUNT;
m_Nrows = m_Ncols = 0;
m_MemSize = 0;
}
MATRIX_ROUTING_HEAD::~MATRIX_ROUTING_HEAD()
{
}
int MATRIX_ROUTING_HEAD::InitRoutingMatrix() int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
{ {
...@@ -109,7 +110,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix() ...@@ -109,7 +110,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
// give a small margin for memory allocation: // give a small margin for memory allocation:
ii = (RoutingMatrix.m_Nrows + 1) * (RoutingMatrix.m_Ncols + 1); ii = (RoutingMatrix.m_Nrows + 1) * (RoutingMatrix.m_Ncols + 1);
for( kk = 0; kk < m_Layers; kk++ ) for( kk = 0; kk < m_RoutingLayersCount; kk++ )
{ {
m_BoardSide[kk] = NULL; m_BoardSide[kk] = NULL;
m_DistSide[kk] = NULL; m_DistSide[kk] = NULL;
...@@ -137,7 +138,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix() ...@@ -137,7 +138,7 @@ int MATRIX_ROUTING_HEAD::InitRoutingMatrix()
return -1; return -1;
} }
m_MemSize = m_Layers * ii * ( sizeof(MATRIX_CELL) + sizeof(DIST_CELL) + sizeof(char) ); m_MemSize = m_RouteCount * ii * ( sizeof(MATRIX_CELL) + sizeof(DIST_CELL) + sizeof(char) );
return m_MemSize; return m_MemSize;
} }
...@@ -149,7 +150,7 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix() ...@@ -149,7 +150,7 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix()
m_InitMatrixDone = false; m_InitMatrixDone = false;
for( ii = 0; ii < MAX_SIDES_COUNT; ii++ ) for( ii = 0; ii < MAX_ROUTING_LAYERS_COUNT; ii++ )
{ {
// de-allocate Dir matrix // de-allocate Dir matrix
if( m_DirSide[ii] ) if( m_DirSide[ii] )
...@@ -179,14 +180,17 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix() ...@@ -179,14 +180,17 @@ void MATRIX_ROUTING_HEAD::UnInitRoutingMatrix()
/** /**
* Function PlaceCells * Function PlaceCells
* initializes the cell board is set and VIA_IMPOSSIBLE HOLE according to the setbacks. * Initialize the matrix routing by setting obstacles for each occupied cell
* The elements of net_code = net_code will not be occupied as places but only * a cell set to HOLE is an obstacle for tracks and vias
* VIA_IMPOSSIBLE * a cell set to VIA_IMPOSSIBLE is an obstacle for vias only.
* a cell set to CELL_is_EDGE is a frontier.
* Tracks and vias having the same net code as net_code are skipped
* (htey do not are obstacles)
*
* For single-sided Routing 1: * For single-sided Routing 1:
* BOTTOM side is used and Route_Layer_BOTTOM = Route_Layer_TOP * BOTTOM side is used, and Route_Layer_BOTTOM = Route_Layer_TOP
* *
* According to the bits = 1 parameter flag: * If flag == FORCE_PADS: all pads will be put in matrix as obstacles.
* If FORCE_PADS: all pads will be placed even those same net_code.
*/ */
void PlaceCells( BOARD* aPcb, int net_code, int flag ) void PlaceCells( BOARD* aPcb, int net_code, int flag )
{ {
...@@ -347,8 +351,6 @@ int Build_Work( BOARD* Pcb ) ...@@ -347,8 +351,6 @@ int Build_Work( BOARD* Pcb )
int demi_pas = RoutingMatrix.m_GridRouting / 2; int demi_pas = RoutingMatrix.m_GridRouting / 2;
wxString msg; wxString msg;
EDA_RECT bbbox = Pcb->GetBoundingBox();
InitWork(); /* clear work list */ InitWork(); /* clear work list */
int cellCount = 0; int cellCount = 0;
...@@ -356,7 +358,7 @@ int Build_Work( BOARD* Pcb ) ...@@ -356,7 +358,7 @@ int Build_Work( BOARD* Pcb )
{ {
pt_rats = &Pcb->m_FullRatsnest[ii]; pt_rats = &Pcb->m_FullRatsnest[ii];
/* We consider her only ratsnest that are active ( obviously not yet routed) /* We consider here only ratsnest that are active ( obviously not yet routed)
* and routables (that are not yet attempt to be routed and fail * and routables (that are not yet attempt to be routed and fail
*/ */
if( (pt_rats->m_Status & CH_ACTIF) == 0 ) if( (pt_rats->m_Status & CH_ACTIF) == 0 )
...@@ -373,45 +375,47 @@ int Build_Work( BOARD* Pcb ) ...@@ -373,45 +375,47 @@ int Build_Work( BOARD* Pcb )
current_net_code = pt_pad->GetNet(); current_net_code = pt_pad->GetNet();
pt_ch = pt_rats; pt_ch = pt_rats;
r1 = ( pt_pad->GetPosition().y - bbbox.GetY() + demi_pas ) / RoutingMatrix.m_GridRouting; r1 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY() + demi_pas )
/ RoutingMatrix.m_GridRouting;
if( r1 < 0 || r1 >= RoutingMatrix.m_Nrows ) if( r1 < 0 || r1 >= RoutingMatrix.m_Nrows )
{ {
msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r1, msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r1,
pt_pad->GetPosition().y, bbbox.GetY() ); pt_pad->GetPosition().y, RoutingMatrix.m_BrdBox.GetY() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
c1 = ( pt_pad->GetPosition().x - bbbox.GetX() + demi_pas ) / RoutingMatrix.m_GridRouting; c1 = ( pt_pad->GetPosition().x - RoutingMatrix.m_BrdBox.GetX() + demi_pas ) / RoutingMatrix.m_GridRouting;
if( c1 < 0 || c1 >= RoutingMatrix.m_Ncols ) if( c1 < 0 || c1 >= RoutingMatrix.m_Ncols )
{ {
msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c1, msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c1,
pt_pad->GetPosition().x, bbbox.GetX() ); pt_pad->GetPosition().x, RoutingMatrix.m_BrdBox.GetX() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
pt_pad = pt_rats->m_PadEnd; pt_pad = pt_rats->m_PadEnd;
r2 = ( pt_pad->GetPosition().y - bbbox.GetY() r2 = ( pt_pad->GetPosition().y - RoutingMatrix.m_BrdBox.GetY()
+ demi_pas ) / RoutingMatrix.m_GridRouting; + demi_pas ) / RoutingMatrix.m_GridRouting;
if( r2 < 0 || r2 >= RoutingMatrix.m_Nrows ) if( r2 < 0 || r2 >= RoutingMatrix.m_Nrows )
{ {
msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r2, msg.Printf( wxT( "error : row = %d ( padY %d pcbY %d) " ), r2,
pt_pad->GetPosition().y, bbbox.GetY() ); pt_pad->GetPosition().y, RoutingMatrix.m_BrdBox.GetY() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
c2 = ( pt_pad->GetPosition().x - bbbox.GetX() + demi_pas ) / RoutingMatrix.m_GridRouting; c2 = ( pt_pad->GetPosition().x - RoutingMatrix.m_BrdBox.GetX() + demi_pas )
/ RoutingMatrix.m_GridRouting;
if( c2 < 0 || c2 >= RoutingMatrix.m_Ncols ) if( c2 < 0 || c2 >= RoutingMatrix.m_Ncols )
{ {
msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c2, msg.Printf( wxT( "error : col = %d ( padX %d pcbX %d) " ), c2,
pt_pad->GetPosition().x, bbbox.GetX() ); pt_pad->GetPosition().x, RoutingMatrix.m_BrdBox.GetX() );
wxMessageBox( msg ); wxMessageBox( msg );
return 0; return 0;
} }
...@@ -424,7 +428,7 @@ int Build_Work( BOARD* Pcb ) ...@@ -424,7 +428,7 @@ int Build_Work( BOARD* Pcb )
return cellCount; return cellCount;
} }
// Initialize WriteCell to make the aLogicOp // Initialize m_opWriteCell member to make the aLogicOp
void MATRIX_ROUTING_HEAD::SetCellOperation( int aLogicOp ) void MATRIX_ROUTING_HEAD::SetCellOperation( int aLogicOp )
{ {
switch( aLogicOp ) switch( aLogicOp )
......
...@@ -86,6 +86,10 @@ static int s_Clearance; // Clearance value used in autorouter ...@@ -86,6 +86,10 @@ static int s_Clearance; // Clearance value used in autorouter
static PICKED_ITEMS_LIST s_ItemsListPicker; static PICKED_ITEMS_LIST s_ItemsListPicker;
int OpenNodes; /* total number of nodes opened */
int ClosNodes; /* total number of nodes closed */
int MoveNodes; /* total number of nodes moved */
int MaxNodes; /* maximum number of nodes opened at one time */
#define NOSUCCESS 0 #define NOSUCCESS 0
#define STOP_FROM_ESC -1 #define STOP_FROM_ESC -1
...@@ -263,7 +267,7 @@ static long newmask[8] = ...@@ -263,7 +267,7 @@ static long newmask[8] =
* -1 if escape (stop being routed) request * -1 if escape (stop being routed) request
* -2 if default memory allocation * -2 if default memory allocation
*/ */
int PCB_EDIT_FRAME::Solve( wxDC* DC, int two_sides ) int PCB_EDIT_FRAME::Solve( wxDC* DC, int aLayersCount )
{ {
int current_net_code; int current_net_code;
int row_source, col_source, row_target, col_target; int row_source, col_source, row_target, col_target;
...@@ -272,6 +276,7 @@ int PCB_EDIT_FRAME::Solve( wxDC* DC, int two_sides ) ...@@ -272,6 +276,7 @@ int PCB_EDIT_FRAME::Solve( wxDC* DC, int two_sides )
bool stop = false; bool stop = false;
wxString msg; wxString msg;
int routedCount = 0; // routed ratsnest count int routedCount = 0; // routed ratsnest count
bool two_sides = aLayersCount == 2;
m_canvas->SetAbortRequest( false ); m_canvas->SetAbortRequest( false );
...@@ -522,7 +527,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe, ...@@ -522,7 +527,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
} }
InitQueue(); /* initialize the search queue */ InitQueue(); /* initialize the search queue */
apx_dist = GetApxDist( row_source, col_source, row_target, col_target ); apx_dist = RoutingMatrix.GetApxDist( row_source, col_source, row_target, col_target );
/* Initialize first search. */ /* Initialize first search. */
if( two_sides ) /* Preferred orientation. */ if( two_sides ) /* Preferred orientation. */
...@@ -713,7 +718,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe, ...@@ -713,7 +718,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
} }
olddir = RoutingMatrix.GetDir( r, c, side ); olddir = RoutingMatrix.GetDir( r, c, side );
newdist = d + CalcDist( ndir[i], olddir, newdist = d + RoutingMatrix.CalcDist( ndir[i], olddir,
( olddir == FROM_OTHERSIDE ) ? ( olddir == FROM_OTHERSIDE ) ?
RoutingMatrix.GetDir( r, c, 1 - side ) : 0, side ); RoutingMatrix.GetDir( r, c, 1 - side ) : 0, side );
...@@ -725,7 +730,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe, ...@@ -725,7 +730,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
RoutingMatrix.SetDist( nr, nc, side, newdist ); RoutingMatrix.SetDist( nr, nc, side, newdist );
if( SetQueue( nr, nc, side, newdist, if( SetQueue( nr, nc, side, newdist,
GetApxDist( nr, nc, row_target, col_target ), RoutingMatrix.GetApxDist( nr, nc, row_target, col_target ),
row_target, col_target ) == 0 ) row_target, col_target ) == 0 )
{ {
return ERR_MEMORY; return ERR_MEMORY;
...@@ -736,7 +741,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe, ...@@ -736,7 +741,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
RoutingMatrix.SetDir( nr, nc, side, ndir[i] ); RoutingMatrix.SetDir( nr, nc, side, ndir[i] );
RoutingMatrix.SetDist( nr, nc, side, newdist ); RoutingMatrix.SetDist( nr, nc, side, newdist );
ReSetQueue( nr, nc, side, newdist, ReSetQueue( nr, nc, side, newdist,
GetApxDist( nr, nc, row_target, col_target ), RoutingMatrix.GetApxDist( nr, nc, row_target, col_target ),
row_target, col_target ); row_target, col_target );
} }
} }
...@@ -781,7 +786,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe, ...@@ -781,7 +786,7 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
if( skip ) /* neighboring hole or trace? */ if( skip ) /* neighboring hole or trace? */
continue; /* yes, can't drill via here */ continue; /* yes, can't drill via here */
newdist = d + CalcDist( FROM_OTHERSIDE, olddir, 0, side ); newdist = d + RoutingMatrix.CalcDist( FROM_OTHERSIDE, olddir, 0, side );
/* if (a) not visited yet, /* if (a) not visited yet,
* or (b) we have found a better path, * or (b) we have found a better path,
......
...@@ -41,9 +41,9 @@ ...@@ -41,9 +41,9 @@
#include <cell.h> #include <cell.h>
struct CWORK // a unit of work is a source-target (a ratsnet item) to connect struct CWORK // a unit of work is a source-target to connect
// this is a ratsnest item in the routing matrix world
{ {
struct CWORK* m_Next;
int m_FromRow; // source row int m_FromRow; // source row
int m_FromCol; // source column int m_FromCol; // source column
int m_ToRow; // target row int m_ToRow; // target row
...@@ -53,34 +53,22 @@ struct CWORK // a unit of work is a source-target (a ratsnet item) to connect ...@@ -53,34 +53,22 @@ struct CWORK // a unit of work is a source-target (a ratsnet item) to connect
int m_ApxDist; // approximate distance int m_ApxDist; // approximate distance
int m_Cost; // cost for sort by length int m_Cost; // cost for sort by length
int m_Priority; // route priority int m_Priority; // route priority
// the function that calculates the cost of this ratsnest:
void CalculateCost();
}; };
// pointers to the first and last item of work to do // the list of ratsnests
static CWORK* Head = NULL; static std::vector <CWORK> WorkList;
static CWORK* Tail = NULL; static unsigned Current = 0;
static CWORK* Current = NULL;
// initialize the work list // initialize the work list
void InitWork() void InitWork()
{ {
CWORK* ptr; WorkList.clear();
Current = 0;
while( ( ptr = Head ) != NULL )
{
Head = ptr->m_Next;
delete ptr;
}
Tail = Current = NULL;
}
// initialize the work list
void ReInitWork()
{
Current = Head;
} }
...@@ -89,40 +77,24 @@ void ReInitWork() ...@@ -89,40 +77,24 @@ void ReInitWork()
* 1 if OK * 1 if OK
* 0 if memory allocation failed * 0 if memory allocation failed
*/ */
static int GetCost( int r1, int c1, int r2, int c2 );
int SetWork( int r1, int c1, int SetWork( int r1, int c1,
int n_c, int n_c,
int r2, int c2, int r2, int c2,
RATSNEST_ITEM* pt_ch, int pri ) RATSNEST_ITEM* pt_ch, int pri )
{ {
CWORK* p; CWORK item;
item.m_FromRow = r1;
if( ( p = (CWORK*) operator new( sizeof(CWORK), std::nothrow ) ) != NULL ) item.m_FromCol = c1;
{ item.m_NetCode = n_c;
p->m_FromRow = r1; item.m_ToRow = r2;
p->m_FromCol = c1; item.m_ToCol = c2;
p->m_NetCode = n_c; item.m_Ratsnest = pt_ch;
p->m_ToRow = r2; item.m_ApxDist = RoutingMatrix.GetApxDist( r1, c1, r2, c2 );
p->m_ToCol = c2; item.CalculateCost();
p->m_Ratsnest = pt_ch; item.m_Priority = pri;
p->m_ApxDist = GetApxDist( r1, c1, r2, c2 ); WorkList.push_back( item );
p->m_Cost = GetCost( r1, c1, r2, c2 );
p->m_Priority = pri;
p->m_Next = NULL;
if( Head ) /* attach at end */
Tail->m_Next = p;
else /* first in list */
Head = Current = p;
Tail = p;
return 1; return 1;
}
else /* can't get any more memory */
{
return 0;
}
} }
...@@ -132,15 +104,15 @@ void GetWork( int* r1, int* c1, ...@@ -132,15 +104,15 @@ void GetWork( int* r1, int* c1,
int* r2, int* c2, int* r2, int* c2,
RATSNEST_ITEM** pt_ch ) RATSNEST_ITEM** pt_ch )
{ {
if( Current ) if( Current < WorkList.size() )
{ {
*r1 = Current->m_FromRow; *r1 = WorkList[Current].m_FromRow;
*c1 = Current->m_FromCol; *c1 = WorkList[Current].m_FromCol;
*n_c = Current->m_NetCode; *n_c = WorkList[Current].m_NetCode;
*r2 = Current->m_ToRow; *r2 = WorkList[Current].m_ToRow;
*c2 = Current->m_ToCol; *c2 = WorkList[Current].m_ToCol;
*pt_ch = Current->m_Ratsnest; *pt_ch = WorkList[Current].m_Ratsnest;
Current = Current->m_Next; Current++;
} }
else /* none left */ else /* none left */
{ {
...@@ -151,64 +123,18 @@ void GetWork( int* r1, int* c1, ...@@ -151,64 +123,18 @@ void GetWork( int* r1, int* c1,
} }
/* order the work items; shortest (low cost) first */ // order the work items; shortest (low cost) first:
void SortWork() bool sort_by_cost( const CWORK& ref, const CWORK& item )
{ {
CWORK* p; if( ref.m_Priority == item.m_Priority )
CWORK* q0; /* put PRIORITY PAD_CONNECTs in q0 */ return ref.m_Cost < item.m_Cost;
CWORK* q1; /* sort other PAD_CONNECTs in q1 */
CWORK* r;
q0 = q1 = NULL;
while( (p = Head) != NULL ) /* prioritize each work item */
{
Head = Head->m_Next;
if( p->m_Priority ) /* put at end of priority list */
{
p->m_Next = NULL;
if( (r = q0) == NULL ) /* empty list? */
{
q0 = p;
}
else /* attach at end */
{
while( r->m_Next ) /* search for end */
r = r->m_Next;
r->m_Next = p; /* attach */
}
}
else if( ( ( r = q1 ) == NULL ) || ( p->m_Cost < q1->m_Cost ) )
{
p->m_Next = q1;
q1 = p;
}
else /* find proper position in list */
{
while( r->m_Next && p->m_Cost >= r->m_Next->m_Cost )
r = r->m_Next;
p->m_Next = r->m_Next;
r->m_Next = p;
}
}
if( (p = q0) != NULL ) /* any priority PAD_CONNECTs? */
{
while( q0->m_Next )
q0 = q0->m_Next;
q0->m_Next = q1; return ref.m_Priority >= item.m_Priority;
} }
else
p = q1;
/* reposition Head and Tail */ void SortWork()
for( Head = Current = Tail = p; Tail && Tail->m_Next; Tail = Tail->m_Next ) {
; sort( WorkList.begin(), WorkList.end(), sort_by_cost );
} }
...@@ -216,13 +142,13 @@ void SortWork() ...@@ -216,13 +142,13 @@ void SortWork()
* cost = (| dx | + | dy |) * disability * cost = (| dx | + | dy |) * disability
* disability = 1 if dx or dy = 0, max if | dx | # | dy | * disability = 1 if dx or dy = 0, max if | dx | # | dy |
*/ */
static int GetCost( int r1, int c1, int r2, int c2 ) void CWORK::CalculateCost()
{ {
int dx, dy, mx, my; int dx, dy, mx, my;
double incl = 1.0; double incl = 1.0;
dx = abs( c2 - c1 ); dx = abs( m_ToCol - m_FromCol );
dy = abs( r2 - r1 ); dy = abs( m_ToRow - m_FromRow );
mx = dx; mx = dx;
my = dy; my = dy;
...@@ -234,5 +160,5 @@ static int GetCost( int r1, int c1, int r2, int c2 ) ...@@ -234,5 +160,5 @@ static int GetCost( int r1, int c1, int r2, int c2 )
if( mx ) if( mx )
incl += (2 * (double) my / mx); incl += (2 * (double) my / mx);
return (int) ( ( dx + dy ) * incl ); m_Cost = (int) ( ( dx + dy ) * incl );
} }
...@@ -76,7 +76,7 @@ BOARD::BOARD() : ...@@ -76,7 +76,7 @@ BOARD::BOARD() :
for( int layer = 0; layer < LAYER_COUNT; ++layer ) for( int layer = 0; layer < LAYER_COUNT; ++layer )
{ {
m_Layer[layer].m_Name = GetDefaultLayerName( layer ); m_Layer[layer].m_Name = GetDefaultLayerName( layer, true );
if( layer <= LAST_COPPER_LAYER ) if( layer <= LAST_COPPER_LAYER )
m_Layer[layer].m_Type = LT_SIGNAL; m_Layer[layer].m_Type = LT_SIGNAL;
...@@ -355,7 +355,7 @@ bool BOARD::SetLayer( int aIndex, const LAYER& aLayer ) ...@@ -355,7 +355,7 @@ bool BOARD::SetLayer( int aIndex, const LAYER& aLayer )
} }
wxString BOARD::GetLayerName( int aLayerIndex ) const wxString BOARD::GetLayerName( int aLayerIndex, bool aTranslate ) const
{ {
if( !IsValidLayerIndex( aLayerIndex ) ) if( !IsValidLayerIndex( aLayerIndex ) )
return wxEmptyString; return wxEmptyString;
...@@ -365,14 +365,51 @@ wxString BOARD::GetLayerName( int aLayerIndex ) const ...@@ -365,14 +365,51 @@ wxString BOARD::GetLayerName( int aLayerIndex ) const
{ {
// default names were set in BOARD::BOARD() but they may be // default names were set in BOARD::BOARD() but they may be
// over-ridden by BOARD::SetLayerName() // over-ridden by BOARD::SetLayerName()
// For non translated name, return the actual copper layer names,
// otherwise, return the native layer names
if( aTranslate || aLayerIndex < FIRST_NO_COPPER_LAYER )
return m_Layer[aLayerIndex].m_Name; return m_Layer[aLayerIndex].m_Name;
} }
return GetDefaultLayerName( aLayerIndex ); return GetDefaultLayerName( aLayerIndex, aTranslate );
} }
wxString BOARD::GetDefaultLayerName( int aLayerNumber ) // Default layer names are statically initialized,
// because we want the English name and the translation
// The English name is stored here, and to get the tranlation
// wxGetTranslation must be called explicitely
static const wxChar * layer_FRONT_name = _( "Front" );
static const wxChar * layer_INNER1_name = _( "Inner1" );
static const wxChar * layer_INNER2_name = _( "Inner2" );
static const wxChar * layer_INNER3_name = _( "Inner3" );
static const wxChar * layer_INNER4_name = _( "Inner4" );
static const wxChar * layer_INNER5_name = _( "Inner5" );
static const wxChar * layer_INNER6_name = _( "Inner6" );
static const wxChar * layer_INNER7_name = _( "Inner7" );
static const wxChar * layer_INNER8_name = _( "Inner8" );
static const wxChar * layer_INNER9_name = _( "Inner9" );
static const wxChar * layer_INNER10_name = _( "Inner10" );
static const wxChar * layer_INNER11_name = _( "Inner11" );
static const wxChar * layer_INNER12_name = _( "Inner12" );
static const wxChar * layer_INNER13_name = _( "Inner13" );
static const wxChar * layer_INNER14_name = _( "Inner14" );
static const wxChar * layer_BACK_name = _( "Back" );
static const wxChar * layer_ADHESIVE_BACK_name = _( "Adhes_Back" );
static const wxChar * layer_ADHESIVE_FRONT_name = _( "Adhes_Front" );
static const wxChar * layer_SOLDERPASTE_BACK_namet = _( "SoldP_Back" );
static const wxChar * layer_SOLDERPASTE_FRONT_name = _( "SoldP_Front" );
static const wxChar * layer_SILKSCREEN_BACK_name = _( "SilkS_Back" );
static const wxChar * layer_SILKSCREEN_FRONT_name = _( "SilkS_Front" );
static const wxChar * layer_SOLDERMASK_BACK_name = _( "Mask_Back" );
static const wxChar * layer_SOLDERMASK_FRONT_name = _( "Mask_Front" );
static const wxChar * layer_DRAW_name = _( "Drawings" );
static const wxChar * layer_COMMENT_name = _( "Comments" );
static const wxChar * layer_ECO1_name = _( "Eco1" );
static const wxChar * layer_ECO2_name = _( "Eco2" );
static const wxChar * layer_EDGE_name = _( "PCB_Edges" );
wxString BOARD::GetDefaultLayerName( int aLayerNumber, bool aTranslate )
{ {
const wxChar* txt; const wxChar* txt;
...@@ -382,39 +419,49 @@ wxString BOARD::GetDefaultLayerName( int aLayerNumber ) ...@@ -382,39 +419,49 @@ wxString BOARD::GetDefaultLayerName( int aLayerNumber )
// Use a switch to explicitly show the mapping more clearly // Use a switch to explicitly show the mapping more clearly
switch( aLayerNumber ) switch( aLayerNumber )
{ {
case LAYER_N_FRONT: txt = _( "Front" ); break; case LAYER_N_FRONT: txt = layer_FRONT_name; break;
case LAYER_N_2: txt = _( "Inner2" ); break; case LAYER_N_2: txt = layer_INNER1_name; break;
case LAYER_N_3: txt = _( "Inner3" ); break; case LAYER_N_3: txt = layer_INNER2_name; break;
case LAYER_N_4: txt = _( "Inner4" ); break; case LAYER_N_4: txt = layer_INNER3_name; break;
case LAYER_N_5: txt = _( "Inner5" ); break; case LAYER_N_5: txt = layer_INNER4_name; break;
case LAYER_N_6: txt = _( "Inner6" ); break; case LAYER_N_6: txt = layer_INNER5_name; break;
case LAYER_N_7: txt = _( "Inner7" ); break; case LAYER_N_7: txt = layer_INNER6_name; break;
case LAYER_N_8: txt = _( "Inner8" ); break; case LAYER_N_8: txt = layer_INNER7_name; break;
case LAYER_N_9: txt = _( "Inner9" ); break; case LAYER_N_9: txt = layer_INNER8_name; break;
case LAYER_N_10: txt = _( "Inner10" ); break; case LAYER_N_10: txt = layer_INNER9_name; break;
case LAYER_N_11: txt = _( "Inner11" ); break; case LAYER_N_11: txt = layer_INNER10_name; break;
case LAYER_N_12: txt = _( "Inner12" ); break; case LAYER_N_12: txt = layer_INNER11_name; break;
case LAYER_N_13: txt = _( "Inner13" ); break; case LAYER_N_13: txt = layer_INNER12_name; break;
case LAYER_N_14: txt = _( "Inner14" ); break; case LAYER_N_14: txt = layer_INNER13_name; break;
case LAYER_N_15: txt = _( "Inner15" ); break; case LAYER_N_15: txt = layer_INNER14_name; break;
case LAYER_N_BACK: txt = _( "Back" ); break; case LAYER_N_BACK: txt = layer_BACK_name; break;
case ADHESIVE_N_BACK: txt = _( "Adhes_Back" ); break; case ADHESIVE_N_BACK: txt =layer_ADHESIVE_BACK_name; break;
case ADHESIVE_N_FRONT: txt = _( "Adhes_Front" ); break; case ADHESIVE_N_FRONT: txt = layer_ADHESIVE_FRONT_name; break;
case SOLDERPASTE_N_BACK: txt = _( "SoldP_Back" ); break; case SOLDERPASTE_N_BACK: txt = layer_SOLDERPASTE_BACK_namet; break;
case SOLDERPASTE_N_FRONT: txt = _( "SoldP_Front" ); break; case SOLDERPASTE_N_FRONT: txt = layer_SOLDERPASTE_FRONT_name; break;
case SILKSCREEN_N_BACK: txt = _( "SilkS_Back" ); break; case SILKSCREEN_N_BACK: txt = layer_SILKSCREEN_BACK_name; break;
case SILKSCREEN_N_FRONT: txt = _( "SilkS_Front" ); break; case SILKSCREEN_N_FRONT: txt = layer_SILKSCREEN_FRONT_name; break;
case SOLDERMASK_N_BACK: txt = _( "Mask_Back" ); break; case SOLDERMASK_N_BACK: txt = layer_SOLDERMASK_BACK_name; break;
case SOLDERMASK_N_FRONT: txt = _( "Mask_Front" ); break; case SOLDERMASK_N_FRONT: txt = layer_SOLDERMASK_FRONT_name; break;
case DRAW_N: txt = _( "Drawings" ); break; case DRAW_N: txt = layer_DRAW_name; break;
case COMMENT_N: txt = _( "Comments" ); break; case COMMENT_N: txt = layer_COMMENT_name; break;
case ECO1_N: txt = _( "Eco1" ); break; case ECO1_N: txt = layer_ECO1_name; break;
case ECO2_N: txt = _( "Eco2" ); break; case ECO2_N: txt = layer_ECO2_name; break;
case EDGE_N: txt = _( "PCB_Edges" ); break; case EDGE_N: txt = layer_EDGE_name; break;
default: txt = _( "BAD INDEX" ); break; default: txt = wxT( "BAD_INDEX" ); break;
} }
return wxString( txt ); wxString name;
if( aTranslate )
{
name = wxGetTranslation( txt );
name.Trim( true );
name.Trim( false );
}
else
name = txt;
return name;
} }
...@@ -1334,14 +1381,11 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const ...@@ -1334,14 +1381,11 @@ NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetcode ); NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetcode );
#if defined(DEBUG) #if defined(DEBUG)
if( net ) // item can be NULL if anetcode is not valid if( net && aNetcode != net->GetNet()) // item can be NULL if anetcode is not valid
{ {
if( aNetcode != net->GetNet() ) wxLogError( wxT( "FindNet() anetcode %d != GetNet() %d (net: %s)\n" ),
{
printf( "FindNet() anetcode %d != GetNet() %d (net: %s)\n",
aNetcode, net->GetNet(), TO_UTF8( net->GetNetname() ) ); aNetcode, net->GetNet(), TO_UTF8( net->GetNetname() ) );
} }
}
#endif #endif
return net; return net;
......
...@@ -303,10 +303,12 @@ public: ...@@ -303,10 +303,12 @@ public:
* be different than the default if the user has renamed any copper layers. * be different than the default if the user has renamed any copper layers.
* *
* @param aLayerNumber is the layer number to fetch * @param aLayerNumber is the layer number to fetch
* @param aTranslate = true to return the translated version
* = false to get the native version
* @return wxString - containing the layer name or "BAD INDEX" if aLayerNumber * @return wxString - containing the layer name or "BAD INDEX" if aLayerNumber
* is not legal * is not legal
*/ */
static wxString GetDefaultLayerName( int aLayerNumber ); static wxString GetDefaultLayerName( int aLayerNumber, bool aTranslate );
/** /**
* Function ReturnFlippedLayerNumber * Function ReturnFlippedLayerNumber
...@@ -619,10 +621,13 @@ public: ...@@ -619,10 +621,13 @@ public:
* Function GetLayerName * Function GetLayerName
* returns the name of the layer given by aLayerIndex. * returns the name of the layer given by aLayerIndex.
* *
* @param aLayerIndex A layer index, like LAYER_N_BACK, etc. * @param aLayerIndex = A layer index, like LAYER_N_BACK, etc.
* @param aTranslate = true to return the translated version (default)
* = false to get the native English name
* (Useful to build filenames from layer names)
* @return wxString - the layer name. * @return wxString - the layer name.
*/ */
wxString GetLayerName( int aLayerIndex ) const; wxString GetLayerName( int aLayerIndex, bool aTranslate = true ) const;
/** /**
* Function SetLayerName * Function SetLayerName
...@@ -1048,16 +1053,6 @@ public: ...@@ -1048,16 +1053,6 @@ public:
*/ */
ZONE_CONTAINER* InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch ); ZONE_CONTAINER* InsertArea( int netcode, int iarea, int layer, int x, int y, int hatch );
/**
* Function CompleteArea
* complete copper area contour by adding a line from last to first corner
* if there is only 1 or 2 corners, remove (delete) the area
* @param area_to_complete = area to complete or remove
* @param style = style of last corner
* @return 1 if Ok, 0 if area removed
*/
int CompleteArea( ZONE_CONTAINER* area_to_complete, int style );
/** /**
* Function TestAreaPolygon * Function TestAreaPolygon
* Test an area for self-intersection. * Test an area for self-intersection.
......
...@@ -112,7 +112,6 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre ) ...@@ -112,7 +112,6 @@ void DRAWSEGMENT::Flip( const wxPoint& aCentre )
SetLayer( BOARD::ReturnFlippedLayerNumber( GetLayer() ) ); SetLayer( BOARD::ReturnFlippedLayerNumber( GetLayer() ) );
} }
const wxPoint DRAWSEGMENT::GetArcEnd() const const wxPoint DRAWSEGMENT::GetArcEnd() const
{ {
wxPoint endPoint; // start of arc wxPoint endPoint; // start of arc
...@@ -134,45 +133,23 @@ const wxPoint DRAWSEGMENT::GetArcEnd() const ...@@ -134,45 +133,23 @@ const wxPoint DRAWSEGMENT::GetArcEnd() const
return endPoint; // after rotation, the end of the arc. return endPoint; // after rotation, the end of the arc.
} }
const double DRAWSEGMENT::GetArcAngleStart() const
/* use GetArcStart() now
const wxPoint DRAWSEGMENT::GetStart() const
{ {
switch( m_Shape ) // due to the Y axis orient atan2 needs - y value
{ double angleStart = atan2( (double)(GetArcStart().y - GetCenter().y),
case S_ARC: (double)(GetArcStart().x - GetCenter().x) );
return m_End; // the start of the arc is held in field m_End, center point is in m_Start. // angleStart is in radians, convert it in 1/10 degrees
angleStart = angleStart / M_PI * 1800.0;
case S_SEGMENT:
default: // Normalize it to 0 ... 360 deg, to avoid discontinuity for angles near 180 deg
return m_Start; // because 180 deg and -180 are very near angles when ampping betewwen -180 ... 180 deg.
} // and this is not easy to handle in calculations
if( angleStart < 0 )
angleStart += 3600.0;
return angleStart;
} }
const wxPoint DRAWSEGMENT::GetEnd() const
{
wxPoint endPoint; // start of arc
switch( m_Shape )
{
case S_ARC:
// rotate the starting point of the arc, given by m_End, through the
// angle m_Angle to get the ending point of the arc.
// m_Start is the arc centre
endPoint = m_End; // m_End = start point of arc
RotatePoint( &endPoint, m_Start, -m_Angle );
return endPoint; // after rotation, the end of the arc.
break;
case S_SEGMENT:
default:
return m_End;
}
}
*/
void DRAWSEGMENT::SetAngle( double aAngle ) void DRAWSEGMENT::SetAngle( double aAngle )
{ {
NORMALIZE_ANGLE_360( aAngle ); NORMALIZE_ANGLE_360( aAngle );
...@@ -450,14 +427,12 @@ EDA_RECT DRAWSEGMENT::GetBoundingBox() const ...@@ -450,14 +427,12 @@ EDA_RECT DRAWSEGMENT::GetBoundingBox() const
bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) bool DRAWSEGMENT::HitTest( const wxPoint& aPosition )
{ {
/* Calculate coordinates to test relative to segment origin. */
wxPoint relPos = aPosition - m_Start;
switch( m_Shape ) switch( m_Shape )
{ {
case S_CIRCLE: case S_CIRCLE:
case S_ARC: case S_ARC:
{ {
wxPoint relPos = aPosition - GetCenter();
int radius = GetRadius(); int radius = GetRadius();
int dist = (int) hypot( (double) relPos.x, (double) relPos.y ); int dist = (int) hypot( (double) relPos.x, (double) relPos.y );
...@@ -466,19 +441,36 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition ) ...@@ -466,19 +441,36 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aPosition )
if( m_Shape == S_CIRCLE ) if( m_Shape == S_CIRCLE )
return true; return true;
wxPoint startVec = wxPoint( m_End.x - m_Start.x, m_End.y - m_Start.y ); // For arcs, the test point angle must be >= arc angle start
wxPoint endVec = m_End - m_Start; // and <= arc angle end
RotatePoint( &endVec, -m_Angle ); // However angle values > 360 deg are not easy to handle
// so we calculate the relative angle between arc start point and teast point
// this relative arc should be < arc angle if arc angle > 0 (CW arc)
// and > arc angle if arc angle < 0 (CCW arc)
double arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg, in 0.1 deg
// Check dot products double arc_hittest = atan2( (double) relPos.y, (double) relPos.x );
if( (long long)relPos.x*startVec.x + (long long)relPos.y*startVec.y < 0 ) arc_hittest = arc_hittest / M_PI * 1800; // angles are in 1/10 deg
return false;
if( (long long)relPos.x*endVec.x + (long long)relPos.y*endVec.y < 0 ) // Calculate relative angle between the starting point of the arc, and the test point
return false; arc_hittest -= arc_angle_start;
// Normalise arc_hittest between 0 ... 360 deg
NORMALIZE_ANGLE_POS( arc_hittest );
// Check angle: inside the arc angle when it is > 0
// and outside the not drawn arc when it is < 0
if( GetAngle() >= 0.0 )
{
if( arc_hittest <= GetAngle() )
return true; return true;
} }
else
{
if( arc_hittest >= (3600.0 + GetAngle()) )
return true;
}
}
} }
break; break;
......
...@@ -120,6 +120,12 @@ public: ...@@ -120,6 +120,12 @@ public:
const wxPoint& GetArcStart() const { return m_End; } const wxPoint& GetArcStart() const { return m_End; }
const wxPoint GetArcEnd() const; const wxPoint GetArcEnd() const;
/**
* function GetArcAngleStart()
* @return the angle of the stating point of this arc, between 0 and 3600 in 0.1 deg
*/
const double GetArcAngleStart() const;
/** /**
* Function GetRadius * Function GetRadius
* returns the radius of this item * returns the radius of this item
......
...@@ -102,8 +102,21 @@ wxString DRC_ITEM::GetErrorText() const ...@@ -102,8 +102,21 @@ wxString DRC_ITEM::GetErrorText() const
case DRCE_NETCLASS_uVIADRILLSIZE: case DRCE_NETCLASS_uVIADRILLSIZE:
return wxString( _("NetClass uVia Drill &lt; global limit")); return wxString( _("NetClass uVia Drill &lt; global limit"));
case DRCE_VIA_INSIDE_KEEPOUT:
return wxString( _("Via inside a keepout area"));
case DRCE_TRACK_INSIDE_KEEPOUT:
return wxString( _("Track inside a keepout area"));
case DRCE_PAD_INSIDE_KEEPOUT:
return wxString( _("Pad inside a keepout area"));
default: default:
return wxString( wxT("PROGRAM BUG, PLEASE LEAVE THE ROOM.") ); {
wxString msg;
msg.Printf( wxT( "Unknown DRC error code %d" ), m_ErrorCode );
return ( msg );
}
} }
} }
......
...@@ -56,9 +56,13 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) : ...@@ -56,9 +56,13 @@ ZONE_CONTAINER::ZONE_CONTAINER( BOARD* aBoard ) :
m_IsFilled = false; // fill status : true when the zone is filled m_IsFilled = false; // fill status : true when the zone is filled
m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments m_FillMode = 0; // How to fill areas: 0 = use filled polygons, != 0 fill with segments
m_priority = 0; m_priority = 0;
smoothedPoly = NULL; m_smoothedPoly = NULL;
cornerSmoothingType = ZONE_SETTINGS::SMOOTHING_NONE; m_cornerSmoothingType = ZONE_SETTINGS::SMOOTHING_NONE;
cornerRadius = 0; SetIsKeepout( false );
SetDoNotAllowCopperPour( false ); // has meaning only if m_isKeepout == true
SetDoNotAllowVias( true ); // has meaning only if m_isKeepout == true
SetDoNotAllowTracks( true ); // has meaning only if m_isKeepout == true
m_cornerRadius = 0;
utility = 0; // flags used in polygon calculations utility = 0; // flags used in polygon calculations
utility2 = 0; // flags used in polygon calculations utility2 = 0; // flags used in polygon calculations
m_Poly = new CPolyLine(); // Outlines m_Poly = new CPolyLine(); // Outlines
...@@ -87,8 +91,15 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) : ...@@ -87,8 +91,15 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) :
m_FilledPolysList = aZone.m_FilledPolysList; m_FilledPolysList = aZone.m_FilledPolysList;
m_FillSegmList = aZone.m_FillSegmList; m_FillSegmList = aZone.m_FillSegmList;
cornerSmoothingType = aZone.cornerSmoothingType; m_isKeepout = aZone.m_isKeepout;
cornerRadius = aZone.cornerRadius; m_doNotAllowCopperPour = aZone.m_doNotAllowCopperPour;
m_doNotAllowVias = aZone.m_doNotAllowVias;
m_doNotAllowTracks = aZone.m_doNotAllowTracks;
m_cornerSmoothingType = aZone.m_cornerSmoothingType;
m_cornerRadius = aZone.m_cornerRadius;
utility = aZone.utility; utility = aZone.utility;
utility2 = aZone.utility; utility2 = aZone.utility;
} }
...@@ -221,10 +232,8 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const ...@@ -221,10 +232,8 @@ void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const
for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ ) for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ )
{ {
seg_start.x = m_Poly->m_HatchLines[ic].xi + offset.x; seg_start = m_Poly->m_HatchLines[ic].m_Start + offset;
seg_start.y = m_Poly->m_HatchLines[ic].yi + offset.y; seg_end = m_Poly->m_HatchLines[ic].m_End + offset;
seg_end.x = m_Poly->m_HatchLines[ic].xf + offset.x;
seg_end.y = m_Poly->m_HatchLines[ic].yf + offset.y;
lines.push_back( seg_start ); lines.push_back( seg_start );
lines.push_back( seg_end ); lines.push_back( seg_end );
} }
......
...@@ -48,7 +48,6 @@ class PCB_EDIT_FRAME; ...@@ -48,7 +48,6 @@ class PCB_EDIT_FRAME;
class BOARD; class BOARD;
class ZONE_CONTAINER; class ZONE_CONTAINER;
/** /**
* Struct SEGMENT * Struct SEGMENT
* is a simple container used when filling areas with segments * is a simple container used when filling areas with segments
...@@ -499,24 +498,24 @@ public: ...@@ -499,24 +498,24 @@ public:
*/ */
CPolyLine* GetSmoothedPoly() const CPolyLine* GetSmoothedPoly() const
{ {
if( smoothedPoly ) if( m_smoothedPoly )
return smoothedPoly; return m_smoothedPoly;
else else
return m_Poly; return m_Poly;
}; };
void SetCornerSmoothingType( int aType ) { cornerSmoothingType = aType; }; void SetCornerSmoothingType( int aType ) { m_cornerSmoothingType = aType; };
int GetCornerSmoothingType() const { return cornerSmoothingType; }; int GetCornerSmoothingType() const { return m_cornerSmoothingType; };
void SetCornerRadius( unsigned int aRadius ) void SetCornerRadius( unsigned int aRadius )
{ {
cornerRadius = aRadius; m_cornerRadius = aRadius;
if( cornerRadius > (unsigned int) Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) ) if( m_cornerRadius > (unsigned int) Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) )
cornerRadius = Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ); m_cornerRadius = Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS );
}; };
unsigned int GetCornerRadius() const { return cornerRadius; }; unsigned int GetCornerRadius() const { return m_cornerRadius; };
void AddPolygon( std::vector< wxPoint >& aPolygon ); void AddPolygon( std::vector< wxPoint >& aPolygon );
...@@ -536,6 +535,20 @@ public: ...@@ -536,6 +535,20 @@ public:
virtual EDA_ITEM* Clone() const; virtual EDA_ITEM* Clone() const;
/**
* Accessors to parameters used in Keepout zones:
*/
bool GetIsKeepout() const { return m_isKeepout; }
bool GetDoNotAllowCopperPour() const { return m_doNotAllowCopperPour; }
bool GetDoNotAllowVias() const { return m_doNotAllowVias; }
bool GetDoNotAllowTracks() const { return m_doNotAllowTracks; }
void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
void SetDoNotAllowCopperPour( bool aEnable ) { m_doNotAllowCopperPour = aEnable; }
void SetDoNotAllowVias( bool aEnable ) { m_doNotAllowVias = aEnable; }
void SetDoNotAllowTracks( bool aEnable ) { m_doNotAllowTracks = aEnable; }
#if defined(DEBUG) #if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override void Show( int nestLevel, std::ostream& os ) const { ShowDummy( os ); } // override
#endif #endif
...@@ -574,13 +587,28 @@ public: ...@@ -574,13 +587,28 @@ public:
private: private:
wxString m_Netname; // Net Name wxString m_Netname; // Net Name
CPolyLine* smoothedPoly; // Corner-smoothed version of m_Poly CPolyLine* m_smoothedPoly; // Corner-smoothed version of m_Poly
int cornerSmoothingType; int m_cornerSmoothingType;
unsigned int cornerRadius; unsigned int m_cornerRadius;
// Priority: when a zone outline is inside and other zone, if its priority is higher
// the other zone priority, it will be created inside. /* Priority: when a zone outline is inside and other zone, if its priority is higher
// if priorities are equal, a DRC error is set * the other zone priority, it will be created inside.
* if priorities are equal, a DRC error is set
*/
unsigned m_priority; unsigned m_priority;
/* A zone outline can be a keepout zone.
* It will be never filled, and DRC should test for pads, tracks and vias
*/
bool m_isKeepout;
/* For keepout zones only:
* what is not allowed inside the keepout ( pads, tracks and vias )
*/
bool m_doNotAllowCopperPour;
bool m_doNotAllowVias;
bool m_doNotAllowTracks;
ZoneConnection m_PadConnection; ZoneConnection m_PadConnection;
/* set of filled polygons used to draw a zone as a filled area. /* set of filled polygons used to draw a zone as a filled area.
......
...@@ -39,8 +39,10 @@ ZONE_SETTINGS::ZONE_SETTINGS() ...@@ -39,8 +39,10 @@ ZONE_SETTINGS::ZONE_SETTINGS()
{ {
m_ZonePriority = 0; m_ZonePriority = 0;
m_FillMode = 0; // Mode for filling zone : 1 use segments, 0 use polygons m_FillMode = 0; // Mode for filling zone : 1 use segments, 0 use polygons
m_ZoneClearance = 200; // Clearance value // Clearance value
m_ZoneMinThickness = 100; // Min thickness value in filled areas m_ZoneClearance = Mils2iu( ZONE_CLEARANCE_MIL );
// Min thickness value in filled areas (this is the minimum width of copper to fill solid areas) :
m_ZoneMinThickness = Mils2iu( ZONE_THICKNESS_MIL );
m_NetcodeSelection = 0; // Net code selection for the current zone m_NetcodeSelection = 0; // Net code selection for the current zone
m_CurrentZone_Layer = 0; // Layer used to create the current zone m_CurrentZone_Layer = 0; // Layer used to create the current zone
m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; // Option to show the zone area (outlines only, short hatches or full hatches
...@@ -49,15 +51,22 @@ ZONE_SETTINGS::ZONE_SETTINGS() ...@@ -49,15 +51,22 @@ ZONE_SETTINGS::ZONE_SETTINGS()
// ARC_APPROX_SEGMENTS_COUNT_LOW_DEF // ARC_APPROX_SEGMENTS_COUNT_LOW_DEF
// or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments // or ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF segments
m_ThermalReliefGap = 200; // tickness of the gap in thermal reliefs // tickness of the gap in thermal reliefs:
m_ThermalReliefCopperBridge = 200; // tickness of the copper bridge in thermal reliefs m_ThermalReliefGap = Mils2iu( ZONE_THERMAL_RELIEF_GAP_MIL );
// tickness of the copper bridge in thermal reliefs:
m_ThermalReliefCopperBridge = Mils2iu( ZONE_THERMAL_RELIEF_COPPER_WIDTH_MIL );
m_PadConnection = THERMAL_PAD; // How pads are covered by copper in zone m_PadConnection = THERMAL_PAD; // How pads are covered by copper in zone
m_Zone_45_Only = false; m_Zone_45_Only = false;
cornerSmoothingType = SMOOTHING_NONE; m_cornerSmoothingType = SMOOTHING_NONE;
cornerRadius = 0; m_cornerRadius = 0;
SetIsKeepout( false );
SetDoNotAllowCopperPour( false );
SetDoNotAllowVias( true );
SetDoNotAllowTracks( true );
} }
...@@ -74,8 +83,12 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource ) ...@@ -74,8 +83,12 @@ ZONE_SETTINGS& ZONE_SETTINGS::operator << ( const ZONE_CONTAINER& aSource )
m_ThermalReliefGap = aSource.m_ThermalReliefGap; m_ThermalReliefGap = aSource.m_ThermalReliefGap;
m_ThermalReliefCopperBridge = aSource.m_ThermalReliefCopperBridge; m_ThermalReliefCopperBridge = aSource.m_ThermalReliefCopperBridge;
m_PadConnection = aSource.GetPadConnection(); m_PadConnection = aSource.GetPadConnection();
cornerSmoothingType = aSource.GetCornerSmoothingType(); m_cornerSmoothingType = aSource.GetCornerSmoothingType();
cornerRadius = aSource.GetCornerRadius(); m_cornerRadius = aSource.GetCornerRadius();
m_isKeepout = aSource.GetIsKeepout();
m_keepoutDoNotAllowCopperPour = aSource.GetDoNotAllowCopperPour();
m_keepoutDoNotAllowVias = aSource.GetDoNotAllowVias();
m_keepoutDoNotAllowTracks = aSource.GetDoNotAllowTracks();
return *this; return *this;
} }
...@@ -91,8 +104,12 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c ...@@ -91,8 +104,12 @@ void ZONE_SETTINGS::ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport ) c
aTarget.m_ThermalReliefGap = m_ThermalReliefGap; aTarget.m_ThermalReliefGap = m_ThermalReliefGap;
aTarget.m_ThermalReliefCopperBridge = m_ThermalReliefCopperBridge; aTarget.m_ThermalReliefCopperBridge = m_ThermalReliefCopperBridge;
aTarget.SetPadConnection( m_PadConnection ); aTarget.SetPadConnection( m_PadConnection );
aTarget.SetCornerSmoothingType( cornerSmoothingType ); aTarget.SetCornerSmoothingType( m_cornerSmoothingType );
aTarget.SetCornerRadius( cornerRadius ); aTarget.SetCornerRadius( m_cornerRadius );
aTarget.SetIsKeepout( GetIsKeepout() );
aTarget.SetDoNotAllowCopperPour( GetDoNotAllowCopperPour() );
aTarget.SetDoNotAllowVias( GetDoNotAllowVias() );
aTarget.SetDoNotAllowTracks( GetDoNotAllowTracks() );
if( aFullExport ) if( aFullExport )
{ {
......
...@@ -18,6 +18,8 @@ class ZONE_CONTAINER; ...@@ -18,6 +18,8 @@ class ZONE_CONTAINER;
/** /**
* Class ZONE_SETTINGS * Class ZONE_SETTINGS
* handles zones parameters. * handles zones parameters.
* Because a zone can be on copper or non copper layers, and can be also
* a keepout area, some parameters are irrelevant depending on the type of zone
*/ */
class ZONE_SETTINGS class ZONE_SETTINGS
{ {
...@@ -51,10 +53,23 @@ public: ...@@ -51,10 +53,23 @@ public:
bool m_Zone_45_Only; bool m_Zone_45_Only;
private: private:
int cornerSmoothingType; ///< Corner smoothing type int m_cornerSmoothingType; ///< Corner smoothing type
unsigned int cornerRadius; ///< Corner chamfer distance / fillet radius unsigned int m_cornerRadius; ///< Corner chamfer distance / fillet radius
ZoneConnection m_PadConnection; ZoneConnection m_PadConnection;
/* A zone outline can be a keepout zone.
* It will be never filled, and DRC should test for pads, tracks and vias
*/
bool m_isKeepout;
/* For keepout zones only:
* what is not allowed inside the keepout ( pads, tracks and vias )
*/
bool m_keepoutDoNotAllowCopperPour;
bool m_keepoutDoNotAllowVias;
bool m_keepoutDoNotAllowTracks;
public: public:
ZONE_SETTINGS(); ZONE_SETTINGS();
...@@ -77,25 +92,37 @@ public: ...@@ -77,25 +92,37 @@ public:
*/ */
void ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport = true ) const; void ExportSetting( ZONE_CONTAINER& aTarget, bool aFullExport = true ) const;
void SetCornerSmoothingType( int aType) { cornerSmoothingType = aType; } void SetCornerSmoothingType( int aType) { m_cornerSmoothingType = aType; }
int GetCornerSmoothingType() const { return cornerSmoothingType; } int GetCornerSmoothingType() const { return m_cornerSmoothingType; }
void SetCornerRadius( int aRadius ) void SetCornerRadius( int aRadius )
{ {
if( aRadius > Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) ) if( aRadius > Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ) )
cornerRadius = Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS ); m_cornerRadius = Mils2iu( MAX_ZONE_CORNER_RADIUS_MILS );
else if( aRadius < 0 ) else if( aRadius < 0 )
cornerRadius = 0; m_cornerRadius = 0;
else else
cornerRadius = aRadius; m_cornerRadius = aRadius;
}; };
unsigned int GetCornerRadius() const { return cornerRadius; } unsigned int GetCornerRadius() const { return m_cornerRadius; }
ZoneConnection GetPadConnection() const { return m_PadConnection; } ZoneConnection GetPadConnection() const { return m_PadConnection; }
void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; } void SetPadConnection( ZoneConnection aPadConnection ) { m_PadConnection = aPadConnection; }
/**
* Accessors to parameters used in Keepout zones:
*/
const bool GetIsKeepout() const { return m_isKeepout; }
const bool GetDoNotAllowCopperPour() const { return m_keepoutDoNotAllowCopperPour; }
const bool GetDoNotAllowVias() const { return m_keepoutDoNotAllowVias; }
const bool GetDoNotAllowTracks() const { return m_keepoutDoNotAllowTracks; }
void SetIsKeepout( bool aEnable ) { m_isKeepout = aEnable; }
void SetDoNotAllowCopperPour( bool aEnable ) { m_keepoutDoNotAllowCopperPour = aEnable; }
void SetDoNotAllowVias( bool aEnable ) { m_keepoutDoNotAllowVias = aEnable; }
void SetDoNotAllowTracks( bool aEnable ) { m_keepoutDoNotAllowTracks = aEnable; }
}; };
......
...@@ -133,6 +133,7 @@ BOARD_ITEM* PCB_BASE_FRAME::PcbGeneralLocateAndDisplay( int aHotKeyCode ) ...@@ -133,6 +133,7 @@ BOARD_ITEM* PCB_BASE_FRAME::PcbGeneralLocateAndDisplay( int aHotKeyCode )
break; break;
case ID_PCB_ZONES_BUTT: case ID_PCB_ZONES_BUTT:
case ID_PCB_KEEPOUT_AREA_BUTT:
scanList = GENERAL_COLLECTOR::Zones; scanList = GENERAL_COLLECTOR::Zones;
break; break;
......
///////////////////////////////////////////////////////////////////////////// /**
// Name: dialog_copper_zones.cpp * @file dialog_copper_zones.cpp
// Author: jean-pierre Charras */
// Created: 09/oct/2008
// Licence: GNU License /*
///////////////////////////////////////////////////////////////////////////// * This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 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 <wx/wx.h> #include <wx/wx.h>
#include <wx/imaglist.h>
#include <fctsys.h> #include <fctsys.h>
#include <appl_wxstruct.h> #include <appl_wxstruct.h>
#include <confirm.h> #include <confirm.h>
#include <PolyLine.h> #include <PolyLine.h>
#include <pcbnew.h> #include <pcbnew.h>
#include <wxPcbStruct.h> #include <wxPcbStruct.h>
#include <trigo.h>
#include <zones.h> #include <zones.h>
#include <base_units.h> #include <base_units.h>
#include <class_zone_settings.h> #include <class_zone_settings.h>
#include <class_board.h> #include <class_board.h>
#include <dialog_copper_zones_base.h> #include <dialog_copper_zones_base.h>
#include <wx/imaglist.h> // needed for wx/listctrl.h, in wxGTK 2.8.12
#include <wx/listctrl.h> #include <wx/listctrl.h>
...@@ -54,8 +76,6 @@ private: ...@@ -54,8 +76,6 @@ private:
static wxString m_netNameShowFilter; ///< the filter to show nets (default * "*"). static wxString m_netNameShowFilter; ///< the filter to show nets (default * "*").
///< static to keep this pattern for an entire pcbnew session ///< static to keep this pattern for an entire pcbnew session
wxListView* m_LayerSelectionCtrl;
/** /**
* Function initDialog * Function initDialog
* fills in the dialog controls using the current settings. * fills in the dialog controls using the current settings.
...@@ -133,16 +153,6 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* ...@@ -133,16 +153,6 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS*
SetReturnCode( ZONE_ABORT ); // Will be changed on buttons click SetReturnCode( ZONE_ABORT ); // Will be changed on buttons click
m_LayerSelectionCtrl = new wxListView( this, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxLC_NO_HEADER | wxLC_REPORT
| wxLC_SINGLE_SEL | wxRAISED_BORDER );
wxListItem col0;
col0.SetId( 0 );
m_LayerSelectionCtrl->InsertColumn( 0, col0 );
m_layerSizer->Add( m_LayerSelectionCtrl, 1,
wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );
// Fix static text widget minimum width to a suitable value so that // Fix static text widget minimum width to a suitable value so that
// resizing the dialog is not necessary when changing the corner smoothing type. // resizing the dialog is not necessary when changing the corner smoothing type.
// Depends on the default text in the widget. // Depends on the default text in the widget.
...@@ -151,8 +161,6 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* ...@@ -151,8 +161,6 @@ DIALOG_COPPER_ZONE::DIALOG_COPPER_ZONE( PCB_BASE_FRAME* aParent, ZONE_SETTINGS*
initDialog(); initDialog();
GetSizer()->SetSizeHints( this ); GetSizer()->SetSizeHints( this );
Center();
} }
...@@ -177,10 +185,14 @@ void DIALOG_COPPER_ZONE::initDialog() ...@@ -177,10 +185,14 @@ void DIALOG_COPPER_ZONE::initDialog()
switch( m_settings.GetPadConnection() ) switch( m_settings.GetPadConnection() )
{ {
case PAD_NOT_IN_ZONE: // Pads are not covered case THT_THERMAL: // Thermals only for THT pads
m_PadInZoneOpt->SetSelection( 2 ); m_PadInZoneOpt->SetSelection( 2 );
break; break;
case PAD_NOT_IN_ZONE: // Pads are not covered
m_PadInZoneOpt->SetSelection( 3 );
break;
default: default:
case THERMAL_PAD: // Use thermal relief for pads case THERMAL_PAD: // Use thermal relief for pads
m_PadInZoneOpt->SetSelection( 1 ); m_PadInZoneOpt->SetSelection( 1 );
...@@ -191,7 +203,9 @@ void DIALOG_COPPER_ZONE::initDialog() ...@@ -191,7 +203,9 @@ void DIALOG_COPPER_ZONE::initDialog()
break; break;
} }
if( m_settings.GetPadConnection() != THERMAL_PAD ) // Antipad and spokes are significant only for thermals
if( m_settings.GetPadConnection() != THERMAL_PAD &&
m_settings.GetPadConnection() != THT_THERMAL )
{ {
m_AntipadSizeValue->Enable( false ); m_AntipadSizeValue->Enable( false );
m_CopperWidthValue->Enable( false ); m_CopperWidthValue->Enable( false );
...@@ -231,6 +245,10 @@ void DIALOG_COPPER_ZONE::initDialog() ...@@ -231,6 +245,10 @@ void DIALOG_COPPER_ZONE::initDialog()
m_ArcApproximationOpt->SetSelection( m_ArcApproximationOpt->SetSelection(
m_settings.m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ? 1 : 0 ); m_settings.m_ArcToSegmentsCount == ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF ? 1 : 0 );
// Create one column in m_LayerSelectionCtrl
wxListItem col0;
col0.SetId( 0 );
m_LayerSelectionCtrl->InsertColumn( 0, col0 );
// Build copper layer list and append to layer widget // Build copper layer list and append to layer widget
int layerCount = board->GetCopperLayerCount(); int layerCount = board->GetCopperLayerCount();
int layerNumber, itemIndex, layerColor; int layerNumber, itemIndex, layerColor;
...@@ -319,11 +337,16 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportab ...@@ -319,11 +337,16 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportab
{ {
switch( m_PadInZoneOpt->GetSelection() ) switch( m_PadInZoneOpt->GetSelection() )
{ {
case 2: case 3:
// Pads are not covered // Pads are not covered
m_settings.SetPadConnection( PAD_NOT_IN_ZONE ); m_settings.SetPadConnection( PAD_NOT_IN_ZONE );
break; break;
case 2:
// Use thermal relief for THT pads
m_settings.SetPadConnection( THT_THERMAL );
break;
case 1: case 1:
// Use thermal relief for pads // Use thermal relief for pads
m_settings.SetPadConnection( THERMAL_PAD ); m_settings.SetPadConnection( THERMAL_PAD );
...@@ -370,20 +393,25 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportab ...@@ -370,20 +393,25 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportab
// Test if this is a reasonable value for this parameter // Test if this is a reasonable value for this parameter
// A too large value can hang Pcbnew // A too large value can hang Pcbnew
#define CLEARANCE_MAX_VALUE 100*IU_PER_MILS #define CLEARANCE_MAX_VALUE ZONE_CLEARANCE_MAX_VALUE_MIL*IU_PER_MILS
if( m_settings.m_ZoneClearance > CLEARANCE_MAX_VALUE ) if( m_settings.m_ZoneClearance > CLEARANCE_MAX_VALUE )
{ {
DisplayError( this, _( "Clearance must be smaller than 0.5\" / 12.7 mm." ) ); wxString msg;
msg.Printf( _( "Clearance must be smaller than %f\" / %f mm." ),
ZONE_CLEARANCE_MAX_VALUE_MIL / 1000.0, ZONE_CLEARANCE_MAX_VALUE_MIL * 0.0254 );
DisplayError( this, msg );
return false; return false;
} }
txtvalue = m_ZoneMinThicknessCtrl->GetValue(); txtvalue = m_ZoneMinThicknessCtrl->GetValue();
m_settings.m_ZoneMinThickness = ReturnValueFromString( g_UserUnit, txtvalue ); m_settings.m_ZoneMinThickness = ReturnValueFromString( g_UserUnit, txtvalue );
if( m_settings.m_ZoneMinThickness < (1*IU_PER_MILS) ) if( m_settings.m_ZoneMinThickness < (ZONE_THICKNESS_MIN_VALUE_MIL*IU_PER_MILS) )
{ {
DisplayError( this, wxString msg;
_( "Minimum width must be larger than 0.001\" / 0.0254 mm." ) ); msg.Printf( _( "Minimum width must be larger than %f\" / %f mm." ),
ZONE_THICKNESS_MIN_VALUE_MIL / 1000.0, ZONE_THICKNESS_MIN_VALUE_MIL * 0.0254 );
DisplayError( this, msg );
return false; return false;
} }
...@@ -402,9 +430,20 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportab ...@@ -402,9 +430,20 @@ bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportab
m_settings.m_ThermalReliefCopperBridge = ReturnValueFromTextCtrl( *m_CopperWidthValue ); m_settings.m_ThermalReliefCopperBridge = ReturnValueFromTextCtrl( *m_CopperWidthValue );
m_Config->Write( ZONE_THERMAL_RELIEF_GAP_STRING_KEY, (long) m_settings.m_ThermalReliefGap ); if( m_Config )
{
m_Config->Write( ZONE_CLEARANCE_WIDTH_STRING_KEY,
(double) m_settings.m_ZoneClearance / IU_PER_MILS );
m_Config->Write( ZONE_MIN_THICKNESS_WIDTH_STRING_KEY,
(double) m_settings.m_ZoneMinThickness / IU_PER_MILS );
m_Config->Write( ZONE_THERMAL_RELIEF_GAP_STRING_KEY,
(double) m_settings.m_ThermalReliefGap / IU_PER_MILS );
m_Config->Write( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, (long) m_settings.m_ThermalReliefCopperBridge ); m_Config->Write( ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY,
(double) m_settings.m_ThermalReliefCopperBridge / IU_PER_MILS );
}
if( m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness ) if( m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness )
{ {
...@@ -528,6 +567,7 @@ void DIALOG_COPPER_ZONE::OnPadsInZoneClick( wxCommandEvent& event ) ...@@ -528,6 +567,7 @@ void DIALOG_COPPER_ZONE::OnPadsInZoneClick( wxCommandEvent& event )
m_CopperWidthValue->Enable( false ); m_CopperWidthValue->Enable( false );
break; break;
case 2:
case 1: case 1:
m_AntipadSizeValue->Enable( true ); m_AntipadSizeValue->Enable( true );
m_CopperWidthValue->Enable( true ); m_CopperWidthValue->Enable( true );
......
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 11 2012) // C++ code generated with wxFormBuilder (version Mar 17 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -32,12 +32,16 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i ...@@ -32,12 +32,16 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
wxBoxSizer* m_OptionsBoxSizer; wxBoxSizer* m_OptionsBoxSizer;
m_OptionsBoxSizer = new wxBoxSizer( wxHORIZONTAL ); m_OptionsBoxSizer = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* m_layerSizer;
m_layerSizer = new wxBoxSizer( wxVERTICAL ); m_layerSizer = new wxBoxSizer( wxVERTICAL );
m_staticText17 = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticText17 = new wxStaticText( this, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText17->Wrap( -1 ); m_staticText17->Wrap( -1 );
m_layerSizer->Add( m_staticText17, 0, wxLEFT|wxRIGHT|wxTOP, 5 ); m_layerSizer->Add( m_staticText17, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
m_LayerSelectionCtrl = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ALIGN_LEFT|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_SMALL_ICON );
m_layerSizer->Add( m_LayerSelectionCtrl, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_OptionsBoxSizer->Add( m_layerSizer, 1, wxEXPAND, 5 ); m_OptionsBoxSizer->Add( m_layerSizer, 1, wxEXPAND, 5 );
...@@ -128,7 +132,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i ...@@ -128,7 +132,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
m_cornerSmoothingTitle = new wxStaticText( this, wxID_ANY, _("Chamfer distance (mm):"), wxDefaultPosition, wxDefaultSize, 0 ); m_cornerSmoothingTitle = new wxStaticText( this, wxID_ANY, _("Chamfer distance (mm):"), wxDefaultPosition, wxDefaultSize, 0 );
m_cornerSmoothingTitle->Wrap( -1 ); m_cornerSmoothingTitle->Wrap( -1 );
bSizer9->Add( m_cornerSmoothingTitle, 0, wxLEFT|wxRIGHT|wxTOP, 5 ); bSizer9->Add( m_cornerSmoothingTitle, 0, wxRIGHT|wxLEFT, 5 );
m_cornerSmoothingCtrl = new wxTextCtrl( this, ID_M_CORNERSMOOTHINGCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); m_cornerSmoothingCtrl = new wxTextCtrl( this, ID_M_CORNERSMOOTHINGCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
bSizer9->Add( m_cornerSmoothingCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 ); bSizer9->Add( m_cornerSmoothingCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
...@@ -143,7 +147,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i ...@@ -143,7 +147,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
m_staticText13->Wrap( -1 ); m_staticText13->Wrap( -1 );
m_LeftBox->Add( m_staticText13, 0, wxLEFT|wxRIGHT|wxTOP, 5 ); m_LeftBox->Add( m_staticText13, 0, wxLEFT|wxRIGHT|wxTOP, 5 );
wxString m_PadInZoneOptChoices[] = { _("Solid"), _("Thermal relief"), _("None") }; wxString m_PadInZoneOptChoices[] = { _("Solid"), _("Thermal relief"), _("THT thermal"), _("None") };
int m_PadInZoneOptNChoices = sizeof( m_PadInZoneOptChoices ) / sizeof( wxString ); int m_PadInZoneOptNChoices = sizeof( m_PadInZoneOptChoices ) / sizeof( wxString );
m_PadInZoneOpt = new wxChoice( this, ID_M_PADINZONEOPT, wxDefaultPosition, wxDefaultSize, m_PadInZoneOptNChoices, m_PadInZoneOptChoices, 0 ); m_PadInZoneOpt = new wxChoice( this, ID_M_PADINZONEOPT, wxDefaultPosition, wxDefaultSize, m_PadInZoneOptNChoices, m_PadInZoneOptChoices, 0 );
m_PadInZoneOpt->SetSelection( 0 ); m_PadInZoneOpt->SetSelection( 0 );
...@@ -183,7 +187,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i ...@@ -183,7 +187,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
m_staticText171->Wrap( -1 ); m_staticText171->Wrap( -1 );
m_staticText171->SetToolTip( _("On each copper layer, zones are filled by priority order.\nSo when a zone is inside an other zone:\n* If its priority is highter: its outlines are removed from the other layer.\n* If its priority is equal: a DRC error is set.") ); m_staticText171->SetToolTip( _("On each copper layer, zones are filled by priority order.\nSo when a zone is inside an other zone:\n* If its priority is highter: its outlines are removed from the other layer.\n* If its priority is equal: a DRC error is set.") );
m_MiddleBox->Add( m_staticText171, 0, wxRIGHT|wxLEFT, 5 ); m_MiddleBox->Add( m_staticText171, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_PriorityLevelCtrl = new wxSpinCtrl( this, ID_M_PRIORITYLEVELCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 0 ); m_PriorityLevelCtrl = new wxSpinCtrl( this, ID_M_PRIORITYLEVELCTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 0, 100, 0 );
m_MiddleBox->Add( m_PriorityLevelCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); m_MiddleBox->Add( m_PriorityLevelCtrl, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
...@@ -238,7 +242,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i ...@@ -238,7 +242,7 @@ DIALOG_COPPER_ZONE_BASE::DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID i
m_ExportableSetupSizer->Add( bSizer81, 0, wxEXPAND, 5 ); m_ExportableSetupSizer->Add( bSizer81, 0, wxEXPAND, 5 );
m_MainBoxSizer->Add( m_ExportableSetupSizer, 1, wxALL|wxEXPAND, 5 ); m_MainBoxSizer->Add( m_ExportableSetupSizer, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizer10; wxBoxSizer* bSizer10;
bSizer10 = new wxBoxSizer( wxHORIZONTAL ); bSizer10 = new wxBoxSizer( wxHORIZONTAL );
......
This diff is collapsed.
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 11 2012) // C++ code generated with wxFormBuilder (version Mar 17 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <wx/font.h> #include <wx/font.h>
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/listctrl.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/listbox.h> #include <wx/listbox.h>
#include <wx/choice.h> #include <wx/choice.h>
...@@ -71,8 +72,8 @@ class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM ...@@ -71,8 +72,8 @@ class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM
}; };
wxBoxSizer* m_MainBoxSizer; wxBoxSizer* m_MainBoxSizer;
wxBoxSizer* m_layerSizer;
wxStaticText* m_staticText17; wxStaticText* m_staticText17;
wxListView* m_LayerSelectionCtrl;
wxStaticText* m_staticText2; wxStaticText* m_staticText2;
wxListBox* m_ListNetNameSelection; wxListBox* m_ListNetNameSelection;
wxStaticText* m_staticText16; wxStaticText* m_staticText16;
...@@ -124,7 +125,7 @@ class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM ...@@ -124,7 +125,7 @@ class DIALOG_COPPER_ZONE_BASE : public DIALOG_SHIM
public: public:
DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID id = ID_DIALOG_COPPER_ZONE_BASE, const wxString& title = _("Zone Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 550,500 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); DIALOG_COPPER_ZONE_BASE( wxWindow* parent, wxWindowID id = ID_DIALOG_COPPER_ZONE_BASE, const wxString& title = _("Zone Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 567,500 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_COPPER_ZONE_BASE(); ~DIALOG_COPPER_ZONE_BASE();
}; };
......
...@@ -165,6 +165,7 @@ void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event ) ...@@ -165,6 +165,7 @@ void DIALOG_DRC_CONTROL::OnStartdrcClick( wxCommandEvent& event )
m_tester->SetSettings( true, // Pad to pad DRC test enabled m_tester->SetSettings( true, // Pad to pad DRC test enabled
true, // unconnected pdas DRC test enabled true, // unconnected pdas DRC test enabled
true, // DRC test for zones enabled true, // DRC test for zones enabled
true, // DRC test for keepout areas enabled
reportName, m_CreateRptCtrl->IsChecked() ); reportName, m_CreateRptCtrl->IsChecked() );
DelDRCMarkers(); DelDRCMarkers();
...@@ -243,6 +244,7 @@ void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event ) ...@@ -243,6 +244,7 @@ void DIALOG_DRC_CONTROL::OnListUnconnectedClick( wxCommandEvent& event )
m_tester->SetSettings( true, // Pad to pad DRC test enabled m_tester->SetSettings( true, // Pad to pad DRC test enabled
true, // unconnected pdas DRC test enabled true, // unconnected pdas DRC test enabled
true, // DRC test for zones enabled true, // DRC test for zones enabled
true, // DRC test for keepout areas enabled
reportName, m_CreateRptCtrl->IsChecked() ); reportName, m_CreateRptCtrl->IsChecked() );
DelDRCMarkers(); DelDRCMarkers();
......
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Aug 24 2011) // C++ code generated with wxFormBuilder (version Apr 10 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -120,7 +120,7 @@ class DIALOG_MODULE_BOARD_EDITOR_BASE : public wxDialog ...@@ -120,7 +120,7 @@ class DIALOG_MODULE_BOARD_EDITOR_BASE : public wxDialog
public: public:
wxStaticBoxSizer* m_Sizer3DValues; wxStaticBoxSizer* m_Sizer3DValues;
DIALOG_MODULE_BOARD_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Module properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 550,800 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); DIALOG_MODULE_BOARD_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Module properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 544,599 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_MODULE_BOARD_EDITOR_BASE(); ~DIALOG_MODULE_BOARD_EDITOR_BASE();
}; };
......
/**
* @file dialog_keepout_area_properties.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2012 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 <wx/wx.h>
#include <fctsys.h>
#include <appl_wxstruct.h>
#include <confirm.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <zones.h>
#include <base_units.h>
#include <class_zone_settings.h>
#include <class_board.h>
#include <dialog_keepout_area_properties_base.h>
#include <wx/imaglist.h> // needed for wx/listctrl.h, in wxGTK 2.8.12
#include <wx/listctrl.h>
/**
* Class DIALOG_KEEPOUT_AREA_PROPERTIES
* is the derived class from dialog_copper_zone_frame created by wxFormBuilder
*/
class DIALOG_KEEPOUT_AREA_PROPERTIES : public DIALOG_KEEPOUT_AREA_PROPERTIES_BASE
{
public:
DIALOG_KEEPOUT_AREA_PROPERTIES( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings );
private:
PCB_BASE_FRAME* m_Parent;
wxConfig* m_Config; ///< Current config
ZONE_SETTINGS m_zonesettings;
ZONE_SETTINGS* m_ptr;
std::vector<int> m_LayerId; ///< Handle the real layer number from layer
///< name position in m_LayerSelectionCtrl
/**
* Function initDialog
* fills in the dialog controls using the current settings.
*/
void initDialog();
void OnOkClick( wxCommandEvent& event );
void OnCancelClick( wxCommandEvent& event );
void OnSize( wxSizeEvent& event );
/**
* Function AcceptOptionsForKeepOut
* Test validity of options, and copy options in m_zonesettings, for keepout zones
* @return bool - false if incorrect options, true if ok.
*/
bool AcceptOptionsForKeepOut();
/**
* Function makeLayerBitmap
* creates the colored rectangle bitmaps used in the layer selection widget.
* @param aColor is the color to fill the rectangle with.
*/
wxBitmap makeLayerBitmap( int aColor );
};
#define LAYER_BITMAP_SIZE_X 20
#define LAYER_BITMAP_SIZE_Y 10
ZONE_EDIT_T InvokeKeepoutAreaEditor( PCB_BASE_FRAME* aCaller, ZONE_SETTINGS* aSettings )
{
DIALOG_KEEPOUT_AREA_PROPERTIES dlg( aCaller, aSettings );
ZONE_EDIT_T result = ZONE_EDIT_T( dlg.ShowModal() );
return result;
}
DIALOG_KEEPOUT_AREA_PROPERTIES::DIALOG_KEEPOUT_AREA_PROPERTIES( PCB_BASE_FRAME* aParent, ZONE_SETTINGS* aSettings ) :
DIALOG_KEEPOUT_AREA_PROPERTIES_BASE( aParent )
{
m_Parent = aParent;
m_Config = wxGetApp().GetSettings();
m_ptr = aSettings;
m_zonesettings = *aSettings;
SetReturnCode( ZONE_ABORT ); // Will be changed on button OK ckick
initDialog();
GetSizer()->SetSizeHints( this );
}
void DIALOG_KEEPOUT_AREA_PROPERTIES::initDialog()
{
BOARD* board = m_Parent->GetBoard();
wxString msg;
if( m_zonesettings.m_Zone_45_Only )
m_OrientEdgesOpt->SetSelection( 1 );
switch( m_zonesettings.m_Zone_HatchingStyle )
{
case CPolyLine::NO_HATCH:
m_OutlineAppearanceCtrl->SetSelection( 0 );
break;
case CPolyLine::DIAGONAL_EDGE:
m_OutlineAppearanceCtrl->SetSelection( 1 );
break;
case CPolyLine::DIAGONAL_FULL:
m_OutlineAppearanceCtrl->SetSelection( 2 );
break;
}
// Create one column in m_LayerSelectionCtrl
wxListItem col0;
col0.SetId( 0 );
m_LayerSelectionCtrl->InsertColumn( 0, col0 );
// Build copper layer list and append to layer widget
int layerCount = board->GetCopperLayerCount();
int layerNumber, itemIndex, layerColor;
wxImageList* imageList = new wxImageList( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
m_LayerSelectionCtrl->AssignImageList( imageList, wxIMAGE_LIST_SMALL );
for( int ii = 0; ii < layerCount; ii++ )
{
layerNumber = LAYER_N_BACK;
if( layerCount <= 1 || ii < layerCount - 1 )
layerNumber = ii;
else if( ii == layerCount - 1 )
layerNumber = LAYER_N_FRONT;
m_LayerId.insert( m_LayerId.begin(), layerNumber );
msg = board->GetLayerName( layerNumber );
layerColor = board->GetLayerColor( layerNumber );
imageList->Add( makeLayerBitmap( layerColor ) );
itemIndex = m_LayerSelectionCtrl->InsertItem( 0, msg, ii );
if( m_zonesettings.m_CurrentZone_Layer == layerNumber )
m_LayerSelectionCtrl->Select( itemIndex );
}
// Init keepout parameters:
m_cbTracksCtrl->SetValue( m_zonesettings.GetDoNotAllowTracks() );
m_cbViasCtrl->SetValue( m_zonesettings.GetDoNotAllowVias() );
m_cbCopperPourCtrl->SetValue( m_zonesettings.GetDoNotAllowCopperPour() );
}
void DIALOG_KEEPOUT_AREA_PROPERTIES::OnCancelClick( wxCommandEvent& event )
{
EndModal( ZONE_ABORT );
}
void DIALOG_KEEPOUT_AREA_PROPERTIES::OnOkClick( wxCommandEvent& event )
{
if( AcceptOptionsForKeepOut() )
{
*m_ptr = m_zonesettings;
EndModal( ZONE_OK );
}
}
void DIALOG_KEEPOUT_AREA_PROPERTIES::OnSize( wxSizeEvent& event )
{
Layout();
// Set layer list column width to widget width minus a few pixels
m_LayerSelectionCtrl->SetColumnWidth( 0, m_LayerSelectionCtrl->GetSize().x - 5 );
event.Skip();
}
bool DIALOG_KEEPOUT_AREA_PROPERTIES::AcceptOptionsForKeepOut()
{
// Init keepout parameters:
m_zonesettings.SetIsKeepout( true );
m_zonesettings.SetDoNotAllowTracks( m_cbTracksCtrl->GetValue() );
m_zonesettings.SetDoNotAllowVias( m_cbViasCtrl->GetValue() );
m_zonesettings.SetDoNotAllowCopperPour( m_cbCopperPourCtrl->GetValue() );
// Test for not allowed items: should have at least one item not allowed:
if( ! m_zonesettings.GetDoNotAllowTracks() &&
! m_zonesettings.GetDoNotAllowVias() &&
! m_zonesettings.GetDoNotAllowCopperPour() )
{
DisplayError( NULL,
_("Tracks, vias and pads are allowed. The keepout is useless" ) );
return false;
}
// Get the layer selection for this zone
int ii = m_LayerSelectionCtrl->GetFirstSelected();
if( ii < 0 )
{
DisplayError( NULL, _( "No layer selected." ) );
return false;
}
m_zonesettings.m_CurrentZone_Layer = m_LayerId[ii];
switch( m_OutlineAppearanceCtrl->GetSelection() )
{
case 0:
m_zonesettings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH;
break;
case 1:
m_zonesettings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE;
break;
case 2:
m_zonesettings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL;
break;
}
if( m_Config )
{
m_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY,
(long) m_zonesettings.m_Zone_HatchingStyle );
}
if( m_OrientEdgesOpt->GetSelection() == 0 )
m_zonesettings.m_Zone_45_Only = false;
else
m_zonesettings.m_Zone_45_Only = true;
m_zonesettings.m_ZonePriority = 0; //m_PriorityLevelCtrl->GetValue();
return true;
}
wxBitmap DIALOG_KEEPOUT_AREA_PROPERTIES::makeLayerBitmap( int aColor )
{
wxBitmap bitmap( LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
wxBrush brush;
wxMemoryDC iconDC;
iconDC.SelectObject( bitmap );
brush.SetColour( MakeColour( aColor ) );
brush.SetStyle( wxSOLID );
iconDC.SetBrush( brush );
iconDC.DrawRectangle( 0, 0, LAYER_BITMAP_SIZE_X, LAYER_BITMAP_SIZE_Y );
return bitmap;
}
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 10 2012)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_keepout_area_properties_base.h"
///////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE( DIALOG_KEEPOUT_AREA_PROPERTIES_BASE, DIALOG_SHIM )
EVT_BUTTON( wxID_CANCEL, DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::_wxFB_OnCancelClick )
EVT_BUTTON( wxID_OK, DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::_wxFB_OnOkClick )
END_EVENT_TABLE()
DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::DIALOG_KEEPOUT_AREA_PROPERTIES_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( wxDefaultSize, wxDefaultSize );
wxBoxSizer* m_MainSizer;
m_MainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* m_UpperSizer;
m_UpperSizer = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* m_layersListSizer;
m_layersListSizer = new wxBoxSizer( wxVERTICAL );
m_staticTextLayerSelection = new wxStaticText( this, wxID_ANY, _("Layer selection:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextLayerSelection->Wrap( -1 );
m_layersListSizer->Add( m_staticTextLayerSelection, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_LayerSelectionCtrl = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_ALIGN_LEFT|wxLC_ICON|wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_SMALL_ICON );
m_layersListSizer->Add( m_LayerSelectionCtrl, 1, wxALL|wxEXPAND, 5 );
m_UpperSizer->Add( m_layersListSizer, 1, wxEXPAND, 5 );
wxBoxSizer* bSizerRight;
bSizerRight = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* m_OutilinesBoxOpt;
m_OutilinesBoxOpt = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Outlines Options:") ), wxVERTICAL );
wxString m_OrientEdgesOptChoices[] = { _("Any"), _("H, V and 45 deg") };
int m_OrientEdgesOptNChoices = sizeof( m_OrientEdgesOptChoices ) / sizeof( wxString );
m_OrientEdgesOpt = new wxRadioBox( this, wxID_ANY, _("Zone Edges Orient"), wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptNChoices, m_OrientEdgesOptChoices, 1, wxRA_SPECIFY_COLS );
m_OrientEdgesOpt->SetSelection( 0 );
m_OutilinesBoxOpt->Add( m_OrientEdgesOpt, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
wxString m_OutlineAppearanceCtrlChoices[] = { _("Line"), _("Hatched Outline"), _("Full Hatched") };
int m_OutlineAppearanceCtrlNChoices = sizeof( m_OutlineAppearanceCtrlChoices ) / sizeof( wxString );
m_OutlineAppearanceCtrl = new wxRadioBox( this, wxID_ANY, _("Outlines Appearence"), wxDefaultPosition, wxDefaultSize, m_OutlineAppearanceCtrlNChoices, m_OutlineAppearanceCtrlChoices, 1, wxRA_SPECIFY_COLS );
m_OutlineAppearanceCtrl->SetSelection( 1 );
m_OutilinesBoxOpt->Add( m_OutlineAppearanceCtrl, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
bSizerRight->Add( m_OutilinesBoxOpt, 0, wxEXPAND|wxALL, 5 );
wxStaticBoxSizer* sbSizerCutoutOpts;
sbSizerCutoutOpts = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Keepout Options:") ), wxVERTICAL );
m_cbTracksCtrl = new wxCheckBox( this, wxID_ANY, _("No Tracks"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerCutoutOpts->Add( m_cbTracksCtrl, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_cbViasCtrl = new wxCheckBox( this, wxID_ANY, _("No Vias"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerCutoutOpts->Add( m_cbViasCtrl, 0, wxTOP|wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_cbCopperPourCtrl = new wxCheckBox( this, wxID_ANY, _("No Copper Pour"), wxDefaultPosition, wxDefaultSize, 0 );
sbSizerCutoutOpts->Add( m_cbCopperPourCtrl, 0, wxALL|wxEXPAND, 5 );
bSizerRight->Add( sbSizerCutoutOpts, 0, wxEXPAND|wxALL, 5 );
m_UpperSizer->Add( bSizerRight, 0, wxEXPAND, 5 );
m_MainSizer->Add( m_UpperSizer, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_MainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
m_sdbSizerButtons = new wxStdDialogButtonSizer();
m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
m_sdbSizerButtons->Realize();
m_MainSizer->Add( m_sdbSizerButtons, 0, wxEXPAND, 5 );
this->SetSizer( m_MainSizer );
this->Layout();
this->Centre( wxBOTH );
}
DIALOG_KEEPOUT_AREA_PROPERTIES_BASE::~DIALOG_KEEPOUT_AREA_PROPERTIES_BASE()
{
}
This diff is collapsed.
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 10 2012)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_KEEPOUT_AREA_PROPERTIES_BASE_H__
#define __DIALOG_KEEPOUT_AREA_PROPERTIES_BASE_H__
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/listctrl.h>
#include <wx/sizer.h>
#include <wx/radiobox.h>
#include <wx/statbox.h>
#include <wx/checkbox.h>
#include <wx/statline.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_KEEPOUT_AREA_PROPERTIES_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_KEEPOUT_AREA_PROPERTIES_BASE : public DIALOG_SHIM
{
DECLARE_EVENT_TABLE()
private:
// Private event handlers
void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
void _wxFB_OnOkClick( wxCommandEvent& event ){ OnOkClick( event ); }
protected:
wxStaticText* m_staticTextLayerSelection;
wxListView* m_LayerSelectionCtrl;
wxRadioBox* m_OrientEdgesOpt;
wxRadioBox* m_OutlineAppearanceCtrl;
wxCheckBox* m_cbTracksCtrl;
wxCheckBox* m_cbViasCtrl;
wxCheckBox* m_cbCopperPourCtrl;
wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_KEEPOUT_AREA_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Keepout Area Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 308,355 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
~DIALOG_KEEPOUT_AREA_PROPERTIES_BASE();
};
#endif //__DIALOG_KEEPOUT_AREA_PROPERTIES_BASE_H__
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 11 2012) // C++ code generated with wxFormBuilder (version Apr 10 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE( DialogNonCopperZonesPropertiesBase, DIALOG_SHIM ) BEGIN_EVENT_TABLE( DialogNonCopperZonesPropertiesBase, DIALOG_SHIM )
EVT_BUTTON( wxID_OK, DialogNonCopperZonesPropertiesBase::_wxFB_OnOkClick )
EVT_BUTTON( wxID_CANCEL, DialogNonCopperZonesPropertiesBase::_wxFB_OnCancelClick ) EVT_BUTTON( wxID_CANCEL, DialogNonCopperZonesPropertiesBase::_wxFB_OnCancelClick )
EVT_BUTTON( wxID_OK, DialogNonCopperZonesPropertiesBase::_wxFB_OnOkClick )
END_EVENT_TABLE() END_EVENT_TABLE()
DialogNonCopperZonesPropertiesBase::DialogNonCopperZonesPropertiesBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) DialogNonCopperZonesPropertiesBase::DialogNonCopperZonesPropertiesBase( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
...@@ -24,24 +24,21 @@ DialogNonCopperZonesPropertiesBase::DialogNonCopperZonesPropertiesBase( wxWindow ...@@ -24,24 +24,21 @@ DialogNonCopperZonesPropertiesBase::DialogNonCopperZonesPropertiesBase( wxWindow
wxBoxSizer* m_UpperSizer; wxBoxSizer* m_UpperSizer;
m_UpperSizer = new wxBoxSizer( wxHORIZONTAL ); m_UpperSizer = new wxBoxSizer( wxHORIZONTAL );
wxStaticBoxSizer* sbLeftSizer_; wxBoxSizer* bSizerLeft;
sbLeftSizer_ = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Zone Fill Options:") ), wxVERTICAL ); bSizerLeft = new wxBoxSizer( wxVERTICAL );
wxString m_FillModeCtrlChoices[] = { _("Use polygons"), _("Use segments") }; m_staticTextLayerSelection = new wxStaticText( this, wxID_ANY, _("Layer selection:"), wxDefaultPosition, wxDefaultSize, 0 );
int m_FillModeCtrlNChoices = sizeof( m_FillModeCtrlChoices ) / sizeof( wxString ); m_staticTextLayerSelection->Wrap( -1 );
m_FillModeCtrl = new wxRadioBox( this, wxID_ANY, _("Filling Mode:"), wxDefaultPosition, wxDefaultSize, m_FillModeCtrlNChoices, m_FillModeCtrlChoices, 1, wxRA_SPECIFY_COLS ); bSizerLeft->Add( m_staticTextLayerSelection, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_FillModeCtrl->SetSelection( 0 );
sbLeftSizer_->Add( m_FillModeCtrl, 0, wxALL|wxEXPAND, 5 );
m_MinThicknessValueTitle = new wxStaticText( this, wxID_ANY, _("Zone min thickness value"), wxDefaultPosition, wxDefaultSize, 0 ); m_LayerSelectionCtrl = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
m_MinThicknessValueTitle->Wrap( -1 ); bSizerLeft->Add( m_LayerSelectionCtrl, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
sbLeftSizer_->Add( m_MinThicknessValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_ZoneMinThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
sbLeftSizer_->Add( m_ZoneMinThicknessCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_UpperSizer->Add( bSizerLeft, 1, wxEXPAND, 5 );
m_UpperSizer->Add( sbLeftSizer_, 0, 0, 5 ); wxBoxSizer* bSizerRight;
bSizerRight = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* m_OutilinesBoxOpt; wxStaticBoxSizer* m_OutilinesBoxOpt;
m_OutilinesBoxOpt = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Outlines Options:") ), wxVERTICAL ); m_OutilinesBoxOpt = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Outlines Options:") ), wxVERTICAL );
...@@ -50,39 +47,41 @@ DialogNonCopperZonesPropertiesBase::DialogNonCopperZonesPropertiesBase( wxWindow ...@@ -50,39 +47,41 @@ DialogNonCopperZonesPropertiesBase::DialogNonCopperZonesPropertiesBase( wxWindow
int m_OrientEdgesOptNChoices = sizeof( m_OrientEdgesOptChoices ) / sizeof( wxString ); int m_OrientEdgesOptNChoices = sizeof( m_OrientEdgesOptChoices ) / sizeof( wxString );
m_OrientEdgesOpt = new wxRadioBox( this, wxID_ANY, _("Zone Edges Orient"), wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptNChoices, m_OrientEdgesOptChoices, 1, wxRA_SPECIFY_COLS ); m_OrientEdgesOpt = new wxRadioBox( this, wxID_ANY, _("Zone Edges Orient"), wxDefaultPosition, wxDefaultSize, m_OrientEdgesOptNChoices, m_OrientEdgesOptChoices, 1, wxRA_SPECIFY_COLS );
m_OrientEdgesOpt->SetSelection( 0 ); m_OrientEdgesOpt->SetSelection( 0 );
m_OutilinesBoxOpt->Add( m_OrientEdgesOpt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); m_OutilinesBoxOpt->Add( m_OrientEdgesOpt, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
wxString m_OutlineAppearanceCtrlChoices[] = { _("Line"), _("Hatched Outline"), _("Full Hatched") }; wxString m_OutlineAppearanceCtrlChoices[] = { _("Line"), _("Hatched Outline"), _("Full Hatched") };
int m_OutlineAppearanceCtrlNChoices = sizeof( m_OutlineAppearanceCtrlChoices ) / sizeof( wxString ); int m_OutlineAppearanceCtrlNChoices = sizeof( m_OutlineAppearanceCtrlChoices ) / sizeof( wxString );
m_OutlineAppearanceCtrl = new wxRadioBox( this, wxID_ANY, _("Outlines Appearence"), wxDefaultPosition, wxDefaultSize, m_OutlineAppearanceCtrlNChoices, m_OutlineAppearanceCtrlChoices, 1, wxRA_SPECIFY_COLS ); m_OutlineAppearanceCtrl = new wxRadioBox( this, wxID_ANY, _("Outlines Appearence"), wxDefaultPosition, wxDefaultSize, m_OutlineAppearanceCtrlNChoices, m_OutlineAppearanceCtrlChoices, 1, wxRA_SPECIFY_COLS );
m_OutlineAppearanceCtrl->SetSelection( 1 ); m_OutlineAppearanceCtrl->SetSelection( 1 );
m_OutilinesBoxOpt->Add( m_OutlineAppearanceCtrl, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 ); m_OutilinesBoxOpt->Add( m_OutlineAppearanceCtrl, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_UpperSizer->Add( m_OutilinesBoxOpt, 0, 0, 5 ); bSizerRight->Add( m_OutilinesBoxOpt, 0, wxEXPAND|wxALL, 5 );
wxBoxSizer* m_ButtonsSizer; m_MinThicknessValueTitle = new wxStaticText( this, wxID_ANY, _("Zone min thickness value"), wxDefaultPosition, wxDefaultSize, 0 );
m_ButtonsSizer = new wxBoxSizer( wxVERTICAL ); m_MinThicknessValueTitle->Wrap( -1 );
bSizerRight->Add( m_MinThicknessValueTitle, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_buttonOk = new wxButton( this, wxID_OK, _("OK"), wxDefaultPosition, wxDefaultSize, 0 );
m_buttonOk->SetDefault();
m_ButtonsSizer->Add( m_buttonOk, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_buttonCancel = new wxButton( this, wxID_CANCEL, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0 ); m_ZoneMinThicknessCtrl = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_ButtonsSizer->Add( m_buttonCancel, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); bSizerRight->Add( m_ZoneMinThicknessCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
m_UpperSizer->Add( m_ButtonsSizer, 1, wxALIGN_CENTER_VERTICAL, 5 ); m_UpperSizer->Add( bSizerRight, 0, wxEXPAND, 5 );
m_MainSizer->Add( m_UpperSizer, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 ); m_MainSizer->Add( m_UpperSizer, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL, 5 );
m_staticTextLayerSelection = new wxStaticText( this, wxID_ANY, _("Layer selection:"), wxDefaultPosition, wxDefaultSize, 0 ); m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
m_staticTextLayerSelection->Wrap( -1 ); m_MainSizer->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
m_MainSizer->Add( m_staticTextLayerSelection, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_LayerSelectionCtrl = new wxListBox( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); m_sdbSizerButtons = new wxStdDialogButtonSizer();
m_MainSizer->Add( m_LayerSelectionCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); m_sdbSizerButtonsOK = new wxButton( this, wxID_OK );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsOK );
m_sdbSizerButtonsCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizerButtons->AddButton( m_sdbSizerButtonsCancel );
m_sdbSizerButtons->Realize();
m_MainSizer->Add( m_sdbSizerButtons, 0, wxEXPAND, 5 );
this->SetSizer( m_MainSizer ); this->SetSizer( m_MainSizer );
......
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 11 2012) // C++ code generated with wxFormBuilder (version Apr 10 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -13,17 +13,18 @@ ...@@ -13,17 +13,18 @@
#include <wx/intl.h> #include <wx/intl.h>
#include "dialog_shim.h" #include "dialog_shim.h"
#include <wx/string.h> #include <wx/string.h>
#include <wx/radiobox.h> #include <wx/stattext.h>
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
#include <wx/font.h> #include <wx/font.h>
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/stattext.h> #include <wx/listbox.h>
#include <wx/textctrl.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/radiobox.h>
#include <wx/statbox.h> #include <wx/statbox.h>
#include <wx/textctrl.h>
#include <wx/statline.h>
#include <wx/button.h> #include <wx/button.h>
#include <wx/listbox.h>
#include <wx/dialog.h> #include <wx/dialog.h>
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
...@@ -37,29 +38,30 @@ class DialogNonCopperZonesPropertiesBase : public DIALOG_SHIM ...@@ -37,29 +38,30 @@ class DialogNonCopperZonesPropertiesBase : public DIALOG_SHIM
private: private:
// Private event handlers // Private event handlers
void _wxFB_OnOkClick( wxCommandEvent& event ){ OnOkClick( event ); }
void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); } void _wxFB_OnCancelClick( wxCommandEvent& event ){ OnCancelClick( event ); }
void _wxFB_OnOkClick( wxCommandEvent& event ){ OnOkClick( event ); }
protected: protected:
wxRadioBox* m_FillModeCtrl;
wxStaticText* m_MinThicknessValueTitle;
wxTextCtrl* m_ZoneMinThicknessCtrl;
wxRadioBox* m_OrientEdgesOpt;
wxRadioBox* m_OutlineAppearanceCtrl;
wxButton* m_buttonOk;
wxButton* m_buttonCancel;
wxStaticText* m_staticTextLayerSelection; wxStaticText* m_staticTextLayerSelection;
wxListBox* m_LayerSelectionCtrl; wxListBox* m_LayerSelectionCtrl;
wxRadioBox* m_OrientEdgesOpt;
wxRadioBox* m_OutlineAppearanceCtrl;
wxStaticText* m_MinThicknessValueTitle;
wxTextCtrl* m_ZoneMinThicknessCtrl;
wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizerButtons;
wxButton* m_sdbSizerButtonsOK;
wxButton* m_sdbSizerButtonsCancel;
// Virtual event handlers, overide them in your derived class // Virtual event handlers, overide them in your derived class
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); } virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
public: public:
DialogNonCopperZonesPropertiesBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Non Copper Zones Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 416,287 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER ); DialogNonCopperZonesPropertiesBase( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Non Copper Zones Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 369,317 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxSUNKEN_BORDER );
~DialogNonCopperZonesPropertiesBase(); ~DialogNonCopperZonesPropertiesBase();
}; };
......
...@@ -479,6 +479,7 @@ void DIALOG_PAD_PROPERTIES::initValues() ...@@ -479,6 +479,7 @@ void DIALOG_PAD_PROPERTIES::initValues()
wxCommandEvent cmd_event; wxCommandEvent cmd_event;
setPadLayersList( m_dummyPad->GetLayerMask() ); setPadLayersList( m_dummyPad->GetLayerMask() );
OnDrillShapeSelected( cmd_event ); OnDrillShapeSelected( cmd_event );
OnPadShapeSelection( cmd_event );
} }
......
...@@ -135,27 +135,9 @@ void DIALOG_PCB_TEXT_PROPERTIES::MyInit() ...@@ -135,27 +135,9 @@ void DIALOG_PCB_TEXT_PROPERTIES::MyInit()
} }
} }
switch( (int) m_SelectedPCBText->GetOrientation() ) wxString orientationStr;
{ orientationStr << m_SelectedPCBText->GetOrientation();
default: m_OrientationCtrl->SetValue( orientationStr );
m_OrientationCtrl->SetSelection( 0 );
break;
case 900:
case -2700:
m_OrientationCtrl->SetSelection( 1 );
break;
case 1800:
case -1800:
m_OrientationCtrl->SetSelection( 2 );
break;
case 2700:
case -900:
m_OrientationCtrl->SetSelection( 3 );
break;
}
if( m_SelectedPCBText->m_Mirror ) if( m_SelectedPCBText->m_Mirror )
m_DisplayCtrl->SetSelection( 1 ); m_DisplayCtrl->SetSelection( 1 );
...@@ -263,7 +245,10 @@ void DIALOG_PCB_TEXT_PROPERTIES::OnOkClick( wxCommandEvent& event ) ...@@ -263,7 +245,10 @@ void DIALOG_PCB_TEXT_PROPERTIES::OnOkClick( wxCommandEvent& event )
m_SelectedPCBText->m_Mirror = (m_DisplayCtrl->GetSelection() == 1) ? true : false; m_SelectedPCBText->m_Mirror = (m_DisplayCtrl->GetSelection() == 1) ? true : false;
// Set the text orientation // Set the text orientation
m_SelectedPCBText->m_Orient = m_OrientationCtrl->GetSelection() * 900; long orientation;
m_OrientationCtrl->GetValue().ToLong( &orientation );
orientation = orientation % 3600;
m_SelectedPCBText->SetOrientation( orientation );
// Set whether the PCB text is slanted (it is not italics, as italics has additional curves in style) // Set whether the PCB text is slanted (it is not italics, as italics has additional curves in style)
m_SelectedPCBText->m_Italic = m_StyleCtrl->GetSelection() ? 1 : 0; m_SelectedPCBText->m_Italic = m_StyleCtrl->GetSelection() ? 1 : 0;
......
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Mar 19 2012) // C++ code generated with wxFormBuilder (version Apr 11 2012)
// http://www.wxformbuilder.org/ // http://www.wxformbuilder.org/
// //
// PLEASE DO "NOT" EDIT THIS FILE! // PLEASE DO "NOT" EDIT THIS FILE!
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/textctrl.h> #include <wx/textctrl.h>
#include <wx/sizer.h>
#include <wx/choice.h> #include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/button.h> #include <wx/button.h>
#include <wx/dialog.h> #include <wx/dialog.h>
...@@ -38,25 +38,25 @@ class DIALOG_PCB_TEXT_PROPERTIES_BASE : public DIALOG_SHIM ...@@ -38,25 +38,25 @@ class DIALOG_PCB_TEXT_PROPERTIES_BASE : public DIALOG_SHIM
wxStaticText* m_TextLabel; wxStaticText* m_TextLabel;
wxTextCtrl* m_TextContentCtrl; wxTextCtrl* m_TextContentCtrl;
wxStaticText* m_SizeXLabel; wxStaticText* m_SizeXLabel;
wxTextCtrl* m_SizeXCtrl;
wxStaticText* m_SizeYLabel;
wxTextCtrl* m_SizeYCtrl;
wxStaticText* m_ThicknessLabel;
wxTextCtrl* m_ThicknessCtrl;
wxStaticText* m_PositionXLabel; wxStaticText* m_PositionXLabel;
wxTextCtrl* m_PositionXCtrl;
wxStaticText* m_PositionYLabel;
wxTextCtrl* m_PositionYCtrl;
wxStaticText* m_LayerLabel; wxStaticText* m_LayerLabel;
wxChoice* m_LayerSelectionCtrl;
wxStaticText* m_staticText8;
wxChoice* m_OrientationCtrl;
wxStaticText* m_staticText9;
wxChoice* m_StyleCtrl;
wxStaticText* m_staticText10; wxStaticText* m_staticText10;
wxTextCtrl* m_SizeXCtrl;
wxTextCtrl* m_PositionXCtrl;
wxChoice* m_LayerSelectionCtrl;
wxChoice* m_DisplayCtrl; wxChoice* m_DisplayCtrl;
wxStaticText* m_SizeYLabel;
wxStaticText* m_PositionYLabel;
wxStaticText* m_staticText9;
wxStaticText* m_staticText11; wxStaticText* m_staticText11;
wxTextCtrl* m_SizeYCtrl;
wxTextCtrl* m_PositionYCtrl;
wxChoice* m_StyleCtrl;
wxChoice* m_justifyChoice; wxChoice* m_justifyChoice;
wxStaticText* m_ThicknessLabel;
wxStaticText* m_orientationLabel;
wxTextCtrl* m_ThicknessCtrl;
wxTextCtrl* m_OrientationCtrl;
wxStdDialogButtonSizer* m_StandardSizer; wxStdDialogButtonSizer* m_StandardSizer;
wxButton* m_StandardSizerOK; wxButton* m_StandardSizerOK;
wxButton* m_StandardSizerCancel; wxButton* m_StandardSizerCancel;
...@@ -69,7 +69,7 @@ class DIALOG_PCB_TEXT_PROPERTIES_BASE : public DIALOG_SHIM ...@@ -69,7 +69,7 @@ class DIALOG_PCB_TEXT_PROPERTIES_BASE : public DIALOG_SHIM
public: public:
DIALOG_PCB_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 433,465 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU ); DIALOG_PCB_TEXT_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 433,450 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU );
~DIALOG_PCB_TEXT_PROPERTIES_BASE(); ~DIALOG_PCB_TEXT_PROPERTIES_BASE();
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment