Symbol Library Editor refactor

NEW: Component Tree widget in the Symbol Library Editor
NEW: Multiple contexts enable switching between modified components
NEW: Cut/Copy/Paste to transfer components between libraries
NEW: Cut/Copy/Paste for symbol graphical items
CHANGE: Redone menu and toolbar in the Symbol Library Editor
CHANGE: Modified a few icosn to make the user interface look more
    coherent (new icons: import/export part, new library, add library;
    modified: save part)
This commit is contained in:
Maciej Suminski 2017-11-21 23:41:13 +01:00
commit 527c6f0014
71 changed files with 5797 additions and 2306 deletions

View File

@ -123,6 +123,7 @@ set( BMAPS_MID
add_hierarchical_subsheet
add_junction
add_keepout_area
add_library
add_line2bus
add_line_label
add_line
@ -227,6 +228,7 @@ set( BMAPS_MID
export_idf
export_footprint_names
export_module
export_part
export
fabrication
file_footprint
@ -275,6 +277,7 @@ set( BMAPS_MID
import_footprint_names
import_hierarchical_label
import_module
import_part
import_setup
import
info
@ -466,6 +469,7 @@ set( BMAPS_MID
rotate_pos_z
save_as
save_library
save_part
save_part_in_mem
save_project
save_setup
@ -483,6 +487,7 @@ set( BMAPS_MID
sim_probe
sim_add_signal
sim_settings
search_tree
setcolor_3d_bg
setcolor_silkscreen
setcolor_soldermask

View File

@ -0,0 +1,83 @@
/* 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, 0x1e, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xad, 0xd6, 0x7d, 0x4c, 0x13,
0x67, 0x1c, 0x07, 0xf0, 0x03, 0x13, 0xb3, 0xb1, 0x7f, 0x97, 0x2c, 0x7b, 0x49, 0xda, 0x7b, 0x0e,
0x46, 0xad, 0xae, 0x36, 0x2a, 0x06, 0x34, 0x8e, 0xd2, 0x2b, 0x25, 0x5b, 0x70, 0xc1, 0x69, 0x7d,
0xe9, 0xb6, 0x90, 0xc5, 0xea, 0x64, 0xbe, 0xc4, 0x89, 0x94, 0xbe, 0xce, 0x66, 0x4a, 0xb6, 0xb1,
0xe9, 0xe6, 0x1b, 0x2f, 0xc1, 0x01, 0x31, 0x0c, 0x6d, 0xa9, 0x22, 0x2f, 0xa2, 0x09, 0x8e, 0x81,
0x28, 0xb0, 0x01, 0x43, 0xcc, 0xd5, 0x21, 0xa0, 0xc6, 0x11, 0x92, 0xbd, 0x64, 0xa4, 0x34, 0x5a,
0xb4, 0x14, 0x7f, 0x7b, 0xee, 0x8e, 0x97, 0xca, 0xb5, 0x61, 0x6d, 0x7a, 0xc9, 0x37, 0xf7, 0xe4,
0x7a, 0x7d, 0x3e, 0x7d, 0xee, 0xf9, 0xf5, 0x79, 0x8e, 0x20, 0xe6, 0x1d, 0x2a, 0x0b, 0xfa, 0x2a,
0xcd, 0x4c, 0x56, 0xd1, 0x06, 0xf4, 0xa9, 0x32, 0x9f, 0x5a, 0xa3, 0x3e, 0xf8, 0xca, 0x4b, 0xc4,
0xff, 0x38, 0x3a, 0x1c, 0xc4, 0x8b, 0x8c, 0x9d, 0xf0, 0x31, 0x35, 0x31, 0x93, 0x82, 0xe0, 0xeb,
0x82, 0x2f, 0x28, 0x2d, 0x68, 0x24, 0xe9, 0x04, 0x05, 0xc9, 0x47, 0xc9, 0xc7, 0xa9, 0x36, 0x34,
0xae, 0x32, 0xa2, 0x49, 0xda, 0x42, 0x8e, 0x2a, 0xcd, 0x64, 0x7d, 0xba, 0x1e, 0xad, 0x0a, 0x05,
0xf5, 0x34, 0x10, 0x71, 0x8c, 0x83, 0x00, 0x7f, 0x7f, 0xa2, 0x20, 0xec, 0xf5, 0xe7, 0x6e, 0x5e,
0x6f, 0x7b, 0x2d, 0x8e, 0xed, 0x38, 0xe1, 0x62, 0x3c, 0xc4, 0x5f, 0xe2, 0x93, 0x50, 0x1b, 0x0f,
0xd2, 0x1f, 0x29, 0x50, 0x58, 0x49, 0xaf, 0xca, 0x20, 0x56, 0x2c, 0x04, 0x01, 0x23, 0x15, 0x44,
0x00, 0xa9, 0xf4, 0xe2, 0x64, 0x76, 0x14, 0x2c, 0x20, 0xad, 0x97, 0x42, 0xca, 0xd5, 0x94, 0x59,
0x8c, 0x36, 0x22, 0x9f, 0x22, 0x77, 0xe5, 0xcb, 0x84, 0xc6, 0xb1, 0x48, 0x10, 0x9b, 0x2d, 0x56,
0x00, 0x79, 0x5a, 0x42, 0x43, 0xe9, 0x06, 0xf1, 0xae, 0x94, 0x42, 0xf4, 0x98, 0xed, 0x5c, 0x7b,
0x43, 0x0b, 0x6d, 0x7f, 0xb5, 0x71, 0xd0, 0x92, 0x73, 0x14, 0x28, 0x4d, 0xe8, 0x6f, 0x42, 0xe5,
0x80, 0x60, 0x89, 0x51, 0xd7, 0x78, 0x04, 0x90, 0xdf, 0x13, 0x1a, 0xc2, 0x9d, 0x55, 0xac, 0x28,
0xa6, 0xb8, 0xce, 0x0f, 0xdf, 0x3e, 0x0c, 0x25, 0x83, 0x25, 0x5c, 0x7b, 0xf9, 0x19, 0x0a, 0xd2,
0xcc, 0xe8, 0x1a, 0xdb, 0x69, 0xd6, 0x29, 0x1f, 0x6c, 0x2c, 0x9e, 0x9a, 0xcd, 0xbb, 0xc7, 0x1e,
0x41, 0xac, 0xda, 0xe9, 0x0d, 0x0b, 0xc2, 0xd5, 0xf6, 0xfb, 0xb2, 0xb3, 0x3c, 0xe4, 0x7c, 0xe8,
0x84, 0xfd, 0xdd, 0xfb, 0xb9, 0xf6, 0xea, 0xe3, 0xd4, 0x24, 0x6d, 0x22, 0xbf, 0x60, 0xa1, 0xf7,
0x8b, 0xfc, 0xa0, 0x29, 0x85, 0xd9, 0x64, 0x7e, 0xef, 0x0d, 0x0f, 0xd2, 0x68, 0x88, 0x45, 0xb8,
0x10, 0x9e, 0xbe, 0xe9, 0xe4, 0x21, 0x97, 0xdb, 0x05, 0xea, 0x6b, 0x6a, 0xae, 0xbd, 0xae, 0x00,
0xb9, 0x69, 0x3d, 0x95, 0x15, 0x15, 0x48, 0xa5, 0x17, 0x2d, 0x51, 0x5a, 0xc8, 0x47, 0x6c, 0xc7,
0x92, 0x7a, 0x09, 0x8c, 0xfb, 0xc6, 0x21, 0xb1, 0x2e, 0x91, 0x83, 0x70, 0x69, 0x7b, 0x15, 0x06,
0x89, 0x38, 0x10, 0x6a, 0xe8, 0x8f, 0x10, 0x4a, 0x37, 0xa0, 0x6d, 0x6b, 0xbf, 0xe4, 0x2b, 0x2e,
0xf3, 0xe7, 0x4c, 0xe8, 0x1b, 0xeb, 0xe3, 0x90, 0x44, 0x07, 0x85, 0x2b, 0x8e, 0xf4, 0x12, 0x84,
0x2d, 0x36, 0x10, 0xf2, 0x4c, 0x44, 0x08, 0x29, 0x8d, 0xe4, 0x37, 0x2b, 0x4f, 0xa2, 0x29, 0xb6,
0x73, 0x7d, 0xaf, 0x1e, 0xaa, 0x1f, 0x54, 0x73, 0x90, 0xac, 0x92, 0x1d, 0x11, 0xea, 0x25, 0x08,
0x88, 0x89, 0x0e, 0x64, 0x25, 0x3b, 0x64, 0x15, 0xfc, 0xfc, 0x94, 0x0f, 0x97, 0x83, 0xf5, 0x96,
0x95, 0x6b, 0xaf, 0x3a, 0x4d, 0x3d, 0x53, 0x99, 0xc9, 0x93, 0x51, 0x83, 0x70, 0x55, 0x8d, 0x4b,
0xec, 0x3c, 0xd4, 0xf9, 0x4f, 0x27, 0x6c, 0x6a, 0xdb, 0xc4, 0xb5, 0xd7, 0x14, 0x22, 0x0f, 0x6d,
0x14, 0x67, 0x47, 0x05, 0xca, 0x30, 0x89, 0x5e, 0xc5, 0xf3, 0xf0, 0x24, 0xbe, 0x96, 0x5f, 0x76,
0x18, 0x37, 0x03, 0xb2, 0x46, 0x19, 0xd7, 0x4e, 0xb3, 0x22, 0x4f, 0x46, 0x3e, 0xb9, 0x3c, 0x2a,
0x90, 0x32, 0x5f, 0xf4, 0xce, 0xdb, 0x47, 0x90, 0x7b, 0x66, 0x7d, 0xdb, 0x63, 0x35, 0x82, 0xde,
0x70, 0x04, 0xf4, 0x79, 0x05, 0x90, 0x75, 0x20, 0x69, 0x52, 0x63, 0x5b, 0xba, 0x38, 0x6c, 0xc8,
0xf5, 0x96, 0x10, 0xc2, 0xa3, 0x31, 0xad, 0xfe, 0x8e, 0x7a, 0x3a, 0x03, 0xd5, 0x7d, 0x7e, 0x1d,
0x98, 0x92, 0x11, 0xe8, 0xfb, 0xfa, 0x01, 0x7c, 0xbc, 0x7b, 0xc3, 0x28, 0xff, 0x70, 0xc3, 0x84,
0x82, 0x2d, 0xaa, 0xb4, 0x15, 0x35, 0xca, 0xcb, 0x10, 0xcc, 0x41, 0xed, 0xc0, 0x14, 0x8f, 0x40,
0x2f, 0x86, 0x72, 0x76, 0x7e, 0xd0, 0x12, 0x0c, 0x6a, 0xbd, 0x1b, 0x09, 0x84, 0xf7, 0x1b, 0x69,
0x35, 0x15, 0x14, 0xca, 0xcd, 0xde, 0x7d, 0x2a, 0x18, 0xb4, 0xe0, 0xca, 0x30, 0x1f, 0x62, 0x77,
0xd0, 0x7d, 0xdb, 0x75, 0xfe, 0xbd, 0x06, 0x33, 0xcc, 0xa4, 0xc9, 0xd4, 0x35, 0x0d, 0xdd, 0x87,
0xaa, 0x8c, 0xcb, 0xcd, 0x17, 0xd3, 0xbb, 0x0b, 0xd8, 0x6c, 0x53, 0x35, 0x83, 0xe6, 0x84, 0x2f,
0x32, 0x88, 0x36, 0x8a, 0x52, 0xec, 0xb9, 0x97, 0xfd, 0xec, 0x9c, 0x30, 0xa5, 0xd3, 0x61, 0xdb,
0xc5, 0xd3, 0xe7, 0xd2, 0xb9, 0xb4, 0x1f, 0x1a, 0x84, 0x0f, 0xbf, 0xf5, 0x46, 0x06, 0xa9, 0xf2,
0x51, 0x4e, 0xc5, 0x27, 0x97, 0xa6, 0x7e, 0x39, 0x34, 0x0c, 0x33, 0xe9, 0xb2, 0x0c, 0x41, 0xa7,
0x79, 0x08, 0x3a, 0x0c, 0x83, 0x70, 0x33, 0xef, 0x2e, 0xdc, 0x38, 0xc0, 0x66, 0x00, 0x9a, 0x74,
0xb7, 0x39, 0xe8, 0x33, 0x07, 0x80, 0xbd, 0x1b, 0x60, 0xcf, 0xb9, 0x10, 0xd0, 0x7d, 0x2d, 0xc0,
0x98, 0x1d, 0xe0, 0xde, 0x96, 0x80, 0x11, 0x99, 0xc9, 0xca, 0x63, 0xd9, 0x3f, 0x40, 0xb5, 0xae,
0x19, 0x5a, 0xf6, 0x32, 0xd0, 0xba, 0xef, 0x0e, 0x5c, 0xd9, 0xd1, 0x03, 0xad, 0x39, 0x77, 0xa0,
0x65, 0xa7, 0x0b, 0xae, 0x68, 0xfa, 0xef, 0x5d, 0xdd, 0x72, 0x6b, 0x90, 0x4d, 0xf9, 0x7b, 0xbf,
0x82, 0xf6, 0xe8, 0x04, 0xfc, 0x31, 0x06, 0xdc, 0x31, 0xf0, 0x67, 0x08, 0xe8, 0xc9, 0x30, 0x7f,
0xc3, 0xc4, 0xc0, 0x1c, 0x14, 0xb8, 0x07, 0xb1, 0xdb, 0xb7, 0xbc, 0x51, 0x0e, 0x67, 0x75, 0x4d,
0x1c, 0xf4, 0xd3, 0x76, 0x17, 0xd4, 0xa5, 0x76, 0xa5, 0xcd, 0x2f, 0x86, 0xdf, 0x1e, 0xf2, 0xfd,
0xb4, 0x0f, 0x85, 0x80, 0xc6, 0x2e, 0xf0, 0x37, 0xfc, 0x7b, 0x3e, 0x60, 0x44, 0x06, 0xe4, 0x93,
0x97, 0x51, 0x20, 0xb1, 0xe3, 0x8a, 0xc3, 0x2b, 0x03, 0x75, 0x81, 0x7a, 0x0e, 0xaa, 0x59, 0x77,
0x9d, 0xc6, 0x4a, 0x4c, 0x20, 0xa4, 0x3d, 0x03, 0x60, 0xac, 0x05, 0xd8, 0x5a, 0x16, 0x6a, 0x8e,
0x96, 0xe2, 0xe1, 0x2a, 0xf8, 0xf3, 0x1c, 0x44, 0x16, 0x2a, 0x8c, 0x64, 0x87, 0x22, 0x4f, 0xec,
0x49, 0x3d, 0x28, 0x9a, 0x48, 0x36, 0x8b, 0xdc, 0x55, 0x1f, 0x35, 0x3d, 0xe3, 0x1e, 0x9d, 0xce,
0x05, 0xa7, 0x93, 0xec, 0xeb, 0x31, 0x84, 0xdf, 0xed, 0xc4, 0x2f, 0x10, 0xf4, 0x79, 0xbe, 0xbc,
0x4b, 0x60, 0x36, 0x61, 0xfd, 0x8f, 0xf8, 0x5f, 0x4c, 0x2c, 0x96, 0x6f, 0x7c, 0x23, 0x61, 0xed,
0x8e, 0xd7, 0x37, 0x1f, 0xdf, 0x50, 0xd6, 0x53, 0xb4, 0xb9, 0x72, 0xd4, 0x99, 0xd9, 0xd9, 0x60,
0x5b, 0x56, 0x24, 0xc3, 0x9f, 0xc5, 0xf1, 0x90, 0x7d, 0xc1, 0x97, 0x13, 0xfc, 0xb2, 0x28, 0x0c,
0xbe, 0xfe, 0x1f, 0x61, 0x1f, 0xc8, 0xed, 0xe9, 0xe0, 0xae, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x49,
0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE add_library_xpm[1] = {{ png, sizeof( png ), "add_library_xpm" }};
//EOF

View File

@ -0,0 +1,69 @@
/* Do not modify this file, it was automatically generated by the
* PNG2cpp CMake script, using a *.png file as input.
*/
#include <bitmaps.h>
static const unsigned char png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
0xce, 0x00, 0x00, 0x03, 0x3c, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xb5, 0x96, 0x7b, 0x48, 0x53,
0x51, 0x1c, 0xc7, 0xef, 0x9c, 0xc6, 0x8a, 0xfe, 0xc9, 0xfe, 0x8a, 0xe8, 0xaf, 0xca, 0x3f, 0x12,
0x04, 0xff, 0xc8, 0xf7, 0x4c, 0xc2, 0x08, 0x09, 0x7a, 0x91, 0x98, 0xd1, 0x0b, 0x05, 0xd3, 0x68,
0x62, 0x2f, 0xc2, 0x12, 0x73, 0xbe, 0x89, 0xfc, 0x23, 0x84, 0x95, 0xa1, 0xfd, 0x13, 0x81, 0xb8,
0xa9, 0x69, 0x39, 0x9d, 0xb3, 0xcd, 0x6d, 0xce, 0xbd, 0xe7, 0x1e, 0xee, 0xe5, 0x36, 0xcd, 0xc8,
0x9a, 0x56, 0xa8, 0x85, 0x6b, 0x13, 0xb7, 0x5f, 0xe7, 0x5c, 0x9d, 0x98, 0x48, 0x6e, 0xe6, 0x2e,
0x7c, 0xb9, 0xe7, 0x9e, 0x7b, 0xcf, 0xf9, 0xdc, 0xdf, 0xef, 0xf7, 0x3d, 0x9c, 0x43, 0x10, 0xeb,
0xae, 0x0a, 0x82, 0x38, 0x82, 0x6e, 0x14, 0x22, 0x9c, 0x17, 0x82, 0x24, 0x20, 0x01, 0x93, 0x42,
0xe9, 0xaf, 0x26, 0x88, 0x03, 0xe1, 0x04, 0x65, 0x60, 0x50, 0x05, 0x85, 0x02, 0x4c, 0x2a, 0xf5,
0x17, 0x6a, 0x5f, 0x0f, 0x2b, 0x48, 0xd3, 0xd2, 0x02, 0xaf, 0xd2, 0xd3, 0xfd, 0x2b, 0xd1, 0xf5,
0xa1, 0xe8, 0xf6, 0x87, 0x05, 0x64, 0xe7, 0xf3, 0xc1, 0xeb, 0xf5, 0x82, 0x82, 0xc5, 0x82, 0x2a,
0x1a, 0xcd, 0xc7, 0x8c, 0x88, 0xf8, 0x89, 0xfa, 0x0b, 0xc2, 0x02, 0x5a, 0x5c, 0x5c, 0x24, 0x35,
0x63, 0xb3, 0x41, 0x4b, 0x6a, 0xaa, 0x6f, 0x25, 0xa5, 0x3d, 0x35, 0x04, 0xb1, 0x2f, 0x2c, 0x20,
0x2c, 0xaf, 0xc7, 0x03, 0xd2, 0x86, 0x06, 0xa8, 0x8c, 0x8a, 0xf2, 0x55, 0x52, 0xa9, 0xdf, 0xd1,
0x37, 0xe7, 0xc3, 0x02, 0x0a, 0xe8, 0x8b, 0x5e, 0x0f, 0x2f, 0xe2, 0xe3, 0x03, 0xd1, 0xb1, 0x6b,
0x09, 0x62, 0x6f, 0xd0, 0x93, 0x33, 0x09, 0x82, 0x81, 0x06, 0xf2, 0xb1, 0x50, 0x5b, 0x8d, 0x27,
0x31, 0xb2, 0xd9, 0xe4, 0xc4, 0x73, 0x53, 0x53, 0x64, 0xea, 0x02, 0xc2, 0xcf, 0x1e, 0xb7, 0x1b,
0x44, 0x35, 0x35, 0x50, 0x19, 0x19, 0xe9, 0x43, 0xce, 0xfc, 0x86, 0xc6, 0x9c, 0xf9, 0x2f, 0x90,
0x7b, 0x7e, 0x1e, 0xaa, 0x69, 0x34, 0x20, 0xff, 0x7e, 0x45, 0xf8, 0x19, 0xf7, 0xe3, 0x9f, 0x98,
0xd2, 0x6a, 0x81, 0x15, 0x17, 0xb7, 0xb4, 0xf2, 0xae, 0xad, 0x8e, 0x20, 0xf6, 0x6c, 0x39, 0x75,
0x1b, 0x45, 0xb4, 0x36, 0x95, 0x9e, 0x85, 0x85, 0x40, 0x74, 0x7e, 0x54, 0xbb, 0xcf, 0x68, 0x6c,
0xe6, 0xb6, 0xd4, 0x68, 0xbd, 0x26, 0xb8, 0x2e, 0x98, 0x1e, 0x99, 0x85, 0x8f, 0x52, 0x29, 0x34,
0xc6, 0xc4, 0xe0, 0xe8, 0xf0, 0xda, 0x6b, 0x42, 0xda, 0xbd, 0x25, 0x50, 0x20, 0x5d, 0xeb, 0x25,
0x2b, 0x1b, 0x03, 0xde, 0x25, 0x3d, 0x18, 0x58, 0x93, 0xe0, 0x9e, 0x9b, 0x87, 0xde, 0x92, 0x12,
0xbc, 0xc0, 0xfd, 0xc8, 0x28, 0x6e, 0x34, 0x8f, 0x68, 0x4d, 0x49, 0x18, 0x9b, 0x82, 0xe6, 0x5d,
0x2e, 0xb2, 0x36, 0xf8, 0xbe, 0x11, 0x48, 0x55, 0xe5, 0x00, 0xe9, 0x3d, 0x1b, 0x7c, 0xc8, 0x37,
0x02, 0xf7, 0x66, 0xe9, 0xd6, 0x40, 0xb8, 0x26, 0x13, 0x12, 0x09, 0x69, 0x04, 0x7c, 0x5f, 0x5f,
0x23, 0x0c, 0x52, 0x94, 0xdb, 0x61, 0xb0, 0xd0, 0x0c, 0xb2, 0x07, 0x63, 0xd0, 0x71, 0x9c, 0x07,
0x8d, 0xfb, 0x72, 0x78, 0x21, 0xa5, 0x2e, 0xe0, 0xba, 0xfa, 0x5d, 0x87, 0xa1, 0xf3, 0x84, 0x00,
0x7a, 0x73, 0x84, 0xa4, 0x44, 0x0c, 0xf3, 0xaa, 0x84, 0x85, 0x26, 0x50, 0x55, 0x3b, 0x61, 0xe0,
0xaa, 0x11, 0xf8, 0x97, 0x0d, 0x28, 0x32, 0x2b, 0xf0, 0x72, 0x0d, 0x3f, 0x38, 0xc9, 0xf2, 0x26,
0x61, 0x86, 0x30, 0x32, 0xa4, 0x75, 0x34, 0xfa, 0x66, 0x08, 0x44, 0xc5, 0x1a, 0xd0, 0x3f, 0x9b,
0x04, 0x4d, 0xdd, 0x38, 0xa8, 0xab, 0x9c, 0xa0, 0x7c, 0xec, 0x00, 0x59, 0xe9, 0x18, 0x48, 0xef,
0x5a, 0x41, 0x52, 0x6c, 0x21, 0x41, 0xfd, 0xb9, 0x7a, 0xe8, 0xbb, 0xa0, 0x03, 0x61, 0x81, 0x09,
0x44, 0x45, 0xe6, 0xc5, 0x8e, 0x34, 0x95, 0xa5, 0x35, 0x45, 0x7a, 0x30, 0x28, 0x10, 0xd6, 0x27,
0xf1, 0x24, 0x02, 0x69, 0x41, 0x5b, 0x3f, 0x0e, 0xf2, 0x87, 0x63, 0x30, 0x7c, 0xdf, 0x06, 0x43,
0xb7, 0xad, 0x20, 0xbe, 0x65, 0x81, 0xc1, 0x1b, 0x26, 0x10, 0xe4, 0x8f, 0xfe, 0x05, 0xe2, 0x9e,
0x1d, 0x81, 0xbe, 0x6c, 0x3d, 0xf9, 0xbe, 0x3b, 0x4b, 0xed, 0x6a, 0x4f, 0x56, 0xe4, 0x07, 0xe5,
0xba, 0x69, 0xdd, 0x2c, 0xc8, 0x1f, 0xd9, 0x43, 0x02, 0xbd, 0x3f, 0xa5, 0x85, 0x77, 0x59, 0x1a,
0x32, 0x3a, 0x5e, 0xb6, 0x7e, 0x96, 0x93, 0x24, 0x6b, 0x0d, 0x0e, 0x54, 0x16, 0x3a, 0x08, 0xb7,
0x07, 0x8b, 0xcc, 0xd0, 0x75, 0x52, 0xf5, 0x95, 0x9d, 0xa0, 0xd8, 0xdc, 0xde, 0x4e, 0xae, 0x09,
0xc4, 0x77, 0x74, 0x41, 0x83, 0x7a, 0xcf, 0x8d, 0xa0, 0x7e, 0x33, 0x08, 0xf2, 0x46, 0x7f, 0x77,
0xd0, 0xe5, 0x86, 0xb6, 0xe4, 0xe1, 0x43, 0x41, 0x6d, 0x7c, 0x4f, 0xa3, 0xe3, 0x7d, 0x82, 0x3c,
0x8d, 0x5f, 0xfb, 0x64, 0x1c, 0x34, 0xb5, 0x4e, 0x64, 0x06, 0x07, 0xa8, 0x98, 0x0e, 0x64, 0x6b,
0x07, 0x02, 0xdb, 0x49, 0x73, 0x04, 0x40, 0x03, 0x57, 0x8c, 0xa4, 0x41, 0x7a, 0x4e, 0x8f, 0x4c,
0x23, 0xe7, 0x31, 0x2b, 0x08, 0x88, 0xf8, 0xa7, 0xbd, 0xd5, 0xcd, 0xcd, 0xab, 0x5b, 0x79, 0x4d,
0x54, 0xf4, 0x40, 0x6b, 0x62, 0x77, 0x79, 0x3b, 0x5d, 0x55, 0xb2, 0x2c, 0xf9, 0xb2, 0x52, 0x91,
0xd2, 0x14, 0x3a, 0xbc, 0x8e, 0x06, 0xae, 0x19, 0x49, 0xf7, 0x49, 0x18, 0x16, 0x6f, 0xe7, 0x31,
0xa5, 0x89, 0x73, 0x54, 0x19, 0xbb, 0xad, 0x87, 0x13, 0x04, 0x66, 0x2b, 0xc9, 0xe8, 0xec, 0xc0,
0xbb, 0xa8, 0x9f, 0xe1, 0xa4, 0xc8, 0x5f, 0xb6, 0xc5, 0x9a, 0x76, 0x6c, 0xfb, 0x71, 0x0b, 0x83,
0xc4, 0xc5, 0xd6, 0xa5, 0xae, 0x4c, 0xb5, 0xf3, 0x6d, 0x92, 0x3a, 0x31, 0xd4, 0x5d, 0x36, 0xe8,
0x03, 0x24, 0x87, 0xae, 0x78, 0xde, 0x41, 0x57, 0xbe, 0x46, 0x05, 0xdf, 0xb9, 0xd9, 0xb7, 0x7f,
0x00, 0x15, 0xb1, 0xf0, 0x25, 0x56, 0x5d, 0x02, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e,
0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE export_part_xpm[1] = {{ png, sizeof( png ), "export_part_xpm" }};
//EOF

View File

@ -0,0 +1,64 @@
/* Do not modify this file, it was automatically generated by the
* PNG2cpp CMake script, using a *.png file as input.
*/
#include <bitmaps.h>
static const unsigned char png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
0xce, 0x00, 0x00, 0x02, 0xf2, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xb5, 0x96, 0x5f, 0x48, 0x53,
0x51, 0x1c, 0xc7, 0xcf, 0xdc, 0xbd, 0x77, 0x7f, 0x9c, 0xff, 0x8a, 0x1e, 0x2c, 0x82, 0x08, 0x14,
0xf4, 0x41, 0x91, 0xa8, 0x17, 0x6b, 0xa9, 0x29, 0x66, 0xa5, 0xa6, 0x96, 0xa9, 0xe8, 0x34, 0x2b,
0x53, 0x68, 0x69, 0x2f, 0x51, 0x38, 0xa6, 0x9b, 0xae, 0x10, 0x19, 0x3d, 0x58, 0xcb, 0x85, 0x5b,
0x45, 0x64, 0x7f, 0x96, 0xfd, 0x5f, 0xe9, 0x2c, 0xc8, 0x42, 0xc2, 0x50, 0x49, 0x7b, 0x49, 0x44,
0xea, 0x21, 0x43, 0x56, 0x84, 0x26, 0xae, 0x4d, 0xda, 0x7e, 0x9d, 0x73, 0xd9, 0x2d, 0x35, 0x67,
0xd3, 0x76, 0x0f, 0x7c, 0xb9, 0xf7, 0x9c, 0x7b, 0xcf, 0xef, 0x73, 0x7e, 0x7f, 0xce, 0xe1, 0x20,
0xb4, 0xa0, 0xd5, 0x23, 0x14, 0x8b, 0x1f, 0x02, 0xc4, 0x67, 0xc3, 0x90, 0x2d, 0x58, 0xa0, 0x11,
0x08, 0x6c, 0x8d, 0x08, 0xad, 0xe7, 0x13, 0x94, 0x44, 0x40, 0xf5, 0x02, 0x01, 0x68, 0x84, 0xc2,
0x69, 0xfc, 0x5e, 0xc6, 0x2b, 0x68, 0xc0, 0x64, 0x02, 0xb3, 0x5c, 0xee, 0xf1, 0x7a, 0xd7, 0x89,
0xbd, 0x5b, 0xc7, 0x0b, 0x68, 0xb4, 0xbb, 0x1b, 0x5c, 0x2e, 0x17, 0xf4, 0x19, 0x0c, 0xd0, 0x20,
0x16, 0xbb, 0x35, 0x41, 0x41, 0xdf, 0xf1, 0x78, 0x05, 0x2f, 0xa0, 0xd9, 0xd9, 0x59, 0x56, 0xf6,
0x91, 0x11, 0x30, 0x25, 0x26, 0xba, 0xbd, 0x21, 0xb5, 0xea, 0x10, 0x8a, 0xe4, 0x05, 0x44, 0xe4,
0x72, 0x3a, 0xa1, 0x57, 0xaf, 0x07, 0x2d, 0x4d, 0xbb, 0xb5, 0x42, 0xe1, 0x57, 0xfc, 0x4f, 0x2e,
0x2f, 0x20, 0x4e, 0x9f, 0x87, 0x86, 0xa0, 0x35, 0x21, 0x81, 0xf3, 0xce, 0x72, 0x06, 0xa1, 0xd5,
0x7e, 0x1b, 0xd7, 0x20, 0xa4, 0xc4, 0x13, 0xbb, 0x89, 0xf0, 0x7b, 0x3f, 0x31, 0xf2, 0xce, 0x62,
0x61, 0x0d, 0x4f, 0x8e, 0x8f, 0xb3, 0xa1, 0xe3, 0x44, 0xfa, 0x4e, 0x87, 0x03, 0x7a, 0x74, 0x3a,
0xd0, 0x52, 0x94, 0x1b, 0x57, 0xe6, 0x17, 0x3c, 0x27, 0xfb, 0xbf, 0x40, 0x8e, 0xa9, 0x29, 0x68,
0x14, 0x8b, 0x81, 0x5d, 0xbd, 0x57, 0xa4, 0x4f, 0xc6, 0xc9, 0x22, 0xc6, 0x07, 0x07, 0xc1, 0x10,
0x17, 0xf7, 0xd3, 0xfb, 0xed, 0xf6, 0x59, 0x84, 0x22, 0x56, 0x1c, 0xba, 0xc5, 0x3c, 0x9a, 0x1b,
0x4a, 0xe7, 0xcc, 0x0c, 0xe7, 0x9d, 0x07, 0xe7, 0xee, 0x13, 0x9e, 0x9b, 0x1a, 0x90, 0x1c, 0xf9,
0xd2, 0xc7, 0xde, 0x5e, 0x68, 0x89, 0x8e, 0x26, 0xde, 0x91, 0xbd, 0x67, 0xc4, 0x92, 0xf9, 0x0d,
0x6a, 0xeb, 0xaa, 0x83, 0x19, 0xc7, 0x34, 0x6b, 0x88, 0x0b, 0xd7, 0x52, 0x22, 0xff, 0x3c, 0xad,
0xa9, 0x21, 0x1b, 0xdc, 0x83, 0x0b, 0xc5, 0x81, 0xed, 0xf4, 0xcc, 0x49, 0x89, 0xd2, 0x27, 0x48,
0x71, 0x3e, 0x16, 0x8e, 0x9a, 0x36, 0x43, 0xdf, 0x5b, 0x2b, 0x9b, 0x9b, 0xa9, 0x89, 0x09, 0x7e,
0x40, 0xe5, 0xc6, 0x78, 0xc8, 0x6f, 0x97, 0x82, 0xc2, 0x1c, 0x09, 0xa5, 0xe9, 0x14, 0x8c, 0xbd,
0xec, 0xf9, 0x2b, 0x47, 0xf3, 0x42, 0x17, 0x15, 0xb5, 0x74, 0xe8, 0xe4, 0xb5, 0xf4, 0x85, 0xe4,
0x7a, 0xda, 0x48, 0x94, 0x71, 0x9c, 0x7a, 0x54, 0x94, 0x29, 0x04, 0x75, 0x6b, 0x16, 0x14, 0x5f,
0xdc, 0x08, 0x07, 0x6e, 0x4a, 0xa1, 0xe4, 0xbe, 0x0c, 0x14, 0x1d, 0x21, 0x50, 0x50, 0xc9, 0x40,
0xed, 0x1a, 0xd1, 0xbc, 0x30, 0x2e, 0x2c, 0x06, 0xbc, 0xf2, 0x1d, 0x3e, 0xf3, 0x92, 0xae, 0xa2,
0xec, 0x59, 0x97, 0x18, 0x58, 0xa8, 0xdc, 0x2b, 0xe2, 0xdf, 0xa0, 0xf2, 0xae, 0x30, 0xa8, 0x7c,
0x11, 0x01, 0xc7, 0x3a, 0x62, 0xe0, 0xee, 0x9b, 0x96, 0x95, 0x95, 0xb7, 0x2f, 0x50, 0x8e, 0x59,
0x04, 0xf9, 0x37, 0xa4, 0x50, 0x7c, 0x4f, 0x06, 0x07, 0x9f, 0x84, 0xc2, 0x91, 0xe7, 0xe1, 0x50,
0xf5, 0x6a, 0x15, 0x54, 0xd9, 0xd6, 0x82, 0xb2, 0x29, 0x1e, 0xd4, 0xc1, 0x14, 0x39, 0x8e, 0xec,
0x18, 0x92, 0xe5, 0x57, 0x49, 0xa7, 0xe8, 0xe8, 0xd1, 0xc5, 0x40, 0xd9, 0x6d, 0x22, 0xd8, 0x77,
0x4d, 0x02, 0x85, 0x96, 0x60, 0x50, 0x3c, 0x0c, 0x81, 0xf2, 0xce, 0x50, 0x38, 0xfc, 0x2c, 0x9c,
0x05, 0x1e, 0xb2, 0x85, 0x41, 0x9e, 0x5a, 0x34, 0xb9, 0x4b, 0xc9, 0x14, 0xfa, 0xbd, 0x49, 0x7d,
0x81, 0x58, 0xaf, 0x2e, 0x63, 0xaf, 0xda, 0x25, 0x50, 0x74, 0x27, 0x18, 0x4a, 0x1e, 0xc8, 0xa0,
0xf4, 0x71, 0x08, 0x94, 0x59, 0x43, 0xd9, 0x67, 0x9e, 0x49, 0x6a, 0x4f, 0xa9, 0x63, 0x9a, 0x03,
0x02, 0xe2, 0x72, 0xb5, 0xff, 0xba, 0x04, 0x0a, 0x6e, 0x49, 0x59, 0x60, 0x21, 0x56, 0x86, 0x5e,
0x34, 0x9c, 0xac, 0x16, 0xed, 0x5e, 0xd6, 0x89, 0xfd, 0x2f, 0x10, 0x97, 0xaf, 0xbc, 0xab, 0x62,
0xc8, 0x69, 0x93, 0xfc, 0x48, 0xd1, 0x32, 0xd6, 0xad, 0xa7, 0x96, 0x71, 0xae, 0x71, 0x2d, 0x49,
0x4d, 0xf5, 0xa7, 0x35, 0xd1, 0xc3, 0x44, 0x19, 0x5a, 0x7a, 0x6c, 0xef, 0x09, 0x0a, 0x4a, 0xf4,
0x1b, 0x20, 0xbb, 0x59, 0xf2, 0x07, 0x66, 0x64, 0x20, 0xad, 0x89, 0xf9, 0x20, 0x57, 0xd1, 0xd5,
0x01, 0xbf, 0x9c, 0x64, 0x56, 0xd3, 0x6e, 0x02, 0xc9, 0x34, 0x30, 0x9e, 0xe4, 0x06, 0xfa, 0xb5,
0xfc, 0x24, 0x13, 0xc3, 0xcb, 0x75, 0x2b, 0x55, 0x43, 0xbf, 0xdf, 0x79, 0x8e, 0xfe, 0xb6, 0x5d,
0x45, 0x9b, 0x37, 0x55, 0x20, 0x9a, 0x8f, 0x9b, 0x10, 0x7b, 0x81, 0xdc, 0x76, 0x9a, 0x1e, 0x48,
0x52, 0x09, 0xf7, 0x04, 0xca, 0xee, 0x2f, 0xa6, 0x8a, 0xf5, 0x99, 0x69, 0x7e, 0xb8, 0x6a, 0x00,
0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE import_part_xpm[1] = {{ png, sizeof( png ), "import_part_xpm" }};
//EOF

View File

@ -8,94 +8,74 @@
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, 0x00, 0x04, 0x73, 0x42, 0x49, 0x54, 0x08, 0x08, 0x08, 0x08, 0x7c, 0x08, 0x64,
0x88, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0d, 0xd7, 0x00, 0x00, 0x0d,
0xd7, 0x01, 0x42, 0x28, 0x9b, 0x78, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f,
0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63,
0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x00, 0x00, 0x05, 0x0e, 0x49,
0x44, 0x41, 0x54, 0x48, 0x89, 0x95, 0x96, 0x5b, 0x68, 0x1c, 0xe7, 0x15, 0x80, 0xbf, 0xf3, 0xff,
0x73, 0xdb, 0x99, 0x95, 0x54, 0x49, 0x96, 0x2c, 0xa9, 0xb2, 0x14, 0x5b, 0x89, 0xf0, 0x05, 0xc7,
0x52, 0x52, 0xb0, 0xa9, 0xd4, 0x26, 0x2e, 0x76, 0xd2, 0x42, 0x02, 0xb1, 0xf1, 0x85, 0xa4, 0xb4,
0x0f, 0xa5, 0xc5, 0xe4, 0x21, 0x0f, 0x01, 0x37, 0x50, 0xd7, 0x34, 0xae, 0x69, 0x63, 0x19, 0x42,
0x13, 0x68, 0x21, 0x90, 0xbe, 0xd5, 0x14, 0x4c, 0x4d, 0x29, 0x85, 0xa6, 0xd0, 0x36, 0x81, 0x40,
0x2e, 0x76, 0x52, 0x93, 0x58, 0x06, 0x47, 0xb1, 0xc9, 0xcd, 0x21, 0xad, 0x25, 0x79, 0x55, 0xcb,
0xd9, 0xfb, 0xce, 0xcc, 0xff, 0xf7, 0x61, 0x6d, 0x27, 0xab, 0xdd, 0x4d, 0xc8, 0x79, 0x9a, 0x73,
0xe6, 0xcc, 0xf9, 0xe6, 0xdc, 0xfe, 0x19, 0x61, 0x85, 0xec, 0x38, 0xbc, 0x6e, 0x26, 0xb5, 0x76,
0x58, 0xa5, 0xf2, 0xba, 0xb5, 0x72, 0xee, 0x6f, 0x47, 0xe7, 0x4e, 0xfe, 0xf9, 0xcd, 0x6b, 0x6b,
0x8c, 0x5d, 0xe9, 0x59, 0x17, 0x47, 0xc3, 0xfe, 0x6d, 0x7d, 0xff, 0x99, 0xbf, 0x34, 0xb3, 0x65,
0xf9, 0xfc, 0xa1, 0x2b, 0x28, 0x91, 0x26, 0x27, 0x63, 0xad, 0xd3, 0x64, 0x83, 0xef, 0x17, 0x56,
0xab, 0x61, 0x1d, 0x9b, 0x5d, 0x7e, 0x9e, 0xe4, 0xa3, 0x85, 0x2b, 0x9d, 0x27, 0xce, 0x94, 0x59,
0x28, 0xb4, 0x06, 0xf5, 0x66, 0x2c, 0x3b, 0x37, 0x7f, 0x4d, 0x3b, 0xae, 0xab, 0x11, 0xdc, 0xf5,
0xe3, 0xe3, 0x4d, 0x3e, 0xef, 0x5e, 0xbc, 0x48, 0x03, 0xe8, 0xc1, 0x23, 0x43, 0x61, 0xb9, 0xca,
0xc0, 0xf2, 0xb0, 0x60, 0x95, 0x0e, 0x01, 0x52, 0x5f, 0x30, 0x08, 0x97, 0x16, 0x6b, 0x2d, 0x41,
0xd3, 0xeb, 0x3c, 0x00, 0xa2, 0x6c, 0x96, 0x1c, 0xa0, 0xb5, 0x6e, 0xe9, 0xa7, 0x3e, 0xaf, 0x94,
0x4b, 0xde, 0x9d, 0xb1, 0x4f, 0xc9, 0x2a, 0xf0, 0x94, 0x47, 0x5f, 0xd0, 0x87, 0xb4, 0xa8, 0x44,
0xb3, 0x88, 0x88, 0x38, 0x8d, 0x8e, 0x23, 0xbf, 0x6b, 0x50, 0x1b, 0x32, 0x12, 0xc5, 0x44, 0x2d,
0xac, 0xdb, 0x26, 0x7a, 0x26, 0x38, 0x70, 0xc7, 0x01, 0x84, 0x2f, 0x07, 0x2d, 0x5d, 0xaf, 0xf5,
0x85, 0xfe, 0x0a, 0x50, 0xf8, 0x8d, 0xf6, 0x20, 0xb4, 0xbb, 0xed, 0x89, 0x07, 0x7e, 0x15, 0x56,
0x32, 0x86, 0xb1, 0x8e, 0x31, 0x32, 0x3a, 0x83, 0x93, 0xd6, 0x5d, 0x94, 0x08, 0x5a, 0x09, 0x22,
0x20, 0x02, 0xc6, 0x82, 0xb9, 0x31, 0x21, 0x5a, 0x8b, 0x64, 0x7a, 0x1f, 0xf9, 0xf5, 0xe0, 0x64,
0x1e, 0x7a, 0x7a, 0x6e, 0x04, 0x6b, 0x28, 0x56, 0x23, 0x28, 0x21, 0xd9, 0xea, 0x05, 0x19, 0x32,
0xf9, 0x69, 0x9e, 0x7b, 0x71, 0x09, 0x4f, 0x2b, 0xe2, 0xb4, 0x80, 0x56, 0x8a, 0xc8, 0xd7, 0x68,
0xad, 0x50, 0x37, 0xde, 0xdb, 0x5a, 0x48, 0x8d, 0xc5, 0xd1, 0x8a, 0x99, 0x17, 0xae, 0x88, 0xab,
0xe5, 0x47, 0xd5, 0xe4, 0xbb, 0x3c, 0xbc, 0x6d, 0x15, 0xf7, 0x8d, 0x2f, 0x03, 0x8d, 0x63, 0x7a,
0x0b, 0xbb, 0x77, 0x2f, 0x5a, 0x1b, 0x59, 0x77, 0x68, 0xf6, 0x10, 0x83, 0x83, 0x8b, 0x14, 0xaa,
0x86, 0x77, 0x73, 0x70, 0x6e, 0x1e, 0xe6, 0x0b, 0x42, 0xe8, 0x3b, 0x44, 0xbe, 0x43, 0x36, 0x70,
0xc8, 0x06, 0x2e, 0x51, 0xe0, 0x10, 0xfa, 0x0e, 0xb9, 0xb2, 0x66, 0x76, 0x1e, 0x3e, 0xfe, 0x54,
0xb1, 0x54, 0x34, 0x4c, 0xad, 0x2d, 0xc3, 0x27, 0x3f, 0x6d, 0x0f, 0xba, 0xb6, 0x76, 0x74, 0xdc,
0x68, 0x1b, 0x17, 0xa5, 0xc2, 0x91, 0x77, 0x7e, 0xc6, 0xb1, 0x3d, 0xc3, 0xf4, 0x87, 0x96, 0x7c,
0xc5, 0x52, 0xa8, 0x42, 0xe8, 0x6b, 0xa2, 0x40, 0x13, 0x05, 0x2e, 0xd9, 0xa0, 0x0e, 0x0d, 0x7d,
0xcd, 0x72, 0xd9, 0x92, 0x18, 0xc1, 0xb1, 0x35, 0x9e, 0xd9, 0xdf, 0x4d, 0x94, 0xff, 0x3d, 0x54,
0xe6, 0x9a, 0xfa, 0x78, 0xab, 0x74, 0xa2, 0xf4, 0x44, 0x35, 0x22, 0x05, 0x88, 0x4d, 0x8c, 0xd7,
0xb1, 0xc4, 0x23, 0x53, 0x19, 0xe4, 0x74, 0x95, 0x77, 0xae, 0x0a, 0x9e, 0xa3, 0xf0, 0x1d, 0x8d,
0xeb, 0xd4, 0xdf, 0x2d, 0x4d, 0x0d, 0xd5, 0x44, 0xc8, 0xb8, 0xc2, 0x68, 0x57, 0xca, 0xa3, 0xf7,
0x0e, 0x24, 0xdd, 0xa5, 0x3f, 0x3a, 0x54, 0xfe, 0xd4, 0x04, 0x69, 0xc8, 0x28, 0x15, 0x7b, 0x57,
0x25, 0x4b, 0x16, 0x60, 0x63, 0xe7, 0x46, 0x5e, 0x5d, 0x7c, 0x95, 0xb8, 0xfb, 0x35, 0xa6, 0x6f,
0xf7, 0xd9, 0x34, 0xa8, 0x71, 0xb5, 0x22, 0xf0, 0x34, 0xa1, 0xaf, 0xc9, 0x06, 0x0e, 0x81, 0xa7,
0x09, 0x5c, 0xc5, 0x78, 0xbf, 0x62, 0xe7, 0x86, 0x88, 0xef, 0x6c, 0x0c, 0x4f, 0xcf, 0xbf, 0xfd,
0x58, 0x4b, 0x48, 0x03, 0x08, 0x87, 0xa9, 0x38, 0x2b, 0x0a, 0x60, 0x7d, 0xd7, 0x7a, 0xe6, 0xae,
0xcf, 0x71, 0x78, 0xf6, 0x30, 0x53, 0x1b, 0x3f, 0x61, 0x28, 0x4c, 0x19, 0xed, 0x56, 0x88, 0x80,
0xa3, 0x14, 0x8e, 0x16, 0x94, 0x12, 0xd6, 0xf6, 0x6a, 0x46, 0x3a, 0x0d, 0xdf, 0x1a, 0x0b, 0xcd,
0xd2, 0xd2, 0xc9, 0xfd, 0xd6, 0xa6, 0x5f, 0x0e, 0x92, 0x94, 0x4d, 0xb5, 0xb0, 0x7e, 0xbd, 0xa1,
0x6b, 0x03, 0x73, 0xd7, 0xe7, 0x30, 0xd6, 0xf0, 0xf3, 0xbf, 0x3c, 0x5a, 0x78, 0x72, 0x57, 0xef,
0x7c, 0xa8, 0xca, 0x74, 0x05, 0x50, 0xae, 0x25, 0x94, 0xaa, 0x29, 0x03, 0x59, 0xc1, 0x31, 0x45,
0x1e, 0xff, 0xde, 0x08, 0x3f, 0x3c, 0xfe, 0x66, 0xed, 0xf2, 0x99, 0x1f, 0x5c, 0x6f, 0x4b, 0xb9,
0x09, 0xba, 0xff, 0xd0, 0xe8, 0x20, 0x16, 0x3f, 0xf1, 0xea, 0xb3, 0xdb, 0xe1, 0x76, 0x70, 0x29,
0x7f, 0x09, 0x80, 0xea, 0xe2, 0xb2, 0x7d, 0xe5, 0xfc, 0x5f, 0x0f, 0x1e, 0xdf, 0x3f, 0xb2, 0xd0,
0xa9, 0x4a, 0x28, 0x31, 0x44, 0x9e, 0x25, 0xad, 0xe6, 0x79, 0x6a, 0xcf, 0x6d, 0x9c, 0x78, 0x2d,
0xe6, 0xed, 0xf7, 0x97, 0xdb, 0x1c, 0xb9, 0x2b, 0x40, 0x71, 0xca, 0x44, 0x1c, 0x49, 0xe5, 0xe6,
0x21, 0xf0, 0xd0, 0xcb, 0x0f, 0x51, 0x4a, 0x4a, 0x48, 0x6a, 0xd1, 0x09, 0x99, 0x3f, 0xfc, 0x63,
0xe6, 0xd4, 0xaa, 0xc8, 0x3d, 0xfa, 0x93, 0x6f, 0xaf, 0xe2, 0xeb, 0xd9, 0x18, 0xcf, 0x94, 0xf8,
0xe5, 0xae, 0x21, 0xce, 0x5e, 0xd6, 0xbc, 0x7c, 0xb1, 0x4d, 0xb9, 0x2e, 0x4e, 0x35, 0x83, 0x44,
0xa9, 0xc9, 0x4a, 0x24, 0x99, 0x95, 0xbe, 0x5e, 0x49, 0x30, 0x9a, 0xcb, 0xa7, 0x8e, 0x5c, 0xa8,
0x69, 0xcd, 0x73, 0xef, 0x5d, 0xfe, 0x1f, 0x3b, 0xd7, 0x47, 0x1c, 0xd8, 0xde, 0xcb, 0x6d, 0x7d,
0x19, 0x4e, 0x9c, 0xf9, 0x82, 0x14, 0x56, 0xf4, 0xab, 0xde, 0x23, 0x47, 0xbe, 0x59, 0xcb, 0x5a,
0xaf, 0x19, 0x64, 0x11, 0x6b, 0xcf, 0xde, 0xd4, 0x7f, 0xfc, 0x9b, 0xb3, 0xdc, 0x3d, 0xd6, 0xcb,
0x58, 0x7f, 0x17, 0x67, 0x3e, 0x58, 0xb9, 0x92, 0x5f, 0x2c, 0xf5, 0x3d, 0xb2, 0x76, 0xb2, 0x16,
0xa9, 0xa6, 0x9b, 0x7e, 0xc1, 0x56, 0x54, 0x62, 0x4f, 0xdf, 0xd4, 0x93, 0xd4, 0x72, 0xec, 0xef,
0x86, 0xd0, 0xd7, 0xe4, 0xda, 0x7c, 0x9f, 0xda, 0x82, 0xee, 0x3b, 0xb8, 0x3a, 0x32, 0xa9, 0xf4,
0xc7, 0x99, 0xe6, 0x53, 0x3a, 0x28, 0x52, 0x45, 0x71, 0xee, 0xf3, 0xb6, 0x7c, 0x05, 0x4a, 0xf1,
0x57, 0x83, 0x00, 0xa8, 0xd4, 0x0d, 0xee, 0x8c, 0x3d, 0x4a, 0xae, 0xf6, 0x38, 0x3e, 0x79, 0x9c,
0xe7, 0xb7, 0x3e, 0x4f, 0x7f, 0xd0, 0x8f, 0x58, 0xd0, 0x65, 0x42, 0xcf, 0x9a, 0xf3, 0x5f, 0x3d,
0x6c, 0x0b, 0x90, 0x18, 0x3d, 0x51, 0xcd, 0xe2, 0x4c, 0xf7, 0x4f, 0xb3, 0x7b, 0x64, 0x37, 0xdb,
0x07, 0xb6, 0xb3, 0x6f, 0x74, 0x1f, 0x4e, 0xc5, 0x62, 0x85, 0xe5, 0x17, 0x66, 0x3e, 0xbe, 0xb6,
0xf2, 0xa1, 0xe1, 0x6e, 0xd8, 0x73, 0x17, 0xac, 0xee, 0x6c, 0x13, 0x35, 0x9c, 0x80, 0xa1, 0x27,
0x21, 0xb3, 0xf9, 0x96, 0xc9, 0xb1, 0x8e, 0xdd, 0x5a, 0xeb, 0x90, 0xf0, 0xc2, 0xf2, 0x05, 0x72,
0xd5, 0x1c, 0x1d, 0x6e, 0x07, 0x6f, 0xe4, 0xde, 0xc0, 0x2b, 0x82, 0x55, 0xcc, 0xb6, 0x8a, 0xf3,
0xf8, 0x0e, 0x58, 0xd3, 0x0d, 0x5b, 0xd6, 0xc0, 0xc1, 0x93, 0x2d, 0x1c, 0x86, 0x8e, 0x82, 0x3f,
0x06, 0x99, 0x2d, 0xf0, 0xfe, 0xee, 0x3a, 0xc8, 0xc0, 0xd6, 0x5a, 0x28, 0x7c, 0x5a, 0x59, 0xe0,
0x9e, 0x7f, 0xde, 0x83, 0xa7, 0x3c, 0x0a, 0x49, 0x81, 0x9e, 0x22, 0x89, 0xb2, 0xe6, 0xf5, 0x56,
0xa0, 0x5c, 0xbe, 0x0e, 0xba, 0x9a, 0x6f, 0x93, 0x51, 0x69, 0xb6, 0x0e, 0x2a, 0x7d, 0xd6, 0x5e,
0x47, 0xa5, 0x32, 0xe6, 0x54, 0xc1, 0xa9, 0x42, 0xcd, 0xaf, 0x51, 0x33, 0xf5, 0x9f, 0x10, 0xbf,
0x60, 0x8b, 0x92, 0xf0, 0x56, 0xab, 0x38, 0x4f, 0xff, 0x0b, 0x46, 0x7b, 0xe1, 0xc3, 0x5c, 0x1b,
0xd0, 0x7f, 0x7f, 0x01, 0x8b, 0xbf, 0x85, 0xe4, 0xea, 0x67, 0x20, 0xb0, 0xcf, 0xf6, 0x7c, 0xc4,
0x14, 0xc6, 0x6c, 0x46, 0x70, 0xe3, 0x90, 0x4a, 0xb5, 0x43, 0x45, 0x5e, 0x91, 0xc0, 0x38, 0x72,
0xae, 0x55, 0x9c, 0x38, 0x81, 0xf7, 0x16, 0xda, 0x40, 0x00, 0xb0, 0x90, 0x2c, 0x36, 0x58, 0x1a,
0x66, 0xfa, 0xde, 0x27, 0x6e, 0x1f, 0xf6, 0x24, 0x9d, 0x34, 0x62, 0xef, 0xb6, 0x22, 0x9b, 0x5e,
0x3a, 0xf6, 0xe1, 0x3e, 0x6e, 0xed, 0xa5, 0x15, 0x76, 0x9c, 0x32, 0xad, 0xc2, 0x8a, 0x92, 0xfc,
0xbf, 0x1f, 0xdb, 0x3b, 0x10, 0x94, 0x29, 0xb6, 0xdc, 0x62, 0x81, 0xff, 0x03, 0xfb, 0x5a, 0xcd,
0xb5, 0xd6, 0xa0, 0xef, 0x61, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60,
0x82,
0xce, 0x00, 0x00, 0x04, 0x20, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xad, 0x96, 0x7b, 0x6c, 0x53,
0x55, 0x18, 0xc0, 0x6f, 0x57, 0xb3, 0x88, 0x33, 0x8b, 0x28, 0x66, 0xd6, 0xa9, 0xed, 0x3d, 0xb7,
0xb0, 0xd1, 0xb1, 0xd2, 0xb9, 0xc9, 0x63, 0x64, 0xac, 0x6b, 0xbb, 0x4e, 0x79, 0x64, 0x44, 0x58,
0x84, 0xfd, 0xc3, 0x1f, 0x26, 0xf8, 0x08, 0x68, 0x0c, 0xda, 0xe7, 0x9a, 0x55, 0x1e, 0x66, 0x42,
0xd4, 0x39, 0xd0, 0x41, 0x86, 0x03, 0xc5, 0x0c, 0xda, 0x59, 0xe7, 0x1e, 0x19, 0x53, 0x64, 0x40,
0x16, 0x18, 0x41, 0x40, 0x71, 0x35, 0xe3, 0x51, 0x25, 0x98, 0x2c, 0x1a, 0x2a, 0x5b, 0x5b, 0x58,
0xdb, 0xf5, 0xb1, 0xcf, 0xef, 0xb6, 0xd9, 0x56, 0x7b, 0xdb, 0x6c, 0xc3, 0x9e, 0xe4, 0x97, 0x9e,
0x9c, 0xdc, 0x7c, 0xbf, 0xfb, 0x9d, 0xfb, 0xf5, 0x7c, 0x87, 0x02, 0xa0, 0x1e, 0x46, 0xb2, 0x91,
0xe5, 0xc8, 0xfa, 0x2f, 0x4f, 0xcd, 0x6d, 0xaf, 0xb3, 0xcd, 0x3b, 0x55, 0xfb, 0x75, 0xd6, 0xce,
0x37, 0x1b, 0x9e, 0x55, 0x6f, 0x6b, 0x78, 0x3c, 0x93, 0x9a, 0xc1, 0x38, 0x6f, 0xa5, 0xe6, 0xd8,
0x2d, 0x54, 0xc0, 0xde, 0xca, 0x0b, 0x72, 0xc0, 0x75, 0x0a, 0x83, 0x0b, 0x90, 0x17, 0x91, 0x9d,
0x88, 0xf5, 0xe2, 0x8d, 0x39, 0xbe, 0x6f, 0x07, 0x32, 0xe1, 0xc3, 0x93, 0x4f, 0x8c, 0xbd, 0xda,
0x98, 0x7d, 0x6f, 0x4d, 0x2d, 0x1d, 0x2c, 0x37, 0xd1, 0x43, 0x0a, 0x23, 0xdd, 0x51, 0xae, 0x21,
0x45, 0xc9, 0x44, 0x97, 0x3a, 0xa9, 0x47, 0xec, 0x56, 0x0a, 0x42, 0x57, 0x73, 0x38, 0xb0, 0xeb,
0xac, 0x48, 0x86, 0x18, 0x90, 0xb3, 0xe3, 0x40, 0x0d, 0xb9, 0xee, 0xf3, 0xc1, 0xe1, 0x49, 0x07,
0xdb, 0xed, 0x4c, 0x78, 0xfd, 0x82, 0x00, 0x8a, 0x4f, 0xd0, 0x90, 0xdf, 0x42, 0x40, 0x6e, 0xa2,
0xbd, 0x2a, 0x9d, 0x48, 0x3e, 0x9d, 0x08, 0xec, 0x12, 0x0e, 0x13, 0xa2, 0x52, 0xa4, 0x11, 0x71,
0x84, 0xc7, 0xa9, 0xb1, 0x50, 0x98, 0x07, 0xae, 0x31, 0x3e, 0xf4, 0x3b, 0x33, 0xa0, 0xce, 0x8e,
0x82, 0x1f, 0x84, 0x20, 0x69, 0x67, 0x40, 0xa9, 0x27, 0x01, 0xf9, 0xf6, 0xc2, 0x79, 0x54, 0x95,
0x95, 0xcf, 0xc1, 0x6c, 0x4e, 0xe3, 0x88, 0x3c, 0xbd, 0x1c, 0xd1, 0x4a, 0x64, 0x3f, 0x72, 0x23,
0x14, 0xa6, 0x02, 0x41, 0x14, 0x8d, 0xa0, 0xe8, 0xd7, 0x11, 0x01, 0x5c, 0xf7, 0xbc, 0x07, 0xa5,
0x28, 0x92, 0x5a, 0x08, 0x28, 0x0c, 0xe4, 0x0e, 0xa5, 0xb2, 0x42, 0x22, 0x78, 0xea, 0x56, 0x0f,
0x47, 0x14, 0xf2, 0x70, 0x44, 0x8b, 0x90, 0xed, 0xc8, 0xf7, 0xae, 0x51, 0xfe, 0x3d, 0xe7, 0x28,
0x1f, 0x06, 0xdd, 0xe9, 0x70, 0xe9, 0xee, 0x0b, 0xd0, 0x3d, 0xb4, 0x15, 0x96, 0xe2, 0xd6, 0x15,
0x7c, 0xc1, 0x40, 0x99, 0x91, 0xfc, 0xc8, 0x06, 0x5d, 0xb7, 0x3f, 0x00, 0xeb, 0x1b, 0xc3, 0x93,
0xac, 0xfa, 0xf8, 0x3e, 0xa4, 0xa9, 0xbf, 0xf1, 0xce, 0x44, 0xf4, 0x24, 0x22, 0x47, 0x74, 0xa7,
0x07, 0x32, 0x5c, 0x27, 0x6e, 0x3d, 0x0a, 0x87, 0x1d, 0x8f, 0xc1, 0xc5, 0x7f, 0xde, 0x82, 0x0f,
0x06, 0x36, 0x43, 0x7e, 0x27, 0x03, 0x4b, 0x3f, 0x65, 0x82, 0x4a, 0x03, 0xbd, 0x83, 0x15, 0xbd,
0xfc, 0x79, 0x08, 0xaa, 0x0e, 0xc2, 0x24, 0x6b, 0xea, 0xbd, 0x33, 0x16, 0xa5, 0x23, 0x59, 0x81,
0x00, 0x55, 0xa8, 0x6f, 0x7e, 0x2a, 0xf8, 0xda, 0x39, 0x01, 0x6c, 0xec, 0xcb, 0x86, 0x9b, 0x9e,
0x1e, 0xa8, 0x3c, 0xad, 0x80, 0x9c, 0x76, 0x31, 0x94, 0xec, 0x26, 0x2e, 0xa5, 0x86, 0x59, 0xf7,
0x7f, 0x45, 0x3c, 0xe4, 0xa1, 0x6d, 0x0d, 0x4f, 0x17, 0x54, 0xee, 0x16, 0x8e, 0x16, 0x76, 0xd3,
0x50, 0xd4, 0xbd, 0x00, 0xdc, 0x81, 0x3b, 0xb0, 0xb0, 0x23, 0x07, 0xc4, 0xdf, 0x89, 0x01, 0x4b,
0xdb, 0x2b, 0xd7, 0xe5, 0x8a, 0x62, 0x45, 0x9d, 0x57, 0x67, 0x29, 0x9a, 0x18, 0x15, 0x06, 0x52,
0x5d, 0x52, 0x47, 0xdc, 0x0b, 0x30, 0x83, 0xb5, 0x67, 0x56, 0xc3, 0xcf, 0xc3, 0x57, 0x22, 0x92,
0x1c, 0x2b, 0x5b, 0x71, 0xb4, 0x97, 0xa2, 0xcc, 0x69, 0xb1, 0x22, 0x8f, 0xef, 0x01, 0x45, 0x0a,
0x3d, 0xbd, 0xb7, 0x70, 0x1f, 0x09, 0xb3, 0xc1, 0x35, 0x97, 0x35, 0xd0, 0x72, 0xab, 0x25, 0x22,
0x92, 0x1e, 0x61, 0x33, 0x22, 0x97, 0x29, 0x0a, 0x78, 0xa9, 0x11, 0x99, 0xe8, 0xf3, 0xd2, 0xc3,
0x4c, 0x24, 0x78, 0xb3, 0xa3, 0x19, 0x4c, 0xbf, 0x98, 0x22, 0xf3, 0xa2, 0xcf, 0x98, 0x71, 0x95,
0x91, 0xde, 0x97, 0x32, 0x11, 0x56, 0x95, 0x3b, 0xd7, 0x12, 0x15, 0xf5, 0x3b, 0xfb, 0x61, 0xc3,
0xd9, 0x0d, 0x91, 0x79, 0xf1, 0x1e, 0xe2, 0x51, 0xea, 0x45, 0x9b, 0x53, 0x22, 0xaa, 0x30, 0x08,
0x05, 0xf8, 0x1d, 0xfc, 0xe2, 0x36, 0x71, 0x24, 0xb8, 0xdd, 0x65, 0x07, 0x69, 0x97, 0x34, 0x32,
0x2f, 0x33, 0x11, 0x4f, 0x85, 0x96, 0x5e, 0x9c, 0x12, 0x91, 0x42, 0x2b, 0x7c, 0x69, 0xe5, 0x2e,
0xe2, 0x62, 0x03, 0xc7, 0x32, 0xdf, 0xc6, 0x80, 0x4a, 0x4f, 0x82, 0x55, 0xe6, 0xbc, 0xf4, 0x59,
0x8b, 0x7e, 0xcb, 0xe7, 0x8a, 0x30, 0x1b, 0xc3, 0x92, 0x4f, 0x98, 0xb1, 0x78, 0x51, 0xde, 0x51,
0x2c, 0x84, 0x1a, 0xe2, 0x88, 0x6e, 0xee, 0x2c, 0x45, 0xf1, 0x87, 0x6a, 0x44, 0x64, 0x22, 0x5d,
0xb2, 0x26, 0x02, 0xf1, 0xa2, 0x82, 0x83, 0x58, 0xda, 0x46, 0xfa, 0x78, 0x22, 0xd1, 0x99, 0xeb,
0x0f, 0x22, 0xaa, 0xa1, 0x87, 0x24, 0x2d, 0x0c, 0x47, 0xb4, 0xec, 0x23, 0xe2, 0x2b, 0xd7, 0x8a,
0xde, 0x4e, 0x24, 0x9a, 0xf6, 0x64, 0x88, 0x17, 0xa9, 0xdf, 0xcd, 0xca, 0x60, 0xbf, 0xc3, 0xfc,
0x36, 0x31, 0x47, 0x24, 0xdf, 0x41, 0x5c, 0xe5, 0x7a, 0x51, 0x69, 0x4a, 0x44, 0x4a, 0xbd, 0x70,
0x79, 0x69, 0x2d, 0x71, 0x4b, 0x3a, 0x24, 0xd8, 0xec, 0x6c, 0xd0, 0xfb, 0x57, 0x2f, 0x14, 0xf7,
0x14, 0x03, 0x2b, 0x66, 0x7b, 0xd0, 0x6a, 0xdd, 0x73, 0x73, 0x53, 0x22, 0x52, 0x69, 0xc9, 0x1b,
0xcb, 0xf6, 0x92, 0xd1, 0x2d, 0x17, 0xb6, 0xc0, 0xc4, 0xa8, 0x1f, 0xac, 0x87, 0x85, 0xc7, 0x98,
0x68, 0x0f, 0x9a, 0x1c, 0x53, 0xa2, 0x77, 0xac, 0x00, 0x96, 0x9f, 0x00, 0xb6, 0x1e, 0x4b, 0x22,
0xfa, 0xa3, 0x1a, 0x60, 0xd8, 0x02, 0xf0, 0xfb, 0x2b, 0x31, 0x19, 0x19, 0xe9, 0x23, 0xcf, 0x1f,
0x20, 0xb0, 0xa2, 0x67, 0x05, 0x38, 0xfd, 0x4e, 0xf0, 0x87, 0xfd, 0xb0, 0xa9, 0x6f, 0x13, 0x2c,
0x3e, 0x84, 0x3d, 0xa8, 0x86, 0x9c, 0x4c, 0x24, 0xfa, 0x73, 0x38, 0xfa, 0x42, 0xd7, 0xfe, 0x4e,
0x22, 0xf2, 0x3b, 0xa2, 0x0f, 0xf8, 0xae, 0x4d, 0x89, 0xca, 0x8c, 0xf4, 0xe0, 0xa2, 0xaf, 0xa2,
0x85, 0xc0, 0x6e, 0x9f, 0xac, 0x4b, 0x16, 0x99, 0x2f, 0x61, 0x7b, 0x90, 0x51, 0xf4, 0x7e, 0x22,
0xd1, 0x95, 0xdb, 0xd1, 0x38, 0x7d, 0x37, 0x93, 0x88, 0x86, 0x6d, 0xd1, 0x07, 0xee, 0x1e, 0x8f,
0xc9, 0x48, 0x47, 0x02, 0xb2, 0x26, 0x06, 0x72, 0x2d, 0xff, 0x2d, 0x04, 0xb6, 0x07, 0xa9, 0xb4,
0xa2, 0xca, 0x44, 0xa2, 0xea, 0x43, 0x00, 0xfa, 0x36, 0x80, 0x8d, 0x4d, 0xc9, 0xbe, 0x51, 0x1e,
0xa6, 0x2b, 0x8f, 0xfe, 0x4e, 0x89, 0xe8, 0x3d, 0x78, 0x3a, 0x9f, 0xc3, 0xd3, 0xdb, 0xa3, 0x30,
0xd0, 0xbe, 0x92, 0x5d, 0xf4, 0x08, 0x66, 0x13, 0x50, 0x1a, 0x88, 0x1f, 0xfb, 0x90, 0x30, 0x91,
0xa8, 0xea, 0x00, 0x4c, 0x32, 0xab, 0xff, 0xd1, 0xc4, 0x90, 0x6b, 0xc4, 0xcf, 0xa8, 0xb5, 0xf4,
0x5a, 0xbc, 0x56, 0x99, 0xf1, 0xb4, 0x68, 0xc5, 0x25, 0x5e, 0xbc, 0x68, 0xba, 0xcb, 0x09, 0x5e,
0x16, 0xb9, 0xe0, 0xfa, 0xbf, 0x1c, 0x59, 0xd1, 0x95, 0xe1, 0x38, 0xaf, 0xa0, 0x00, 0x00, 0x00,
0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE new_library_xpm[1] = {{ png, sizeof( png ), "new_library_xpm" }};

View File

@ -8,58 +8,90 @@
static const unsigned char png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
0xce, 0x00, 0x00, 0x03, 0x22, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xed, 0x95, 0x6b, 0x48, 0x53,
0x61, 0x18, 0xc7, 0xd7, 0x07, 0x71, 0x69, 0x48, 0x6a, 0x69, 0x11, 0x45, 0x5a, 0x61, 0x50, 0x39,
0xe7, 0x1d, 0x0b, 0xcb, 0x2e, 0x8a, 0x74, 0x45, 0x0a, 0x2c, 0xf2, 0x82, 0x1f, 0x8a, 0x8c, 0x28,
0x4c, 0xbc, 0x24, 0x86, 0x6e, 0x35, 0x75, 0xb1, 0x74, 0x17, 0xdc, 0x25, 0x82, 0x70, 0xd0, 0x87,
0x72, 0x31, 0x51, 0x19, 0x44, 0x28, 0xce, 0x30, 0xe7, 0x19, 0x23, 0x9a, 0x39, 0x37, 0xef, 0xcc,
0xa6, 0xa2, 0x42, 0x37, 0x2b, 0x45, 0x7c, 0x7a, 0x9f, 0x83, 0x1b, 0x2b, 0x97, 0x66, 0x9b, 0xdf,
0x3a, 0xf0, 0xe7, 0x5c, 0x9e, 0xe7, 0xf9, 0xff, 0xde, 0xf7, 0x39, 0xef, 0x79, 0x0f, 0x83, 0xb1,
0xd2, 0x71, 0xb1, 0x75, 0xd3, 0xbe, 0x22, 0xc3, 0x38, 0xbb, 0xd4, 0xe8, 0x52, 0x7b, 0xf2, 0x0d,
0x36, 0x46, 0x76, 0xeb, 0x46, 0x86, 0xdb, 0x07, 0x01, 0xc5, 0x94, 0xf7, 0x4c, 0xad, 0xbf, 0x66,
0x04, 0x57, 0x22, 0xb1, 0x49, 0x46, 0xe6, 0xab, 0xc0, 0xff, 0xa0, 0x65, 0x41, 0x3e, 0xb9, 0x46,
0xd8, 0x70, 0xbd, 0x9b, 0x96, 0x6f, 0x6e, 0xb7, 0xfb, 0x20, 0x66, 0x0e, 0x15, 0xea, 0x93, 0xdd,
0x71, 0x0e, 0xc5, 0xcc, 0x6a, 0xcb, 0x8c, 0xe3, 0x98, 0xa6, 0x03, 0x6e, 0xf6, 0x40, 0x50, 0x9e,
0x09, 0x82, 0x6f, 0xf7, 0xc2, 0x16, 0xa2, 0xa0, 0xbc, 0x5e, 0x08, 0xbc, 0x65, 0x02, 0x8c, 0x61,
0x8e, 0x23, 0x9f, 0xd4, 0xfe, 0x35, 0xc8, 0xeb, 0xf2, 0x9b, 0xc8, 0xa8, 0xd2, 0x77, 0x53, 0xb1,
0x5c, 0x33, 0x44, 0x73, 0xcc, 0x10, 0xcf, 0x1b, 0x80, 0xed, 0x05, 0x16, 0x08, 0x29, 0xee, 0x83,
0x5d, 0x25, 0xfd, 0xb4, 0x42, 0xef, 0xf4, 0xc3, 0x8e, 0x42, 0x0b, 0x24, 0xf2, 0x07, 0x21, 0x86,
0xe4, 0x1c, 0xaa, 0xb4, 0x40, 0x58, 0xc1, 0xdb, 0x69, 0xaf, 0xac, 0xce, 0xa8, 0x55, 0xcd, 0xca,
0xef, 0x4a, 0xc7, 0xa5, 0xa4, 0x2a, 0xcb, 0xc7, 0x6d, 0xf9, 0xbd, 0xb0, 0x93, 0x00, 0xc2, 0x4a,
0x07, 0x60, 0x7f, 0xd9, 0x10, 0xb0, 0x38, 0xc3, 0xc0, 0xe2, 0x0e, 0xc3, 0x81, 0xf2, 0x61, 0xd8,
0x7b, 0x77, 0x90, 0x06, 0x86, 0x14, 0x5b, 0xe0, 0x28, 0xdf, 0xfc, 0x89, 0x99, 0xd3, 0x9e, 0xf9,
0x4f, 0x2d, 0xdc, 0x7a, 0x83, 0xaa, 0x3e, 0xfe, 0x70, 0x70, 0x2e, 0x8c, 0x18, 0xa2, 0x79, 0x6c,
0x85, 0x15, 0x12, 0xf8, 0xa3, 0x70, 0xf0, 0xc1, 0x28, 0xc4, 0x55, 0x5a, 0x81, 0x7d, 0x6f, 0x84,
0x86, 0x9f, 0x12, 0x0e, 0xcd, 0xfa, 0x5f, 0xed, 0xe4, 0xad, 0xca, 0x5c, 0x26, 0x93, 0xb1, 0x14,
0x0a, 0x45, 0x21, 0x4a, 0x2e, 0x7f, 0x54, 0x94, 0x50, 0xd2, 0x61, 0x4a, 0x11, 0x5a, 0x69, 0xc8,
0x61, 0x81, 0x0d, 0x4e, 0x88, 0xc6, 0x21, 0x59, 0x34, 0x01, 0x49, 0xd5, 0x63, 0x10, 0x5f, 0x35,
0x0a, 0x69, 0x32, 0xeb, 0x42, 0x74, 0xc1, 0x6b, 0xa3, 0xbd, 0x06, 0x85, 0x1e, 0x2b, 0x82, 0x48,
0xe2, 0xfb, 0xfa, 0xfa, 0x7a, 0x50, 0xab, 0xd5, 0xb4, 0x9e, 0xa9, 0x1a, 0xe0, 0x4c, 0x95, 0x01,
0x4e, 0x8a, 0x6d, 0x70, 0xac, 0x66, 0x0c, 0x4e, 0x4b, 0x27, 0xe1, 0xac, 0x7c, 0x8a, 0x06, 0x5e,
0x50, 0x4c, 0x40, 0xea, 0x7d, 0x1d, 0x3c, 0x7f, 0xa1, 0x76, 0xe4, 0x63, 0x2d, 0x7a, 0x2c, 0x0b,
0x11, 0x0a, 0x85, 0x49, 0x24, 0xe9, 0x0b, 0x45, 0x51, 0xd0, 0xd2, 0xd2, 0x02, 0x5a, 0xad, 0x16,
0xf4, 0x7a, 0x3d, 0x68, 0xda, 0xf4, 0x90, 0x21, 0x35, 0x43, 0xaa, 0x64, 0x8c, 0xcc, 0x66, 0x1c,
0x52, 0xc4, 0x13, 0x90, 0x26, 0x27, 0xaa, 0xee, 0x81, 0x97, 0x5a, 0x8a, 0xce, 0xc1, 0x5c, 0xac,
0xc1, 0x6b, 0xe2, 0xf1, 0x59, 0x2c, 0x16, 0x1f, 0xf9, 0x23, 0x48, 0x24, 0x12, 0xb5, 0x37, 0x35,
0x35, 0x2d, 0x74, 0x75, 0x75, 0x01, 0x39, 0x83, 0x4e, 0xa7, 0xa3, 0x0b, 0x51, 0x52, 0x75, 0x17,
0x64, 0x28, 0x06, 0x21, 0x51, 0xf0, 0x01, 0x92, 0x85, 0x36, 0x38, 0x2f, 0xe9, 0x03, 0xa5, 0x86,
0x72, 0xc4, 0x9d, 0x6b, 0x9a, 0x9b, 0x9b, 0x17, 0x24, 0x12, 0x49, 0xbb, 0x4b, 0x88, 0x40, 0x20,
0x60, 0xd5, 0xd4, 0xd4, 0xcc, 0x60, 0x01, 0x8e, 0xcc, 0x3e, 0x3a, 0x67, 0x95, 0x3c, 0xa1, 0x20,
0x5d, 0x36, 0x02, 0xe9, 0xd2, 0x21, 0xa8, 0x78, 0x4a, 0x2d, 0x89, 0xdb, 0xeb, 0xb0, 0x23, 0xc4,
0xeb, 0x2b, 0x9f, 0xcf, 0x8f, 0x5c, 0x02, 0x22, 0x0f, 0x1b, 0x54, 0x2a, 0xd5, 0xbc, 0xab, 0xd9,
0x38, 0x2b, 0x43, 0xa8, 0x87, 0x5c, 0x99, 0xde, 0x65, 0xcc, 0xb9, 0x96, 0xbc, 0xab, 0x79, 0xf4,
0xfc, 0x05, 0xc2, 0xe5, 0x72, 0x43, 0x78, 0x3c, 0xde, 0x37, 0x4c, 0xc0, 0x5e, 0x37, 0x36, 0x36,
0xba, 0x25, 0xf4, 0x40, 0x2f, 0xe2, 0x39, 0x53, 0x56, 0x56, 0xb6, 0xdb, 0x01, 0xe2, 0x70, 0x38,
0x8f, 0xeb, 0xea, 0xea, 0x66, 0x5d, 0x8d, 0xd2, 0x1d, 0x29, 0x95, 0xca, 0x39, 0xf4, 0x76, 0x80,
0xc8, 0x0a, 0xf9, 0x51, 0x5b, 0x5b, 0x0b, 0x6b, 0x21, 0xb2, 0x28, 0xbe, 0xdb, 0x39, 0xeb, 0xf0,
0x81, 0xcd, 0x66, 0xf3, 0xb8, 0xac, 0x56, 0x2b, 0x0d, 0x43, 0x06, 0xbd, 0x87, 0xda, 0x41, 0x9e,
0x6e, 0x9d, 0x46, 0xa3, 0xb1, 0x83, 0xbc, 0xe8, 0xbf, 0x82, 0x27, 0x41, 0xe1, 0x86, 0x70, 0x88,
0x30, 0x44, 0xd0, 0xd7, 0xb8, 0x30, 0x16, 0x41, 0x4c, 0x04, 0xf9, 0x7a, 0x12, 0x84, 0x10, 0xb6,
0x81, 0xfd, 0x3b, 0xc8, 0x97, 0xfe, 0x23, 0xe0, 0x0d, 0xf6, 0xd3, 0xd3, 0xad, 0x73, 0x02, 0xf9,
0x21, 0xc8, 0x1f, 0x6f, 0xb0, 0x9f, 0xee, 0x7e, 0x3f, 0xae, 0xb4, 0x08, 0xf2, 0x47, 0x50, 0x00,
0xd9, 0xd6, 0xdb, 0xd7, 0x6a, 0x79, 0x93, 0x0d, 0x56, 0x8b, 0x0c, 0x04, 0x79, 0x13, 0x6d, 0x26,
0x0a, 0x5e, 0x23, 0xa1, 0xb7, 0xf7, 0x4f, 0x9c, 0xdd, 0x44, 0xac, 0x31, 0x0f, 0x89, 0xb8, 0x00,
0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
0xce, 0x00, 0x00, 0x05, 0x24, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xad, 0xd6, 0x7f, 0x50, 0x93,
0x75, 0x1c, 0x07, 0xf0, 0x91, 0x5d, 0x77, 0x69, 0x67, 0x75, 0xdd, 0x69, 0x5a, 0x17, 0x7b, 0x9e,
0x0d, 0x7f, 0x80, 0x09, 0x81, 0x1a, 0x48, 0x8a, 0xec, 0x07, 0x6a, 0x61, 0x9e, 0xe9, 0x34, 0xe9,
0x3a, 0xb5, 0x3f, 0x2c, 0xcc, 0xea, 0xec, 0x0c, 0xf6, 0x03, 0x4e, 0x48, 0x31, 0x83, 0x48, 0x44,
0x45, 0x74, 0x8a, 0x16, 0x2a, 0x0e, 0x22, 0x4a, 0xed, 0xc2, 0x32, 0x3b, 0xfc, 0x91, 0x65, 0x59,
0x19, 0x9b, 0x0c, 0xf7, 0x6c, 0x83, 0x31, 0xd8, 0xc6, 0x04, 0xc7, 0x60, 0x30, 0x60, 0xe3, 0xdd,
0xf3, 0xec, 0xb9, 0x89, 0xb0, 0xa1, 0x70, 0xe7, 0x73, 0xf7, 0xbe, 0xe7, 0x7b, 0xdf, 0x7d, 0xf7,
0xbc, 0xf6, 0x7d, 0x9e, 0xcf, 0xf3, 0xfd, 0x8e, 0xc3, 0x19, 0x76, 0x88, 0x32, 0xc8, 0x5d, 0x89,
0x0a, 0xe2, 0xb8, 0x50, 0x4a, 0x6e, 0x12, 0xa4, 0xf3, 0xe6, 0x77, 0xf7, 0xf6, 0x99, 0x4a, 0x2f,
0xd9, 0xf0, 0xd5, 0xc5, 0xe0, 0x39, 0x71, 0xc5, 0x06, 0x8f, 0x77, 0xc0, 0x6c, 0xae, 0xdb, 0xf9,
0x8c, 0x5a, 0xc5, 0xe9, 0x53, 0x57, 0x84, 0xf4, 0x07, 0x84, 0xee, 0x1f, 0xee, 0x70, 0x04, 0x19,
0x64, 0xd3, 0xdc, 0x42, 0x1e, 0x62, 0xf3, 0x09, 0x57, 0x42, 0x16, 0xd9, 0x71, 0xd3, 0xd4, 0x88,
0xa4, 0x3c, 0x2d, 0x22, 0xb7, 0x05, 0x8f, 0x60, 0x57, 0x1d, 0x5a, 0x9d, 0xbd, 0x16, 0x2b, 0x95,
0x37, 0x49, 0x5d, 0xce, 0x81, 0xe7, 0xc6, 0xf4, 0x80, 0x30, 0xfd, 0x43, 0x90, 0x65, 0x59, 0x53,
0xc7, 0x8b, 0x64, 0x64, 0x7f, 0xd8, 0xb7, 0x7c, 0xf0, 0xbf, 0x63, 0x53, 0x6b, 0x33, 0x41, 0x94,
0x57, 0x8f, 0xc7, 0x53, 0x6b, 0x83, 0x46, 0x4c, 0x7f, 0xc6, 0x40, 0x9d, 0xd6, 0x03, 0x3e, 0x08,
0xea, 0xf0, 0x80, 0x04, 0x40, 0xa2, 0x34, 0x6e, 0x2c, 0x33, 0x0b, 0x06, 0x08, 0x3f, 0x1d, 0x8e,
0xb8, 0xea, 0x38, 0xa8, 0x5b, 0x9b, 0x46, 0x01, 0xf5, 0x59, 0xbb, 0x6c, 0xca, 0xc9, 0x43, 0x20,
0xe7, 0x85, 0x91, 0x21, 0xb1, 0x94, 0xfb, 0x5e, 0x5c, 0x2e, 0xe9, 0x62, 0xa0, 0x94, 0xcb, 0x29,
0xa8, 0xb1, 0xd5, 0x40, 0xd3, 0x6a, 0x7e, 0x20, 0x54, 0xd7, 0xd4, 0xe5, 0xed, 0x6a, 0x3d, 0xfa,
0xec, 0x10, 0xc8, 0xe3, 0xbc, 0x0f, 0xa4, 0x08, 0x3b, 0x56, 0x75, 0x53, 0x85, 0x32, 0x63, 0x19,
0xae, 0xdd, 0xbe, 0x86, 0xda, 0x3b, 0xb5, 0xa8, 0xbf, 0x6d, 0xf5, 0x41, 0x13, 0x36, 0xa9, 0x31,
0x71, 0xb3, 0x06, 0x4f, 0x7e, 0xa0, 0xc1, 0x53, 0x1f, 0x6a, 0x30, 0x91, 0x3e, 0x3f, 0xf1, 0xbe,
0xda, 0x07, 0xdd, 0x6a, 0x71, 0x0d, 0x78, 0xbd, 0xbd, 0x47, 0xda, 0x74, 0x85, 0x40, 0xdb, 0x71,
0x36, 0x9e, 0xae, 0x91, 0x21, 0xba, 0xda, 0xea, 0x7e, 0x30, 0x9c, 0x46, 0xf5, 0x7f, 0xed, 0xd8,
0xa0, 0xd4, 0xe1, 0xdd, 0x12, 0x3d, 0xde, 0x51, 0x52, 0x58, 0x9c, 0xaf, 0xc3, 0xa4, 0x2d, 0x75,
0x98, 0xb2, 0xb5, 0x1e, 0xcf, 0x7d, 0xc2, 0x66, 0x2a, 0xdd, 0x9e, 0xfc, 0xb1, 0x16, 0x4b, 0xbf,
0xd4, 0xf9, 0xc6, 0x30, 0x63, 0xd7, 0x1f, 0xba, 0x85, 0x73, 0xf4, 0x77, 0xe1, 0x36, 0xd0, 0x50,
0x67, 0x70, 0x48, 0x22, 0xe1, 0x8c, 0xa3, 0x0b, 0xa1, 0x37, 0xb2, 0x6a, 0x16, 0x6e, 0xd8, 0xb5,
0x90, 0xec, 0xab, 0x47, 0x42, 0xae, 0x1e, 0xd1, 0xdb, 0x29, 0x44, 0x66, 0x53, 0xe0, 0x4a, 0x75,
0xe0, 0x2b, 0xf4, 0x98, 0x9e, 0xc9, 0xc4, 0x80, 0xb0, 0x0c, 0x3d, 0x08, 0x19, 0x85, 0xb9, 0x39,
0x06, 0xc4, 0xd0, 0x63, 0x96, 0x16, 0x18, 0xb1, 0x6c, 0xb7, 0x16, 0x5d, 0x9d, 0xcd, 0x00, 0xb5,
0x72, 0xe4, 0x5b, 0x27, 0x4a, 0x0b, 0x9d, 0x29, 0xc8, 0x20, 0xba, 0x98, 0xe7, 0xb3, 0xa2, 0x66,
0x05, 0x28, 0xab, 0x8b, 0xc6, 0x28, 0x84, 0x29, 0x74, 0xe0, 0xc9, 0x29, 0x84, 0x6f, 0x33, 0x20,
0x72, 0x7b, 0x03, 0xa2, 0x73, 0x4c, 0x88, 0xa1, 0x13, 0xb5, 0xbd, 0x11, 0x11, 0x59, 0x46, 0x1f,
0x18, 0x99, 0xad, 0xa7, 0x91, 0x7a, 0x50, 0x2d, 0x36, 0xa0, 0x25, 0xeb, 0xfe, 0xcf, 0x48, 0x2c,
0x25, 0xd7, 0xc6, 0x7f, 0xc6, 0x56, 0x5c, 0xf2, 0xaf, 0xc9, 0x30, 0xb9, 0x4c, 0xa8, 0xfa, 0xa7,
0x19, 0xab, 0x8b, 0x0c, 0x98, 0x95, 0x6d, 0xa4, 0x81, 0x46, 0xc4, 0x7d, 0x6e, 0xc6, 0xc2, 0xfc,
0x16, 0x5f, 0xe2, 0x73, 0xcd, 0x98, 0xb3, 0xd3, 0x84, 0x39, 0x39, 0x0d, 0x58, 0xb9, 0x4f, 0x8f,
0xf3, 0xea, 0x8e, 0xfe, 0x36, 0xaa, 0xe8, 0xc1, 0xc5, 0x20, 0x90, 0x11, 0x79, 0x31, 0x7b, 0x49,
0x2f, 0x03, 0xa5, 0x5d, 0x4f, 0xc3, 0x49, 0xe3, 0x49, 0x94, 0x37, 0x94, 0xa3, 0xf0, 0xa7, 0x66,
0xac, 0x39, 0x64, 0xc2, 0xcb, 0xbb, 0x9a, 0x90, 0xb8, 0xdb, 0x82, 0x25, 0xfb, 0x6c, 0x78, 0x75,
0x7f, 0x2b, 0x84, 0x05, 0x16, 0xbc, 0x92, 0x67, 0x46, 0x8a, 0xd2, 0x84, 0xe2, 0x5f, 0xac, 0x18,
0x18, 0xe8, 0xbf, 0xa8, 0xa9, 0x18, 0x37, 0x0a, 0x28, 0x93, 0xf8, 0x6d, 0xf6, 0x51, 0x9e, 0xef,
0x25, 0x2d, 0xa1, 0x4a, 0x90, 0xf9, 0x6f, 0x26, 0xa6, 0x7d, 0x3f, 0x0d, 0xd7, 0xcd, 0x7f, 0x60,
0xcb, 0x71, 0x23, 0x56, 0x1f, 0x6c, 0x86, 0x80, 0xbe, 0x78, 0x72, 0x91, 0x1d, 0xaf, 0x17, 0xdb,
0x21, 0x2e, 0xb4, 0xe2, 0xed, 0x12, 0x0b, 0xa4, 0xaa, 0x06, 0x68, 0x1a, 0x9c, 0x5e, 0xbb, 0xbd,
0x74, 0xca, 0xa8, 0xca, 0x5b, 0x28, 0x27, 0x3a, 0x66, 0xa8, 0x58, 0xe8, 0xaa, 0xfd, 0x2a, 0x56,
0xd5, 0xac, 0xf2, 0xb5, 0x97, 0xec, 0x8d, 0xee, 0x74, 0xb8, 0x9c, 0x96, 0xf5, 0x74, 0x65, 0xad,
0x28, 0xb6, 0xf8, 0x66, 0x22, 0xda, 0xc3, 0x20, 0x36, 0x6c, 0x38, 0x4c, 0xc1, 0xe6, 0x1c, 0x40,
0x4c, 0xea, 0xf9, 0x9e, 0xbf, 0xce, 0x70, 0xc6, 0x3f, 0x10, 0x5a, 0x2c, 0x0f, 0x9d, 0x22, 0x94,
0x11, 0x6e, 0x7e, 0x15, 0xbb, 0xec, 0xa8, 0x1d, 0x6a, 0xcc, 0x3e, 0x3b, 0xdb, 0xd7, 0x4e, 0xcc,
0x24, 0x9d, 0x67, 0xae, 0x96, 0xbe, 0x65, 0xa3, 0xdf, 0xfe, 0x75, 0x87, 0xf4, 0x10, 0xef, 0x69,
0xc6, 0xf2, 0x03, 0x16, 0xa4, 0x1c, 0xa0, 0x60, 0x71, 0x78, 0xf0, 0xc5, 0x8f, 0xbd, 0x78, 0x24,
0xe9, 0x9b, 0xee, 0x51, 0x41, 0x82, 0xf4, 0xd0, 0xa5, 0x0b, 0x77, 0x90, 0x0e, 0xff, 0xfa, 0xe6,
0x4f, 0x58, 0x25, 0x0f, 0xcc, 0xda, 0x27, 0xc9, 0x8a, 0x78, 0xcc, 0xeb, 0xc5, 0xa6, 0xcb, 0xda,
0x0e, 0xac, 0x3f, 0xd2, 0x00, 0xc9, 0x7e, 0x3d, 0x74, 0xd6, 0x6e, 0x9c, 0xb9, 0x01, 0x24, 0x17,
0x74, 0x07, 0x87, 0x34, 0x2f, 0x06, 0x42, 0xf4, 0x6c, 0xe4, 0xf3, 0x76, 0xf3, 0x7a, 0x87, 0x43,
0x11, 0xa5, 0x7c, 0xd0, 0xab, 0x39, 0xc5, 0xde, 0x5c, 0x84, 0x1c, 0x3b, 0x67, 0xa4, 0xb7, 0x05,
0x3b, 0xce, 0xdf, 0x74, 0xa0, 0xdf, 0x0b, 0xfa, 0xb9, 0xdd, 0x07, 0x0a, 0xb6, 0xa8, 0x0a, 0x33,
0xc9, 0xb3, 0x51, 0x4a, 0x12, 0xc3, 0xa1, 0x97, 0x0e, 0xf2, 0x20, 0x54, 0x10, 0xa7, 0xfc, 0xd0,
0xa3, 0x8b, 0x2b, 0xa0, 0xb5, 0x0e, 0xc0, 0x78, 0x1b, 0xb8, 0xa4, 0x03, 0x24, 0x63, 0x86, 0x32,
0x88, 0xe6, 0xf0, 0x93, 0xbc, 0x00, 0x28, 0x36, 0x9f, 0xec, 0x11, 0xa7, 0x73, 0x3f, 0xf2, 0x43,
0x1c, 0x51, 0x39, 0xd6, 0x95, 0x78, 0x90, 0x7a, 0x82, 0x45, 0xc6, 0x04, 0x25, 0x6d, 0x9d, 0x3c,
0xc1, 0xb7, 0x07, 0x55, 0xf1, 0x03, 0xa0, 0x45, 0x9f, 0x92, 0x0e, 0xb1, 0x8c, 0x9b, 0x70, 0x2f,
0xf4, 0x46, 0x91, 0xe7, 0x2e, 0x32, 0x26, 0x48, 0x28, 0x0b, 0x8d, 0x4b, 0xd8, 0x46, 0x76, 0x30,
0xfb, 0x4f, 0x65, 0x63, 0x25, 0x2e, 0x58, 0x2e, 0x60, 0x7e, 0xf5, 0x7c, 0x30, 0xb0, 0x50, 0x46,
0xf6, 0xbd, 0x26, 0x7d, 0xe1, 0xe9, 0x87, 0x02, 0x89, 0xd2, 0xc9, 0xd4, 0xd8, 0x3c, 0xd2, 0xb5,
0xf1, 0xf7, 0x8d, 0xf0, 0x1f, 0x05, 0x75, 0x05, 0x98, 0x59, 0xc6, 0x83, 0x40, 0x4e, 0xb6, 0x0e,
0xae, 0xed, 0x83, 0xd0, 0x96, 0x72, 0x40, 0xf5, 0x27, 0xb0, 0xb9, 0x6c, 0x04, 0xc8, 0x90, 0x02,
0xb4, 0xab, 0x00, 0xfd, 0x9a, 0x7b, 0x66, 0xa4, 0x20, 0x8e, 0x45, 0x17, 0x93, 0x88, 0xaf, 0x8e,
0x87, 0xdd, 0x6d, 0x87, 0xdb, 0xeb, 0xc6, 0xda, 0x4b, 0x6b, 0x11, 0x79, 0x98, 0x87, 0xc4, 0x0c,
0xf2, 0xe7, 0x60, 0x90, 0xa9, 0x9d, 0xfd, 0x41, 0x5a, 0xeb, 0x08, 0x90, 0x9b, 0x62, 0x07, 0xf4,
0x68, 0x07, 0x21, 0x66, 0x0f, 0x9a, 0xf5, 0x35, 0x5b, 0x08, 0xcc, 0xed, 0x8b, 0x3a, 0x1b, 0xe5,
0x6b, 0xcf, 0xdb, 0xc3, 0xeb, 0x17, 0x2a, 0xb8, 0xd9, 0xc1, 0xa0, 0xbf, 0x1b, 0xd9, 0xeb, 0x30,
0x95, 0x17, 0x14, 0x6a, 0xaf, 0x64, 0x07, 0xb4, 0x9d, 0xba, 0x67, 0x46, 0x52, 0xb2, 0x2f, 0x4a,
0xc9, 0xc3, 0x0c, 0xd5, 0xd0, 0x42, 0x58, 0x90, 0x43, 0x3a, 0x44, 0xe9, 0xdc, 0xe5, 0xc1, 0xa0,
0x94, 0xc3, 0x80, 0xac, 0x0a, 0x78, 0x53, 0x39, 0xd2, 0x33, 0x8a, 0xa0, 0xa7, 0xbb, 0x88, 0x3d,
0x0f, 0x42, 0x44, 0xae, 0x40, 0x41, 0x5e, 0xa1, 0x57, 0x6f, 0xa7, 0x40, 0x4e, 0xf4, 0x2c, 0xd8,
0x41, 0xdc, 0xa1, 0x67, 0xd3, 0x27, 0x94, 0x93, 0x6e, 0x81, 0x82, 0x08, 0x0d, 0x06, 0x49, 0x8a,
0x71, 0x37, 0x63, 0x7a, 0x8f, 0xfc, 0xc7, 0xa2, 0x34, 0xfe, 0xf3, 0x49, 0xe9, 0xc4, 0x32, 0x91,
0x94, 0x9b, 0x45, 0xaf, 0x16, 0x15, 0x74, 0x57, 0xc8, 0x70, 0x28, 0x58, 0x42, 0x92, 0x2a, 0x9c,
0x7e, 0x88, 0xfe, 0xb3, 0x18, 0x18, 0xba, 0xff, 0x7f, 0xd1, 0x69, 0x21, 0x60, 0xa3, 0x7d, 0xdf,
0xe5, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE save_library_xpm[1] = {{ png, sizeof( png ), "save_library_xpm" }};

View File

@ -0,0 +1,70 @@
/* Do not modify this file, it was automatically generated by the
* PNG2cpp CMake script, using a *.png file as input.
*/
#include <bitmaps.h>
static const unsigned char png[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52,
0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa9, 0x4a, 0x4c,
0xce, 0x00, 0x00, 0x03, 0x4e, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xb5, 0x96, 0x6b, 0x48, 0x93,
0x51, 0x18, 0xc7, 0xcf, 0xd2, 0xe1, 0x4a, 0xbf, 0x74, 0x31, 0x83, 0xae, 0x14, 0x2d, 0x32, 0x32,
0x2c, 0xad, 0xe9, 0xc8, 0x6e, 0xc3, 0x22, 0xd3, 0x48, 0x08, 0x02, 0xcb, 0x24, 0x2a, 0x50, 0x91,
0x2c, 0x2b, 0xb3, 0x8b, 0x6d, 0xd3, 0x75, 0x97, 0xb2, 0x68, 0x65, 0x69, 0x7d, 0xe8, 0x4b, 0xa8,
0x15, 0xdd, 0xe8, 0x62, 0x41, 0x31, 0x27, 0x49, 0xde, 0x62, 0x96, 0xce, 0x6d, 0x6e, 0x5e, 0x66,
0xf3, 0x12, 0xb8, 0x22, 0x53, 0x71, 0xfb, 0x77, 0xce, 0xcb, 0x06, 0x59, 0x5b, 0xe5, 0x9c, 0x0f,
0x3c, 0x3c, 0xef, 0xfb, 0x70, 0xde, 0xe7, 0x77, 0xfe, 0xe7, 0xf2, 0x9e, 0x43, 0xc8, 0x6f, 0x26,
0x25, 0x24, 0x98, 0x06, 0xde, 0xaf, 0xb9, 0x05, 0x87, 0x6a, 0x4c, 0xa1, 0x27, 0x34, 0x16, 0x57,
0x1e, 0x7c, 0xa4, 0xb6, 0x87, 0xbf, 0x5d, 0xb5, 0x84, 0x8c, 0xc4, 0x28, 0x64, 0x39, 0x75, 0xc8,
0x78, 0xbc, 0x97, 0xb9, 0x84, 0xcc, 0x74, 0xe6, 0x45, 0xb2, 0x7a, 0xe3, 0xf8, 0x64, 0x0d, 0x5c,
0xf9, 0x52, 0x69, 0x83, 0x8d, 0xbf, 0xa3, 0x3c, 0x6c, 0xa4, 0xa0, 0xd5, 0x0c, 0x24, 0xe5, 0xf1,
0x20, 0xf3, 0xf1, 0xf9, 0x46, 0x9f, 0x93, 0xc6, 0x14, 0x54, 0x5d, 0x54, 0x84, 0x5b, 0x51, 0x51,
0x76, 0x87, 0xba, 0xe7, 0x22, 0xe9, 0x87, 0xd6, 0x31, 0x01, 0xe9, 0xca, 0xca, 0x30, 0x30, 0x30,
0x80, 0x4a, 0xa5, 0x12, 0x39, 0x02, 0x81, 0x6d, 0x4d, 0x46, 0x99, 0x8d, 0x15, 0x9d, 0x90, 0xa2,
0x41, 0x40, 0x6a, 0x3d, 0xe7, 0xfe, 0x29, 0xf5, 0xa3, 0x07, 0x55, 0x3e, 0x79, 0x85, 0x17, 0x75,
0xdd, 0x78, 0x5a, 0xdd, 0x8d, 0x3b, 0x8f, 0x35, 0x90, 0x64, 0xa9, 0xec, 0x93, 0xf6, 0x7d, 0x42,
0xe0, 0xfe, 0x06, 0x04, 0x65, 0x34, 0x62, 0x1a, 0xf5, 0xa9, 0x07, 0x1a, 0x31, 0x25, 0xbd, 0x01,
0xe1, 0x72, 0xad, 0xcd, 0x6f, 0x67, 0xf9, 0x41, 0xbf, 0x9d, 0xea, 0x18, 0x41, 0xa2, 0x4a, 0xe2,
0x97, 0xa8, 0x12, 0xfe, 0x37, 0xa8, 0xfc, 0xd1, 0x6b, 0xac, 0x3a, 0x55, 0x8f, 0x08, 0x85, 0x16,
0xcb, 0xe4, 0x8d, 0x10, 0x9f, 0x31, 0x60, 0xc6, 0xe1, 0x26, 0xcc, 0xc9, 0xd2, 0x61, 0xde, 0x51,
0x3d, 0xe6, 0x1d, 0xd3, 0x63, 0x2e, 0x8d, 0xb3, 0x32, 0x75, 0x88, 0x3c, 0xd3, 0x8c, 0xf0, 0x9c,
0x26, 0x88, 0x58, 0xdb, 0x6c, 0xcd, 0xd7, 0xf1, 0x49, 0x15, 0x5b, 0x47, 0x34, 0x74, 0x6f, 0x3e,
0x7e, 0xc1, 0xe6, 0x7c, 0x1d, 0x05, 0x68, 0x31, 0xfb, 0x88, 0x0e, 0xc2, 0xe3, 0x06, 0x2c, 0x92,
0x1a, 0x11, 0x22, 0x37, 0x61, 0x49, 0x8e, 0x09, 0x8b, 0x65, 0x26, 0x2c, 0xcc, 0x6e, 0xe6, 0xc0,
0xb3, 0x32, 0x9b, 0xb0, 0xf6, 0xbc, 0xfe, 0x47, 0xc0, 0x9e, 0x8a, 0x6c, 0xb7, 0xc5, 0x65, 0x84,
0xa4, 0xd1, 0xe2, 0x65, 0xcc, 0xe9, 0x73, 0x15, 0x03, 0x69, 0x4a, 0x4a, 0x30, 0x38, 0x38, 0x88,
0x0b, 0xf7, 0xb5, 0x88, 0xbd, 0xa4, 0xc7, 0x82, 0x6c, 0x03, 0x07, 0x08, 0x3f, 0xdd, 0x86, 0xc8,
0x73, 0xed, 0x10, 0x9f, 0x6f, 0x87, 0xe8, 0x6c, 0x1b, 0x96, 0x2a, 0x5a, 0x38, 0xf8, 0xc6, 0x7c,
0x93, 0x2d, 0x28, 0xf5, 0x7d, 0xf1, 0x5f, 0x55, 0xb8, 0x03, 0xf5, 0x59, 0xad, 0xc8, 0x15, 0x08,
0x20, 0x89, 0x3e, 0x89, 0x98, 0x7c, 0x23, 0x85, 0xb4, 0x62, 0xe5, 0x05, 0x33, 0x24, 0xf9, 0x16,
0x44, 0x5f, 0xee, 0xc4, 0xda, 0x8b, 0x9f, 0x11, 0x41, 0xa1, 0x71, 0x4a, 0x33, 0xc2, 0x76, 0xdd,
0xeb, 0xde, 0x3d, 0x75, 0x45, 0x90, 0x47, 0xab, 0x8e, 0x29, 0xea, 0x35, 0x9b, 0x61, 0x69, 0xd4,
0x22, 0xe1, 0xb2, 0x86, 0x16, 0xec, 0xc0, 0x1a, 0x5a, 0x3c, 0x46, 0xd9, 0x85, 0x2d, 0x05, 0x3d,
0x58, 0x7f, 0xa5, 0x13, 0xf1, 0xd7, 0x2c, 0xd8, 0x24, 0xab, 0x44, 0xa6, 0xff, 0x64, 0xbb, 0xdc,
0xc7, 0xa7, 0x9d, 0x7e, 0x2b, 0xf1, 0x08, 0xe4, 0xf4, 0x1e, 0xeb, 0x0f, 0x24, 0xde, 0x30, 0x20,
0xf6, 0x2a, 0x53, 0x63, 0xc1, 0x06, 0x0a, 0x89, 0xa5, 0x90, 0x84, 0xeb, 0xcd, 0xa8, 0x32, 0xf4,
0xc2, 0xa4, 0x56, 0xe3, 0x8a, 0x50, 0x38, 0x44, 0xbf, 0x65, 0x7b, 0xaf, 0x80, 0x7a, 0x80, 0x47,
0x20, 0x36, 0x8c, 0xb5, 0xcd, 0x56, 0x24, 0x15, 0x1a, 0xa9, 0xaa, 0x0e, 0xce, 0x13, 0x0b, 0x5b,
0x71, 0xb7, 0xc2, 0x32, 0xac, 0xcd, 0xb3, 0xf4, 0x74, 0xb6, 0xc1, 0xed, 0xf4, 0xcf, 0xd2, 0x47,
0xeb, 0xbc, 0xfd, 0x65, 0x4a, 0xd2, 0xfe, 0x09, 0xb2, 0x5a, 0x2c, 0xdc, 0x5c, 0xb1, 0x58, 0xfa,
0xae, 0x13, 0x3b, 0x6e, 0xb6, 0x60, 0x5b, 0x41, 0x1b, 0x72, 0x1f, 0xb6, 0xfe, 0xd1, 0x19, 0x8f,
0x41, 0x6c, 0x8e, 0x8c, 0x2a, 0x15, 0x58, 0x8e, 0x45, 0xf6, 0x2e, 0x7f, 0xd0, 0x82, 0xe4, 0xdb,
0xfa, 0x61, 0x10, 0x6e, 0xe8, 0xe6, 0xcf, 0xf7, 0x6c, 0xe8, 0x9c, 0xab, 0x8e, 0xfb, 0xc9, 0x3a,
0x9c, 0xbd, 0xb3, 0xbc, 0x13, 0xd0, 0xff, 0xfd, 0x3b, 0xde, 0x2a, 0x14, 0x90, 0xfb, 0xfa, 0x72,
0x8b, 0x81, 0xf6, 0x7c, 0x9d, 0x47, 0xfb, 0xc8, 0x95, 0x22, 0x27, 0xc4, 0x5c, 0x53, 0x03, 0x65,
0x48, 0xc8, 0x90, 0xa3, 0x13, 0xc5, 0xa7, 0x09, 0x99, 0xe8, 0xd1, 0x3e, 0x72, 0x35, 0x47, 0x9c,
0x8a, 0xbe, 0x3e, 0xa7, 0x0a, 0x1b, 0x55, 0xd1, 0x45, 0xdb, 0xc7, 0x91, 0x91, 0xda, 0xdf, 0x56,
0x1d, 0x8b, 0x1d, 0x75, 0x75, 0xb8, 0x1e, 0x1a, 0x6a, 0x73, 0x9c, 0x59, 0x25, 0xa7, 0x08, 0x99,
0x4c, 0x3c, 0x31, 0x77, 0xa0, 0x81, 0xfe, 0x7e, 0xa8, 0xf3, 0xf2, 0x20, 0xe7, 0xf3, 0x99, 0x8a,
0x1e, 0xda, 0x26, 0x9e, 0x8c, 0xc6, 0x5c, 0x81, 0xba, 0xb4, 0x5a, 0x14, 0x89, 0xc5, 0x36, 0xc7,
0x21, 0x58, 0x4a, 0x55, 0x04, 0x92, 0xd1, 0x9a, 0xbb, 0x83, 0x4f, 0x36, 0x6e, 0xdc, 0x57, 0x9a,
0xdf, 0x4b, 0xbc, 0x65, 0x4e, 0x50, 0x55, 0x61, 0xe1, 0xb0, 0xa3, 0x9c, 0x5e, 0x54, 0xa6, 0x13,
0x6f, 0x9a, 0xbb, 0xcb, 0x89, 0xd7, 0xcd, 0xdd, 0x75, 0x6b, 0xac, 0x60, 0x7f, 0x5c, 0x20, 0xbd,
0x61, 0x3f, 0x01, 0x9b, 0x99, 0x59, 0x96, 0x90, 0x4a, 0xbf, 0x59, 0x00, 0x00, 0x00, 0x00, 0x49,
0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE save_part_xpm[1] = {{ png, sizeof( png ), "save_part_xpm" }};
//EOF

View File

@ -0,0 +1,36 @@
/* 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, 0x04, 0x00, 0x00, 0x00, 0x03, 0x43, 0x84,
0x45, 0x00, 0x00, 0x01, 0x32, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0xed, 0x93, 0xbd, 0x4b, 0x42,
0x61, 0x14, 0x87, 0x5f, 0xa2, 0x2e, 0xa5, 0x81, 0x15, 0x04, 0x0e, 0x19, 0xb7, 0xa1, 0x31, 0x5a,
0x82, 0x40, 0x08, 0xca, 0xd1, 0x21, 0xb0, 0xa1, 0x2d, 0x72, 0x89, 0xa6, 0x94, 0x20, 0x5c, 0x4a,
0x22, 0xa8, 0xa8, 0xa9, 0x8f, 0x5b, 0x38, 0x36, 0xc4, 0x45, 0x91, 0xe0, 0xd2, 0x90, 0xf4, 0x21,
0x85, 0x20, 0x77, 0xc8, 0x20, 0x3a, 0xff, 0x4a, 0x10, 0xb8, 0xf8, 0xb4, 0xbc, 0x5c, 0x2e, 0xdc,
0x04, 0x5d, 0x9a, 0xfc, 0x3d, 0xd3, 0x81, 0xf3, 0xbc, 0xe7, 0x70, 0xe0, 0x55, 0xaa, 0x97, 0x7f,
0xcf, 0x8e, 0xf1, 0xd3, 0x1d, 0xfd, 0xa7, 0x4a, 0xe5, 0xd7, 0x5b, 0x75, 0xfc, 0x3c, 0x72, 0x4d,
0xbd, 0x2d, 0x19, 0x42, 0x05, 0xa5, 0xf2, 0x1b, 0x2d, 0xc1, 0x8f, 0xcd, 0xb8, 0xaf, 0xba, 0x21,
0xc9, 0x2c, 0x29, 0xaa, 0xba, 0xce, 0x75, 0x22, 0x5d, 0x70, 0x4c, 0x89, 0x55, 0xe2, 0x41, 0xe9,
0x9e, 0x2c, 0x6b, 0x1c, 0xf1, 0x89, 0x60, 0x13, 0xa5, 0x44, 0x9a, 0x1c, 0xef, 0x9e, 0xfa, 0xc0,
0x48, 0x50, 0xda, 0x24, 0xc3, 0x21, 0x53, 0x6c, 0x23, 0xd8, 0x84, 0x59, 0xe0, 0x80, 0x84, 0xf7,
0xba, 0xb0, 0xcb, 0x7c, 0xbb, 0xf5, 0xf6, 0x58, 0x44, 0xb0, 0xe9, 0xa3, 0x86, 0xd0, 0x20, 0x84,
0x83, 0x20, 0x9c, 0x10, 0xa3, 0x12, 0x94, 0x6e, 0x49, 0x31, 0x47, 0x8c, 0x38, 0x82, 0xed, 0xad,
0x32, 0xcd, 0x39, 0xc2, 0x1b, 0x51, 0x9e, 0xbc, 0x99, 0x9e, 0x54, 0x21, 0x8c, 0x45, 0x83, 0x7d,
0x2d, 0x0d, 0xeb, 0x06, 0x93, 0x02, 0x82, 0x43, 0xd6, 0x77, 0x18, 0x4f, 0xb2, 0x98, 0x44, 0x10,
0x56, 0xb4, 0xa4, 0xb8, 0x43, 0x78, 0xc6, 0xe0, 0x05, 0xc1, 0xa5, 0xfc, 0x97, 0x54, 0x23, 0x42,
0x92, 0x04, 0x4b, 0x5a, 0x32, 0x99, 0x61, 0x99, 0x09, 0xd2, 0x08, 0xc2, 0x16, 0x06, 0x5f, 0x41,
0x49, 0x78, 0xe5, 0x8c, 0x22, 0x1f, 0x94, 0x11, 0x5c, 0x1c, 0x5c, 0x2e, 0x29, 0xea, 0xb6, 0x2a,
0x56, 0x70, 0xd2, 0x60, 0x73, 0xf4, 0xbb, 0x73, 0x86, 0x9a, 0x03, 0x57, 0x4a, 0x45, 0x94, 0xd9,
0x25, 0x63, 0xbd, 0x5f, 0xae, 0xf3, 0x0b, 0x33, 0xe6, 0xeb, 0xc7, 0x2a, 0x08, 0xcb, 0x0a, 0x00,
0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
};
const BITMAP_OPAQUE search_tree_xpm[1] = {{ png, sizeof( png ), "search_tree_xpm" }};
//EOF

View File

@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
width="26"
height="26"
id="svg2"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="add_library.svg">
<metadata
id="metadata166">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1916"
inkscape:window-height="1176"
id="namedview164"
showgrid="true"
inkscape:zoom="9.8333331"
inkscape:cx="1.915385"
inkscape:cy="10.576725"
inkscape:window-x="1920"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid4171" />
</sodipodi:namedview>
<defs
id="defs4">
<filter
style="color-interpolation-filters:sRGB"
id="filter3945-3">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur12-6" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter3941-7">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur9-5" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter3945-36">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur12-7" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter3941-5">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur9-3" />
</filter>
<radialGradient
id="radialGradient3010-5"
gradientUnits="userSpaceOnUse"
cy="20.493999"
cx="35.292999"
gradientTransform="matrix(0,-0.37207013,-0.43717023,0,26.320772,18.586092)"
r="16.955999">
<stop
stop-color="#539bed"
offset="0"
id="stop15-6" />
<stop
stop-color="#0969d3"
offset="1"
id="stop17-2" />
</radialGradient>
<radialGradient
id="f"
gradientUnits="userSpaceOnUse"
cy="35.126999"
cx="23.070999"
gradientTransform="matrix(1.1339295,0.02027846,-0.01018271,0.34234541,-78.115554,14.367665)"
r="10.319">
<stop
offset="0"
id="stop17" />
<stop
stop-opacity="0"
offset="1"
id="stop19" />
</radialGradient>
</defs>
<rect
style="opacity:1;fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:#d4aa00;stroke-width:1.03579581;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4298"
width="6.0397334"
height="24.979227"
x="19.479198"
y="0.54951072" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4300"
width="0.93513572"
height="10.755731"
x="22.036732"
y="3.2597971" />
<rect
style="opacity:1;fill:#5599ff;fill-opacity:1;fill-rule:nonzero;stroke:#0044aa;stroke-width:1.04181492;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4298-3"
width="5.9002724"
height="21.007425"
x="11.514425"
y="4.5084424" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4300-56"
width="0.920017"
height="8.2753372"
x="14.009696"
y="8.4033079" />
<circle
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.0999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4208"
cx="22.491428"
cy="21.753193"
r="1.4022287" />
<rect
style="opacity:1;fill:#24b024;fill-opacity:1;fill-rule:nonzero;stroke:#447821;stroke-width:1.01576376;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4298-7"
width="6.138113"
height="23.63736"
x="4.8727951"
y="-0.14059457"
transform="matrix(0.98219163,0.18788188,-0.18445897,0.98284022,0,0)" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4300-5"
width="0.95037615"
height="10.178031"
x="7.4720087"
y="2.4238956"
transform="matrix(0.98219163,0.18788188,-0.18445897,0.98284022,0,0)" />
<ellipse
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.0999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4208-3"
cx="3.0607922"
cy="20.845539"
transform="matrix(0.99865271,-0.05189193,0.0500435,0.99874704,0,0)"
rx="1.455725"
ry="1.4720935" />
<circle
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.0999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4208-6"
cx="14.473551"
cy="21.861053"
r="1.4022287" />
<g
id="g4582"
transform="matrix(0.49509083,0,0,0.49509083,32.39824,11.591285)">
<path
id="path21"
d="m -39.660415,26.794437 a 12.791895,3.7195357 0 1 1 -25.58255,0 12.791895,3.7195357 0 1 1 25.58255,0 z"
style="opacity:0.10824998;fill:url(#f)"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="fill:#c472d8;fill-opacity:1;stroke:#ab37c8;stroke-width:0.80298311px;stroke-opacity:1"
id="path23-6"
d="m -49.216231,27.75476 v -7.41345 l 7.834313,-0.03299 v -5.74491 h -7.826855 l -0.007,-8.1798449 -5.508635,0.0092 0.0035,8.1560279 -7.843028,0.0605 -0.02804,5.7229 7.877886,-0.02383 0.0053,7.424454 5.492853,0.022 z" />
<path
inkscape:connector-curvature="0"
style="opacity:0.40860003;fill:#ba5bd2;fill-opacity:1;stroke:#ba5ad2;stroke-width:0.80299997;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path25-2"
d="m -49.711899,27.358042 v -7.419364 h 7.853548 l -0.0053,-4.126304 h -7.840987 V 7.6039518 l -3.921513,0.014672 0.007,8.1937222 -7.871607,0.01467 -0.02103,4.084171 7.901442,0.0073 -0.01051,7.413861 3.909109,0.02567 z" />
<path
style="opacity:0.31183005;fill:#ffffff;fill-rule:evenodd"
inkscape:connector-curvature="0"
id="path27-9"
d="m -62.268794,17.453783 c 0,1.591179 20.40054,-0.795588 20.40054,-0.02567 v -2.463758 l -7.83863,0.02546 V 6.8058647 h -4.710717 V 14.98965 h -7.851193 v 2.463759 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,184 @@
<?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.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="export_part.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1916"
inkscape:window-height="1176"
id="namedview43"
showgrid="true"
inkscape:zoom="21.730769"
inkscape:cx="12.884956"
inkscape:cy="13"
inkscape:window-x="1920"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid3000"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6">
<filter
id="filter3941">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur9" />
</filter>
<filter
id="filter3945">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur12" />
</filter>
<radialGradient
id="radialGradient3010"
gradientUnits="userSpaceOnUse"
cy="20.494"
cx="35.293"
gradientTransform="matrix(0,-0.37207013,-0.43717023,0,26.320772,18.586092)"
r="16.956">
<stop
stop-color="#539bed"
offset="0"
id="stop15" />
<stop
stop-color="#0969d3"
offset="1"
id="stop17" />
</radialGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4207"
id="linearGradient4213"
x1="8.5"
y1="16"
x2="25.5"
y2="16"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
id="linearGradient4207">
<stop
id="stop4211"
offset="0"
style="stop-color:#cd87de;stop-opacity:1" />
<stop
id="stop4209"
offset="1"
style="stop-color:#ab37c8;stop-opacity:1" />
</linearGradient>
</defs>
<path
d="m 4.5,1.5 0,23 17,-11.5 z"
stroke-miterlimit="4"
id="path19"
style="fill:#fafafa;stroke:#800000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
d="m 7.5,9.5 4,0"
stroke-miterlimit="4"
id="path21"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="m 7.5,15.5 4,0"
stroke-miterlimit="4"
id="path23"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
stroke-linejoin="miter"
d="M21.5,13,25,13"
stroke="#4d4d4d"
stroke-linecap="round"
stroke-dasharray="none"
stroke-miterlimit="4"
stroke-width="1.50000000000000000"
fill="#f0f0f0"
id="path25"
style="stroke:#800000" />
<path
d="M 4.5,9 1,9"
stroke-miterlimit="4"
id="path27"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="M 4.5,17 1,17"
stroke-miterlimit="4"
id="path29"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="m 9.5,13.5 0,4"
stroke-miterlimit="4"
id="path31"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<g
transform="translate(-0.22142,2.9613778)"
id="g4228"
style="stroke:#892ca0">
<g
id="g4271"
transform="matrix(0.99972422,0,0,1.0138482,0.49280792,-0.3165955)">
<path
stroke-miterlimit="4"
d="M 15.5,8.927706 V 12.5 l -6.646132,0.01746 v 6.649969 l 6.646246,-0.01746 v 3.54755 l 9.850669,-6.660207 -9.850669,-7.109421 z"
style="color:#000000;fill:url(#linearGradient4213);fill-opacity:1;stroke:#ab37c8;stroke-width:0.67293131;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
id="path104"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<path
d="m 16.272923,13.127409 -6.649096,0.01746 v 5.410651 l 6.649096,-0.01746 v 2.818171 l 7.84198,-5.35228 -7.84198,-5.712706 z"
style="color:#000000;fill:none;stroke:#ffffff;stroke-width:0.67307878px;stroke-opacity:0.29411765"
id="path106"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -0,0 +1,176 @@
<?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.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="import_part.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1916"
inkscape:window-height="1176"
id="namedview43"
showgrid="true"
inkscape:zoom="21.730769"
inkscape:cx="12.884956"
inkscape:cy="13"
inkscape:window-x="1920"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="g3882">
<inkscape:grid
type="xygrid"
id="grid3000"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6">
<filter
id="filter3941">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur9" />
</filter>
<filter
id="filter3945">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur12" />
</filter>
<radialGradient
id="radialGradient3010"
gradientUnits="userSpaceOnUse"
cy="20.494"
cx="35.293"
gradientTransform="matrix(0,-0.37207013,-0.43717023,0,26.320772,18.586092)"
r="16.956">
<stop
stop-color="#539bed"
offset="0"
id="stop15" />
<stop
stop-color="#0969d3"
offset="1"
id="stop17" />
</radialGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#e"
id="radialGradient3886"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0,0.40730059,-0.50386077,0,29.544437,6.2435788)"
cx="35.292999"
cy="20.493999"
r="16.955999" />
<radialGradient
id="e"
gradientUnits="userSpaceOnUse"
cy="20.493999"
cx="35.292999"
gradientTransform="matrix(0,-0.84302,1.0202,0,-4.8963249,41.059418)"
r="16.955999">
<stop
stop-color="#73d216"
offset="0"
id="stop12-7" />
<stop
stop-color="#4e9a06"
offset="1"
id="stop14-2" />
</radialGradient>
</defs>
<path
d="m 4.5,1.5 0,23 17,-11.5 z"
stroke-miterlimit="4"
id="path19"
style="fill:#fafafa;stroke:#800000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
d="m 7.5,9.5 4,0"
stroke-miterlimit="4"
id="path21"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="m 7.5,15.5 4,0"
stroke-miterlimit="4"
id="path23"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
stroke-linejoin="miter"
d="M21.5,13,25,13"
stroke="#4d4d4d"
stroke-linecap="round"
stroke-dasharray="none"
stroke-miterlimit="4"
stroke-width="1.50000000000000000"
fill="#f0f0f0"
id="path25"
style="stroke:#800000" />
<path
d="M 4.5,9 1,9"
stroke-miterlimit="4"
id="path27"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="M 4.5,17 1,17"
stroke-miterlimit="4"
id="path29"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="m 9.5,13.5 0,4"
stroke-miterlimit="4"
id="path31"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<g
id="g3882"
transform="matrix(0,-0.78872395,0.9644876,0,-7.4293335,31.16795)">
<path
id="path25-6"
stroke-miterlimit="10"
d="m 19.626377,7.977654 -8.892386,0.0019 v 6.277014 l -3.9488121,0.0037 8.4671621,9.661444 8.319975,-9.661927 -3.948606,-0.002 0.0024,-6.280396 z"
style="color:#000000;fill:url(#radialGradient3886);fill-rule:evenodd;stroke:#3a7304;stroke-width:0.48848495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -13,7 +13,7 @@
width="26"
height="26"
id="svg2"
inkscape:version="0.91 r13725"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="new_library.svg">
<metadata
id="metadata166">
@ -36,15 +36,15 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1366"
inkscape:window-height="717"
inkscape:window-width="1916"
inkscape:window-height="1176"
id="namedview164"
showgrid="true"
inkscape:zoom="9.8333331"
inkscape:cx="1.915385"
inkscape:cy="10.576725"
inkscape:window-x="0"
inkscape:window-y="1080"
inkscape:window-x="1920"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<inkscape:grid
@ -97,6 +97,19 @@
offset="1"
id="stop17-2" />
</radialGradient>
<filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter4288"
x="-0.38282099"
width="1.765642"
y="-0.382779"
height="1.765558">
<feGaussianBlur
inkscape:collect="always"
stdDeviation="0.8772019"
id="feGaussianBlur4290" />
</filter>
</defs>
<rect
style="opacity:1;fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:#d4aa00;stroke-width:1.03579581;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
@ -162,66 +175,17 @@
cx="14.473551"
cy="21.861053"
r="1.4022287" />
<g
transform="matrix(-1.1611535,0,0,-1.2412687,33.33417,18.289374)"
id="g33-2"
style="fill:#ffffff;stroke:#ffffff">
<path
style="opacity:0.75;fill:#ffffff;stroke:#ffffff;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3945-3)"
inkscape:connector-curvature="0"
d="M 12.266,2.5 23.5,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path35-9" />
<path
style="opacity:0.75;fill:#ffffff;stroke:#ffffff;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3941-7)"
inkscape:connector-curvature="0"
d="M 23.5,2.5 12.266,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path37-1" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#ffffff;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
d="M 21.359,15.782 13.395884,15.751334 13.364919,10.0462 9.6601383,10.0428 10.954809,8.5020026 17.471006,0.95630604 23.839291,8.4330071 25.092345,10.101132 21.604416,10.045 l -0.04435,5.085465 z"
stroke-miterlimit="10"
id="path39-2"
sodipodi:nodetypes="ccccccccccc" />
<path
inkscape:connector-curvature="0"
style="color:#000000;opacity:0.38502401;fill:#ffffff;stroke:#ffffff;stroke-width:0.43488666;stroke-miterlimit:10"
d="m 20.995,15.339 -6.8567,0.0017 0,-5.7344 -2.9211,-0.0069 6.408,-7.7025 6.3022,7.7047 -2.931,0.0023 -0.0012,5.7354 z"
stroke-miterlimit="10"
id="path41-7" />
</g>
<g
transform="matrix(-1,0,0,-1,30.5001,16.687055)"
id="g33-9">
<path
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3945-36)"
inkscape:connector-curvature="0"
d="M 12.266,2.5 23.5,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path35-1" />
<path
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3941-5)"
inkscape:connector-curvature="0"
d="M 23.5,2.5 12.266,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path37-2" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:url(#radialGradient3010-5);fill-rule:evenodd;stroke:#065ec2;stroke-width:0.435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
d="m 21.359,15.782 -7.7154,-0.0017 0,-5.7341 -3.4261,-0.0034 7.3464,-8.8258 7.2188,8.8262 -3.426,0.0018 0.0021,5.7372 z"
stroke-miterlimit="10"
id="path39-7" />
<path
inkscape:connector-curvature="0"
style="color:#000000;opacity:0.38502401;fill:none;stroke:#ffffff;stroke-width:0.43488666;stroke-miterlimit:10"
d="m 20.995,15.339 -6.8567,0.0017 0,-5.7344 -2.9211,-0.0069 6.408,-7.7025 6.3022,7.7047 -2.931,0.0023 -0.0012,5.7354 z"
stroke-miterlimit="10"
id="path41-0" />
</g>
<path
style="opacity:1;fill:#ffff00;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;filter:url(#filter4288)"
id="path4146"
sodipodi:type="arc"
sodipodi:cx="13.126579"
sodipodi:cy="5.656394"
sodipodi:rx="2.75"
sodipodi:ry="2.75"
sodipodi:start="3.1699543"
sodipodi:end="3.1206487"
sodipodi:open="true"
d="M 10.377685,5.5784099 A 2.75,2.75 0 0 1 13.170674,2.9067475 2.75,2.75 0 0 1 15.87656,5.6665933 2.75,2.75 0 0 1 13.150277,8.4062919 2.75,2.75 0 0 1 10.377182,5.7139857"
transform="matrix(1.1807649,0,0,1.1807649,-11.253013,-2.7468737)" />
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@ -1,21 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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"
version="1.0"
width="26"
version="1.1"
height="26"
id="svg2"
inkscape:version="0.91 r"
sodipodi:docname="save_library.svg">
inkscape:version="0.91 r13725"
sodipodi:docname="new_library.svg">
<metadata
id="metadata150">
id="metadata166">
<rdf:RDF>
<cc:Work
rdf:about="">
@ -35,367 +36,53 @@
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1053"
id="namedview148"
inkscape:window-width="1366"
inkscape:window-height="717"
id="namedview164"
showgrid="true"
inkscape:zoom="21.730769"
inkscape:cx="1.3115044"
inkscape:cy="12.907965"
inkscape:zoom="9.8333331"
inkscape:cx="1.915385"
inkscape:cy="10.576725"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-y="1080"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
inkscape:showpageshadow="false">
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid3066"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
spacingx="0.5px"
spacingy="0.5px" />
id="grid4171" />
</sodipodi:namedview>
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
id="linearGradient3841">
<stop
style="stop-color:#797979;stop-opacity:1"
offset="0"
id="stop3843" />
<stop
style="stop-color:#9a9a9a;stop-opacity:1"
offset="1"
id="stop3845" />
</linearGradient>
<linearGradient
id="linearGradient3823">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop3825" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop3827" />
</linearGradient>
<radialGradient
id="t"
xlink:href="#a"
gradientUnits="userSpaceOnUse"
cy="486.64999"
cx="605.71002"
gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)"
r="117.14" />
<linearGradient
id="a">
<stop
offset="0"
id="stop8" />
<stop
stop-opacity="0"
offset="1"
id="stop10" />
</linearGradient>
<radialGradient
id="s"
xlink:href="#a"
gradientUnits="userSpaceOnUse"
cy="486.64999"
cx="605.71002"
gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)"
r="117.14" />
<linearGradient
id="ac"
y2="609.51001"
gradientUnits="userSpaceOnUse"
x2="302.85999"
gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)"
y1="366.64999"
x1="302.85999">
<stop
stop-opacity="0"
offset="0"
id="stop14" />
<stop
offset=".5"
id="stop16" />
<stop
stop-opacity="0"
offset="1"
id="stop18" />
</linearGradient>
<radialGradient
id="r"
gradientUnits="userSpaceOnUse"
cy="6.4576998"
cx="23.447001"
gradientTransform="matrix(-1.3145,-0.010063,-0.01023,1.3362,46.221,-4.9099)"
r="19.062">
<stop
stop-color="#fff"
offset="0"
id="stop21" />
<stop
stop-color="#fff"
stop-opacity="0"
offset="1"
id="stop23" />
</radialGradient>
<linearGradient
id="v"
y2="12.584"
gradientUnits="userSpaceOnUse"
x2="12.624"
gradientTransform="matrix(0.91411,0,0,0.91411,-3.8687,-2.7069)"
y1="27.393999"
x1="33.060001">
<stop
stop-color="#fff"
offset="0"
id="stop26" />
<stop
stop-color="#fff"
stop-opacity="0"
offset="1"
id="stop28" />
</linearGradient>
<radialGradient
id="u"
gradientUnits="userSpaceOnUse"
cy="36.421001"
cx="24.837"
gradientTransform="matrix(0.61219543,0,0,-0.2208348,-4.3776481,22.748021)"
r="15.645">
<stop
offset="0"
id="stop31" />
<stop
stop-opacity="0"
offset="1"
id="stop33" />
</radialGradient>
<linearGradient
id="x"
y2="35.280998"
gradientUnits="userSpaceOnUse"
x2="24.688"
gradientTransform="matrix(0.54167,0,0,0.54167,0.40830031,2.0180928)"
y1="35.280998"
x1="7.0625">
<stop
stop-color="#838383"
offset="0"
id="stop36" />
<stop
stop-color="#bbb"
stop-opacity="0"
offset="1"
id="stop38" />
</linearGradient>
<linearGradient
id="y"
y2="40.944"
gradientUnits="userSpaceOnUse"
x2="36.182999"
gradientTransform="matrix(0.54167,0,0,0.54167,-0.02259269,2.7362389)"
y1="28.481001"
x1="7.6046">
<stop
stop-color="#bbb"
offset="0"
id="stop41" />
<stop
stop-color="#9f9f9f"
offset="1"
id="stop43" />
</linearGradient>
<linearGradient
id="z"
y2="33.758999"
gradientUnits="userSpaceOnUse"
x2="12.222"
gradientTransform="matrix(0.54167,0,0,0.54167,-0.02259269,2.7362389)"
y1="37.206001"
x1="12.277">
<stop
stop-color="#eee"
offset="0"
id="stop46" />
<stop
stop-color="#eee"
stop-opacity="0"
offset="1"
id="stop48" />
</linearGradient>
<radialGradient
id="q"
gradientUnits="userSpaceOnUse"
cy="2.9584999"
cx="15.571"
gradientTransform="matrix(0.69669595,0.42342344,-0.3850082,0.63353723,-1.2978465,0.09459019)"
r="20.936001">
<stop
stop-color="#e4e4e4"
offset="0"
id="stop51" />
<stop
stop-color="#d3d3d3"
offset="1"
id="stop53" />
</radialGradient>
<linearGradient
id="aa"
y2="47.620998"
gradientUnits="userSpaceOnUse"
x2="44.096001"
gradientTransform="matrix(0.54167,0,0,0.54167,-0.02259269,2.736239)"
y1="4.4331002"
x1="12.378">
<stop
stop-color="#fff"
offset="0"
id="stop56" />
<stop
stop-color="#fff"
stop-opacity="0"
offset="1"
id="stop58" />
</linearGradient>
<linearGradient
id="ab"
y2="26.357"
gradientUnits="userSpaceOnUse"
x2="23.688"
gradientTransform="matrix(0.54167,0,0,0.54167,-0.02259269,2.7362389)"
y1="11.319"
x1="23.688">
<stop
stop-color="#fff"
stop-opacity=".25490"
offset="0"
id="stop61" />
<stop
stop-color="#fff"
offset="1"
id="stop63" />
</linearGradient>
<linearGradient
id="w"
y2="11.781"
gradientUnits="userSpaceOnUse"
x2="21.747999"
y1="31.965"
x1="33.431"
gradientTransform="matrix(0.56214513,0,0,0.57454937,-0.90708569,1.6016569)">
<stop
stop-color="#fff"
offset="0"
id="stop66" />
<stop
stop-color="#e6e6e6"
offset=".5"
id="stop68" />
<stop
stop-color="#fff"
offset=".75"
id="stop70" />
<stop
stop-color="#e1e1e1"
offset=".84167"
id="stop72" />
<stop
stop-color="#fff"
offset="1"
id="stop74" />
</linearGradient>
<linearGradient
id="ad"
y2="16.743"
gradientUnits="userSpaceOnUse"
x2="8.8952999"
y1="15.868"
x1="14.752">
<stop
stop-color="#3465a4"
offset="0"
id="stop77" />
<stop
stop-color="#3465a4"
stop-opacity="0"
offset="1"
id="stop79" />
</linearGradient>
<linearGradient
id="ae"
y2="21.118"
gradientUnits="userSpaceOnUse"
x2="7"
y1="18.25"
x1="12.25">
<stop
stop-color="#204a87"
offset="0"
id="stop82" />
<stop
stop-color="#204a87"
stop-opacity="0"
offset="1"
id="stop84" />
</linearGradient>
<linearGradient
id="linearGradient2834"
y2="23.891001"
gradientUnits="userSpaceOnUse"
x2="1.3099999"
gradientTransform="matrix(0,-0.33674,-0.33543,0,20.014,15.582)"
y1="23.891001"
x1="28.671">
<stop
id="stop2266"
style="stop-color:#d7e866"
offset="0" />
<stop
id="stop2268"
style="stop-color:#8cab2a"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient2831"
y2="33.332001"
gradientUnits="userSpaceOnUse"
x2="57.410999"
gradientTransform="matrix(0,0.35779214,-0.35535445,0,22.381416,-1.3220206)"
y1="33.332001"
x1="8.5272999">
<stop
id="stop4224"
style="stop-color:#fff"
offset="0" />
<stop
id="stop4226"
style="stop-color:#fff;stop-opacity:0"
offset="1" />
</linearGradient>
<filter
color-interpolation-filters="sRGB"
id="filter3945">
style="color-interpolation-filters:sRGB"
id="filter3945-3">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur12" />
id="feGaussianBlur12-6" />
</filter>
<filter
color-interpolation-filters="sRGB"
id="filter3941">
style="color-interpolation-filters:sRGB"
id="filter3941-7">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur9" />
id="feGaussianBlur9-5" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter3945-36">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur12-7" />
</filter>
<filter
style="color-interpolation-filters:sRGB"
id="filter3941-5">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur9-3" />
</filter>
<radialGradient
id="radialGradient3010"
id="radialGradient3010-5"
gradientUnits="userSpaceOnUse"
cy="20.493999"
cx="35.292999"
@ -404,111 +91,137 @@
<stop
stop-color="#539bed"
offset="0"
id="stop15" />
id="stop15-6" />
<stop
stop-color="#0969d3"
offset="1"
id="stop17" />
id="stop17-2" />
</radialGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3823"
id="linearGradient3829"
x1="13.5"
y1="26"
x2="13.5"
y2="18"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3841"
id="linearGradient3847"
x1="13.5"
y1="17.5"
x2="13.5"
y2="10"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
style="fill:none;fill-opacity:1;stroke:url(#linearGradient3829);stroke-opacity:1;opacity:0.1"
id="rect3097"
width="25"
height="7.9999952"
x="0.5"
y="17.5"
rx="1.5"
ry="1.5" />
<path
style="fill:#cccccc;stroke:url(#linearGradient3847);stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="M 1.5,17.5 5,10 l 16,0 3.5,7.5"
id="path3877"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;stroke:#b3b3b3;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
d="m 7,11.5 -2,4 16,0 -2,-4"
id="path3879"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
style="opacity:1;fill:#ffd42a;fill-opacity:1;fill-rule:nonzero;stroke:#d4aa00;stroke-width:1.03579581;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4298"
width="6.0397334"
height="24.979227"
x="19.479198"
y="0.54951072" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4300"
width="0.93513572"
height="10.755731"
x="22.036732"
y="3.2597971" />
<rect
style="opacity:1;fill:#5599ff;fill-opacity:1;fill-rule:nonzero;stroke:#0044aa;stroke-width:1.04181492;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4298-3"
width="5.9002724"
height="21.007425"
x="11.514425"
y="4.5084424" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4300-56"
width="0.920017"
height="8.2753372"
x="14.009696"
y="8.4033079" />
<circle
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.0999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4208"
cx="22.491428"
cy="21.753193"
r="1.4022287" />
<rect
style="opacity:1;fill:#24b024;fill-opacity:1;fill-rule:nonzero;stroke:#447821;stroke-width:1.01576376;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4298-7"
width="6.138113"
height="23.63736"
x="4.8727951"
y="-0.14059457"
transform="matrix(0.98219163,0.18788188,-0.18445897,0.98284022,0,0)" />
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4300-5"
width="0.95037615"
height="10.178031"
x="7.4720087"
y="2.4238956"
transform="matrix(0.98219163,0.18788188,-0.18445897,0.98284022,0,0)" />
<ellipse
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.0999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4208-3"
cx="3.0607922"
cy="20.845539"
transform="matrix(0.99865271,-0.05189193,0.0500435,0.99874704,0,0)"
rx="1.455725"
ry="1.4720935" />
<circle
style="opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.0999999;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4208-6"
cx="14.473551"
cy="21.861053"
r="1.4022287" />
<g
transform="matrix(-1,0,0,-1,30.5002,15.9995)"
id="g33">
transform="matrix(-1.1611535,0,0,-1.2412687,33.33417,18.289374)"
id="g33-2"
style="fill:#ffffff;stroke:#ffffff">
<path
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3945)"
style="opacity:0.75;fill:#ffffff;stroke:#ffffff;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3945-3)"
inkscape:connector-curvature="0"
d="M 12.266,2.5 23.5,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path35" />
id="path35-9" />
<path
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3941)"
style="opacity:0.75;fill:#ffffff;stroke:#ffffff;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3941-7)"
inkscape:connector-curvature="0"
d="M 23.5,2.5 12.266,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path37" />
id="path37-1" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:url(#radialGradient3010);fill-rule:evenodd;stroke:#065ec2;stroke-width:0.435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
style="color:#000000;fill:#ffffff;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
d="M 21.359,15.782 13.395884,15.751334 13.364919,10.0462 9.6601383,10.0428 10.954809,8.5020026 17.471006,0.95630604 23.839291,8.4330071 25.092345,10.101132 21.604416,10.045 l -0.04435,5.085465 z"
stroke-miterlimit="10"
id="path39-2"
sodipodi:nodetypes="ccccccccccc" />
<path
inkscape:connector-curvature="0"
style="color:#000000;opacity:0.38502401;fill:#ffffff;stroke:#ffffff;stroke-width:0.43488666;stroke-miterlimit:10"
d="m 20.995,15.339 -6.8567,0.0017 0,-5.7344 -2.9211,-0.0069 6.408,-7.7025 6.3022,7.7047 -2.931,0.0023 -0.0012,5.7354 z"
stroke-miterlimit="10"
id="path41-7" />
</g>
<g
transform="matrix(-1,0,0,-1,30.5001,16.687055)"
id="g33-9">
<path
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3945-36)"
inkscape:connector-curvature="0"
d="M 12.266,2.5 23.5,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path35-1" />
<path
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3941-5)"
inkscape:connector-curvature="0"
d="M 23.5,2.5 12.266,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path37-2" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:url(#radialGradient3010-5);fill-rule:evenodd;stroke:#065ec2;stroke-width:0.435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
d="m 21.359,15.782 -7.7154,-0.0017 0,-5.7341 -3.4261,-0.0034 7.3464,-8.8258 7.2188,8.8262 -3.426,0.0018 0.0021,5.7372 z"
stroke-miterlimit="10"
id="path39" />
id="path39-7" />
<path
inkscape:connector-curvature="0"
style="opacity:0.38502401;color:#000000;fill:none;stroke:#ffffff;stroke-width:0.43488666;stroke-miterlimit:10"
d="m 20.995,15.339 -6.8567,0.0017 V 9.6063 l -2.9211,-0.0069 6.408,-7.7025 6.3022,7.7047 -2.931,0.0023 -0.0012,5.7354 z"
style="color:#000000;opacity:0.38502401;fill:none;stroke:#ffffff;stroke-width:0.43488666;stroke-miterlimit:10"
d="m 20.995,15.339 -6.8567,0.0017 0,-5.7344 -2.9211,-0.0069 6.408,-7.7025 6.3022,7.7047 -2.931,0.0023 -0.0012,5.7354 z"
stroke-miterlimit="10"
id="path41" />
id="path41-0" />
</g>
<rect
style="fill:#cccccc;fill-opacity:1;stroke:#969696;stroke-opacity:1"
id="rect3869"
width="23"
height="6.9999976"
x="1.5"
y="17.5"
rx="0.5"
ry="0.5" />
<path
style="fill:none;stroke:#e6e6e6;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
d="m 2.5,22.5 0,-4 21,0"
id="path3881"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
sodipodi:type="arc"
style="fill:#00cf00;fill-opacity:1;stroke:none"
id="path3871"
sodipodi:cx="22"
sodipodi:cy="20"
sodipodi:rx="1.4876027"
sodipodi:ry="1.5130434"
d="m 23.487603,20 a 1.4876027,1.5130434 0 1 1 -2.975206,0 1.4876027,1.5130434 0 1 1 2.975206,0 z"
transform="matrix(0.67222249,0,0,0.66091957,6.2111052,7.7816086)" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path3839"
d="m 23.5,19.5 0,4 -21,0"
style="fill:none;stroke:#b3b3b3;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
</svg>

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="26"
width="26"
version="1.1"
id="svg2"
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
sodipodi:docname="save_part.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1916"
inkscape:window-height="1176"
id="namedview43"
showgrid="true"
inkscape:zoom="21.730769"
inkscape:cx="12.884956"
inkscape:cy="13"
inkscape:window-x="1920"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="svg2">
<inkscape:grid
type="xygrid"
id="grid3000"
empspacing="2"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true" />
</sodipodi:namedview>
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6">
<filter
id="filter3941">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur9" />
</filter>
<filter
id="filter3945">
<feGaussianBlur
stdDeviation="0.05617153"
id="feGaussianBlur12" />
</filter>
<radialGradient
id="radialGradient3010"
gradientUnits="userSpaceOnUse"
cy="20.494"
cx="35.293"
gradientTransform="matrix(0,-0.37207013,-0.43717023,0,26.320772,18.586092)"
r="16.956">
<stop
stop-color="#539bed"
offset="0"
id="stop15" />
<stop
stop-color="#0969d3"
offset="1"
id="stop17" />
</radialGradient>
</defs>
<path
d="m 4.5,1.5 0,23 17,-11.5 z"
stroke-miterlimit="4"
id="path19"
style="fill:#fafafa;stroke:#800000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
d="m 7.5,9.5 4,0"
stroke-miterlimit="4"
id="path21"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="m 7.5,15.5 4,0"
stroke-miterlimit="4"
id="path23"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
stroke-linejoin="miter"
d="M21.5,13,25,13"
stroke="#4d4d4d"
stroke-linecap="round"
stroke-dasharray="none"
stroke-miterlimit="4"
stroke-width="1.50000000000000000"
fill="#f0f0f0"
id="path25"
style="stroke:#800000" />
<path
d="M 4.5,9 1,9"
stroke-miterlimit="4"
id="path27"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="M 4.5,17 1,17"
stroke-miterlimit="4"
id="path29"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
d="m 9.5,13.5 0,4"
stroke-miterlimit="4"
id="path31"
style="fill:#f0f0f0;stroke:#800000;stroke-width:1.20000005;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<g
transform="rotate(-180,15.314129,8.0053679)"
id="g33">
<path
d="M 12.266,2.5 23.5,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path35"
inkscape:connector-curvature="0"
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3945)" />
<path
d="M 23.5,2.5 12.266,13.734"
transform="matrix(-1,0,0,0.99999984,35.000085,2.9472792e-4)"
stroke-miterlimit="4"
id="path37"
inkscape:connector-curvature="0"
style="opacity:0.75;fill:none;stroke-width:0;stroke-miterlimit:4;filter:url(#filter3941)" />
<path
style="color:#000000;fill:url(#radialGradient3010);fill-rule:evenodd;stroke:#065ec2;stroke-width:0.435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none"
d="m 21.359,15.782 -7.7154,-0.0017 v -5.7341 l -3.4261,-0.0034 7.3464,-8.8258 7.2188,8.8262 -3.426,0.0018 0.0021,5.7372 z"
stroke-miterlimit="10"
id="path39"
inkscape:connector-curvature="0" />
<path
style="color:#000000;opacity:0.38502401;fill:none;stroke:#ffffff;stroke-width:0.43488666;stroke-miterlimit:10"
d="m 20.995,15.339 -6.8567,0.0017 V 9.6063 l -2.9211,-0.0069 6.408,-7.7025 6.3022,7.7047 -2.931,0.0023 -0.0012,5.7354 z"
stroke-miterlimit="10"
id="path41"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@ -0,0 +1,48 @@
<?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"
version="1.1"
id="svg2"
viewBox="0 0 26 26"
height="26"
width="26">
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
transform="translate(0,-1026.3622)"
id="layer1">
<rect
y="1033.927"
x="1.0101525"
height="12.058696"
width="24.054258"
id="rect3336"
style="fill:#d2d2d2;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<text
id="text4138"
y="1044.5966"
x="2.0834394"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'Droid Sans';-inkscape-font-specification:'Droid Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'Droid Sans';-inkscape-font-specification:'Droid Sans, Normal';text-align:start;writing-mode:lr-tb;text-anchor:start"
y="1044.5966"
x="2.0834394"
id="tspan4140">ab?</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -34,6 +34,8 @@
#include <html_messagebox.h>
#include <dialog_exit_base.h>
#include <functional>
class DIALOG_EXIT: public DIALOG_EXIT_BASE
{
@ -175,3 +177,168 @@ int YesNoCancelDialog( wxWindow* aParent,
return dlg.ShowModal();
}
int SelectSingleOption( wxWindow* aParent, const wxString& aTitle, const wxString& aMessage, const wxArrayString& aOptions )
{
int ret = -1;
wxDialog* dlg = new wxDialog( aParent, wxID_ANY, aTitle );
wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
if( !aMessage.IsEmpty() )
boxSizer->Add( new wxStaticText( dlg, wxID_ANY, aMessage ), 0, wxEXPAND | wxALL, 5 );
std::vector<wxRadioButton*> radioButtons;
radioButtons.reserve( aOptions.Count() );
for( const wxString& option : aOptions )
{
radioButtons.emplace_back( new wxRadioButton( dlg, wxID_ANY, _( option ) ) );
boxSizer->Add( radioButtons.back(), 0, wxEXPAND | wxALL, 5 );
}
wxStdDialogButtonSizer* m_sdboxSizer = new wxStdDialogButtonSizer();
m_sdboxSizer->AddButton( new wxButton( dlg, wxID_OK ) );
m_sdboxSizer->AddButton( new wxButton( dlg, wxID_CANCEL ) );
m_sdboxSizer->Realize();
boxSizer->Add( m_sdboxSizer, 1, wxEXPAND | wxALL, 5 );
dlg->SetSizer( boxSizer );
dlg->Layout();
boxSizer->Fit( dlg );
boxSizer->SetSizeHints( dlg );
dlg->Centre( wxBOTH );
if( dlg->ShowModal() == wxID_OK )
{
for( unsigned int i = 0; i < radioButtons.size(); ++i )
{
if( radioButtons[i]->GetValue() )
{
ret = i;
break;
}
}
}
else
{
ret = -1;
}
dlg->Destroy();
return ret;
}
class DIALOG_MULTI_OPTIONS : public wxDialog
{
public:
DIALOG_MULTI_OPTIONS( wxWindow* aParent, const wxString& aTitle, const wxString& aMessage,
const wxArrayString& aOptions )
: wxDialog( aParent, wxID_ANY, aTitle )
{
SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
if( !aMessage.IsEmpty() )
boxSizer->Add( new wxStaticText( this, wxID_ANY, aMessage ), 0, wxEXPAND | wxALL, 5 );
m_checklist = new wxCheckListBox( this, wxID_ANY );
for( const wxString& option : aOptions )
m_checklist->Append( option );
boxSizer->Add( m_checklist, 1, wxEXPAND | wxALL, 5 );
wxBoxSizer* btnSizer = new wxBoxSizer( wxHORIZONTAL );
wxButton* selectAll = new wxButton( this, wxID_ANY, _( "Select All" ) );
btnSizer->Add( selectAll, 1, wxEXPAND | wxALL, 5 );
wxButton* unselectAll = new wxButton( this, wxID_ANY, _( "Unselect All" ) );
btnSizer->Add( unselectAll, 1, wxEXPAND | wxALL, 5 );
boxSizer->Add( btnSizer, 0, wxEXPAND | wxALL, 5 );
wxStdDialogButtonSizer* m_sdboxSizer = new wxStdDialogButtonSizer();
m_sdboxSizer->AddButton( new wxButton( this, wxID_OK ) );
m_sdboxSizer->AddButton( new wxButton( this, wxID_CANCEL ) );
m_sdboxSizer->Realize();
boxSizer->Add( m_sdboxSizer, 0, wxEXPAND | wxALL, 5 );
SetSizer( boxSizer );
Layout();
boxSizer->Fit( this );
boxSizer->SetSizeHints( this );
Centre( wxBOTH );
selectAll->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_MULTI_OPTIONS::selectAll, this );
unselectAll->Bind( wxEVT_COMMAND_BUTTON_CLICKED, &DIALOG_MULTI_OPTIONS::unselectAll, this );
}
std::vector<int> GetSelection() const
{
std::vector<int> ret;
for( unsigned int i = 0; i < m_checklist->GetCount(); ++i )
{
if( m_checklist->IsChecked( i ) )
ret.push_back( i );
}
return ret;
}
void SetCheckboxes( bool aValue )
{
for( unsigned int i = 0; i < m_checklist->GetCount(); ++i )
m_checklist->Check( i, aValue );
}
protected:
wxCheckListBox* m_checklist;
void selectAll( wxCommandEvent& aEvent )
{
SetCheckboxes( true );
}
void unselectAll( wxCommandEvent& aEvent )
{
SetCheckboxes( false );
}
};
std::pair<bool, std::vector<int>> SelectMultipleOptions( wxWindow* aParent, const wxString& aTitle,
const wxString& aMessage, const wxArrayString& aOptions, bool aDefaultState )
{
std::vector<int> ret;
bool clickedOk;
DIALOG_MULTI_OPTIONS dlg( aParent, aTitle, aMessage, aOptions );
dlg.SetCheckboxes( aDefaultState );
if( dlg.ShowModal() == wxID_OK )
{
ret = dlg.GetSelection();
clickedOk = true;
}
else
{
clickedOk = false;
}
return std::make_pair( clickedOk, ret );
}
std::pair<bool, std::vector<int>> SelectMultipleOptions( wxWindow* aParent, const wxString& aTitle,
const wxString& aMessage, const std::vector<std::string>& aOptions, bool aDefaultState )
{
wxArrayString array;
for( const auto& option : aOptions )
array.Add( option );
return SelectMultipleOptions( aParent, aTitle, aMessage, array, aDefaultState );
}

View File

@ -155,7 +155,9 @@ bool DIALOG_SHIM::Show( bool show )
// If showing, use previous position and size.
if( show )
{
#ifndef __WINDOWS__
wxDialog::Raise(); // Needed on OS X and some other window managers (i.e. Unity)
#endif
ret = wxDialog::Show( show );
// classname is key, returns a zeroed out default EDA_RECT if none existed before.

View File

@ -83,6 +83,7 @@ set( EESCHEMA_DLGS
)
set( EESCHEMA_WIDGETS
widgets/cmp_tree_pane.cpp
widgets/component_tree.cpp
widgets/widget_eeschema_color_config.cpp
widgets/pin_shape_combobox.cpp
@ -124,6 +125,7 @@ set( EESCHEMA_SRCS
getpart.cpp
cmp_tree_model.cpp
cmp_tree_model_adapter.cpp
cmp_tree_model_adapter_base.cpp
generate_alias_info.cpp
hierarch.cpp
highlight_connection.cpp
@ -142,6 +144,8 @@ set( EESCHEMA_SRCS
lib_draw_item.cpp
lib_export.cpp
lib_field.cpp
lib_manager.cpp
lib_manager_adapter.cpp
lib_pin.cpp
lib_polyline.cpp
lib_rectangle.cpp

View File

@ -37,7 +37,7 @@
#include <general.h>
#include <class_library.h>
#include <lib_pin.h>
#include <protos.h>
#include <list_operations.h>
#include <sch_bus_entry.h>
#include <sch_marker.h>
#include <sch_junction.h>
@ -47,21 +47,11 @@
#include <sch_component.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
// Imported functions:
extern void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen );
extern void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector );
extern void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
extern void MirrorX( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint );
extern void MirrorY( PICKED_ITEMS_LIST& aItemsList, wxPoint& Center );
extern void DuplicateItemsInList( SCH_SCREEN* screen,
PICKED_ITEMS_LIST& aItemsList,
const wxPoint aMoveVector );
#include <list_operations.h>
static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC,
const wxPoint& aPosition, bool aErase );
int SCH_EDIT_FRAME::BlockCommand( EDA_KEY key )
{
int cmd = BLOCK_IDLE;

View File

@ -91,26 +91,27 @@ int LIB_EDIT_FRAME::BlockCommand( EDA_KEY key )
}
bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* aDC )
{
int ItemCount = 0;
bool nextCmd = false;
BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
wxPoint pt;
if( GetScreen()->m_BlockLocate.GetCount() )
if( block->GetCount() )
{
BLOCK_STATE_T state = GetScreen()->m_BlockLocate.GetState();
BLOCK_COMMAND_T command = GetScreen()->m_BlockLocate.GetCommand();
m_canvas->CallEndMouseCapture( DC );
GetScreen()->m_BlockLocate.SetState( state );
GetScreen()->m_BlockLocate.SetCommand( command );
BLOCK_STATE_T state = block->GetState();
BLOCK_COMMAND_T command = block->GetCommand();
m_canvas->CallEndMouseCapture( aDC );
block->SetState( state );
block->SetCommand( command );
m_canvas->SetMouseCapture( DrawAndSizingBlockOutlines, AbortBlockCurrentCommand );
SetCrossHairPosition( wxPoint( GetScreen()->m_BlockLocate.GetRight(),
GetScreen()->m_BlockLocate.GetBottom() ) );
SetCrossHairPosition( wxPoint( block->GetRight(),
block->GetBottom() ) );
m_canvas->MoveCursorToCrossHair();
}
switch( GetScreen()->m_BlockLocate.GetCommand() )
switch( block->GetCommand() )
{
case BLOCK_IDLE:
DisplayError( this, wxT( "Error in HandleBlockPLace" ) );
@ -121,7 +122,7 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
case BLOCK_MOVE: // Move
case BLOCK_DUPLICATE: // Duplicate
if( GetCurPart() )
ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
ItemCount = GetCurPart()->SelectItems( *block,
m_unit, m_convert,
m_editPinsPerPartOrConvert );
if( ItemCount )
@ -130,12 +131,12 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
if( m_canvas->IsMouseCaptured() )
{
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
m_canvas->CallMouseCapture( DC, wxDefaultPosition, false );
m_canvas->CallMouseCapture( aDC, wxDefaultPosition, false );
}
GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
block->SetState( STATE_BLOCK_MOVE );
m_canvas->Refresh( true );
}
break;
@ -143,12 +144,37 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
case BLOCK_PRESELECT_MOVE: // Move with preselection list
nextCmd = true;
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_MOVE );
block->SetState( STATE_BLOCK_MOVE );
break;
case BLOCK_COPY: // Save a copy of items in the clipboard buffer
case BLOCK_CUT:
if( GetCurPart() )
ItemCount = GetCurPart()->SelectItems( *block, m_unit, m_convert,
m_editPinsPerPartOrConvert );
if( ItemCount )
{
copySelectedItems();
auto cmd = block->GetCommand();
if( cmd == BLOCK_COPY )
{
GetCurPart()->ClearSelectedItems();
block->ClearItemsList();
}
else if( cmd == BLOCK_CUT )
{
SaveCopyInUndoList( GetCurPart() );
GetCurPart()->DeleteSelectedItems();
OnModify();
}
}
break;
case BLOCK_DELETE: // Delete
if( GetCurPart() )
ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
ItemCount = GetCurPart()->SelectItems( *block,
m_unit, m_convert,
m_editPinsPerPartOrConvert );
if( ItemCount )
@ -161,8 +187,10 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
}
break;
case BLOCK_COPY: // Save
case BLOCK_PASTE:
wxFAIL; // should not happen
break;
case BLOCK_FLIP:
break;
@ -170,20 +198,20 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y:
if( GetCurPart() )
ItemCount = GetCurPart()->SelectItems( GetScreen()->m_BlockLocate,
ItemCount = GetCurPart()->SelectItems( *block,
m_unit, m_convert,
m_editPinsPerPartOrConvert );
if( ItemCount )
SaveCopyInUndoList( GetCurPart() );
pt = GetScreen()->m_BlockLocate.Centre();
pt = block->Centre();
pt = GetNearestGridPosition( pt );
pt.y = -pt.y;
if( GetCurPart() )
{
OnModify();
int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
int block_cmd = block->GetCommand();
if( block_cmd == BLOCK_MIRROR_Y)
GetCurPart()->MirrorSelectedItemsH( pt );
@ -196,7 +224,7 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
break;
case BLOCK_ZOOM: // Window Zoom
Window_Zoom( GetScreen()->m_BlockLocate );
Window_Zoom( *block );
break;
case BLOCK_ABORT:
@ -207,17 +235,16 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
case BLOCK_DUPLICATE_AND_INCREMENT: // not used in Eeschema
case BLOCK_MOVE_EXACT: // not used in Eeschema
case BLOCK_CUT: // not used in libedit
break;
}
if( !nextCmd )
{
if( GetScreen()->m_BlockLocate.GetCommand() != BLOCK_SELECT_ITEMS_ONLY && GetCurPart() )
if( block->GetCommand() != BLOCK_SELECT_ITEMS_ONLY && GetCurPart() )
GetCurPart()->ClearSelectedItems();
GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
block->SetState( STATE_NO_BLOCK );
block->SetCommand( BLOCK_IDLE );
GetScreen()->SetCurItem( NULL );
m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString,
false );
@ -230,6 +257,7 @@ bool LIB_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
{
BLOCK_SELECTOR* block = &GetScreen()->m_BlockLocate;
wxPoint pt;
if( !m_canvas->IsMouseCaptured() )
@ -237,9 +265,9 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
DisplayError( this, wxT( "HandleBlockPLace : m_mouseCaptureCallback = NULL" ) );
}
GetScreen()->m_BlockLocate.SetState( STATE_BLOCK_STOP );
block->SetState( STATE_BLOCK_STOP );
switch( GetScreen()->m_BlockLocate.GetCommand() )
switch( block->GetCommand() )
{
case BLOCK_IDLE:
break;
@ -248,12 +276,12 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
case BLOCK_DRAG_ITEM:
case BLOCK_MOVE: // Move
case BLOCK_PRESELECT_MOVE: // Move with preselection list
GetScreen()->m_BlockLocate.ClearItemsList();
block->ClearItemsList();
if( GetCurPart() )
SaveCopyInUndoList( GetCurPart() );
pt = GetScreen()->m_BlockLocate.GetMoveVector();
pt = block->GetMoveVector();
pt.y *= -1;
if( GetCurPart() )
@ -263,12 +291,12 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
break;
case BLOCK_DUPLICATE: // Duplicate
GetScreen()->m_BlockLocate.ClearItemsList();
block->ClearItemsList();
if( GetCurPart() )
SaveCopyInUndoList( GetCurPart() );
pt = GetScreen()->m_BlockLocate.GetMoveVector();
pt = block->GetMoveVector();
pt.y = -pt.y;
if( GetCurPart() )
@ -277,7 +305,15 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
break;
case BLOCK_PASTE: // Paste (recopy the last block saved)
GetScreen()->m_BlockLocate.ClearItemsList();
block->ClearItemsList();
if( GetCurPart() )
SaveCopyInUndoList( GetCurPart() );
pt = block->GetMoveVector();
pt.y = -pt.y;
pasteClipboard( pt );
break;
case BLOCK_ROTATE: // Invert by popup menu, from block move
@ -286,13 +322,13 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
if( GetCurPart() )
SaveCopyInUndoList( GetCurPart() );
pt = GetScreen()->m_BlockLocate.Centre();
pt = block->Centre();
pt = GetNearestGridPosition( pt );
pt.y = -pt.y;
if( GetCurPart() )
{
int block_cmd = GetScreen()->m_BlockLocate.GetCommand();
int block_cmd = block->GetCommand();
if( block_cmd == BLOCK_MIRROR_Y)
GetCurPart()->MirrorSelectedItemsH( pt );
@ -314,14 +350,81 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
OnModify();
GetScreen()->m_BlockLocate.SetState( STATE_NO_BLOCK );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_IDLE );
block->SetState( STATE_NO_BLOCK );
block->SetCommand( BLOCK_IDLE );
GetScreen()->SetCurItem( NULL );
m_canvas->EndMouseCapture( GetToolId(), m_canvas->GetCurrentCursor(), wxEmptyString, false );
m_canvas->Refresh( true );
}
void LIB_EDIT_FRAME::InitBlockPasteInfos()
{
BLOCK_SELECTOR& block = GetScreen()->m_BlockLocate;
// Copy the clipboard contents to the screen block selector
// (only the copy, the new instances will be appended to the part once the items are placed)
block.GetItems().CopyList( m_clipboard.GetItems() );
// Set the pate reference point
block.SetLastCursorPosition( m_clipboard.GetLastCursorPosition() );
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
}
void LIB_EDIT_FRAME::copySelectedItems()
{
LIB_PART* part = GetCurPart();
if( !part )
return;
m_clipboard.ClearListAndDeleteItems(); // delete previous saved list, if exists
m_clipboard.SetLastCursorPosition( GetScreen()->m_BlockLocate.GetEnd() ); // store the reference point
for( LIB_ITEM& item : part->GetDrawItems() )
{
// We *do not* copy fields because they are unique for the whole component
// so skip them (do not duplicate) if they are flagged selected.
if( item.Type() == LIB_FIELD_T )
item.ClearFlags( SELECTED );
if( !item.IsSelected() )
continue;
// Do not clear the 'selected' flag. It is required to have items drawn when they are pasted.
LIB_ITEM* copy = (LIB_ITEM*) item.Clone();
// In list the wrapper is owner of the schematic item, we can use the UR_DELETED
// status for the picker because pickers with this status are owner of the picked item
// (or TODO ?: create a new status like UR_DUPLICATE)
ITEM_PICKER picker( copy, UR_DELETED );
m_clipboard.PushItem( picker );
}
}
void LIB_EDIT_FRAME::pasteClipboard( const wxPoint& aOffset )
{
LIB_PART* part = GetCurPart();
if( !part || m_clipboard.GetCount() == 0 )
return;
for( unsigned int i = 0; i < m_clipboard.GetCount(); i++ )
{
// Append a copy to the current part, so the clipboard buffer might be pasted multiple times
LIB_ITEM* item = (LIB_ITEM*) m_clipboard.GetItem( i )->Clone();
item->SetParent( part );
item->SetSelected();
part->AddDrawItem( item );
}
GetCurPart()->MoveSelectedItems( aOffset );
OnModify();
}
/*
* Traces the outline of the search block structures
* The entire block follows the cursor
@ -329,9 +432,8 @@ void LIB_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase )
{
BLOCK_SELECTOR* block;
BASE_SCREEN* screen = aPanel->GetScreen();
block = &screen->m_BlockLocate;
BLOCK_SELECTOR* block = &screen->m_BlockLocate;
LIB_EDIT_FRAME* parent = (LIB_EDIT_FRAME*) aPanel->GetParent();
wxASSERT( parent != NULL );
@ -352,6 +454,12 @@ void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint&
{
block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert, opts );
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
{
LIB_ITEM* libItem = (LIB_ITEM*) block->GetItem( ii );
libItem->Draw( aPanel, aDC, block->GetMoveVector(), g_GhostColor, g_XorMode, nullptr, opts.transform );
}
}
// Repaint new view
@ -360,5 +468,11 @@ void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint&
GRSetDrawMode( aDC, g_XorMode );
block->Draw( aPanel, aDC, block->GetMoveVector(), g_XorMode, block->GetColor() );
for( unsigned ii = 0; ii < block->GetCount(); ii++ )
{
LIB_ITEM* libItem = (LIB_ITEM*) block->GetItem( ii );
libItem->Draw( aPanel, aDC, block->GetMoveVector(), g_GhostColor, g_XorMode, nullptr, opts.transform );
}
component->Draw( aPanel, aDC, block->GetMoveVector(), unit, convert, opts );
}

View File

@ -175,13 +175,10 @@ struct null_deleter
}
};
LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) :
EDA_ITEM( LIB_PART_T ),
m_me( this, null_deleter() )
{
m_name = aName;
m_library = aLibrary;
m_dateModified = 0;
m_unitCount = 1;
m_pinNameOffset = 40;
@ -190,21 +187,15 @@ LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) :
m_showPinNumbers = true;
m_showPinNames = true;
m_libId.SetLibItemName( aName, false );
// Create the default alias if the name parameter is not empty.
if( !aName.IsEmpty() )
m_aliases.push_back( new LIB_ALIAS( aName, this ) );
// Add the MANDATORY_FIELDS in RAM only. These are assumed to be present
// when the field editors are invoked.
LIB_FIELD* value = new LIB_FIELD( this, VALUE );
value->SetText( aName );
m_drawings[LIB_FIELD_T].push_back( value );
m_drawings[LIB_FIELD_T].push_back( new LIB_FIELD( this, VALUE ) );
m_drawings[LIB_FIELD_T].push_back( new LIB_FIELD( this, REFERENCE ) );
m_drawings[LIB_FIELD_T].push_back( new LIB_FIELD( this, FOOTPRINT ) );
m_drawings[LIB_FIELD_T].push_back( new LIB_FIELD( this, DATASHEET ) );
SetLib( aLibrary );
SetName( aName );
}
@ -215,7 +206,6 @@ LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) :
LIB_ITEM* newItem;
m_library = aLibrary;
m_name = aPart.m_name;
m_FootprintList = aPart.m_FootprintList;
m_unitCount = aPart.m_unitCount;
m_unitsLocked = aPart.m_unitsLocked;
@ -305,14 +295,21 @@ wxString LIB_PART::SubReference( int aUnit, bool aAddSeparator )
void LIB_PART::SetName( const wxString& aName )
{
m_name = aName;
GetValueField().SetText( aName );
m_libId.SetLibItemName( aName, false );
// The LIB_ALIAS that is the LIB_PART name has to be created so create it.
if( m_aliases.size() == 0 )
m_aliases.push_back( new LIB_ALIAS( aName, this ) );
else
m_aliases[0]->SetName( aName );
LIB_FIELD& valueField = GetValueField();
// LIB_FIELD::SetText() calls LIB_PART::SetName(),
// the following if-clause is to break an infinite loop
if( valueField.GetText() != aName )
valueField.SetText( aName );
}
@ -897,23 +894,16 @@ bool LIB_PART::Load( LINE_READER& aLineReader, wxString& aErrorMsg )
m_showPinNames = ( drawname == 'N' ) ? false : true;
// Copy part name and prefix.
LIB_FIELD& value = GetValueField();
if( componentName[0] != '~' )
{
m_name = FROM_UTF8( componentName );
value.SetText( m_name );
SetName( FROM_UTF8( componentName ) );
}
else
{
m_name = FROM_UTF8( &componentName[1] );
value.SetText( m_name );
value.SetVisible( false );
SetName( FROM_UTF8( &componentName[1] ) );
GetValueField().SetVisible( false );
}
// Add the root alias to the alias list.
m_aliases.push_back( new LIB_ALIAS( m_name, this ) );
LIB_FIELD& reference = GetReferenceField();
if( strcmp( prefix, "~" ) == 0 )
@ -1111,7 +1101,7 @@ bool LIB_PART::LoadField( LINE_READER& aLineReader, wxString& aErrorMsg )
*fixedField = *field;
if( field->GetId() == VALUE )
m_name = field->GetText();
SetName( field->GetText() );
delete field;
}
@ -1671,6 +1661,15 @@ void LIB_PART::SetConversion( bool aSetConvert )
}
void LIB_PART::SetLib( PART_LIB* aLibrary )
{
m_library = aLibrary;
if( aLibrary )
m_libId.SetLibNickname( aLibrary->GetName() );
}
wxArrayString LIB_PART::GetAliasNames( bool aIncludeRoot ) const
{
wxArrayString names;
@ -1708,6 +1707,7 @@ void LIB_PART::SetAliases( const wxArrayString& aAliasList )
{
wxCHECK_RET( !m_library,
wxT( "Part aliases cannot be changed when they are owned by a library." ) );
wxCHECK_RET( !aAliasList.IsEmpty(), wxT( "Alias list cannot be empty" ) );
if( aAliasList == GetAliasNames() )
return;
@ -1782,7 +1782,7 @@ LIB_ALIAS* LIB_PART::RemoveAlias( LIB_ALIAS* aAlias )
wxLogTrace( traceSchLibMem,
wxT( "%s: part:'%s', alias:'%s', alias count %llu, reference count %ld." ),
GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
GetChars( m_name ),
GetChars( GetName() ),
GetChars( aAlias->GetName() ),
(long long unsigned) m_aliases.size(),
m_me.use_count() );

View File

@ -89,8 +89,6 @@ class LIB_ALIAS : public EDA_ITEM
*/
LIB_PART* shared;
friend class LIB_PART;
protected:
wxString name;
wxString description; ///< documentation for info
@ -226,12 +224,7 @@ struct PART_DRAW_OPTIONS
*/
class LIB_PART : public EDA_ITEM
{
friend class PART_LIB;
friend class LIB_ALIAS;
friend class SCH_LEGACY_PLUGIN_CACHE;
PART_SPTR m_me; ///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
wxString m_name;
LIB_ID m_libId;
int m_pinNameOffset; ///< The offset in mils to draw the pin name. Set to 0
///< to draw the pin name above the pin.
@ -258,7 +251,7 @@ class LIB_PART : public EDA_ITEM
private:
void deleteAllFields();
// LIB_PART() { } // not legal
public:
@ -280,16 +273,15 @@ public:
virtual void SetName( const wxString& aName );
const wxString& GetName() const { return m_name; }
const wxString& GetName() const { return m_aliases[0]->GetName(); }
const LIB_ID& GetLibId() const { return m_libId; }
void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
const wxString GetLibraryName();
PART_LIB* GetLib() { return m_library; }
void SetLib( PART_LIB* aLibrary ) { m_library = aLibrary; }
void SetLib( PART_LIB* aLibrary );
wxArrayString GetAliasNames( bool aIncludeRoot = true ) const;

View File

@ -146,7 +146,7 @@ void PART_LIB::EnableBuffering( bool aEnable )
}
void PART_LIB::GetAliasNames( wxArrayString& aNames )
void PART_LIB::GetAliasNames( wxArrayString& aNames ) const
{
m_plugin->EnumerateSymbolLib( aNames, fileName.GetFullPath(), m_properties.get() );
@ -154,7 +154,7 @@ void PART_LIB::GetAliasNames( wxArrayString& aNames )
}
void PART_LIB::GetAliases( std::vector<LIB_ALIAS*>& aAliases )
void PART_LIB::GetAliases( std::vector<LIB_ALIAS*>& aAliases ) const
{
m_plugin->EnumerateSymbolLib( aAliases, fileName.GetFullPath(), m_properties.get() );
@ -164,7 +164,7 @@ void PART_LIB::GetAliases( std::vector<LIB_ALIAS*>& aAliases )
}
void PART_LIB::GetEntryTypePowerNames( wxArrayString& aNames )
void PART_LIB::GetEntryTypePowerNames( wxArrayString& aNames ) const
{
std::vector<LIB_ALIAS*> aliases;
@ -186,7 +186,7 @@ void PART_LIB::GetEntryTypePowerNames( wxArrayString& aNames )
}
LIB_ALIAS* PART_LIB::FindAlias( const wxString& aName )
LIB_ALIAS* PART_LIB::FindAlias( const wxString& aName ) const
{
LIB_ALIAS* alias = m_plugin->LoadSymbol( fileName.GetFullPath(), aName, m_properties.get() );
@ -194,13 +194,13 @@ LIB_ALIAS* PART_LIB::FindAlias( const wxString& aName )
// symbols. This allows the symbol library table conversion tool to determine the
// correct library where the symbol was found.
if( alias && alias->GetPart() && !alias->GetPart()->GetLib() )
alias->GetPart()->SetLib( this );
alias->GetPart()->SetLib( const_cast<PART_LIB*>( this ) );
return alias;
}
LIB_PART* PART_LIB::FindPart( const wxString& aName )
LIB_PART* PART_LIB::FindPart( const wxString& aName ) const
{
LIB_ALIAS* alias = FindAlias( aName );
@ -211,7 +211,7 @@ LIB_PART* PART_LIB::FindPart( const wxString& aName )
}
bool PART_LIB::HasPowerParts()
bool PART_LIB::HasPowerParts() const
{
// return true if at least one power part is found in lib
std::vector<LIB_ALIAS*> aliases;

View File

@ -401,21 +401,21 @@ public:
*
* @param aNames - String array to place entry names into.
*/
void GetAliasNames( wxArrayString& aNames );
void GetAliasNames( wxArrayString& aNames ) const;
/**
* Load a vector with all the entries in this library.
*
* @param aAliases - vector to receive the aliases.
*/
void GetAliases( std::vector<LIB_ALIAS*>& aAliases );
void GetAliases( std::vector<LIB_ALIAS*>& aAliases ) const;
/**
* Load a string array with the names of entries of type POWER in this library.
*
* @param aNames - String array to place entry names into.
*/
void GetEntryTypePowerNames( wxArrayString& aNames );
void GetEntryTypePowerNames( wxArrayString& aNames ) const;
/**
* Find #LIB_ALIAS by \a aName.
@ -423,7 +423,7 @@ public:
* @param aName - Name of entry, case sensitive.
* @return #LIB_ALIAS* if found. NULL if not found.
*/
LIB_ALIAS* FindAlias( const wxString& aName );
LIB_ALIAS* FindAlias( const wxString& aName ) const;
/**
* Find part by \a aName.
@ -434,7 +434,7 @@ public:
* @param aName - Name of part, case sensitive.
* @return LIB_PART* - part if found, else NULL.
*/
LIB_PART* FindPart( const wxString& aName );
LIB_PART* FindPart( const wxString& aName ) const;
/**
* Add \a aPart entry to library.
@ -481,14 +481,14 @@ public:
*
* @return wxString - Full library file name with path and extension.
*/
wxString GetFullFileName() { return fileName.GetFullPath(); }
wxString GetFullFileName() const { return fileName.GetFullPath(); }
/**
* Function GetLogicalName
* returns the logical name of the library.
* @return wxString - The logical name of this library.
*/
const wxString GetLogicalName()
const wxString GetLogicalName() const
{
/* for now is the filename without path or extension.
@ -518,7 +518,7 @@ public:
* @return true if at least one power part is found in lib
* Useful to select or list only libs containing power parts
*/
bool HasPowerParts();
bool HasPowerParts() const;
};

View File

@ -105,6 +105,7 @@ int CMP_TREE_NODE::Compare( CMP_TREE_NODE const& aNode1, CMP_TREE_NODE const& aN
CMP_TREE_NODE::CMP_TREE_NODE()
: Parent( nullptr ),
Type( INVALID ),
InTree( false ),
IntrinsicRank( 0 ),
Score( kLowestDefaultScore ),
Unit( 0 )
@ -177,6 +178,7 @@ CMP_TREE_NODE_LIB_ID::CMP_TREE_NODE_LIB_ID( CMP_TREE_NODE* aParent, LIB_ALIAS* a
CMP_TREE_NODE_UNIT& CMP_TREE_NODE_LIB_ID::AddUnit( int aUnit )
{
CMP_TREE_NODE_UNIT* unit = new CMP_TREE_NODE_UNIT( this, aUnit );
unit->InTree = true;
Children.push_back( std::unique_ptr<CMP_TREE_NODE>( unit ) );
return *unit;
}
@ -236,12 +238,14 @@ CMP_TREE_NODE_LIB::CMP_TREE_NODE_LIB( CMP_TREE_NODE* aParent, wxString const& aN
Name = aName;
MatchName = aName.Lower();
Parent = aParent;
LibId.SetLibNickname( aName );
}
CMP_TREE_NODE_LIB_ID& CMP_TREE_NODE_LIB::AddAlias( LIB_ALIAS* aAlias )
{
CMP_TREE_NODE_LIB_ID* alias = new CMP_TREE_NODE_LIB_ID( this, aAlias );
alias->InTree = true;
Children.push_back( std::unique_ptr<CMP_TREE_NODE>( alias ) );
return *alias;
}
@ -268,6 +272,7 @@ CMP_TREE_NODE_ROOT::CMP_TREE_NODE_ROOT()
CMP_TREE_NODE_LIB& CMP_TREE_NODE_ROOT::AddLib( wxString const& aName )
{
CMP_TREE_NODE_LIB* lib = new CMP_TREE_NODE_LIB( this, aName );
lib->InTree = true;
Children.push_back( std::unique_ptr<CMP_TREE_NODE>( lib ) );
return *lib;
}

View File

@ -80,9 +80,12 @@ public:
ROOT, LIB, LIBID, UNIT, INVALID
};
CMP_TREE_NODE* Parent; ///< Parent node or null
std::vector<std::unique_ptr<CMP_TREE_NODE>> Children; ///< List of child nodes
enum TYPE Type; ///< Node type
typedef std::vector<std::unique_ptr<CMP_TREE_NODE>> PTR_VECTOR;
CMP_TREE_NODE* Parent; ///< Parent node or null
PTR_VECTOR Children; ///< List of child nodes
enum TYPE Type; ///< Node type
bool InTree; ///< Flag indicating whether the node is added to the tree
/**
* The rank of the item before any search terms are applied. This is

View File

@ -26,51 +26,7 @@
#include <symbol_lib_table.h>
#include <wx/progdlg.h>
CMP_TREE_MODEL_ADAPTER::WIDTH_CACHE CMP_TREE_MODEL_ADAPTER::m_width_cache;
static const int kDataViewIndent = 20;
/**
* Convert CMP_TREE_NODE -> wxDataViewItem
*/
static wxDataViewItem ToItem( CMP_TREE_NODE const* aNode )
{
return wxDataViewItem( const_cast<void*>( static_cast<void const*>( aNode ) ) );
}
/**
* Convert wxDataViewItem -> CMP_TREE_NODE
*/
static CMP_TREE_NODE const* ToNode( wxDataViewItem aItem )
{
return static_cast<CMP_TREE_NODE const*>( aItem.GetID() );
}
/**
* Convert CMP_TREE_NODE's children to wxDataViewItemArray
*/
static unsigned int IntoArray( CMP_TREE_NODE const& aNode, wxDataViewItemArray& aChildren )
{
unsigned int n = 0;
for( auto const& child: aNode.Children )
{
if( child->Score > 0 )
{
aChildren.Add( ToItem( &*child ) );
++n;
}
}
return n;
}
CMP_TREE_MODEL_ADAPTER::PTR CMP_TREE_MODEL_ADAPTER::Create( SYMBOL_LIB_TABLE* aLibs )
CMP_TREE_MODEL_ADAPTER_BASE::PTR CMP_TREE_MODEL_ADAPTER::Create( SYMBOL_LIB_TABLE* aLibs )
{
auto adapter = new CMP_TREE_MODEL_ADAPTER( aLibs );
auto container = CMP_TREE_MODEL_ADAPTER::PTR( adapter );
@ -79,13 +35,7 @@ CMP_TREE_MODEL_ADAPTER::PTR CMP_TREE_MODEL_ADAPTER::Create( SYMBOL_LIB_TABLE* aL
CMP_TREE_MODEL_ADAPTER::CMP_TREE_MODEL_ADAPTER( SYMBOL_LIB_TABLE* aLibs )
:m_filter( CMP_FILTER_NONE ),
m_show_units( true ),
m_libs( aLibs ),
m_preselect_unit( 0 ),
m_col_part( nullptr ),
m_col_desc( nullptr ),
m_widget( nullptr )
: m_libs( aLibs )
{}
@ -93,28 +43,9 @@ CMP_TREE_MODEL_ADAPTER::~CMP_TREE_MODEL_ADAPTER()
{}
void CMP_TREE_MODEL_ADAPTER::SetFilter( CMP_FILTER_TYPE aFilter )
{
m_filter = aFilter;
}
void CMP_TREE_MODEL_ADAPTER::ShowUnits( bool aShow )
{
m_show_units = aShow;
}
void CMP_TREE_MODEL_ADAPTER::SetPreselectNode( LIB_ID const& aLibId, int aUnit )
{
m_preselect_lib_id = aLibId;
m_preselect_unit = aUnit;
}
void CMP_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname )
{
bool onlyPowerSymbols = ( m_filter == CMP_FILTER_POWER );
bool onlyPowerSymbols = ( GetFilter() == CMP_FILTER_POWER );
wxArrayString aliases;
@ -135,26 +66,6 @@ void CMP_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname )
}
void CMP_TREE_MODEL_ADAPTER::AddLibrariesWithProgress( const std::vector<wxString>& aNicknames, EDA_DRAW_FRAME* aParent )
{
auto* prg = new wxProgressDialog(
_( "Loading symbol libraries" ),
wxEmptyString,
aNicknames.size(),
aParent );
unsigned int ii = 0;
for( auto nickname : aNicknames )
{
prg->Update( ii++, wxString::Format( _( "Loading library '%s'" ), nickname ) );
AddLibrary( nickname );
}
prg->Destroy();
}
void CMP_TREE_MODEL_ADAPTER::AddAliasList(
wxString const& aNodeName,
wxArrayString const& aAliasNameList )
@ -182,312 +93,3 @@ void CMP_TREE_MODEL_ADAPTER::AddAliasList(
AddAliasList( aNodeName, alias_list );
}
void CMP_TREE_MODEL_ADAPTER::AddAliasList(
wxString const& aNodeName,
std::vector<LIB_ALIAS*> const& aAliasList )
{
auto& lib_node = m_tree.AddLib( aNodeName );
for( auto a: aAliasList )
{
lib_node.AddAlias( a );
}
lib_node.AssignIntrinsicRanks();
m_tree.AssignIntrinsicRanks();
}
void CMP_TREE_MODEL_ADAPTER::UpdateSearchString( wxString const& aSearch )
{
m_tree.ResetScore();
wxStringTokenizer tokenizer( aSearch );
while( tokenizer.HasMoreTokens() )
{
const wxString term = tokenizer.GetNextToken().Lower();
EDA_COMBINED_MATCHER matcher( term );
m_tree.UpdateScore( matcher );
}
m_tree.SortNodes();
Cleared();
AttachTo( m_widget );
ShowResults() || ShowPreselect() || ShowSingleLibrary();
}
void CMP_TREE_MODEL_ADAPTER::AttachTo( wxDataViewCtrl* aDataViewCtrl )
{
m_widget = aDataViewCtrl;
aDataViewCtrl->Freeze();
aDataViewCtrl->SetIndent( kDataViewIndent );
aDataViewCtrl->AssociateModel( this );
aDataViewCtrl->ClearColumns();
wxString part_head = _( "Part" );
wxString desc_head = _( "Desc" );
m_col_part = aDataViewCtrl->AppendTextColumn( part_head, 0, wxDATAVIEW_CELL_INERT,
ColWidth( m_tree, 0, part_head ) );
m_col_desc = aDataViewCtrl->AppendTextColumn( desc_head, 1, wxDATAVIEW_CELL_INERT,
ColWidth( m_tree, 1, desc_head ) );
aDataViewCtrl->Thaw();
}
LIB_ID CMP_TREE_MODEL_ADAPTER::GetAliasFor( wxDataViewItem aSelection ) const
{
auto node = ToNode( aSelection );
LIB_ID emptyId;
if( !node )
return emptyId;
return node->LibId;
}
int CMP_TREE_MODEL_ADAPTER::GetUnitFor( wxDataViewItem aSelection ) const
{
auto node = ToNode( aSelection );
return node ? node->Unit : 0;
}
int CMP_TREE_MODEL_ADAPTER::GetComponentsCount() const
{
int n = 0;
for( auto& lib: m_tree.Children )
{
for( auto& alias: lib->Children )
{
(void) alias;
++n;
}
}
return n;
}
bool CMP_TREE_MODEL_ADAPTER::HasContainerColumns( wxDataViewItem const& aItem ) const
{
return IsContainer( aItem );
}
bool CMP_TREE_MODEL_ADAPTER::IsContainer( wxDataViewItem const& aItem ) const
{
auto node = ToNode( aItem );
return node ? node->Children.size() : true;
}
wxDataViewItem CMP_TREE_MODEL_ADAPTER::GetParent( wxDataViewItem const& aItem ) const
{
auto node = ToNode( aItem );
auto parent = node ? node->Parent : nullptr;
// wxDataViewModel has no root node, but rather top-level elements have
// an invalid (null) parent.
if( !node || !parent || parent->Type == CMP_TREE_NODE::TYPE::ROOT )
{
return ToItem( nullptr );
}
else
{
return ToItem( parent );
}
}
unsigned int CMP_TREE_MODEL_ADAPTER::GetChildren(
wxDataViewItem const& aItem,
wxDataViewItemArray& aChildren ) const
{
auto node = ( aItem.IsOk() ? ToNode( aItem ) : &m_tree );
if( node->Type != CMP_TREE_NODE::TYPE::LIBID || m_show_units )
return IntoArray( *node, aChildren );
else
return 0;
}
void CMP_TREE_MODEL_ADAPTER::GetValue(
wxVariant& aVariant,
wxDataViewItem const& aItem,
unsigned int aCol ) const
{
auto node = ToNode( aItem );
wxASSERT( node );
switch( aCol )
{
case 0:
aVariant = node->Name;
break;
case 1:
aVariant = node->Desc;
break;
default:
wxFAIL_MSG( "Invalid column ID!" );
}
}
bool CMP_TREE_MODEL_ADAPTER::GetAttr(
wxDataViewItem const& aItem,
unsigned int aCol,
wxDataViewItemAttr& aAttr ) const
{
auto node = ToNode( aItem );
wxASSERT( node );
if( node->Type != CMP_TREE_NODE::LIBID )
{
// Currently only aliases are formatted at all
return false;
}
if( !node->IsRoot && aCol == 0 )
{
// Names of non-root aliases are italicized
aAttr.SetItalic( true );
return true;
}
else
{
return false;
}
}
int CMP_TREE_MODEL_ADAPTER::ColWidth( CMP_TREE_NODE& aTree, int aCol, wxString const& aHeading )
{
const int indent = aCol ? 0 : kDataViewIndent;
int min_width = WidthFor( aHeading, aCol );
int width = std::max( aTree.Score > 0 ? WidthFor( aTree, aCol ) : 0, min_width );
if( aTree.Score > 0 )
{
for( auto& node: aTree.Children )
{
width = std::max( width, ColWidth( *node, aCol, aHeading ) + indent );
}
}
return width;
}
int CMP_TREE_MODEL_ADAPTER::WidthFor( CMP_TREE_NODE& aNode, int aCol )
{
auto result = m_width_cache.find( aNode.Name );
if( result != m_width_cache.end() )
{
return result->second[aCol];
}
else
{
int wname = m_widget->GetTextExtent( aNode.Name ).x + kDataViewIndent;
int wdesc = m_widget->GetTextExtent( aNode.Desc ).x;
auto& val = m_width_cache[aNode.Name];
val.push_back( wname );
val.push_back( wdesc );
return val[aCol];
}
}
int CMP_TREE_MODEL_ADAPTER::WidthFor( wxString const& aHeading, int aCol )
{
static std::vector<int> widths;
for( int i = (int) widths.size(); i <= aCol; ++i )
{
widths.push_back( 0 );
}
if( widths[aCol] == 0 )
{
widths[aCol] = m_widget->GetTextExtent( aHeading ).x;
}
return widths[aCol];
}
bool CMP_TREE_MODEL_ADAPTER::FindAndExpand(
CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc )
{
for( auto& node: aNode.Children )
{
if( aFunc( &*node ) )
{
auto item = wxDataViewItem(
const_cast<void*>( static_cast<void const*>( &*node ) ) );
m_widget->ExpandAncestors( item );
m_widget->EnsureVisible( item );
m_widget->Select( item );
return true;
}
else if( FindAndExpand( *node, aFunc ) )
{
return true;
}
}
return false;
}
bool CMP_TREE_MODEL_ADAPTER::ShowResults()
{
return FindAndExpand( m_tree,
[]( CMP_TREE_NODE const* n )
{
return n->Type == CMP_TREE_NODE::TYPE::LIBID && n->Score > 1;
} );
}
bool CMP_TREE_MODEL_ADAPTER::ShowPreselect()
{
if( !m_preselect_lib_id.IsValid() )
return false;
return FindAndExpand( m_tree,
[&]( CMP_TREE_NODE const* n )
{
if( n->Type == CMP_TREE_NODE::LIBID && ( n->Children.empty() || !m_preselect_unit ) )
return m_preselect_lib_id == n->LibId;
else if( n->Type == CMP_TREE_NODE::UNIT && m_preselect_unit )
return m_preselect_lib_id == n->Parent->LibId && m_preselect_unit == n->Unit;
else
return false;
} );
}
bool CMP_TREE_MODEL_ADAPTER::ShowSingleLibrary()
{
return FindAndExpand( m_tree,
[]( CMP_TREE_NODE const* n )
{
return n->Type == CMP_TREE_NODE::TYPE::LIBID &&
n->Parent->Parent->Children.size() == 1;
} );
}

View File

@ -22,84 +22,18 @@
#ifndef _CMP_TREE_MODEL_ADAPTER_H
#define _CMP_TREE_MODEL_ADAPTER_H
#include <lib_id.h>
#include <draw_frame.h>
#include <cmp_tree_model.h>
#include <wx/hashmap.h>
#include <wx/dataview.h>
#include <vector>
#include <functional>
#include <cmp_tree_model_adapter_base.h>
class SYMBOL_LIB_TABLE;
/**
* Adapter class in the component selector Model-View-Adapter (mediated MVC)
* architecture. The other pieces are in:
*
* - Model: CMP_TREE_NODE and descendants in eeschema/cmp_tree_model.h
* - View:
* - DIALOG_CHOOSE_COMPONENT in eeschema/dialogs/dialog_choose_component.h
* - wxDataViewCtrl
*
* This adapter presents the interface specified by wxDataViewModel to the
* wxDataViewCtrl:
*
* +---+ +------------------+
* +---+ Generates | A | | VIEW |
* | M | from libs | D | wxDataViewModel |------------------|
* | O | <---------- | A | <------------------> | wxDataViewCtrl |
* | D | | P | |------------------|
* | E | <---------> | T | <------------------- | wxTextCtrl |
* | L | UpdateScore | E | UpdateSearchString() |------------------|
* +---+ | R | | |
* +---+ +------------------+
*
* Because this adapter is a wxDataViewModel, it is reference-counted by
* wxObject. To ensure this interface is used correctly, the constructor
* is private; CMP_TREE_MODEL_ADAPTER should be created by the static
* factory method CMP_TREE_MODEL_ADAPTER::Create().
*
* Quick summary of methods used to drive this class:
*
* - `SetFilter()` - set whether the view is restricted to power parts
* - `ShowUnits()` - set whether units are displayed
* - `SetPreselectNode()` - set a node to highlight when not searching
* - `AddLibrary()` - populate the model with all aliases in a library
* - `AddAliasList()` - populate the model with a specific list of aliases
*
* Quick summary of methods used by the View:
*
* - `UpdateSearchString()` - pass in the user's search text
* - `AttachTo()` - pass in the wxDataViewCtrl
* - `GetAliasFor()` - get the LIB_ALIAS* for a selected item
* - `GetUnitFor()` - get the unit for a selected item
* - `GetComponentsCount()` - count the aliases loaded
*
* Methods implemented as part of wxDataViewModel:
*
* - `HasContainerColumns()` - whether a parent item has more than one column
* - `IsContainer()` - whether an item is a parent
* - `GetParent()` - return the parent of an item, or invalid if root
* - `GetChildren()` - get the children of an item
* - `GetColumnCount()` - get the number of columns in the view
* - `GetColumnType()` - get the data type shown in each column
* - `GetValue()` - get the data shown in a cell
* - `SetValue()` - edit the data in a cell (does nothing)
* - `GetAttr()` - get any per-item formatting
* - `Compare()` - compare two rows, for sorting
* - `HasDefaultCompare()` - whether sorted by default
*/
class CMP_TREE_MODEL_ADAPTER: public wxDataViewModel
class CMP_TREE_MODEL_ADAPTER: public CMP_TREE_MODEL_ADAPTER_BASE
{
public:
/**
* Reference-counting container for a pointer to CMP_TREE_MODEL_ADAPTER.
*/
typedef wxObjectDataPtr<CMP_TREE_MODEL_ADAPTER> PTR;
//typedef wxObjectDataPtr<CMP_TREE_MODEL_ADAPTER> PTR;
/**
* Destructor. Do NOT delete this class manually; it is reference-counted
@ -115,57 +49,13 @@ public:
*/
static PTR Create( SYMBOL_LIB_TABLE* aLibs );
/**
* This enum allows a selective filtering of components to list
*/
enum CMP_FILTER_TYPE
{
CMP_FILTER_NONE, ///< no filtering
CMP_FILTER_POWER, ///< list components flagged PWR
};
/**
* Set the component filter type. Must be set before adding libraries
*
* @param aFilter if CMP_FILTER_POWER, only power parts are loaded
*/
void SetFilter( CMP_FILTER_TYPE aFilter );
/**
* Whether or not to show units. May be set at any time; updates at the next
* UpdateSearchString()
*
* @param aShow if true, units are displayed
*/
void ShowUnits( bool aShow );
/**
* Set the component name to be selected if there are no search results.
* May be set at any time; updates at the next UpdateSearchString().
*
* @param aLibId symbol #LIB_ID to be selected
* @param aUnit unit to be selected, if > 0 (0 selects the alias itself)
*/
void SetPreselectNode( LIB_ID const& aLibId, int aUnit );
/**
* Add all the components and their aliases in this library. To be called
* in the setup phase.
*
* @param aLibNickname reference to a symbol library nickname
*/
void AddLibrary( wxString const& aLibNickname );
/**
* Add all the libraries in a SYMBOL_LIB_TABLE to the model,
* displaying a progress dialog attached to the parent frame
*
* @param aNicknames is the list of library nicknames
* @param aParent is the parent window to display the progress dialog
*/
void AddLibrariesWithProgress( const std::vector<wxString>& aNicknames, EDA_DRAW_FRAME* aParent );
void AddLibrary( wxString const& aLibNickname ) override;
/**
* Add the given list of components, by name. To be called in the setup
@ -176,60 +66,9 @@ public:
*/
void AddAliasList(
wxString const& aNodeName,
wxArrayString const& aAliasNameList );
/**
* Add the given list of components by alias. To be called in the setup
* phase.
*
* @param aNodeName the parent node the components will appear under
* @param aAliasList list of aliases
*/
void AddAliasList(
wxString const& aNodeName,
std::vector<LIB_ALIAS*> const& aAliasList );
/**
* Set the search string provided by the user.
*
* @param aSearch full, unprocessed search text
*/
void UpdateSearchString( wxString const& aSearch );
/**
* Attach to a wxDataViewCtrl and initialize it. This will set up columns
* and associate the model via the adapter.
*
* @param aDataViewCtrl the view component in the dialog
*/
void AttachTo( wxDataViewCtrl* aDataViewCtrl );
/**
* Return the alias for the given item.
*
* @param aSelection item from the wxDataViewCtrl
* (see wxDataViewCtrl::GetSelection())
*
* @return alias, or nullptr if none is selected
*/
LIB_ID GetAliasFor( wxDataViewItem aSelection ) const;
/**
* Return the unit for the given item.
*
* @param aSelection item from the wxDataViewCtrl
* (see wxDataViewCtrl::GetSelection())
*
* @return Unit, or zero if the alias itself is selected. Return valid is
* invalid if GetAliasFor() returns nullptr.
*/
int GetUnitFor( wxDataViewItem aSelection ) const;
/**
* Return the number of components loaded in the tree.
*/
int GetComponentsCount() const;
wxArrayString const& aAliasNameList ) override;
using CMP_TREE_MODEL_ADAPTER_BASE::AddAliasList;
protected:
/**
@ -237,143 +76,8 @@ protected:
*/
CMP_TREE_MODEL_ADAPTER( SYMBOL_LIB_TABLE* aLibs );
/**
* Check whether a container has columns too
*/
virtual bool HasContainerColumns( wxDataViewItem const& aItem ) const override;
/**
* Check whether an item can have children.
*/
virtual bool IsContainer( wxDataViewItem const& aItem ) const override;
/**
* Get the parent of an item.
*
* @param aItem item to get the parent of
* @return parent of aItem, or an invalid wxDataViewItem if parent is root
*/
virtual wxDataViewItem GetParent( wxDataViewItem const& aItem ) const override;
/**
* Populate a list of all the children of an item
*
* @return number of children
*/
virtual unsigned int GetChildren(
wxDataViewItem const& aItem,
wxDataViewItemArray& aChildren ) const override;
/**
* Return the number of columns in the model
*/
virtual unsigned int GetColumnCount() const override { return 2; }
/**
* Return the type of data stored in the column
*
* @return type of data as indicated by wxVariant::GetType()
*/
virtual wxString GetColumnType( unsigned int aCol ) const override { return "string"; }
/**
* Get the value of an item.
*
* @param aVariant wxVariant to receive the data
* @param aItem item whose data will be placed into aVariant
* @param aCol column number of the data
*/
virtual void GetValue(
wxVariant& aVariant,
wxDataViewItem const& aItem,
unsigned int aCol ) const override;
/**
* Set the value of an item. Does nothing - this model doesn't support
* editing.
*/
virtual bool SetValue(
wxVariant const& aVariant,
wxDataViewItem const& aItem,
unsigned int aCol ) override { return false; }
/**
* Get any formatting for an item.
*
* @param aItem item to get formatting for
* @param aCol column number of interest
* @param aAttr receiver for attributes
* @return true iff the item has non-default attributes
*/
virtual bool GetAttr(
wxDataViewItem const& aItem,
unsigned int aCol,
wxDataViewItemAttr& aAttr ) const override;
private:
CMP_FILTER_TYPE m_filter;
bool m_show_units;
SYMBOL_LIB_TABLE* m_libs;
LIB_ID m_preselect_lib_id;
int m_preselect_unit;
CMP_TREE_NODE_ROOT m_tree;
wxDataViewColumn* m_col_part;
wxDataViewColumn* m_col_desc;
wxDataViewCtrl* m_widget;
WX_DECLARE_STRING_HASH_MAP( std::vector<int>, WIDTH_CACHE );
static WIDTH_CACHE m_width_cache;
/**
* Compute the width required for the given column of a node and its
* children.
*
* @param aTree - root node of the tree
* @param aCol - column number
* @param aHeading - heading text, to set the minimum width
*/
int ColWidth( CMP_TREE_NODE& aTree, int aCol, wxString const& aHeading );
/**
* Return the width required to display a single row's aCol text.
* This is cached for efficiency as it's very slow on some platforms
* (*cough* macOS)
*/
int WidthFor( CMP_TREE_NODE& aNode, int aCol );
/**
* Return the width required to display a column's heading. This is
* cached by column number for the same reason as the width per cell.
*/
int WidthFor( wxString const& aHeading, int aCol );
/**
* Find any results worth highlighting and expand them, according to given
* criteria (f(CMP_TREE_NODE const*) -> bool)
*
* @return whether a node was expanded
*/
bool FindAndExpand(
CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc );
/**
* Find and expand successful search results
*/
bool ShowResults();
/**
* Find and expand preselected node
*/
bool ShowPreselect();
/**
* Find and expand a library if there is only one
*/
bool ShowSingleLibrary();
};
#endif // _CMP_TREE_MODEL_ADAPTER_H

View File

@ -0,0 +1,520 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
* Copyright (C) 2014-2017 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include <cmp_tree_model_adapter_base.h>
#include <eda_pattern_match.h>
#include <wx/progdlg.h>
#include <wx/tokenzr.h>
CMP_TREE_MODEL_ADAPTER_BASE::WIDTH_CACHE CMP_TREE_MODEL_ADAPTER_BASE::m_width_cache;
static const int kDataViewIndent = 20;
/**
* Convert CMP_TREE_NODE -> wxDataViewItem
*/
wxDataViewItem CMP_TREE_MODEL_ADAPTER_BASE::ToItem( CMP_TREE_NODE const* aNode )
{
return wxDataViewItem( const_cast<void*>( static_cast<void const*>( aNode ) ) );
}
/**
* Convert wxDataViewItem -> CMP_TREE_NODE
*/
CMP_TREE_NODE const* CMP_TREE_MODEL_ADAPTER_BASE::ToNode( wxDataViewItem aItem )
{
return static_cast<CMP_TREE_NODE const*>( aItem.GetID() );
}
/**
* Convert CMP_TREE_NODE's children to wxDataViewItemArray
*/
unsigned int CMP_TREE_MODEL_ADAPTER_BASE::IntoArray(
CMP_TREE_NODE const& aNode, wxDataViewItemArray& aChildren )
{
unsigned int n = 0;
for( auto const& child: aNode.Children )
{
if( child->Score > 0 && child->InTree )
{
aChildren.Add( ToItem( &*child ) );
++n;
}
}
return n;
}
CMP_TREE_MODEL_ADAPTER_BASE::CMP_TREE_MODEL_ADAPTER_BASE()
:m_filter( CMP_FILTER_NONE ),
m_show_units( true ),
m_preselect_unit( 0 ),
m_col_part( nullptr ),
m_col_desc( nullptr ),
m_widget( nullptr )
{}
CMP_TREE_MODEL_ADAPTER_BASE::~CMP_TREE_MODEL_ADAPTER_BASE()
{}
void CMP_TREE_MODEL_ADAPTER_BASE::SetFilter( CMP_FILTER_TYPE aFilter )
{
m_filter = aFilter;
}
void CMP_TREE_MODEL_ADAPTER_BASE::ShowUnits( bool aShow )
{
m_show_units = aShow;
}
void CMP_TREE_MODEL_ADAPTER_BASE::SetPreselectNode( LIB_ID const& aLibId, int aUnit )
{
m_preselect_lib_id = aLibId;
m_preselect_unit = aUnit;
}
void CMP_TREE_MODEL_ADAPTER_BASE::AddLibrariesWithProgress(
const std::vector<wxString>& aNicknames, wxWindow* aParent )
{
auto* prg = new wxProgressDialog(
_( "Loading symbol libraries" ),
wxEmptyString,
aNicknames.size(),
aParent );
unsigned int ii = 0;
for( auto nickname : aNicknames )
{
prg->Update( ii++, wxString::Format( _( "Loading library '%s'" ), nickname ) );
AddLibrary( nickname );
}
prg->Destroy();
}
void CMP_TREE_MODEL_ADAPTER_BASE::AddAliasList(
wxString const& aNodeName,
std::vector<LIB_ALIAS*> const& aAliasList )
{
auto& lib_node = m_tree.AddLib( aNodeName );
for( auto a: aAliasList )
{
lib_node.AddAlias( a );
}
lib_node.AssignIntrinsicRanks();
m_tree.AssignIntrinsicRanks();
}
void CMP_TREE_MODEL_ADAPTER_BASE::UpdateSearchString( wxString const& aSearch )
{
m_widget->Freeze();
m_tree.ResetScore();
wxStringTokenizer tokenizer( aSearch );
while( tokenizer.HasMoreTokens() )
{
const wxString term = tokenizer.GetNextToken().Lower();
EDA_COMBINED_MATCHER matcher( term );
m_tree.UpdateScore( matcher );
}
filterContents();
ShowResults() || ShowPreselect() || ShowSingleLibrary();
m_widget->Thaw();
}
void CMP_TREE_MODEL_ADAPTER_BASE::AttachTo( wxDataViewCtrl* aDataViewCtrl )
{
m_widget = aDataViewCtrl;
aDataViewCtrl->Freeze();
aDataViewCtrl->SetIndent( kDataViewIndent );
aDataViewCtrl->AssociateModel( this );
aDataViewCtrl->ClearColumns();
wxString part_head = _( "Part" );
wxString desc_head = _( "Desc" );
m_col_part = aDataViewCtrl->AppendTextColumn( part_head, 0, wxDATAVIEW_CELL_INERT,
ColWidth( m_tree, 0, part_head ) );
m_col_desc = aDataViewCtrl->AppendTextColumn( desc_head, 1, wxDATAVIEW_CELL_INERT,
ColWidth( m_tree, 1, desc_head ) );
m_col_part->SetSortOrder( 0 );
aDataViewCtrl->Thaw();
}
LIB_ID CMP_TREE_MODEL_ADAPTER_BASE::GetAliasFor( const wxDataViewItem& aSelection ) const
{
auto node = ToNode( aSelection );
LIB_ID emptyId;
if( !node )
return emptyId;
return node->LibId;
}
int CMP_TREE_MODEL_ADAPTER_BASE::GetUnitFor( const wxDataViewItem& aSelection ) const
{
auto node = ToNode( aSelection );
return node ? node->Unit : 0;
}
CMP_TREE_NODE::TYPE CMP_TREE_MODEL_ADAPTER_BASE::GetTypeFor( const wxDataViewItem& aSelection ) const
{
auto node = ToNode( aSelection );
return node ? node->Type : CMP_TREE_NODE::INVALID;
}
int CMP_TREE_MODEL_ADAPTER_BASE::GetComponentsCount() const
{
int n = 0;
for( auto& lib: m_tree.Children )
{
for( auto& alias: lib->Children )
{
(void) alias;
++n;
}
}
return n;
}
wxDataViewItem CMP_TREE_MODEL_ADAPTER_BASE::FindItem( const LIB_ID& aLibId )
{
for( auto& lib: m_tree.Children )
{
if( lib->Name != aLibId.GetLibNickname() )
continue;
// if part name is not specified, return the library node
if( aLibId.GetLibItemName() == "" )
return ToItem( lib.get() );
for( auto& alias: lib->Children )
{
if( alias->Name == aLibId.GetLibItemName() )
return ToItem( alias.get() );
}
break; // could not find the part in the requested library
}
return wxDataViewItem();
}
unsigned int CMP_TREE_MODEL_ADAPTER_BASE::GetChildren(
wxDataViewItem const& aItem,
wxDataViewItemArray& aChildren ) const
{
auto node = ( aItem.IsOk() ? ToNode( aItem ) : &m_tree );
if( node->Type != CMP_TREE_NODE::TYPE::LIBID
|| ( m_show_units && node->Type == CMP_TREE_NODE::TYPE::LIBID ) )
return IntoArray( *node, aChildren );
else
return 0;
}
bool CMP_TREE_MODEL_ADAPTER_BASE::HasContainerColumns( wxDataViewItem const& aItem ) const
{
return IsContainer( aItem );
}
bool CMP_TREE_MODEL_ADAPTER_BASE::IsContainer( wxDataViewItem const& aItem ) const
{
auto node = ToNode( aItem );
return node ? node->Children.size() : true;
}
wxDataViewItem CMP_TREE_MODEL_ADAPTER_BASE::GetParent( wxDataViewItem const& aItem ) const
{
auto node = ToNode( aItem );
auto parent = node ? node->Parent : nullptr;
// wxDataViewModel has no root node, but rather top-level elements have
// an invalid (null) parent.
if( !node || !parent || parent->Type == CMP_TREE_NODE::TYPE::ROOT )
{
return ToItem( nullptr );
}
else
{
return ToItem( parent );
}
}
void CMP_TREE_MODEL_ADAPTER_BASE::GetValue(
wxVariant& aVariant,
wxDataViewItem const& aItem,
unsigned int aCol ) const
{
auto node = ToNode( aItem );
wxASSERT( node );
switch( aCol )
{
default: // column == -1 is used for default Compare function
case 0:
aVariant = node->Name;
break;
case 1:
aVariant = node->Desc;
break;
}
}
bool CMP_TREE_MODEL_ADAPTER_BASE::GetAttr(
wxDataViewItem const& aItem,
unsigned int aCol,
wxDataViewItemAttr& aAttr ) const
{
auto node = ToNode( aItem );
wxASSERT( node );
if( node->Type != CMP_TREE_NODE::LIBID )
{
// Currently only aliases are formatted at all
return false;
}
if( !node->IsRoot && aCol == 0 )
{
// Names of non-root aliases are italicized
aAttr.SetItalic( true );
return true;
}
else
{
return false;
}
}
int CMP_TREE_MODEL_ADAPTER_BASE::ColWidth( CMP_TREE_NODE& aTree, int aCol, wxString const& aHeading )
{
const int indent = aCol ? 0 : kDataViewIndent;
int min_width = WidthFor( aHeading, aCol );
int width = std::max( aTree.Score > 0 ? WidthFor( aTree, aCol ) : 0, min_width );
if( aTree.Score > 0 )
{
for( auto& node: aTree.Children )
{
width = std::max( width, ColWidth( *node, aCol, aHeading ) + indent );
}
}
return width;
}
int CMP_TREE_MODEL_ADAPTER_BASE::WidthFor( CMP_TREE_NODE& aNode, int aCol )
{
auto result = m_width_cache.find( aNode.Name );
if( result != m_width_cache.end() )
{
return result->second[aCol];
}
else
{
int wname = m_widget->GetTextExtent( aNode.Name ).x + kDataViewIndent;
int wdesc = m_widget->GetTextExtent( aNode.Desc ).x;
auto& val = m_width_cache[aNode.Name];
val.push_back( wname );
val.push_back( wdesc );
return val[aCol];
}
}
int CMP_TREE_MODEL_ADAPTER_BASE::WidthFor( wxString const& aHeading, int aCol )
{
static std::vector<int> widths;
for( int i = (int) widths.size(); i <= aCol; ++i )
{
widths.push_back( 0 );
}
if( widths[aCol] == 0 )
{
widths[aCol] = m_widget->GetTextExtent( aHeading ).x;
}
return widths[aCol];
}
bool CMP_TREE_MODEL_ADAPTER_BASE::FindAndExpand(
CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc )
{
for( auto& node: aNode.Children )
{
if( aFunc( &*node ) )
{
auto item = wxDataViewItem(
const_cast<void*>( static_cast<void const*>( &*node ) ) );
m_widget->ExpandAncestors( item );
m_widget->EnsureVisible( item );
m_widget->Select( item );
return true;
}
else if( FindAndExpand( *node, aFunc ) )
{
return true;
}
}
return false;
}
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowResults()
{
return FindAndExpand( m_tree,
[]( CMP_TREE_NODE const* n )
{
return n->Type == CMP_TREE_NODE::TYPE::LIBID && n->Score > 1;
} );
}
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowPreselect()
{
if( !m_preselect_lib_id.IsValid() )
return false;
return FindAndExpand( m_tree,
[&]( CMP_TREE_NODE const* n )
{
if( n->Type == CMP_TREE_NODE::LIBID && ( n->Children.empty() || !m_preselect_unit ) )
return m_preselect_lib_id == n->LibId;
else if( n->Type == CMP_TREE_NODE::UNIT && m_preselect_unit )
return m_preselect_lib_id == n->Parent->LibId && m_preselect_unit == n->Unit;
else
return false;
} );
}
bool CMP_TREE_MODEL_ADAPTER_BASE::ShowSingleLibrary()
{
return FindAndExpand( m_tree,
[]( CMP_TREE_NODE const* n )
{
return n->Type == CMP_TREE_NODE::TYPE::LIBID &&
n->Parent->Parent->Children.size() == 1;
} );
}
void CMP_TREE_MODEL_ADAPTER_BASE::filterContents()
{
// Rebuild the tree using only the filtered nodes
for( auto& lib : m_tree.Children )
{
lib->InTree = false;
for( auto& alias : lib->Children )
{
alias->InTree = false;
for( auto& unit : lib->Children )
unit->InTree = false;
}
}
m_tree.SortNodes();
Cleared();
for( auto& lib : m_tree.Children )
{
if( lib->Score <= 0 )
continue;
wxDataViewItem libItem = ToItem( lib.get() );
for( auto& alias : lib->Children )
{
if( !lib->InTree )
{
lib->InTree = true;
ItemAdded( wxDataViewItem( nullptr ), libItem );
}
if( alias->Score > 0 )
{
alias->InTree = true;
ItemAdded( libItem, ToItem( alias.get() ) );
wxDataViewItem aliasItem = ToItem( alias.get() );
if( !m_show_units )
continue;
for( auto& unit : alias->Children )
{
unit->InTree = true;
ItemAdded( aliasItem, ToItem( unit.get() ) );
}
}
}
}
}

View File

@ -0,0 +1,398 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
* Copyright (C) 2014-2017 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CMP_TREE_MODEL_ADAPTER_BASE_H
#define _CMP_TREE_MODEL_ADAPTER_BASE_H
#include <lib_id.h>
#include <cmp_tree_model.h>
#include <wx/hashmap.h>
#include <wx/dataview.h>
#include <vector>
#include <functional>
/**
* Adapter class in the component selector Model-View-Adapter (mediated MVC)
* architecture. The other pieces are in:
*
* - Model: CMP_TREE_NODE and descendants in eeschema/cmp_tree_model.h
* - View:
* - DIALOG_CHOOSE_COMPONENT in eeschema/dialogs/dialog_choose_component.h
* - wxDataViewCtrl
*
* This adapter presents the interface specified by wxDataViewModel to the
* wxDataViewCtrl:
*
* +---+ +------------------+
* +---+ Generates | A | | VIEW |
* | M | from libs | D | wxDataViewModel |------------------|
* | O | <---------- | A | <------------------> | wxDataViewCtrl |
* | D | | P | |------------------|
* | E | <---------> | T | <------------------- | wxTextCtrl |
* | L | UpdateScore | E | UpdateSearchString() |------------------|
* +---+ | R | | |
* +---+ +------------------+
*
* Because this adapter is a wxDataViewModel, it is reference-counted by
* wxObject. To ensure this interface is used correctly, the constructor
* is private; CMP_TREE_MODEL_ADAPTER should be created by the static
* factory method CMP_TREE_MODEL_ADAPTER::Create().
*
* Quick summary of methods used to drive this class:
*
* - `SetFilter()` - set whether the view is restricted to power parts
* - `ShowUnits()` - set whether units are displayed
* - `SetPreselectNode()` - set a node to highlight when not searching
* - `AddLibrary()` - populate the model with all aliases in a library
* - `AddAliasList()` - populate the model with a specific list of aliases
*
* Quick summary of methods used by the View:
*
* - `UpdateSearchString()` - pass in the user's search text
* - `AttachTo()` - pass in the wxDataViewCtrl
* - `GetAliasFor()` - get the LIB_ALIAS* for a selected item
* - `GetUnitFor()` - get the unit for a selected item
* - `GetComponentsCount()` - count the aliases loaded
*
* Methods implemented as part of wxDataViewModel:
*
* - `HasContainerColumns()` - whether a parent item has more than one column
* - `IsContainer()` - whether an item is a parent
* - `GetParent()` - return the parent of an item, or invalid if root
* - `GetChildren()` - get the children of an item
* - `GetColumnCount()` - get the number of columns in the view
* - `GetColumnType()` - get the data type shown in each column
* - `GetValue()` - get the data shown in a cell
* - `SetValue()` - edit the data in a cell (does nothing)
* - `GetAttr()` - get any per-item formatting
* - `Compare()` - compare two rows, for sorting
* - `HasDefaultCompare()` - whether sorted by default
*/
class CMP_TREE_MODEL_ADAPTER_BASE: public wxDataViewModel
{
public:
/**
* Reference-counting container for a pointer to CMP_TREE_MODEL_ADAPTER_BASE.
*/
typedef wxObjectDataPtr<CMP_TREE_MODEL_ADAPTER_BASE> PTR;
/**
* Destructor. Do NOT delete this class manually; it is reference-counted
* by wxObject.
*/
~CMP_TREE_MODEL_ADAPTER_BASE();
/**
* This enum allows a selective filtering of components to list
*/
enum CMP_FILTER_TYPE
{
CMP_FILTER_NONE, ///< no filtering
CMP_FILTER_POWER, ///< list components flagged PWR
};
/**
* Set the component filter type. Must be set before adding libraries
*
* @param aFilter if CMP_FILTER_POWER, only power parts are loaded
*/
void SetFilter( CMP_FILTER_TYPE aFilter );
/**
* Return the active filter.
*/
CMP_FILTER_TYPE GetFilter() const { return m_filter; }
/**
* Whether or not to show units. May be set at any time; updates at the next
* UpdateSearchString()
*
* @param aShow if true, units are displayed
*/
void ShowUnits( bool aShow );
/**
* Set the component name to be selected if there are no search results.
* May be set at any time; updates at the next UpdateSearchString().
*
* @param aLibId symbol #LIB_ID to be selected
* @param aUnit unit to be selected, if > 0 (0 selects the alias itself)
*/
void SetPreselectNode( LIB_ID const& aLibId, int aUnit );
/**
* Add all the components and their aliases in this library. To be called
* in the setup phase.
*
* @param aLibNickname reference to a symbol library nickname
*/
virtual void AddLibrary( wxString const& aLibNickname ) = 0;
/**
* Add all the libraries in a SYMBOL_LIB_TABLE to the model,
* displaying a progress dialog attached to the parent frame
*
* @param aNicknames is the list of library nicknames
* @param aParent is the parent window to display the progress dialog
*/
void AddLibrariesWithProgress( const std::vector<wxString>& aNicknames,
wxWindow* aParent );
/**
* Add the given list of components, by name. To be called in the setup
* phase.
*
* @param aNodeName the parent node the components will appear under
* @param aAliasNameList list of alias names
*/
virtual void AddAliasList(
wxString const& aNodeName,
wxArrayString const& aAliasNameList ) = 0;
/**
* Add the given list of components by alias. To be called in the setup
* phase.
*
* @param aNodeName the parent node the components will appear under
* @param aAliasList list of aliases
*/
void AddAliasList(
wxString const& aNodeName,
std::vector<LIB_ALIAS*> const& aAliasList );
/**
* Set the search string provided by the user.
*
* @param aSearch full, unprocessed search text
*/
void UpdateSearchString( wxString const& aSearch );
/**
* Attach to a wxDataViewCtrl and initialize it. This will set up columns
* and associate the model via the adapter.
*
* @param aDataViewCtrl the view component in the dialog
*/
void AttachTo( wxDataViewCtrl* aDataViewCtrl );
/**
* Return the alias for the given item.
*
* @param aSelection item from the wxDataViewCtrl
* (see wxDataViewCtrl::GetSelection())
*
* @return alias, or nullptr if none is selected
*/
LIB_ID GetAliasFor( const wxDataViewItem& aSelection ) const;
/**
* Return the unit for the given item.
*
* @param aSelection item from the wxDataViewCtrl
* (see wxDataViewCtrl::GetSelection())
*
* @return Unit, or zero if the alias itself is selected. Return valid is
* invalid if GetAliasFor() returns nullptr.
*/
int GetUnitFor( const wxDataViewItem& aSelection ) const;
/**
* Return node type for the given item.
*
* @param aSelection item from the wxDataViewCtrl
* (see wxDataViewCtrl::GetSelection())
*
* @return Type of the selected node, might be INVALID.
*/
CMP_TREE_NODE::TYPE GetTypeFor( const wxDataViewItem& aSelection ) const;
/**
* Return the number of components loaded in the tree.
*/
int GetComponentsCount() const;
/**
* Returns tree item corresponding to part.
*
* @param aLibId specifies the part and library name to be searched for.
* @return Tree data item representing the part. Might be invalid if nothings was found.
*/
wxDataViewItem FindItem( const LIB_ID& aLibId );
/**
* Populate a list of all the children of an item
*
* @return number of children
*/
virtual unsigned int GetChildren(
wxDataViewItem const& aItem,
wxDataViewItemArray& aChildren ) const override;
protected:
static wxDataViewItem ToItem( CMP_TREE_NODE const* aNode );
static CMP_TREE_NODE const* ToNode( wxDataViewItem aItem );
static unsigned int IntoArray( CMP_TREE_NODE const& aNode, wxDataViewItemArray& aChildren );
CMP_TREE_NODE_ROOT m_tree;
/**
* Constructor
*/
CMP_TREE_MODEL_ADAPTER_BASE();
/**
* Check whether a container has columns too
*/
virtual bool HasContainerColumns( wxDataViewItem const& aItem ) const override;
/**
* Check whether an item can have children.
*/
virtual bool IsContainer( wxDataViewItem const& aItem ) const override;
/**
* Get the parent of an item.
*
* @param aItem item to get the parent of
* @return parent of aItem, or an invalid wxDataViewItem if parent is root
*/
virtual wxDataViewItem GetParent( wxDataViewItem const& aItem ) const override;
/**
* Return the number of columns in the model
*/
virtual unsigned int GetColumnCount() const override { return 2; }
/**
* Return the type of data stored in the column
*
* @return type of data as indicated by wxVariant::GetType()
*/
virtual wxString GetColumnType( unsigned int aCol ) const override { return "string"; }
/**
* Get the value of an item.
*
* @param aVariant wxVariant to receive the data
* @param aItem item whose data will be placed into aVariant
* @param aCol column number of the data
*/
virtual void GetValue(
wxVariant& aVariant,
wxDataViewItem const& aItem,
unsigned int aCol ) const override;
/**
* Set the value of an item. Does nothing - this model doesn't support
* editing.
*/
virtual bool SetValue(
wxVariant const& aVariant,
wxDataViewItem const& aItem,
unsigned int aCol ) override { return false; }
/**
* Get any formatting for an item.
*
* @param aItem item to get formatting for
* @param aCol column number of interest
* @param aAttr receiver for attributes
* @return true iff the item has non-default attributes
*/
virtual bool GetAttr(
wxDataViewItem const& aItem,
unsigned int aCol,
wxDataViewItemAttr& aAttr ) const override;
private:
CMP_FILTER_TYPE m_filter;
bool m_show_units;
LIB_ID m_preselect_lib_id;
int m_preselect_unit;
wxDataViewColumn* m_col_part;
wxDataViewColumn* m_col_desc;
wxDataViewCtrl* m_widget;
WX_DECLARE_STRING_HASH_MAP( std::vector<int>, WIDTH_CACHE );
static WIDTH_CACHE m_width_cache;
/**
* Compute the width required for the given column of a node and its
* children.
*
* @param aTree - root node of the tree
* @param aCol - column number
* @param aHeading - heading text, to set the minimum width
*/
int ColWidth( CMP_TREE_NODE& aTree, int aCol, wxString const& aHeading );
/**
* Return the width required to display a single row's aCol text.
* This is cached for efficiency as it's very slow on some platforms
* (*cough* macOS)
*/
int WidthFor( CMP_TREE_NODE& aNode, int aCol );
/**
* Return the width required to display a column's heading. This is
* cached by column number for the same reason as the width per cell.
*/
int WidthFor( wxString const& aHeading, int aCol );
/**
* Find any results worth highlighting and expand them, according to given
* criteria (f(CMP_TREE_NODE const*) -> bool)
*
* @return whether a node was expanded
*/
bool FindAndExpand(
CMP_TREE_NODE& aNode,
std::function<bool( CMP_TREE_NODE const* )> aFunc );
/**
* Find and expand successful search results
*/
bool ShowResults();
/**
* Find and expand preselected node
*/
bool ShowPreselect();
/**
* Find and expand a library if there is only one
*/
bool ShowSingleLibrary();
/**
* Filters the items shown in the view according to the score.
*/
void filterContents();
};
#endif // _CMP_TREE_MODEL_ADAPTER_BASE_H

View File

@ -34,7 +34,7 @@
#include <general.h>
void DrawDanglingSymbol( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& pos, COLOR4D Color )
void DrawDanglingSymbol( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& pos, const COLOR4D& Color )
{
BASE_SCREEN* screen = panel->GetScreen();

View File

@ -460,8 +460,6 @@ static const wxString RepeatStepYEntry = "RepeatStepY";
static const wxString RepeatLabelIncrementEntry = "RepeatLabelIncrement";
// Library editor wxConfig entry names.
static const wxChar lastLibExportPathEntry[] = wxT( "LastLibraryExportPath" );
static const wxChar lastLibImportPathEntry[] = wxT( "LastLibraryImportPath" );
static const wxChar defaultPinNumSizeEntry[] = wxT( "LibeditPinNumSize" );
static const wxChar defaultPinNameSizeEntry[] = wxT( "LibeditPinNameSize" );
static const wxChar DefaultPinLengthEntry[] = wxT( "DefaultPinLength" );

View File

@ -185,22 +185,36 @@ enum id_eeschema_frm
/* Library editor main menubar IDs. */
ID_LIBEDIT_DIMENSIONS,
/* Library editor horizontal toolbar IDs. */
ID_LIBEDIT_SAVE_CURRENT_PART,
ID_LIBEDIT_SELECT_PART,
ID_LIBEDIT_SELECT_CURRENT_LIB,
ID_LIBEDIT_SAVE_CURRENT_LIB,
/* Library editor: library edit events */
ID_LIBEDIT_NEW_LIBRARY,
ID_LIBEDIT_ADD_LIBRARY,
ID_LIBEDIT_SAVE_LIBRARY,
ID_LIBEDIT_SAVE_LIBRARY_AS,
ID_LIBEDIT_SAVE_ALL_LIBS,
ID_LIBEDIT_REVERT_LIBRARY,
/* Library editor: part edit events */
ID_LIBEDIT_NEW_PART,
ID_LIBEDIT_NEW_PART_FROM_EXISTING,
ID_LIBEDIT_GET_FRAME_EDIT_PART,
ID_LIBEDIT_GET_FRAME_EDIT_FIELDS,
ID_LIBEDIT_DELETE_PART,
ID_LIBEDIT_EDIT_PART,
ID_LIBEDIT_IMPORT_PART,
ID_LIBEDIT_EXPORT_PART,
ID_LIBEDIT_SAVE_PART,
ID_LIBEDIT_REVERT_PART,
ID_LIBEDIT_REMOVE_PART,
ID_LIBEDIT_CUT_PART,
ID_LIBEDIT_COPY_PART,
ID_LIBEDIT_PASTE_PART,
ID_LIBEDIT_DUPLICATE_PART,
/* Library editor horizontal toolbar IDs. */
ID_DE_MORGAN_NORMAL_BUTT,
ID_DE_MORGAN_CONVERT_BUTT,
ID_LIBEDIT_EDIT_PIN_BY_PIN,
ID_LIBEDIT_EDIT_PIN_BY_TABLE,
ID_LIBEDIT_VIEW_DOC,
ID_LIBEDIT_CHECK_PART,
ID_LIBEDIT_GET_FRAME_EDIT_PART,
ID_LIBEDIT_GET_FRAME_EDIT_FIELDS,
ID_LIBEDIT_SELECT_PART_NUMBER,
ID_LIBEDIT_SELECT_ALIAS,
@ -240,9 +254,9 @@ enum id_eeschema_frm
/* Library editor toolbar options IDs */
ID_LIBEDIT_SHOW_ELECTRICAL_TYPE,
ID_LIBEDIT_SHOW_HIDE_SEARCH_TREE,
/* Library editor menubar IDs */
ID_LIBEDIT_SAVE_CURRENT_LIB_AS,
ID_LIBEDIT_GEN_PNG_FILE,
ID_LIBEDIT_GEN_SVG_FILE,
@ -273,7 +287,6 @@ enum id_eeschema_frm
ID_SIM_SHOW,
ID_END_EESCHEMA_ID_LIST
};

View File

@ -213,13 +213,13 @@ static EDA_HOTKEY HkFindNextDrcMarker( _HKI( "Find Next DRC Marker" ), HK_FIND_N
static EDA_HOTKEY HkZoomSelection( _HKI( "Zoom to Selection" ), HK_ZOOM_SELECTION, '@', ID_ZOOM_SELECTION );
// Special keys for library editor:
static EDA_HOTKEY HkLoadPart( _HKI( "Load Component" ), HK_LIBEDIT_LOAD_PART, 'L' + GR_KB_CTRL );
static EDA_HOTKEY HkCreatePin( _HKI( "Create Pin" ), HK_LIBEDIT_CREATE_PIN, 'P' );
static EDA_HOTKEY HkInsertPin( _HKI( "Repeat Pin" ), HK_REPEAT_LAST, WXK_INSERT );
static EDA_HOTKEY HkMoveLibItem( _HKI( "Move Library Item" ), HK_LIBEDIT_MOVE_GRAPHIC_ITEM, 'M' );
// Load/save files
static EDA_HOTKEY HkSaveLib( _HKI( "Save Library" ), HK_SAVE_LIB, 'S' + GR_KB_CTRL );
static EDA_HOTKEY HkSaveLib( _HKI( "Save Library" ), HK_SAVE_LIB, 'S' + GR_KB_CTRL + GR_KB_ALT, ID_LIBEDIT_SAVE_LIBRARY );
static EDA_HOTKEY HkSavePart( _HKI( "Save Part" ), HK_SAVE_PART, 'S' + GR_KB_CTRL, ID_LIBEDIT_SAVE_PART );
static EDA_HOTKEY HkSaveSchematic( _HKI( "Save Schematic" ), HK_SAVE_SCH, 'S' + GR_KB_CTRL );
static EDA_HOTKEY HkLoadSchematic( _HKI( "Load Schematic" ), HK_LOAD_SCH, 'L' + GR_KB_CTRL );
@ -321,12 +321,15 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
static EDA_HOTKEY* libEdit_Hotkey_List[] =
{
&HkSaveLib,
&HkLoadPart,
&HkSavePart,
&HkCreatePin,
&HkInsertPin,
&HkMoveLibItem,
&HkMirrorX,
&HkMirrorY,
&HkCopyBlock,
&HkPasteBlock,
&HkCutBlock,
NULL
};
@ -703,6 +706,9 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
case HK_ZOOM_REDRAW:
case HK_ZOOM_CENTER:
case HK_ZOOM_AUTO:
case HK_PASTE_BLOCK:
case HK_COPY_BLOCK:
case HK_CUT_BLOCK:
cmd.SetId( hotKey->m_IdMenuEvent );
GetEventHandler()->ProcessEvent( cmd );
break;
@ -777,10 +783,6 @@ bool LIB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
}
break;
case HK_LIBEDIT_LOAD_PART:
LoadOneLibraryPart( cmd );
break;
case HK_LIBEDIT_CREATE_PIN:
if( ! itemInEdit )
{

View File

@ -45,7 +45,6 @@ enum hotkey_id_commnand {
HK_COPY_BLOCK,
HK_PASTE_BLOCK,
HK_CUT_BLOCK,
HK_LIBEDIT_LOAD_PART,
HK_LIBEDIT_CREATE_PIN,
HK_DELETE_PIN,
HK_ROTATE,
@ -76,6 +75,7 @@ enum hotkey_id_commnand {
HK_ADD_GRAPHIC_POLYLINE,
HK_ADD_NOCONN_FLAG,
HK_SAVE_LIB,
HK_SAVE_PART,
HK_SAVE_SCH,
HK_LOAD_SCH,
HK_LEFT_CLICK,

View File

@ -37,17 +37,25 @@
#include <libeditframe.h>
#include <class_library.h>
#include <wildcards_and_files_ext.h>
#include <eeschema_id.h>
#include <lib_manager.h>
#include <wx/filename.h>
extern int ExportPartId;
void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
{
wxString msg;
m_lastDrawItem = NULL;
wxString libName = getTargetLib();
if( !m_libMgr->LibraryExists( libName ) )
{
libName = SelectLibraryFromList();
if( !m_libMgr->LibraryExists( libName ) )
return;
}
wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath,
wxEmptyString, SchematicLibraryFileWildcard(),
@ -56,13 +64,13 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
if( dlg.ShowModal() == wxID_CANCEL )
return;
wxFileName fn = dlg.GetPath();
wxFileName fn = dlg.GetPath();
m_mruPath = fn.GetPath();
wxArrayString symbols;
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
// TODO dialog to select the part to be imported if there is more than one
try
{
pi->EnumerateSymbolLib( symbols, fn.GetFullPath() );
@ -81,27 +89,25 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
return;
}
LIB_ALIAS* entry = pi->LoadSymbol( fn.GetFullPath(), symbols[0] );
wxString symbolName = symbols[0];
LIB_ALIAS* entry = pi->LoadSymbol( fn.GetFullPath(), symbolName );
if( LoadOneLibraryPartAux( entry, fn.GetFullPath() ) )
if( m_libMgr->PartExists( symbols[0], libName ) )
{
DisplayLibInfos();
GetScreen()->ClearUndoRedoList();
Zoom_Automatique( false );
// This effectively adds a new symbol to the library. Set the modified flag so the
// save library toolbar button and menu entry are enabled.
OnModify();
msg.Printf( _( "Symbol '%s' already exists in library '%s'." ), symbolName, libName );
DisplayError( this, msg );
return;
}
m_libMgr->UpdatePart( entry->GetPart(), libName );
loadPart( symbolName, libName, 1 );
}
void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
{
wxString msg, title;
bool createLib = ( event.GetId() == ExportPartId ) ? false : true;
LIB_PART* part = GetCurPart();
wxString msg, title;
LIB_PART* part = getTargetPart();
if( !part )
{
@ -114,9 +120,7 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
fn.SetName( part->GetName().Lower() );
fn.SetExt( SchematicLibraryFileExtension );
title = createLib ? _( "New Symbol Library" ) : _( "Export Symbol" );
wxFileDialog dlg( this, title, m_mruPath, fn.GetFullName(),
wxFileDialog dlg( this, _( "Export Symbol" ), m_mruPath, fn.GetFullName(),
SchematicLibraryFileWildcard(), wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
if( dlg.ShowModal() == wxID_CANCEL )
@ -179,12 +183,6 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
}
m_mruPath = fn.GetPath();
/// @todo Give the user a choice to add the new library to the symbol library table.
DisplayInfoMessage( this, _( "This library will not be available until it is added to the "
"symbol library table." ) );
GetScreen()->ClrModify();
m_drawItem = m_lastDrawItem = NULL;
msg.Printf( _( "Symbol '%s' saved in library '%s'" ), part->GetName(), fn.GetFullPath() );

761
eeschema/lib_manager.cpp Normal file
View File

@ -0,0 +1,761 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <lib_manager.h>
#include <class_libentry.h>
#include <class_library.h>
#include <libeditframe.h>
#include <kiway.h>
#include <profile.h>
#include <symbol_lib_table.h>
#include <sch_legacy_plugin.h>
#include <list>
LIB_MANAGER::LIB_MANAGER( LIB_EDIT_FRAME& aFrame )
: m_frame( aFrame ), m_symbolTable( aFrame.Prj().SchSymbolLibTable() )
{
m_adapter = LIB_MANAGER_ADAPTER::Create( this );
m_adapter->ShowUnits( false );
}
void LIB_MANAGER::Sync( bool aForce )
{
int libTableHash = m_symbolTable->GetModifyHash();
if( aForce || m_syncHash != libTableHash )
{
getAdapter()->Sync( aForce );
m_syncHash = libTableHash;
}
}
int LIB_MANAGER::GetHash() const
{
int hash = m_symbolTable->GetModifyHash();
for( const auto& libBuf : m_libs )
hash += libBuf.second.GetHash();
return hash;
}
int LIB_MANAGER::GetLibraryHash( const wxString& aLibrary ) const
{
const auto libBufIt = m_libs.find( aLibrary );
if( libBufIt != m_libs.end() )
return libBufIt->second.GetHash();
auto row = m_symbolTable->FindRow( aLibrary );
// return -1 if library does not exist or 0 if not modified
return row ? std::hash<std::string>{}( aLibrary.ToStdString() + row->GetFullURI( true ).ToStdString() ) : -1;
}
wxArrayString LIB_MANAGER::GetLibraryNames() const
{
wxArrayString res;
for( const auto& libName : m_symbolTable->GetLogicalLibs() )
res.Add( libName );
return res;
}
bool LIB_MANAGER::FlushAll()
{
bool result = true;
for( auto& libBuf : m_libs )
result &= FlushLibrary( libBuf.first );
return result;
}
bool LIB_MANAGER::FlushLibrary( const wxString& aLibrary )
{
auto it = m_libs.find( aLibrary );
if( it == m_libs.end() ) // no changes to flush
return true;
LIB_BUFFER& libBuf = it->second;
wxArrayString aliases;
try {
m_symbolTable->EnumerateSymbolLib( aLibrary, aliases );
// TODO probably this could be implemented more efficiently
for( const auto& alias : aliases )
m_symbolTable->DeleteAlias( aLibrary, alias );
} catch( IO_ERROR& e) {}
// Assume all libraries are successfully saved
bool res = true;
for( const auto& partBuf : libBuf.GetBuffers() )
{
if( !libBuf.SaveBuffer( partBuf, m_symbolTable ) )
{
// Something went wrong but try to save other libraries
res = false;
}
}
if( res )
libBuf.ClearDeletedBuffer();
return res;
}
bool LIB_MANAGER::SaveLibrary( const wxString& aLibrary, const wxString& aFileName )
{
wxCHECK( LibraryExists( aLibrary ), false );
wxFileName fn( aFileName );
wxCHECK( !fn.FileExists() || fn.IsFileWritable(), false );
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
bool res = true; // assume all libraries are successfully saved
auto it = m_libs.find( aLibrary );
if( it != m_libs.end() )
{
// Handle buffered library
LIB_BUFFER& libBuf = it->second;
const auto& partBuffers = libBuf.GetBuffers();
for( const auto& partBuf : partBuffers )
{
if( !libBuf.SaveBuffer( partBuf, &*pi, true ) )
{
// Something went wrong, but try to save other libraries
res = false;
}
}
// clear the deleted parts buffer only if data is saved to the original file
auto row = m_symbolTable->FindRow( aLibrary );
if( res && row && row->GetFullURI( true ) == aFileName )
libBuf.ClearDeletedBuffer();
}
else
{
// Handle original library
PROPERTIES properties;
properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
for( auto part : getOriginalParts( aLibrary ) )
pi->SaveSymbol( aLibrary, new LIB_PART( *part ), &properties );
}
pi->SaveLibrary( aFileName );
return res;
}
bool LIB_MANAGER::IsLibraryModified( const wxString& aLibrary ) const
{
wxCHECK( LibraryExists( aLibrary ), false );
auto it = m_libs.find( aLibrary );
return it != m_libs.end() ? it->second.IsModified() : false;
}
bool LIB_MANAGER::IsPartModified( const wxString& aAlias, const wxString& aLibrary ) const
{
wxCHECK( LibraryExists( aLibrary ), false );
auto libIt = m_libs.find( aLibrary );
if( libIt == m_libs.end() )
return false;
const LIB_BUFFER& buf = libIt->second;
auto partBuf = buf.GetBuffer( aAlias );
return partBuf ? partBuf->IsModified() : false;
}
bool LIB_MANAGER::ClearLibraryModified( const wxString& aLibrary ) const
{
auto libIt = m_libs.find( aLibrary );
if( libIt == m_libs.end() )
return false;
for( auto& partBuf : libIt->second.GetBuffers() )
{
SCH_SCREEN* screen = partBuf->GetScreen();
if( screen )
screen->ClrModify();
}
return true;
}
bool LIB_MANAGER::ClearPartModified( const wxString& aAlias, const wxString& aLibrary ) const
{
auto libI = m_libs.find( aLibrary );
if( libI == m_libs.end() )
return false;
auto partBuf = libI->second.GetBuffer( aAlias );
wxCHECK( partBuf, false );
partBuf->GetScreen()->ClrModify();
return true;
}
bool LIB_MANAGER::IsLibraryReadOnly( const wxString& aLibrary ) const
{
wxCHECK( LibraryExists( aLibrary ), true );
wxFileName fn( m_symbolTable->GetFullURI( aLibrary ) );
return ( fn.FileExists() && !fn.IsFileWritable() ) || !fn.IsDirWritable();
}
wxArrayString LIB_MANAGER::GetAliasNames( const wxString& aLibrary ) const
{
wxArrayString names;
wxCHECK( LibraryExists( aLibrary ), names );
auto it = m_libs.find( aLibrary );
if( it == m_libs.end() )
{
try {
m_symbolTable->EnumerateSymbolLib( aLibrary, names );
} catch( IO_ERROR& e ) {}
}
else
{
names = it->second.GetAliasNames();
}
return names;
}
std::list<LIB_ALIAS*> LIB_MANAGER::GetAliases( const wxString& aLibrary ) const
{
std::list<LIB_ALIAS*> ret;
wxCHECK( LibraryExists( aLibrary ), ret );
auto libIt = m_libs.find( aLibrary );
if( libIt != m_libs.end() )
{
for( auto& partBuf : libIt->second.GetBuffers() )
{
for( unsigned int i = 0; i < partBuf->GetPart()->GetAliasCount(); ++i )
ret.push_back( partBuf->GetPart()->GetAlias( i ) );
}
}
else
{
wxArrayString symbols;
try {
m_symbolTable->EnumerateSymbolLib( aLibrary, symbols );
for( const auto& symbol : symbols )
ret.push_back( m_symbolTable->LoadSymbol( aLibrary, symbol ) );
} catch( IO_ERROR& e ) {}
}
return ret;
}
LIB_PART* LIB_MANAGER::GetBufferedPart( const wxString& aAlias, const wxString& aLibrary )
{
wxCHECK( LibraryExists( aLibrary ), nullptr );
// try the library buffers first
LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
LIB_PART* bufferedPart = libBuf.GetPart( aAlias );
if( !bufferedPart ) // no buffer part found
{
// create a copy of the part
try {
LIB_ALIAS* alias = m_symbolTable->LoadSymbol( aLibrary, aAlias );
wxCHECK( alias, nullptr );
bufferedPart = new LIB_PART( *alias->GetPart(), nullptr );
libBuf.CreateBuffer( bufferedPart, new SCH_SCREEN( &m_frame.Kiway() ) );
} catch( IO_ERROR& e ) {}
}
return bufferedPart;
}
SCH_SCREEN* LIB_MANAGER::GetScreen( const wxString& aAlias, const wxString& aLibrary )
{
wxCHECK( LibraryExists( aLibrary ), nullptr );
wxCHECK( !aAlias.IsEmpty(), nullptr );
auto it = m_libs.find( aLibrary );
wxCHECK( it != m_libs.end(), nullptr );
LIB_BUFFER& buf = it->second;
auto partBuf = buf.GetBuffer( aAlias );
return partBuf ? partBuf->GetScreen() : nullptr;
}
bool LIB_MANAGER::UpdatePart( LIB_PART* aPart, const wxString& aLibrary, wxString aOldName )
{
wxCHECK( LibraryExists( aLibrary ), false );
wxCHECK( aPart, false );
const wxString partName = aOldName.IsEmpty() ? aPart->GetName() : aOldName;
LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
auto partBuf = libBuf.GetBuffer( partName );
LIB_PART* partCopy = new LIB_PART( *aPart, nullptr );
if( partBuf )
{
libBuf.UpdateBuffer( partBuf, partCopy );
}
else // New entry
{
SCH_SCREEN* screen = new SCH_SCREEN( &m_frame.Kiway() );
libBuf.CreateBuffer( partCopy, screen );
screen->SetModify();
}
getAdapter()->UpdateLibrary( aLibrary );
return true;
}
bool LIB_MANAGER::FlushPart( const wxString& aAlias, const wxString& aLibrary )
{
auto it = m_libs.find( aLibrary );
if( it == m_libs.end() ) // no items to flush
return true;
auto partBuf = it->second.GetBuffer( aAlias );
wxCHECK( partBuf, false );
return it->second.SaveBuffer( partBuf, m_symbolTable );
}
bool LIB_MANAGER::RevertPart( const wxString& aAlias, const wxString& aLibrary )
{
auto it = m_libs.find( aLibrary );
if( it == m_libs.end() ) // no items to flush
return true;
auto partBuf = it->second.GetBuffer( aAlias );
wxCHECK( partBuf, false );
partBuf->SetPart( new LIB_PART( *partBuf->GetOriginal() ) );
return true;
}
bool LIB_MANAGER::RevertLibrary( const wxString& aLibrary )
{
auto it = m_libs.find( aLibrary );
if( it == m_libs.end() ) // nothing to reverse
return false;
m_libs.erase( it );
getAdapter()->UpdateLibrary( aLibrary );
return true;
}
bool LIB_MANAGER::RemovePart( const wxString& aAlias, const wxString& aLibrary )
{
LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
auto partBuf = libBuf.GetBuffer( aAlias );
wxCHECK( partBuf, false );
bool res = libBuf.DeleteBuffer( partBuf );
getAdapter()->UpdateLibrary( aLibrary );
return res;
}
LIB_ALIAS* LIB_MANAGER::GetAlias( const wxString& aAlias, const wxString& aLibrary ) const
{
// Try the library buffers first
auto libIt = m_libs.find( aLibrary );
if( libIt != m_libs.end() )
{
LIB_PART* part = libIt->second.GetPart( aAlias );
if( part )
return part->GetAlias( aAlias );
}
// Get the original part
LIB_ALIAS* alias = nullptr;
try {
alias = m_symbolTable->LoadSymbol( aLibrary, aAlias );
} catch( IO_ERROR& e ) {}
return alias;
}
bool LIB_MANAGER::PartExists( const wxString& aAlias, const wxString& aLibrary ) const
{
auto libBufIt = m_libs.find( aLibrary );
LIB_ALIAS* alias = nullptr;
if( libBufIt != m_libs.end() )
return !!libBufIt->second.GetBuffer( aAlias );
try {
alias = m_symbolTable->LoadSymbol( aLibrary, aAlias );
} catch( IO_ERROR& e ) {}
return alias != nullptr;
}
bool LIB_MANAGER::LibraryExists( const wxString& aLibrary ) const
{
if( aLibrary.IsEmpty() )
return false;
if( m_libs.count( aLibrary ) > 0 )
return true;
return m_symbolTable->HasLibrary( aLibrary );
}
wxString LIB_MANAGER::ValidateName( const wxString& aName )
{
wxString name( aName );
name.Replace( " ", "_" );
return name;
}
wxString LIB_MANAGER::GetUniqueLibraryName() const
{
wxString name = "New_Library";
if( !LibraryExists( name ) )
return name;
name += "_";
for( unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i )
{
if( !LibraryExists( name + wxString::Format( "%u", i ) ) )
return name + wxString::Format( "%u", i );
}
wxFAIL;
return wxEmptyString;
}
wxString LIB_MANAGER::GetUniqueComponentName( const wxString& aLibrary ) const
{
wxString name = "New_Component";
if( !PartExists( name, aLibrary ) )
return name;
name += "_";
for( unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i )
{
if( !PartExists( name + wxString::Format( "%u", i ), aLibrary ) )
return name + wxString::Format( "%u", i );
}
wxFAIL;
return wxEmptyString;
}
wxString LIB_MANAGER::getLibraryName( const wxString& aFilePath )
{
wxFileName fn( aFilePath );
return fn.GetName();
}
bool LIB_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate )
{
wxString libName = getLibraryName( aFilePath );
wxCHECK( !LibraryExists( libName ), false ); // either create or add an existing one
// Select the target library table (global/project)
SYMBOL_LIB_TABLE* libTable = m_frame.SelectSymLibTable();
wxCHECK( libTable, false );
SYMBOL_LIB_TABLE_ROW* libRow = new SYMBOL_LIB_TABLE_ROW( libName, aFilePath,
SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
libTable->InsertRow( libRow );
if( aCreate )
libTable->CreateSymbolLib( libName );
getAdapter()->AddLibrary( libName );
return true;
}
std::set<LIB_PART*> LIB_MANAGER::getOriginalParts( const wxString& aLibrary )
{
std::set<LIB_PART*> parts;
wxCHECK( LibraryExists( aLibrary ), parts );
try {
wxArrayString aliases;
m_symbolTable->EnumerateSymbolLib( aLibrary, aliases );
for( const auto& aliasName : aliases )
{
LIB_ALIAS* alias = m_symbolTable->LoadSymbol( aLibrary, aliasName );
parts.insert( alias->GetPart() );
}
} catch( IO_ERROR& e ) {}
return parts;
}
LIB_MANAGER::LIB_BUFFER& LIB_MANAGER::getLibraryBuffer( const wxString& aLibrary )
{
auto it = m_libs.find( aLibrary );
if( it != m_libs.end() )
return it->second;
auto ret = m_libs.emplace( aLibrary, LIB_BUFFER( aLibrary ) );
LIB_BUFFER& buf = ret.first->second;
for( auto part : getOriginalParts( aLibrary ) )
buf.CreateBuffer( new LIB_PART( *part, nullptr ), new SCH_SCREEN( &m_frame.Kiway() ) );
return buf;
}
LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, SCH_SCREEN* aScreen )
: m_screen( aScreen ), m_part( aPart )
{
m_original = new LIB_PART( *aPart );
}
LIB_MANAGER::PART_BUFFER::~PART_BUFFER()
{
delete m_screen;
delete m_part;
delete m_original;
}
void LIB_MANAGER::PART_BUFFER::SetPart( LIB_PART* aPart )
{
wxCHECK( m_part != aPart, /* void */ );
wxASSERT( aPart );
delete m_part;
m_part = aPart;
}
void LIB_MANAGER::PART_BUFFER::SetOriginal( LIB_PART* aPart )
{
wxCHECK( m_original != aPart, /* void */ );
wxASSERT( aPart );
delete m_original;
m_original = aPart;
}
bool LIB_MANAGER::PART_BUFFER::IsModified() const
{
return m_screen && m_screen->IsModify();
}
wxArrayString LIB_MANAGER::LIB_BUFFER::GetAliasNames() const
{
wxArrayString ret;
for( const auto& alias : m_aliases )
ret.push_back( alias.first );
return ret;
}
bool LIB_MANAGER::LIB_BUFFER::CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen )
{
wxASSERT( m_aliases.count( aCopy->GetName() ) == 0 ); // only for new parts
wxASSERT( aCopy->GetLib() == nullptr );
auto partBuf = std::make_shared<PART_BUFFER>( aCopy, aScreen );
m_parts.push_back( partBuf );
addAliases( partBuf );
// Set the parent library name,
// otherwise it is empty as no library has been given as the owner during object construction
LIB_ID& libId = (LIB_ID&) aCopy->GetLibId();
libId.SetLibNickname( m_libName );
++m_hash;
return true;
}
bool LIB_MANAGER::LIB_BUFFER::UpdateBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf, LIB_PART* aCopy )
{
bool ret = true;
ret &= removeAliases( aPartBuf );
aPartBuf->SetPart( aCopy );
ret &= addAliases( aPartBuf );
++m_hash;
return ret;
}
bool LIB_MANAGER::LIB_BUFFER::DeleteBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf )
{
auto partBufIt = std::find( m_parts.begin(), m_parts.end(), aPartBuf );
wxCHECK( partBufIt != m_parts.end(), false );
m_deleted.emplace_back( *partBufIt );
m_parts.erase( partBufIt );
++m_hash;
return removeAliases( aPartBuf );
}
bool LIB_MANAGER::LIB_BUFFER::SaveBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf,
SYMBOL_LIB_TABLE* aLibTable )
{
wxCHECK( aPartBuf, false );
LIB_PART* part = aPartBuf->GetPart();
wxCHECK( part, false );
wxCHECK( aLibTable->SaveSymbol( m_libName, new LIB_PART( *part ) ) == SYMBOL_LIB_TABLE::SAVE_OK, false );
aPartBuf->SetOriginal( new LIB_PART( *part ) );
++m_hash;
return true;
}
bool LIB_MANAGER::LIB_BUFFER::SaveBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf,
SCH_PLUGIN* aPlugin, bool aBuffer )
{
wxCHECK( aPartBuf, false );
LIB_PART* part = aPartBuf->GetPart();
wxCHECK( part, false );
// set properties to prevent save file on every symbol save
PROPERTIES properties;
properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
// TODO there is no way to check if symbol has been successfully saved
aPlugin->SaveSymbol( m_libName, new LIB_PART( *part ), aBuffer ? &properties : nullptr );
aPartBuf->SetOriginal( new LIB_PART( *part ) );
++m_hash;
return true;
}
bool LIB_MANAGER::LIB_BUFFER::addAliases( PART_BUFFER::PTR aPartBuf )
{
LIB_PART* part = aPartBuf->GetPart();
wxCHECK( part, false );
bool ret = true; // Assume everything is ok
for( unsigned int i = 0; i < part->GetAliasCount(); ++i )
{
bool newAlias;
std::tie( std::ignore, newAlias ) = m_aliases.emplace( part->GetAlias( i )->GetName(), aPartBuf );
if( !newAlias ) // Overwrite check
{
wxFAIL;
ret = false;
}
}
return ret;
}
bool LIB_MANAGER::LIB_BUFFER::removeAliases( PART_BUFFER::PTR aPartBuf )
{
LIB_PART* part = aPartBuf->GetPart();
wxCHECK( part, false );
bool ret = true; // Assume everything is ok
for( unsigned int i = 0; i < part->GetAliasCount(); ++i )
{
auto aliasIt = m_aliases.find( part->GetAlias( i )->GetName() );
if( aliasIt == m_aliases.end() )
{
wxFAIL;
ret = false;
continue;
}
// Be sure the alias belongs to the assigned owner
wxASSERT( aliasIt->second.lock() == aPartBuf );
m_aliases.erase( aliasIt );
}
return ret;
}

430
eeschema/lib_manager.h Normal file
View File

@ -0,0 +1,430 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LIB_MANAGER_H
#define LIB_MANAGER_H
#include <map>
#include <list>
#include <deque>
#include <set>
#include <memory>
#include <wx/arrstr.h>
#include <lib_manager_adapter.h>
class LIB_ALIAS;
class LIB_PART;
class LIB_BUFFER;
class PART_LIB;
class SCH_SCREEN;
class SCH_PLUGIN;
class LIB_EDIT_FRAME;
class SYMBOL_LIB_TABLE;
/**
* Class to handle modifications to the symbol libraries.
*/
class LIB_MANAGER
{
public:
LIB_MANAGER( LIB_EDIT_FRAME& aFrame );
/**
* Updates the LIB_MANAGER data to synchronize with Symbol Library Table.
*/
void Sync( bool aForce = false );
int GetHash() const;
/**
* Retruns a library hash value to determine if it has changed.
*
* For buffered libraries, it returns a number corresponding to the number
* of modifications. For original libraries, hash is computed basing on the
* library URI. Returns -1 when the requested library does not exist.
*/
int GetLibraryHash( const wxString& aLibrary ) const;
/**
* Returns the array of library names.
*/
wxArrayString GetLibraryNames() const;
/**
* Returns a set containing all part names for a specific library.
*/
wxArrayString GetAliasNames( const wxString& aLibrary ) const;
std::list<LIB_ALIAS*> GetAliases( const wxString& aLibrary ) const;
/**
* Creates an empty library and adds it to the library table. The library file is created.
*/
bool CreateLibrary( const wxString& aFilePath )
{
return addLibrary( aFilePath, true );
}
/**
* Adds an existing library. The library is added to the library table as well.
*/
bool AddLibrary( const wxString& aFilePath )
{
return addLibrary( aFilePath, false );
}
/**
* Updates the part buffer with a new version of the part.
* The library buffer creates a copy of the part.
* It is required to save the library to use the updated part in the schematic editor.
*/
bool UpdatePart( LIB_PART* aPart, const wxString& aLibrary, wxString aOldName = wxEmptyString );
/**
* Removes the part from the part buffer.
* It is required to save the library to have the part removed in the schematic editor.
*/
bool RemovePart( const wxString& aName, const wxString& aLibrary );
/**
* Returns either an alias of a working LIB_PART copy, or alias of the original part if there
* is no working copy.
*/
LIB_ALIAS* GetAlias( const wxString& aAlias, const wxString& aLibrary ) const;
/**
* Returns the part copy from the buffer. In case it does not exist yet, the copy is created.
* LIB_MANAGER retains the ownership.
*/
LIB_PART* GetBufferedPart( const wxString& aAlias, const wxString& aLibrary );
/**
* Returns the screen used to edit a specific part. LIB_MANAGER retains the ownership.
*/
SCH_SCREEN* GetScreen( const wxString& aAlias, const wxString& aLibrary );
/**
* Returns true if part with a specific alias exists in library (either original one or buffered).
*/
bool PartExists( const wxString& aAlias, const wxString& aLibrary ) const;
/**
* Returns true if library exists.
*/
bool LibraryExists( const wxString& aLibrary ) const;
/**
* Returns true if library has unsaved modifications.
*/
bool IsLibraryModified( const wxString& aLibrary ) const;
/**
* Returns true if part has unsaved modifications.
*/
bool IsPartModified( const wxString& aAlias, const wxString& aLibrary ) const;
/**
* Clears the modified flag for all parts in a library.
*/
bool ClearLibraryModified( const wxString& aLibrary ) const;
/**
* Clears the modified flag for a part.
*/
bool ClearPartModified( const wxString& aAlias, const wxString& aLibrary ) const;
/**
* Returns true if the library is stored in a read-only file.
* @return True on success, false otherwise.
*/
bool IsLibraryReadOnly( const wxString& aLibrary ) const;
/**
* Saves part changes to the library copy used by the schematic editor. Not it is not
* necessarily saved to the file.
* @return True on success, false otherwise.
*/
bool FlushPart( const wxString& aAlias, const wxString& aLibrary );
/**
* Saves changes to the library copy used by the schematic editor. Note it is not
* necessarily saved to the file.
* @param aLibrary is the library name.
* @return True on success, false otherwise.
*/
bool FlushLibrary( const wxString& aLibrary );
/**
* Saves library to a file, including unsaved changes.
* @param aLibrary is the library name.
* @param aFileName is the target file name.
* @return True on success, false otherwise.
*/
bool SaveLibrary( const wxString& aLibrary, const wxString& aFileName );
/**
* Saves all changes to libraries.
* @return True if all changes have been flushed successfully, false otherwise.
*/
bool FlushAll();
/**
* Reverts unsaved changes for a particular part.
* @return True on success, false otherwise.
*/
bool RevertPart( const wxString& aAlias, const wxString& aLibrary );
/**
* Reverts unsaved changes for a particular library.
* @return True on success, false otherwise.
*/
bool RevertLibrary( const wxString& aLibrary );
/**
* Replaces all characters considered illegal in library/part names with underscores.
*/
static wxString ValidateName( const wxString& aName );
/**
* Returns a library name that is not currently in use.
* Used for generating names for new libraries.
*/
wxString GetUniqueLibraryName() const;
/**
* Returns a component name that is not stored in a library.
* Used for generating names for new components.
*/
wxString GetUniqueComponentName( const wxString& aLibrary ) const;
/**
* Returns the adapter object that provides the stored data.
*/
CMP_TREE_MODEL_ADAPTER_BASE::PTR& GetAdapter() { return m_adapter; }
/**
* Returns the currently modified library name.
*/
const wxString& GetCurrentLib() const
{
return m_currentLib;
}
/**
* Sets the currently modified library name.
*/
void SetCurrentLib( const wxString& aLibrary )
{
m_currentLib = aLibrary;
}
/**
* Returns the currently modified part name.
*/
const wxString& GetCurrentPart() const
{
return m_currentPart;
}
/**
* Sets the currently modified part name.
*/
void SetCurrentPart( const wxString& aPart )
{
m_currentPart = aPart;
}
/**
* Returns the current library and part name as LIB_ID.
*/
LIB_ID GetCurrentLibId() const
{
return LIB_ID( m_currentLib, m_currentPart );
}
private:
///> Parent frame
LIB_EDIT_FRAME& m_frame;
///> Extracts library name basing on the file name
static wxString getLibraryName( const wxString& aFilePath );
///> Helper function to add either existing or create new library
bool addLibrary( const wxString& aFilePath, bool aCreate );
SYMBOL_LIB_TABLE* m_symbolTable;
///> Class to store a working copy of a LIB_PART object and editor context.
class PART_BUFFER
{
public:
PART_BUFFER( LIB_PART* aPart = nullptr, SCH_SCREEN* aScreen = nullptr );
~PART_BUFFER();
LIB_PART* GetPart() const { return m_part; }
void SetPart( LIB_PART* aPart );
LIB_PART* GetOriginal() const { return m_original; }
void SetOriginal( LIB_PART* aPart );
bool IsModified() const;
SCH_SCREEN* GetScreen() const { return m_screen; }
typedef std::shared_ptr<PART_BUFFER> PTR;
typedef std::weak_ptr<PART_BUFFER> WEAK_PTR;
private:
SCH_SCREEN* m_screen;
///> Working copy
LIB_PART* m_part;
///> Initial state of the part
LIB_PART* m_original;
};
///> Class to store a working copy of a library
class LIB_BUFFER
{
public:
LIB_BUFFER( const wxString& aLibrary )
: m_libName( aLibrary ), m_hash( 1 )
{
}
bool IsModified() const
{
if( !m_deleted.empty() )
return true;
for( const auto& partBuf : m_parts )
{
if( partBuf->IsModified() )
return true;
}
return false;
}
int GetHash() const
{
return m_hash;
}
///> Returns all alias names for stored parts
wxArrayString GetAliasNames() const;
///> Returns the working copy of a LIB_PART object with specified alias
LIB_PART* GetPart( const wxString& aAlias ) const
{
auto buf = GetBuffer( aAlias );
return buf ? buf->GetPart() : nullptr;
}
///> Creates a new buffer to store a part. LIB_BUFFER takes ownership of aCopy.
bool CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen );
///> Updates the stored part. LIB_BUFFER takes ownership of aCopy.
bool UpdateBuffer( PART_BUFFER::PTR aPartBuf, LIB_PART* aCopy );
bool DeleteBuffer( PART_BUFFER::PTR aPartBuf );
void ClearDeletedBuffer()
{
m_deleted.clear();
}
///> Saves stored modifications to Symbol Lib Table. It may result in saving the symbol
///> to disk as well, depending on the row properties.
bool SaveBuffer( PART_BUFFER::PTR aPartBuf, SYMBOL_LIB_TABLE* aLibTable );
///> Saves stored modificatiosn using a plugin. aBuffer decides whether the changes
///> should be cached or stored directly to the disk (for SCH_LEGACY_PLUGIN).
bool SaveBuffer( PART_BUFFER::PTR aPartBuf, SCH_PLUGIN* aPlugin, bool aBuffer );
///> Returns a part buffer with LIB_PART holding a particular alias
PART_BUFFER::PTR GetBuffer( const wxString& aAlias ) const
{
auto it = m_aliases.find( aAlias );
return it != m_aliases.end() ? it->second.lock() : PART_BUFFER::PTR( nullptr );
}
///> Returns all buffered parts
const std::deque<PART_BUFFER::PTR>& GetBuffers() const
{
return m_parts;
}
///> Returns all aliases of buffered parts
const std::map<wxString, PART_BUFFER::WEAK_PTR>& GetAliases() const
{
return m_aliases;
}
private:
///> Creates alias entries for a particular part buffer
bool addAliases( PART_BUFFER::PTR aPartBuf );
///> Removes alias entries for a particular part buffer
bool removeAliases( PART_BUFFER::PTR aPartBuf );
std::map<wxString, PART_BUFFER::WEAK_PTR> m_aliases;
std::deque<PART_BUFFER::PTR> m_parts;
///> Buffer to keep deleted parts until the library is saved
std::deque<PART_BUFFER::PTR> m_deleted;
/// Buffered library name
const wxString m_libName;
int m_hash;
friend class PART_BUFFER;
};
///> Returns a set of LIB_PART objects belonging to the original library
std::set<LIB_PART*> getOriginalParts( const wxString& aLibrary );
///> Returns an existing library buffer or creates one to using
///> Symbol Library Table to get the original data.
LIB_BUFFER& getLibraryBuffer( const wxString& aLibrary );
///> The library buffers
std::map<wxString, LIB_BUFFER> m_libs;
///> Symbol Lib Table hash value returned during the last synchronization
int m_syncHash;
///> Currently modified part
wxString m_currentLib;
///> Currently modified library
wxString m_currentPart;
LIB_MANAGER_ADAPTER::PTR m_adapter;
LIB_MANAGER_ADAPTER* getAdapter() { return static_cast<LIB_MANAGER_ADAPTER*>( m_adapter.get() ); }
};
#endif /* LIB_MANAGER_H */

View File

@ -0,0 +1,253 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <lib_manager_adapter.h>
#include <lib_manager.h>
#include <class_libentry.h>
CMP_TREE_MODEL_ADAPTER_BASE::PTR LIB_MANAGER_ADAPTER::Create( LIB_MANAGER* aLibMgr )
{
auto adapter = new LIB_MANAGER_ADAPTER( aLibMgr );
auto container = CMP_TREE_MODEL_ADAPTER_BASE::PTR( adapter );
return container;
}
void LIB_MANAGER_ADAPTER::AddLibrary( const wxString& aLibNickname )
{
auto& lib_node = m_tree.AddLib( aLibNickname );
ItemAdded( wxDataViewItem( nullptr ), ToItem( &lib_node ) );
updateLibrary( lib_node );
finishUpdate();
}
void LIB_MANAGER_ADAPTER::RemoveLibrary( const wxString& aLibNickname )
{
auto it = std::find_if( m_tree.Children.begin(), m_tree.Children.end(),
[&] ( std::unique_ptr<CMP_TREE_NODE>& node ) { return node->Name == aLibNickname; } );
if( it != m_tree.Children.end() )
deleteLibrary( it );
}
void LIB_MANAGER_ADAPTER::UpdateLibrary( const wxString& aLibraryName )
{
CMP_TREE_NODE* node = findLibrary( aLibraryName );
if( !node )
return;
updateLibrary( *(CMP_TREE_NODE_LIB*) node );
finishUpdate();
}
void LIB_MANAGER_ADAPTER::AddAliasList( const wxString& aNodeName,
const wxArrayString& aAliasNameList )
{
wxASSERT( false ); // TODO
}
bool LIB_MANAGER_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
{
const CMP_TREE_NODE* node = ToNode( aItem );
return node ? node->Type == CMP_TREE_NODE::LIB : true;
}
void LIB_MANAGER_ADAPTER::Sync( bool aForce )
{
wxBusyCursor cursor;
int libMgrHash = m_libMgr->GetHash();
if( !aForce && m_lastSyncHash == libMgrHash )
return;
m_lastSyncHash = libMgrHash;
// Process already stored libraries
for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); /* iteration inside */ )
{
const wxString& name = it->get()->Name;
if( !m_libMgr->LibraryExists( name ) )
{
it = deleteLibrary( it );
continue;
}
else if( m_libMgr->GetLibraryHash( name ) != m_libHashes[name] )
{
updateLibrary( *(CMP_TREE_NODE_LIB*) it->get() );
}
++it;
}
// Look for new libraries
for( const auto& libName : m_libMgr->GetLibraryNames() )
{
if( m_libHashes.count( libName ) == 0 )
AddLibrary( libName );
}
finishUpdate();
}
void LIB_MANAGER_ADAPTER::updateLibrary( CMP_TREE_NODE_LIB& aLibNode )
{
if( m_libHashes.count( aLibNode.Name ) == 0 )
{
// add a new library
wxDataViewItem parent = ToItem( &aLibNode );
for( auto alias : m_libMgr->GetAliases( aLibNode.Name ) )
{
auto& aliasNode = aLibNode.AddAlias( alias );
ItemAdded( parent, ToItem( &aliasNode ) );
}
}
else
{
// update an existing libary
std::list<LIB_ALIAS*> aliases = m_libMgr->GetAliases( aLibNode.Name );
wxDataViewItem parent = ToItem( &aLibNode );
// remove the common part from the aliases list
//for( const auto& node : aLibNode.Children )
for( auto nodeIt = aLibNode.Children.begin(); nodeIt != aLibNode.Children.end(); /**/ )
{
auto aliasIt = std::find_if( aliases.begin(), aliases.end(),
[&] ( const LIB_ALIAS* a ) {
return a->GetName() == (*nodeIt)->Name;
} );
if( aliasIt != aliases.end() )
{
// alias exists both in the component tree and the library manager,
// no need to update
aliases.erase( aliasIt );
++nodeIt;
}
else
{
// node does not exist in the library manager, remove the corresponding node
ItemDeleted( parent, ToItem( nodeIt->get() ) );
nodeIt = aLibNode.Children.erase( nodeIt );
}
}
// now the aliases list contains only new aliases that need to be added to the tree
for( auto alias : aliases )
{
auto& aliasNode = aLibNode.AddAlias( alias );
ItemAdded( parent, ToItem( &aliasNode ) );
}
}
aLibNode.AssignIntrinsicRanks();
m_libHashes[aLibNode.Name] = m_libMgr->GetLibraryHash( aLibNode.Name );
}
CMP_TREE_NODE::PTR_VECTOR::iterator LIB_MANAGER_ADAPTER::deleteLibrary(
CMP_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt )
{
CMP_TREE_NODE* node = aLibNodeIt->get();
ItemDeleted( wxDataViewItem( nullptr ), ToItem( node ) );
m_libHashes.erase( node->Name );
auto it = m_tree.Children.erase( aLibNodeIt );
return it;
}
void LIB_MANAGER_ADAPTER::finishUpdate()
{
m_tree.AssignIntrinsicRanks();
}
CMP_TREE_NODE* LIB_MANAGER_ADAPTER::findLibrary( const wxString& aLibNickName )
{
for( auto& lib : m_tree.Children )
{
if( lib->Name == aLibNickName )
return lib.get();
}
return nullptr;
}
bool LIB_MANAGER_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
wxDataViewItemAttr& aAttr ) const
{
// change attributes only for the name field
if( aCol != 0 )
return false;
auto node = ToNode( aItem );
wxCHECK( node, false );
switch( node->Type )
{
case CMP_TREE_NODE::LIB:
// mark modified libs with bold font
aAttr.SetBold( m_libMgr->IsLibraryModified( node->Name ) );
// mark current library with inverted colors
if( node->Name == m_libMgr->GetCurrentLib() )
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
break;
case CMP_TREE_NODE::LIBID:
// mark modified part with bold font
aAttr.SetBold( m_libMgr->IsPartModified( node->Name, node->Parent->Name ) );
// mark aliases with italic font
aAttr.SetItalic( !node->IsRoot );
// mark current library with inverted colors
if( node->LibId == m_libMgr->GetCurrentLibId() )
aAttr.SetColour( wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
break;
default:
return false;
}
return true;
}
LIB_MANAGER_ADAPTER::LIB_MANAGER_ADAPTER( LIB_MANAGER* aLibMgr )
: m_libMgr( aLibMgr ), m_lastSyncHash( -1 )
{
}

View File

@ -0,0 +1,74 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LIB_MANAGER_ADAPTER_H
#define LIB_MANAGER_ADAPTER_H
#include <cmp_tree_model_adapter_base.h>
#include <map>
class LIB_MANAGER;
class LIB_MANAGER_ADAPTER : public CMP_TREE_MODEL_ADAPTER_BASE
{
public:
static PTR Create( LIB_MANAGER* aLibs );
void AddLibrary( const wxString& aLibNickname ) override;
void RemoveLibrary( const wxString& aLibNickname );
void AddAliasList( const wxString& aNodeName, const wxArrayString& aAliasNameList ) override;
bool IsContainer( const wxDataViewItem& aItem ) const override;
void UpdateLibrary( const wxString& aLibraryName );
void Sync( bool aForce = false );
protected:
void updateLibrary( CMP_TREE_NODE_LIB& aLibNode );
CMP_TREE_NODE::PTR_VECTOR::iterator deleteLibrary(
CMP_TREE_NODE::PTR_VECTOR::iterator& aLibNodeIt );
void finishUpdate();
CMP_TREE_NODE* findLibrary( const wxString& aLibNickName );
bool GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
wxDataViewItemAttr& aAttr ) const override;
LIB_MANAGER_ADAPTER( LIB_MANAGER* aLibMgr );
LIB_MANAGER* m_libMgr;
///> Hashes to decide whether a library needs an update
std::map<wxString, int> m_libHashes;
///> LIB_MANAGER hash value returned in the last synchronization
int m_lastSyncHash;
};
#endif /* LIB_MANAGER_ADAPTER_H */

View File

@ -46,6 +46,9 @@
#include <wildcards_and_files_ext.h>
#include <schframe.h>
#include <symbol_lib_table.h>
#include <lib_manager.h>
#include <cmp_tree_pane.h>
#include <component_tree.h>
#include <dialog_choose_component.h>
#include <cmp_tree_model_adapter.h>
@ -64,7 +67,7 @@ void LIB_EDIT_FRAME::DisplayLibInfos()
title += lib + " (" + fileName + ")";
if( !wxFileName::IsFileWritable( fileName ) )
if( wxFileName::FileExists( fileName ) && !wxFileName::IsFileWritable( fileName ) )
title += " " + _( "[Read Only]" );
}
else
@ -140,54 +143,6 @@ bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( const wxString& aAliasName, in
}
void LIB_EDIT_FRAME::LoadOneLibraryPart( wxCommandEvent& event )
{
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
if( GetScreen()->IsModify()
&& !IsOK( this, _( "The current symbol is not saved.\n\nDiscard current changes?" ) ) )
return;
wxString lib = GetCurLib();
// No current lib, ask user for the library to use.
if( lib.empty() )
{
SelectActiveLibrary();
lib = GetCurLib();
if( lib.empty() )
return;
}
// Get the name of the current part to preselect it
LIB_PART* current_part = GetCurPart();
LIB_ID id;
if( current_part )
id = current_part->GetLibId();
SCH_BASE_FRAME::HISTORY_LIST dummyHistoryList;
SCHLIB_FILTER filter;
filter.LoadFrom( lib );
auto sel = SelectComponentFromLibrary( &filter, dummyHistoryList, true, 0, 0, &id, false );
if( sel.LibId.GetLibItemName().empty() )
return;
GetScreen()->ClrModify();
m_lastDrawItem = m_drawItem = NULL;
// Delete previous library symbol, if any
SetCurPart( NULL );
m_aliasName.Empty();
// Load the new library symbol
LoadComponentFromCurrentLib( sel.LibId.GetLibItemName(), sel.Unit, sel.Convert );
}
bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& aLibrary )
{
wxString msg, rootName;
@ -201,25 +156,19 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& a
return false;
}
wxString cmpName = m_aliasName = aEntry->GetName();
LIB_PART* lib_part = aEntry->GetPart();
wxASSERT( lib_part );
LIB_PART* part = new LIB_PART( *lib_part ); // clone it and own it.
SetCurPart( part );
m_aliasName = aEntry->GetName();
LIB_PART* lib_part = m_libMgr->GetBufferedPart( m_aliasName, aLibrary );
wxASSERT( lib_part );
SetScreen( m_libMgr->GetScreen( lib_part->GetName(), aLibrary ) );
SetCurPart( new LIB_PART( *lib_part ) );
SetCurLib( aLibrary );
m_unit = 1;
m_convert = 1;
SetShowDeMorgan( GetCurPart()->HasConversion() );
m_showDeMorgan = false;
if( part->HasConversion() )
m_showDeMorgan = true;
GetScreen()->ClrModify();
Zoom_Automatique( false );
DisplayLibInfos();
UpdateAliasSelectList();
UpdatePartSelectList();
@ -227,6 +176,7 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& a
// Display the document information based on the entry selected just in
// case the entry is an alias.
DisplayCmpDoc();
Refresh();
return true;
}
@ -282,13 +232,268 @@ void LIB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
}
void LIB_EDIT_FRAME::OnSaveActiveLibrary( wxCommandEvent& event )
void LIB_EDIT_FRAME::OnSaveLibrary( wxCommandEvent& event )
{
SaveActiveLibrary( event.GetId() == ID_LIBEDIT_SAVE_CURRENT_LIB_AS );
saveLibrary( getTargetLib(), event.GetId() == ID_LIBEDIT_SAVE_LIBRARY_AS );
m_treePane->Refresh();
}
bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
void LIB_EDIT_FRAME::OnSaveAllLibraries( wxCommandEvent& event )
{
saveAllLibraries();
}
void LIB_EDIT_FRAME::OnRevertLibrary( wxCommandEvent& aEvent )
{
wxString libName = getTargetLib();
bool currentLib = ( libName == GetCurLib() );
// Save the current part name/unit to reload after revert
wxString alias = m_aliasName;
int unit = m_unit;
if( !IsOK( this, _( "The revert operation cannot be undone!\n\nRevert changes?" ) ) )
return;
if( currentLib )
emptyScreen();
m_libMgr->RevertLibrary( libName );
if( currentLib && m_libMgr->PartExists( alias, libName ) )
loadPart( alias, libName, unit );
}
void LIB_EDIT_FRAME::OnCreateNewPart( wxCommandEvent& event )
{
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
m_drawItem = NULL;
wxString lib = getTargetLib();
if( !m_libMgr->LibraryExists( lib ) )
{
lib = SelectLibraryFromList();
if( !m_libMgr->LibraryExists( lib ) )
return;
}
DIALOG_LIB_NEW_COMPONENT dlg( this );
dlg.SetMinSize( dlg.GetSize() );
if( dlg.ShowModal() == wxID_CANCEL )
return;
if( dlg.GetName().IsEmpty() )
{
wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
return;
}
wxString name = dlg.GetName();
name.Replace( " ", "_" );
// Test if there is a component with this name already.
if( !lib.empty() && m_libMgr->PartExists( name, lib ) )
{
wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
name, lib );
DisplayError( this, msg );
return;
}
LIB_PART new_part( name ); // do not create part on the heap, it will be buffered soon
m_aliasName = name;
new_part.GetReferenceField().SetText( dlg.GetReference() );
new_part.SetUnitCount( dlg.GetUnitCount() );
// Initialize new_part.m_TextInside member:
// if 0, pin text is outside the body (on the pin)
// if > 0, pin text is inside the body
new_part.SetConversion( dlg.GetAlternateBodyStyle() );
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
if( dlg.GetPinNameInside() )
{
new_part.SetPinNameOffset( dlg.GetPinTextPosition() );
if( new_part.GetPinNameOffset() == 0 )
new_part.SetPinNameOffset( 1 );
}
else
{
new_part.SetPinNameOffset( 0 );
}
( dlg.GetPowerSymbol() ) ? new_part.SetPower() : new_part.SetNormal();
new_part.SetShowPinNumbers( dlg.GetShowPinNumber() );
new_part.SetShowPinNames( dlg.GetShowPinName() );
new_part.LockUnits( dlg.GetLockItems() );
if( dlg.GetUnitCount() < 2 )
new_part.LockUnits( false );
m_libMgr->UpdatePart( &new_part, lib );
loadPart( name, lib, 1 );
}
void LIB_EDIT_FRAME::OnEditPart( wxCommandEvent& aEvent )
{
int unit = 0;
LIB_ID partId = m_treePane->GetCmpTree()->GetSelectedLibId( &unit );
loadPart( partId.GetLibItemName(), partId.GetLibNickname(), unit );
}
void LIB_EDIT_FRAME::OnSavePart( wxCommandEvent& aEvent )
{
LIB_ID libId = getTargetLibId();
if( m_libMgr->FlushPart( libId.GetLibItemName(), libId.GetLibNickname() ) )
m_libMgr->ClearPartModified( libId.GetLibItemName(), libId.GetLibNickname() );
m_treePane->Refresh();
}
void LIB_EDIT_FRAME::OnRemovePart( wxCommandEvent& aEvent )
{
LIB_ID libId = getTargetLibId();
if( m_libMgr->IsPartModified( libId.GetLibItemName(), libId.GetLibNickname() )
&& !IsOK( this, _( wxString::Format( "Component %s has been modified\n"
"Do you want to remove it from the library?", libId.GetLibItemName().c_str() ) ) ) )
{
return;
}
if( isCurrentPart( libId ) )
emptyScreen();
m_libMgr->RemovePart( libId.GetLibItemName(), libId.GetLibNickname() );
}
void LIB_EDIT_FRAME::OnCopyCutPart( wxCommandEvent& aEvent )
{
int unit = 0;
LIB_ID partId = m_treePane->GetCmpTree()->GetSelectedLibId( &unit );
LIB_PART* part = m_libMgr->GetBufferedPart( partId.GetLibItemName(), partId.GetLibNickname() );
if( !part )
return;
LIB_ID libId = getTargetLibId();
m_copiedPart.reset( new LIB_PART( *part ) );
if( aEvent.GetId() == ID_LIBEDIT_CUT_PART )
{
if( isCurrentPart( libId ) )
emptyScreen();
m_libMgr->RemovePart( libId.GetLibItemName(), libId.GetLibNickname() );
}
}
void LIB_EDIT_FRAME::OnPasteDuplicatePart( wxCommandEvent& aEvent )
{
int unit = 0;
LIB_ID libId = m_treePane->GetCmpTree()->GetSelectedLibId( &unit );
wxString lib = libId.GetLibNickname();
if( !m_libMgr->LibraryExists( lib ) )
return;
LIB_PART* srcPart = nullptr;
if( aEvent.GetId() == ID_LIBEDIT_DUPLICATE_PART )
srcPart = m_libMgr->GetBufferedPart( libId.GetLibItemName(), lib );
else if( aEvent.GetId() == ID_LIBEDIT_PASTE_PART )
srcPart = m_copiedPart.get();
else
wxFAIL;
if( !srcPart )
return;
LIB_PART newPart( *srcPart );
fixDuplicateAliases( &newPart, lib );
m_libMgr->UpdatePart( &newPart, lib );
m_treePane->GetCmpTree()->SelectLibId( LIB_ID( lib, newPart.GetName() ) );
}
void LIB_EDIT_FRAME::fixDuplicateAliases( LIB_PART* aPart, const wxString& aLibrary )
{
wxString newName;
for( unsigned int i = 0; i < aPart->GetAliasCount(); ++i )
{
LIB_ALIAS* alias = aPart->GetAlias( i );
int sfx = 0;
newName = alias->GetName();
while( m_libMgr->PartExists( newName, aLibrary ) )
{
wxString suffix = ( sfx == 0 ) ? wxT( " (copy)" )
: wxString::Format( _( " (copy %d)" ), sfx );
newName = alias->GetName() + suffix;
++sfx;
}
if( i == 0 )
aPart->SetName( newName );
else
alias->SetName( newName );
}
}
void LIB_EDIT_FRAME::OnRevertPart( wxCommandEvent& aEvent )
{
LIB_ID libId = getTargetLibId();
bool currentPart = isCurrentPart( libId );
int unit = m_unit;
if( currentPart )
emptyScreen();
if( m_libMgr->RevertPart( libId.GetLibItemName(), libId.GetLibNickname() ) )
m_libMgr->ClearPartModified( libId.GetLibItemName(), libId.GetLibNickname() );
if( currentPart && m_libMgr->PartExists( libId.GetLibItemName(), libId.GetLibNickname() ) )
loadPart( libId.GetLibItemName(), libId.GetLibNickname(), unit );
}
void LIB_EDIT_FRAME::loadPart( const wxString& aAlias, const wxString& aLibrary, int aUnit )
{
wxCHECK( m_libMgr->PartExists( aAlias, aLibrary ), /* void */ );
LIB_PART* part = m_libMgr->GetBufferedPart( aAlias, aLibrary );
LIB_ALIAS* alias = part ? part->GetAlias( aAlias ) : nullptr;
if( !alias )
{
wxString msg = wxString::Format( _( "Part name '%s' not found in library '%s'" ),
GetChars( aAlias ), GetChars( aLibrary ) );
DisplayError( this, msg );
return;
}
m_lastDrawItem = m_drawItem = nullptr;
m_aliasName = aAlias;
m_unit = ( aUnit <= part->GetUnitCount() ? aUnit : 1 );
LoadOneLibraryPartAux( alias, aLibrary );
}
bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
{
wxFileName fn;
wxString msg;
@ -296,20 +501,15 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
wxString lib = GetCurLib();
if( !newFile && ( lib.empty() || !prj.SchSymbolLibTable()->HasLibrary( lib ) ) )
if( !aNewFile && ( aLibrary.empty() || !prj.SchSymbolLibTable()->HasLibrary( aLibrary ) ) )
{
DisplayError( this, _( "No library specified." ) );
return false;
}
if( GetScreen()->IsModify() && !IsOK( this, _( "Include current symbol changes?" ) ) )
return false;
if( newFile )
if( aNewFile )
{
SEARCH_STACK* search = prj.SchSearchS();
SEARCH_STACK* search = prj.SchSearchS();
// Get a new name for the library
wxString default_path = prj.GetRString( PROJECT::SCH_LIB_PATH );
@ -317,8 +517,11 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
if( !default_path )
default_path = search->LastVisitedPath();
wxFileDialog dlg( this, _( "Symbol Library Name" ), default_path,
wxEmptyString, SchematicLibraryFileWildcard(),
fn.SetName( aLibrary );
fn.SetExt( SchematicLibraryFileExtension );
wxFileDialog dlg( this, wxString::Format( _( "Save Library '%s' As..." ), aLibrary ),
default_path, fn.GetFullName(), SchematicLibraryFileWildcard(),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
if( dlg.ShowModal() == wxID_CANCEL )
@ -330,17 +533,10 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
// file name so add it here.
if( fn.GetExt().IsEmpty() )
fn.SetExt( SchematicLibraryFileExtension );
prj.SetRString( PROJECT::SCH_LIB_PATH, fn.GetPath() );
}
else
{
fn = prj.SchSymbolLibTable()->GetFullURI( lib );
msg.Printf( _( "Modify symbol library file '%s' ?" ), fn.GetFullPath() );
if( !IsOK( this, msg ) )
return false;
fn = prj.SchSymbolLibTable()->GetFullURI( aLibrary );
}
// Verify the user has write privileges before attempting to save the library file.
@ -349,92 +545,29 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
ClearMsgPanel();
wxFileName libFileName = fn;
wxFileName backupFileName = fn;
// Copy .lib file to .bak.
if( libFileName.FileExists() )
{
backupFileName.SetExt( "bak" );
if( backupFileName.FileExists() )
wxRemoveFile( backupFileName.GetFullPath() );
if( !wxCopyFile( libFileName.GetFullPath(), backupFileName.GetFullPath() ) )
{
libFileName.MakeAbsolute();
msg.Printf( _( "Failed to rename old symbol library to file '%s'" ),
backupFileName.GetFullPath() );
DisplayError( this, msg );
return false;
}
}
wxFileName docFileName = libFileName;
if( !backupFile( fn, "bak" ) )
return false;
wxFileName docFileName = fn;
docFileName.SetExt( DOC_EXT );
// Copy .dcm file to .bck.
if( docFileName.FileExists() )
if( !backupFile( docFileName, "bck" ) )
return false;
if( !m_libMgr->SaveLibrary( aLibrary, fn.GetFullPath() ) )
{
backupFileName.SetExt( "bck" );
if( backupFileName.FileExists() )
wxRemoveFile( backupFileName.GetFullPath() );
if( !wxCopyFile( docFileName.GetFullPath(), backupFileName.GetFullPath() ) )
{
msg.Printf( _( "Failed to save old library document to file '%s'" ),
backupFileName.GetFullPath() );
DisplayError( this, msg );
return false;
}
msg.Printf( _( "Failed to save changes to symbol library file '%s'" ),
fn.GetFullPath() );
DisplayErrorMessage( this, _( "Error saving library" ), msg );
return false;
}
// Copy the library and document files to the new destination library files.
if( newFile )
{
wxFileName src = prj.SchSymbolLibTable()->GetFullURI( GetCurLib() );
if( !aNewFile )
m_libMgr->ClearLibraryModified( aLibrary );
if( !wxCopyFile( src.GetFullPath(), libFileName.GetFullPath() ) )
{
msg.Printf( _( "Failed to copy symbol library file '%s'" ), libFileName.GetFullPath() );
DisplayError( this, msg );
return false;
}
src.SetExt( DOC_EXT );
if( !wxCopyFile( src.GetFullPath(), docFileName.GetFullPath() ) )
{
msg.Printf( _( "Failed to copy symbol library document file '%s'" ),
docFileName.GetFullPath() );
DisplayError( this, msg );
return false;
}
}
// Update symbol changes in library.
if( GetScreen()->IsModify() )
{
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
try
{
pi->SaveSymbol( fn.GetFullPath(), new LIB_PART( *GetCurPart() ) );
}
catch( const IO_ERROR& ioe )
{
msg.Printf( _( "Failed to save changes to symbol library file '%s'" ),
libFileName.GetFullPath() );
DisplayErrorMessage( this, msg, ioe.What() );
return false;
}
GetScreen()->ClrModify();
}
msg.Printf( _( "Symbol library file '%s' saved" ), libFileName.GetFullPath() );
msg.Printf( _( "Symbol library file '%s' saved" ), fn.GetFullPath() );
wxString msg1;
msg1.Printf( _( "Symbol library documentation file '%s' saved" ), docFileName.GetFullPath() );
AppendMsgPanel( msg, msg1, BLUE );
@ -446,6 +579,47 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
}
bool LIB_EDIT_FRAME::saveAllLibraries()
{
wxArrayString unsavedLibraries;
// There are two stages: first try to save libraries to the original files.
// In case of problems, ask the user to save them in a new location.
bool firstRun = true;
bool allSaved = false;
while( !allSaved )
{
allSaved = true;
unsavedLibraries.Empty();
for( const auto& lib : m_libMgr->GetLibraryNames() )
{
if( m_libMgr->IsLibraryModified( lib ) )
unsavedLibraries.Add( lib );
}
if( !unsavedLibraries.IsEmpty() )
{
auto res = SelectMultipleOptions( this, _( "Save Libraries" ),
firstRun ? _( "Select libraries to save before closing" )
: _( "Some libraries could not be saved to their original files.\n\n"
"Do you want to save them to a new file?" ),
unsavedLibraries, true );
if( !res.first )
return false; // dialog has been cancelled
for( auto libIndex : res.second )
allSaved &= saveLibrary( unsavedLibraries[libIndex], !firstRun );
firstRun = false;
}
}
return true;
}
void LIB_EDIT_FRAME::DisplayCmpDoc()
{
LIB_ALIAS* alias;
@ -493,197 +667,3 @@ void LIB_EDIT_FRAME::DisplayCmpDoc()
AppendMsgPanel( _( "Key words" ), alias->GetKeyWords(), DARKDARKGRAY );
AppendMsgPanel( _( "Datasheet" ), alias->GetDocFileName(), DARKDARKGRAY );
}
void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event )
{
wxString cmp_name;
wxArrayString nameList;
wxString msg;
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
m_lastDrawItem = NULL;
m_drawItem = NULL;
LIB_PART *part = GetCurPart();
wxString lib = GetCurLib();
if( lib.empty() )
{
SelectActiveLibrary();
lib = GetCurLib();
if( !lib )
{
DisplayError( this, _( "Please select a symbol library." ) );
return;
}
}
auto adapter( CMP_TREE_MODEL_ADAPTER::Create( Prj().SchSymbolLibTable() ) );
wxString name = part ? part->GetName() : wxString( wxEmptyString );
adapter->SetPreselectNode( name, /* aUnit */ 0 );
adapter->ShowUnits( false );
adapter->AddLibrary( lib );
wxString dialogTitle;
dialogTitle.Printf( _( "Delete Symbol (%u items loaded)" ), adapter->GetComponentsCount() );
DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, adapter, m_convert, false );
if( dlg.ShowQuasiModal() == wxID_CANCEL )
{
return;
}
LIB_ID id;
id = dlg.GetSelectedLibId();
if( !id.IsValid() )
return;
LIB_ALIAS* alias = Prj().SchSymbolLibTable()->LoadSymbol( id );
if( !alias )
return;
msg.Printf( _( "Delete symbol '%s' from library '%s'?" ),
id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() );
if( !IsOK( this, msg ) )
return;
part = GetCurPart();
if( !part || !part->HasAlias( id.GetLibItemName() ) )
{
Prj().SchSymbolLibTable()->DeleteAlias( id.GetLibNickname(), id.GetLibItemName() );
m_canvas->Refresh();
return;
}
// If deleting the current entry or removing one of the aliases for
// the current entry, sync the changes in the current entry as well.
if( GetScreen()->IsModify() && !IsOK( this, _(
"The symbol being deleted has been modified."
" All changes will be lost. Discard changes?" ) ) )
{
return;
}
try
{
Prj().SchSymbolLibTable()->DeleteAlias( id.GetLibNickname(), id.GetLibItemName() );
}
catch( ... /* IO_ERROR ioe */ )
{
msg.Printf( _( "Error occurred deleting symbol '%s' from library '%s'" ),
id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() );
DisplayError( this, msg );
return;
}
SetCurPart( NULL ); // delete CurPart
m_aliasName.Empty();
m_canvas->Refresh();
}
void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event )
{
wxString name;
if( GetCurPart() && GetScreen()->IsModify() && !IsOK( this, _(
"All changes to the current symbol will be lost!\n\n"
"Clear the current symbol from the screen?" ) ) )
{
return;
}
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
m_drawItem = NULL;
DIALOG_LIB_NEW_COMPONENT dlg( this );
dlg.SetMinSize( dlg.GetSize() );
if( dlg.ShowModal() == wxID_CANCEL )
return;
if( dlg.GetName().IsEmpty() )
{
wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
return;
}
name = dlg.GetName();
name.Replace( " ", "_" );
wxString lib = GetCurLib();
// Test if there a component with this name already.
if( !lib.empty() && Prj().SchSymbolLibTable()->LoadSymbol( lib, name ) != NULL )
{
wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
name, lib );
DisplayError( this, msg );
return;
}
LIB_PART* new_part = new LIB_PART( name );
SetCurPart( new_part );
m_aliasName = new_part->GetName();
new_part->GetReferenceField().SetText( dlg.GetReference() );
new_part->SetUnitCount( dlg.GetUnitCount() );
// Initialize new_part->m_TextInside member:
// if 0, pin text is outside the body (on the pin)
// if > 0, pin text is inside the body
new_part->SetConversion( dlg.GetAlternateBodyStyle() );
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
if( dlg.GetPinNameInside() )
{
new_part->SetPinNameOffset( dlg.GetPinTextPosition() );
if( new_part->GetPinNameOffset() == 0 )
new_part->SetPinNameOffset( 1 );
}
else
{
new_part->SetPinNameOffset( 0 );
}
( dlg.GetPowerSymbol() ) ? new_part->SetPower() : new_part->SetNormal();
new_part->SetShowPinNumbers( dlg.GetShowPinNumber() );
new_part->SetShowPinNames( dlg.GetShowPinName() );
new_part->LockUnits( dlg.GetLockItems() );
if( dlg.GetUnitCount() < 2 )
new_part->LockUnits( false );
m_unit = 1;
m_convert = 1;
DisplayLibInfos();
DisplayCmpDoc();
UpdateAliasSelectList();
UpdatePartSelectList();
m_editPinsPerPartOrConvert = new_part->UnitsLocked() ? true : false;
m_lastDrawItem = NULL;
GetScreen()->ClearUndoRedoList();
OnModify();
m_canvas->Refresh();
m_mainToolBar->Refresh();
}

View File

@ -337,7 +337,14 @@ void AddMenusForBlock( wxMenu* PopMenu, LIB_EDIT_FRAME* frame )
{
AddMenuItem( PopMenu, ID_POPUP_SELECT_ITEMS_BLOCK, _( "Select Items" ),
KiBitmap( green_xpm ) );
AddMenuItem( PopMenu, ID_POPUP_DUPLICATE_BLOCK, _( "Duplicate Block" ), KiBitmap( duplicate_xpm ) );
msg = AddHotkeyName( _( "Cut Block" ), g_Schematic_Hokeys_Descr,
HK_CUT_BLOCK );
AddMenuItem( PopMenu, wxID_CUT, msg, KiBitmap( cut_xpm ) );
msg = AddHotkeyName( _( "Copy Block" ), g_Schematic_Hokeys_Descr,
HK_COPY_BLOCK );
AddMenuItem( PopMenu, wxID_COPY, msg, KiBitmap( copy_xpm ) );
AddMenuItem( PopMenu, ID_POPUP_DUPLICATE_BLOCK, _( "Duplicate Block" ),
KiBitmap( duplicate_xpm ) );
msg = AddHotkeyName( _( "Flip Block Horizonal" ), g_Libedit_Hokeys_Descr, HK_MIRROR_Y );
AddMenuItem( PopMenu, ID_POPUP_MIRROR_Y_BLOCK, msg,
KiBitmap( mirror_h_xpm ) );

View File

@ -107,6 +107,8 @@ void LIB_EDIT_FRAME::GetComponentFromUndoList( wxCommandEvent& event )
delete lastcmd;
part = (LIB_PART*) wrapper.GetItem();
printf("RestoreCopy [%p]\n", part);
// Do not delete the previous part by calling SetCurPart( part ),
// which calls delete <previous part>.
// <previous part> is now put in redo list and is owned by this list.

View File

@ -37,6 +37,7 @@
#include <gr_basic.h>
#include <schframe.h>
#include <msgpanel.h>
#include <confirm.h>
#include <general.h>
#include <eeschema_id.h>
@ -44,6 +45,10 @@
#include <class_library.h>
#include <lib_polyline.h>
#include <lib_pin.h>
#include <lib_manager.h>
#include <widgets/cmp_tree_pane.h>
#include <widgets/component_tree.h>
#include <symbol_lib_table.h>
#include <kicad_device_context.h>
@ -53,17 +58,11 @@
#include <dialogs/dialog_edit_component_in_lib.h>
#include <dialogs/dialog_lib_edit_pin_table.h>
#include <wildcards_and_files_ext.h>
#include <menus_helpers.h>
/* This method guarantees unique IDs for the library this run of Eeschema
* which prevents ID conflicts and eliminates the need to recompile every
* source file in the project when adding IDs to include/id.h. */
int ExportPartId = ::wxNewId();
int ImportPartId = ::wxNewId();
int CreateNewLibAndSavePartId = ::wxNewId();
wxString LIB_EDIT_FRAME:: m_aliasName;
int LIB_EDIT_FRAME:: m_unit = 1;
int LIB_EDIT_FRAME:: m_convert = 1;
@ -88,15 +87,32 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_SIZE( LIB_EDIT_FRAME::OnSize )
EVT_ACTIVATE( LIB_EDIT_FRAME::OnActivate )
// Main horizontal toolbar.
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnSaveActiveLibrary )
EVT_TOOL( ID_LIBEDIT_SELECT_CURRENT_LIB, LIB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_DELETE_PART, LIB_EDIT_FRAME::DeleteOnePart )
EVT_TOOL( ID_TO_LIBVIEW, LIB_EDIT_FRAME::OnOpenLibraryViewer )
EVT_TOOL( ID_LIBEDIT_NEW_PART, LIB_EDIT_FRAME::CreateNewLibraryPart )
EVT_TOOL( ID_LIBEDIT_NEW_PART_FROM_EXISTING, LIB_EDIT_FRAME::OnCreateNewPartFromExisting )
// Library actions
EVT_TOOL( ID_LIBEDIT_NEW_LIBRARY, LIB_EDIT_FRAME::OnCreateNewLibrary )
EVT_TOOL( ID_LIBEDIT_ADD_LIBRARY, LIB_EDIT_FRAME::OnAddLibrary )
EVT_TOOL( ID_LIBEDIT_SAVE_LIBRARY, LIB_EDIT_FRAME::OnSaveLibrary )
EVT_MENU( ID_LIBEDIT_SAVE_LIBRARY_AS, LIB_EDIT_FRAME::OnSaveLibrary )
EVT_MENU( ID_LIBEDIT_SAVE_ALL_LIBS, LIB_EDIT_FRAME::OnSaveAllLibraries )
EVT_TOOL( ID_LIBEDIT_REVERT_LIBRARY, LIB_EDIT_FRAME::OnRevertLibrary )
EVT_TOOL( ID_LIBEDIT_SELECT_PART, LIB_EDIT_FRAME::LoadOneLibraryPart )
// Part actions
EVT_TOOL( ID_LIBEDIT_NEW_PART, LIB_EDIT_FRAME::OnCreateNewPart )
EVT_TOOL( ID_LIBEDIT_EDIT_PART, LIB_EDIT_FRAME::OnEditPart )
EVT_TOOL( ID_LIBEDIT_IMPORT_PART, LIB_EDIT_FRAME::OnImportPart )
EVT_TOOL( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnExportPart )
EVT_TOOL( ID_LIBEDIT_SAVE_PART, LIB_EDIT_FRAME::OnSavePart )
EVT_TOOL( ID_LIBEDIT_REVERT_PART, LIB_EDIT_FRAME::OnRevertPart )
EVT_TOOL( ID_LIBEDIT_REMOVE_PART, LIB_EDIT_FRAME::OnRemovePart )
EVT_TOOL( ID_LIBEDIT_CUT_PART, LIB_EDIT_FRAME::OnCopyCutPart )
EVT_TOOL( ID_LIBEDIT_COPY_PART, LIB_EDIT_FRAME::OnCopyCutPart )
EVT_TOOL( ID_LIBEDIT_PASTE_PART, LIB_EDIT_FRAME::OnPasteDuplicatePart )
EVT_TOOL( ID_LIBEDIT_DUPLICATE_PART, LIB_EDIT_FRAME::OnPasteDuplicatePart )
// Main horizontal toolbar.
EVT_TOOL( ID_TO_LIBVIEW, LIB_EDIT_FRAME::OnOpenLibraryViewer )
EVT_TOOL( wxID_COPY, LIB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_PASTE, LIB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_CUT, LIB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_UNDO, LIB_EDIT_FRAME::GetComponentFromUndoList )
EVT_TOOL( wxID_REDO, LIB_EDIT_FRAME::GetComponentFromRedoList )
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnEditComponentProperties )
@ -107,10 +123,6 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_TOOL( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnViewEntryDoc )
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnOpenPinTable )
EVT_TOOL( ExportPartId, LIB_EDIT_FRAME::OnExportPart )
EVT_TOOL( CreateNewLibAndSavePartId, LIB_EDIT_FRAME::OnExportPart )
EVT_TOOL( ImportPartId, LIB_EDIT_FRAME::OnImportPart )
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_PART, LIB_EDIT_FRAME::OnSaveCurrentPart )
EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectPart )
EVT_COMBOBOX( ID_LIBEDIT_SELECT_ALIAS, LIB_EDIT_FRAME::OnSelectAlias )
@ -123,10 +135,10 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
// Left vertical toolbar (option toolbar).
EVT_TOOL( ID_LIBEDIT_SHOW_ELECTRICAL_TYPE, LIB_EDIT_FRAME::OnShowElectricalType )
EVT_TOOL( ID_LIBEDIT_SHOW_HIDE_SEARCH_TREE, LIB_EDIT_FRAME::OnToggleSearchTree )
// menubar commands
EVT_MENU( wxID_EXIT, LIB_EDIT_FRAME::CloseWindow )
EVT_MENU( ID_LIBEDIT_SAVE_CURRENT_LIB_AS, LIB_EDIT_FRAME::OnSaveActiveLibrary )
EVT_MENU( ID_LIBEDIT_GEN_PNG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
EVT_MENU( ID_LIBEDIT_GEN_SVG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
@ -155,18 +167,21 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_MENU_RANGE( ID_LIBEDIT_MIRROR_X, ID_LIBEDIT_ORIENT_NORMAL,
LIB_EDIT_FRAME::OnOrient )
// Update user interface elements.
EVT_UPDATE_UI( ExportPartId, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( CreateNewLibAndSavePartId, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( wxID_PASTE, LIB_EDIT_FRAME::OnUpdatePaste )
EVT_UPDATE_UI( ID_LIBEDIT_REVERT_LIBRARY, LIB_EDIT_FRAME::OnUpdateLibModified )
EVT_UPDATE_UI( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_PART, LIB_EDIT_FRAME::OnUpdatePartModified )
EVT_UPDATE_UI( ID_LIBEDIT_REVERT_PART, LIB_EDIT_FRAME::OnUpdatePartModified )
EVT_UPDATE_UI( ID_LIBEDIT_PASTE_PART, LIB_EDIT_FRAME::OnUpdateClipboardNotEmpty )
EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_CHECK_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( ID_LIBEDIT_NEW_PART_FROM_EXISTING, LIB_EDIT_FRAME::OnUpdateEditingPart )
EVT_UPDATE_UI( wxID_UNDO, LIB_EDIT_FRAME::OnUpdateUndo )
EVT_UPDATE_UI( wxID_REDO, LIB_EDIT_FRAME::OnUpdateRedo )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnUpdateSaveCurrentLib )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB_AS, LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_LIBRARY, LIB_EDIT_FRAME::OnUpdateSaveLib )
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_LIBRARY_AS, LIB_EDIT_FRAME::OnUpdateSaveLibAs )
EVT_UPDATE_UI( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnUpdateViewDoc )
EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::OnUpdatePinByPin )
EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnUpdatePinTable )
@ -199,6 +214,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_my_part = NULL;
m_tempCopyComponent = NULL;
m_treePane = nullptr;
m_libMgr = nullptr;
// Delayed initialization
if( m_textSize == -1 )
@ -213,7 +230,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
LoadSettings( config() );
SetScreen( new SCH_SCREEN( aKiway ) );
m_dummyScreen = new SCH_SCREEN( aKiway );
SetScreen( m_dummyScreen );
GetScreen()->m_Center = true;
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
@ -233,6 +251,9 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
if( m_canvas )
m_canvas->SetEnableBlockCommands( true );
m_libMgr = new LIB_MANAGER( *this );
m_treePane = new CMP_TREE_PANE( this, m_libMgr );
ReCreateMenuBar();
ReCreateHToolbar();
ReCreateVToolbar();
@ -280,13 +301,16 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
wxAuiPaneInfo( vert ).Name( "m_VToolBar" ).Right() );
m_auimgr.AddPane( m_optionsToolBar,
wxAuiPaneInfo( vert ).Name( "m_optionsToolBar" ).Left() );
wxAuiPaneInfo( vert ).Name( "m_optionsToolBar" ).Left().Row( 0 ) );
m_auimgr.AddPane( m_canvas,
wxAuiPaneInfo().Name( "DrawFrame" ).CentrePane() );
m_auimgr.AddPane( m_messagePanel,
wxAuiPaneInfo( mesg ).Name( "MsgPanel" ).Bottom().Layer(10) );
wxAuiPaneInfo( mesg ).Name( "MsgPanel" ).Bottom().Layer( 10 ) );
m_auimgr.AddPane( m_treePane, wxAuiPaneInfo().Name( "ComponentTree" ).Left().Row( 1 )
.Resizable().MinSize( 250, 400 ).Dock().CloseButton( false ) );
m_auimgr.Update();
@ -306,12 +330,14 @@ LIB_EDIT_FRAME::~LIB_EDIT_FRAME()
Unbind( wxEVT_COMMAND_MENU_SELECTED, &LIB_EDIT_FRAME::OnEditSymbolLibTable, this,
ID_EDIT_SYM_LIB_TABLE );
// current screen is destroyed in EDA_DRAW_FRAME
SetScreen( m_dummyScreen );
m_drawItem = m_lastDrawItem = NULL;
delete m_tempCopyComponent;
delete m_libMgr;
delete m_my_part;
m_my_part = NULL;
m_tempCopyComponent = NULL;
}
@ -323,30 +349,15 @@ void LIB_EDIT_FRAME::SetDrawItem( LIB_ITEM* drawItem )
void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
if( GetScreen()->IsModify() )
if( saveAllLibraries() )
{
int ii = DisplayExitDialog( this, _( "Save the changes in the library before closing?" ) );
switch( ii )
{
case wxID_NO:
break;
case wxID_YES:
if( SaveActiveLibrary( false ) )
break;
// fall through: cancel the close because of an error
case wxID_CANCEL:
Event.Veto();
return;
}
GetScreen()->ClrModify();
saveSymbolLibTables( true, true );
Destroy();
}
else
{
Event.Veto();
}
Destroy();
}
@ -461,6 +472,28 @@ void LIB_EDIT_FRAME::OnShowElectricalType( wxCommandEvent& event )
}
void LIB_EDIT_FRAME::OnToggleSearchTree( wxCommandEvent& event )
{
auto& treePane = m_auimgr.GetPane( m_treePane );
treePane.Show( !IsSearchTreeShown() );
m_auimgr.Update();
}
void LIB_EDIT_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
{
SCH_BASE_FRAME::OnEditSymbolLibTable( aEvent );
m_libMgr->Sync( true );
m_treePane->Refresh();
}
bool LIB_EDIT_FRAME::IsSearchTreeShown()
{
return m_auimgr.GetPane( m_treePane ).IsShown();
}
void LIB_EDIT_FRAME::OnUpdateSelectTool( wxUpdateUIEvent& aEvent )
{
aEvent.Check( GetToolId() == aEvent.GetId() );
@ -475,7 +508,7 @@ void LIB_EDIT_FRAME::OnUpdateElectricalType( wxUpdateUIEvent& aEvent )
void LIB_EDIT_FRAME::OnUpdateEditingPart( wxUpdateUIEvent& aEvent )
{
LIB_PART* part = GetCurPart();
LIB_PART* part = GetCurPart();
aEvent.Enable( part != NULL );
@ -484,9 +517,44 @@ void LIB_EDIT_FRAME::OnUpdateEditingPart( wxUpdateUIEvent& aEvent )
}
void LIB_EDIT_FRAME::OnUpdateNotEditingPart( wxUpdateUIEvent& event )
void LIB_EDIT_FRAME::OnUpdatePartModified( wxUpdateUIEvent& aEvent )
{
event.Enable( !GetCurPart() );
LIB_ID libId = getTargetLibId();
const wxString& partName = libId.GetLibItemName();
const wxString& libName = libId.GetLibNickname();
if( aEvent.GetId() == ID_LIBEDIT_SAVE_PART )
{
bool readOnly = libName.IsEmpty() || m_libMgr->IsLibraryReadOnly( libName );
aEvent.SetText( readOnly ? _( "Save [Read Only]" ) : _( "Save" ) );
aEvent.Enable( !readOnly && !partName.IsEmpty()
&& m_libMgr->IsPartModified( partName, libName ) );
}
else if( aEvent.GetId() == ID_LIBEDIT_REVERT_PART )
{
aEvent.Enable( !partName.IsEmpty() && !libName.IsEmpty()
&& m_libMgr->IsPartModified( partName, libName ) );
}
else wxFAIL;
}
void LIB_EDIT_FRAME::OnUpdatePaste( wxUpdateUIEvent& event )
{
event.Enable( m_clipboard.GetCount() > 0 );
}
void LIB_EDIT_FRAME::OnUpdateLibModified( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( m_libMgr->IsLibraryModified( getTargetLib() ) );
}
void LIB_EDIT_FRAME::OnUpdateClipboardNotEmpty( wxUpdateUIEvent& aEvent )
{
aEvent.Enable( !!m_copiedPart );
}
@ -504,22 +572,21 @@ void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event )
}
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLib( wxUpdateUIEvent& event )
void LIB_EDIT_FRAME::OnUpdateSaveLib( wxUpdateUIEvent& event )
{
wxString lib = GetCurLib();
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
wxString lib = getTargetLib();
bool readOnly = lib.IsEmpty() || m_libMgr->IsLibraryReadOnly( lib );
event.Enable( !lib.empty() && table->HasLibrary( lib ) && table->IsSymbolLibWritable( lib ) &&
GetScreen()->IsModify() );
event.SetText( readOnly ? _( "Save library [Read Only]" ) : _( "Save library" ) );
event.Enable( !readOnly && m_libMgr->IsLibraryModified( lib ) );
}
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs( wxUpdateUIEvent& event )
void LIB_EDIT_FRAME::OnUpdateSaveLibAs( wxUpdateUIEvent& event )
{
wxString lib = GetCurLib();
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
wxString lib = getTargetLib();
event.Enable( !lib.empty() && table->HasLibrary( lib ) );
event.Enable( m_libMgr->LibraryExists( lib ) );
}
@ -676,50 +743,12 @@ void LIB_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event )
}
void LIB_EDIT_FRAME::OnSaveCurrentPart( wxCommandEvent& aEvent )
{
LIB_PART* part = GetCurPart();
if( !part )
{
DisplayError( this, _( "No part to save." ) );
return;
}
wxString libNickname = GetCurLib();
if( libNickname.empty() )
SelectActiveLibrary();
libNickname = GetCurLib();
if( !libNickname )
{
DisplayError( this, _( "No valid library specified." ) );
return;
}
try
{
Prj().SchSymbolLibTable()->SaveSymbol( libNickname, new LIB_PART( *part ) );
}
catch( ... )
{
wxString msg;
msg.Printf( _( "Unexpected error occured saving symbol '%s' to symbol library '%s'." ),
part->GetName(), libNickname );
DisplayError( this, msg );
return;
}
refreshSchematic();
}
void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
int id = event.GetId();
wxPoint pos;
SCH_SCREEN* screen = GetScreen();
BLOCK_SELECTOR& block = screen->m_BlockLocate;
m_canvas->SetIgnoreMouseEvents( true );
@ -728,6 +757,8 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
switch( id ) // Stop placement commands before handling new command.
{
case wxID_COPY:
case wxID_CUT:
case ID_POPUP_LIBEDIT_END_CREATE_ITEM:
case ID_LIBEDIT_EDIT_PIN:
case ID_POPUP_LIBEDIT_BODY_EDIT_ITEM:
@ -770,10 +801,6 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_LIBEDIT_CANCEL_EDITING:
break;
case ID_LIBEDIT_SELECT_CURRENT_LIB:
SelectActiveLibrary();
break;
case ID_LIBEDIT_EDIT_PIN_BY_PIN:
m_editPinsPerPartOrConvert = m_mainToolBar->GetToolToggled( ID_LIBEDIT_EDIT_PIN_BY_PIN );
break;
@ -898,48 +925,48 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_POPUP_ZOOM_BLOCK:
m_canvas->SetAutoPanRequest( false );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
block.SetCommand( BLOCK_ZOOM );
HandleBlockEnd( &dc );
break;
case ID_POPUP_DELETE_BLOCK:
m_canvas->SetAutoPanRequest( false );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
block.SetCommand( BLOCK_DELETE );
m_canvas->MoveCursorToCrossHair();
HandleBlockEnd( &dc );
break;
case ID_POPUP_DUPLICATE_BLOCK:
m_canvas->SetAutoPanRequest( false );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_DUPLICATE );
block.SetCommand( BLOCK_DUPLICATE );
m_canvas->MoveCursorToCrossHair();
HandleBlockEnd( &dc );
break;
case ID_POPUP_SELECT_ITEMS_BLOCK:
m_canvas->SetAutoPanRequest( false );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_SELECT_ITEMS_ONLY );
block.SetCommand( BLOCK_SELECT_ITEMS_ONLY );
m_canvas->MoveCursorToCrossHair();
HandleBlockEnd( &dc );
break;
case ID_POPUP_MIRROR_Y_BLOCK:
m_canvas->SetAutoPanRequest( false );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_Y );
block.SetCommand( BLOCK_MIRROR_Y );
m_canvas->MoveCursorToCrossHair();
HandleBlockPlace( &dc );
break;
case ID_POPUP_MIRROR_X_BLOCK:
m_canvas->SetAutoPanRequest( false );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
block.SetCommand( BLOCK_MIRROR_X );
m_canvas->MoveCursorToCrossHair();
HandleBlockPlace( &dc );
break;
case ID_POPUP_ROTATE_BLOCK:
m_canvas->SetAutoPanRequest( false );
GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
block.SetCommand( BLOCK_ROTATE );
m_canvas->MoveCursorToCrossHair();
HandleBlockPlace( &dc );
break;
@ -950,6 +977,25 @@ void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
HandleBlockPlace( &dc );
break;
case wxID_COPY:
block.SetCommand( BLOCK_COPY );
block.SetMessageBlock( this );
HandleBlockEnd( &dc );
break;
case wxID_PASTE:
HandleBlockBegin( &dc, BLOCK_PASTE, GetCrossHairPosition() );
break;
case wxID_CUT:
if( block.GetCommand() != BLOCK_MOVE )
break;
block.SetCommand( BLOCK_CUT );
block.SetMessageBlock( this );
HandleBlockEnd( &dc );
break;
default:
DisplayError( this, "LIB_EDIT_FRAME::Process_Special_Functions error" );
break;
@ -968,7 +1014,7 @@ void LIB_EDIT_FRAME::OnActivate( wxActivateEvent& event )
}
wxString LIB_EDIT_FRAME::GetCurLib()
wxString LIB_EDIT_FRAME::GetCurLib() const
{
wxString libNickname = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB );
@ -994,23 +1040,31 @@ wxString LIB_EDIT_FRAME::SetCurLib( const wxString& aLibNickname )
else
Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_LIB, aLibNickname );
m_libMgr->SetCurrentLib( aLibNickname );
return old;
}
LIB_PART* LIB_EDIT_FRAME::GetCurPart()
{
return m_my_part;
}
void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
{
delete m_my_part;
m_my_part = aPart; // take ownership here
wxASSERT( m_my_part != aPart );
if( m_my_part != aPart )
{
delete m_my_part;
m_my_part = aPart;
}
// select the current component in the tree widget
if( aPart )
m_treePane->GetCmpTree()->SelectLibId( aPart->GetLibId() );
wxString partName = aPart ? aPart->GetName() : wxString();
m_libMgr->SetCurrentPart( partName );
// retain in case this wxFrame is re-opened later on the same PROJECT
Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, aPart ? aPart->GetName() : wxString() );
Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, partName );
}
@ -1070,6 +1124,7 @@ void LIB_EDIT_FRAME::EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem )
void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
{
bool partLocked = GetCurPart()->UnitsLocked();
wxString oldName = GetCurPart()->GetName();
DIALOG_EDIT_COMPONENT_IN_LIBRARY dlg( this );
@ -1083,6 +1138,8 @@ void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
m_editPinsPerPartOrConvert = GetCurPart()->UnitsLocked() ? true : false;
}
m_libMgr->UpdatePart( GetCurPart(), GetCurLib(), oldName );
UpdateAliasSelectList();
UpdatePartSelectList();
DisplayLibInfos();
@ -1092,22 +1149,6 @@ void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
}
void LIB_EDIT_FRAME::OnCreateNewPartFromExisting( wxCommandEvent& event )
{
LIB_PART* part = GetCurPart();
wxCHECK_RET( part, "Cannot create new part from non-existent current part." );
INSTALL_UNBUFFERED_DC( dc, m_canvas );
m_canvas->CrossHairOff( &dc );
EditField( &part->GetValueField() );
m_canvas->MoveCursorToCrossHair();
m_canvas->CrossHairOn( &dc );
}
void LIB_EDIT_FRAME::OnSelectTool( wxCommandEvent& aEvent )
{
int id = aEvent.GetId();
@ -1402,6 +1443,14 @@ void LIB_EDIT_FRAME::deleteItem( wxDC* aDC )
}
void LIB_EDIT_FRAME::OnModify()
{
GetScreen()->SetModify();
storeCurrentPart();
m_treePane->GetCmpTree()->Refresh();
}
void LIB_EDIT_FRAME::OnSelectItem( wxCommandEvent& aEvent )
{
int id = aEvent.GetId();
@ -1454,3 +1503,159 @@ void LIB_EDIT_FRAME::refreshSchematic()
// in case any symbols have changed.
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_REFRESH, std::string( "" ), this );
}
bool LIB_EDIT_FRAME::addLibraryFile( bool aCreateNew )
{
wxFileName fileName = getLibraryFileName( !aCreateNew );
wxString libName = fileName.GetName();
if( libName.IsEmpty() )
return false;
if( m_libMgr->LibraryExists( libName ) )
{
DisplayError( this,
wxString::Format( _( "Library '%s' already exists" ), GetChars( libName ) ) );
return false;
}
m_libMgr->AddLibrary( fileName.GetFullPath() );
if( aCreateNew )
Prj().SchSymbolLibTable()->CreateSymbolLib( libName );
return true;
}
wxFileName LIB_EDIT_FRAME::getLibraryFileName( bool aExisting )
{
wxFileName fn = m_libMgr->GetUniqueLibraryName();
fn.SetExt( SchematicLibraryFileExtension );
wxFileDialog dlg( this,
aExisting ? _( "Select Library" ) : _( "New Library" ),
Prj().GetProjectPath(),
aExisting ? wxString( wxEmptyString ) : fn.GetFullName() ,
SchematicLibraryFileWildcard(),
aExisting ? wxFD_OPEN | wxFD_FILE_MUST_EXIST :
wxFD_SAVE | wxFD_CHANGE_DIR | wxFD_OVERWRITE_PROMPT );
if( dlg.ShowModal() == wxID_CANCEL )
return wxFileName();
fn = dlg.GetPath();
fn.SetExt( SchematicLibraryFileExtension );
return fn;
}
LIB_PART* LIB_EDIT_FRAME::getTargetPart() const
{
LIB_ALIAS* alias = nullptr;
if( m_treePane->GetCmpTree()->IsMenuActive() )
{
LIB_ID libId = m_treePane->GetCmpTree()->GetSelectedLibId();
alias = m_libMgr->GetAlias( libId.GetLibItemName(), libId.GetLibNickname() );
}
else if( LIB_PART* part = GetCurPart() )
{
alias = part->GetAlias( 0 );
}
return alias ? alias->GetPart() : nullptr;
}
LIB_ID LIB_EDIT_FRAME::getTargetLibId() const
{
if( m_treePane->GetCmpTree()->IsMenuActive() )
return m_treePane->GetCmpTree()->GetSelectedLibId();
if( LIB_PART* part = GetCurPart() )
return part->GetLibId();
return LIB_ID();
}
wxString LIB_EDIT_FRAME::getTargetLib() const
{
if( m_treePane->GetCmpTree()->IsMenuActive() )
{
LIB_ID libId = m_treePane->GetCmpTree()->GetSelectedLibId();
return libId.GetLibNickname();
}
else
{
return GetCurLib();
}
}
SYMBOL_LIB_TABLE* LIB_EDIT_FRAME::SelectSymLibTable()
{
wxArrayString libTableNames;
libTableNames.Add( _( "Global" ) );
libTableNames.Add( _( "Project" ) );
switch( SelectSingleOption( this, _( "Select Symbol Library Table" ),
_( "Choose the Library Table to add the library:" ), libTableNames ) )
{
case 0: return &SYMBOL_LIB_TABLE::GetGlobalLibTable();
case 1: return Prj().SchSymbolLibTable();
}
return nullptr;
}
bool LIB_EDIT_FRAME::backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt )
{
if( aOriginalFile.FileExists() )
{
wxFileName backupFileName( aOriginalFile );
backupFileName.SetExt( "bck" );
if( backupFileName.FileExists() )
wxRemoveFile( backupFileName.GetFullPath() );
if( !wxCopyFile( aOriginalFile.GetFullPath(), backupFileName.GetFullPath() ) )
{
DisplayError( this, _( "Failed to save backup document to file " ) +
backupFileName.GetFullPath() );
return false;
}
}
return true;
}
void LIB_EDIT_FRAME::storeCurrentPart()
{
if( m_my_part && !GetCurLib().IsEmpty() && GetScreen()->IsModify() )
m_libMgr->UpdatePart( m_my_part, GetCurLib() ); // UpdatePart() makes a copy
}
bool LIB_EDIT_FRAME::isCurrentPart( const LIB_ID& aLibId ) const
{
return ( GetCurPart() && aLibId == GetCurPart()->GetLibId() );
}
void LIB_EDIT_FRAME::emptyScreen()
{
SetCurLib( wxEmptyString );
SetCurPart( nullptr );
m_aliasName.Empty();
m_drawItem = m_lastDrawItem = nullptr;
SetScreen( m_dummyScreen );
m_dummyScreen->ClearUndoRedoList();
Zoom_Automatique( false );
Refresh();
}

View File

@ -4,6 +4,8 @@
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -37,13 +39,17 @@
#include <lib_draw_item.h>
#include <lib_collectors.h>
#include <core/optional.h>
class SCH_EDIT_FRAME;
class SYMBOL_LIB_TABLE;
class LIB_PART;
class LIB_ALIAS;
class LIB_FIELD;
class DIALOG_LIB_EDIT_TEXT;
class CMP_TREE_PANE;
class LIB_ID;
class LIB_MANAGER;
/**
@ -56,6 +62,8 @@ class LIB_EDIT_FRAME : public SCH_BASE_FRAME
LIB_COLLECTOR m_collectedItems; ///< Used for hit testing.
wxComboBox* m_partSelectBox; ///< a Box to select a part to edit (if any)
wxComboBox* m_aliasSelectBox; ///< a box to select the alias to edit (if any)
CMP_TREE_PANE* m_treePane; ///< component search tree widget
LIB_MANAGER* m_libMgr; ///< manager taking care of temporary modificatoins
/** Convert of the item currently being drawn. */
bool m_drawSpecificConvert;
@ -137,7 +145,7 @@ public:
~LIB_EDIT_FRAME();
/** The nickname of the current library being edited and empty string if none. */
wxString GetCurLib();
wxString GetCurLib() const;
/** Sets the current library nickname and returns the old library nickname. */
wxString SetCurLib( const wxString& aLibNickname );
@ -147,7 +155,10 @@ public:
*
* This is a LIB_PART that I own, it is at best a copy of one in a library.
*/
LIB_PART* GetCurPart();
LIB_PART* GetCurPart() const
{
return m_my_part;
}
/**
* Take ownership of aPart and notes that it is the one currently being edited.
@ -204,6 +215,50 @@ public:
void Process_Special_Functions( wxCommandEvent& event );
void OnSelectTool( wxCommandEvent& aEvent );
/**
* Creates a new library. The library is added to the project libraries table.
*/
void OnCreateNewLibrary( wxCommandEvent& aEvent )
{
addLibraryFile( true );
}
/**
* Adds an existing library. The library is added to the project libraries table.
*/
void OnAddLibrary( wxCommandEvent& aEvent )
{
addLibraryFile( false );
}
/**
* The command event handler to save the changes to the current library.
*
* A backup file of the current library is saved with the .bak extension before the
* changes made to the library are saved.
*/
void OnSaveLibrary( wxCommandEvent& event );
/**
* Saves all changes in modified libraries.
*/
void OnSaveAllLibraries( wxCommandEvent& event );
/**
* Reverts unsaved changes in a library.
*/
void OnRevertLibrary( wxCommandEvent& aEvent );
/**
* Creates a new part in the selected library.
*/
void OnCreateNewPart( wxCommandEvent& aEvent );
/**
* Opens the selected part for editing.
*/
void OnEditPart( wxCommandEvent& aEvent );
/**
* Routine to read one part.
* The format is that of libraries, but it loads only 1 component.
@ -213,11 +268,30 @@ public:
void OnImportPart( wxCommandEvent& event );
/**
* Function OnExportPart
* creates a new library and backup the current component in this library or export
* Creates a new library and backup the current component in this library or exports
* the component of the current library.
*/
void OnExportPart( wxCommandEvent& event );
/**
* Saves a single part in the selected library. The library file is updated without including
* the remaining unsaved changes.
*/
void OnSavePart( wxCommandEvent& aEvent );
/**
* Reverts unsaved changes in a part, restoring to the last saved state.
*/
void OnRevertPart( wxCommandEvent& aEvent );
/**
* Removes a part from the working copy of a library.
*/
void OnRemovePart( wxCommandEvent& aEvent );
void OnCopyCutPart( wxCommandEvent& aEvent );
void OnPasteDuplicatePart( wxCommandEvent& aEvent );
void OnSelectAlias( wxCommandEvent& event );
void OnSelectPart( wxCommandEvent& event );
@ -226,39 +300,14 @@ public:
*/
void OnShowElectricalType( wxCommandEvent& event );
/**
* Delete a symbol from the current library.
*
* The deleted entry can be an alias or a component. If the entry is an alias,
* it is removed from the component and the list of alias is updated. If the
* entry is a component and the list of aliases is empty, the component and all
* it drawable items are deleted. Otherwise the first alias in the alias list
* becomes the new component name and the other aliases become dependent on
* renamed component.
*
* @note This only deletes the entry in memory. The file does not change.
*/
void DeleteOnePart( wxCommandEvent& event );
void OnToggleSearchTree( wxCommandEvent& event );
/**
* Create a new library symbol.
*
* If an old component is currently in edit, it is deleted.
*/
void CreateNewLibraryPart( wxCommandEvent& event );
void OnEditSymbolLibTable( wxCommandEvent& aEvent ) override;
bool IsSearchTreeShown();
void OnCreateNewPartFromExisting( wxCommandEvent& event );
void OnEditComponentProperties( wxCommandEvent& event );
void InstallFieldsEditorDialog( wxCommandEvent& event );
/**
* Loads a symbol from the currently selected library.
*
* If a library is already selected, the user is prompted for the component name
* to load. If there is no current selected library, the user is prompted to select
* a library name and then select component to load.
*/
void LoadOneLibraryPart( wxCommandEvent& event );
void InstallFieldsEditorDialog( wxCommandEvent& event );
void OnViewEntryDoc( wxCommandEvent& event );
void OnCheckComponent( wxCommandEvent& event );
@ -268,15 +317,16 @@ public:
void OnOpenPinTable( wxCommandEvent& aEvent );
void OnSaveCurrentPart( wxCommandEvent& aEvent );
void OnUpdatePaste( wxUpdateUIEvent& event );
void OnUpdateSelectTool( wxUpdateUIEvent& aEvent );
void OnUpdateEditingPart( wxUpdateUIEvent& event );
void OnUpdateNotEditingPart( wxUpdateUIEvent& event );
void OnUpdatePartModified( wxUpdateUIEvent& aEvent );
void OnUpdateLibModified( wxUpdateUIEvent& aEvent );
void OnUpdateClipboardNotEmpty( wxUpdateUIEvent& aEvent );
void OnUpdateUndo( wxUpdateUIEvent& event );
void OnUpdateRedo( wxUpdateUIEvent& event );
void OnUpdateSaveCurrentLib( wxUpdateUIEvent& event );
void OnUpdateSaveCurrentLibAs( wxUpdateUIEvent& event );
void OnUpdateSaveLib( wxUpdateUIEvent& event );
void OnUpdateSaveLibAs( wxUpdateUIEvent& event );
void OnUpdateViewDoc( wxUpdateUIEvent& event );
void OnUpdatePinByPin( wxUpdateUIEvent& event );
void OnUpdatePinTable( wxUpdateUIEvent& event );
@ -349,10 +399,7 @@ public:
* Must be called after a schematic change in order to set the "modify" flag of the
* current screen.
*/
void OnModify()
{
GetScreen()->SetModify();
}
void OnModify();
const wxString& GetAliasName() { return m_aliasName; }
@ -419,6 +466,18 @@ public:
bool IsEditingDrawItem() { return m_drawItem && m_drawItem->InEditMode(); }
private:
void loadPart( const wxString& aLibrary, const wxString& aPart, int Unit );
/**
* Saves the changes to the current library.
*
* A backup file of the current library is saved with the .bak extension before the
* changes made to the library are saved.
* @param aLibrary is the library name.
* @param aNewFile Ask for a new file name to save the library.
* @return True if the library was successfully saved.
*/
bool saveLibrary( const wxString& aLibrary, bool aNewFile );
/**
* Called when the frame is activated. Tests if the current library exists.
@ -437,24 +496,6 @@ private:
*/
void SelectActiveLibrary( const wxString& aLibrary = wxEmptyString );
/**
* The command event handler to save the changes to the current library.
*
* A backup file of the current library is saved with the .bak extension before the
* changes made to the library are saved.
*/
void OnSaveActiveLibrary( wxCommandEvent& event );
/**
* Saves the changes to the current library.
*
* A backup file of the current library is saved with the .bak extension before the
* changes made to the library are saved.
* @param newFile Ask for a new file name to save the library.
* @return True if the library was successfully saved.
*/
bool SaveActiveLibrary( bool newFile );
/**
* Loads a symbol from the current active library, optionally setting the selected
* unit and convert.
@ -645,6 +686,71 @@ public:
*/
void SVG_PlotComponent( const wxString& aFullFileName );
/**
* Displays a dialog asking the user to select a symbol library table.
* @return Pointer to the selected symbol library table or nullptr if cancelled.
*/
SYMBOL_LIB_TABLE* SelectSymLibTable();
private:
///> Helper screen used when no part is loaded
SCH_SCREEN* m_dummyScreen;
///> Creates a backup copy of a file with requested extension
bool backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt );
///> Returns currently edited part.
LIB_PART* getTargetPart() const;
///> Returns either the part selected in the component tree, if context menu is active
///> or the currently modified part.
LIB_ID getTargetLibId() const;
///> Returns either the library selected in the component tree, if context menu is active
///> or the library that is currently modified.
wxString getTargetLib() const;
///> Returns true when the operation has succeded (all requested libraries have been saved or
///> none was selected and confirmed by OK).
bool saveAllLibraries();
///> Creates or adds an existing library to the symbol library table.
bool addLibraryFile( bool aCreateNew );
///> Displays a file browser dialog to select a library file.
wxFileName getLibraryFileName( bool aExisting );
///> Stores the currently modified part in the library manager buffer.
void storeCurrentPart();
///> Returns true if currently modified part has the same LIB_ID.
bool isCurrentPart( const LIB_ID& aLibId ) const;
///> Restores the empty editor screen, without any part or library selected.
void emptyScreen();
///> Renames LIB_PART aliases to avoid conflicts before adding a component to a library
void fixDuplicateAliases( LIB_PART* aPart, const wxString& aLibrary );
void InitBlockPasteInfos() override;
/**
* Copies items selected in the current part to the internal clipboard.
*/
void copySelectedItems();
/**
* Pastes items from the internal clipboard to the current part.
* @param aOffset is the offset where the pasted items should be located.
*/
void pasteClipboard( const wxPoint& aOffset );
///> Clipboard buffer storing LIB_ITEMs
BLOCK_SELECTOR m_clipboard;
// Copy/cut/paste buffer to move parts between libraries
std::unique_ptr<LIB_PART> m_copiedPart;
DECLARE_EVENT_TABLE()
};

View File

@ -35,6 +35,7 @@
#include <symbol_lib_table.h>
#include <template_fieldnames.h>
#include <dialog_edit_one_field.h>
#include <lib_manager.h>
void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
@ -42,14 +43,12 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
wxString newFieldValue;
wxString title;
wxString caption;
wxString oldName;
if( aField == NULL )
return;
LIB_PART* parent = aField->GetParent();
wxASSERT( parent );
wxCHECK( parent, /* void */ );
// Editing the component value field is equivalent to creating a new component based
// on the current component. Set the dialog message to inform the user.
@ -75,17 +74,19 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
newFieldValue = dlg.GetText();
wxString fieldText = aField->GetFullText( m_unit );
bool creatingNewComponent = aField->GetId() == VALUE && newFieldValue != aField->GetText();
/* If the value field is changed, this is equivalent to creating a new component from
* the old one. Rename the component and remove any conflicting aliases to prevent name
* errors when updating the library.
*/
if( aField->GetId() == VALUE && newFieldValue != aField->GetText() )
if( creatingNewComponent )
{
wxString msg;
wxString lib = GetCurLib();
// Test the current library for name conflicts.
if( !lib.empty() && Prj().SchSymbolLibTable()->LoadSymbol( lib, newFieldValue ) )
if( !lib.empty() && m_libMgr->PartExists( newFieldValue, lib ) )
{
msg.Printf( _(
"The name '%s' conflicts with an existing entry in the component library '%s'.\n\n"
@ -124,7 +125,7 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
bool conflicts = false;
wxArrayString libAliasNames, symbolAliasNames;
Prj().SchSymbolLibTable()->EnumerateSymbolLib( lib, libAliasNames );
libAliasNames = m_libMgr->GetAliasNames( lib );
symbolAliasNames = parent->GetAliasNames();
for( size_t i = 0; i < symbolAliasNames.GetCount(); i++ )
@ -156,7 +157,7 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
for( size_t i = 0; i < aliases.GetCount(); i++ )
{
if( Prj().SchSymbolLibTable()->LoadSymbol( lib, aliases[ i ] ) != NULL )
if( m_libMgr->GetAlias( aliases[i], lib ) != NULL )
parent->RemoveAlias( aliases[ i ] );
}
}
@ -164,13 +165,18 @@ void LIB_EDIT_FRAME::EditField( LIB_FIELD* aField )
if( !parent->HasAlias( m_aliasName ) )
m_aliasName = newFieldValue;
//m_libMgr->RemovePart( fieldText, lib );
m_libMgr->UpdatePart( parent, lib, fieldText );
}
if( !aField->InEditMode() && !creatingNewComponent )
{
SaveCopyInUndoList( parent );
}
dlg.UpdateField( aField );
if( !aField->InEditMode() )
SaveCopyInUndoList( parent );
m_canvas->Refresh();
OnModify();

View File

@ -0,0 +1,81 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef LIST_OPERATIONS_H
#define LIST_OPERATIONS_H
namespace KIGFX {
class COLOR4D;
}
class wxPoint;
class wxDC;
class EDA_DRAW_PANEL;
class SCH_ITEM;
class SCH_SCREEN;
class PICKED_ITEMS_LIST;
void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen );
void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, const wxPoint& rotationPoint );
void MirrorY( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint );
void MirrorX( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint );
/**
* Function MoveItemsInList
* Move a list of items to a given move vector
* @param aItemsList = list of picked items
* @param aMoveVector = the move vector value
*/
void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector );
/**
* Function DeleteItemsInList
* delete schematic items in aItemsList
* deleted items are put in undo list
*/
void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList );
/**
* Routine to copy a new entity of an object for each object in list and
* reposition it.
* Return the new created object list in aItemsList
*/
void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
const wxPoint& aMoveVector );
/**
* Routine to create a new copy of given struct.
* The new object is not put in draw list (not linked)
*
* @param aDrawStruct = the SCH_ITEM to duplicate
* @param aClone (default = false)
* if true duplicate also some parameters that must be unique
* (timestamp and sheet name)
* aClone must be false. use true only is undo/redo duplications
*/
SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone = false );
void DrawDanglingSymbol( EDA_DRAW_PANEL* panel, wxDC* DC,
const wxPoint& pos, const KIGFX::COLOR4D& Color );
#endif /* LIST_OPERATIONS_H */

View File

@ -25,7 +25,7 @@
/**
* @file eeschema/menubar_libedit.cpp
* @brief (Re)Create the main menubar for the component editor frame (LibEdit)
* @brief (Re)Create the main menubar for the part editor frame (LibEdit)
*/
#include <menus_helpers.h>
@ -37,11 +37,9 @@
#include "hotkeys.h"
#include "libeditframe.h"
extern int CreateNewLibAndSavePartId;
/**
* @brief (Re)Create the menubar for the component editor frame
* @brief (Re)Create the menubar for the part editor frame
*/
void LIB_EDIT_FRAME::ReCreateMenuBar()
{
@ -64,33 +62,40 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
// Menu File:
wxMenu* fileMenu = new wxMenu;
// Select current library
// Creating/loading libraries
AddMenuItem( fileMenu,
ID_LIBEDIT_SELECT_CURRENT_LIB,
_( "Select &Current Library" ),
_( "Select working library" ),
KiBitmap( library_xpm ) );
ID_LIBEDIT_NEW_LIBRARY,
_( "&Create New Library" ),
_( "Creates an empty library" ),
KiBitmap( new_library_xpm ) );
AddMenuItem( fileMenu,
ID_LIBEDIT_ADD_LIBRARY,
_( "&Add Existing Library" ),
_( "Adds a previously created library" ),
KiBitmap( add_library_xpm ) );
// Separator
fileMenu->AppendSeparator();
// Save current library
text = AddHotkeyName( _( "&Save Current Library" ), g_Libedit_Hokeys_Descr, HK_SAVE_LIB );
// Save library variants
text = AddHotkeyName( _( "&Save Library" ), g_Libedit_Hokeys_Descr, HK_SAVE_LIB );
AddMenuItem( fileMenu,
ID_LIBEDIT_SAVE_CURRENT_LIB, text,
ID_LIBEDIT_SAVE_LIBRARY, text,
_( "Save the current active library" ),
KiBitmap( save_xpm ) );
KiBitmap( save_library_xpm ) );
// Save current library as...
AddMenuItem( fileMenu,
ID_LIBEDIT_SAVE_CURRENT_LIB_AS,
_( "Save Current Library &As..." ),
_( "Save current active library as..." ),
ID_LIBEDIT_SAVE_LIBRARY_AS,
_( "&Save Library As.." ),
_( "Save the current library to a new file" ),
KiBitmap( save_as_xpm ) );
AddMenuItem( fileMenu,
CreateNewLibAndSavePartId,
_( "Create &New Library and Save Current Component" ),
_( "Save current component to new library" ),
KiBitmap( new_library_xpm ) );
ID_LIBEDIT_SAVE_ALL_LIBS,
_( "&Save All Libraries" ),
_( "Save all library changes" ),
KiBitmap( save_xpm ) );
// Separator
fileMenu->AppendSeparator();
@ -99,14 +104,14 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
AddMenuItem( fileMenu,
ID_LIBEDIT_GEN_PNG_FILE,
_( "Create &PNG File from Screen..." ),
_( "Create a PNG file from the component displayed on screen" ),
_( "Create a PNG file from the part displayed on screen" ),
KiBitmap( plot_xpm ) );
// Export as SVG file
AddMenuItem( fileMenu,
ID_LIBEDIT_GEN_SVG_FILE,
_( "Create S&VG File..." ),
_( "Create a SVG file from the current loaded component" ),
_( "Create a SVG file from the current loaded part" ),
KiBitmap( plot_svg_xpm ) );
// Separator
@ -139,16 +144,6 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
_( "Redo the last undo command" ),
KiBitmap( redo_xpm ) );
// Separator
editMenu->AppendSeparator();
// Delete
AddMenuItem( editMenu,
ID_LIBEDIT_DELETE_ITEM_BUTT,
_( "&Delete" ),
HELP_DELETE_ITEMS,
KiBitmap( delete_xpm ) );
// Menu View:
wxMenu* viewMenu = new wxMenu;
@ -177,13 +172,77 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
text = AddHotkeyName( _( "&Fit on Screen" ), g_Libedit_Hokeys_Descr, HK_ZOOM_AUTO );
AddMenuItem( viewMenu, ID_ZOOM_PAGE, text, HELP_ZOOM_FIT, KiBitmap( zoom_fit_in_page_xpm ) );
// Separator
viewMenu->AppendSeparator();
// Redraw
text = AddHotkeyName( _( "&Redraw" ), g_Libedit_Hokeys_Descr, HK_ZOOM_REDRAW );
AddMenuItem( viewMenu, ID_ZOOM_REDRAW, text, HELP_ZOOM_REDRAW, KiBitmap( zoom_redraw_xpm ) );
// Separator
viewMenu->AppendSeparator();
AddMenuItem( viewMenu,
ID_LIBEDIT_SHOW_HIDE_SEARCH_TREE,
_( "&Search tree" ),
_( "Toggles the search tree visibility" ),
KiBitmap( search_tree_xpm ) );
// Menu Part:
wxMenu* partMenu = new wxMenu;
AddMenuItem( partMenu,
ID_LIBEDIT_NEW_PART,
_( "Create &New" ),
_( "Create a new empty part" ),
KiBitmap( new_component_xpm ) );
text = AddHotkeyName( _( "&Save Part" ), g_Libedit_Hokeys_Descr, HK_SAVE_PART );
AddMenuItem( partMenu,
ID_LIBEDIT_SAVE_PART,
text,
_( "Saves the current part to the library" ),
KiBitmap( save_part_xpm ) );
partMenu->AppendSeparator();
AddMenuItem( partMenu,
ID_LIBEDIT_IMPORT_PART,
_( "&Import" ),
_( "Import a part to the current library" ),
KiBitmap( import_part_xpm ) );
AddMenuItem( partMenu,
ID_LIBEDIT_EXPORT_PART,
_( "&Export" ),
_( "Export the current part" ),
KiBitmap( export_part_xpm ) );
partMenu->AppendSeparator();
AddMenuItem( partMenu,
ID_LIBEDIT_GET_FRAME_EDIT_PART,
_( "&Properties" ),
_( "Edit part properties" ),
KiBitmap( part_properties_xpm ) );
AddMenuItem( partMenu,
ID_LIBEDIT_GET_FRAME_EDIT_FIELDS,
_( "&Fields" ),
_( "Edit field properties" ),
KiBitmap( edit_text_xpm ) );
partMenu->AppendSeparator();
AddMenuItem( partMenu,
ID_LIBEDIT_EDIT_PIN_BY_TABLE,
_( "Pi&n Table" ),
_( "Show pin table" ),
KiBitmap( pin_table_xpm ) );
AddMenuItem( partMenu,
ID_LIBEDIT_CHECK_PART,
_( "ERC" ),
_( "Check duplicate and off grid pins" ),
KiBitmap( erc_xpm ) );
// Menu Place:
wxMenu* placeMenu = new wxMenu;
@ -243,7 +302,7 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
AddMenuItem( preferencesMenu,
wxID_PREFERENCES,
_( "General &Options" ),
_( "Set Component Editor default values and options" ),
_( "Set Part Editor default values and options" ),
KiBitmap( preference_xpm ) );
// Language submenu
@ -293,6 +352,7 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
menuBar->Append( fileMenu, _( "&File" ) );
menuBar->Append( editMenu, _( "&Edit" ) );
menuBar->Append( viewMenu, _( "&View" ) );
menuBar->Append( partMenu, _( "&Part" ) );
menuBar->Append( placeMenu, _( "&Place" ) );
menuBar->Append( preferencesMenu, _( "P&references" ) );
menuBar->Append( helpMenu, _( "&Help" ) );

View File

@ -34,7 +34,7 @@
#include <schframe.h>
#include <general.h>
#include <protos.h>
#include <list_operations.h>
#include <sch_bus_entry.h>
#include <sch_marker.h>
#include <sch_line.h>
@ -72,7 +72,7 @@ void SetSchItemParent( SCH_ITEM* Struct, SCH_SCREEN* Screen )
}
void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& rotationPoint )
void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, const wxPoint& rotationPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
@ -83,7 +83,7 @@ void RotateListOfItems( PICKED_ITEMS_LIST& aItemsList, wxPoint& rotationPoint )
}
void MirrorY( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
void MirrorY( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
@ -94,7 +94,7 @@ void MirrorY( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
}
void MirrorX( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
void MirrorX( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMirrorPoint )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
@ -105,13 +105,7 @@ void MirrorX( PICKED_ITEMS_LIST& aItemsList, wxPoint& aMirrorPoint )
}
/**
* Function MoveItemsInList
* Move a list of items to a given move vector
* @param aItemsList = list of picked items
* @param aMoveVector = the move vector value
*/
void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector )
void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint& aMoveVector )
{
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
{
@ -121,11 +115,6 @@ void MoveItemsInList( PICKED_ITEMS_LIST& aItemsList, const wxPoint aMoveVector )
}
/**
* Function DeleteItemsInList
* delete schematic items in aItemsList
* deleted items are put in undo list
*/
void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList )
{
SCH_SCREEN* screen = (SCH_SCREEN*) panel->GetScreen();
@ -182,12 +171,8 @@ void SCH_EDIT_FRAME::DeleteItem( SCH_ITEM* aItem )
}
/* Routine to copy a new entity of an object for each object in list and
* reposition it.
* Return the new created object list in aItemsList
*/
void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
const wxPoint aMoveVector )
const wxPoint& aMoveVector )
{
SCH_ITEM* newitem;
@ -238,16 +223,6 @@ void DuplicateItemsInList( SCH_SCREEN* screen, PICKED_ITEMS_LIST& aItemsList,
}
/**
* Function DuplicateStruct
* Routine to create a new copy of given struct.
* The new object is not put in draw list (not linked)
* @param aDrawStruct = the SCH_ITEM to duplicate
* @param aClone (default = false)
* if true duplicate also some parameters that must be unique
* (timestamp and sheet name)
* aClone must be false. use true only is undo/redo duplications
*/
SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone )
{
wxCHECK_MSG( aDrawStruct != NULL, NULL,

View File

@ -286,7 +286,6 @@ void LIB_EDIT_FRAME::PlacePin()
SaveCopyInUndoList( part );
m_canvas->SetMouseCapture( NULL, NULL );
OnModify();
cur_pin->Move( newpos );
if( cur_pin->IsNew() )
@ -314,6 +313,7 @@ void LIB_EDIT_FRAME::PlacePin()
m_drawItem = NULL;
OnModify();
m_canvas->Refresh();
}

View File

@ -409,7 +409,6 @@ wxString RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::GetActionDescription() const
bool RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::PerformAction( RESCUER* aRescuer )
{
LIB_PART new_part( *m_cache_candidate );
new_part.SetLibId( m_new_id );
new_part.SetName( m_new_id.GetLibItemName() );
new_part.RemoveAllAliases();
aRescuer->AddPart( &new_part );

View File

@ -309,7 +309,6 @@ class LEGACY_RESCUER : public RESCUER
{
private:
std::unique_ptr<PART_LIB> m_rescue_lib;
PART_LIBS* m_libs;
public:
LEGACY_RESCUER( SCH_EDIT_FRAME& aEditFrame, PROJECT& aProject ) :

View File

@ -1,56 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2014 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __PROTOS_H__
#define __PROTOS_H__
class EDA_DRAW_PANEL;
class PICKED_ITEMS_LIST;
class SCH_ITEM;
// operations_on_item_lists.cpp
void DeleteItemsInList( EDA_DRAW_PANEL* panel, PICKED_ITEMS_LIST& aItemsList );
/**
* Function DuplicateStruct
* creates a new copy of given struct.
* @param aDrawStruct = the SCH_ITEM to duplicate
* @param aClone (defualt = true)
* if true duplicate also some parameters that must be unique
* (timestamp and sheet name)
* aClone must be false. use true only is undo/redo duplications
*/
SCH_ITEM* DuplicateStruct( SCH_ITEM* DrawStruct, bool aClone = false );
/****************/
/* EEREDRAW.CPP */
/****************/
void DrawDanglingSymbol( EDA_DRAW_PANEL* panel, wxDC* DC,
const wxPoint& pos, COLOR4D Color );
#endif /* __PROTOS_H__ */

View File

@ -268,37 +268,7 @@ void SCH_BASE_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
if( dlg.ShowModal() == wxID_CANCEL )
return;
try
{
FILE_OUTPUTFORMATTER sf( SYMBOL_LIB_TABLE::GetGlobalTableFileName() );
SYMBOL_LIB_TABLE::GetGlobalLibTable().Format( &sf, 0 );
}
catch( const IO_ERROR& ioe )
{
wxString msg = wxString::Format( _( "Error occurred saving the global symbol library "
"table:\n\n%s" ),
GetChars( ioe.What().GetData() ) );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
if( !Prj().GetProjectName().IsEmpty() )
{
wxFileName fn( Prj().GetProjectPath(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
try
{
Prj().SchSymbolLibTable()->Save( fn.GetFullPath() );
}
catch( const IO_ERROR& ioe )
{
wxString msg = wxString::Format( _( "Error occurred saving project specific "
"symbol library table:\n\n%s" ),
GetChars( ioe.What() ) );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
saveSymbolLibTables( true, true );
LIB_EDIT_FRAME* editor = (LIB_EDIT_FRAME*) Kiway().Player( FRAME_SCH_LIB_EDITOR, false );
@ -335,3 +305,47 @@ LIB_PART* SCH_BASE_FRAME::GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib, b
return SchGetLibPart( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowErrorMsg );
}
bool SCH_BASE_FRAME::saveSymbolLibTables( bool aGlobal, bool aProject )
{
bool success = true;
if( aGlobal )
{
try
{
FILE_OUTPUTFORMATTER sf( SYMBOL_LIB_TABLE::GetGlobalTableFileName() );
SYMBOL_LIB_TABLE::GetGlobalLibTable().Format( &sf, 0 );
}
catch( const IO_ERROR& ioe )
{
success = false;
wxString msg = wxString::Format( _( "Error occurred saving the global symbol library "
"table:\n\n%s" ),
GetChars( ioe.What().GetData() ) );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
if( aProject && !Prj().GetProjectName().IsEmpty() )
{
wxFileName fn( Prj().GetProjectPath(), SYMBOL_LIB_TABLE::GetSymbolLibTableFileName() );
try
{
Prj().SchSymbolLibTable()->Save( fn.GetFullPath() );
}
catch( const IO_ERROR& ioe )
{
success = false;
wxString msg = wxString::Format( _( "Error occurred saving project specific "
"symbol library table:\n\n%s" ),
GetChars( ioe.What() ) );
wxMessageBox( msg, _( "File Save Error" ), wxOK | wxICON_ERROR );
}
}
return success;
}

View File

@ -201,7 +201,7 @@ public:
const LIB_ID* aHighlight = nullptr,
bool aAllowFields = true );
void OnEditSymbolLibTable( wxCommandEvent& aEvent );
virtual void OnEditSymbolLibTable( wxCommandEvent& aEvent );
/**
* Load symbol from symbol library table.
@ -281,6 +281,15 @@ protected:
* false on cancel
*/
bool SelectPartNameToLoad( wxString& aLibrary, wxString& aBufName );
/**
* Saves Symbol Library Tables to disk.
*
* @param aGlobal when true, the Global Table is saved.
* @param aProject when true, the Project Table is saved.
* @return True when all requested actions succeeded.
*/
bool saveSymbolLibTables( bool aGlobal, bool aProject );
};
#endif // SCH_BASE_FRAME_H_

View File

@ -2476,30 +2476,22 @@ LIB_PART* SCH_LEGACY_PLUGIN_CACHE::loadPart( FILE_LINE_READER& aReader )
part->SetUnitCount( 1 );
// Copy part name and prefix.
LIB_FIELD& value = part->GetValueField();
// The root alias is added to the alias list by SetName() which is called by SetText().
if( name.IsEmpty() )
{
part->m_name = "~";
value.SetText( "~" );
part->SetName( "~" );
}
else if( name[0] != '~' )
{
part->m_name = name;
value.SetText( name );
part->SetName( name );
}
else
{
name = name.Right( name.Length() - 1 );
part->m_name = name;
value.SetText( name );
value.SetVisible( false );
part->SetName( name.Right( name.Length() - 1 ) );
part->GetValueField().SetVisible( false );
}
// Don't set the library alias, this is determined by the symbol library table.
part->SetLibId( LIB_ID( wxEmptyString, part->GetName() ) );
// There are some code paths in SetText() that do not set the root alias to the
// alias list so add it here if it didn't get added by SetText().
if( !part->HasAlias( part->GetName() ) )
@ -2766,7 +2758,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadField( std::unique_ptr< LIB_PART >& aPart,
// Ensure the VALUE field = the part name (can be not the case
// with malformed libraries: edited by hand, or converted from other tools)
if( fixedField->GetId() == VALUE )
fixedField->m_Text = aPart->m_name;
fixedField->m_Text = aPart->GetName();
}
else
{

View File

@ -35,7 +35,7 @@
#include <base_units.h>
#include <eeschema_config.h>
#include <general.h>
#include <protos.h>
#include <list_operations.h>
#include <sch_line.h>
#include <schframe.h>
#include <class_netlist_object.h>

View File

@ -40,7 +40,7 @@
#include <gal/stroke_font.h>
#include <bitmaps.h>
#include <protos.h>
#include <list_operations.h>
#include <sch_text.h>
#include <class_netlist_object.h>

View File

@ -40,7 +40,7 @@
#include <general.h>
#include <eeschema_id.h>
#include <protos.h>
#include <list_operations.h>
#include <class_library.h>
#include <sch_bus_entry.h>
#include <sch_marker.h>

View File

@ -32,7 +32,7 @@
#include <schframe.h>
#include <general.h>
#include <protos.h>
#include <list_operations.h>
#include <sch_bus_entry.h>
#include <sch_marker.h>
#include <sch_junction.h>

View File

@ -322,8 +322,6 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_MENU_RANGE( ID_SELECT_ITEM_START, ID_SELECT_ITEM_END, SCH_EDIT_FRAME::OnSelectItem )
/* Handle user interface update events. */
EVT_UPDATE_UI( wxID_CUT, SCH_EDIT_FRAME::OnUpdateBlockSelected )
EVT_UPDATE_UI( wxID_COPY, SCH_EDIT_FRAME::OnUpdateBlockSelected )
EVT_UPDATE_UI( wxID_PASTE, SCH_EDIT_FRAME::OnUpdatePaste )
EVT_UPDATE_UI( ID_TB_OPTIONS_HIDDEN_PINS, SCH_EDIT_FRAME::OnUpdateHiddenPins )
EVT_UPDATE_UI( ID_TB_OPTIONS_BUS_WIRES_ORIENT, SCH_EDIT_FRAME::OnUpdateBusOrientation )
@ -783,14 +781,6 @@ void SCH_EDIT_FRAME::OnModify()
}
void SCH_EDIT_FRAME::OnUpdateBlockSelected( wxUpdateUIEvent& event )
{
bool enable = ( GetScreen() && GetScreen()->m_BlockLocate.GetCommand() == BLOCK_MOVE );
event.Enable( enable );
}
void SCH_EDIT_FRAME::OnUpdatePaste( wxUpdateUIEvent& event )
{
event.Enable( m_blockItems.GetCount() > 0 );

View File

@ -869,7 +869,6 @@ private:
void OnCopySchematicItemRequest( wxCommandEvent& event );
/* User interface update event handlers. */
void OnUpdateBlockSelected( wxUpdateUIEvent& event );
void OnUpdatePaste( wxUpdateUIEvent& event );
void OnUpdateHiddenPins( wxUpdateUIEvent& event );
void OnUpdateBusOrientation( wxUpdateUIEvent& event );

View File

@ -45,11 +45,6 @@
#endif
extern int ExportPartId;
extern int ImportPartId;
extern int CreateNewLibAndSavePartId;
void LIB_EDIT_FRAME::ReCreateVToolbar()
{
if( m_drawToolBar != NULL )
@ -108,55 +103,49 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT );
// Set up toolbar
m_mainToolBar->AddTool( ID_LIBEDIT_SELECT_CURRENT_LIB, wxEmptyString, KiBitmap( library_xpm ),
_( "Select working library" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_NEW_LIBRARY, wxEmptyString,
KiBitmap( new_library_xpm ),
_( "Create a new library" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_CURRENT_LIB, wxEmptyString,
m_mainToolBar->AddTool( ID_LIBEDIT_ADD_LIBRARY, wxEmptyString,
KiBitmap( add_library_xpm ),
_( "Add an existing library" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_LIBRARY, wxEmptyString,
KiBitmap( save_library_xpm ),
_( "Save into current library" ) );
m_mainToolBar->AddTool( CreateNewLibAndSavePartId, wxEmptyString, KiBitmap( new_library_xpm ),
_( "Save current component to new library" ) );
m_mainToolBar->AddTool( ID_TO_LIBVIEW, wxEmptyString, KiBitmap( library_browse_xpm ),
HELP_RUN_LIB_VIEWER );
m_mainToolBar->AddSeparator();
m_mainToolBar->AddTool( ID_LIBEDIT_DELETE_PART, wxEmptyString, KiBitmap( delete_xpm ),
_( "Delete component in current library" ) );
_( "Save current library" ) );
m_mainToolBar->AddSeparator();
m_mainToolBar->AddTool( ID_LIBEDIT_NEW_PART, wxEmptyString, KiBitmap( new_component_xpm ),
_( "Create new component" ) );
_( "Create new part" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_SELECT_PART, wxEmptyString,
KiBitmap( import_cmp_from_lib_xpm ),
_( "Load component from current library" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_PART, wxEmptyString,
KiBitmap( save_part_xpm ),
_( "Save current part" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_NEW_PART_FROM_EXISTING, wxEmptyString,
KiBitmap( copycomponent_xpm ),
_( "Create new component from current component" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_IMPORT_PART, wxEmptyString, KiBitmap( import_part_xpm ),
_( "Import part" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_CURRENT_PART, wxEmptyString,
KiBitmap( save_part_in_mem_xpm ),
_( "Update current component in current library" ) );
m_mainToolBar->AddTool( ImportPartId, wxEmptyString, KiBitmap( import_xpm ),
_( "Import component" ) );
m_mainToolBar->AddTool( ExportPartId, wxEmptyString, KiBitmap( export_xpm ),
_( "Export component" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_EXPORT_PART, wxEmptyString, KiBitmap( export_part_xpm ),
_( "Export part" ) );
m_mainToolBar->AddSeparator();
msg = AddHotkeyName( _( "Undo last command" ), g_Libedit_Hokeys_Descr, HK_UNDO, IS_COMMENT );
m_mainToolBar->AddTool( wxID_PASTE, wxEmptyString, KiBitmap( paste_xpm ),
_( "Paste" ) );
m_mainToolBar->AddSeparator();
msg = AddHotkeyName( HELP_UNDO, g_Libedit_Hokeys_Descr, HK_UNDO, IS_COMMENT );
m_mainToolBar->AddTool( wxID_UNDO, wxEmptyString, KiBitmap( undo_xpm ), msg );
msg = AddHotkeyName( _( "Redo last command" ), g_Libedit_Hokeys_Descr, HK_REDO,
IS_COMMENT );
msg = AddHotkeyName( HELP_REDO, g_Libedit_Hokeys_Descr, HK_REDO, IS_COMMENT );
m_mainToolBar->AddTool( wxID_REDO, wxEmptyString, KiBitmap( redo_xpm ), msg );
m_mainToolBar->AddSeparator();
m_mainToolBar->AddTool( ID_LIBEDIT_GET_FRAME_EDIT_PART, wxEmptyString,
KiBitmap( part_properties_xpm ), _( "Edit component properties" ) );
KiBitmap( part_properties_xpm ), _( "Edit part properties" ) );
m_mainToolBar->AddTool( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, wxEmptyString,
KiBitmap( text_xpm ),
@ -250,5 +239,9 @@ void LIB_EDIT_FRAME::CreateOptionToolbar()
KiBitmap( pin_show_etype_xpm ),
_( "Show pins electrical type" ), wxITEM_CHECK );
m_optionsToolBar->AddTool( ID_LIBEDIT_SHOW_HIDE_SEARCH_TREE, wxEmptyString,
KiBitmap( search_tree_xpm ),
_( "Toggles the search tree" ), wxITEM_CHECK );
m_optionsToolBar->Realize();
}

View File

@ -80,12 +80,6 @@ void SCH_EDIT_FRAME::ReCreateHToolbar()
m_mainToolBar->AddSeparator();
m_mainToolBar->AddTool( wxID_CUT, wxEmptyString, KiBitmap( cut_xpm ),
_( "Cut selected item" ) );
m_mainToolBar->AddTool( wxID_COPY, wxEmptyString, KiBitmap( copy_xpm ),
_( "Copy selected item" ) );
m_mainToolBar->AddTool( wxID_PASTE, wxEmptyString, KiBitmap( paste_xpm ),
_( "Paste" ) );

View File

@ -0,0 +1,103 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "cmp_tree_pane.h"
#include <component_tree.h>
#include <eeschema_id.h>
#include <lib_manager.h>
#include <libeditframe.h>
#include <symbol_lib_table.h>
CMP_TREE_PANE::CMP_TREE_PANE( LIB_EDIT_FRAME* aParent, LIB_MANAGER* aLibMgr )
: wxPanel( aParent ),
m_libEditFrame( aParent ),
m_libMgr( aLibMgr )
{
// Create widgets
wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
m_libMgr->Sync();
m_tree = new COMPONENT_TREE( this, &SYMBOL_LIB_TABLE::GetGlobalLibTable(),
m_libMgr->GetAdapter(), COMPONENT_TREE::SEARCH );
boxSizer->Add( m_tree, 1, wxEXPAND | wxALL, 5 );
SetSizer( boxSizer );
Layout();
boxSizer->Fit( this );
// Setup right click-context menus
std::unique_ptr<wxMenu> menuLibrary = std::make_unique<wxMenu>();
menuLibrary->Append( ID_LIBEDIT_NEW_LIBRARY, _( "New library..." ) );
menuLibrary->Append( ID_LIBEDIT_ADD_LIBRARY, _( "Add existing library..." ) );
menuLibrary->Append( ID_LIBEDIT_SAVE_LIBRARY, _( "Save library" ) );
menuLibrary->Append( ID_LIBEDIT_SAVE_LIBRARY_AS, _( "Save library as..." ) );
menuLibrary->Append( ID_LIBEDIT_REVERT_LIBRARY, _( "Revert library" ) );
menuLibrary->AppendSeparator();
menuLibrary->Append( ID_LIBEDIT_NEW_PART, _( "New part..." ) );
menuLibrary->Append( ID_LIBEDIT_IMPORT_PART, _( "Import part..." ) );
menuLibrary->Append( ID_LIBEDIT_PASTE_PART, _( "Paste part" ) );
std::unique_ptr<wxMenu> menuPart = std::make_unique<wxMenu>();
menuPart->Append( ID_LIBEDIT_EDIT_PART, _( "Edit" ) );
menuPart->Append( ID_LIBEDIT_REMOVE_PART, _( "Remove" ) );
menuPart->Append( ID_LIBEDIT_EXPORT_PART, _( "Export..." ) );
menuPart->Append( ID_LIBEDIT_SAVE_PART, _( "Save" ) );
menuPart->Append( ID_LIBEDIT_REVERT_PART, _( "Revert" ) );
menuPart->AppendSeparator();
menuPart->Append( ID_LIBEDIT_CUT_PART, _( "Cut" ) );
menuPart->Append( ID_LIBEDIT_COPY_PART, _( "Copy" ) );
menuPart->Append( ID_LIBEDIT_DUPLICATE_PART, _( "Duplicate" ) );
menuPart->AppendSeparator();
// Menu displayed when nothing is selected
std::unique_ptr<wxMenu> menuNoSelection = std::make_unique<wxMenu>();
menuNoSelection->Append( ID_LIBEDIT_NEW_LIBRARY, _( "New library..." ) );
menuNoSelection->Append( ID_LIBEDIT_ADD_LIBRARY, _( "Add existing library..." ) );
m_tree->SetMenu( CMP_TREE_NODE::LIBID, std::move( menuPart ) );
m_tree->SetMenu( CMP_TREE_NODE::LIB, std::move( menuLibrary ) );
m_tree->SetMenu( CMP_TREE_NODE::INVALID, std::move( menuNoSelection ) );
// Event handlers
Bind( COMPONENT_SELECTED, &CMP_TREE_PANE::onComponentSelected, this );
}
CMP_TREE_PANE::~CMP_TREE_PANE()
{
delete m_tree;
}
void CMP_TREE_PANE::onComponentSelected( wxCommandEvent& aEvent )
{
// Repost the event
wxCommandEvent evt( ID_LIBEDIT_EDIT_PART );
// I cannot figure out why the two methods below do not work..
//wxPostEvent( libEditFrame, evt );
//wxQueueEvent( m_libEditFrame, new wxCommandEvent( ID_LIBEDIT_EDIT_PART ) );
m_libEditFrame->OnEditPart( evt );
}

View File

@ -0,0 +1,57 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* 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 3
* 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:
* https://www.gnu.org/licenses/gpl-3.0.html
* or you may search the http://www.gnu.org website for the version 3 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef CMP_TREE_PANE_H
#define CMP_TREE_PANE_H
#include <wx/panel.h>
class COMPONENT_TREE;
class LIB_EDIT_FRAME;
class LIB_MANAGER;
/**
* Library Editor pane with component tree and symbol library table selector.
*/
class CMP_TREE_PANE : public wxPanel
{
public:
CMP_TREE_PANE( LIB_EDIT_FRAME* aParent, LIB_MANAGER* aLibMgr );
~CMP_TREE_PANE();
COMPONENT_TREE* GetCmpTree() const
{
return m_tree;
}
protected:
void onSymLibTableSelected( wxCommandEvent& aEvent );
void onComponentSelected( wxCommandEvent& aEvent );
LIB_EDIT_FRAME* m_libEditFrame;
COMPONENT_TREE* m_tree; ///< component search tree widget
LIB_MANAGER* m_libMgr;
};
#endif /* CMP_TREE_PANE_H */

View File

@ -36,13 +36,17 @@
COMPONENT_TREE::COMPONENT_TREE( wxWindow* aParent, SYMBOL_LIB_TABLE* aSymLibTable,
CMP_TREE_MODEL_ADAPTER::PTR& aAdapter, WIDGETS aWidgets )
CMP_TREE_MODEL_ADAPTER_BASE::PTR& aAdapter, WIDGETS aWidgets )
: wxPanel( aParent ),
m_sym_lib_table( aSymLibTable ),
m_adapter( aAdapter ),
m_query_ctrl( nullptr ),
m_details_ctrl( nullptr )
m_details_ctrl( nullptr ),
m_filtering( false )
{
// create space for context menu pointers, INVALID is the max value
m_menus.resize( CMP_TREE_NODE::TYPE::INVALID + 1 );
auto sizer = new wxBoxSizer( wxVERTICAL );
// Search text control
@ -89,6 +93,7 @@ COMPONENT_TREE::COMPONENT_TREE( wxWindow* aParent, SYMBOL_LIB_TABLE* aSymLibTabl
m_tree_ctrl->Bind( wxEVT_DATAVIEW_ITEM_ACTIVATED, &COMPONENT_TREE::onTreeActivate, this );
m_tree_ctrl->Bind( wxEVT_DATAVIEW_SELECTION_CHANGED, &COMPONENT_TREE::onTreeSelect, this );
m_tree_ctrl->Bind( wxEVT_COMMAND_DATAVIEW_ITEM_CONTEXT_MENU, &COMPONENT_TREE::onContextMenu, this );
Bind( COMPONENT_PRESELECTED, &COMPONENT_TREE::onPreselect, this );
@ -127,6 +132,12 @@ LIB_ID COMPONENT_TREE::GetSelectedLibId( int* aUnit ) const
}
void COMPONENT_TREE::SelectLibId( const LIB_ID& aLibId )
{
selectIfValid( m_adapter->FindItem( aLibId ) );
}
void COMPONENT_TREE::selectIfValid( const wxDataViewItem& aTreeId )
{
if( aTreeId.IsOk() )
@ -154,9 +165,24 @@ void COMPONENT_TREE::postSelectEvent()
void COMPONENT_TREE::onQueryText( wxCommandEvent& aEvent )
{
// Store the state
if( !m_filtering )
{
m_selection = m_tree_ctrl->GetSelection();
saveExpandFlag();
}
m_adapter->UpdateSearchString( m_query_ctrl->GetLineText( 0 ) );
m_filtering = !m_query_ctrl->IsEmpty();
postPreselectEvent();
// Restore the state
if( !m_filtering )
{
selectIfValid( m_selection );
restoreExpandFlag();
}
// Required to avoid interaction with SetHint()
// See documentation for wxTextEntry::SetHint
aEvent.Skip();
@ -236,5 +262,46 @@ void COMPONENT_TREE::onPreselect( wxCommandEvent& aEvent )
}
void COMPONENT_TREE::onContextMenu( wxDataViewEvent& aEvent )
{
auto const sel = m_tree_ctrl->GetSelection();
auto type = sel.IsOk() ? m_adapter->GetTypeFor( sel ) : CMP_TREE_NODE::INVALID;
if( m_menus[type] )
{
m_menuActive = true;
PopupMenu( m_menus[type].get() );
m_menuActive = false;
}
}
void COMPONENT_TREE::saveExpandFlag()
{
wxDataViewItemArray items;
m_adapter->GetChildren( wxDataViewItem( nullptr ), items );
m_expanded.clear();
for( const auto& item : items )
{
if( m_tree_ctrl->IsExpanded( item ) )
m_expanded.push_back( item );
}
}
void COMPONENT_TREE::restoreExpandFlag()
{
m_tree_ctrl->Freeze();
for( const auto& item : m_expanded )
{
m_tree_ctrl->Expand( item );
}
m_tree_ctrl->Thaw();
}
wxDEFINE_EVENT( COMPONENT_PRESELECTED, wxCommandEvent );
wxDEFINE_EVENT( COMPONENT_SELECTED, wxCommandEvent );

View File

@ -47,7 +47,7 @@ public:
enum WIDGETS { NONE = 0x00, SEARCH = 0x01, DETAILS = 0x02, ALL = 0xFF };
COMPONENT_TREE( wxWindow* aParent, SYMBOL_LIB_TABLE* aSymLibTable,
CMP_TREE_MODEL_ADAPTER::PTR& aAdapter, WIDGETS aWidgets = ALL );
CMP_TREE_MODEL_ADAPTER_BASE::PTR& aAdapter, WIDGETS aWidgets = ALL );
/**
* For multi-unit components, if the user selects the component itself
@ -60,6 +60,32 @@ public:
*/
LIB_ID GetSelectedLibId( int* aUnit = nullptr ) const;
/**
* Select a part in the tree widget.
*
* @param aLibId is the identifier of part to be selected.
*/
void SelectLibId( const LIB_ID& aLibId );
/**
* Associates a right click context menu for a specific node type.
* @param aType is the node type to have a menu associated.
* @param aMenu is the associated menu.
*/
void SetMenu( CMP_TREE_NODE::TYPE aType, std::unique_ptr<wxMenu> aMenu )
{
m_menus[aType] = std::move( aMenu );
}
/**
* Returns the status of right-click context menu.
* @return True in case a right-click context menu is active.
*/
bool IsMenuActive() const
{
return m_menuActive;
}
protected:
/**
* If a wxDataViewitem is valid, select it and post a selection event.
@ -86,12 +112,36 @@ protected:
void onDetailsLink( wxHtmlLinkEvent& aEvent );
void onPreselect( wxCommandEvent& aEvent );
void onContextMenu( wxDataViewEvent& aEvent );
/**
* Store the list of expanded nodes in the tree widget.
*/
void saveExpandFlag();
/**
* Restore the expanded nodes in the tree widget.
*/
void restoreExpandFlag();
SYMBOL_LIB_TABLE* m_sym_lib_table;
CMP_TREE_MODEL_ADAPTER::PTR m_adapter;
CMP_TREE_MODEL_ADAPTER_BASE::PTR m_adapter;
wxTextCtrl* m_query_ctrl;
wxDataViewCtrl* m_tree_ctrl;
wxHtmlWindow* m_details_ctrl;
///> Right click context menus for each tree level
std::vector<std::unique_ptr<wxMenu>> m_menus;
///> Flag indicating whether a right-click context menu is active
bool m_menuActive;
bool m_filtering;
///> List of expanded nodes
std::vector<wxDataViewItem> m_expanded;
wxDataViewItem m_selection;
};
///> Custom event sent when a new component is preselected

View File

@ -43,7 +43,6 @@ class WIDGET_EESCHEMA_COLOR_CONFIG : public wxPanel
{
private:
EDA_DRAW_FRAME* m_drawFrame;
wxColourPickerCtrl* m_SelBgColor;
wxBoxSizer* m_mainBoxSizer;
// Creates the controls and sizers

View File

@ -48,6 +48,7 @@ EXTERN_BITMAP( add_hierarchical_subsheet_xpm )
EXTERN_BITMAP( add_hierar_pin_xpm )
EXTERN_BITMAP( add_junction_xpm )
EXTERN_BITMAP( add_keepout_area_xpm )
EXTERN_BITMAP( add_library_xpm )
EXTERN_BITMAP( add_line2bus_xpm )
EXTERN_BITMAP( add_line_label_xpm )
EXTERN_BITMAP( add_line_xpm )
@ -158,6 +159,7 @@ EXTERN_BITMAP( export_dsn_xpm )
EXTERN_BITMAP( export_idf_xpm )
EXTERN_BITMAP( export_footprint_names_xpm )
EXTERN_BITMAP( export_module_xpm )
EXTERN_BITMAP( export_part_xpm )
EXTERN_BITMAP( export_xpm )
EXTERN_BITMAP( fabrication_xpm )
EXTERN_BITMAP( file_footprint_xpm )
@ -216,6 +218,7 @@ EXTERN_BITMAP( import_cmp_from_lib_xpm )
EXTERN_BITMAP( import_footprint_names_xpm )
EXTERN_BITMAP( import_hierarchical_label_xpm )
EXTERN_BITMAP( import_module_xpm )
EXTERN_BITMAP( import_part_xpm )
EXTERN_BITMAP( import_setup_xpm )
EXTERN_BITMAP( import_xpm )
EXTERN_BITMAP( import3d_xpm )
@ -434,10 +437,12 @@ EXTERN_BITMAP( rotate_neg_z_xpm )
EXTERN_BITMAP( rotate_pos_z_xpm )
EXTERN_BITMAP( save_as_xpm )
EXTERN_BITMAP( save_library_xpm )
EXTERN_BITMAP( save_part_xpm )
EXTERN_BITMAP( save_part_in_mem_xpm )
EXTERN_BITMAP( save_project_xpm )
EXTERN_BITMAP( save_setup_xpm )
EXTERN_BITMAP( save_xpm )
EXTERN_BITMAP( search_tree_xpm )
EXTERN_BITMAP( select_grid_xpm )
EXTERN_BITMAP( select_layer_pair_xpm )
EXTERN_BITMAP( select_w_layer_xpm )

View File

@ -32,6 +32,7 @@
#define __INCLUDE__CONFIRM_H__
#include <wx/window.h>
#include <vector>
/**
* Function DisplayExitDialog
@ -121,4 +122,30 @@ void DisplayHtmlInfoMessage( wxWindow* parent, const wxString& title,
const wxSize& size = wxDefaultSize );
/**
* Displays a dialog with radioboxes asking the user to select an option.
* @param aParent is the parent window.
* @param aTitle is the dialog title.
* @param aMessage is a text label displayed in the first row of the dialog.
* @param aOptions is a vector of possible options.
* @return Index of the selected option or -1 when the dialog has been cancelled.
*/
int SelectSingleOption( wxWindow* aParent, const wxString& aTitle, const wxString& aMessage,
const wxArrayString& aOptions );
/**
* Displays a dialog with checkboxes asking the user to select one or more options.
* @param aParent is the parent window.
* @param aTitle is the dialog title.
* @param aMessage is a text label displayed in the first row of the dialog.
* @param aOptions is a vector of possible options.
* @param aDefaultState is the default state for the checkboxes.
* @return Vector containing indices of the selected option.
*/
std::pair<bool, std::vector<int>> SelectMultipleOptions( wxWindow* aParent, const wxString& aTitle,
const wxString& aMessage, const wxArrayString& aOptions, bool aDefaultState = false );
std::pair<bool, std::vector<int>> SelectMultipleOptions( wxWindow* aParent, const wxString& aTitle,
const wxString& aMessage, const std::vector<std::string>& aOptions, bool aDefaultState = false );
#endif /* __INCLUDE__CONFIRM_H__ */