ADDED: Dialog to handle import of unmatched layers from CADSTAR

This commit is contained in:
Roberto Fernandez Bautista 2020-10-01 23:47:38 +01:00 committed by Jon Evans
parent 3e49669304
commit 72d9a36fd6
11 changed files with 1562 additions and 20 deletions

View File

@ -112,6 +112,8 @@ set( PCBNEW_DIALOGS
dialogs/dialog_graphic_item_properties_base.cpp dialogs/dialog_graphic_item_properties_base.cpp
dialogs/dialog_import_settings.cpp dialogs/dialog_import_settings.cpp
dialogs/dialog_import_settings_base.cpp dialogs/dialog_import_settings_base.cpp
dialogs/dialog_imported_layers_base.cpp
dialogs/dialog_imported_layers.cpp
dialogs/dialog_rule_area_properties.cpp dialogs/dialog_rule_area_properties.cpp
dialogs/dialog_rule_area_properties_base.cpp dialogs/dialog_rule_area_properties_base.cpp
dialogs/dialog_layer_selection_base.cpp dialogs/dialog_layer_selection_base.cpp

View File

@ -0,0 +1,278 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
* Copyright (C) 2020 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 <layers_id_colors_and_visibility.h>
#include <dialog_imported_layers.h>
PCB_LAYER_ID DIALOG_IMPORTED_LAYERS::GetSelectedLayerID()
{
// First check if there is a KiCad element selected
wxString selectedKiCadLayerName;
long itemIndex = -1;
if( ( itemIndex = m_kicad_layers_list->GetNextItem(
itemIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ) )
!= wxNOT_FOUND )
{
selectedKiCadLayerName = m_kicad_layers_list->GetItemText( itemIndex );
}
else
{
return PCB_LAYER_ID::UNDEFINED_LAYER;
}
// There should only be one selected (or none) as the list is set with wxLC_SINGLE_SEL style
wxASSERT_MSG( ( m_kicad_layers_list->GetNextItem(
itemIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ) )
== wxNOT_FOUND,
"There are more than one KiCad layer selected (unexpected)" );
for( LAYER_NUM layer = 0; layer < PCB_LAYER_ID_COUNT; ++layer )
{
if( LayerName( ToLAYER_ID( layer ) ) == selectedKiCadLayerName )
return ToLAYER_ID( layer );
}
return PCB_LAYER_ID::UNDEFINED_LAYER;
}
PCB_LAYER_ID DIALOG_IMPORTED_LAYERS::GetAutoMatchLayerID( wxString aInputLayerName )
{
for( INPUT_LAYER_DESC inputLayerDesc : m_input_layers )
{
if( inputLayerDesc.Name == aInputLayerName )
return inputLayerDesc.AutoMapLayer;
}
return PCB_LAYER_ID::UNDEFINED_LAYER;
}
void DIALOG_IMPORTED_LAYERS::AddMappings()
{
PCB_LAYER_ID selectedKiCadLayerID = GetSelectedLayerID();
if( selectedKiCadLayerID == PCB_LAYER_ID::UNDEFINED_LAYER )
return;
// Now iterate through each selected layer in the unmatched layers list
int itemIndex = -1;
wxArrayInt rowsToDelete;
while( ( itemIndex = m_unmatched_layers_list->GetNextItem(
itemIndex, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED ) )
!= wxNOT_FOUND )
{
wxString selectedLayerName = m_unmatched_layers_list->GetItemText( itemIndex );
wxString kiName = LayerName( selectedKiCadLayerID );
// add layer pair to the GUI list and also to the map
long newItemIndex = m_matched_layers_list->InsertItem( 0, selectedLayerName );
m_matched_layers_list->SetItem( newItemIndex, 1, kiName );
m_matched_layers_map.insert( { selectedLayerName, selectedKiCadLayerID } );
// remove selected layer from vector and also GUI list
for( auto iter = m_unmatched_layer_names.begin(); iter != m_unmatched_layer_names.end();
++iter )
{
if( *iter == selectedLayerName )
{
m_unmatched_layer_names.erase( iter );
break;
}
}
rowsToDelete.Add( itemIndex );
}
DeleteListItems( rowsToDelete, m_unmatched_layers_list );
}
void DIALOG_IMPORTED_LAYERS::RemoveMappings( int aStatus )
{
wxArrayInt rowsToDelete;
int itemIndex = -1;
while( ( itemIndex = m_matched_layers_list->GetNextItem( itemIndex, wxLIST_NEXT_ALL, aStatus ) )
!= wxNOT_FOUND )
{
wxString selectedLayerName = m_matched_layers_list->GetItemText( itemIndex, 0 );
wxCHECK( m_matched_layers_map.find( selectedLayerName ) != m_matched_layers_map.end(),
/*void*/ );
m_matched_layers_map.erase( selectedLayerName );
rowsToDelete.Add( itemIndex );
m_unmatched_layers_list->InsertItem( 0, selectedLayerName );
m_unmatched_layer_names.push_back( selectedLayerName );
}
DeleteListItems( rowsToDelete, m_matched_layers_list );
}
void DIALOG_IMPORTED_LAYERS::DeleteListItems( const wxArrayInt& aRowsToDelete,
wxListCtrl* aListCtrl )
{
for( long n = ( aRowsToDelete.GetCount() - 1 ); 0 <= n; n-- )
{
aListCtrl->DeleteItem( aRowsToDelete[n] );
}
}
void DIALOG_IMPORTED_LAYERS::OnAutoMatchLayersClicked( wxCommandEvent& event )
{
// Iterate through each selected layer in the unmatched layers list
int itemIndex = -1;
wxArrayInt rowsToDelete;
while( ( itemIndex = m_unmatched_layers_list->GetNextItem(
itemIndex, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE ) )
!= wxNOT_FOUND )
{
wxString layerName = m_unmatched_layers_list->GetItemText( itemIndex );
PCB_LAYER_ID autoMatchLayer = GetAutoMatchLayerID( layerName );
if( autoMatchLayer == PCB_LAYER_ID::UNDEFINED_LAYER )
continue;
wxString kiName = LayerName( autoMatchLayer );
// add layer pair to the GUI list and also to the map
long newItemIndex = m_matched_layers_list->InsertItem( 0, layerName );
m_matched_layers_list->SetItem( newItemIndex, 1, kiName );
m_matched_layers_map.insert( { layerName, autoMatchLayer } );
// remove selected layer from vector and also GUI list
for( auto iter = m_unmatched_layer_names.begin(); iter != m_unmatched_layer_names.end();
++iter )
{
if( *iter == layerName )
{
m_unmatched_layer_names.erase( iter );
break;
}
}
rowsToDelete.Add( itemIndex );
}
DeleteListItems( rowsToDelete, m_unmatched_layers_list );
}
DIALOG_IMPORTED_LAYERS::DIALOG_IMPORTED_LAYERS( wxWindow* aParent,
const std::vector<INPUT_LAYER_DESC>& aLayerDesc )
: DIALOG_IMPORTED_LAYERS_BASE( aParent )
{
LSET kiCadLayers;
// Read in the input layers
for( INPUT_LAYER_DESC inLayer : aLayerDesc )
{
m_input_layers.push_back( inLayer );
m_unmatched_layer_names.push_back( inLayer.Name );
kiCadLayers |= inLayer.PermittedLayers;
}
// Initialize columns in the wxListCtrl elements:
wxListItem importedLayersHeader;
importedLayersHeader.SetId( 0 );
importedLayersHeader.SetText( _( "Imported Layer" ) );
importedLayersHeader.SetWidth( 200 );
m_unmatched_layers_list->InsertColumn( 0, importedLayersHeader );
wxListItem kicadLayersHeader;
kicadLayersHeader.SetId( 0 );
kicadLayersHeader.SetText( _( "KiCad Layer" ) );
kicadLayersHeader.SetWidth( 100 );
m_kicad_layers_list->InsertColumn( 0, kicadLayersHeader );
kicadLayersHeader.SetId( 1 );
m_matched_layers_list->InsertColumn( 0, importedLayersHeader );
m_matched_layers_list->InsertColumn( 1, kicadLayersHeader );
// Load the input layer list to unmatched layers
int row = 0;
for( wxString importedLayerName : m_unmatched_layer_names )
{
wxListItem item;
item.SetId( row );
item.SetText( importedLayerName );
m_unmatched_layers_list->InsertItem( item );
++row;
}
// Load the KiCad Layer names
row = 0;
LSEQ kicadLayersSeq = kiCadLayers.Seq();
for( PCB_LAYER_ID layer : kicadLayersSeq )
{
wxString kiName = LayerName( layer );
wxListItem item;
item.SetId( row );
item.SetText( kiName );
m_kicad_layers_list->InsertItem( item );
++row;
}
m_sdbSizerOK->SetDefault();
FinishDialogSettings();
}
LAYER_MAP DIALOG_IMPORTED_LAYERS::GetMapModal( wxWindow* aParent,
const std::vector<INPUT_LAYER_DESC>& aLayerDesc )
{
DIALOG_IMPORTED_LAYERS dlg( aParent, aLayerDesc );
bool dataOk = false;
while( !dataOk )
{
dlg.ShowModal();
if( dlg.m_unmatched_layer_names.size() > 0 )
{
wxMessageBox( _( "All layers must be matched. Please click on 'Auto-Matched Layers' "
"to automatically match the remaining layers." ),
_( "Unmatched Layers" ), wxICON_ERROR | wxOK );
}
else
{
dataOk = true;
}
}
return dlg.m_matched_layers_map;
}

View File

@ -0,0 +1,68 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com>
* Copyright (C) 2020 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 DIALOG_IMPORTED_LAYERS_H
#define DIALOG_IMPORTED_LAYERS_H
#include <dialog_imported_layers_base.h>
#include <plugins/cadstar/cadstar_pcb_archive_plugin.h> // INPUT_LAYER_DESC
class DIALOG_IMPORTED_LAYERS : public DIALOG_IMPORTED_LAYERS_BASE
{
private:
const int selected = wxLIST_STATE_SELECTED;
const int allitems = wxLIST_STATE_DONTCARE;
std::vector<INPUT_LAYER_DESC> m_input_layers;
std::vector<wxString> m_unmatched_layer_names;
LAYER_MAP m_matched_layers_map;
//Helper functions
PCB_LAYER_ID GetSelectedLayerID();
PCB_LAYER_ID GetAutoMatchLayerID( wxString aInputLayerName );
void AddMappings();
void RemoveMappings( int aStatus );
void DeleteListItems( const wxArrayInt& aRowsToDelete, wxListCtrl* aListCtrl );
//Event Handlers
void OnAutoMatchLayersClicked( wxCommandEvent& event ) override;
void OnUnMatchedDoubleClick( wxListEvent& event ) override { AddMappings(); }
void OnAddClicked( wxCommandEvent& event ) override { AddMappings(); }
void OnMatchedDoubleClick( wxListEvent& event ) override { RemoveMappings( selected ); }
void OnRemoveClicked( wxCommandEvent& event ) override { RemoveMappings( selected ); }
void OnRemoveAllClicked( wxCommandEvent& event ) override { RemoveMappings( allitems ); }
public:
DIALOG_IMPORTED_LAYERS( wxWindow* aParent, const std::vector<INPUT_LAYER_DESC>& aLayerDesc );
/**
* @brief Creates and shows a dialog (modal) and returns the data from it after completion.
* If the dialog is closed or cancel is pressed, returns an empty LAYER_MAP
* @param aParent Parent window for the invoked dialog.
* @param aLayerDesc
* @return Mapped layers
*/
static LAYER_MAP GetMapModal( wxWindow* aParent,
const std::vector<INPUT_LAYER_DESC>& aLayerDesc );
};
#endif // DIALOG_IMPORTED_LAYERS_H

View File

@ -0,0 +1,143 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_imported_layers_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_IMPORTED_LAYERS_BASE::DIALOG_IMPORTED_LAYERS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( 600,350 ), wxDefaultSize );
bSizerMain = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerTop;
bSizerTop = new wxBoxSizer( wxHORIZONTAL );
wxStaticBoxSizer* sbSizer1;
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Unmatched Layers") ), wxHORIZONTAL );
wxBoxSizer* bSizerUnmatched;
bSizerUnmatched = new wxBoxSizer( wxVERTICAL );
m_staticText1 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("Imported Layers"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText1->Wrap( -1 );
bSizerUnmatched->Add( m_staticText1, 0, wxALL, 5 );
m_unmatched_layers_list = new wxListCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( 200,-1 ), wxLC_NO_HEADER|wxLC_REPORT );
m_unmatched_layers_list->SetMaxSize( wxSize( 300,-1 ) );
bSizerUnmatched->Add( m_unmatched_layers_list, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
sbSizer1->Add( bSizerUnmatched, 1, wxEXPAND, 5 );
wxBoxSizer* bSizerKiCad;
bSizerKiCad = new wxBoxSizer( wxVERTICAL );
m_staticText2 = new wxStaticText( sbSizer1->GetStaticBox(), wxID_ANY, _("KiCad Layers"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText2->Wrap( -1 );
bSizerKiCad->Add( m_staticText2, 0, wxALL, 5 );
m_kicad_layers_list = new wxListCtrl( sbSizer1->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( 120,-1 ), wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL );
m_kicad_layers_list->SetMinSize( wxSize( 120,-1 ) );
m_kicad_layers_list->SetMaxSize( wxSize( 150,-1 ) );
bSizerKiCad->Add( m_kicad_layers_list, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
sbSizer1->Add( bSizerKiCad, 0, wxEXPAND, 5 );
bSizerTop->Add( sbSizer1, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
wxStaticBoxSizer* sbSizer2;
sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, wxEmptyString ), wxVERTICAL );
m_button_add = new wxButton( sbSizer2->GetStaticBox(), wxID_ANY, _(">"), wxDefaultPosition, wxSize( 30,100 ), 0 );
m_button_add->SetFont( wxFont( 9, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
m_button_add->SetToolTip( _("Add selected layers to matched layers list.") );
sbSizer2->Add( m_button_add, 0, wxALL, 5 );
m_button_remove = new wxButton( sbSizer2->GetStaticBox(), wxID_ANY, _("<"), wxDefaultPosition, wxSize( 30,100 ), 0 );
m_button_remove->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
m_button_remove->SetToolTip( _("Remove selected layers from matched layers list.") );
sbSizer2->Add( m_button_remove, 0, wxALL, 5 );
m_button_removeall = new wxButton( sbSizer2->GetStaticBox(), wxID_ANY, _("<<"), wxDefaultPosition, wxSize( 30,50 ), 0 );
m_button_removeall->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL, false, wxEmptyString ) );
m_button_removeall->SetToolTip( _("Remove all matched layers.") );
sbSizer2->Add( m_button_removeall, 0, wxALL, 5 );
bSizerTop->Add( sbSizer2, 0, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
wxStaticBoxSizer* sbSizer3;
sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Matched Layers") ), wxHORIZONTAL );
m_matched_layers_list = new wxListCtrl( sbSizer3->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxSize( 300,-1 ), wxLC_REPORT );
m_matched_layers_list->SetMaxSize( wxSize( 500,-1 ) );
sbSizer3->Add( m_matched_layers_list, 1, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
bSizerTop->Add( sbSizer3, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
bSizerMain->Add( bSizerTop, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizerBottom;
bSizerBottom = new wxBoxSizer( wxHORIZONTAL );
m_button_automatch = new wxButton( this, wxID_ANY, _("Auto-Match Layers"), wxDefaultPosition, wxDefaultSize, 0 );
m_button_automatch->SetToolTip( _("Automatically match any unmatched layers to their KiCad equivalent.") );
bSizerBottom->Add( m_button_automatch, 0, wxALL, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizer->Realize();
bSizerBottom->Add( m_sdbSizer, 1, wxALL|wxEXPAND, 5 );
bSizerMain->Add( bSizerBottom, 0, wxEXPAND|wxLEFT, 5 );
this->SetSizer( bSizerMain );
this->Layout();
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnClose ) );
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnUpdateUI ) );
m_unmatched_layers_list->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnUnMatchedDoubleClick ), NULL, this );
m_kicad_layers_list->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnUnMatchedDoubleClick ), NULL, this );
m_button_add->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnAddClicked ), NULL, this );
m_button_remove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnRemoveClicked ), NULL, this );
m_button_removeall->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnRemoveAllClicked ), NULL, this );
m_matched_layers_list->Connect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnMatchedDoubleClick ), NULL, this );
m_button_automatch->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnAutoMatchLayersClicked ), NULL, this );
}
DIALOG_IMPORTED_LAYERS_BASE::~DIALOG_IMPORTED_LAYERS_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnClose ) );
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnUpdateUI ) );
m_unmatched_layers_list->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnUnMatchedDoubleClick ), NULL, this );
m_kicad_layers_list->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnUnMatchedDoubleClick ), NULL, this );
m_button_add->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnAddClicked ), NULL, this );
m_button_remove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnRemoveClicked ), NULL, this );
m_button_removeall->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnRemoveAllClicked ), NULL, this );
m_matched_layers_list->Disconnect( wxEVT_COMMAND_LIST_ITEM_ACTIVATED, wxListEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnMatchedDoubleClick ), NULL, this );
m_button_automatch->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORTED_LAYERS_BASE::OnAutoMatchLayersClicked ), NULL, this );
}

View File

@ -0,0 +1,773 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_imported_layers_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">dialog_imported_layers_base</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="center"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">600,350</property>
<property name="name">DIALOG_IMPORTED_LAYERS_BASE</property>
<property name="pos"></property>
<property name="size">795,476</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Edit Mapping of Imported Layers</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnClose">OnClose</event>
<event name="OnUpdateUI">OnUpdateUI</event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerTop</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property>
<property name="label">Unmatched Layers</property>
<property name="minimum_size"></property>
<property name="name">sbSizer1</property>
<property name="orient">wxHORIZONTAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerUnmatched</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Imported Layers</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="proportion">1</property>
<object class="wxListCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size">300,-1</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_unmatched_layers_list</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">200,-1</property>
<property name="style">wxLC_NO_HEADER|wxLC_REPORT</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnListItemActivated">OnUnMatchedDoubleClick</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerKiCad</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">KiCad Layers</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size">-1,-1</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText2</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="proportion">1</property>
<object class="wxListCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size">150,-1</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">120,-1</property>
<property name="moveable">1</property>
<property name="name">m_kicad_layers_list</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">120,-1</property>
<property name="style">wxLC_NO_HEADER|wxLC_REPORT|wxLC_SINGLE_SEL</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnListItemActivated">OnUnMatchedDoubleClick</event>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property>
<property name="label"></property>
<property name="minimum_size"></property>
<property name="name">sbSizer2</property>
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font">,90,90,9,75,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">&gt;</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_button_add</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">30,100</property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Add selected layers to matched layers list.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnAddClicked</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font">,90,90,-1,75,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">&lt;</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_button_remove</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">30,100</property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Remove selected layers from matched layers list.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnRemoveClicked</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font">,90,90,-1,75,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">&lt;&lt;</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_button_removeall</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">30,50</property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Remove all matched layers.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnRemoveAllClicked</event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT|wxTOP</property>
<property name="proportion">1</property>
<object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property>
<property name="label">Matched Layers</property>
<property name="minimum_size"></property>
<property name="name">sbSizer3</property>
<property name="orient">wxHORIZONTAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="proportion">1</property>
<object class="wxListCtrl" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size">500,-1</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_matched_layers_list</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">300,-1</property>
<property name="style">wxLC_REPORT</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnListItemActivated">OnMatchedDoubleClick</event>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerBottom</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Auto-Match Layers</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_button_automatch</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Automatically match any unmatched layers to their KiCad equivalent.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnAutoMatchLayersClicked</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">0</property>
<property name="Cancel">0</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@ -0,0 +1,69 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
#include "dialog_shim.h"
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/listctrl.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_IMPORTED_LAYERS_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_IMPORTED_LAYERS_BASE : public DIALOG_SHIM
{
private:
protected:
wxBoxSizer* bSizerMain;
wxStaticText* m_staticText1;
wxListCtrl* m_unmatched_layers_list;
wxStaticText* m_staticText2;
wxListCtrl* m_kicad_layers_list;
wxButton* m_button_add;
wxButton* m_button_remove;
wxButton* m_button_removeall;
wxListCtrl* m_matched_layers_list;
wxButton* m_button_automatch;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
// Virtual event handlers, overide them in your derived class
virtual void OnClose( wxCloseEvent& event ) { event.Skip(); }
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnUnMatchedDoubleClick( wxListEvent& event ) { event.Skip(); }
virtual void OnAddClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveAllClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void OnMatchedDoubleClick( wxListEvent& event ) { event.Skip(); }
virtual void OnAutoMatchLayersClicked( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_IMPORTED_LAYERS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Edit Mapping of Imported Layers"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 795,476 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_IMPORTED_LAYERS_BASE();
};

View File

@ -49,6 +49,8 @@
#include <settings/settings_manager.h> #include <settings/settings_manager.h>
#include <project/project_file.h> #include <project/project_file.h>
#include <project/project_local_settings.h> #include <project/project_local_settings.h>
#include <plugins/cadstar/cadstar_pcb_archive_plugin.h>
#include <dialogs/dialog_imported_layers.h>
//#define USE_INSTRUMENTATION 1 //#define USE_INSTRUMENTATION 1
@ -587,6 +589,20 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) ); PLUGIN::RELEASER pi( IO_MGR::PluginFind( pluginType ) );
if( pluginType == IO_MGR::CADSTAR_PCB_ARCHIVE )
{
// TODO: Generalise this so that it is applicable to all non-kicad plugins
CADSTAR_PCB_ARCHIVE_PLUGIN* cadstarPlugin = nullptr;
cadstarPlugin = dynamic_cast<CADSTAR_PCB_ARCHIVE_PLUGIN*>( (PLUGIN*) pi );
wxCHECK( cadstarPlugin, false );
cadstarPlugin->RegisterLayerMappingCallback(
std::bind( DIALOG_IMPORTED_LAYERS::GetMapModal, this, std::placeholders::_1 ) );
}
// This will rename the file if there is an autosave and the user want to recover // This will rename the file if there is an autosave and the user want to recover
CheckForAutoSaveFile( fullFileName ); CheckForAutoSaveFile( fullFileName );

View File

@ -82,6 +82,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard )
} }
loadBoardStackup(); loadBoardStackup();
remapUnsureLayers();
loadDesignRules(); loadDesignRules();
loadComponentLibrary(); loadComponentLibrary();
loadGroups(); loadGroups();
@ -116,14 +117,30 @@ void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard )
} }
void CADSTAR_PCB_ARCHIVE_LOADER::logBoardStackupWarning( void CADSTAR_PCB_ARCHIVE_LOADER::logBoardStackupWarning( const wxString& aCadstarLayerName,
const wxString& aCadstarLayerName, const PCB_LAYER_ID& aKiCadLayer ) const PCB_LAYER_ID& aKiCadLayer )
{
if( mLogLayerWarnings )
{ {
wxLogWarning( wxString::Format( wxLogWarning( wxString::Format(
_( "The CADSTAR layer '%s' has no KiCad equivalent. All elements on this " _( "The CADSTAR layer '%s' has no KiCad equivalent. All elements on this "
"layer have been mapped to KiCad layer '%s' instead." ), "layer have been mapped to KiCad layer '%s' instead." ),
aCadstarLayerName, LSET::Name( aKiCadLayer ) ) ); aCadstarLayerName, LSET::Name( aKiCadLayer ) ) );
} }
}
void CADSTAR_PCB_ARCHIVE_LOADER::logBoardStackupMessage( const wxString& aCadstarLayerName,
const PCB_LAYER_ID& aKiCadLayer )
{
if( mLogLayerWarnings )
{
wxLogMessage( wxString::Format(
_( "The CADSTAR layer '%s' has been assumed to be a technical layer. All "
"elements on this layer have been mapped to KiCad layer '%s'." ),
aCadstarLayerName, LSET::Name( aKiCadLayer ) ) );
}
}
void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup() void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
@ -255,11 +272,46 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
else else
kicadLayerID = PCB_LAYER_ID::F_Adhes; kicadLayerID = PCB_LAYER_ID::F_Adhes;
wxLogMessage( wxString::Format( logBoardStackupMessage( curLayer.Name, kicadLayerID );
_( "The CADSTAR layer '%s' has been assumed to be an adhesive layer. " }
"All elements on this layer have been mapped to KiCad layer '%s'." ), else if( curLayer.Name.Lower().Contains( "silk" )
curLayer.Name, LSET::Name( kicadLayerID ) ) ); || curLayer.Name.Lower().Contains( "legend" ) )
//TODO: allow user to decide if this is actually an adhesive layer or not. {
if( numElecAndPowerLayers > 0 )
kicadLayerID = PCB_LAYER_ID::B_SilkS;
else
kicadLayerID = PCB_LAYER_ID::F_SilkS;
logBoardStackupMessage( curLayer.Name, kicadLayerID );
}
else if( curLayer.Name.Lower().Contains( "assembly" )
|| curLayer.Name.Lower().Contains( "fabrication" ) )
{
if( numElecAndPowerLayers > 0 )
kicadLayerID = PCB_LAYER_ID::B_Fab;
else
kicadLayerID = PCB_LAYER_ID::F_Fab;
logBoardStackupMessage( curLayer.Name, kicadLayerID );
}
else if( curLayer.Name.Lower().Contains( "resist" )
|| curLayer.Name.Lower().Contains( "mask" ) )
{
if( numElecAndPowerLayers > 0 )
kicadLayerID = PCB_LAYER_ID::B_Mask;
else
kicadLayerID = PCB_LAYER_ID::F_Mask;
logBoardStackupMessage( curLayer.Name, kicadLayerID );
}
else if( curLayer.Name.Lower().Contains( "paste" ) )
{
if( numElecAndPowerLayers > 0 )
kicadLayerID = PCB_LAYER_ID::B_Paste;
else
kicadLayerID = PCB_LAYER_ID::F_Paste;
logBoardStackupMessage( curLayer.Name, kicadLayerID );
} }
else else
{ {
@ -269,7 +321,6 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
kicadLayerID = PCB_LAYER_ID::Eco1_User; kicadLayerID = PCB_LAYER_ID::Eco1_User;
logBoardStackupWarning( curLayer.Name, kicadLayerID ); logBoardStackupWarning( curLayer.Name, kicadLayerID );
//TODO: allow user to decide which layer this should be mapped onto.
} }
break; break;
@ -413,6 +464,58 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
} }
void CADSTAR_PCB_ARCHIVE_LOADER::remapUnsureLayers()
{
LSET enabledLayers = mBoard->GetEnabledLayers();
LSET validRemappingLayers = enabledLayers | LSET::AllBoardTechMask() |
LSET::UserMask() | LSET::UserDefinedLayers();
std::vector<INPUT_LAYER_DESC> inputLayers;
std::map<wxString, LAYER_ID> cadstarLayerNameMap;
for( std::pair<LAYER_ID, PCB_LAYER_ID> layerPair : mLayermap )
{
LAYER* curLayer = &Assignments.Layerdefs.Layers.at( layerPair.first );
//Only remap layers that we aren't sure about
if( curLayer->Type == LAYER_TYPE::DOC
|| ( curLayer->Type == LAYER_TYPE::NONELEC
&& curLayer->SubType == LAYER_SUBTYPE::LAYERSUBTYPE_NONE ) )
{
INPUT_LAYER_DESC iLdesc;
iLdesc.Name = curLayer->Name;
iLdesc.PermittedLayers = validRemappingLayers;
iLdesc.AutoMapLayer = layerPair.second;
inputLayers.push_back( iLdesc );
cadstarLayerNameMap.insert( { curLayer->Name, curLayer->ID } );
}
}
if( inputLayers.size() == 0 )
return;
// Callback:
LAYER_MAP reMappedLayers = mLayerMappingHandler( inputLayers );
for( std::pair<wxString, PCB_LAYER_ID> layerPair : reMappedLayers )
{
if( layerPair.second == PCB_LAYER_ID::UNDEFINED_LAYER )
{
wxASSERT_MSG( false, "Unexpected Layer ID" );
continue;
}
LAYER_ID cadstarLayerID = cadstarLayerNameMap.at( layerPair.first );
mLayermap.at( cadstarLayerID ) = layerPair.second;
enabledLayers |= LSET( layerPair.second );
}
mBoard->SetEnabledLayers( enabledLayers );
mBoard->SetVisibleLayers( enabledLayers );
}
void CADSTAR_PCB_ARCHIVE_LOADER::loadDesignRules() void CADSTAR_PCB_ARCHIVE_LOADER::loadDesignRules()
{ {
BOARD_DESIGN_SETTINGS& ds = mBoard->GetDesignSettings(); BOARD_DESIGN_SETTINGS& ds = mBoard->GetDesignSettings();

View File

@ -27,6 +27,7 @@
#define CADSTAR_PCB_ARCHIVE_LOADER_H_ #define CADSTAR_PCB_ARCHIVE_LOADER_H_
#include <cadstar_pcb_archive_parser.h> #include <cadstar_pcb_archive_parser.h>
#include <cadstar_pcb_archive_plugin.h> // LAYER_MAPPING_HANDLER definition
#include <class_board.h> #include <class_board.h>
#include <set> #include <set>
@ -35,9 +36,12 @@ class BOARD;
class CADSTAR_PCB_ARCHIVE_LOADER : public CADSTAR_PCB_ARCHIVE_PARSER class CADSTAR_PCB_ARCHIVE_LOADER : public CADSTAR_PCB_ARCHIVE_PARSER
{ {
public: public:
explicit CADSTAR_PCB_ARCHIVE_LOADER( wxString aFilename ) explicit CADSTAR_PCB_ARCHIVE_LOADER(
wxString aFilename, LAYER_MAPPING_HANDLER aLayerMappingHandler, bool aLogLayerWarnings )
: CADSTAR_PCB_ARCHIVE_PARSER( aFilename ) : CADSTAR_PCB_ARCHIVE_PARSER( aFilename )
{ {
mLayerMappingHandler = aLayerMappingHandler;
mLogLayerWarnings = aLogLayerWarnings;
mBoard = nullptr; mBoard = nullptr;
mDesignCenter.x = 0; mDesignCenter.x = 0;
mDesignCenter.y = 0; mDesignCenter.y = 0;
@ -67,6 +71,8 @@ public:
private: private:
LAYER_MAPPING_HANDLER mLayerMappingHandler; ///< Callback to get layer mapping
bool mLogLayerWarnings; ///< Used in loadBoardStackup()
::BOARD* mBoard; ::BOARD* mBoard;
std::map<LAYER_ID, PCB_LAYER_ID> mLayermap; ///< Map between Cadstar and KiCad Layers. std::map<LAYER_ID, PCB_LAYER_ID> mLayermap; ///< Map between Cadstar and KiCad Layers.
///< Populated by loadBoardStackup(). ///< Populated by loadBoardStackup().
@ -105,6 +111,7 @@ private:
// Functions for loading individual elements: // Functions for loading individual elements:
void loadBoardStackup(); void loadBoardStackup();
void remapUnsureLayers(); ///< Callback mLayerMappingHandler for layers we aren't sure of
void loadDesignRules(); void loadDesignRules();
void loadComponentLibrary(); void loadComponentLibrary();
void loadGroups(); void loadGroups();
@ -120,8 +127,10 @@ private:
void loadNets(); void loadNets();
// Helper functions for element loading: // Helper functions for element loading:
void logBoardStackupWarning( void logBoardStackupWarning( const wxString& aCadstarLayerName,
const wxString& aCadstarLayerName, const PCB_LAYER_ID& aKiCadLayer ); const PCB_LAYER_ID& aKiCadLayer );
void logBoardStackupMessage( const wxString& aCadstarLayerName,
const PCB_LAYER_ID& aKiCadLayer );
void loadLibraryFigures( const SYMDEF_PCB& aComponent, MODULE* aModule ); void loadLibraryFigures( const SYMDEF_PCB& aComponent, MODULE* aModule );
void loadLibraryCoppers( const SYMDEF_PCB& aComponent, MODULE* aModule ); void loadLibraryCoppers( const SYMDEF_PCB& aComponent, MODULE* aModule );
void loadLibraryAreas( const SYMDEF_PCB& aComponent, MODULE* aModule ); void loadLibraryAreas( const SYMDEF_PCB& aComponent, MODULE* aModule );

View File

@ -30,10 +30,35 @@
#include <properties.h> #include <properties.h>
LAYER_MAP CADSTAR_PCB_ARCHIVE_PLUGIN::DefaultLayerMappingCallback(
const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector )
{
LAYER_MAP retval;
// Just return a the auto-mapped layers
for( INPUT_LAYER_DESC layerDesc : aInputLayerDescriptionVector )
{
retval.insert( { layerDesc.Name, layerDesc.AutoMapLayer } );
}
return retval;
}
void CADSTAR_PCB_ARCHIVE_PLUGIN::RegisterLayerMappingCallback(
LAYER_MAPPING_HANDLER aLayerMappingHandler )
{
m_layer_mapping_handler = aLayerMappingHandler;
m_show_layer_mapping_warnings = false; // only show warnings with default callback
}
CADSTAR_PCB_ARCHIVE_PLUGIN::CADSTAR_PCB_ARCHIVE_PLUGIN() CADSTAR_PCB_ARCHIVE_PLUGIN::CADSTAR_PCB_ARCHIVE_PLUGIN()
{ {
m_board = nullptr; m_board = nullptr;
m_props = nullptr; m_props = nullptr;
m_layer_mapping_handler = CADSTAR_PCB_ARCHIVE_PLUGIN::DefaultLayerMappingCallback;
m_show_layer_mapping_warnings = true;
} }
@ -60,7 +85,8 @@ BOARD* CADSTAR_PCB_ARCHIVE_PLUGIN::Load(
m_props = aProperties; m_props = aProperties;
m_board = aAppendToMe ? aAppendToMe : new BOARD(); m_board = aAppendToMe ? aAppendToMe : new BOARD();
CADSTAR_PCB_ARCHIVE_LOADER tempPCB( aFileName ); CADSTAR_PCB_ARCHIVE_LOADER tempPCB(
aFileName, m_layer_mapping_handler, m_show_layer_mapping_warnings );
tempPCB.Load( m_board ); tempPCB.Load( m_board );
//center the board: //center the board:

View File

@ -29,6 +29,44 @@
#include <io_mgr.h> #include <io_mgr.h>
#include <layers_id_colors_and_visibility.h> // PCB_LAYER_ID
/**
* @brief Describes an imported layer and how it could be mapped to KiCad Layers
*/
struct INPUT_LAYER_DESC
{
wxString Name; ///< Imported layer name as displayed in original application.
LSET PermittedLayers; ///< KiCad layers that the imported layer can be mapped onto.
PCB_LAYER_ID AutoMapLayer; ///< Best guess as to what the equivalent KiCad layer might be.
INPUT_LAYER_DESC()
{
Name = wxEmptyString;
PermittedLayers = LSET();
AutoMapLayer = PCB_LAYER_ID::UNDEFINED_LAYER;
}
};
/**
* A CADSTAR layer name.
*/
typedef wxString INPUT_LAYER_NAME;
/**
* @brief Map of CADSTAR (INPUT_LAYER_NAME) to KiCad Layers.
* If the mapped KiCad layer is UNDEFINED_LAYER, then the CADSTAR layer will not
* be imported
*/
typedef std::map<INPUT_LAYER_NAME, PCB_LAYER_ID> LAYER_MAP;
/**
* @brief Pointer to a function that takes a map of Cadstar and KiCad layers
* and returns a re-mapped version. If the re-mapped layer
*/
typedef std::function<LAYER_MAP( const std::vector<INPUT_LAYER_DESC>& )> LAYER_MAPPING_HANDLER;
class CADSTAR_PCB_ARCHIVE_PLUGIN : public PLUGIN class CADSTAR_PCB_ARCHIVE_PLUGIN : public PLUGIN
{ {
@ -50,12 +88,29 @@ public:
// -----</PUBLIC PLUGIN API>------------------------------------------------- // -----</PUBLIC PLUGIN API>-------------------------------------------------
/**
* @brief Default callback - just returns the automapped layers
* @param aInputLayerDescriptionVector
* @return Auto-mapped layers
*/
static LAYER_MAP DefaultLayerMappingCallback(
const std::vector<INPUT_LAYER_DESC>& aInputLayerDescriptionVector );
/**
* @brief Register a different handler to be called when mapping of Cadstar to KiCad
* layers occurs
* @param aLayerMappingHandler
*/
void RegisterLayerMappingCallback( LAYER_MAPPING_HANDLER aLayerMappingHandler );
CADSTAR_PCB_ARCHIVE_PLUGIN(); CADSTAR_PCB_ARCHIVE_PLUGIN();
~CADSTAR_PCB_ARCHIVE_PLUGIN(); ~CADSTAR_PCB_ARCHIVE_PLUGIN();
private: private:
const PROPERTIES* m_props; const PROPERTIES* m_props;
BOARD* m_board; BOARD* m_board;
LAYER_MAPPING_HANDLER m_layer_mapping_handler;
bool m_show_layer_mapping_warnings;
}; };
#endif // CADSTAR_ARCHIVE_PLUGIN_H_ #endif // CADSTAR_ARCHIVE_PLUGIN_H_