diff --git a/common/selcolor.cpp b/common/selcolor.cpp index c9574b45a5..8d4308d27f 100644 --- a/common/selcolor.cpp +++ b/common/selcolor.cpp @@ -77,7 +77,7 @@ EDA_COLOR_T DisplayColorFrame( wxWindow* aParent, EDA_COLOR_T aOldColor ) CHOOSE_COLOR_DLG::CHOOSE_COLOR_DLG( wxWindow* aParent, EDA_COLOR_T aOldColor ) : - wxDialog( aParent, -1, _( "Colors" ), wxDefaultPosition, wxDefaultSize, + wxDialog( aParent, wxID_ANY, _( "Colors" ), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ) { m_color = aOldColor; @@ -85,6 +85,8 @@ CHOOSE_COLOR_DLG::CHOOSE_COLOR_DLG( wxWindow* aParent, EDA_COLOR_T aOldColor ) : init_Dialog(); // Resize the dialog GetSizer()->SetSizeHints( this ); + + Centre(); } void CHOOSE_COLOR_DLG::init_Dialog() diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index 33d95c4f0c..a850228702 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -793,11 +793,12 @@ public: * @param aSide = 0 to list footprints on BACK side, * 1 to list footprints on FRONT side * 2 to list footprints on both sides + * @param aFormatCSV = true to use a comma separated file (CSV) format; defautl = false * @return the number of footprints found on aSide side, * or -1 if the file could not be created */ int DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, - bool aForceSmdItems, int aSide ); + bool aForceSmdItems, int aSide, bool aFormatCSV = false ); /** * Function GenFootprintsReport diff --git a/pcbnew/dialogs/dialog_gen_module_position_file_base.cpp b/pcbnew/dialogs/dialog_gen_module_position_file_base.cpp index 352459a90d..3c2798ab2a 100644 --- a/pcbnew/dialogs/dialog_gen_module_position_file_base.cpp +++ b/pcbnew/dialogs/dialog_gen_module_position_file_base.cpp @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Mar 9 2015) +// C++ code generated with wxFormBuilder (version Mar 28 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -31,7 +31,6 @@ DIALOG_GEN_MODULE_POSITION_BASE::DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* pare bSizerdirBrowse = new wxBoxSizer( wxHORIZONTAL ); m_outputDirectoryName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); - m_outputDirectoryName->SetMaxLength( 0 ); m_outputDirectoryName->SetToolTip( _("Target directory for plot files. Can be absolute or relative to the board file location.") ); m_outputDirectoryName->SetMinSize( wxSize( 350,-1 ) ); @@ -52,11 +51,17 @@ DIALOG_GEN_MODULE_POSITION_BASE::DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* pare wxBoxSizer* bSizerOptions; bSizerOptions = new wxBoxSizer( wxHORIZONTAL ); + wxString m_rbFormatChoices[] = { _("Ascii"), _("CSV") }; + int m_rbFormatNChoices = sizeof( m_rbFormatChoices ) / sizeof( wxString ); + m_rbFormat = new wxRadioBox( this, wxID_ANY, _("Format:"), wxDefaultPosition, wxDefaultSize, m_rbFormatNChoices, m_rbFormatChoices, 1, wxRA_SPECIFY_COLS ); + m_rbFormat->SetSelection( 0 ); + bSizerOptions->Add( m_rbFormat, 0, wxALL, 5 ); + wxString m_radioBoxUnitsChoices[] = { _("Inches"), _("mm") }; int m_radioBoxUnitsNChoices = sizeof( m_radioBoxUnitsChoices ) / sizeof( wxString ); m_radioBoxUnits = new wxRadioBox( this, wxID_ANY, _("Units:"), wxDefaultPosition, wxDefaultSize, m_radioBoxUnitsNChoices, m_radioBoxUnitsChoices, 1, wxRA_SPECIFY_COLS ); m_radioBoxUnits->SetSelection( 0 ); - bSizerOptions->Add( m_radioBoxUnits, 1, wxALL, 5 ); + bSizerOptions->Add( m_radioBoxUnits, 0, wxALL|wxEXPAND, 5 ); wxString m_radioBoxFilesCountChoices[] = { _("One file per side"), _("One file for board") }; int m_radioBoxFilesCountNChoices = sizeof( m_radioBoxFilesCountChoices ) / sizeof( wxString ); @@ -104,8 +109,6 @@ DIALOG_GEN_MODULE_POSITION_BASE::DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* pare this->Centre( wxBOTH ); // Connect Events - this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnClose ) ); - this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnInitDialog ) ); m_browseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOutputDirectoryBrowseClicked ), NULL, this ); m_sdbSizerButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOKButton ), NULL, this ); } @@ -113,8 +116,6 @@ DIALOG_GEN_MODULE_POSITION_BASE::DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* pare DIALOG_GEN_MODULE_POSITION_BASE::~DIALOG_GEN_MODULE_POSITION_BASE() { // Disconnect Events - this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnClose ) ); - this->Disconnect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnInitDialog ) ); m_browseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOutputDirectoryBrowseClicked ), NULL, this ); m_sdbSizerButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_GEN_MODULE_POSITION_BASE::OnOKButton ), NULL, this ); diff --git a/pcbnew/dialogs/dialog_gen_module_position_file_base.fbp b/pcbnew/dialogs/dialog_gen_module_position_file_base.fbp index 6b5131a5ab..efbc343fcb 100644 --- a/pcbnew/dialogs/dialog_gen_module_position_file_base.fbp +++ b/pcbnew/dialogs/dialog_gen_module_position_file_base.fbp @@ -44,7 +44,7 @@ -1,-1 DIALOG_GEN_MODULE_POSITION_BASE - 510,351 + 525,304 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER DIALOG_SHIM; dialog_shim.h Generate Component Position Files @@ -61,13 +61,13 @@ - OnClose + - OnInitDialog + @@ -400,7 +400,97 @@ 5 wxALL - 1 + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + "Ascii" "CSV" + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Format: + 1 + + 0 + + + 0 + + 1 + m_rbFormat + 1 + + + protected + 1 + + Resizable + 0 + 1 + + wxRA_SPECIFY_COLS + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 1 1 diff --git a/pcbnew/dialogs/dialog_gen_module_position_file_base.h b/pcbnew/dialogs/dialog_gen_module_position_file_base.h index 72a4bd9577..cc64f79ff0 100644 --- a/pcbnew/dialogs/dialog_gen_module_position_file_base.h +++ b/pcbnew/dialogs/dialog_gen_module_position_file_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version Mar 9 2015) +// C++ code generated with wxFormBuilder (version Mar 28 2016) // http://www.wxformbuilder.org/ // // PLEASE DO "NOT" EDIT THIS FILE! @@ -42,6 +42,7 @@ class DIALOG_GEN_MODULE_POSITION_BASE : public DIALOG_SHIM wxStaticText* m_staticTextDir; wxTextCtrl* m_outputDirectoryName; wxButton* m_browseButton; + wxRadioBox* m_rbFormat; wxRadioBox* m_radioBoxUnits; wxRadioBox* m_radioBoxFilesCount; wxRadioBox* m_radioBoxForceSmd; @@ -51,15 +52,13 @@ class DIALOG_GEN_MODULE_POSITION_BASE : public DIALOG_SHIM wxButton* m_sdbSizerButtonsCancel; // Virtual event handlers, overide them in your derived class - virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } - virtual void OnInitDialog( wxInitDialogEvent& event ) { event.Skip(); } virtual void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ) { event.Skip(); } virtual void OnOKButton( wxCommandEvent& event ) { event.Skip(); } public: - DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Component Position Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 510,351 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_GEN_MODULE_POSITION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Generate Component Position Files"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 525,304 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_GEN_MODULE_POSITION_BASE(); }; diff --git a/pcbnew/exporters/gen_modules_placefile.cpp b/pcbnew/exporters/gen_modules_placefile.cpp index 202ddb1518..8bc79ab942 100644 --- a/pcbnew/exporters/gen_modules_placefile.cpp +++ b/pcbnew/exporters/gen_modules_placefile.cpp @@ -50,7 +50,7 @@ #include /* - * The format of the kicad place file is: + * The ASCII format of the kicad place file is: * ### Module positions - created on 04/12/2012 15:24:24 ### * ### Printed by Pcbnew version pcbnew (2012-11-30 BZR 3828)-testing * ## Unit = inches, Angle = deg. @@ -68,8 +68,9 @@ * ## End */ -#define PLACEFILE_UNITS_KEY wxT( "PlaceFileUnits" ) -#define PLACEFILE_OPT_KEY wxT( "PlaceFileOpts" ) +#define PLACEFILE_UNITS_KEY wxT( "PlaceFileUnits" ) +#define PLACEFILE_OPT_KEY wxT( "PlaceFileOpts" ) +#define PLACEFILE_FORMAT_KEY wxT( "PlaceFileFormat" ) #define PCB_BACK_SIDE 0 @@ -113,6 +114,7 @@ private: static int m_unitsOpt; static int m_fileOpt; + static int m_fileFormat; void initDialog(); void OnOutputDirectoryBrowseClicked( wxCommandEvent& event ); @@ -146,6 +148,7 @@ private: // Static members to remember choices int DIALOG_GEN_MODULE_POSITION::m_unitsOpt = 0; int DIALOG_GEN_MODULE_POSITION::m_fileOpt = 0; +int DIALOG_GEN_MODULE_POSITION::m_fileFormat = 0; // Use standard board side name. do not translate them, // they are keywords in place file @@ -157,11 +160,13 @@ void DIALOG_GEN_MODULE_POSITION::initDialog() m_config = Kiface().KifaceSettings(); m_config->Read( PLACEFILE_UNITS_KEY, &m_unitsOpt, 1 ); m_config->Read( PLACEFILE_OPT_KEY, &m_fileOpt, 0 ); + m_config->Read( PLACEFILE_FORMAT_KEY, &m_fileFormat, 0 ); // Output directory m_outputDirectoryName->SetValue( m_plotOpts.GetOutputDirectory() ); m_radioBoxUnits->SetSelection( m_unitsOpt ); m_radioBoxFilesCount->SetSelection( m_fileOpt ); + m_rbFormat->SetSelection( m_fileFormat ); m_sdbSizerButtonsOK->SetDefault(); } @@ -199,9 +204,12 @@ void DIALOG_GEN_MODULE_POSITION::OnOKButton( wxCommandEvent& event ) { m_unitsOpt = m_radioBoxUnits->GetSelection(); m_fileOpt = m_radioBoxFilesCount->GetSelection(); + m_fileFormat = m_rbFormat->GetSelection(); + m_config->Write( PLACEFILE_UNITS_KEY, m_unitsOpt ); m_config->Write( PLACEFILE_OPT_KEY, m_fileOpt ); + m_config->Write( PLACEFILE_FORMAT_KEY, m_fileFormat ); // Set output directory and replace backslashes with forward ones // (Keep unix convention in cfg files) @@ -210,10 +218,11 @@ void DIALOG_GEN_MODULE_POSITION::OnOKButton( wxCommandEvent& event ) dirStr.Replace( wxT( "\\" ), wxT( "/" ) ); m_plotOpts.SetOutputDirectory( dirStr ); - m_parent->SetPlotSettings( m_plotOpts ); CreateFiles(); + + // the dialog is not closed here. } @@ -223,11 +232,13 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles() wxFileName fn; wxString msg; bool singleFile = OneFileOnly(); + bool useCSVfmt = m_fileFormat == 1; int fullcount = 0; // Count the footprints to place, do not yet create a file int fpcount = m_parent->DoGenFootprintsPositionFile( wxEmptyString, UnitsMM(), - ForceAllSmd(), PCB_BOTH_SIDES ); + ForceAllSmd(), PCB_BOTH_SIDES, + useCSVfmt ); if( fpcount == 0) { wxMessageBox( _( "No footprint for automated placement." ) ); @@ -235,7 +246,7 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles() } // Create output directory if it does not exist (also transform it in - // absolute form). Bail if it fails + // absolute path). Bail if it fails wxFileName outputDir = wxFileName::DirName( m_plotOpts.GetOutputDirectory() ); wxString boardFilename = m_parent->GetBoard()->GetFileName(); @@ -264,10 +275,17 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles() else fn.SetName( fn.GetName() + wxT( "-" ) + frontSideName ); - fn.SetExt( FootprintPlaceFileExtension ); + + if( useCSVfmt ) + { + fn.SetName( fn.GetName() + wxT( "-" ) + FootprintPlaceFileExtension ); + fn.SetExt( wxT( "csv" ) ); + } + else + fn.SetExt( FootprintPlaceFileExtension ); fpcount = m_parent->DoGenFootprintsPositionFile( fn.GetFullPath(), UnitsMM(), - ForceAllSmd(), side ); + ForceAllSmd(), side, useCSVfmt ); if( fpcount < 0 ) { msg.Printf( _( "Unable to create '%s'." ), GetChars( fn.GetFullPath() ) ); @@ -298,10 +316,17 @@ bool DIALOG_GEN_MODULE_POSITION::CreateFiles() fn = brd->GetFileName(); fn.SetPath( outputDir.GetPath() ); fn.SetName( fn.GetName() + wxT( "-" ) + backSideName ); - fn.SetExt( wxT( "pos" ) ); + + if( useCSVfmt ) + { + fn.SetName( fn.GetName() + wxT( "-" ) + FootprintPlaceFileExtension ); + fn.SetExt( wxT( "csv" ) ); + } + else + fn.SetExt( FootprintPlaceFileExtension ); fpcount = m_parent->DoGenFootprintsPositionFile( fn.GetFullPath(), UnitsMM(), - ForceAllSmd(), side ); + ForceAllSmd(), side, useCSVfmt ); if( fpcount < 0 ) { @@ -390,7 +415,8 @@ void PCB_EDIT_FRAME::GenFootprintsPositionFile( wxCommandEvent& event ) */ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, bool aUnitsMM, - bool aForceSmdItems, int aSide ) + bool aForceSmdItems, int aSide, + bool aFormatCSV ) { MODULE* footprint; @@ -477,58 +503,99 @@ int PCB_EDIT_FRAME::DoGenFootprintsPositionFile( const wxString& aFullFileName, // Switch the locale to standard C (needed to print floating point numbers) LOCALE_IO toggle; - // Write file header - fprintf( file, "### Module positions - created on %s ###\n", TO_UTF8( DateAndTime() ) ); - - wxString Title = Pgm().App().GetAppName() + wxT( " " ) + GetBuildVersion(); - fprintf( file, "### Printed by Pcbnew version %s\n", TO_UTF8( Title ) ); - - fputs( unit_text, file ); - - fputs( "## Side : ", file ); - - if( aSide == PCB_BACK_SIDE ) - fputs( TO_UTF8( backSideName ), file ); - else if( aSide == PCB_FRONT_SIDE ) - fputs( TO_UTF8( frontSideName ), file ); - else - fputs( "All", file ); - - fputs( "\n", file ); - - fprintf(file, "%-*s %-*s %-*s %9.9s %9.9s %8.8s %s\n", - int(lenRefText), "# Ref", - int(lenValText), "Val", - int(lenPkgText), "Package", - "PosX", "PosY", "Rot", "Side" ); - - for( int ii = 0; ii < footprintCount; ii++ ) + if( aFormatCSV ) { - wxPoint footprint_pos; - footprint_pos = list[ii].m_Module->GetPosition(); - footprint_pos -= File_Place_Offset; + wxChar csv_sep = ','; - LAYER_NUM layer = list[ii].m_Module->GetLayer(); - wxASSERT( layer==F_Cu || layer==B_Cu ); + // Set first line:; + fprintf( file, "Ref%cVal%cPackage%cPosX%cPosY%cRot%cSide\n", + csv_sep, csv_sep, csv_sep, csv_sep, csv_sep, csv_sep ); - const wxString& ref = list[ii].m_Reference; - const wxString& val = list[ii].m_Value; - const wxString& pkg = list[ii].m_Module->GetFPID().GetFootprintName(); + for( int ii = 0; ii < footprintCount; ii++ ) + { + wxPoint footprint_pos; + footprint_pos = list[ii].m_Module->GetPosition(); + footprint_pos -= File_Place_Offset; - fprintf(file, "%-*s %-*s %-*s %9.4f %9.4f %8.4f %s\n", - lenRefText, TO_UTF8( ref ), - lenValText, TO_UTF8( val ), - lenPkgText, TO_UTF8( pkg ), - footprint_pos.x * conv_unit, - // Keep the coordinates in the first quadrant, - // (i.e. change y sign - -footprint_pos.y * conv_unit, - list[ii].m_Module->GetOrientation() / 10.0, - (layer == F_Cu ) ? TO_UTF8( frontSideName ) : TO_UTF8( backSideName )); + LAYER_NUM layer = list[ii].m_Module->GetLayer(); + wxASSERT( layer == F_Cu || layer == B_Cu ); + + wxString line = list[ii].m_Reference; + line << csv_sep; + line << list[ii].m_Value; + line << csv_sep; + line << wxString( list[ii].m_Module->GetFPID().GetFootprintName() ); + line << csv_sep; + + line << wxString::Format( "%f%c%f%c%f", + footprint_pos.x * conv_unit, csv_sep, + // Keep the Y axis oriented from bottom to top, + // ( change y coordinate sign ) + -footprint_pos.y * conv_unit, csv_sep, + list[ii].m_Module->GetOrientation() / 10.0 ); + line << csv_sep; + + line << ( (layer == F_Cu ) ? frontSideName : backSideName ); + line << '\n'; + + fputs( TO_UTF8( line ), file ); + } } + else + { + // Write file header + fprintf( file, "### Module positions - created on %s ###\n", TO_UTF8( DateAndTime() ) ); - // Write EOF - fputs( "## End\n", file ); + wxString Title = Pgm().App().GetAppName() + wxT( " " ) + GetBuildVersion(); + fprintf( file, "### Printed by Pcbnew version %s\n", TO_UTF8( Title ) ); + + fputs( unit_text, file ); + + fputs( "## Side : ", file ); + + if( aSide == PCB_BACK_SIDE ) + fputs( TO_UTF8( backSideName ), file ); + else if( aSide == PCB_FRONT_SIDE ) + fputs( TO_UTF8( frontSideName ), file ); + else + fputs( "All", file ); + + fputs( "\n", file ); + + fprintf(file, "%-*s %-*s %-*s %9.9s %9.9s %8.8s %s\n", + int(lenRefText), "# Ref", + int(lenValText), "Val", + int(lenPkgText), "Package", + "PosX", "PosY", "Rot", "Side" ); + + for( int ii = 0; ii < footprintCount; ii++ ) + { + wxPoint footprint_pos; + footprint_pos = list[ii].m_Module->GetPosition(); + footprint_pos -= File_Place_Offset; + + LAYER_NUM layer = list[ii].m_Module->GetLayer(); + wxASSERT( layer == F_Cu || layer == B_Cu ); + + const wxString& ref = list[ii].m_Reference; + const wxString& val = list[ii].m_Value; + const wxString& pkg = list[ii].m_Module->GetFPID().GetFootprintName(); + + fprintf(file, "%-*s %-*s %-*s %9.4f %9.4f %8.4f %s\n", + lenRefText, TO_UTF8( ref ), + lenValText, TO_UTF8( val ), + lenPkgText, TO_UTF8( pkg ), + footprint_pos.x * conv_unit, + // Keep the coordinates in the first quadrant, + // (i.e. change y sign + -footprint_pos.y * conv_unit, + list[ii].m_Module->GetOrientation() / 10.0, + (layer == F_Cu ) ? TO_UTF8( frontSideName ) : TO_UTF8( backSideName )); + } + + // Write EOF + fputs( "## End\n", file ); + } fclose( file ); return footprintCount;