/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2009 Wayne Stambaugh * Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ /** * @file dialog_eeschema_options.cpp */ #include #include #include #include #include "../widgets/widget_eeschema_color_config.h" #include #include #include #include int DIALOG_EESCHEMA_OPTIONS::m_lastPageSelected = 0; DIALOG_EESCHEMA_OPTIONS::DIALOG_EESCHEMA_OPTIONS( SCH_EDIT_FRAME* parent ) : DIALOG_EESCHEMA_OPTIONS_BASE( parent ), m_last_scale( -1 ) { m_choiceUnits->SetFocus(); m_sdbSizerOK->SetDefault(); // wxformbuilder doesn't seem to let us set minimal sizes. Copy the default // sizes into the minimal sizes, then, and autosize: for( int i = 0; i < m_fieldGrid->GetNumberCols(); ++i ) { m_fieldGrid->SetColMinimalWidth( i, m_fieldGrid->GetColSize( i ) ); m_fieldGrid->AutoSizeColLabelSize( i ); } m_scaleSlider->SetStep( 25 ); // Embed the hotkeys list HOTKEY_SECTIONS sections = WIDGET_HOTKEY_LIST::GenSections( g_Schematic_Hokeys_Descr ); m_hotkeyListCtrl = new WIDGET_HOTKEY_LIST( m_panelHotkeys, sections ); m_hotkeyListCtrl->InstallOnPanel( m_panelHotkeys ); // Embed the color configurator m_colorConfigCtrl = new WIDGET_EESCHEMA_COLOR_CONFIG( m_panelColors, GetParent() ); m_colorConfigCtrl->InstallOnPanel( m_panelColors ); // Make sure we select the last used tab of the options tab page m_notebook->SetSelection( m_lastPageSelected ); // Lay out all child pages // No, I don't know why this->Layout() doesn't propagate through to these, // but at least on MSW, it does not. for( size_t i = 0; i < m_notebook->GetPageCount(); ++i ) { m_notebook->GetPage( i )->Layout(); } Layout(); // Now all widgets have the size fixed, call FinishDialogSettings FinishDialogSettings(); } SCH_EDIT_FRAME* DIALOG_EESCHEMA_OPTIONS::GetParent() { return static_cast( DIALOG_EESCHEMA_OPTIONS_BASE::GetParent() ); } void DIALOG_EESCHEMA_OPTIONS::SetUnits( const wxArrayString& aUnits, int aSelect ) { wxASSERT( aUnits.GetCount() > 0 && ( aSelect >= 0 && (size_t) aSelect < aUnits.GetCount() ) ); m_choiceUnits->Append( aUnits ); m_choiceUnits->SetSelection( aSelect ); } void DIALOG_EESCHEMA_OPTIONS::SetRefIdSeparator( wxChar aSep, wxChar aFirstId) { // m_choiceSeparatorRefId displays one of // "A" ".A" "-A" "_A" ".1" "-1" "_1" option int sel = 0; switch( aSep ) { default: case 0: aFirstId = 'A'; // cannot use a number without separator break; case '.': sel = 1; break; case '-': sel = 2; break; case '_': sel = 3; break; } if( aFirstId == '1' ) sel += 3; m_choiceSeparatorRefId->SetSelection( sel ); } void DIALOG_EESCHEMA_OPTIONS::GetRefIdSeparator( int& aSep, int& aFirstId) { // m_choiceSeparatorRefId displays one of // "A" ".A" "-A" "_A" ".1" "-1" "_1" option aFirstId = 'A'; switch( m_choiceSeparatorRefId->GetSelection() ) { default: case 0: aSep = 0; break; case 1: aSep = '.'; break; case 2: aSep = '-'; break; case 3: aSep = '_'; break; case 4: aFirstId = '1'; aSep = '.'; break; case 5: aFirstId = '1'; aSep = '-'; break; case 6: aFirstId = '1'; aSep = '_'; break; } } void DIALOG_EESCHEMA_OPTIONS::SetGridSizes( const GRIDS& aGridSizes, int aGridId ) { wxASSERT( aGridSizes.size() > 0 ); int select = wxNOT_FOUND; for( size_t i = 0; i < aGridSizes.size(); i++ ) { wxString tmp; tmp.Printf( wxT( "%0.1f" ), aGridSizes[i].m_Size.x ); m_choiceGridSize->Append( tmp ); if( aGridSizes[i].m_CmdId == aGridId ) select = (int) i; } m_choiceGridSize->SetSelection( select ); } void DIALOG_EESCHEMA_OPTIONS::OnAddButtonClick( wxCommandEvent& event ) { // If a single row is selected, insert after that row. int selected_row = -1; int n_found = 0; for( int row = 0; row < m_fieldGrid->GetNumberRows(); ++row ) { bool this_row_selected = false; for( int col = 0; col < m_fieldGrid->GetNumberCols(); ++col ) { if( m_fieldGrid->IsInSelection( row, col ) ) this_row_selected = true; } if( this_row_selected ) { selected_row = row; ++n_found; } } TransferDataFromFieldGrid(); TEMPLATE_FIELDNAMES::iterator pos; if( n_found == 1 ) pos = templateFields.begin() + selected_row + 1; else pos = templateFields.end(); // Add a new fieldname to the fieldname list TEMPLATE_FIELDNAME newFieldname = TEMPLATE_FIELDNAME( "Fieldname" ); newFieldname.m_Value = wxT( "Value" ); newFieldname.m_Visible = false; templateFields.insert( pos, newFieldname ); TransferDataToFieldGrid(); event.Skip(); } void DIALOG_EESCHEMA_OPTIONS::OnDeleteButtonClick( wxCommandEvent& event ) { // wxGrid has a somewhat complex way of detemining selection. // This is pretty much the easiest way to do it, here. std::vector rows_to_delete( templateFields.size(), false ); for( int row = 0; row < m_fieldGrid->GetNumberRows(); ++row ) { for( int col = 0; col < m_fieldGrid->GetNumberCols(); ++col ) { if( m_fieldGrid->IsInSelection( row, col ) ) rows_to_delete[row] = true; } } TransferDataFromFieldGrid(); int n_rows = m_fieldGrid->GetNumberRows(); for( int count = 0; count < n_rows; ++count ) { // Iterate backwards, unsigned-friendly way for future int row = n_rows - count - 1; if( rows_to_delete[row] ) { templateFields.erase( templateFields.begin() + row ); } } TransferDataToFieldGrid(); } void DIALOG_EESCHEMA_OPTIONS::OnScaleSlider( wxScrollEvent& aEvent ) { m_scaleAuto->SetValue( false ); } void DIALOG_EESCHEMA_OPTIONS::OnScaleAuto( wxCommandEvent& aEvent ) { if( m_scaleAuto->GetValue() ) { m_last_scale = m_scaleSlider->GetValue(); m_scaleSlider->SetValue( 25 * KiIconScale( GetParent() ) ); } else { if( m_last_scale >= 0 ) m_scaleSlider->SetValue( m_last_scale ); } } bool DIALOG_EESCHEMA_OPTIONS::TransferDataToWindow() { if( !wxDialog::TransferDataToWindow() ) return false; if( !m_hotkeyListCtrl->TransferDataToControl() ) return false; if( !TransferDataToFieldGrid() ) return false; int scale_fourths = GetParent()->GetIconScale(); if( scale_fourths <= 0 ) { m_scaleAuto->SetValue( true ); m_scaleSlider->SetValue( 25 * KiIconScale( GetParent() ) ); } else { m_scaleAuto->SetValue( false ); m_scaleSlider->SetValue( scale_fourths * 25 ); } Layout(); return true; } bool DIALOG_EESCHEMA_OPTIONS::TransferDataFromWindow() { m_lastPageSelected = m_notebook->GetSelection(); if( !wxDialog::TransferDataFromWindow() ) return false; if( !m_hotkeyListCtrl->TransferDataFromControl() ) return false; GetParent()->WriteHotkeyConfig( g_Eeschema_Hokeys_Descr ); if( !m_colorConfigCtrl->TransferDataFromControl() ) return false; if( !TransferDataFromFieldGrid() ) return false; const int scale_fourths = m_scaleAuto->GetValue() ? -1 : m_scaleSlider->GetValue() / 25; if( GetParent()->GetIconScale() != scale_fourths ) GetParent()->SetIconScale( scale_fourths ); // Refresh hotkeys GetParent()->ReCreateMenuBar(); GetParent()->Refresh(); return true; } bool DIALOG_EESCHEMA_OPTIONS::TransferDataToFieldGrid() { m_fieldGrid->Freeze(); if( m_fieldGrid->GetNumberRows() ) m_fieldGrid->DeleteRows( 0, m_fieldGrid->GetNumberRows() ); m_fieldGrid->AppendRows( templateFields.size() ); for( int row = 0; row < m_fieldGrid->GetNumberRows(); ++row ) { m_fieldGrid->SetCellValue( row, 0, templateFields[row].m_Name ); m_fieldGrid->SetCellValue( row, 1, templateFields[row].m_Value ); m_fieldGrid->SetCellValue( row, 2, templateFields[row].m_Visible ? wxT( "1" ) : wxEmptyString ); // Set cell properties m_fieldGrid->SetCellAlignment( row, 0, wxALIGN_LEFT, wxALIGN_CENTRE ); m_fieldGrid->SetCellAlignment( row, 1, wxALIGN_LEFT, wxALIGN_CENTRE ); // Render the Visible column as a check box m_fieldGrid->SetCellEditor( row, 2, new wxGridCellBoolEditor() ); m_fieldGrid->SetCellRenderer( row, 2, new wxGridCellBoolRenderer() ); m_fieldGrid->SetCellAlignment( row, 2, wxALIGN_CENTRE, wxALIGN_CENTRE ); } m_fieldGrid->AutoSizeRows(); m_fieldGrid->Thaw(); return true; } bool DIALOG_EESCHEMA_OPTIONS::TransferDataFromFieldGrid() { for( int row = 0; row < m_fieldGrid->GetNumberRows(); ++row ) { templateFields[row].m_Name = m_fieldGrid->GetCellValue( row, 0 ); templateFields[row].m_Value = m_fieldGrid->GetCellValue( row, 1 ); templateFields[row].m_Visible = ( m_fieldGrid->GetCellValue( row, 2 ) != wxEmptyString ); } return true; } void DIALOG_EESCHEMA_OPTIONS::SetTemplateFields( const TEMPLATE_FIELDNAMES& aFields ) { // Set the template fields object templateFields = aFields; // Build and refresh the view TransferDataToFieldGrid(); } TEMPLATE_FIELDNAMES DIALOG_EESCHEMA_OPTIONS::GetTemplateFields( void ) { return templateFields; }