Commit f3590e51 authored by charras's avatar charras

pcbnew: fixed a crash when removing A netclass. More about netclass work.

parent b0a52709
...@@ -688,7 +688,7 @@ bool LIB_COMPONENT::Load( FILE* file, char* line, int* lineNum, ...@@ -688,7 +688,7 @@ bool LIB_COMPONENT::Load( FILE* file, char* line, int* lineNum,
|| ( p = strtok( NULL, " \t\n" ) ) == NULL /* m_UnitCount: */ || ( p = strtok( NULL, " \t\n" ) ) == NULL /* m_UnitCount: */
|| sscanf( p, "%d", &m_UnitCount ) != 1 ) || sscanf( p, "%d", &m_UnitCount ) != 1 )
{ {
errorMsg.Printf( _( "Wrong DEF format in line %d, skipped." ), errorMsg.Printf( wxT( "Wrong DEF format in line %d, skipped." ),
*lineNum ); *lineNum );
while( GetLine( file, line, lineNum, 1024 ) ) while( GetLine( file, line, lineNum, 1024 ) )
{ {
......
...@@ -1025,7 +1025,7 @@ with pin %s at location (%d, %d)" ), ...@@ -1025,7 +1025,7 @@ with pin %s at location (%d, %d)" ),
if( m_showDeMorgan ) if( m_showDeMorgan )
{ {
if( curr_pin->m_Convert ) if( curr_pin->m_Convert )
msg += _( " of converion" ); msg += _( " of converted" );
else else
msg += _( " of normal" ); msg += _( " of normal" );
} }
......
...@@ -135,7 +135,6 @@ class RATSNEST_ITEM; ...@@ -135,7 +135,6 @@ class RATSNEST_ITEM;
#include "class_board.h" #include "class_board.h"
// Class for handle current printed board design settings // Class for handle current printed board design settings
#define HISTORY_NUMBER 8
class EDA_BoardDesignSettings class EDA_BoardDesignSettings
{ {
public: public:
...@@ -146,11 +145,9 @@ public: ...@@ -146,11 +145,9 @@ public:
int m_CurrentViaSize; // Current via size int m_CurrentViaSize; // Current via size
int m_CurrentMicroViaSize; // Current micro via size int m_CurrentMicroViaSize; // Current micro via size
bool m_MicroViasAllowed; // true to allow micro vias bool m_MicroViasAllowed; // true to allow micro vias
int m_ViaSizeHistory[HISTORY_NUMBER]; // Last HISTORY_NUMBER used via sizes
int m_CurrentViaType; // via type (VIA_BLIND_BURIED, VIA_TROUGHT VIA_MICROVIA) int m_CurrentViaType; // via type (VIA_BLIND_BURIED, VIA_TROUGHT VIA_MICROVIA)
int m_CurrentTrackWidth; // current track width int m_CurrentTrackWidth; // current track width
bool m_UseConnectedTrackWidth; // if true, when creating a new track starting on an existing track, use this track width bool m_UseConnectedTrackWidth; // if true, when creating a new track starting on an existing track, use this track width
int m_TrackWidthHistory[HISTORY_NUMBER]; // Last HISTORY_NUMBER used track widths
int m_DrawSegmentWidth; // current graphic line width (not EDGE layer) int m_DrawSegmentWidth; // current graphic line width (not EDGE layer)
int m_EdgeSegmentWidth; // current graphic line width (EDGE layer only) int m_EdgeSegmentWidth; // current graphic line width (EDGE layer only)
int m_PcbTextWidth; // current Pcb (not module) Text width int m_PcbTextWidth; // current Pcb (not module) Text width
......
No preview for this file type
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
#ifndef CLASS_BOARD_H #ifndef CLASS_BOARD_H
#define CLASS_BOARD_H #define CLASS_BOARD_H
#include "dlist.h" #include "dlist.h"
#include "class_netinfo.h" #include "class_netinfo.h"
...@@ -65,6 +64,7 @@ struct LAYER ...@@ -65,6 +64,7 @@ struct LAYER
* Class BOARD * Class BOARD
* holds information pertinent to a PCBNEW printed circuit board. * holds information pertinent to a PCBNEW printed circuit board.
*/ */
#define HISTORY_MAX_COUNT 8
class BOARD : public BOARD_ITEM class BOARD : public BOARD_ITEM
{ {
friend class WinEDA_PcbFrame; friend class WinEDA_PcbFrame;
...@@ -103,7 +103,11 @@ public: ...@@ -103,7 +103,11 @@ public:
*/ */
ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress ZONE_CONTAINER* m_CurrentZoneContour; // zone contour currently in progress
std::vector <int> m_ViaSizeHistory; // Last used via sizes (max count = HISTORY_MAX_COUNT)
std::vector <int> m_TrackWidthHistory; // Last used track widths (max count = HISTORY_MAX_COUNT)
/**********************************/
public:
BOARD( EDA_BaseStruct* aParent, WinEDA_BasePcbFrame* frame ); BOARD( EDA_BaseStruct* aParent, WinEDA_BasePcbFrame* frame );
~BOARD(); ~BOARD();
......
...@@ -202,13 +202,6 @@ EDA_BoardDesignSettings::EDA_BoardDesignSettings() ...@@ -202,13 +202,6 @@ EDA_BoardDesignSettings::EDA_BoardDesignSettings()
m_MicroViaDrill = 50; // micro via drill (for the entire board) m_MicroViaDrill = 50; // micro via drill (for the entire board)
m_CurrentMicroViaSize = 150; // Current micro via size m_CurrentMicroViaSize = 150; // Current micro via size
m_MicroViasAllowed = false; // true to allow micro vias m_MicroViasAllowed = false; // true to allow micro vias
for( ii = 0; ii < HISTORY_NUMBER; ii++ )
{
m_TrackWidthHistory[ii] = 0; // Last HISTORY_NUMBER used track widths
m_ViaSizeHistory[ii] = 0; // Last HISTORY_NUMBER used via sizes
}
m_DrawSegmentWidth = 100; // current graphic line width (not EDGE layer) m_DrawSegmentWidth = 100; // current graphic line width (not EDGE layer)
m_EdgeSegmentWidth = 100; // current graphic line width (EDGE layer only) m_EdgeSegmentWidth = 100; // current graphic line width (EDGE layer only)
m_PcbTextWidth = 100; // current Pcb (not module) Text width m_PcbTextWidth = 100; // current Pcb (not module) Text width
......
...@@ -80,9 +80,11 @@ DIALOG_COPPER_LAYERS_SETUP_BASE::DIALOG_COPPER_LAYERS_SETUP_BASE( wxWindow* pare ...@@ -80,9 +80,11 @@ DIALOG_COPPER_LAYERS_SETUP_BASE::DIALOG_COPPER_LAYERS_SETUP_BASE( wxWindow* pare
sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxVERTICAL ); sbSizer1 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Messages:") ), wxVERTICAL );
m_MessagesList = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO ); m_MessagesList = new wxHtmlWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO );
sbSizer1->Add( m_MessagesList, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); m_MessagesList->SetMinSize( wxSize( -1,150 ) );
bMainSizer->Add( sbSizer1, 1, wxEXPAND, 5 ); sbSizer1->Add( m_MessagesList, 0, wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND, 5 );
bMainSizer->Add( sbSizer1, 0, wxEXPAND, 5 );
m_sdbSizer1 = new wxStdDialogButtonSizer(); m_sdbSizer1 = new wxStdDialogButtonSizer();
m_sdbSizer1OK = new wxButton( this, wxID_OK ); m_sdbSizer1OK = new wxButton( this, wxID_OK );
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
<property name="minimum_size">-1,-1</property> <property name="minimum_size">-1,-1</property>
<property name="name">DIALOG_COPPER_LAYERS_SETUP_BASE</property> <property name="name">DIALOG_COPPER_LAYERS_SETUP_BASE</property>
<property name="pos"></property> <property name="pos"></property>
<property name="size">558,479</property> <property name="size">558,598</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property> <property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass"></property> <property name="subclass"></property>
<property name="title">Copper layers setup</property> <property name="title">Copper layers setup</property>
...@@ -254,7 +254,7 @@ ...@@ -254,7 +254,7 @@
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxEXPAND</property>
<property name="proportion">1</property> <property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1"> <object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="label">Messages:</property> <property name="label">Messages:</property>
...@@ -265,8 +265,8 @@ ...@@ -265,8 +265,8 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property> <property name="flag">wxBOTTOM|wxRIGHT|wxLEFT|wxEXPAND</property>
<property name="proportion">1</property> <property name="proportion">0</property>
<object class="wxHtmlWindow" expanded="1"> <object class="wxHtmlWindow" expanded="1">
<property name="bg"></property> <property name="bg"></property>
<property name="context_help"></property> <property name="context_help"></property>
...@@ -276,7 +276,7 @@ ...@@ -276,7 +276,7 @@
<property name="hidden">0</property> <property name="hidden">0</property>
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="maximum_size"></property> <property name="maximum_size"></property>
<property name="minimum_size"></property> <property name="minimum_size">-1,150</property>
<property name="name">m_MessagesList</property> <property name="name">m_MessagesList</property>
<property name="permission">protected</property> <property name="permission">protected</property>
<property name="pos"></property> <property name="pos"></property>
......
...@@ -52,7 +52,7 @@ class DIALOG_COPPER_LAYERS_SETUP_BASE : public wxDialog ...@@ -52,7 +52,7 @@ class DIALOG_COPPER_LAYERS_SETUP_BASE : public wxDialog
public: public:
DIALOG_COPPER_LAYERS_SETUP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Copper layers setup"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 558,479 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); DIALOG_COPPER_LAYERS_SETUP_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Copper layers setup"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 558,598 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_COPPER_LAYERS_SETUP_BASE(); ~DIALOG_COPPER_LAYERS_SETUP_BASE();
}; };
......
...@@ -365,20 +365,25 @@ void DIALOG_DESIGN_RULES::CopyRulesListToBoard() ...@@ -365,20 +365,25 @@ void DIALOG_DESIGN_RULES::CopyRulesListToBoard()
{ {
NETCLASSES& netclasses = m_Pcb->m_NetClasses; NETCLASSES& netclasses = m_Pcb->m_NetClasses;
// Remove all netclasses from board. We'll copy new list after
netclasses.Clear(); netclasses.Clear();
// gridRow2class( wxGrid* grid, int row, NETCLASS* nc, int units ) // Copy the default NetClass:
gridRow2class( m_grid, 0, netclasses.GetDefault(), m_Parent->m_InternalUnits ); gridRow2class( m_grid, 0, netclasses.GetDefault(), m_Parent->m_InternalUnits );
// Copy other NetClasses :
for( int row = 1; row < m_grid->GetNumberRows(); ++row ) for( int row = 1; row < m_grid->GetNumberRows(); ++row )
{ {
NETCLASS* nc = new NETCLASS( m_Pcb, m_grid->GetRowLabelValue( row ) ); NETCLASS* nc = new NETCLASS( m_Pcb, m_grid->GetRowLabelValue( row ) );
if( !m_Pcb->m_NetClasses.Add( nc ) ) if( !m_Pcb->m_NetClasses.Add( nc ) )
{ {
// @todo: put up an error message here. // this netclass cannot be added because an other netclass with the same name exists
// Should not occur because OnAddNetclassClick() tests for existing NetClass names
wxString msg;
msg.Printf( wxT("CopyRulesListToBoard(): The NetClass \"%s\" already exists. Skip"),
m_grid->GetRowLabelValue( row ).GetData() );
wxMessageBox( msg );
delete nc; delete nc;
continue; continue;
} }
...@@ -386,6 +391,7 @@ void DIALOG_DESIGN_RULES::CopyRulesListToBoard() ...@@ -386,6 +391,7 @@ void DIALOG_DESIGN_RULES::CopyRulesListToBoard()
gridRow2class( m_grid, row, nc, m_Parent->m_InternalUnits ); gridRow2class( m_grid, row, nc, m_Parent->m_InternalUnits );
} }
// Now read all nets and push them in the corresponding netclass net buffer
for( NETCUPS::const_iterator netcup = m_AllNets.begin(); netcup != m_AllNets.end(); ++netcup ) for( NETCUPS::const_iterator netcup = m_AllNets.begin(); netcup != m_AllNets.end(); ++netcup )
{ {
NETCLASS* nc = netclasses.Find( netcup->clazz ); NETCLASS* nc = netclasses.Find( netcup->clazz );
...@@ -471,11 +477,12 @@ void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event ) ...@@ -471,11 +477,12 @@ void DIALOG_DESIGN_RULES::OnRemoveNetclassClick( wxCommandEvent& event )
for( int ii = select.GetCount() - 1; ii >= 0; ii-- ) for( int ii = select.GetCount() - 1; ii >= 0; ii-- )
{ {
if( select[ii] != 0 ) // Do not remove the default class int grid_row = select[ii];
if( grid_row != 0 ) // Do not remove the default class
{ {
wxString classname = m_grid->GetRowLabelValue( ii ); wxString classname = m_grid->GetRowLabelValue( grid_row );
m_grid->DeleteRows( select[ii] ); m_grid->DeleteRows( grid_row );
// reset the net class to default for members of the removed class // reset the net class to default for members of the removed class
swapNetClass( classname, NETCLASS::Default ); swapNetClass( classname, NETCLASS::Default );
...@@ -653,14 +660,34 @@ bool DIALOG_DESIGN_RULES::TestDataValidity() ...@@ -653,14 +660,34 @@ bool DIALOG_DESIGN_RULES::TestDataValidity()
for( int row = 0; row < m_grid->GetNumberRows(); row++ ) for( int row = 0; row < m_grid->GetNumberRows(); row++ )
{ {
int tracksize = ReturnValueFromString( g_UnitMetric,
m_grid->GetCellValue( row, GRID_TRACKSIZE ),
m_Parent->m_InternalUnits );
if( tracksize < g_DesignSettings.m_TrackMinWidth )
{
result = false;
msg.Printf( _( "%s: <b>Track Size</b> &lt; <b>Min Track Size</b><br>" ),
GetChars( m_grid->GetRowLabelValue(row)) );
m_MessagesList->AppendToPage( msg );
}
// Test vias
int viadia = ReturnValueFromString( g_UnitMetric, int viadia = ReturnValueFromString( g_UnitMetric,
m_grid->GetCellValue( m_grid->GetCellValue( row, GRID_VIASIZE ),
row, GRID_VIASIZE ),
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits );
if( viadia < g_DesignSettings.m_ViasMinSize )
{
result = false;
msg.Printf( _( "%s: <b>Via Diameter</b> &lt; <b>Minimun Via Diameter</b><br>" ),
GetChars( m_grid->GetRowLabelValue(row)) );
m_MessagesList->AppendToPage( msg );
}
int viadrill = ReturnValueFromString( g_UnitMetric, int viadrill = ReturnValueFromString( g_UnitMetric,
m_grid->GetCellValue( m_grid->GetCellValue( row, GRID_VIADRILL ),
row, GRID_VIADRILL ),
m_Parent->m_InternalUnits ); m_Parent->m_InternalUnits );
if( viadrill && viadrill >= viadia ) if( viadrill && viadrill >= viadia )
{ {
...@@ -670,6 +697,32 @@ bool DIALOG_DESIGN_RULES::TestDataValidity() ...@@ -670,6 +697,32 @@ bool DIALOG_DESIGN_RULES::TestDataValidity()
m_MessagesList->AppendToPage( msg ); m_MessagesList->AppendToPage( msg );
} }
// Test Micro vias
int muviadia = ReturnValueFromString( g_UnitMetric,
m_grid->GetCellValue( row, GRID_uVIASIZE ),
m_Parent->m_InternalUnits );
if( muviadia < g_DesignSettings.m_MicroViasMinSize )
{
result = false;
msg.Printf( _( "%s: <b>MicroVia Diameter</b> &lt; <b>Minimun MicroVia Diameter</b><br>" ),
GetChars( m_grid->GetRowLabelValue(row)) );
m_MessagesList->AppendToPage( msg );
}
int muviadrill = ReturnValueFromString( g_UnitMetric,
m_grid->GetCellValue( row, GRID_uVIADRILL ),
m_Parent->m_InternalUnits );
if( muviadrill && muviadrill >= muviadia )
{
result = false;
msg.Printf( _( "%s: <b>MicroVia Drill</b> &ge; <b>MicroVia Dia</b><br>" ),
GetChars( m_grid->GetRowLabelValue(row)) );
m_MessagesList->AppendToPage( msg );
}
} }
return result; return result;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "dialog_design_rules_base.h" #include "dialog_design_rules_base.h"
// helper struct to handle a net and its netclass in dialog design rule editor
struct NETCUP struct NETCUP
{ {
NETCUP( const wxString& aNet, const wxString& aClass ) NETCUP( const wxString& aNet, const wxString& aClass )
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "wxPcbStruct.h" #include "wxPcbStruct.h"
#include "dialog_track_options.h" #include "dialog_track_options.h"
#include <algorithm>
/** /**
* DIALOG_TRACKS_OPTIONS, derived from DIALOG_TRACKS_OPTIONS_BASE * DIALOG_TRACKS_OPTIONS, derived from DIALOG_TRACKS_OPTIONS_BASE
...@@ -21,8 +21,8 @@ ...@@ -21,8 +21,8 @@
* automatically created by wxFormBuilder * automatically created by wxFormBuilder
*/ */
DIALOG_TRACKS_OPTIONS::DIALOG_TRACKS_OPTIONS( WinEDA_PcbFrame* parent ) DIALOG_TRACKS_OPTIONS::DIALOG_TRACKS_OPTIONS( WinEDA_PcbFrame* parent ) :
: DIALOG_TRACKS_OPTIONS_BASE(parent) DIALOG_TRACKS_OPTIONS_BASE( parent )
{ {
m_Parent = parent; m_Parent = parent;
} }
...@@ -82,7 +82,6 @@ void DIALOG_TRACKS_OPTIONS::SetDisplayValue() ...@@ -82,7 +82,6 @@ void DIALOG_TRACKS_OPTIONS::SetDisplayValue()
m_MicroViaDrillCtrl->Enable( g_DesignSettings.m_MicroViasAllowed ); m_MicroViaDrillCtrl->Enable( g_DesignSettings.m_MicroViasAllowed );
m_AllowMicroViaCtrl->SetValue( g_DesignSettings.m_MicroViasAllowed ); m_AllowMicroViaCtrl->SetValue( g_DesignSettings.m_MicroViasAllowed );
} }
...@@ -129,84 +128,32 @@ void WinEDA_BasePcbFrame::AddHistory( int value, KICAD_T type ) ...@@ -129,84 +128,32 @@ void WinEDA_BasePcbFrame::AddHistory( int value, KICAD_T type )
// Mise a jour des listes des dernieres epaisseurs de via et track utilisées // Mise a jour des listes des dernieres epaisseurs de via et track utilisées
{ {
bool addhistory = TRUE; std::vector <int> * vlist = NULL;
int ii;
switch( type ) switch( type )
{ {
case TYPE_TRACK: case TYPE_TRACK:
for( ii = 0; ii < HISTORY_NUMBER; ii++ ) vlist = &GetBoard()->m_TrackWidthHistory;
{
if( g_DesignSettings.m_TrackWidthHistory[ii] == value )
{
addhistory = FALSE;
break;
}
}
if( !addhistory )
break;
for( ii = HISTORY_NUMBER - 1; ii > 0; ii-- )
{
g_DesignSettings.m_TrackWidthHistory[ii] =
g_DesignSettings.m_TrackWidthHistory[ii - 1];
}
g_DesignSettings.m_TrackWidthHistory[0] = value;
// Reclassement par valeur croissante
for( ii = 0; ii < HISTORY_NUMBER - 1; ii++ )
{
if( g_DesignSettings.m_TrackWidthHistory[ii + 1] == 0 )
break; // Fin de liste
if( g_DesignSettings.m_TrackWidthHistory[ii] >
g_DesignSettings.m_TrackWidthHistory[ii + 1] )
{
EXCHG( g_DesignSettings.m_TrackWidthHistory[ii],
g_DesignSettings.m_TrackWidthHistory[ii + 1] );
}
}
break; break;
case TYPE_VIA: case TYPE_VIA:
for( ii = 0; ii < HISTORY_NUMBER; ii++ ) vlist = &GetBoard()->m_ViaSizeHistory;
{
if( g_DesignSettings.m_ViaSizeHistory[ii] == value )
{
addhistory = FALSE;
break; break;
}
}
if( !addhistory )
break;
for( ii = HISTORY_NUMBER - 1; ii > 0; ii-- )
{
g_DesignSettings.m_ViaSizeHistory[ii] = g_DesignSettings.m_ViaSizeHistory[ii - 1];
}
g_DesignSettings.m_ViaSizeHistory[0] = value; default:
return;
// Reclassement par valeur croissante
for( ii = 0; ii < HISTORY_NUMBER - 1; ii++ )
{
if( g_DesignSettings.m_ViaSizeHistory[ii + 1] == 0 )
break; // Fin de liste
if( g_DesignSettings.m_ViaSizeHistory[ii] > g_DesignSettings.m_ViaSizeHistory[ii + 1] )
{
EXCHG( g_DesignSettings.m_ViaSizeHistory[ii],
g_DesignSettings.m_ViaSizeHistory[ii + 1] );
}
} }
break; // values are sorted by increasing value in list, so we can use binary_search()
// (see C++ Standard Template Library C++ Algorithms binary_search)
if( binary_search( vlist->begin(), vlist->end(), value ) == false )
{ // value not already existing
vlist->push_back( value );
if( vlist->size() >= HISTORY_MAX_COUNT )
vlist->erase( vlist->begin() );
default: // Sort new list by by increasing value
break; sort( vlist->begin(), vlist->end() );
} }
} }
......
...@@ -995,8 +995,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -995,8 +995,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_AUX_TOOLBAR_PCB_TRACK_WIDTH: case ID_AUX_TOOLBAR_PCB_TRACK_WIDTH:
{ {
int ii = m_SelTrackWidthBox->GetChoice(); int ii = m_SelTrackWidthBox->GetChoice();
g_DesignSettings.m_CurrentTrackWidth = g_DesignSettings.m_CurrentTrackWidth = GetBoard()->m_TrackWidthHistory[ii];
g_DesignSettings.m_TrackWidthHistory[ii];
DisplayTrackSettings(); DisplayTrackSettings();
m_SelTrackWidthBox_Changed = false; m_SelTrackWidthBox_Changed = false;
m_SelViaSizeBox_Changed = false; m_SelViaSizeBox_Changed = false;
...@@ -1016,8 +1015,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -1016,8 +1015,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
g_DesignSettings.m_UseConnectedTrackWidth = false; g_DesignSettings.m_UseConnectedTrackWidth = false;
{ {
int ii = id - ID_POPUP_PCB_SELECT_WIDTH1; int ii = id - ID_POPUP_PCB_SELECT_WIDTH1;
g_DesignSettings.m_CurrentTrackWidth = g_DesignSettings.m_CurrentTrackWidth = GetBoard()->m_TrackWidthHistory[ii];
g_DesignSettings.m_TrackWidthHistory[ii];
DisplayTrackSettings(); DisplayTrackSettings();
} }
break; break;
...@@ -1035,8 +1033,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event ) ...@@ -1035,8 +1033,7 @@ void WinEDA_PcbFrame::Process_Special_Functions( wxCommandEvent& event )
case ID_AUX_TOOLBAR_PCB_VIA_SIZE: case ID_AUX_TOOLBAR_PCB_VIA_SIZE:
{ {
int ii = m_SelViaSizeBox->GetChoice(); int ii = m_SelViaSizeBox->GetChoice();
g_DesignSettings.m_CurrentViaSize = g_DesignSettings.m_CurrentViaSize = GetBoard()->m_ViaSizeHistory[ii];
g_DesignSettings.m_ViaSizeHistory[ii];
DisplayTrackSettings(); DisplayTrackSettings();
m_SelTrackWidthBox_Changed = false; m_SelTrackWidthBox_Changed = false;
m_SelViaSizeBox_Changed = false; m_SelViaSizeBox_Changed = false;
......
...@@ -175,15 +175,6 @@ bool WinEDA_PcbFrame::Clear_Pcb( bool aQuery ) ...@@ -175,15 +175,6 @@ bool WinEDA_PcbFrame::Clear_Pcb( bool aQuery )
GetScreen()->SetGrid( gridsize ); GetScreen()->SetGrid( gridsize );
g_HightLigt_Status = 0; g_HightLigt_Status = 0;
for( int ii = 1; ii < HISTORY_NUMBER; ii++ )
{
g_DesignSettings.m_ViaSizeHistory[ii] = 0;
g_DesignSettings.m_TrackWidthHistory[ii] = 0;
}
g_DesignSettings.m_TrackWidthHistory[0] = g_DesignSettings.m_CurrentTrackWidth;
g_DesignSettings.m_ViaSizeHistory[0] = g_DesignSettings.m_CurrentViaSize;
g_DesignSettings.m_CopperLayerCount = 2; // Default copper layers count set to 2: double layer board g_DesignSettings.m_CopperLayerCount = 2; // Default copper layers count set to 2: double layer board
Zoom_Automatique( true ); Zoom_Automatique( true );
......
...@@ -521,7 +521,6 @@ static int WriteSetup( FILE* aFile, WinEDA_BasePcbFrame* aFrame, BOARD* aBoard ) ...@@ -521,7 +521,6 @@ static int WriteSetup( FILE* aFile, WinEDA_BasePcbFrame* aFrame, BOARD* aBoard )
/******************************************************************************/ /******************************************************************************/
{ {
char text[1024]; char text[1024];
int ii;
fprintf( aFile, "$SETUP\n" ); fprintf( aFile, "$SETUP\n" );
sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT ); sprintf( text, "InternalUnit %f INCH\n", 1.0 / PCB_INTERNAL_UNIT );
...@@ -544,13 +543,8 @@ static int WriteSetup( FILE* aFile, WinEDA_BasePcbFrame* aFrame, BOARD* aBoard ) ...@@ -544,13 +543,8 @@ static int WriteSetup( FILE* aFile, WinEDA_BasePcbFrame* aFrame, BOARD* aBoard )
} }
fprintf( aFile, "TrackWidth %d\n", g_DesignSettings.m_CurrentTrackWidth ); fprintf( aFile, "TrackWidth %d\n", g_DesignSettings.m_CurrentTrackWidth );
for( int ii = 0; ii < HISTORY_NUMBER; ii++ ) for( unsigned ii = 0; ii < aBoard->m_TrackWidthHistory.size(); ii++ )
{ fprintf( aFile, "TrackWidthHistory %d\n", aBoard->m_TrackWidthHistory[ii] );
if( g_DesignSettings.m_TrackWidthHistory[ii] == 0 )
break;
fprintf( aFile, "TrackWidthHistory %d\n",
g_DesignSettings.m_TrackWidthHistory[ii] );
}
fprintf( aFile, "TrackClearence %d\n", g_DesignSettings.m_TrackClearance ); fprintf( aFile, "TrackClearence %d\n", g_DesignSettings.m_TrackClearance );
...@@ -564,12 +558,8 @@ static int WriteSetup( FILE* aFile, WinEDA_BasePcbFrame* aFrame, BOARD* aBoard ) ...@@ -564,12 +558,8 @@ static int WriteSetup( FILE* aFile, WinEDA_BasePcbFrame* aFrame, BOARD* aBoard )
fprintf( aFile, "ViaAltDrill %d\n", g_DesignSettings.m_ViaDrillCustomValue ); fprintf( aFile, "ViaAltDrill %d\n", g_DesignSettings.m_ViaDrillCustomValue );
fprintf( aFile, "ViaMinSize %d\n", g_DesignSettings.m_ViasMinSize ); fprintf( aFile, "ViaMinSize %d\n", g_DesignSettings.m_ViasMinSize );
for( ii = 0; ii < HISTORY_NUMBER; ii++ ) for( unsigned ii = 0; ii < aBoard->m_ViaSizeHistory.size(); ii++ )
{ fprintf( aFile, "ViaSizeHistory %d\n", aBoard->m_ViaSizeHistory[ii] );
if( g_DesignSettings.m_ViaSizeHistory[ii] == 0 )
break;
fprintf( aFile, "ViaSizeHistory %d\n", g_DesignSettings.m_ViaSizeHistory[ii] );
}
fprintf( aFile, "MicroViaSize %d\n", g_DesignSettings.m_CurrentMicroViaSize); fprintf( aFile, "MicroViaSize %d\n", g_DesignSettings.m_CurrentMicroViaSize);
fprintf( aFile, "MicroViaDrill %d\n", g_DesignSettings.m_MicroViaDrill); fprintf( aFile, "MicroViaDrill %d\n", g_DesignSettings.m_MicroViaDrill);
......
...@@ -185,11 +185,6 @@ void WinEDA_PcbFrame::ReCreateMenuBar() ...@@ -185,11 +185,6 @@ void WinEDA_PcbFrame::ReCreateMenuBar()
item->SetBitmap( preference_xpm ); item->SetBitmap( preference_xpm );
configmenu->Append( item ); configmenu->Append( item );
item = new wxMenuItem( configmenu, ID_PCB_COPPER_LAYERS_SETUP, _( "Copper &Layers" ),
_( "Select copper layers count and layers names" ) );
item->SetBitmap( copper_layers_setup_xpm );
configmenu->Append( item );
item = new wxMenuItem( configmenu, ID_PCB_DISPLAY_OPTIONS_SETUP, _( "&Display" ), item = new wxMenuItem( configmenu, ID_PCB_DISPLAY_OPTIONS_SETUP, _( "&Display" ),
_( "Select how items (pads, tracks texts ... ) are displayed" ) ); _( "Select how items (pads, tracks texts ... ) are displayed" ) );
item->SetBitmap( display_options_xpm ); item->SetBitmap( display_options_xpm );
...@@ -211,13 +206,18 @@ void WinEDA_PcbFrame::ReCreateMenuBar() ...@@ -211,13 +206,18 @@ void WinEDA_PcbFrame::ReCreateMenuBar()
configmenu->AppendSeparator(); configmenu->AppendSeparator();
AddHotkeyConfigMenu( configmenu ); AddHotkeyConfigMenu( configmenu );
// Add acces to the Design Rules Dialog: // Add access to the Design Rules Dialog:
wxMenu* designRulesMenu = new wxMenu; wxMenu* designRulesMenu = new wxMenu;
item = new wxMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, item = new wxMenuItem( designRulesMenu, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG,
_( "Design Rules" ), _( "Open the design rules dialog editor" ) ); _( "Design Rules" ), _( "Open the design rules dialog editor" ) );
item->SetBitmap( hammer_xpm ); item->SetBitmap( hammer_xpm );
designRulesMenu->Append( item ); designRulesMenu->Append( item );
item = new wxMenuItem( designRulesMenu, ID_PCB_COPPER_LAYERS_SETUP, _( "Copper &Layers" ),
_( "Select copper layers count and layers names" ) );
item->SetBitmap( copper_layers_setup_xpm );
designRulesMenu->Append( item );
///////////////////////////// /////////////////////////////
// Ajustage de dimensions: // // Ajustage de dimensions: //
///////////////////////////// /////////////////////////////
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
/* Bitmaps */ /* Bitmaps */
#include "bitmaps.h" #include "bitmaps.h"
static wxMenu* Append_Track_Width_List(); static wxMenu* Append_Track_Width_List( BOARD * aBoard );
/******************************************************************************/ /******************************************************************************/
...@@ -291,7 +291,7 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) ...@@ -291,7 +291,7 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
break; break;
case ID_TRACK_BUTT: case ID_TRACK_BUTT:
ADD_MENUITEM_WITH_SUBMENU( aPopMenu, Append_Track_Width_List(), ADD_MENUITEM_WITH_SUBMENU( aPopMenu, Append_Track_Width_List( GetBoard() ),
ID_POPUP_PCB_SELECT_WIDTH, ID_POPUP_PCB_SELECT_WIDTH,
_( "Select Track Width" ), width_track_xpm ); _( "Select Track Width" ), width_track_xpm );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER, ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_CU_LAYER,
...@@ -364,7 +364,7 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu ) ...@@ -364,7 +364,7 @@ bool WinEDA_PcbFrame::OnRightClick( const wxPoint& aMousePos, wxMenu* aPopMenu )
} }
if( locate_track ) if( locate_track )
ADD_MENUITEM_WITH_SUBMENU( aPopMenu, Append_Track_Width_List(), ADD_MENUITEM_WITH_SUBMENU( aPopMenu, Append_Track_Width_List( GetBoard() ),
ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ), ID_POPUP_PCB_SELECT_WIDTH, _( "Select Track Width" ),
width_track_xpm ); width_track_xpm );
ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_LAYER, ADD_MENUITEM( aPopMenu, ID_POPUP_PCB_SELECT_LAYER,
...@@ -826,17 +826,14 @@ void WinEDA_PcbFrame::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aP ...@@ -826,17 +826,14 @@ void WinEDA_PcbFrame::createPopUpMenuForMarkers( MARKER_PCB* aMarker, wxMenu* aP
} }
/********************************************/ /*******************************************************/
static wxMenu* Append_Track_Width_List() static wxMenu* Append_Track_Width_List( BOARD * aBoard )
/********************************************/ /*******************************************************/
/* create a wxMenu * which shows the last used track widths and via diameters /* create a wxMenu * which shows the last used track widths and via diameters
* @return a pointeur to the menu * @return a pointeur to the menu
*/ */
{ {
#define TRACK_HISTORY_NUMBER_MAX 6
#define VIA_HISTORY_NUMBER_MAX 4
int ii;
wxString msg; wxString msg;
wxMenu* trackwidth_menu; wxMenu* trackwidth_menu;
double value; double value;
...@@ -855,12 +852,10 @@ static wxMenu* Append_Track_Width_List() ...@@ -855,12 +852,10 @@ static wxMenu* Append_Track_Width_List()
if( g_DesignSettings.m_UseConnectedTrackWidth ) if( g_DesignSettings.m_UseConnectedTrackWidth )
trackwidth_menu->Check( ID_POPUP_PCB_SELECT_AUTO_WIDTH, TRUE ); trackwidth_menu->Check( ID_POPUP_PCB_SELECT_AUTO_WIDTH, TRUE );
for( ii = 0; (ii < HISTORY_NUMBER) && (ii < TRACK_HISTORY_NUMBER_MAX); ii++ ) for( unsigned ii = 0; ii < aBoard->m_TrackWidthHistory.size(); ii++ )
{ {
if( g_DesignSettings.m_TrackWidthHistory[ii] == 0 )
break;
value = To_User_Unit( g_UnitMetric, value = To_User_Unit( g_UnitMetric,
g_DesignSettings.m_TrackWidthHistory[ii], aBoard->m_TrackWidthHistory[ii],
PCB_INTERNAL_UNIT ); PCB_INTERNAL_UNIT );
if( g_UnitMetric == INCHES ) // Affichage en mils if( g_UnitMetric == INCHES ) // Affichage en mils
msg.Printf( _( "Track %.1f" ), value * 1000 ); msg.Printf( _( "Track %.1f" ), value * 1000 );
...@@ -869,25 +864,23 @@ static wxMenu* Append_Track_Width_List() ...@@ -869,25 +864,23 @@ static wxMenu* Append_Track_Width_List()
trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, TRUE ); trackwidth_menu->Append( ID_POPUP_PCB_SELECT_WIDTH1 + ii, msg, wxEmptyString, TRUE );
if( (g_DesignSettings.m_TrackWidthHistory[ii] == g_DesignSettings.m_CurrentTrackWidth) if( (aBoard->m_TrackWidthHistory[ii] == g_DesignSettings.m_CurrentTrackWidth)
&& !g_DesignSettings.m_UseConnectedTrackWidth ) && !g_DesignSettings.m_UseConnectedTrackWidth )
trackwidth_menu->Check( ID_POPUP_PCB_SELECT_WIDTH1 + ii, TRUE ); trackwidth_menu->Check( ID_POPUP_PCB_SELECT_WIDTH1 + ii, TRUE );
} }
trackwidth_menu->AppendSeparator(); trackwidth_menu->AppendSeparator();
for( ii = 0; (ii < HISTORY_NUMBER) && (ii < VIA_HISTORY_NUMBER_MAX); ii++ ) for( unsigned ii = 0; ii < aBoard->m_ViaSizeHistory.size(); ii++ )
{ {
if( g_DesignSettings.m_ViaSizeHistory[ii] == 0 )
break;
value = To_User_Unit( g_UnitMetric, value = To_User_Unit( g_UnitMetric,
g_DesignSettings.m_ViaSizeHistory[ii], aBoard->m_ViaSizeHistory[ii],
PCB_INTERNAL_UNIT ); PCB_INTERNAL_UNIT );
if( g_UnitMetric == INCHES ) if( g_UnitMetric == INCHES )
msg.Printf( _( "Via %.1f" ), value * 1000 ); msg.Printf( _( "Via %.1f" ), value * 1000 );
else else
msg.Printf( _( "Via %.3f" ), value ); msg.Printf( _( "Via %.3f" ), value );
trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, TRUE ); trackwidth_menu->Append( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, msg, wxEmptyString, TRUE );
if( g_DesignSettings.m_ViaSizeHistory[ii] == g_DesignSettings.m_CurrentViaSize ) if( aBoard->m_ViaSizeHistory[ii] == g_DesignSettings.m_CurrentViaSize )
trackwidth_menu->Check( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, TRUE ); trackwidth_menu->Check( ID_POPUP_PCB_SELECT_VIASIZE1 + ii, TRUE );
} }
......
...@@ -186,16 +186,6 @@ bool Read_Config( const wxString& projectFileName ) ...@@ -186,16 +186,6 @@ bool Read_Config( const wxString& projectFileName )
/* User library path takes precedent over default library search paths. */ /* User library path takes precedent over default library search paths. */
wxGetApp().InsertLibraryPath( g_UserLibDirBuffer, 1 ); wxGetApp().InsertLibraryPath( g_UserLibDirBuffer, 1 );
// Some parameters must be reinitialized after loading a new board or config
g_DesignSettings.m_TrackWidthHistory[0] = g_DesignSettings.m_CurrentTrackWidth;
g_DesignSettings.m_ViaSizeHistory[0] = g_DesignSettings.m_CurrentViaSize;
for( ii = 1; ii < HISTORY_NUMBER; ii++ )
{
g_DesignSettings.m_TrackWidthHistory[ii] = 0;
g_DesignSettings.m_ViaSizeHistory[ii] = 0;
}
/* Reset the ITEM_NOT_SHOW flag when loading a new config /* Reset the ITEM_NOT_SHOW flag when loading a new config
* Because it could creates SERIOUS mistakes for the user, * Because it could creates SERIOUS mistakes for the user,
* if some items are not visible after loading a board... * if some items are not visible after loading a board...
......
...@@ -1236,7 +1236,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1236,7 +1236,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
// Next we add the via's which may be used. // Next we add the via's which may be used.
int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize; int defaultViaSize = aBoard->m_BoardSettings->m_CurrentViaSize;
// TODO: output vias sizes in NetClasses
/* I need at least one via for the (class...) scope below /* I need at least one via for the (class...) scope below
if( defaultViaSize ) if( defaultViaSize )
*/ */
...@@ -1251,11 +1251,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError ) ...@@ -1251,11 +1251,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IOError )
pcb->library->SetViaStartIndex( pcb->library->padstacks.size()-1 ); pcb->library->SetViaStartIndex( pcb->library->padstacks.size()-1 );
} }
for( int i=0; i<HISTORY_NUMBER; ++i ) for( unsigned i=0; i < aBoard->m_ViaSizeHistory.size(); ++i )
{ {
int viaSize = aBoard->m_BoardSettings->m_ViaSizeHistory[i]; int viaSize = aBoard->m_ViaSizeHistory[i];
if( !viaSize )
break;
if( viaSize == defaultViaSize ) if( viaSize == defaultViaSize )
continue; continue;
......
...@@ -78,16 +78,13 @@ void WinEDA_PcbFrame::AuxiliaryToolBar_Update_UI( ) ...@@ -78,16 +78,13 @@ void WinEDA_PcbFrame::AuxiliaryToolBar_Update_UI( )
m_SelTrackWidthBox_Changed = false; m_SelTrackWidthBox_Changed = false;
m_SelTrackWidthBox->Clear(); m_SelTrackWidthBox->Clear();
for( int ii = 0; ii < HISTORY_NUMBER; ii++ ) for( unsigned ii = 0; ii < GetBoard()->m_TrackWidthHistory.size(); ii++ )
{ {
if( g_DesignSettings.m_TrackWidthHistory[ii] == 0 ) msg = _( "Track" ) + ReturnStringValue(GetBoard()->m_TrackWidthHistory[ii]);
break; // Fin de liste
msg = _( "Track" ) + ReturnStringValue(g_DesignSettings.m_TrackWidthHistory[ii]);
m_SelTrackWidthBox->Append( msg ); m_SelTrackWidthBox->Append( msg );
if( g_DesignSettings.m_TrackWidthHistory[ii] == if( GetBoard()->m_TrackWidthHistory[ii] == g_DesignSettings.m_CurrentTrackWidth )
g_DesignSettings.m_CurrentTrackWidth )
m_SelTrackWidthBox->SetSelection( ii ); m_SelTrackWidthBox->SetSelection( ii );
} }
} }
...@@ -99,15 +96,12 @@ void WinEDA_PcbFrame::AuxiliaryToolBar_Update_UI( ) ...@@ -99,15 +96,12 @@ void WinEDA_PcbFrame::AuxiliaryToolBar_Update_UI( )
m_SelViaSizeBox_Changed = false; m_SelViaSizeBox_Changed = false;
m_SelViaSizeBox->Clear(); m_SelViaSizeBox->Clear();
for( int ii = 0; ii < HISTORY_NUMBER; ii++ ) for( unsigned ii = 0; ii < GetBoard()->m_ViaSizeHistory.size(); ii++ )
{ {
if( g_DesignSettings.m_ViaSizeHistory[ii] == 0 ) msg = _( "Via" ) + ReturnStringValue(GetBoard()->m_ViaSizeHistory[ii]);
break; // Fin de liste
msg = _( "Via" ) + ReturnStringValue(g_DesignSettings.m_ViaSizeHistory[ii]);
m_SelViaSizeBox->Append( msg ); m_SelViaSizeBox->Append( msg );
if( g_DesignSettings.m_ViaSizeHistory[ii] == g_DesignSettings.m_CurrentViaSize ) if( GetBoard()->m_ViaSizeHistory[ii] == g_DesignSettings.m_CurrentViaSize )
m_SelViaSizeBox->SetSelection( ii ); m_SelViaSizeBox->SetSelection( ii );
} }
} }
...@@ -115,7 +109,7 @@ void WinEDA_PcbFrame::AuxiliaryToolBar_Update_UI( ) ...@@ -115,7 +109,7 @@ void WinEDA_PcbFrame::AuxiliaryToolBar_Update_UI( )
if( m_SelZoomBox ) if( m_SelZoomBox )
{ {
bool not_found = true; bool not_found = true;
for( int jj = 0; jj < (int)GetScreen()->m_ZoomList.GetCount(); jj++ ) for( unsigned jj = 0; jj < GetScreen()->m_ZoomList.GetCount(); jj++ )
{ {
if( GetScreen()->GetZoom() == GetScreen()->m_ZoomList[jj] ) if( GetScreen()->GetZoom() == GetScreen()->m_ZoomList[jj] )
{ {
......
...@@ -43,7 +43,7 @@ void WinEDA_PcbFrame::Via_Edit_Control( wxCommandEvent& event ) ...@@ -43,7 +43,7 @@ void WinEDA_PcbFrame::Via_Edit_Control( wxCommandEvent& event )
case ID_POPUP_PCB_SELECT_VIASIZE8: // selec the new current value for via size (via diameter) case ID_POPUP_PCB_SELECT_VIASIZE8: // selec the new current value for via size (via diameter)
DrawPanel->MouseToCursorSchema(); DrawPanel->MouseToCursorSchema();
ii = event.GetId() - ID_POPUP_PCB_SELECT_VIASIZE1; ii = event.GetId() - ID_POPUP_PCB_SELECT_VIASIZE1;
g_DesignSettings.m_CurrentViaSize = g_DesignSettings.m_ViaSizeHistory[ii]; g_DesignSettings.m_CurrentViaSize = GetBoard()->m_ViaSizeHistory[ii];
DisplayTrackSettings(); DisplayTrackSettings();
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment