Commit a6a34f35 authored by jean-pierre charras's avatar jean-pierre charras

Eeschema: fix bug in dialog_lib_edit_text (OnOkClick method never called).

Other very minor changes.
parents f0790efd 820085db
/**********************************/
/* edit_graphic_bodyitem_text.cpp */
/* dialog_lib_edit_text.cpp */
/**********************************/
/* Code for editing component library text items, not fields. */
......@@ -113,7 +113,7 @@ void DIALOG_LIB_EDIT_TEXT::InitDialog( )
void DIALOG_LIB_EDIT_TEXT::OnCancelClick( wxCommandEvent& event )
{
event.Skip();
EndModal(wxID_CANCEL);
}
......@@ -193,5 +193,5 @@ void DIALOG_LIB_EDIT_TEXT::OnOkClick( wxCommandEvent& event )
if( m_Parent->GetDrawItem() )
m_Parent->GetDrawItem()->DisplayInfo( m_Parent );
Close();
EndModal(wxID_OK);
}
......@@ -108,8 +108,16 @@ DIALOG_LIB_EDIT_TEXT_BASE::DIALOG_LIB_EDIT_TEXT_BASE( wxWindow* parent, wxWindow
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
// Connect Events
m_sdbSizer1Cancel->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCancelClick ), NULL, this );
m_sdbSizer1OK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnOkClick ), NULL, this );
}
DIALOG_LIB_EDIT_TEXT_BASE::~DIALOG_LIB_EDIT_TEXT_BASE()
{
// Disconnect Events
m_sdbSizer1Cancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnCancelClick ), NULL, this );
m_sdbSizer1OK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_LIB_EDIT_TEXT_BASE::OnOkClick ), NULL, this );
}
......@@ -815,11 +815,11 @@
<property name="name">m_sdbSizer1</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick"></event>
<event name="OnCancelButtonClick"></event>
<event name="OnCancelButtonClick">OnCancelClick</event>
<event name="OnContextHelpButtonClick"></event>
<event name="OnHelpButtonClick"></event>
<event name="OnNoButtonClick"></event>
<event name="OnOKButtonClick"></event>
<event name="OnOKButtonClick">OnOkClick</event>
<event name="OnSaveButtonClick"></event>
<event name="OnYesButtonClick"></event>
</object>
......
......@@ -49,6 +49,11 @@ class DIALOG_LIB_EDIT_TEXT_BASE : public wxDialog
wxStdDialogButtonSizer* m_sdbSizer1;
wxButton* m_sdbSizer1OK;
wxButton* m_sdbSizer1Cancel;
// Virtual event handlers, overide them in your derived class
virtual void OnCancelClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
public:
......
/**********************************/
/* Netlist generator for pads-pcb */
/**********************************/
/* read the generic netlist created by eeschema and convert it to a pads-pcb form
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
/* Pads-pcb sample:
*PADS-PCB*
*PART*
* C1 CHIP_D
* C2 C1206
* C3 CHIP_B
* C4 CHIP_B
* D1 CHIP_B
* JP1 unknown
*
*NET*
*SIGNAL* N03791
* C3.1 R1.1 JP2.7 U1.3
*SIGNAL* VCC
* U2.14 Y1.8 JP5.2 U3.2 C1.1 U1.20 JP1.8 JP1.3
* C5.2 C6.1 C7.2 U1.7 Y1.7
*SIGNAL* N01384
* JP5.1 U1.1
*SIGNAL* N02594
*END*
*/
/* Generic netlist sample:
* $BeginNetlist
* $BeginComponentList
*
* $BeginComponent
* TimeStamp=32568D1E
* Footprint=
* Reference=JP1
* Value=CONN_8X2
* Libname=CONN_8X2
* $BeginPinList
* 1=GND
* 2=REF10_1
* 3=GND
* 4=REF11_1
* 5=GND
* 6=REF7_1
* 7=GND
* 8=REF9_1
* 9=GND
* 10=REF6_1
* 11=GND
* 12=REF8_1
* 13=GND
* 14=REF4_1
* 15=GND
* 16=REF5_1
* $EndPinList
* $EndComponent
*
* $BeginComponent
* TimeStamp=325679C1
* Footprint=
* Reference=RR1
* Value=9x1K
* Libref=RR9
* $BeginPinList
* 1=VCC
* 2=REF5_1
* 3=REF4_1
* 4=REF8_1
* 5=REF6_1
* 6=REF9_1
* 7=REF7_1
* 8=REF11_1
* 9=REF10_1
* 10=?
* $EndPinList
* $EndComponent
* $EndComponentList
*
* $BeginNets
* Net 0 ""
* Net 1 "GND"
* BUS1 31
* U3 19
* U3 10
* U3 1
* Net 172 ""
* BUS1 32
* Net 173 ""
* BUS1 30
* $EndNets
*
* $EndNetlist
*/
char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine );
int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
int ReadAndWriteNetsDataSection( FILE* InFile, FILE* OutFile, int* LineNumber );
int AreStringsEqual( const char * src, const char * ref );
class ComponentDataClass
{
public:
char m_Reference[256];
char m_Value[256];
char m_Footprint[256];
char m_LibRef[256];
long m_TimeStamp;
public:
ComponentDataClass()
{
InitData();
}
void InitData()
{
m_TimeStamp = 0;
m_Reference[0] = 0;
m_Value[0] = 0;
m_Footprint[0] = 0;
m_LibRef[0] = 0;
}
};
/********************************/
int main( int argc, char** argv )
/********************************/
{
char* InputfileName, * OutputFilename;
FILE* InFile, * OutFile;
int LineNumber;
char Line[1024];
if( argc < 3 )
{
printf( "\nUsage; netlist_form_pads-pcb infile outfile\n" );
return -1;
}
InputfileName = argv[1];
OutputFilename = argv[2];
if( ( InFile = fopen( InputfileName, "rt" ) ) == NULL )
{
printf( "Failed to open file %s", InputfileName );
return -2;
}
if( ( OutFile = fopen( OutputFilename, "wt" ) ) == NULL )
{
printf( "Failed to create file %s", OutputFilename );
return -3;
}
/* Write header: */
fprintf( OutFile, "*PADS-PCB*\n*PART*\n" );
/* Read and write data lines */
while( GetLine( InFile, Line, &LineNumber, sizeof(Line) ) )
{
if( AreStringsEqual( Line, "$BeginComponent" ) )
{
ReadAndWriteComponentDataSection( InFile, OutFile, &LineNumber );
continue;
}
if( AreStringsEqual( Line, "$BeginNets" ) )
{
fprintf( OutFile, "\n*NET*\n" );
ReadAndWriteNetsDataSection( InFile, OutFile, &LineNumber );
continue;
}
}
fprintf( OutFile, "*END*\n" );
fclose( InFile );
fclose( OutFile );
return 0;
}
/****************************************************************/
int ReadAndWriteComponentDataSection( FILE* InFile, FILE* OutFile, int* LineNumber )
/****************************************************************/
/* Read the Components Section from the Generic Netlist and create Components section in Pads-Pcb format
* For the component section only reference and footprint are used.
* Create lines like:
* C1 CHIP_D
* C2 unknown
*/
{
char Line[1024];
class ComponentDataClass ComponentData;
char* ident, * data;
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
{
if( AreStringsEqual( Line, "$BeginPinList" ) )
{
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
if( AreStringsEqual( Line, "$EndPinList" ) )
break;
continue;
}
if( AreStringsEqual( Line, "$EndComponent" ) ) // Create the output for the component:
{
/* Create the line like: C2 unknown */
fprintf( OutFile, "%s ", ComponentData.m_Reference );
fprintf( OutFile, "%s\n",
strlen( ComponentData.m_Footprint ) ? ComponentData.m_Footprint : "unknown" );
return 0;
}
ident = strtok( Line, "=\n\r" );
data = strtok( NULL, "=\n\r" );
if( data == NULL )
continue;
if( AreStringsEqual( Line, "TimeStamp" ) )
{
ComponentData.m_TimeStamp = atol( data );
continue;
}
if( AreStringsEqual( Line, "Footprint" ) )
{
strncpy( ComponentData.m_Footprint, data, 255 );
continue;
}
if( AreStringsEqual( Line, "Reference" ) )
{
strncpy( ComponentData.m_Reference, data, 255 );
continue;
}
if( AreStringsEqual( Line, "Value" ) )
{
strncpy( ComponentData.m_Value, data, 255 );
continue;
}
if( AreStringsEqual( Line, "Libref" ) )
{
strncpy( ComponentData.m_LibRef, data, 255 );
continue;
}
}
return 1;
}
/****************************************************************/
int ReadAndWriteNetsDataSection( FILE* InFile, FILE* OutFile, int* LineNumber )
/****************************************************************/
/* Read the Nets Section from the Generic Netlist and create Nets section in Pads-Pcb format
* create info type:
*SIGNAL* N03791
* C3.1 R1.1 JP2.7 U1.3
*/
{
char Line[1024];
char* ident, * netnum, * netname, * pin;
while( GetLine( InFile, Line, LineNumber, sizeof(Line) ) )
{
if( AreStringsEqual( Line, "$EndNets" ) )
return 0;
ident = strtok( Line, " \n\r" );
if( AreStringsEqual( ident, "Net" ) )
{
netnum = strtok( NULL, " \n\r" );
netname = strtok( NULL, " \"\n\r" );
if( (netname == NULL) || strlen( netname ) == 0 )
{ // Create the line like: *SIGNAL* N03791
int num = atoi( netnum );
sprintf( Line, "N-%6.6d", num );
netname = Line;
}
fprintf( OutFile, "*SIGNAL* %s\n", netname );
}
else
{
// Create the line like: C3.1 R1.1 JP2.7 U1.3
pin = strtok( NULL, " \n\r" );
fprintf( OutFile, " %s.%s\n", ident, pin );
}
}
return 1;
}
/*****************************************************************/
char* GetLine( FILE* File, char* Line, int* LineNum, int SizeLine )
/*****************************************************************/
/* Return a non empty line
* increment *LineNum for each read line
* Comment lines (starting by '#') are skipped
*/
{
do {
if( fgets( Line, SizeLine, File ) == NULL )
return NULL;
if( LineNum )
*LineNum += 1;
} while( Line[0] == '#' || Line[0] == '\n' || Line[0] == '\r'
|| Line[0] == 0 );
strtok( Line, "\n\r" );
return Line;
}
/***************************************************/
int AreStringsEqual( const char * src, const char * ref )
/***************************************************/
/* Compare 2 strings (case insensitive),
* and return 1 (true) if equal or 0 (false) if different
* stricmp does the same job, but does not exist under all systems
*/
{
int match = 1;
while (src && ref )
{
unsigned char c1 = *src;
unsigned char c2 = *ref;
if ( c1 >= 'a' && c1 <= 'z' )
c1 += 'A' - 'a';
if ( c2 >= 'a' && c2 <= 'z' )
c2 += 'A' - 'a';
if ( c1 != c2 )
{
match = 0;
break;
}
if ( c1 == 0 || c2 == 0 )
break;
src++; ref++;
}
return match;
}
G04 start of page 2 for group 0 idx 0
G04 Title: (unknown), component *
G04 Creator: pcb 20080202 *
G04 CreationDate: Sat 27 Feb 2010 07:29:32 PM GMT UTC *
G04 For: randomplague *
G04 Format: Gerber/RS-274X *
G04 PCB-Dimensions: 70000 45000 *
G04 PCB-Coordinate-Origin: lower left *
%MOIN*%
%FSLAX24Y24*%
%LNFRONT*%
%ADD11C,0.0200*%
%ADD12C,0.0600*%
%ADD13R,0.0200X0.0200*%
%ADD14R,0.0512X0.0512*%
%ADD15C,0.0380*%
G54D11*X1900Y1250D02*X1250D01*
X1900Y750D02*X750D01*
X2550D02*X3250D01*
X1250Y1250D02*X750Y1750D01*
X1900Y2250D02*Y2600D01*
X750Y3750D01*
X1000Y2750D02*X750D01*
X1000D02*X1500Y2250D01*
Y1750D02*X1900D01*
X1500D02*Y2250D01*
X3250Y750D02*Y3069D01*
X5750Y3750D02*X4000D01*
X4600Y2250D02*Y2900D01*
X4000Y3500D01*
X3250Y3069D02*X2819Y3500D01*
X4600Y750D02*X5750D01*
X4600Y1250D02*X5250D01*
X5750Y1750D01*
X4600D02*X5000D01*
X5750Y2750D02*X5250Y2250D01*
X5000Y2000D02*Y1750D01*
Y2000D02*X5250Y2250D01*
G54D11*G36*
X5450Y4050D02*Y3450D01*
X6050D01*
Y4050D01*
X5450D01*
G37*
G54D12*X5750Y2750D03*
Y1750D03*
G54D11*G36*
X450Y4050D02*Y3450D01*
X1050D01*
Y4050D01*
X450D01*
G37*
G54D12*X750Y2750D03*
Y1750D03*
Y750D03*
X5750D03*
G54D13*X3950D02*X4600D01*
X3950Y1250D02*X4600D01*
X3950Y1750D02*X4600D01*
X1900Y2250D02*X2550D01*
X1900Y1750D02*X2550D01*
X1900Y1250D02*X2550D01*
X1900Y750D02*X2550D01*
X3950Y2250D02*X4600D01*
G54D14*X2819Y4051D02*Y3500D01*
X4000Y4051D02*Y3500D01*
G54D15*M02*
......@@ -17,7 +17,7 @@
; General Product Description Definitions
!define PRODUCT_NAME "KiCad"
!define PRODUCT_VERSION "2010.05.05"
!define PRODUCT_VERSION "2010.12.06"
!define PRODUCT_WEB_SITE "http://iut-tice.ujf-grenoble.fr/kicad/"
!define SOURCEFORGE_WEB_SITE "http://kicad.sourceforge.net/"
!define COMPANY_NAME ""
......
This diff is collapsed.
This diff is collapsed.
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 18 2009)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_plot_base__
#define __dialog_plot_base__
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/gdicmn.h>
#include <wx/checkbox.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/radiobox.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_PLOT_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_PLOT_BASE : public wxDialog
{
private:
protected:
enum
{
ID_USE_GERBER_EXTENSIONS = 1000,
ID_ALLOW_PRINT_PAD_ON_SILKSCREEN,
ID_PRINT_VALUE,
ID_PRINT_REF,
ID_PRINT_MODULE_TEXTS,
ID_FORCE_PRINT_INVISIBLE_TEXT,
ID_DRILL_SHAPE_OPT,
ID_BROWSE_OUTPUT_DIRECTORY,
ID_MIROR_OPT,
ID_MASKVIA_OPT,
ID_EXEC_PLOT,
ID_SAVE_OPT_PLOT,
ID_CREATE_DRILL_FILE,
};
wxStaticBoxSizer* m_CopperLayersBoxSizer;
wxStaticBoxSizer* m_TechnicalLayersBoxSizer;
wxCheckBox* m_Use_Gerber_Extensions;
wxCheckBox* m_Exclude_Edges_Pcb;
wxCheckBox* m_SubtractMaskFromSilk;
wxCheckBox* m_Plot_Sheet_Ref;
wxCheckBox* m_Plot_Pads_on_Silkscreen;
wxCheckBox* m_Plot_Text_Value;
wxCheckBox* m_Plot_Text_Ref;
wxCheckBox* m_Plot_Text_Div;
wxCheckBox* m_Plot_Invisible_Text;
wxRadioBox* m_Drill_Shape_Opt;
wxRadioBox* m_Scale_Opt;
wxRadioBox* m_PlotModeOpt;
wxRadioBox* m_Choice_Plot_Offset;
wxRadioBox* m_PlotFormatOpt;
wxStaticText* m_textPenSize;
wxTextCtrl* m_HPGLPenSizeOpt;
wxStaticText* m_staticText3;
wxTextCtrl* m_HPGLPenSpeedOpt;
wxStaticText* m_textPenOvr;
wxTextCtrl* m_HPGLPenOverlayOpt;
wxCheckBox* m_Plot_PS_Negative;
wxTextCtrl* m_OutputDirectory;
wxButton* m_BrowseButton;
wxCheckBox* m_PlotMirorOpt;
wxCheckBox* m_PlotNoViaOnMaskOpt;
wxStaticText* m_staticText6;
wxTextCtrl* m_LinesWidth;
wxStaticText* m_staticText7;
wxTextCtrl* m_FineAdjustXscaleOpt;
wxStaticText* m_staticText8;
wxTextCtrl* m_FineAdjustYscaleOpt;
wxButton* m_PlotButton;
wxButton* m_buttonSaveOpt;
wxButton* m_buttonDrill;
wxButton* m_buttonQuit;
wxStaticText* m_staticText2;
wxTextCtrl* m_MessagesBox;
// Virtual event handlers, overide them in your derived class
virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void SetPlotFormat( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void Plot( wxCommandEvent& event ) { event.Skip(); }
virtual void SaveOptPlot( wxCommandEvent& event ) { event.Skip(); }
virtual void CreateDrillFile( wxCommandEvent& event ) { event.Skip(); }
virtual void OnQuit( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Plot"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_PLOT_BASE();
};
#endif //__dialog_plot_base__
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Sep 8 2010)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __dialog_plot_base__
#define __dialog_plot_base__
#include <wx/intl.h>
#include <wx/string.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
#include <wx/gdicmn.h>
#include <wx/checkbox.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/radiobox.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_PLOT_BASE
///////////////////////////////////////////////////////////////////////////////
class DIALOG_PLOT_BASE : public wxDialog
{
private:
protected:
enum
{
ID_USE_GERBER_EXTENSIONS = 1000,
ID_ALLOW_PRINT_PAD_ON_SILKSCREEN,
ID_PRINT_VALUE,
ID_PRINT_REF,
ID_PRINT_MODULE_TEXTS,
ID_FORCE_PRINT_INVISIBLE_TEXT,
ID_DRILL_SHAPE_OPT,
ID_BROWSE_OUTPUT_DIRECTORY,
ID_MIROR_OPT,
ID_MASKVIA_OPT,
ID_EXEC_PLOT,
ID_SAVE_OPT_PLOT,
ID_CREATE_DRILL_FILE,
};
wxStaticBoxSizer* m_CopperLayersBoxSizer;
wxStaticBoxSizer* m_TechnicalLayersBoxSizer;
wxCheckBox* m_Use_Gerber_Extensions;
wxCheckBox* m_Exclude_Edges_Pcb;
wxCheckBox* m_SubtractMaskFromSilk;
wxCheckBox* m_Plot_Sheet_Ref;
wxCheckBox* m_Plot_Pads_on_Silkscreen;
wxCheckBox* m_Plot_Text_Value;
wxCheckBox* m_Plot_Text_Ref;
wxCheckBox* m_Plot_Text_Div;
wxCheckBox* m_Plot_Invisible_Text;
wxRadioBox* m_Drill_Shape_Opt;
wxRadioBox* m_Scale_Opt;
wxRadioBox* m_PlotModeOpt;
wxRadioBox* m_Choice_Plot_Offset;
wxRadioBox* m_PlotFormatOpt;
wxStaticText* m_textPenSize;
wxTextCtrl* m_HPGLPenSizeOpt;
wxStaticText* m_staticText3;
wxTextCtrl* m_HPGLPenSpeedOpt;
wxStaticText* m_textPenOvr;
wxTextCtrl* m_HPGLPenOverlayOpt;
wxCheckBox* m_Plot_PS_Negative;
wxTextCtrl* m_OutputDirectory;
wxButton* m_BrowseButton;
wxCheckBox* m_PlotMirorOpt;
wxCheckBox* m_PlotNoViaOnMaskOpt;
wxStaticText* m_staticText6;
wxTextCtrl* m_LinesWidth;
wxStaticText* m_staticText7;
wxTextCtrl* m_FineAdjustXscaleOpt;
wxStaticText* m_staticText8;
wxTextCtrl* m_FineAdjustYscaleOpt;
wxButton* m_PlotButton;
wxButton* m_buttonSaveOpt;
wxButton* m_buttonDrill;
wxButton* m_buttonQuit;
wxStaticText* m_staticText2;
wxTextCtrl* m_MessagesBox;
// Virtual event handlers, overide them in your derived class
virtual void OnCloseWindow( wxCloseEvent& event ) { event.Skip(); }
virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); }
virtual void SetPlotFormat( wxCommandEvent& event ) { event.Skip(); }
virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); }
virtual void Plot( wxCommandEvent& event ) { event.Skip(); }
virtual void SaveOptPlot( wxCommandEvent& event ) { event.Skip(); }
virtual void CreateDrillFile( wxCommandEvent& event ) { event.Skip(); }
virtual void OnQuit( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Plot"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_PLOT_BASE();
};
#endif //__dialog_plot_base__
release version:
2010 dec 03 (BZR R2639)
2010 dec 06 (BZR testing 2644)
files (.zip,.tgz):
kicad-2010-12-03-testing
kicad-2010-12-06-testing
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