First work about net classes. This is a work in progress and a moving target

This commit is contained in:
charras 2009-07-18 11:44:19 +00:00
parent ff58b0a819
commit e7c9ae2b45
24 changed files with 3378 additions and 487 deletions

View File

@ -4,6 +4,13 @@ KiCad ChangeLog 2009
Please add newer entries at the top, list the date and your name with
email address.
2009-july-18 UPDATE Jean-Pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
================================================================================
++pcbnew
First work about net classes. This is a work in progress and a moving target.
Manual routing and DRC do not used yet this feature
2009-Jul-13 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++pcbnew

View File

@ -61,6 +61,7 @@ set(PCB_COMMON_SRCS
../pcbnew/class_drawsegment.cpp
../pcbnew/class_drc_item.cpp
../pcbnew/class_edge_mod.cpp
../pcbnew/class_netclass.cpp
../pcbnew/class_netinfo_item.cpp
../pcbnew/class_netinfolist.cpp
../pcbnew/class_marker.cpp

View File

@ -728,7 +728,7 @@ enum main_id {
ID_PCB_USER_GRID_SETUP,
ID_PCB_DISPLAY_FOOTPRINT_DOC,
ID_PCB_GEN_BOM_FILE_FROM_BOARD,
ID_PCBUNUSED3,
ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
ID_PCBUNUSED4,
ID_PCBUNUSED5,
ID_PCBUNUSED6,

View File

@ -431,6 +431,11 @@ public:
void Show3D_Frame( wxCommandEvent& event );
void GeneralControle( wxDC* DC, wxPoint Mouse );
/** function ShowDesignRulesEditor
* Display the Design Rules Editor.
*/
void ShowDesignRulesEditor( wxCommandEvent& event );
/**
* Function UpdateToolbarLayerInfo
* updates the currently selected layer in the layer listbox and

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,8 @@ set(PCBNEW_SRCS
deltrack.cpp
dialog_copper_zones.cpp
dialog_copper_zones_base.cpp
dialog_design_rules.cpp
dialog_design_rules_base.cpp
dialog_display_options.cpp
dialog_display_options_base.cpp
dialog_drc_base.cpp

View File

@ -36,6 +36,11 @@ BOARD::BOARD( EDA_BaseStruct* parent, WinEDA_BasePcbFrame* frame ) :
m_Layer[layer].m_Name = ReturnPcbLayerName( layer, true );
m_Layer[layer].m_Type = LT_SIGNAL;
}
// Add the default Netclass to list
m_NetClassesList.m_Parent = this;
NETCLASS * default_netclass = new NETCLASS(this);
m_NetClassesList.AddNetclass( default_netclass );
}
@ -929,6 +934,9 @@ bool BOARD::Save( FILE* aFile ) const
bool rc = false;
BOARD_ITEM* item;
// save the netclasses
m_NetClassesList.Save( aFile );
// save the nets
for( unsigned ii = 0; ii < m_NetInfo->GetNetsCount(); ii++ )
if( !m_NetInfo->GetNetItem( ii )->Save( aFile ) )

View File

@ -22,7 +22,7 @@ enum LAYER_T {
LT_SIGNAL,
LT_POWER,
LT_MIXED,
LT_JUMPER,
LT_JUMPER
};
@ -97,6 +97,7 @@ public:
std::vector<RATSNEST_ITEM> m_LocalRatsnest; /* Rastnest list relative to a given footprint
* (used while moving a footprint) */
NETCLASS_LIST m_NetClassesList; // List of current netclasses. There is always the default netclass
ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress
BOARD( EDA_BaseStruct* aParent, WinEDA_BasePcbFrame* frame );
@ -335,6 +336,17 @@ public:
*/
int ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount );
/**
* Function TransfertDesignRulesToNets
* Copy Netclass parameters to each net, corresponding to its net class
* Must be called after a Design Rules edition, or after reading a netlist (or editing the list of nets)
* Also this function remove the non existing nets in netclasses and add net nets in default netclass
* (this happens after reading a netlist)
* @param none
* @return none
*/
void TransfertDesignRulesToNets( );
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.

298
pcbnew/class_netclass.cpp Normal file
View File

@ -0,0 +1,298 @@
/*************************************/
/* class to handle Net Classes */
/**************************************/
#include "fctsys.h"
#include "common.h"
#include "kicad_string.h"
#include "pcbnew.h"
NET_DESIGN_PARAMS::NET_DESIGN_PARAMS()
{
m_TracksWidth = 170; // "Default" value for tracks thickness used to route this net
m_TracksMinWidth = 150; // Minimum value for tracks thickness (used in DRC)
m_ViasSize = 550; // "Default" value for vias sizes used to route this net
m_ViasMinSize = 400; // Minimum value for vias sizes (used in DRC)
m_Clearance = 140; // "Default" clearance when routing
m_MinClearance = 110; // Minimum value for clearance (used in DRC)
}
/* A NETCLASS handles a list of nets and the parameters used to route or test (in DRC) these nets
* This is mainly used in autotouters like Freeroute, but this can be also used in manual routing
*/
NETCLASS::NETCLASS( BOARD* aParent, const wxString& aName )
{
m_Parent = aParent;
m_Name = aName; // Name of the net class
}
NETCLASS::~NETCLASS()
{
}
NETCLASS_LIST::NETCLASS_LIST( BOARD* aParent )
{
m_Parent = aParent;
std::vector <NETCLASS*> m_Netclass_List;
}
NETCLASS_LIST::~NETCLASS_LIST()
{
ClearList();
}
void NETCLASS_LIST::ClearList()
{
// the NETCLASS_LIST is owner of its items, so delete them
for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ )
delete m_Netclass_List[ii];
m_Netclass_List.clear();
}
/** Function AddNetclass()
* @param aNetclass = a pointer to the netclass to add
* @return true if Ok, false if cannot be added (mainly because a netclass with the same name exists)
*/
bool NETCLASS_LIST::AddNetclass( NETCLASS* aNetclass )
{
// Test for an existing netclass:
for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ )
{
if( m_Netclass_List[ii]->m_Name.CmpNoCase( aNetclass->m_Name ) == 0 )
return false; // this netclass already exists
}
m_Netclass_List.push_back( aNetclass );
return true;
}
/**
* Function TransfertDesignRulesToNets
* Copy Netclass parameters to each net, corresponding to its net class
* Must be called after a Design Rules edition, or after reading a netlist (or editing the list of nets)
* Also this function remove the non existing nets in netclasses and add net nets in default netclass
* (this happens after reading a netlist)
* @param none
* @return none
*/
void BOARD::TransfertDesignRulesToNets()
{
// Clear .m_Flag member of nets (used to detect not in netclass list nets)
for( unsigned ii = 1; ; ii++ )
{
NETINFO_ITEM* net = FindNet( ii );
if( net == NULL )
break;
net->m_Flag = 0;
}
for( unsigned ii = 0; ii < m_NetClassesList.m_Netclass_List.size(); ii++ )
{
//Transfert rules and netclass name to nets:
NETCLASS* netclass = m_NetClassesList.m_Netclass_List[ii];
for( unsigned jj = 0; jj < netclass->GetMembersCount(); jj++ )
{
wxString netname = netclass->GetMemberName( jj );
NETINFO_ITEM* net = FindNet( netname );
if( net == NULL ) // This net does not exists: remove it
{
netclass->m_MembersNetNames.RemoveAt( jj );
jj--;
}
else
{
net->SetClass( *netclass );
net->m_Flag = 1;
}
}
}
// Now, set nets that do not have yet a netclass to default netclass
NETCLASS* defaultnetclass = m_NetClassesList.m_Netclass_List[0];
for( unsigned ii = 1; ; ii++ )
{
NETINFO_ITEM* net = FindNet( ii );
if( net == NULL )
break;
if( net->m_Flag == 0 )
{
net->SetClass( *defaultnetclass );
defaultnetclass->AddMember( net->GetNetname() );
}
}
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool NETCLASS_LIST::Save( FILE* aFile ) const
{
bool success = true;
for( unsigned ii = 0; ii < m_Netclass_List.size(); ii++ )
{
success = m_Netclass_List[ii]->Save( aFile );
if( !success )
break;
}
return success;
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool NETCLASS::Save( FILE* aFile ) const
{
bool success = true;
fprintf( aFile, "$NETCLASS\n" );
fprintf( aFile, "Name \"%s\"\n", CONV_TO_UTF8( m_Name ) );
// Write parameters
success = m_NetParams.Save( aFile );
// Write members list:
for( unsigned ii = 0; ii < GetMembersCount(); ii++ )
fprintf( aFile, "AddNet \"%s\"\n", CONV_TO_UTF8( GetMemberName( ii ) ) );
fprintf( aFile, "$EndNETCLASS\n" );
return success;
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool NET_DESIGN_PARAMS::Save( FILE* aFile ) const
{
bool success = true;
fprintf( aFile, "$PARAMS_START\n" );
fprintf( aFile, "TracksWidth %d\n", m_TracksWidth );
fprintf( aFile, "TracksMinWidth %d\n", m_TracksMinWidth );
fprintf( aFile, "ViasSize %d\n", m_ViasSize );
fprintf( aFile, "ViasMinSize %d\n", m_ViasMinSize );
fprintf( aFile, "Clearance %d\n", m_Clearance );
fprintf( aFile, "MinClearance %d\n", m_MinClearance );
fprintf( aFile, "$PARAMS_END\n" );
return success;
}
/**
* Function ReadDescr
* reads the data structures for this object from a FILE in "*.brd" format.
* @param aFile The FILE to read to.
* @return bool - true if success reading else false.
*/
bool NET_DESIGN_PARAMS::ReadDescr( FILE* aFile, int* aLineNum )
{
bool success = true;
char Line[1024];
while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL )
{
if( strnicmp( Line, "$PARAMS_END", 11 ) == 0 )
return success;
if( strnicmp( Line, "TracksWidth", 11 ) == 0 )
{
m_TracksWidth = atoi( Line + 11 );
continue;
}
if( strnicmp( Line, "TracksMinWidth", 14 ) == 0 )
{
m_TracksMinWidth = atoi( Line + 14 );
continue;
}
if( strnicmp( Line, "ViasSize", 8 ) == 0 )
{
m_ViasSize = atoi( Line + 8 );
continue;
}
if( strnicmp( Line, "ViasMinSize", 11 ) == 0 )
{
m_ViasMinSize = atoi( Line + 11 );
continue;
}
if( strnicmp( Line, "Clearance", 9 ) == 0 )
{
m_Clearance = atoi( Line + 9 );
continue;
}
if( strnicmp( Line, "MinClearance", 12 ) == 0 )
{
m_MinClearance = atoi( Line + 12 );
continue;
}
}
return success;
}
/**
* Function ReadDescr
* reads the data structures for this object from a FILE in "*.brd" format.
* @param aFile The FILE to read to.
* @return bool - true if success reading else false.
*/
bool NETCLASS::ReadDescr( FILE* aFile, int* aLineNum )
{
bool success = true;
char Line[1024];
char Buffer[1024];
while( GetLine( aFile, Line, aLineNum, 1024 ) != NULL )
{
if( strnicmp( Line, "$endNETCLASS", 6 ) == 0 )
return success;
if( strnicmp( Line, "$PARAMS_START", 13 ) == 0 )
{
m_NetParams.ReadDescr( aFile, aLineNum );
continue;
}
if( strnicmp( Line, "Name", 4 ) == 0 )
{
ReadDelimitedText( Buffer, Line + 4, sizeof(Buffer) );
m_Name = CONV_FROM_UTF8( Buffer );
}
if( strnicmp( Line, "AddNet", 6 ) == 0 )
{
ReadDelimitedText( Buffer, Line + 6, sizeof(Buffer) );
wxString netname = CONV_FROM_UTF8( Buffer );
AddMember( netname );
}
}
return success;
}

156
pcbnew/class_netclass.h Normal file
View File

@ -0,0 +1,156 @@
/*************************************/
/* class to Net Classes */
/**************************************/
#ifndef CLASS_NETCLASS_H
#define CLASS_NETCLASS_H
/* this small class NET_DESIGN_PARAMS handles netclass parameters.
* This is a separate class because these parameters are also duplicated
* (for calculation time consideration) in each NETINFO_ITEM when making tests DRC and routing
*/
class NET_DESIGN_PARAMS
{
public:
int m_TracksWidth; // "Default" value for tracks thickness used to route this net
int m_TracksMinWidth; // Minimum value for tracks thickness (used in DRC)
int m_ViasSize; // "Default" value for vias sizes used to route this net
int m_ViasMinSize; // Minimum value for vias sizes (used in DRC)
int m_Clearance; // "Default" clearance when routing
int m_MinClearance; // Minimum value for clearance (used in DRC)
public:
NET_DESIGN_PARAMS();
~NET_DESIGN_PARAMS() {}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/**
* Function ReadDescr
* reads the data structures for this object from a FILE in "*.brd" format.
* @param aFile The FILE to read to.
* @return bool - true if success reading else false.
*/
bool ReadDescr( FILE* aFile, int* aLineNum );
};
/**
* @info A NETCLASS handles a list of nets and the parameters used to route or test these nets
*/
class NETCLASS
{
public:
BOARD* m_Parent;
wxString m_Name; // Name of the net class
wxArrayString m_MembersNetNames; // List of nets members of this class
NET_DESIGN_PARAMS m_NetParams; // values of net classes parameters
public:
NETCLASS( BOARD* aParent, const wxString& aName = wxT( "default" ) );
~NETCLASS();
/** Function GetMembersCount
*@return the number of nets using this rule
*/
unsigned GetMembersCount() const
{
return m_MembersNetNames.GetCount();
}
void ClearMembersList()
{
m_MembersNetNames.Clear();
}
void AddMember( const wxString& aNetname )
{
m_MembersNetNames.Add( aNetname );
}
wxString GetMemberName( unsigned aIdx ) const
{
if( aIdx < GetMembersCount() )
return m_MembersNetNames[aIdx];
else
return wxEmptyString;
}
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
/**
* Function ReadDescr
* reads the data structures for this object from a FILE in "*.brd" format.
* @param aFile The FILE to read to.
* @return bool - true if success reading else false.
*/
bool ReadDescr( FILE* aFile, int* aLineNum );
};
/* This NETCLASS_LIST handles the list of NETCLASS for the board
* Note: the NETCLASS_LIST is owner of all NETCLASS in list
*/
class NETCLASS_LIST
{
public:
BOARD* m_Parent;
std::vector <NETCLASS*> m_Netclass_List;
public:
NETCLASS_LIST( BOARD* aParent = NULL );
~NETCLASS_LIST();
void ClearList();
/** Function GetNetClassCount()
* @return the number of existing netclasses
*/
unsigned GetNetClassCount()
{
return m_Netclass_List.size();
}
/** Function GetNetClass()
* @param aIdx = the index in netclass list
* @return a NETCLASS* pointer on the netclass
*/
NETCLASS* GetNetClass( unsigned aIdx )
{
if( GetNetClassCount() && aIdx < GetNetClassCount() )
return m_Netclass_List[aIdx];
else
return NULL;
}
/** Function AddNetclass()
* @param aNetclass = a pointer to the netclass to add
* @return true if Ok, false if cannot be added (mainly because a netclass with the same name exists)
*/
bool AddNetclass( NETCLASS* aNetclass );
/**
* Function Save
* writes the data structures for this object out to a FILE in "*.brd" format.
* @param aFile The FILE to write to.
* @return bool - true if success writing else false.
*/
bool Save( FILE* aFile ) const;
};
#endif // #ifndef CLASS_NETCLASS_H

View File

@ -9,6 +9,8 @@
#ifndef __CLASSES_NETINFO__
#define __CLASSES_NETINFO__
#include "class_netclass.h"
// Forward declaration:
class NETINFO_ITEM;
@ -151,13 +153,17 @@ private:
// Used for fast comparisons in rastnest and DRC computations.
wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout used by eeschema
wxString m_ShortNetname; // short net name, like vout from /mysheet/mysubsheet/vout
wxString m_NetClassName; /* Net Class name. if void this is equivalent to "default" (the first
* item of the net classes list
*/
NET_DESIGN_PARAMS m_NetParams; // values of net classes parameters
public:
int m_NbNodes; // Pads count for this net
int m_NbLink; // Ratsnets count for this net
int m_NbNoconn; // Ratsnets remaining to route count
int m_ForceWidth; // specific width (0 = default width)
int m_Flag; // used in some calculations. Had no special meaning
std::vector <D_PAD*> m_ListPad; // List of pads connected to this net
unsigned m_RatsnestStartIdx; /* Starting point of ratsnests of this net (included)
* in a general buffer of ratsnest (a vector<RATSNEST_ITEM*> buffer)
@ -168,7 +174,86 @@ public:
~NETINFO_ITEM();
/* Readind and writing data on files */
/** Functions SetClassParameters
* copy the class parameters in the locale buffer m_NetParams
*/
void SetClassParameters(const NET_DESIGN_PARAMS& aParams )
{
m_NetParams = aParams;
}
/** Functions SetClass
* copy the class Name and class parmeters
*/
void SetClass(const NETCLASS& aNetclass )
{
m_NetParams = aNetclass.m_NetParams;
m_NetClassName = aNetclass.m_Name;
}
/** Functions GetClassName
* @return the class Name
*/
wxString GetClassName( ) const
{
return m_NetClassName;
}
/** function GetTracksWidth()
* @return the "default" value for tracks thickness used to route this net
*/
int GetTracksWidth()
{
return m_NetParams.m_TracksWidth;
}
/** Function GetTracksMinWidth()
* @return the Minimum value for tracks thickness (used in DRC)
*/
int GetTracksMinWidth()
{
return m_NetParams.m_TracksMinWidth = 150;
}
/** Function
* @return the "Default" value for vias sizes used to route this net
*/
int GetViasSize()
{
return m_NetParams.m_ViasSize;
}
/** Function GetViasMinSize()
* @return the Minimum value for vias sizes (used in DRC)
*/
int GetViasMinSize()
{
return m_NetParams.m_ViasMinSize;
}
/** Function GetClearance()
* @return the "Default" clearance when routing
*/
int GetClearance()
{
return m_NetParams.m_Clearance;
}
/** Function GetMinClearance()
* @return the Minimum value for clearance (used in DRC)
*/
int GetMinClearance()
{
return m_NetParams.m_MinClearance;
}
/* Reading and writing data on files */
int ReadDescr( FILE* File, int* LineNum );
/**

View File

@ -17,8 +17,10 @@
NETINFO_ITEM::NETINFO_ITEM( BOARD_ITEM* aParent )
{
SetNet( 0 );
m_NbNodes = m_NbLink = m_NbNoconn = 0;
m_ForceWidth = 0;
m_NbNodes = 0;
m_NbLink = 0;
m_NbNoconn = 0;
m_Flag = 0;
m_RatsnestStartIdx = 0; // Starting point of ratsnests of this net in a general buffer of ratsnest
m_RatsnestEndIdx = 0; // Ending point of ratsnests of this net
}
@ -58,10 +60,10 @@ int NETINFO_ITEM:: ReadDescr( FILE* File, int* LineNum )
continue;
}
if( strncmp( Line, "Lw", 2 ) == 0 ) /* Texte */
if( strncmp( Line, "NetClass", 8 ) == 0 ) /* Net Class */
{
sscanf( Line + 2, " %d", &tmp );
m_ForceWidth = tmp;
ReadDelimitedText( Ltmp, Line + 8, sizeof(Ltmp) );
m_NetClassName = CONV_FROM_UTF8( Ltmp );
continue;
}
}
@ -70,9 +72,9 @@ int NETINFO_ITEM:: ReadDescr( FILE* File, int* LineNum )
}
/**************************************/
/*******************************************/
bool NETINFO_ITEM::Save( FILE* aFile ) const
/**************************************/
/*******************************************/
/** Note: the old name of class NETINFO_ITEM was EQUIPOT
* so in Save (and read) functions, for compatibility, we use EQUIPOT as keyword
@ -84,8 +86,7 @@ bool NETINFO_ITEM::Save( FILE* aFile ) const
fprintf( aFile, "Na %d \"%s\"\n", GetNet(), CONV_TO_UTF8( m_Netname ) );
fprintf( aFile, "St %s\n", "~" );
if( m_ForceWidth )
fprintf( aFile, "Lw %d\n", m_ForceWidth );
fprintf( aFile, "NetClass \"%s\"\n", CONV_TO_UTF8(m_NetClassName) );
if( fprintf( aFile, "$EndEQUIPOT\n" ) != sizeof("$EndEQUIPOT\n") - 1 )
goto out;

View File

@ -125,6 +125,7 @@ void NETINFO_LIST::BuildListOfNets()
}
m_Parent->m_NbNodes = nodes_count;
m_Parent->TransfertDesignRulesToNets( );
m_Parent->m_Status_Pcb |= NET_CODES_OK;

View File

@ -0,0 +1,487 @@
/////////////////////////////////////////////////////////////////////////////
// Name: dialog_design_rules.cpp
// Author: jean-pierre Charras
/////////////////////////////////////////////////////////////////////////////
/* functions relatives to the design rules editor
*/
#include "fctsys.h"
#include "common.h"
#include "class_drawpanel.h"
#include "confirm.h"
#include "pcbnew.h"
#include "id.h"
#include "dialog_design_rules.h"
#include "wx/generic/gridctrl.h"
// Fields Positions on layer grid
#define LAYERS_GRID_ROUTABLE_POSITION 0
#define LAYERS_GRID_STATUS_POSITION 1
#define LAYERS_GRID_NAME_POSITION 2
// Fields Positions on rules grid
#define RULE_GRID_TRACKSIZE_POSITION 0
#define RULE_GRID_VIASIZE_POSITION 1
#define RULE_GRID_CLEARANCE_POSITION 2
#define RULE_GRID_MINTRACKSIZE_POSITION 3
#define RULE_GRID_MINVIASIZE_POSITION 4
/***********************************************************************************/
DIALOG_DESIGN_RULES::DIALOG_DESIGN_RULES( WinEDA_PcbFrame* parent ) :
DIALOG_DESIGN_RULES_BASE( parent )
/***********************************************************************************/
{
m_Parent = parent;
Init();
SetAutoLayout( true );
GetSizer()->Fit( this );
GetSizer()->SetSizeHints( this );
}
/********************************************************************/
void DIALOG_DESIGN_RULES::Init()
/********************************************************************/
{
SetFocus();
// Initialize the layers grid:
m_ActivesLayersCount = g_DesignSettings.m_CopperLayerCount;
m_Pcb = m_Parent->GetBoard();
m_Changes = 0;
m_LayersCountSelection->SetSelection( m_ActivesLayersCount / 2 );
// Initialize the Routable column
SetRoutableLayerStatus();
// Initialize the Status column (layers attribute)
LAYER_T typelist[4] = { LT_SIGNAL, LT_POWER, LT_MIXED, LT_JUMPER };
for( int ii = 0; ii < 4; ii++ )
{
m_LayersType[ii] = typelist[ii];
m_LayersTypeName[ii] = CONV_FROM_UTF8( LAYER::ShowType( typelist[ii] ) );
}
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
m_gridLayersProperties->SetCellEditor( ii, LAYERS_GRID_STATUS_POSITION,
new wxGridCellChoiceEditor( WXSIZEOF(
m_LayersTypeName ),
m_LayersTypeName ) );
int select = LT_SIGNAL;
for( int jj = 0; jj < 4; jj++ )
{
int layer = LAYER_CMP_N - ii;
if( m_Pcb->GetLayerType( layer ) == m_LayersType[jj] )
{
select = m_LayersType[jj];
break;
}
}
m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_STATUS_POSITION,
m_LayersTypeName[select] );
m_gridLayersProperties->SetCellOverflow( ii, LAYERS_GRID_STATUS_POSITION, false );
}
// Initialize the Name column
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
wxString layer_name = m_Pcb->GetLayerName( LAYER_CMP_N - ii );
m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_NAME_POSITION, layer_name );
}
// Initialize the Rules List
InitRulesList();
/* Initialize the list of nets buffers
(note the netcode 0 is not a real net, so it is not loaded)
*/
for ( unsigned ii = 1; ; ii ++ )
{
NETINFO_ITEM* net = m_Pcb->FindNet( ii );
if( net == NULL )
break;
m_StockNets.push_back(net);
// search the index in rules list for this net
int rules_idx = 0;
for (int jj = 0; jj < m_gridNetClassesProperties->GetNumberRows(); jj++ )
{
if( m_gridNetClassesProperties->GetRowLabelValue(jj).CmpNoCase(net->GetClassName()) == 0 )
{
rules_idx = jj;
break;
}
}
m_NetsLinkToClasses.push_back(rules_idx); // All nets are set to default net class
}
InitializeRulesSelectionBoxes();
}
/** Function FillListBoxWithNetsNames
* populates the aListBox with net names members of the aNetclassIndex net class
* the "Client Data pointer" is used to store the index of nets in ne nets lists
*/
void DIALOG_DESIGN_RULES::FillListBoxWithNetsNames(wxListBox* aListBox, int aNetclassIndex)
{
aListBox->Clear();
unsigned idx = 0;
for(unsigned ii = 0; ii < m_StockNets.size(); ii++ )
{
if (aNetclassIndex == m_NetsLinkToClasses[ii] )
{
aListBox->Append( m_StockNets[ii]->GetNetname() );
// Store the index of this net
aListBox->SetClientData(idx, (void *) ii);
idx++;
}
}
}
/* Initialize the combno boxes by the list of existing net classes
*/
void DIALOG_DESIGN_RULES::InitializeRulesSelectionBoxes()
{
m_CBoxRightSelection->Clear();
m_CBoxLeftSelection->Clear();
for (int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ )
{
m_CBoxRightSelection->Append(m_gridNetClassesProperties->GetRowLabelValue(ii));
m_CBoxLeftSelection->Append(m_gridNetClassesProperties->GetRowLabelValue(ii));
}
m_CBoxRightSelection->Select(0);
m_CBoxLeftSelection->Select(0);
m_buttonRightToLeft->Enable(false);
m_buttonLeftToRight->Enable(false);;
FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection() );
FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection() );
}
/* Initialize the Routable column, and the R/W property of some cells
*/
void DIALOG_DESIGN_RULES::SetRoutableLayerStatus()
{
m_gridLayersProperties->SetColFormatBool( LAYERS_GRID_ROUTABLE_POSITION );
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
int layer = LAYER_CMP_N - ii;
wxString value = layer < (m_ActivesLayersCount - 1) ? wxT( "1" ) : wxT( "0" );
if( m_ActivesLayersCount > 1 && layer == LAYER_CMP_N )
value = wxT( "1" );
if( layer == COPPER_LAYER_N )
value = wxT( "1" );
m_gridLayersProperties->SetCellValue( ii, LAYERS_GRID_ROUTABLE_POSITION, value );
m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_ROUTABLE_POSITION );
// Set to Read Only cell for non existing copper layers:
m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_STATUS_POSITION, value != wxT( "1" ) );
m_gridLayersProperties->SetReadOnly( ii, LAYERS_GRID_NAME_POSITION, value != wxT( "1" ) );
}
}
/* Initialize the rules list from board
*/
void DIALOG_DESIGN_RULES::InitRulesList()
{
for( int ii = 0; ; ii++ )
{
const NETCLASS * netclass = m_Pcb->m_NetClassesList.GetNetClass(ii);
if ( netclass == NULL )
break;
// Creates one entry if needed
if (ii >= m_gridNetClassesProperties->GetNumberRows() )
m_gridNetClassesProperties->AppendRows( );
// Init name
m_gridNetClassesProperties->SetRowLabelValue(ii, netclass->m_Name);
// Init data
wxString msg;
msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_TracksWidth,
m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_TRACKSIZE_POSITION, msg);
msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_ViasSize,
m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_VIASIZE_POSITION, msg);
msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_Clearance,
m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_CLEARANCE_POSITION, msg);
msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_TracksMinWidth,
m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_MINTRACKSIZE_POSITION, msg);
msg = ReturnStringFromValue( g_UnitMetric,
netclass->m_NetParams.m_ViasMinSize,
m_Parent->m_InternalUnits, false );
m_gridNetClassesProperties->SetCellValue(ii, RULE_GRID_MINVIASIZE_POSITION, msg);
}
}
/* Copy the rules list to board
*/
void DIALOG_DESIGN_RULES::CopyRulesListToBoard()
{
m_Pcb->m_NetClassesList.ClearList();
for( int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ )
{
NETCLASS * netclass = new NETCLASS(m_Pcb,
m_gridNetClassesProperties->GetRowLabelValue(ii) );
m_Pcb->m_NetClassesList.AddNetclass(netclass);
// Init data
netclass->m_NetParams.m_TracksWidth =
ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_TRACKSIZE_POSITION),
m_Parent->m_InternalUnits );
netclass->m_NetParams.m_ViasSize =
ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_VIASIZE_POSITION),
m_Parent->m_InternalUnits );
netclass->m_NetParams.m_Clearance =
ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_CLEARANCE_POSITION),
m_Parent->m_InternalUnits );
netclass->m_NetParams.m_TracksMinWidth =
ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_MINTRACKSIZE_POSITION),
m_Parent->m_InternalUnits );
netclass->m_NetParams.m_ViasMinSize =
ReturnValueFromString( g_UnitMetric,
m_gridNetClassesProperties->GetCellValue(ii, RULE_GRID_MINVIASIZE_POSITION),
m_Parent->m_InternalUnits );
// Copy the list of nets associated to this netclass:
for(unsigned idx = 0; idx < m_StockNets.size(); idx++ )
{
if( m_NetsLinkToClasses[idx] == ii )
netclass->AddMember(m_StockNets[idx]->GetNetname());
}
}
m_Pcb->TransfertDesignRulesToNets( );
}
/*****************************************************************/
void DIALOG_DESIGN_RULES::OnCancelButtonClick( wxCommandEvent& event )
/*****************************************************************/
{
EndModal( 0 );
}
/**************************************************************************/
void DIALOG_DESIGN_RULES::OnOkButtonClick( wxCommandEvent& event )
/**************************************************************************/
{
g_DesignSettings.m_CopperLayerCount = m_ActivesLayersCount;
// Initialize the new layer name
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
wxString layer_name = m_gridLayersProperties->GetCellValue( ii, LAYERS_GRID_NAME_POSITION );
if( layer_name != m_Pcb->GetLayerName( LAYER_CMP_N - ii ) )
{
m_Pcb->SetLayerName( LAYER_CMP_N - ii, layer_name );
}
}
// Initialize the layer type
for( int ii = 0; ii < m_gridLayersProperties->GetNumberRows(); ii++ )
{
wxString txt = m_gridLayersProperties->GetCellValue( ii, LAYERS_GRID_STATUS_POSITION );
int layer = LAYER_CMP_N - ii;
for( int jj = 0; jj < 3; jj++ )
{
if( m_LayersTypeName[jj] == txt )
{
m_Pcb->SetLayerType( layer, m_LayersType[jj] );
break;
}
}
}
CopyRulesListToBoard();
EndModal( 1 );
}
/**************************************************************************/
void DIALOG_DESIGN_RULES::OnLayerCountClick( wxCommandEvent& event )
/**************************************************************************/
{
m_ActivesLayersCount = m_LayersCountSelection->GetSelection() * 2;
if( m_ActivesLayersCount <= 0 )
m_ActivesLayersCount = 1;
// Reinit the routable layers status
SetRoutableLayerStatus();
}
/**************************************************************************/
void DIALOG_DESIGN_RULES::OnAddNetclassClick( wxCommandEvent& event )
/**************************************************************************/
{
wxString class_name;
if( Get_Message( _("New Net Class Name:"),
wxEmptyString,
class_name,
this ) )
return;
// The name must dot exists:
for( int ii = 0; ii < m_gridNetClassesProperties->GetNumberRows(); ii++ )
{
wxString value;
value = m_gridNetClassesProperties->GetRowLabelValue(ii);
if( class_name.CmpNoCase( value) == 0 ) // Already exists!
{
DisplayError(this, _("This NetClass is alerady existing, cannot add it") );
return;
}
}
m_gridNetClassesProperties->AppendRows( );
m_gridNetClassesProperties->SetRowLabelValue(
m_gridNetClassesProperties->GetNumberRows()-1,
class_name);
// Copy values of the previous class:
int irow = m_gridNetClassesProperties->GetNumberRows()-1;
for( int icol = 0; icol < m_gridNetClassesProperties->GetNumberCols(); icol++ )
{
wxString value;
value = m_gridNetClassesProperties->GetCellValue(irow-1, icol);
m_gridNetClassesProperties->SetCellValue(irow, icol, value);
}
InitializeRulesSelectionBoxes();
}
/**************************************************************************/
void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event )
/**************************************************************************/
{
wxArrayInt select = m_gridNetClassesProperties->GetSelectedRows();
for( int ii = select.GetCount()-1; ii >= 0; ii-- )
{
if( select[ii] != 0 ) // Do not remove the default class
{
m_gridNetClassesProperties->DeleteRows(select[ii]);
// reset the net class to default for nets member of the removed net class
for ( unsigned jj = 0; jj< m_NetsLinkToClasses.size(); jj++ )
if( m_NetsLinkToClasses[jj] == ii )
m_NetsLinkToClasses[jj] = 0; // Reset to default net class
}
}
InitializeRulesSelectionBoxes();
}
/*
* Called on the left Choice Box selection
*/
void DIALOG_DESIGN_RULES::OnLeftCBSelection( wxCommandEvent& event )
{
FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection() );
if ( m_CBoxLeftSelection->GetCurrentSelection() == m_CBoxRightSelection->GetCurrentSelection() )
{
m_buttonRightToLeft->Enable(false);
m_buttonLeftToRight->Enable(false);
}
else
{
m_buttonRightToLeft->Enable(true);
m_buttonLeftToRight->Enable(true);
}
}
/*
* Called on the Right Choice Box selection
*/
void DIALOG_DESIGN_RULES::OnRightCBSelection( wxCommandEvent& event )
{
FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection() );
if ( m_CBoxLeftSelection->GetCurrentSelection() == m_CBoxRightSelection->GetCurrentSelection() )
{
m_buttonRightToLeft->Enable(false);
m_buttonLeftToRight->Enable(false);;
}
else
{
m_buttonRightToLeft->Enable(true);
m_buttonLeftToRight->Enable(true);
}
}
/* Called on clicking the "<<<" or Copy Right to Left button:
* Selected items are moved from the right list to the left list
*/
void DIALOG_DESIGN_RULES::OnRightToLeftCopyButton( wxCommandEvent& event )
{
int idx_class = m_CBoxLeftSelection->GetCurrentSelection();
if ( idx_class == wxNOT_FOUND )
return;
for( unsigned ii = 0; ii < m_listBoxRightNetSelect->GetCount(); ii++ )
{
if( ! m_listBoxRightNetSelect->IsSelected(ii) )
continue;
unsigned idx = (unsigned) m_listBoxRightNetSelect->GetClientData( ii);
m_NetsLinkToClasses[idx] = idx_class;
}
FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection());
FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection());
}
/* Called on clicking the ">>>" or Copy Left to Right button:
* Selected items are moved from the left list to the right list
*/
void DIALOG_DESIGN_RULES::OnLeftToRightCopyButton( wxCommandEvent& event )
{
int idx_class = m_CBoxRightSelection->GetCurrentSelection();
if ( idx_class == wxNOT_FOUND )
return;
for( unsigned ii = 0; ii < m_listBoxLeftNetSelect->GetCount(); ii++ )
{
if( ! m_listBoxLeftNetSelect->IsSelected(ii) )
continue;
unsigned idx = (unsigned) m_listBoxLeftNetSelect->GetClientData(ii);
m_NetsLinkToClasses[idx] = idx_class;
}
FillListBoxWithNetsNames(m_listBoxLeftNetSelect, m_CBoxLeftSelection->GetCurrentSelection());
FillListBoxWithNetsNames(m_listBoxRightNetSelect, m_CBoxRightSelection->GetCurrentSelection());
}
/* Called on clicking the left "select all" button:
* select alls items of the left netname list lisxt box
*/
void DIALOG_DESIGN_RULES::OnLeftSelectAllButton( wxCommandEvent& event )
{
for( unsigned ii = 0; ii < m_listBoxLeftNetSelect->GetCount(); ii++ )
m_listBoxLeftNetSelect->SetSelection(ii);
}
/* Called on clicking the right "select all" button:
* select alls items of the right netname list lisxt box
*/
void DIALOG_DESIGN_RULES::OnRightSelectAllButton( wxCommandEvent& event )
{
for( unsigned ii = 0; ii < m_listBoxRightNetSelect->GetCount(); ii++ )
m_listBoxRightNetSelect->SetSelection(ii);
}

View File

@ -0,0 +1,52 @@
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_DESIGN_RULES
///////////////////////////////////////////////////////////////////////////////
#ifndef __dialog_design_rules_h_
#define __dialog_design_rules_h_
#include "dialog_design_rules_base.h"
class DIALOG_DESIGN_RULES : public DIALOG_DESIGN_RULES_BASE
{
private:
WinEDA_PcbFrame * m_Parent;
int m_ActivesLayersCount;
BOARD * m_Pcb;
int m_Changes;
LAYER_T m_LayersType[4];
wxString m_LayersTypeName[4];
std::vector<NETINFO_ITEM*> m_StockNets; // full list of nets on board
std::vector<int> m_NetsLinkToClasses; // index to affect each net to an existing net class
private:
void OnLayerCountClick( wxCommandEvent& event );
void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); }
void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); }
void OnNetClassesGridLeftClick( wxGridEvent& event ){ event.Skip(); }
void OnNetClassesGridRightClick( wxGridEvent& event ){ event.Skip(); }
void OnCancelButtonClick( wxCommandEvent& event );
void OnOkButtonClick( wxCommandEvent& event );
void OnAddNetclassClick( wxCommandEvent& event );
void OnRemoveNetclassClick( wxCommandEvent& event );
void OnLeftCBSelection( wxCommandEvent& event );
void OnRightCBSelection( wxCommandEvent& event );
void OnRightToLeftCopyButton( wxCommandEvent& event );
void OnLeftToRightCopyButton( wxCommandEvent& event );
void OnLeftSelectAllButton( wxCommandEvent& event );
void OnRightSelectAllButton( wxCommandEvent& event );
void Init();
void InitRulesList();
void InitializeRulesSelectionBoxes();
void CopyRulesListToBoard();
void SetRoutableLayerStatus( );
void FillListBoxWithNetsNames(wxListBox* aListBox, int aNetclassIndex);
public:
DIALOG_DESIGN_RULES( WinEDA_PcbFrame* parent );
~DIALOG_DESIGN_RULES( ) { };
};
#endif //__dialog_design_rules_h_

View File

@ -0,0 +1,260 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "dialog_design_rules_base.h"
///////////////////////////////////////////////////////////////////////////
DIALOG_DESIGN_RULES_BASE::DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( 600,450 ), wxDefaultSize );
wxBoxSizer* bMainSizer;
bMainSizer = new wxBoxSizer( wxVERTICAL );
m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
m_panelLayers = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bMainSizerLayers;
bMainSizerLayers = new wxBoxSizer( wxHORIZONTAL );
wxString m_LayersCountSelectionChoices[] = { _("1"), _("2"), _("4"), _("6"), _("8"), _("10"), _("12"), _("14"), _("16") };
int m_LayersCountSelectionNChoices = sizeof( m_LayersCountSelectionChoices ) / sizeof( wxString );
m_LayersCountSelection = new wxRadioBox( m_panelLayers, ID_LAYERS_COUNT_SELECTION, _("Layers Count"), wxDefaultPosition, wxDefaultSize, m_LayersCountSelectionNChoices, m_LayersCountSelectionChoices, 1, wxRA_SPECIFY_COLS );
m_LayersCountSelection->SetSelection( 1 );
bMainSizerLayers->Add( m_LayersCountSelection, 0, wxALL, 5 );
m_gridLayersProperties = new wxGrid( m_panelLayers, ID_LAYERS_PROPERTIES, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_gridLayersProperties->CreateGrid( 16, 3 );
m_gridLayersProperties->EnableEditing( true );
m_gridLayersProperties->EnableGridLines( true );
m_gridLayersProperties->EnableDragGridSize( false );
m_gridLayersProperties->SetMargins( 0, 0 );
// Columns
m_gridLayersProperties->SetColSize( 0, 100 );
m_gridLayersProperties->SetColSize( 1, 100 );
m_gridLayersProperties->SetColSize( 2, 150 );
m_gridLayersProperties->EnableDragColMove( false );
m_gridLayersProperties->EnableDragColSize( true );
m_gridLayersProperties->SetColLabelSize( 30 );
m_gridLayersProperties->SetColLabelValue( 0, _("Active") );
m_gridLayersProperties->SetColLabelValue( 1, _("Status") );
m_gridLayersProperties->SetColLabelValue( 2, _("Name") );
m_gridLayersProperties->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridLayersProperties->AutoSizeRows();
m_gridLayersProperties->EnableDragRowSize( true );
m_gridLayersProperties->SetRowLabelSize( 80 );
m_gridLayersProperties->SetRowLabelValue( 0, _("Top Layer") );
m_gridLayersProperties->SetRowLabelValue( 1, _("Inner 14") );
m_gridLayersProperties->SetRowLabelValue( 2, _("Inner 13") );
m_gridLayersProperties->SetRowLabelValue( 3, _("Inner 12") );
m_gridLayersProperties->SetRowLabelValue( 4, _("Inner 11") );
m_gridLayersProperties->SetRowLabelValue( 5, _("Inner 10") );
m_gridLayersProperties->SetRowLabelValue( 6, _("Inner 9") );
m_gridLayersProperties->SetRowLabelValue( 7, _("Inner 8") );
m_gridLayersProperties->SetRowLabelValue( 8, _("Inner 7") );
m_gridLayersProperties->SetRowLabelValue( 9, _("Inner 6") );
m_gridLayersProperties->SetRowLabelValue( 10, _("Inner 5") );
m_gridLayersProperties->SetRowLabelValue( 11, _("Inner 4") );
m_gridLayersProperties->SetRowLabelValue( 12, _("Inner 3") );
m_gridLayersProperties->SetRowLabelValue( 13, _("Inner 2") );
m_gridLayersProperties->SetRowLabelValue( 14, _("Inner 1") );
m_gridLayersProperties->SetRowLabelValue( 15, _("Bottom Layer") );
m_gridLayersProperties->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridLayersProperties->SetDefaultCellAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
bMainSizerLayers->Add( m_gridLayersProperties, 1, wxALL|wxEXPAND, 5 );
m_panelLayers->SetSizer( bMainSizerLayers );
m_panelLayers->Layout();
bMainSizerLayers->Fit( m_panelLayers );
m_notebook->AddPage( m_panelLayers, _("Layers"), true );
m_panelNetClasses = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bmainSizerNclasses;
bmainSizerNclasses = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbSizer1;
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( m_panelNetClasses, wxID_ANY, _("Net classes:") ), wxHORIZONTAL );
m_gridNetClassesProperties = new wxGrid( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_gridNetClassesProperties->CreateGrid( 1, 5 );
m_gridNetClassesProperties->EnableEditing( true );
m_gridNetClassesProperties->EnableGridLines( true );
m_gridNetClassesProperties->EnableDragGridSize( false );
m_gridNetClassesProperties->SetMargins( 0, 0 );
// Columns
m_gridNetClassesProperties->SetColSize( 0, 100 );
m_gridNetClassesProperties->SetColSize( 1, 100 );
m_gridNetClassesProperties->SetColSize( 2, 100 );
m_gridNetClassesProperties->SetColSize( 3, 100 );
m_gridNetClassesProperties->SetColSize( 4, 100 );
m_gridNetClassesProperties->EnableDragColMove( false );
m_gridNetClassesProperties->EnableDragColSize( true );
m_gridNetClassesProperties->SetColLabelSize( 30 );
m_gridNetClassesProperties->SetColLabelValue( 0, _("Track size") );
m_gridNetClassesProperties->SetColLabelValue( 1, _("Vias size") );
m_gridNetClassesProperties->SetColLabelValue( 2, _("Clearance") );
m_gridNetClassesProperties->SetColLabelValue( 3, _("Track Min Size") );
m_gridNetClassesProperties->SetColLabelValue( 4, _("Via Min Size") );
m_gridNetClassesProperties->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Rows
m_gridNetClassesProperties->AutoSizeRows();
m_gridNetClassesProperties->EnableDragRowSize( true );
m_gridNetClassesProperties->SetRowLabelSize( 80 );
m_gridNetClassesProperties->SetRowLabelValue( 0, _("Default") );
m_gridNetClassesProperties->SetRowLabelValue( 1, _("Special") );
m_gridNetClassesProperties->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Label Appearance
// Cell Defaults
m_gridNetClassesProperties->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_gridNetClassesProperties->SetMinSize( wxSize( -1,100 ) );
sbSizer1->Add( m_gridNetClassesProperties, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizerButtons;
bSizerButtons = new wxBoxSizer( wxVERTICAL );
m_buttonADD = new wxButton( m_panelNetClasses, wxID_ADD_NETCLASS, _("Add"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButtons->Add( m_buttonADD, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
m_buttonRemove = new wxButton( m_panelNetClasses, wxID_REMOVE_NETCLASS, _("Remove"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButtons->Add( m_buttonRemove, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 );
sbSizer1->Add( bSizerButtons, 0, wxALIGN_CENTER_VERTICAL, 5 );
bmainSizerNclasses->Add( sbSizer1, 1, wxEXPAND, 5 );
wxBoxSizer* bSizerNetSelect;
bSizerNetSelect = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bLeftSizerNetSelect;
bLeftSizerNetSelect = new wxBoxSizer( wxVERTICAL );
wxArrayString m_CBoxLeftSelectionChoices;
m_CBoxLeftSelection = new wxChoice( m_panelNetClasses, ID_LEFT_CHOICE_CLICK, wxDefaultPosition, wxDefaultSize, m_CBoxLeftSelectionChoices, 0 );
m_CBoxLeftSelection->SetSelection( 0 );
bLeftSizerNetSelect->Add( m_CBoxLeftSelection, 0, wxALL|wxEXPAND, 5 );
m_listBoxLeftNetSelect = new wxListBox( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_MULTIPLE );
bLeftSizerNetSelect->Add( m_listBoxLeftNetSelect, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bSizerNetSelect->Add( bLeftSizerNetSelect, 1, wxEXPAND, 5 );
wxBoxSizer* bmiddleSizerNetSelect;
bmiddleSizerNetSelect = new wxBoxSizer( wxVERTICAL );
m_buttonRightToLeft = new wxButton( m_panelNetClasses, ID_LEFT_TO_RIGHT_COPY, _("<<<"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizerNetSelect->Add( m_buttonRightToLeft, 0, wxALIGN_CENTER_HORIZONTAL|wxRIGHT|wxLEFT, 5 );
m_buttonLeftToRight = new wxButton( m_panelNetClasses, ID_RIGHT_TO_LEFT_COPY, _(">>>"), wxDefaultPosition, wxDefaultSize, 0 );
bmiddleSizerNetSelect->Add( m_buttonLeftToRight, 0, wxALIGN_CENTER_HORIZONTAL|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bSizerButtonsSelecAll;
bSizerButtonsSelecAll = new wxBoxSizer( wxHORIZONTAL );
m_buttonLeftSelAll = new wxButton( m_panelNetClasses, wxID_ANY, _("<< Select All"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButtonsSelecAll->Add( m_buttonLeftSelAll, 0, wxTOP|wxBOTTOM, 5 );
m_buttonRightSelAll = new wxButton( m_panelNetClasses, wxID_ANY, _("Select All >>"), wxDefaultPosition, wxDefaultSize, 0 );
bSizerButtonsSelecAll->Add( m_buttonRightSelAll, 0, wxALIGN_RIGHT|wxALIGN_BOTTOM|wxTOP|wxBOTTOM, 5 );
bmiddleSizerNetSelect->Add( bSizerButtonsSelecAll, 0, wxALIGN_CENTER_HORIZONTAL, 5 );
bSizerNetSelect->Add( bmiddleSizerNetSelect, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxBoxSizer* bLeftSizerNetSelect1;
bLeftSizerNetSelect1 = new wxBoxSizer( wxVERTICAL );
wxArrayString m_CBoxRightSelectionChoices;
m_CBoxRightSelection = new wxChoice( m_panelNetClasses, ID_RIGHT_CHOICE_CLICK, wxDefaultPosition, wxDefaultSize, m_CBoxRightSelectionChoices, 0 );
m_CBoxRightSelection->SetSelection( 0 );
bLeftSizerNetSelect1->Add( m_CBoxRightSelection, 0, wxALL|wxEXPAND, 5 );
m_listBoxRightNetSelect = new wxListBox( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, wxLB_EXTENDED|wxLB_MULTIPLE );
bLeftSizerNetSelect1->Add( m_listBoxRightNetSelect, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bSizerNetSelect->Add( bLeftSizerNetSelect1, 1, wxEXPAND, 5 );
bmainSizerNclasses->Add( bSizerNetSelect, 1, wxEXPAND, 5 );
m_staticTextMsg = new wxStaticText( m_panelNetClasses, wxID_ANY, _("Messages:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextMsg->Wrap( -1 );
bmainSizerNclasses->Add( m_staticTextMsg, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_MessagesList = new wxHtmlWindow( m_panelNetClasses, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO|wxSUNKEN_BORDER );
m_MessagesList->SetMinSize( wxSize( -1,100 ) );
bmainSizerNclasses->Add( m_MessagesList, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
m_panelNetClasses->SetSizer( bmainSizerNclasses );
m_panelNetClasses->Layout();
bmainSizerNclasses->Fit( m_panelNetClasses );
m_notebook->AddPage( m_panelNetClasses, _("Net Classes"), false );
bMainSizer->Add( m_notebook, 1, wxALL|wxEXPAND, 5 );
m_sdbSizer1 = new wxStdDialogButtonSizer();
m_sdbSizer1OK = new wxButton( this, wxID_OK );
m_sdbSizer1->AddButton( m_sdbSizer1OK );
m_sdbSizer1Cancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer1->AddButton( m_sdbSizer1Cancel );
m_sdbSizer1->Realize();
bMainSizer->Add( m_sdbSizer1, 0, wxALIGN_RIGHT, 5 );
this->SetSizer( bMainSizer );
this->Layout();
// Connect Events
m_LayersCountSelection->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerCountClick ), NULL, this );
m_gridLayersProperties->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridLeftClick ), NULL, this );
m_gridLayersProperties->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridRighttClick ), NULL, this );
m_gridNetClassesProperties->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridLeftClick ), NULL, this );
m_gridNetClassesProperties->Connect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this );
m_buttonADD->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this );
m_buttonRemove->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this );
m_CBoxLeftSelection->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this );
m_buttonRightToLeft->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this );
m_buttonLeftToRight->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this );
m_buttonLeftSelAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftSelectAllButton ), NULL, this );
m_buttonRightSelAll->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightSelectAllButton ), NULL, this );
m_CBoxRightSelection->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this );
m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnCancelButtonClick ), NULL, this );
m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnOkButtonClick ), NULL, this );
}
DIALOG_DESIGN_RULES_BASE::~DIALOG_DESIGN_RULES_BASE()
{
// Disconnect Events
m_LayersCountSelection->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerCountClick ), NULL, this );
m_gridLayersProperties->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridLeftClick ), NULL, this );
m_gridLayersProperties->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnLayerGridRighttClick ), NULL, this );
m_gridNetClassesProperties->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridLeftClick ), NULL, this );
m_gridNetClassesProperties->Disconnect( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEventHandler( DIALOG_DESIGN_RULES_BASE::OnNetClassesGridRightClick ), NULL, this );
m_buttonADD->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnAddNetclassClick ), NULL, this );
m_buttonRemove->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRemoveNetclassClick ), NULL, this );
m_CBoxLeftSelection->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftCBSelection ), NULL, this );
m_buttonRightToLeft->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightToLeftCopyButton ), NULL, this );
m_buttonLeftToRight->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftToRightCopyButton ), NULL, this );
m_buttonLeftSelAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnLeftSelectAllButton ), NULL, this );
m_buttonRightSelAll->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightSelectAllButton ), NULL, this );
m_CBoxRightSelection->Disconnect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnRightCBSelection ), NULL, this );
m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnCancelButtonClick ), NULL, this );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_DESIGN_RULES_BASE::OnOkButtonClick ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Apr 16 2008)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_design_rules_base__
#define __dialog_design_rules_base__
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/radiobox.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/grid.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/statbox.h>
#include <wx/choice.h>
#include <wx/listbox.h>
#include <wx/stattext.h>
#include <wx/html/htmlwin.h>
#include <wx/notebook.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
#define ID_LAYERS_COUNT_SELECTION 1000
#define ID_LAYERS_PROPERTIES 1001
#define wxID_ADD_NETCLASS 1002
#define wxID_REMOVE_NETCLASS 1003
#define ID_LEFT_CHOICE_CLICK 1004
#define ID_LEFT_TO_RIGHT_COPY 1005
#define ID_RIGHT_TO_LEFT_COPY 1006
#define ID_RIGHT_CHOICE_CLICK 1007
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_DESIGN_RULES_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_DESIGN_RULES_BASE : public wxDialog
{
private:
protected:
wxNotebook* m_notebook;
wxPanel* m_panelLayers;
wxRadioBox* m_LayersCountSelection;
wxGrid* m_gridLayersProperties;
wxPanel* m_panelNetClasses;
wxGrid* m_gridNetClassesProperties;
wxButton* m_buttonADD;
wxButton* m_buttonRemove;
wxChoice* m_CBoxLeftSelection;
wxListBox* m_listBoxLeftNetSelect;
wxButton* m_buttonRightToLeft;
wxButton* m_buttonLeftToRight;
wxButton* m_buttonLeftSelAll;
wxButton* m_buttonRightSelAll;
wxChoice* m_CBoxRightSelection;
wxListBox* m_listBoxRightNetSelect;
wxStaticText* m_staticTextMsg;
wxHtmlWindow* m_MessagesList;
wxStdDialogButtonSizer* m_sdbSizer1;
wxButton* m_sdbSizer1OK;
wxButton* m_sdbSizer1Cancel;
// Virtual event handlers, overide them in your derived class
virtual void OnLayerCountClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLayerGridLeftClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnLayerGridRighttClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnNetClassesGridLeftClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnNetClassesGridRightClick( wxGridEvent& event ){ event.Skip(); }
virtual void OnAddNetclassClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRemoveNetclassClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftCBSelection( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightToLeftCopyButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftToRightCopyButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnLeftSelectAllButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightSelectAllButton( wxCommandEvent& event ){ event.Skip(); }
virtual void OnRightCBSelection( wxCommandEvent& event ){ event.Skip(); }
virtual void OnCancelButtonClick( wxCommandEvent& event ){ event.Skip(); }
virtual void OnOkButtonClick( wxCommandEvent& event ){ event.Skip(); }
public:
DIALOG_DESIGN_RULES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Design Rules Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 684,486 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_DESIGN_RULES_BASE();
};
#endif //__dialog_design_rules_base__

View File

@ -776,7 +776,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
/** ReadPcbFile
* Read a board file <file>.brd
* @param Append if 0: a previoulsy loaded boar is delete before loadin the file.
* @param Append if 0: a previoulsy loaded board is deleted before loading the file.
* else all items of the board file are added to the existing board
*/
{
@ -790,6 +790,7 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
NbDraw = NbTrack = NbZone = NbMod = NbNets = -1;
GetBoard()->m_Status_Pcb = 0;
GetBoard()->m_NetClassesList.ClearList();
while( GetLine( File, Line, &LineNum ) != NULL )
{
@ -831,6 +832,15 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
continue;
}
if( strnicmp( Line, "$NETCLASS", 8 ) == 0 )
{
NETCLASS* netclass = new NETCLASS( GetBoard() );
netclass->ReadDescr( File, &LineNum );
if( ! GetBoard()->m_NetClassesList.AddNetclass( netclass ) )
delete netclass;
continue;
}
if( strnicmp( Line, "$CZONE_OUTLINE", 7 ) == 0 )
{
ZONE_CONTAINER * zone_descr = new ZONE_CONTAINER(GetBoard());
@ -913,6 +923,15 @@ int WinEDA_PcbFrame::ReadPcbFile( FILE* File, bool Append )
BestZoom();
// One netclass *must* exists (the default netclass)
if( GetBoard()->m_NetClassesList.GetNetClassCount() == 0 )
{
NETCLASS* ncdefault = new NETCLASS(GetBoard());
GetBoard()->m_NetClassesList.AddNetclass( ncdefault );
}
GetBoard()->TransfertDesignRulesToNets( );
GetBoard()->m_Status_Pcb = 0;
return 1;
}

View File

@ -205,6 +205,13 @@ void WinEDA_PcbFrame::ReCreateMenuBar()
configmenu->AppendSeparator();
AddHotkeyConfigMenu( configmenu );
// Add acces to the Design Rules Dialog:
wxMenu* designRulesMenu = new wxMenu;
item = new wxMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
_( "Design Rules" ), _( "Open the design rules dialog editor" ) );
item->SetBitmap( hammer_xpm );
designRulesMenu->Append( item );
/////////////////////////////
// Ajustage de dimensions: //
/////////////////////////////
@ -319,6 +326,7 @@ void WinEDA_PcbFrame::ReCreateMenuBar()
menuBar->Append( filesMenu, _( "&File" ) );
menuBar->Append( configmenu, _( "&Preferences" ) );
menuBar->Append( designRulesMenu, _( "&Design Rules" ) );
menuBar->Append( sizes_menu, _( "&Dimensions" ) );
menuBar->Append( miscellaneous_menu, _( "&Miscellaneous" ) );
menuBar->Append( postprocess_menu, _( "P&ostprocess" ) );

View File

@ -38,6 +38,9 @@ static wxMenu* Append_Track_Width_List()
trackwidth_menu = new wxMenu;
ADD_MENUITEM( trackwidth_menu, ID_PCB_TRACK_SIZE_SETUP,
_( "New Width/Size" ), showtrack_xpm );
trackwidth_menu->Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH,
_( "Auto Width" ),
_(

View File

@ -16,6 +16,8 @@
#include "3d_viewer.h"
#include "kbool/include/kbool/booleng.h"
#include "dialog_design_rules.h"
// Keys used in read/write config
#define PCB_CURR_GRID wxT( "PcbCurrGrid" )
#define PCB_MAGNETIC_PADS_OPT wxT( "PcbMagPadOpt" )
@ -116,6 +118,9 @@ BEGIN_EVENT_TABLE( WinEDA_PcbFrame, WinEDA_BasePcbFrame )
// Menu 3D Frame
EVT_MENU( ID_MENU_PCB_SHOW_3D_FRAME, WinEDA_PcbFrame::Show3D_Frame )
// Menu Get Design Rules Editor
EVT_MENU( ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, WinEDA_PcbFrame::ShowDesignRulesEditor )
// Horizontal toolbar
EVT_TOOL( ID_TO_LIBRARY, WinEDA_PcbFrame::Process_Special_Functions )
EVT_TOOL( ID_SHEET_SET, WinEDA_DrawFrame::Process_PageSettings )
@ -639,3 +644,17 @@ void WinEDA_PcbFrame::Show3D_Frame( wxCommandEvent& event )
m_Draw3DFrame = new WinEDA3D_DrawFrame( this, _( "3D Viewer" ) );
m_Draw3DFrame->Show( TRUE );
}
/**
* Display the Design Rules Editor.
*/
void WinEDA_PcbFrame::ShowDesignRulesEditor( wxCommandEvent& event )
{
DIALOG_DESIGN_RULES dR_editor( this );
int change = dR_editor.ShowModal( );
if ( change )
{
ReCreateLayerBox( NULL );
GetScreen()->SetModify();
}
}

View File

@ -678,9 +678,6 @@ void WinEDA_PcbFrame::UpdateToolbarLayerInfo()
WinEDAChoiceBox* WinEDA_PcbFrame::ReCreateLayerBox( WinEDA_Toolbar* parent )
/**************************************************************************/
{
// wxASSERT("ReCreateLayerBox"==""); // get a stack trace, who is calling me and from where
D(printf("ReCreateLayerBox\n");)
if( m_SelLayerBox == NULL )
{
if( parent == NULL )