ADDED: PCB tables.
This commit is contained in:
parent
48f983826d
commit
e445249720
|
@ -42,6 +42,8 @@
|
|||
#include <pcb_track.h>
|
||||
#include <pcb_base_frame.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <zone.h>
|
||||
|
@ -376,6 +378,9 @@ private:
|
|||
void addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
|
||||
void addTable( const PCB_TABLE* aTable, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner );
|
||||
|
||||
void addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aDstContainer,
|
||||
PCB_LAYER_ID aLayerId );
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <pad.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <pcb_painter.h> // for PCB_RENDER_SETTINGS
|
||||
#include <zone.h>
|
||||
|
@ -225,12 +226,17 @@ void BOARD_ADAPTER::addFootprintShapes( const FOOTPRINT* aFootprint, CONTAINER_2
|
|||
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( item );
|
||||
|
||||
if( textbox->GetLayer() == aLayerId )
|
||||
{
|
||||
if( textbox->IsBorderEnabled() )
|
||||
addShape( textbox, aContainer, aFootprint );
|
||||
addShape( textbox, aContainer, aFootprint );
|
||||
|
||||
addText( textbox, aContainer, aFootprint );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
{
|
||||
PCB_TABLE* table = static_cast<PCB_TABLE*>( item );
|
||||
|
||||
if( table->GetLayer() == aLayerId )
|
||||
addTable( table, aContainer, aFootprint );
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -726,7 +732,9 @@ void BOARD_ADAPTER::addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aC
|
|||
// So for polygon, we use PCB_SHAPE::TransformShapeToPolygon
|
||||
|
||||
if( aTextBox->GetShape() == SHAPE_T::RECTANGLE )
|
||||
{
|
||||
addShape( static_cast<const PCB_SHAPE*>( aTextBox ), aContainer, aOwner );
|
||||
}
|
||||
else
|
||||
{
|
||||
SHAPE_POLY_SET polyList;
|
||||
|
@ -739,6 +747,17 @@ void BOARD_ADAPTER::addShape( const PCB_TEXTBOX* aTextBox, CONTAINER_2D_BASE* aC
|
|||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::addTable( const PCB_TABLE* aTable, CONTAINER_2D_BASE* aContainer,
|
||||
const BOARD_ITEM* aOwner )
|
||||
{
|
||||
// JEY TODO: tables
|
||||
// add borders
|
||||
|
||||
for( PCB_TABLECELL* cell : aTable->GetCells() )
|
||||
addText( cell, aContainer, aOwner );
|
||||
}
|
||||
|
||||
|
||||
void BOARD_ADAPTER::addSolidAreasShapes( const ZONE* aZone, CONTAINER_2D_BASE* aContainer,
|
||||
PCB_LAYER_ID aLayerId )
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <pad.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <zone.h>
|
||||
#include <convert_basic_shapes_to_polygon.h>
|
||||
|
@ -622,6 +623,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
addShape( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
|
||||
break;
|
||||
|
||||
case PCB_TABLE_T:
|
||||
addTable( static_cast<PCB_TABLE*>( item ), layerContainer, item );
|
||||
break;
|
||||
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
case PCB_DIM_CENTER_T:
|
||||
case PCB_DIM_RADIAL_T:
|
||||
|
@ -686,6 +691,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
break;
|
||||
|
||||
default:
|
||||
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ),
|
||||
item->Type() );
|
||||
|
@ -847,6 +856,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
addShape( static_cast<PCB_TEXTBOX*>( item ), layerContainer, item );
|
||||
break;
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
break;
|
||||
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
case PCB_DIM_CENTER_T:
|
||||
case PCB_DIM_RADIAL_T:
|
||||
|
@ -942,6 +955,10 @@ void BOARD_ADAPTER::createLayers( REPORTER* aStatusReporter )
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -680,6 +680,8 @@ set( PCB_COMMON_SRCS
|
|||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_target.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_reference_image.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_field.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_table.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_tablecell.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_text.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/pcb_textbox.cpp
|
||||
${CMAKE_SOURCE_DIR}/pcbnew/project_pcb.cpp
|
||||
|
|
|
@ -349,6 +349,8 @@ static struct EDA_ITEM_DESC
|
|||
.Map( PCB_FIELD_T, _HKI( "Text" ) )
|
||||
.Map( PCB_TEXT_T, _HKI( "Text" ) )
|
||||
.Map( PCB_TEXTBOX_T, _HKI( "Text Box" ) )
|
||||
.Map( PCB_TABLE_T, _HKI( "Table" ) )
|
||||
.Map( PCB_TABLECELL_T, _HKI( "Table Cell" ) )
|
||||
.Map( PCB_TRACE_T, _HKI( "Track" ) )
|
||||
.Map( PCB_ARC_T, _HKI( "Track" ) )
|
||||
.Map( PCB_VIA_T, _HKI( "Via" ) )
|
||||
|
|
|
@ -2015,8 +2015,8 @@ static struct EDA_SHAPE_DESC
|
|||
&EDA_SHAPE::SetWidth, &EDA_SHAPE::GetWidth, PROPERTY_DISPLAY::PT_SIZE ) );
|
||||
|
||||
void ( EDA_SHAPE::*lineStyleSetter )( LINE_STYLE ) = &EDA_SHAPE::SetLineStyle;
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<EDA_SHAPE, LINE_STYLE>(
|
||||
_HKI( "Line Style" ), lineStyleSetter, &EDA_SHAPE::GetLineStyle ) );
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<EDA_SHAPE, LINE_STYLE>( _HKI( "Line Style" ),
|
||||
lineStyleSetter, &EDA_SHAPE::GetLineStyle ) );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<EDA_SHAPE, COLOR4D>( _HKI( "Line Color" ),
|
||||
&EDA_SHAPE::SetLineColor, &EDA_SHAPE::GetLineColor ) )
|
||||
|
|
|
@ -296,6 +296,10 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags )
|
|||
}
|
||||
break;
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
break;
|
||||
|
||||
default:
|
||||
wxASSERT_MSG( false, "Unhandled type in function hash_fp_item() (exporter_gencad.cpp)" );
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ bottom
|
|||
bottom_left
|
||||
bottom_right
|
||||
castellated_pads
|
||||
cells
|
||||
center
|
||||
chamfer
|
||||
chamfer_ratio
|
||||
|
@ -66,6 +67,9 @@ circle
|
|||
clearance
|
||||
clearance_min
|
||||
color
|
||||
cols
|
||||
column_count
|
||||
column_widths
|
||||
comment
|
||||
company
|
||||
connect
|
||||
|
@ -108,6 +112,7 @@ exclude_from_pos_files
|
|||
exclude_from_bom
|
||||
extension_height
|
||||
extension_offset
|
||||
external
|
||||
fab_layers_line_width
|
||||
fab_layers_text_dims
|
||||
face
|
||||
|
@ -158,6 +163,7 @@ hatch_smoothing_level
|
|||
hatch_smoothing_value
|
||||
hatch_border_algorithm
|
||||
hatch_min_hole_area
|
||||
header
|
||||
height
|
||||
hide
|
||||
hole_to_hole_min
|
||||
|
@ -269,9 +275,12 @@ right
|
|||
rotate
|
||||
roundrect
|
||||
roundrect_rratio
|
||||
rows
|
||||
row_heights
|
||||
scale
|
||||
segment
|
||||
segment_width
|
||||
separators
|
||||
setup
|
||||
sheetfile
|
||||
sheetname
|
||||
|
@ -286,6 +295,7 @@ solder_paste_margin
|
|||
solder_paste_margin_ratio
|
||||
solder_paste_ratio
|
||||
solid
|
||||
span
|
||||
stackup
|
||||
start
|
||||
status
|
||||
|
@ -293,6 +303,8 @@ stroke
|
|||
style
|
||||
suffix
|
||||
suppress_zeroes
|
||||
table
|
||||
table_cell
|
||||
tags
|
||||
target
|
||||
title
|
||||
|
|
|
@ -298,6 +298,83 @@ TOOL_ACTION ACTIONS::rightJustify( TOOL_ACTION_ARGS()
|
|||
.Tooltip( _( "Right-justify fields and text items" ) )
|
||||
.Icon( BITMAPS::text_align_right ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::selectColumns( TOOL_ACTION_ARGS()
|
||||
.Name( "common.InteractiveSelection.SelectColumns" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select Column(s)" ) )
|
||||
.Tooltip( _( "Select complete column(s) containing the current selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::selectRows( TOOL_ACTION_ARGS()
|
||||
.Name( "common.InteractiveSelection.Rows" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select Row(s)" ) )
|
||||
.Tooltip( _( "Select complete row(s) containing the current selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::selectTable( TOOL_ACTION_ARGS()
|
||||
.Name( "common.InteractiveSelection.SelectTable" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select Table" ) )
|
||||
.Tooltip( _( "Select parent table of selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::addRowAbove( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.addRowAbove" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Row Above" ) )
|
||||
.Tooltip( _( "Insert a new table row above the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::addRowBelow( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.addRowBelow" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Row Below" ) )
|
||||
.Tooltip( _( "Insert a new table row below the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::addColBefore( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.addColBefore" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Column Before" ) )
|
||||
.Tooltip( _( "Insert a new table column before the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::addColAfter( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.addColAfter" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Column After" ) )
|
||||
.Tooltip( _( "Insert a new table column after the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::deleteRows( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.deleteRows" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Delete Row(s)" ) )
|
||||
.Tooltip( _( "Delete rows containing the currently selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::deleteColumns( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.deleteColumns" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Delete Column(s)" ) )
|
||||
.Tooltip( _( "Delete columns containing the currently selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::mergeCells( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.mergeCells" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Merge Cells" ) )
|
||||
.Tooltip( _( "Turn selected table cells into a single cell" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::unmergeCells( TOOL_ACTION_ARGS()
|
||||
.Name( "common.TableEditor.unmergeCell" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Unmerge Cells" ) )
|
||||
.Tooltip( _( "Turn merged table cells back into separate cells." ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION ACTIONS::activatePointEditor( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.activatePointEditor" )
|
||||
.Scope( AS_GLOBAL ) );
|
||||
|
@ -765,7 +842,7 @@ TOOL_ACTION ACTIONS::updatePreferences( TOOL_ACTION_ARGS()
|
|||
.Name( "common.Control.updatePreferences" )
|
||||
.Scope( AS_GLOBAL ) );
|
||||
|
||||
TOOL_ACTION ACTIONS::selectColumns( TOOL_ACTION_ARGS()
|
||||
TOOL_ACTION ACTIONS::selectLibTreeColumns( TOOL_ACTION_ARGS()
|
||||
.Name( "common.Control.selectColumns" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select Columns..." ) ) );
|
||||
|
|
|
@ -931,7 +931,7 @@ void LIB_TREE::onHeaderContextMenu( wxDataViewEvent& aEvent )
|
|||
|
||||
ACTION_MENU menu( true, nullptr );
|
||||
|
||||
menu.Add( ACTIONS::selectColumns );
|
||||
menu.Add( ACTIONS::selectLibTreeColumns );
|
||||
|
||||
if( GetPopupMenuSelectionFromUser( menu ) != wxID_NONE )
|
||||
{
|
||||
|
|
|
@ -393,7 +393,19 @@ bool DIALOG_TABLECELL_PROPERTIES::TransferDataFromWindow()
|
|||
m_table->SetSeparatorsStroke( stroke );
|
||||
}
|
||||
|
||||
m_cell->SetText( m_textCtrl->GetValue() );
|
||||
wxString txt = m_textCtrl->GetValue();
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
|
||||
// Replace it now.
|
||||
txt.Replace( "\r", "\n" );
|
||||
#elif defined( __WINDOWS__ )
|
||||
// On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
|
||||
// drawing routines so strip the \r char.
|
||||
txt.Replace( "\r", "" );
|
||||
#endif
|
||||
|
||||
m_cell->SetText( txt );
|
||||
|
||||
if( m_fontCtrl->HaveFontSelection() )
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -76,7 +76,7 @@ DIALOG_TABLECELL_PROPERTIES_BASE::DIALOG_TABLECELL_PROPERTIES_BASE( wxWindow* pa
|
|||
wxBoxSizer* bSizer16;
|
||||
bSizer16 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_textEntrySizer = new wxGridBagSizer( 4, 3 );
|
||||
m_textEntrySizer = new wxGridBagSizer( 3, 3 );
|
||||
m_textEntrySizer->SetFlexibleDirection( wxBOTH );
|
||||
m_textEntrySizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
m_textEntrySizer->SetEmptyCellSize( wxSize( 0,2 ) );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b)
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
|
|
@ -4226,6 +4226,10 @@ void SCH_IO_KICAD_SEXPR_PARSER::parseSchTextBoxContent( SCH_TEXTBOX* aTextBox )
|
|||
cell->SetColSpan( parseInt( "column span" ) );
|
||||
cell->SetRowSpan( parseInt( "row span" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Expecting( "at, size, stroke, fill, effects or uuid" );
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
@ -4252,7 +4256,10 @@ void SCH_IO_KICAD_SEXPR_PARSER::parseSchTextBoxContent( SCH_TEXTBOX* aTextBox )
|
|||
break;
|
||||
|
||||
default:
|
||||
Expecting( "at, size, stroke, fill, effects or uuid" );
|
||||
if( SCH_TABLECELL* cell = dynamic_cast<SCH_TABLECELL*>( aTextBox ) )
|
||||
Expecting( "at, size, stroke, fill, effects, span or uuid" );
|
||||
else
|
||||
Expecting( "at, size, stroke, fill, effects or uuid" );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -301,7 +301,7 @@ public:
|
|||
* This is a pure virtual function. Derived classes must implement this.
|
||||
*/
|
||||
virtual double Similarity( const SCH_ITEM& aItem ) const = 0;
|
||||
virtual bool operator==( const SCH_ITEM& aItem ) const = 0;
|
||||
virtual bool operator==( const SCH_ITEM& aOtherItem ) const = 0;
|
||||
|
||||
/**
|
||||
* Print a schematic item.
|
||||
|
|
|
@ -2418,11 +2418,8 @@ void SCH_PAINTER::draw( const SCH_TEXTBOX* aTextBox, int aLayer )
|
|||
|
||||
void SCH_PAINTER::draw( const SCH_TABLE* aTable, int aLayer )
|
||||
{
|
||||
const_cast<SCH_TABLE*>( aTable )->RunOnChildren(
|
||||
[&]( SCH_ITEM* aChild )
|
||||
{
|
||||
draw( static_cast<SCH_TEXTBOX*>( aChild ), aLayer );
|
||||
} );
|
||||
for( SCH_TABLECELL* cell : aTable->GetCells() )
|
||||
draw( static_cast<SCH_TEXTBOX*>( cell ), aLayer );
|
||||
|
||||
if( aLayer == LAYER_SELECTION_SHADOWS )
|
||||
return;
|
||||
|
|
|
@ -66,10 +66,7 @@ SCH_TABLE::SCH_TABLE( const SCH_TABLE& aTable ) :
|
|||
m_rowHeights = aTable.m_rowHeights;
|
||||
|
||||
for( SCH_TABLECELL* src : aTable.m_cells )
|
||||
m_cells.push_back( new SCH_TABLECELL( *src ) );
|
||||
|
||||
for( SCH_TABLECELL* dest : m_cells )
|
||||
dest->SetParent( this );
|
||||
AddCell( new SCH_TABLECELL( *src ) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,6 +136,8 @@ VECTOR2I SCH_TABLE::GetEnd() const
|
|||
|
||||
void SCH_TABLE::Normalize()
|
||||
{
|
||||
// JEY TODO: pukes on rotated tables...
|
||||
|
||||
int y = GetPosition().y;
|
||||
|
||||
for( int row = 0; row < GetRowCount(); ++row )
|
||||
|
@ -151,20 +150,29 @@ void SCH_TABLE::Normalize()
|
|||
int colWidth = m_colWidths[ col ];
|
||||
|
||||
SCH_TABLECELL* cell = GetCell( row, col );
|
||||
cell->SetPosition( VECTOR2I( x, y ) );
|
||||
cell->SetEnd( cell->GetStart() + VECTOR2I( colWidth, rowHeight ) );
|
||||
VECTOR2I pos( x, y );
|
||||
|
||||
if( cell->GetPosition() != pos )
|
||||
{
|
||||
cell->SetPosition( pos );
|
||||
cell->ClearRenderCache();
|
||||
}
|
||||
|
||||
VECTOR2I end = cell->GetStart() + VECTOR2I( colWidth, rowHeight );
|
||||
|
||||
if( cell->GetColSpan() > 1 || cell->GetRowSpan() > 1 )
|
||||
{
|
||||
VECTOR2I extraSize;
|
||||
|
||||
for( int ii = col + 1; ii < col + cell->GetColSpan(); ++ii )
|
||||
extraSize.x += m_colWidths[ii];
|
||||
end.x += m_colWidths[ii];
|
||||
|
||||
for( int ii = row + 1; ii < row + cell->GetRowSpan(); ++ii )
|
||||
extraSize.y += m_rowHeights[ii];
|
||||
end.y += m_rowHeights[ii];
|
||||
}
|
||||
|
||||
cell->SetEnd( cell->GetEnd() + extraSize );
|
||||
if( cell->GetEnd() != end )
|
||||
{
|
||||
cell->SetEnd( end );
|
||||
cell->ClearRenderCache();
|
||||
}
|
||||
|
||||
x += colWidth;
|
||||
|
@ -198,6 +206,8 @@ void SCH_TABLE::Rotate( const VECTOR2I& aCenter )
|
|||
{
|
||||
for( SCH_TABLECELL* cell : m_cells )
|
||||
cell->Rotate( aCenter );
|
||||
|
||||
Normalize();
|
||||
}
|
||||
|
||||
|
||||
|
@ -599,36 +609,48 @@ static struct SCH_TABLE_DESC
|
|||
&EDA_SHAPE::SetStartY, &EDA_SHAPE::GetStartY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) );
|
||||
|
||||
const wxString tableProps = _( "Table Properties" );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, bool>( _HKI( "External Border" ),
|
||||
&SCH_TABLE::SetStrokeExternal, &SCH_TABLE::StrokeExternal ) );
|
||||
&SCH_TABLE::SetStrokeExternal, &SCH_TABLE::StrokeExternal ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, bool>( _HKI( "Header Border" ),
|
||||
&SCH_TABLE::SetStrokeHeader, &SCH_TABLE::StrokeHeader ) );
|
||||
&SCH_TABLE::SetStrokeHeader, &SCH_TABLE::StrokeHeader ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, int>( _HKI( "Border Width" ),
|
||||
&SCH_TABLE::SetBorderWidth, &SCH_TABLE::GetBorderWidth,
|
||||
PROPERTY_DISPLAY::PT_SIZE ) );
|
||||
PROPERTY_DISPLAY::PT_SIZE ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<SCH_TABLE, LINE_STYLE>( _HKI( "Border Style" ),
|
||||
&SCH_TABLE::SetBorderStyle, &SCH_TABLE::GetBorderStyle ) );
|
||||
&SCH_TABLE::SetBorderStyle, &SCH_TABLE::GetBorderStyle ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, COLOR4D>( _HKI( "Border Color" ),
|
||||
&SCH_TABLE::SetBorderColor, &SCH_TABLE::GetBorderColor ) );
|
||||
&SCH_TABLE::SetBorderColor, &SCH_TABLE::GetBorderColor ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, bool>( _HKI( "Row Separators" ),
|
||||
&SCH_TABLE::SetStrokeRows, &SCH_TABLE::StrokeRows ) );
|
||||
&SCH_TABLE::SetStrokeRows, &SCH_TABLE::StrokeRows ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, bool>( _HKI( "Cell Separators" ),
|
||||
&SCH_TABLE::SetStrokeColumns, &SCH_TABLE::StrokeColumns ) );
|
||||
&SCH_TABLE::SetStrokeColumns, &SCH_TABLE::StrokeColumns ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, int>( _HKI( "Separators Width" ),
|
||||
&SCH_TABLE::SetSeparatorsWidth, &SCH_TABLE::GetSeparatorsWidth,
|
||||
PROPERTY_DISPLAY::PT_SIZE ) );
|
||||
PROPERTY_DISPLAY::PT_SIZE ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<SCH_TABLE, LINE_STYLE>( _HKI( "Separators Style" ),
|
||||
&SCH_TABLE::SetSeparatorsStyle, &SCH_TABLE::GetSeparatorsStyle ) );
|
||||
&SCH_TABLE::SetSeparatorsStyle, &SCH_TABLE::GetSeparatorsStyle ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<SCH_TABLE, COLOR4D>( _HKI( "Separators Color" ),
|
||||
&SCH_TABLE::SetSeparatorsColor, &SCH_TABLE::GetSeparatorsColor ) );
|
||||
&SCH_TABLE::SetSeparatorsColor, &SCH_TABLE::GetSeparatorsColor ),
|
||||
tableProps );
|
||||
}
|
||||
} _SCH_TABLE_DESC;
|
||||
|
|
|
@ -135,6 +135,41 @@ void SCH_TABLECELL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PAN
|
|||
}
|
||||
|
||||
|
||||
double SCH_TABLECELL::Similarity( const SCH_ITEM& aOtherItem ) const
|
||||
{
|
||||
if( aOtherItem.Type() != Type() )
|
||||
return 0.0;
|
||||
|
||||
const SCH_TABLECELL& other = static_cast<const SCH_TABLECELL&>( aOtherItem );
|
||||
|
||||
double similarity = 1.0;
|
||||
|
||||
if( m_colSpan != other.m_colSpan )
|
||||
similarity *= 0.9;
|
||||
|
||||
if( m_rowSpan != other.m_rowSpan )
|
||||
similarity *= 0.9;
|
||||
|
||||
similarity *= SCH_TEXTBOX::Similarity( other );
|
||||
|
||||
return similarity;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_TABLECELL::operator==( const SCH_ITEM& aOtherItem ) const
|
||||
{
|
||||
if( aOtherItem.Type() != Type() )
|
||||
return false;
|
||||
|
||||
const SCH_TABLECELL& other = static_cast<const SCH_TABLECELL&>( aOtherItem );
|
||||
|
||||
return m_colSpan == other.m_colSpan
|
||||
&& m_rowSpan == other.m_rowSpan
|
||||
&& SCH_TEXTBOX::operator==( other );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct SCH_TABLECELL_DESC
|
||||
{
|
||||
SCH_TABLECELL_DESC()
|
||||
|
|
|
@ -71,6 +71,10 @@ public:
|
|||
|
||||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
double Similarity( const SCH_ITEM& aOther ) const override;
|
||||
|
||||
bool operator==( const SCH_ITEM& aOther ) const override;
|
||||
|
||||
protected:
|
||||
int m_colSpan;
|
||||
int m_rowSpan;
|
||||
|
|
|
@ -145,83 +145,6 @@ TOOL_ACTION EE_ACTIONS::syncSelection( TOOL_ACTION_ARGS()
|
|||
.Name( "eeschema.InteractiveSelection.SyncSelection" )
|
||||
.Scope( AS_GLOBAL ) );
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::selectColumns( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.InteractiveSelection.SelectColumns" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select Column(s)" ) )
|
||||
.Tooltip( _( "Select complete column(s) containing the current selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::selectRows( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.InteractiveSelection.Rows" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select Row(s)" ) )
|
||||
.Tooltip( _( "Select complete row(s) containing the current selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::selectTable( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.InteractiveSelection.SelectTable" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Select Table" ) )
|
||||
.Tooltip( _( "Select parent table of selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::addRowAbove( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.addRowAbove" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Row Above" ) )
|
||||
.Tooltip( _( "Insert a new table row above the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::addRowBelow( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.addRowBelow" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Row Below" ) )
|
||||
.Tooltip( _( "Insert a new table row below the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::addColumnBefore( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.addColumnBefore" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Column Before" ) )
|
||||
.Tooltip( _( "Insert a new table column before the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::addColumnAfter( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.addColumnAfter" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Column After" ) )
|
||||
.Tooltip( _( "Insert a new table column after the selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::deleteRows( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.deleteRows" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Delete Row(s)" ) )
|
||||
.Tooltip( _( "Delete rows containing the currently selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::deleteColumns( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.deleteColumns" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Delete Column(s)" ) )
|
||||
.Tooltip( _( "Delete columns containing the currently selected cell(s)" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::mergeCells( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.mergeCells" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Merge Cells" ) )
|
||||
.Tooltip( _( "Turn selected table cells into a single cell" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
TOOL_ACTION EE_ACTIONS::unmergeCells( TOOL_ACTION_ARGS()
|
||||
.Name( "eeschema.TableEditor.unmergeCell" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Unmerge Cells" ) )
|
||||
.Tooltip( _( "Turn merged table cells back into separate cells." ) )
|
||||
.Icon( BITMAPS::spreadsheet ) ); // JEY TODO: need icon
|
||||
|
||||
// SYMBOL_EDITOR_CONTROL
|
||||
//
|
||||
TOOL_ACTION EE_ACTIONS::saveLibraryAs( TOOL_ACTION_ARGS()
|
||||
|
|
|
@ -69,19 +69,6 @@ public:
|
|||
/// Selection synchronization (PCB -> SCH)
|
||||
static TOOL_ACTION syncSelection;
|
||||
|
||||
// Tables
|
||||
static TOOL_ACTION selectRows;
|
||||
static TOOL_ACTION selectColumns;
|
||||
static TOOL_ACTION selectTable;
|
||||
static TOOL_ACTION addRowAbove;
|
||||
static TOOL_ACTION addRowBelow;
|
||||
static TOOL_ACTION addColumnBefore;
|
||||
static TOOL_ACTION addColumnAfter;
|
||||
static TOOL_ACTION deleteRows;
|
||||
static TOOL_ACTION deleteColumns;
|
||||
static TOOL_ACTION mergeCells;
|
||||
static TOOL_ACTION unmergeCells;
|
||||
|
||||
// Locking
|
||||
static TOOL_ACTION toggleLock;
|
||||
static TOOL_ACTION lock;
|
||||
|
|
|
@ -280,9 +280,9 @@ bool EE_SELECTION_TOOL::Init()
|
|||
menu.AddItem( EE_ACTIONS::clearHighlight, haveHighlight && EE_CONDITIONS::Idle, 1 );
|
||||
menu.AddSeparator( haveHighlight && EE_CONDITIONS::Idle, 1 );
|
||||
|
||||
menu.AddItem( EE_ACTIONS::selectColumns, tableCellSelection && EE_CONDITIONS::Idle, 2 );
|
||||
menu.AddItem( EE_ACTIONS::selectRows, tableCellSelection && EE_CONDITIONS::Idle, 2 );
|
||||
menu.AddItem( EE_ACTIONS::selectTable, tableCellSelection && EE_CONDITIONS::Idle, 2 );
|
||||
menu.AddItem( ACTIONS::selectColumns, tableCellSelection && EE_CONDITIONS::Idle, 2 );
|
||||
menu.AddItem( ACTIONS::selectRows, tableCellSelection && EE_CONDITIONS::Idle, 2 );
|
||||
menu.AddItem( ACTIONS::selectTable, tableCellSelection && EE_CONDITIONS::Idle, 2 );
|
||||
|
||||
menu.AddSeparator( 100 );
|
||||
menu.AddItem( EE_ACTIONS::drawWire, schEditCondition && EE_CONDITIONS::Empty, 100 );
|
||||
|
@ -2545,9 +2545,9 @@ void EE_SELECTION_TOOL::setTransitions()
|
|||
Go( &EE_SELECTION_TOOL::Main, EE_ACTIONS::selectionActivate.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectNode, EE_ACTIONS::selectNode.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectConnection, EE_ACTIONS::selectConnection.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectColumns, EE_ACTIONS::selectColumns.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectRows, EE_ACTIONS::selectRows.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectTable, EE_ACTIONS::selectTable.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectColumns, ACTIONS::selectColumns.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectRows, ACTIONS::selectRows.MakeEvent() );
|
||||
Go( &EE_SELECTION_TOOL::SelectTable, ACTIONS::selectTable.MakeEvent() );
|
||||
|
||||
Go( &EE_SELECTION_TOOL::ClearSelection, EE_ACTIONS::clearSelection.MakeEvent() );
|
||||
|
||||
|
|
|
@ -2165,13 +2165,14 @@ int SCH_DRAWING_TOOLS::DrawTable( const TOOL_EVENT& aEvent )
|
|||
else if( table && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
||||
{
|
||||
VECTOR2I gridSize = grid.GetGridSize( grid.GetItemGrid( table ) );
|
||||
int fontSize = schematic->Settings().m_DefaultTextSize;
|
||||
VECTOR2I origin( table->GetPosition() );
|
||||
VECTOR2I requestedSize( cursorPos - origin );
|
||||
|
||||
int colCount = std::max( 1, requestedSize.x / ( gridSize.x * 24 ) );
|
||||
int rowCount = std::max( 1, requestedSize.y / ( gridSize.y * 8 ) );
|
||||
int colCount = std::max( 1, requestedSize.x / ( fontSize * 15 ) );
|
||||
int rowCount = std::max( 1, requestedSize.y / ( fontSize * 2 ) );
|
||||
|
||||
VECTOR2I cellSize( std::max( gridSize.x * 4, requestedSize.x / colCount ),
|
||||
VECTOR2I cellSize( std::max( gridSize.x * 5, requestedSize.x / colCount ),
|
||||
std::max( gridSize.y * 2, requestedSize.y / rowCount ) );
|
||||
|
||||
cellSize.x = KiROUND( (double) cellSize.x / gridSize.x ) * gridSize.x;
|
||||
|
|
|
@ -21,16 +21,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <kiway.h>
|
||||
#include <tools/sch_edit_tool.h>
|
||||
#include <tools/ee_selection_tool.h>
|
||||
#include <ee_actions.h>
|
||||
#include <string_utils.h>
|
||||
#include <sch_table.h>
|
||||
#include <sch_tablecell.h>
|
||||
#include <sch_commit.h>
|
||||
#include <pgm_base.h>
|
||||
#include <core/kicad_algo.h>
|
||||
#include <tools/sch_edit_table_tool.h>
|
||||
|
||||
|
||||
|
@ -44,78 +35,13 @@ bool SCH_EDIT_TABLE_TOOL::Init()
|
|||
{
|
||||
EE_TOOL_BASE::Init();
|
||||
|
||||
auto tableCellSelection = EE_CONDITIONS::MoreThan( 0 )
|
||||
&& EE_CONDITIONS::OnlyTypes( { SCH_TABLECELL_T } );
|
||||
|
||||
auto tableCellBlockSelection =
|
||||
[&]( const SELECTION& sel )
|
||||
{
|
||||
if( sel.CountType( SCH_TABLECELL_T ) < 2 )
|
||||
return false;
|
||||
|
||||
int colMin = std::numeric_limits<int>::max();
|
||||
int colMax = 0;
|
||||
int rowMin = std::numeric_limits<int>::max();
|
||||
int rowMax = 0;
|
||||
int selectedArea = 0;
|
||||
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
wxCHECK2( item->Type() == SCH_TABLECELL_T, continue );
|
||||
|
||||
SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
|
||||
colMin = std::min( colMin, cell->GetColumn() );
|
||||
colMax = std::max( colMax, cell->GetColumn() + cell->GetColSpan() );
|
||||
rowMin = std::min( rowMin, cell->GetRow() );
|
||||
rowMax = std::max( rowMax, cell->GetRow() + cell->GetRowSpan() );
|
||||
|
||||
selectedArea += cell->GetColSpan() * cell->GetRowSpan();
|
||||
}
|
||||
|
||||
return selectedArea == ( colMax - colMin ) * ( rowMax - rowMin );
|
||||
};
|
||||
|
||||
auto mergedCellsSelection =
|
||||
[&]( const SELECTION& sel )
|
||||
{
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
if( SCH_TABLECELL* cell = dynamic_cast<SCH_TABLECELL*>( item ) )
|
||||
{
|
||||
if( cell->GetColSpan() > 1 || cell->GetRowSpan() > 1 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
//
|
||||
// Add editing actions to the selection tool menu
|
||||
//
|
||||
CONDITIONAL_MENU& selToolMenu = m_selectionTool->GetToolMenu().GetMenu();
|
||||
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::addRowAbove, tableCellSelection && EE_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::addRowBelow, tableCellSelection && EE_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::addColumnBefore, tableCellSelection && EE_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::addColumnAfter, tableCellSelection && EE_CONDITIONS::Idle, 100 );
|
||||
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::deleteRows, tableCellSelection && EE_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::deleteColumns, tableCellSelection && EE_CONDITIONS::Idle, 100 );
|
||||
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::mergeCells, tableCellSelection && tableCellBlockSelection, 100 );
|
||||
selToolMenu.AddItem( EE_ACTIONS::unmergeCells, tableCellSelection && mergedCellsSelection, 100 );
|
||||
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
addMenus( m_selectionTool->GetToolMenu().GetMenu() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
SCH_TABLECELL* copyCell( SCH_TABLECELL* aSource )
|
||||
SCH_TABLECELL* SCH_EDIT_TABLE_TOOL::copyCell( SCH_TABLECELL* aSource )
|
||||
{
|
||||
SCH_TABLECELL* cell = new SCH_TABLECELL();
|
||||
|
||||
|
@ -127,415 +53,23 @@ SCH_TABLECELL* copyCell( SCH_TABLECELL* aSource )
|
|||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::AddRowAbove( const TOOL_EVENT& aEvent )
|
||||
const SELECTION& SCH_EDIT_TABLE_TOOL::getTableCellSelection()
|
||||
{
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
SCH_TABLECELL* topmost = nullptr;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
|
||||
|
||||
if( !topmost || cell->GetRow() < topmost->GetRow() )
|
||||
topmost = cell;
|
||||
}
|
||||
|
||||
if( !topmost )
|
||||
return 0;
|
||||
|
||||
int row = topmost->GetRow();
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( topmost->GetParent() );
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
|
||||
// Make a copy of the source row before things start moving around
|
||||
std::vector<SCH_TABLECELL*> sources;
|
||||
sources.reserve( table->GetColCount() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, m_frame->GetScreen() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
SCH_TABLECELL* cell = copyCell( sources[col] );
|
||||
table->InsertCell( row * table->GetColCount(), cell );
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Row Above" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::AddRowBelow( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
SCH_TABLECELL* bottommost = nullptr;
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
|
||||
|
||||
if( !bottommost || cell->GetRow() > bottommost->GetRow() )
|
||||
bottommost = cell;
|
||||
}
|
||||
|
||||
if( !bottommost )
|
||||
return 0;
|
||||
|
||||
int row = bottommost->GetRow();
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( bottommost->GetParent() );
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
|
||||
// Make a copy of the source row before things start moving around
|
||||
std::vector<SCH_TABLECELL*> sources;
|
||||
sources.reserve( table->GetColCount() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, m_frame->GetScreen() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
SCH_TABLECELL* cell = copyCell( sources[col] );
|
||||
table->InsertCell( ( row + 1 ) * table->GetColCount(), cell );
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Row Below" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::AddColumnBefore( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
SCH_TABLECELL* leftmost = nullptr;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
|
||||
|
||||
if( !leftmost || cell->GetColumn() < leftmost->GetColumn() )
|
||||
leftmost = cell;
|
||||
}
|
||||
|
||||
if( !leftmost )
|
||||
return 0;
|
||||
|
||||
int col = leftmost->GetColumn();
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( leftmost->GetParent() );
|
||||
int rowCount = table->GetRowCount();
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
|
||||
// Make a copy of the source column before things start moving around
|
||||
std::vector<SCH_TABLECELL*> sources;
|
||||
sources.reserve( rowCount );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, m_frame->GetScreen() );
|
||||
table->SetColCount( table->GetColCount() + 1 );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
{
|
||||
SCH_TABLECELL* cell = copyCell( sources[row] );
|
||||
table->InsertCell( row * table->GetColCount() + col, cell );
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Column Before" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::AddColumnAfter( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
SCH_TABLECELL* rightmost = nullptr;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
|
||||
|
||||
if( !rightmost || cell->GetColumn() > rightmost->GetColumn() )
|
||||
rightmost = cell;
|
||||
}
|
||||
|
||||
if( !rightmost )
|
||||
return 0;
|
||||
|
||||
int col = rightmost->GetColumn();
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( rightmost->GetParent() );
|
||||
int rowCount = table->GetRowCount();
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
|
||||
// Make a copy of the source column before things start moving around
|
||||
std::vector<SCH_TABLECELL*> sources;
|
||||
sources.reserve( rowCount );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, m_frame->GetScreen() );
|
||||
table->SetColCount( table->GetColCount() + 1 );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
{
|
||||
SCH_TABLECELL* cell = copyCell( sources[row] );
|
||||
table->InsertCell( row * table->GetColCount() + col + 1, cell );
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Column After" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::DeleteColumns( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( selection[0]->GetParent() );
|
||||
int deleted = 0;
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
bool deleteColumn = false;
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
if( table->GetCell( row, col )->IsSelected() )
|
||||
{
|
||||
deleteColumn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( deleteColumn )
|
||||
{
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
table->GetCell( row, col )->SetFlags( STRUCT_DELETED );
|
||||
|
||||
deleted++;
|
||||
}
|
||||
}
|
||||
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
|
||||
if( deleted == table->GetColCount() )
|
||||
{
|
||||
commit.Remove( table, m_frame->GetScreen() );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Modify( table, m_frame->GetScreen() );
|
||||
|
||||
table->DeleteMarkedCells();
|
||||
table->SetColCount( table->GetColCount() - deleted );
|
||||
table->Normalize();
|
||||
}
|
||||
|
||||
if( deleted > 1 )
|
||||
commit.Push( _( "Delete Columns" ) );
|
||||
else
|
||||
commit.Push( _( "Delete Column" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::DeleteRows( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& selection = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( selection[0]->GetParent() );
|
||||
int deleted = 0;
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
bool deleteRow = false;
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
if( table->GetCell( row, col )->IsSelected() )
|
||||
{
|
||||
deleteRow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( deleteRow )
|
||||
{
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
table->GetCell( row, col )->SetFlags( STRUCT_DELETED );
|
||||
|
||||
deleted++;
|
||||
}
|
||||
}
|
||||
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
|
||||
if( deleted == table->GetRowCount() )
|
||||
{
|
||||
commit.Remove( table, m_frame->GetScreen() );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Modify( table, m_frame->GetScreen() );
|
||||
|
||||
table->DeleteMarkedCells();
|
||||
table->Normalize();
|
||||
}
|
||||
|
||||
if( deleted > 1 )
|
||||
commit.Push( _( "Delete Rows" ) );
|
||||
else
|
||||
commit.Push( _( "Delete Row" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::MergeCells( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& sel = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
|
||||
if( sel.Empty() )
|
||||
return 0;
|
||||
|
||||
int colMin = std::numeric_limits<int>::max();
|
||||
int colMax = 0;
|
||||
int rowMin = std::numeric_limits<int>::max();
|
||||
int rowMax = 0;
|
||||
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( sel[0]->GetParent() );
|
||||
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
wxCHECK2( item->Type() == SCH_TABLECELL_T, continue );
|
||||
|
||||
SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
|
||||
colMin = std::min( colMin, cell->GetColumn() );
|
||||
colMax = std::max( colMax, cell->GetColumn() + cell->GetColSpan() );
|
||||
rowMin = std::min( rowMin, cell->GetRow() );
|
||||
rowMax = std::max( rowMax, cell->GetRow() + cell->GetRowSpan() );
|
||||
}
|
||||
|
||||
wxString content;
|
||||
VECTOR2I extents;
|
||||
|
||||
for( int row = rowMin; row < rowMax; ++row )
|
||||
{
|
||||
extents.y += table->GetRowHeight( row );
|
||||
extents.x = 0;
|
||||
|
||||
for( int col = colMin; col < colMax; ++col )
|
||||
{
|
||||
extents.x += table->GetColWidth( col );
|
||||
|
||||
SCH_TABLECELL* cell = table->GetCell( row, col );
|
||||
|
||||
if( !cell->GetText().IsEmpty() )
|
||||
{
|
||||
if( !content.IsEmpty() )
|
||||
content += "\n";
|
||||
|
||||
content += cell->GetText();
|
||||
}
|
||||
|
||||
commit.Modify( cell, m_frame->GetScreen() );
|
||||
cell->SetColSpan( 0 );
|
||||
cell->SetRowSpan( 0 );
|
||||
cell->SetText( wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
SCH_TABLECELL* topLeft = table->GetCell( rowMin, colMin );
|
||||
topLeft->SetColSpan( colMax - colMin );
|
||||
topLeft->SetRowSpan( rowMax - rowMin );
|
||||
topLeft->SetText( content );
|
||||
topLeft->SetEnd( topLeft->GetStart() + extents );
|
||||
|
||||
table->Normalize();
|
||||
commit.Push( _( "Merge Cells" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int SCH_EDIT_TABLE_TOOL::UnmergeCells( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
EE_SELECTION& sel = m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
|
||||
if( sel.Empty() )
|
||||
return 0;
|
||||
|
||||
SCH_COMMIT commit( m_toolMgr );
|
||||
SCH_TABLE* table = static_cast<SCH_TABLE*>( sel[0]->GetParent() );
|
||||
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
wxCHECK2( item->Type() == SCH_TABLECELL_T, continue );
|
||||
|
||||
SCH_TABLECELL* cell = static_cast<SCH_TABLECELL*>( item );
|
||||
int rowSpan = cell->GetRowSpan();
|
||||
int colSpan = cell->GetColSpan();
|
||||
|
||||
for( int row = cell->GetRow(); row < cell->GetRow() + rowSpan; ++row )
|
||||
{
|
||||
for( int col = cell->GetColumn(); col < cell->GetColumn() + colSpan; ++col )
|
||||
{
|
||||
SCH_TABLECELL* target = table->GetCell( row, col );
|
||||
commit.Modify( target, m_frame->GetScreen() );
|
||||
target->SetColSpan( 1 );
|
||||
target->SetRowSpan( 1 );
|
||||
|
||||
VECTOR2I extents( table->GetColWidth( col ), table->GetRowHeight( row ) );
|
||||
target->SetEnd( target->GetStart() + extents );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
commit.Push( _( "Unmerge Cells" ) );
|
||||
|
||||
return 0;
|
||||
return m_selectionTool->RequestSelection( { SCH_TABLECELL_T } );
|
||||
}
|
||||
|
||||
|
||||
void SCH_EDIT_TABLE_TOOL::setTransitions()
|
||||
{
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddRowAbove, EE_ACTIONS::addRowAbove.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddRowBelow, EE_ACTIONS::addRowBelow.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddRowAbove, ACTIONS::addRowAbove.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddRowBelow, ACTIONS::addRowBelow.MakeEvent() );
|
||||
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddColumnBefore, EE_ACTIONS::addColumnBefore.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddColumnAfter, EE_ACTIONS::addColumnAfter.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddColumnBefore, ACTIONS::addColBefore.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::AddColumnAfter, ACTIONS::addColAfter.MakeEvent() );
|
||||
|
||||
Go( &SCH_EDIT_TABLE_TOOL::DeleteRows, EE_ACTIONS::deleteRows.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::DeleteColumns, EE_ACTIONS::deleteColumns.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::DeleteRows, ACTIONS::deleteRows.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::DeleteColumns, ACTIONS::deleteColumns.MakeEvent() );
|
||||
|
||||
Go( &SCH_EDIT_TABLE_TOOL::MergeCells, EE_ACTIONS::mergeCells.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::UnmergeCells, EE_ACTIONS::unmergeCells.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::MergeCells, ACTIONS::mergeCells.MakeEvent() );
|
||||
Go( &SCH_EDIT_TABLE_TOOL::UnmergeCells, ACTIONS::unmergeCells.MakeEvent() );
|
||||
}
|
||||
|
|
|
@ -21,16 +21,21 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef SCH_TABLE_TOOL_H
|
||||
#define SCH_TABLE_TOOL_H
|
||||
#ifndef SCH_EDIT_TABLE_TOOL_H
|
||||
#define SCH_EDIT_TABLE_TOOL_H
|
||||
|
||||
#include <tools/ee_tool_base.h>
|
||||
#include <tool/edit_table_tool_base.h>
|
||||
#include <sch_table.h>
|
||||
#include <sch_tablecell.h>
|
||||
#include <sch_commit.h>
|
||||
|
||||
|
||||
class SCH_EDIT_FRAME;
|
||||
|
||||
|
||||
class SCH_EDIT_TABLE_TOOL : public EE_TOOL_BASE<SCH_EDIT_FRAME>
|
||||
class SCH_EDIT_TABLE_TOOL : public EE_TOOL_BASE<SCH_EDIT_FRAME>,
|
||||
public EDIT_TABLE_TOOL_BASE<SCH_TABLE, SCH_TABLECELL, SCH_COMMIT>
|
||||
{
|
||||
public:
|
||||
SCH_EDIT_TABLE_TOOL();
|
||||
|
@ -39,19 +44,28 @@ public:
|
|||
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||
bool Init() override;
|
||||
|
||||
int AddRowAbove( const TOOL_EVENT& aEvent );
|
||||
int AddRowBelow( const TOOL_EVENT& aEvent );
|
||||
int AddColumnBefore( const TOOL_EVENT& aEvent );
|
||||
int AddColumnAfter( const TOOL_EVENT& aEvent );
|
||||
int DeleteRows( const TOOL_EVENT& aEvent );
|
||||
int DeleteColumns( const TOOL_EVENT& aEvent );
|
||||
int AddRowAbove( const TOOL_EVENT& aEvent ) { return doAddRowAbove( aEvent ); }
|
||||
int AddRowBelow( const TOOL_EVENT& aEvent ) { return doAddRowBelow( aEvent ); }
|
||||
int AddColumnBefore( const TOOL_EVENT& aEvent ) { return doAddColumnBefore( aEvent ); }
|
||||
int AddColumnAfter( const TOOL_EVENT& aEvent ) { return doAddColumnAfter( aEvent ); }
|
||||
int DeleteRows( const TOOL_EVENT& aEvent ) { return doDeleteRows( aEvent ); }
|
||||
int DeleteColumns( const TOOL_EVENT& aEvent ) { return doDeleteColumns( aEvent ); }
|
||||
|
||||
int MergeCells( const TOOL_EVENT& aEvent );
|
||||
int UnmergeCells( const TOOL_EVENT& aEvent );
|
||||
int MergeCells( const TOOL_EVENT& aEvent ) { return doMergeCells( aEvent ); }
|
||||
int UnmergeCells( const TOOL_EVENT& aEvent ) { return doUnmergeCells( aEvent ); }
|
||||
|
||||
private:
|
||||
///< Set up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
private:
|
||||
TOOL_MANAGER* getToolMgr() override { return m_toolMgr; }
|
||||
BASE_SCREEN* getScreen() override { return m_frame->GetScreen(); }
|
||||
|
||||
const SELECTION& getTableCellSelection() override;
|
||||
void clearSelection() override { m_toolMgr->RunAction( EE_ACTIONS::clearSelection ); };
|
||||
|
||||
SCH_TABLECELL* copyCell( SCH_TABLECELL* aSource ) override;
|
||||
};
|
||||
|
||||
#endif //SCH_TABLE_TOOL_H
|
||||
#endif //SCH_EDIT_TABLE_TOOL_H
|
||||
|
|
|
@ -1427,11 +1427,13 @@ int SCH_EDIT_TOOL::DoDelete( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
else if( sch_item->Type() == SCH_FIELD_T )
|
||||
{
|
||||
// Hide field
|
||||
commit.Modify( item, m_frame->GetScreen() );
|
||||
static_cast<SCH_FIELD*>( sch_item )->SetVisible( false );
|
||||
}
|
||||
else if( sch_item->Type() == SCH_TABLECELL_T )
|
||||
{
|
||||
// Clear contents of table cell
|
||||
commit.Modify( item, m_frame->GetScreen() );
|
||||
static_cast<SCH_TABLECELL*>( sch_item )->SetText( wxEmptyString );
|
||||
}
|
||||
|
|
|
@ -91,6 +91,8 @@ enum KICAD_T
|
|||
PCB_GENERATOR_T, ///< class PCB_GENERATOR, generator on a layer
|
||||
PCB_TEXT_T, ///< class PCB_TEXT, text on a layer
|
||||
PCB_TEXTBOX_T, ///< class PCB_TEXTBOX, wrapped text on a layer
|
||||
PCB_TABLE_T, ///< class PCB_TABLE, table of PCB_TABLECELLs
|
||||
PCB_TABLECELL_T, ///< class PCB_TABLECELL, PCB_TEXTBOX for use in tables
|
||||
PCB_TRACE_T, ///< class PCB_TRACK, a track segment (segment on a copper layer)
|
||||
PCB_VIA_T, ///< class PCB_VIA, a via (like a track segment on a copper layer)
|
||||
PCB_ARC_T, ///< class PCB_ARC, an arc track segment on a copper layer
|
||||
|
@ -442,6 +444,8 @@ constexpr bool IsPcbnewType( const KICAD_T aType )
|
|||
case PCB_FIELD_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TABLECELL_T:
|
||||
case PCB_TRACE_T:
|
||||
case PCB_VIA_T:
|
||||
case PCB_ARC_T:
|
||||
|
|
|
@ -78,6 +78,19 @@ public:
|
|||
static TOOL_ACTION centerJustify;
|
||||
static TOOL_ACTION rightJustify;
|
||||
|
||||
// Tables
|
||||
static TOOL_ACTION selectRows;
|
||||
static TOOL_ACTION selectColumns;
|
||||
static TOOL_ACTION selectTable;
|
||||
static TOOL_ACTION addRowAbove;
|
||||
static TOOL_ACTION addRowBelow;
|
||||
static TOOL_ACTION addColBefore;
|
||||
static TOOL_ACTION addColAfter;
|
||||
static TOOL_ACTION deleteRows;
|
||||
static TOOL_ACTION deleteColumns;
|
||||
static TOOL_ACTION mergeCells;
|
||||
static TOOL_ACTION unmergeCells;
|
||||
|
||||
// Find and Replace
|
||||
static TOOL_ACTION showSearch;
|
||||
static TOOL_ACTION find;
|
||||
|
@ -185,7 +198,7 @@ public:
|
|||
static TOOL_ACTION activatePointEditor;
|
||||
static TOOL_ACTION cycleArcEditMode;
|
||||
static TOOL_ACTION updatePreferences;
|
||||
static TOOL_ACTION selectColumns;
|
||||
static TOOL_ACTION selectLibTreeColumns;
|
||||
|
||||
// Suite
|
||||
static TOOL_ACTION openPreferences;
|
||||
|
|
|
@ -0,0 +1,555 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023-2024 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
|
||||
*/
|
||||
|
||||
#ifndef EDIT_TABLE_TOOL_BASE_H
|
||||
#define EDIT_TABLE_TOOL_BASE_H
|
||||
|
||||
#include <tool/tool_base.h>
|
||||
#include <tool/selection.h>
|
||||
#include <tool/actions.h>
|
||||
#include <wx/translation.h>
|
||||
|
||||
class BASE_SCREEN;
|
||||
|
||||
|
||||
/**
|
||||
* SCH_TABLE_EDIT_TOOL and PCB_TABLE_EDIT_TOOL share most of their algorithms, which are
|
||||
* implemented here.
|
||||
*/
|
||||
|
||||
|
||||
template<typename T_TABLE, typename T_TABLECELL, typename T_COMMIT>
|
||||
class EDIT_TABLE_TOOL_BASE
|
||||
{
|
||||
protected:
|
||||
void addMenus( CONDITIONAL_MENU& selToolMenu )
|
||||
{
|
||||
auto cellSelection = SELECTION_CONDITIONS::MoreThan( 0 )
|
||||
&& SELECTION_CONDITIONS::OnlyTypes( { SCH_TABLECELL_T,
|
||||
PCB_TABLECELL_T } );
|
||||
|
||||
auto cellBlockSelection =
|
||||
[&]( const SELECTION& sel )
|
||||
{
|
||||
if( sel.Size() < 2 )
|
||||
return false;
|
||||
|
||||
int colMin = std::numeric_limits<int>::max();
|
||||
int colMax = 0;
|
||||
int rowMin = std::numeric_limits<int>::max();
|
||||
int rowMax = 0;
|
||||
int selectedArea = 0;
|
||||
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
if( T_TABLECELL* cell = dynamic_cast<T_TABLECELL*>( item ) )
|
||||
{
|
||||
colMin = std::min( colMin, cell->GetColumn() );
|
||||
colMax = std::max( colMax, cell->GetColumn() + cell->GetColSpan() );
|
||||
rowMin = std::min( rowMin, cell->GetRow() );
|
||||
rowMax = std::max( rowMax, cell->GetRow() + cell->GetRowSpan() );
|
||||
|
||||
selectedArea += cell->GetColSpan() * cell->GetRowSpan();
|
||||
}
|
||||
}
|
||||
|
||||
return selectedArea == ( colMax - colMin ) * ( rowMax - rowMin );
|
||||
};
|
||||
|
||||
auto mergedCellsSelection =
|
||||
[&]( const SELECTION& sel )
|
||||
{
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
if( T_TABLECELL* cell = dynamic_cast<T_TABLECELL*>( item ) )
|
||||
{
|
||||
if( cell->GetColSpan() > 1 || cell->GetRowSpan() > 1 )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
//
|
||||
// Add editing actions to the selection tool menu
|
||||
//
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
selToolMenu.AddItem( ACTIONS::addRowAbove, cellSelection && SELECTION_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( ACTIONS::addRowBelow, cellSelection && SELECTION_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( ACTIONS::addColBefore, cellSelection && SELECTION_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( ACTIONS::addColAfter, cellSelection && SELECTION_CONDITIONS::Idle, 100 );
|
||||
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
selToolMenu.AddItem( ACTIONS::deleteRows, cellSelection && SELECTION_CONDITIONS::Idle, 100 );
|
||||
selToolMenu.AddItem( ACTIONS::deleteColumns, cellSelection && SELECTION_CONDITIONS::Idle, 100 );
|
||||
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
selToolMenu.AddItem( ACTIONS::mergeCells, cellSelection && cellBlockSelection, 100 );
|
||||
selToolMenu.AddItem( ACTIONS::unmergeCells, cellSelection && mergedCellsSelection, 100 );
|
||||
|
||||
selToolMenu.AddSeparator( 100 );
|
||||
}
|
||||
|
||||
int doAddRowAbove( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& selection = getTableCellSelection();
|
||||
T_TABLECELL* topmost = nullptr;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
T_TABLECELL* cell = static_cast<T_TABLECELL*>( item );
|
||||
|
||||
if( !topmost || cell->GetRow() < topmost->GetRow() )
|
||||
topmost = cell;
|
||||
}
|
||||
|
||||
if( !topmost )
|
||||
return 0;
|
||||
|
||||
int row = topmost->GetRow();
|
||||
T_TABLE* table = static_cast<T_TABLE*>( topmost->GetParent() );
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
|
||||
// Make a copy of the source row before things start moving around
|
||||
std::vector<T_TABLECELL*> sources;
|
||||
sources.reserve( table->GetColCount() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, getScreen() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
T_TABLECELL* cell = copyCell( sources[col] );
|
||||
table->InsertCell( row * table->GetColCount(), cell );
|
||||
}
|
||||
|
||||
for( int afterRow = table->GetRowCount() - 1; afterRow > row; afterRow-- )
|
||||
table->SetRowHeight( afterRow, table->GetRowHeight( afterRow - 1 ) );
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Row Above" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doAddRowBelow( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& selection = getTableCellSelection();
|
||||
T_TABLECELL* bottommost = nullptr;
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
T_TABLECELL* cell = static_cast<T_TABLECELL*>( item );
|
||||
|
||||
if( !bottommost || cell->GetRow() > bottommost->GetRow() )
|
||||
bottommost = cell;
|
||||
}
|
||||
|
||||
if( !bottommost )
|
||||
return 0;
|
||||
|
||||
int row = bottommost->GetRow();
|
||||
T_TABLE* table = static_cast<T_TABLE*>( bottommost->GetParent() );
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
|
||||
// Make a copy of the source row before things start moving around
|
||||
std::vector<T_TABLECELL*> sources;
|
||||
sources.reserve( table->GetColCount() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, getScreen() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
T_TABLECELL* cell = copyCell( sources[col] );
|
||||
table->InsertCell( ( row + 1 ) * table->GetColCount(), cell );
|
||||
}
|
||||
|
||||
for( int afterRow = table->GetRowCount() - 1; afterRow > row; afterRow-- )
|
||||
table->SetRowHeight( afterRow, table->GetRowHeight( afterRow - 1 ) );
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Row Below" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doAddColumnBefore( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& selection = getTableCellSelection();
|
||||
T_TABLECELL* leftmost = nullptr;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
T_TABLECELL* cell = static_cast<T_TABLECELL*>( item );
|
||||
|
||||
if( !leftmost || cell->GetColumn() < leftmost->GetColumn() )
|
||||
leftmost = cell;
|
||||
}
|
||||
|
||||
if( !leftmost )
|
||||
return 0;
|
||||
|
||||
int col = leftmost->GetColumn();
|
||||
T_TABLE* table = static_cast<T_TABLE*>( leftmost->GetParent() );
|
||||
int rowCount = table->GetRowCount();
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
|
||||
// Make a copy of the source column before things start moving around
|
||||
std::vector<T_TABLECELL*> sources;
|
||||
sources.reserve( rowCount );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, getScreen() );
|
||||
table->SetColCount( table->GetColCount() + 1 );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
{
|
||||
T_TABLECELL* cell = copyCell( sources[row] );
|
||||
table->InsertCell( row * table->GetColCount() + col, cell );
|
||||
}
|
||||
|
||||
for( int afterCol = table->GetColCount() - 1; afterCol > col; afterCol-- )
|
||||
table->SetColWidth( afterCol, table->GetColWidth( afterCol - 1 ) );
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Column Before" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doAddColumnAfter( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& selection = getTableCellSelection();
|
||||
T_TABLECELL* rightmost = nullptr;
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
T_TABLECELL* cell = static_cast<T_TABLECELL*>( item );
|
||||
|
||||
if( !rightmost || cell->GetColumn() > rightmost->GetColumn() )
|
||||
rightmost = cell;
|
||||
}
|
||||
|
||||
if( !rightmost )
|
||||
return 0;
|
||||
|
||||
int col = rightmost->GetColumn();
|
||||
T_TABLE* table = static_cast<T_TABLE*>( rightmost->GetParent() );
|
||||
int rowCount = table->GetRowCount();
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
|
||||
// Make a copy of the source column before things start moving around
|
||||
std::vector<T_TABLECELL*> sources;
|
||||
sources.reserve( rowCount );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
sources.push_back( table->GetCell( row, col ) );
|
||||
|
||||
commit.Modify( table, getScreen() );
|
||||
table->SetColCount( table->GetColCount() + 1 );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
{
|
||||
T_TABLECELL* cell = copyCell( sources[row] );
|
||||
table->InsertCell( row * table->GetColCount() + col + 1, cell );
|
||||
}
|
||||
|
||||
for( int afterCol = table->GetColCount() - 1; afterCol > col; afterCol-- )
|
||||
table->SetColWidth( afterCol, table->GetColWidth( afterCol - 1 ) );
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Push( _( "Add Column After" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doDeleteRows( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& selection = getTableCellSelection();
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
T_TABLE* table = static_cast<T_TABLE*>( selection[0]->GetParent() );
|
||||
std::vector<int> deleted;
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
bool deleteRow = false;
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
if( table->GetCell( row, col )->IsSelected() )
|
||||
{
|
||||
deleteRow = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( deleteRow )
|
||||
{
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
table->GetCell( row, col )->SetFlags( STRUCT_DELETED );
|
||||
|
||||
deleted.push_back( row );
|
||||
}
|
||||
}
|
||||
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
|
||||
if( deleted.size() == (unsigned) table->GetRowCount() )
|
||||
{
|
||||
commit.Remove( table );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Modify( table, getScreen() );
|
||||
|
||||
clearSelection();
|
||||
table->DeleteMarkedCells();
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
for( int deletedRow : deleted )
|
||||
{
|
||||
if( deletedRow >= row )
|
||||
offset++;
|
||||
}
|
||||
|
||||
table->SetRowHeight( row, table->GetRowHeight( row + offset ) );
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
}
|
||||
|
||||
if( deleted.size() > 1 )
|
||||
commit.Push( _( "Delete Rows" ) );
|
||||
else
|
||||
commit.Push( _( "Delete Row" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doDeleteColumns( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& selection = getTableCellSelection();
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
T_TABLE* table = static_cast<T_TABLE*>( selection[0]->GetParent() );
|
||||
std::vector<int> deleted;
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
bool deleteColumn = false;
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
if( table->GetCell( row, col )->IsSelected() )
|
||||
{
|
||||
deleteColumn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( deleteColumn )
|
||||
{
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
table->GetCell( row, col )->SetFlags( STRUCT_DELETED );
|
||||
|
||||
deleted.push_back( col );
|
||||
}
|
||||
}
|
||||
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
|
||||
if( deleted.size() == (unsigned) table->GetColCount() )
|
||||
{
|
||||
commit.Remove( table );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Modify( table, getScreen() );
|
||||
|
||||
clearSelection();
|
||||
table->DeleteMarkedCells();
|
||||
table->SetColCount( table->GetColCount() - deleted.size() );
|
||||
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
for( int deletedCol : deleted )
|
||||
{
|
||||
if( deletedCol >= col )
|
||||
offset++;
|
||||
}
|
||||
|
||||
table->SetColWidth( col, table->GetColWidth( col + offset ) );
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
}
|
||||
|
||||
if( deleted.size() > 1 )
|
||||
commit.Push( _( "Delete Columns" ) );
|
||||
else
|
||||
commit.Push( _( "Delete Column" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doMergeCells( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& sel = getTableCellSelection();
|
||||
|
||||
if( sel.Empty() )
|
||||
return 0;
|
||||
|
||||
int colMin = std::numeric_limits<int>::max();
|
||||
int colMax = 0;
|
||||
int rowMin = std::numeric_limits<int>::max();
|
||||
int rowMax = 0;
|
||||
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
T_TABLE* table = static_cast<T_TABLE*>( sel[0]->GetParent() );
|
||||
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
if( T_TABLECELL* cell = dynamic_cast<T_TABLECELL*>( item ) )
|
||||
{
|
||||
colMin = std::min( colMin, cell->GetColumn() );
|
||||
colMax = std::max( colMax, cell->GetColumn() + cell->GetColSpan() );
|
||||
rowMin = std::min( rowMin, cell->GetRow() );
|
||||
rowMax = std::max( rowMax, cell->GetRow() + cell->GetRowSpan() );
|
||||
}
|
||||
}
|
||||
|
||||
wxString content;
|
||||
VECTOR2I extents;
|
||||
|
||||
for( int row = rowMin; row < rowMax; ++row )
|
||||
{
|
||||
extents.y += table->GetRowHeight( row );
|
||||
extents.x = 0;
|
||||
|
||||
for( int col = colMin; col < colMax; ++col )
|
||||
{
|
||||
extents.x += table->GetColWidth( col );
|
||||
|
||||
T_TABLECELL* cell = table->GetCell( row, col );
|
||||
|
||||
if( !cell->GetText().IsEmpty() )
|
||||
{
|
||||
if( !content.IsEmpty() )
|
||||
content += "\n";
|
||||
|
||||
content += cell->GetText();
|
||||
}
|
||||
|
||||
commit.Modify( cell, getScreen() );
|
||||
cell->SetColSpan( 0 );
|
||||
cell->SetRowSpan( 0 );
|
||||
cell->SetText( wxEmptyString );
|
||||
}
|
||||
}
|
||||
|
||||
T_TABLECELL* topLeft = table->GetCell( rowMin, colMin );
|
||||
topLeft->SetColSpan( colMax - colMin );
|
||||
topLeft->SetRowSpan( rowMax - rowMin );
|
||||
topLeft->SetText( content );
|
||||
topLeft->SetEnd( topLeft->GetStart() + extents );
|
||||
|
||||
table->Normalize();
|
||||
commit.Push( _( "Merge Cells" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int doUnmergeCells( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const SELECTION& sel = getTableCellSelection();
|
||||
|
||||
if( sel.Empty() )
|
||||
return 0;
|
||||
|
||||
T_COMMIT commit( getToolMgr() );
|
||||
T_TABLE* table = static_cast<T_TABLE*>( sel[0]->GetParent() );
|
||||
|
||||
for( EDA_ITEM* item : sel )
|
||||
{
|
||||
if( T_TABLECELL* cell = dynamic_cast<T_TABLECELL*>( item ) )
|
||||
{
|
||||
int rowSpan = cell->GetRowSpan();
|
||||
int colSpan = cell->GetColSpan();
|
||||
|
||||
for( int row = cell->GetRow(); row < cell->GetRow() + rowSpan; ++row )
|
||||
{
|
||||
for( int col = cell->GetColumn(); col < cell->GetColumn() + colSpan; ++col )
|
||||
{
|
||||
T_TABLECELL* target = table->GetCell( row, col );
|
||||
commit.Modify( target, getScreen() );
|
||||
target->SetColSpan( 1 );
|
||||
target->SetRowSpan( 1 );
|
||||
|
||||
VECTOR2I extents( table->GetColWidth( col ), table->GetRowHeight( row ) );
|
||||
target->SetEnd( target->GetStart() + extents );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table->Normalize();
|
||||
commit.Push( _( "Unmerge Cells" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual TOOL_MANAGER* getToolMgr() = 0;
|
||||
virtual BASE_SCREEN* getScreen() = 0;
|
||||
|
||||
virtual const SELECTION& getTableCellSelection() = 0;
|
||||
virtual void clearSelection() = 0;
|
||||
|
||||
virtual T_TABLECELL* copyCell( T_TABLECELL* aSource ) = 0;
|
||||
};
|
||||
|
||||
#endif //EDIT_TABLE_TOOL_BASE_H
|
|
@ -132,6 +132,8 @@ set( PCBNEW_DIALOGS
|
|||
dialogs/dialog_print_pcbnew.cpp
|
||||
dialogs/dialog_swap_layers.cpp
|
||||
dialogs/dialog_swap_layers_base.cpp
|
||||
dialogs/dialog_tablecell_properties.cpp
|
||||
dialogs/dialog_tablecell_properties_base.cpp
|
||||
dialogs/dialog_target_properties.cpp
|
||||
dialogs/dialog_target_properties_base.cpp
|
||||
dialogs/dialog_text_properties.cpp
|
||||
|
@ -361,6 +363,7 @@ set( PCBNEW_CLASS_SRCS
|
|||
tools/drc_tool.cpp
|
||||
tools/edit_tool.cpp
|
||||
tools/edit_tool_move_fct.cpp
|
||||
tools/pcb_edit_table_tool.cpp
|
||||
tools/global_edit_tool.cpp
|
||||
tools/group_tool.cpp
|
||||
tools/footprint_editor_control.cpp
|
||||
|
|
|
@ -142,6 +142,7 @@ void ARRAY_CREATOR::Invoke()
|
|||
case PCB_GENERATOR_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TRACE_T:
|
||||
case PCB_ARC_T:
|
||||
case PCB_VIA_T:
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <pcb_shape.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pgm_base.h>
|
||||
#include <pcbnew_settings.h>
|
||||
|
@ -916,6 +917,7 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode, bool aSkipConnectivity
|
|||
case PCB_FIELD_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TARGET_T:
|
||||
if( aMode == ADD_MODE::APPEND || aMode == ADD_MODE::BULK_APPEND )
|
||||
m_drawings.push_back( aBoardItem );
|
||||
|
@ -1019,6 +1021,7 @@ void BOARD::Remove( BOARD_ITEM* aBoardItem, REMOVE_MODE aRemoveMode )
|
|||
case PCB_FIELD_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TARGET_T:
|
||||
alg::delete_matching( m_drawings, aBoardItem );
|
||||
break;
|
||||
|
@ -1170,6 +1173,15 @@ BOARD_ITEM* BOARD::GetItem( const KIID& aID ) const
|
|||
|
||||
for( BOARD_ITEM* drawing : Drawings() )
|
||||
{
|
||||
if( drawing->Type() == PCB_TABLE_T )
|
||||
{
|
||||
for( PCB_TABLECELL* cell : static_cast<PCB_TABLE*>( drawing )->GetCells() )
|
||||
{
|
||||
if( cell->m_Uuid == aID )
|
||||
return drawing;
|
||||
}
|
||||
}
|
||||
|
||||
if( drawing->m_Uuid == aID )
|
||||
return drawing;
|
||||
}
|
||||
|
@ -1505,6 +1517,8 @@ INSPECT_RESULT BOARD::Visit( INSPECTOR inspector, void* testData,
|
|||
case PCB_FIELD_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TABLECELL_T:
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
case PCB_DIM_CENTER_T:
|
||||
case PCB_DIM_RADIAL_T:
|
||||
|
@ -2524,6 +2538,13 @@ bool BOARD::cmp_drawings::operator()( const BOARD_ITEM* aFirst,
|
|||
|
||||
return textbox->PCB_SHAPE::Compare( other ) && textbox->EDA_TEXT::Compare( other );
|
||||
}
|
||||
else if( aFirst->Type() == PCB_TABLE_T )
|
||||
{
|
||||
const PCB_TABLE* table = static_cast<const PCB_TABLE*>( aFirst );
|
||||
const PCB_TABLE* other = static_cast<const PCB_TABLE*>( aSecond );
|
||||
|
||||
return PCB_TABLE::Compare( table, other );
|
||||
}
|
||||
|
||||
return aFirst->m_Uuid < aSecond->m_Uuid;
|
||||
}
|
||||
|
@ -2594,14 +2615,22 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer,
|
|||
{
|
||||
const PCB_TEXTBOX* textbox = static_cast<const PCB_TEXTBOX*>( item );
|
||||
|
||||
// plot border
|
||||
// border
|
||||
textbox->PCB_SHAPE::TransformShapeToPolygon( aOutlines, aLayer, 0, maxError,
|
||||
ERROR_INSIDE );
|
||||
// plot text
|
||||
// text
|
||||
textbox->TransformTextToPolySet( aOutlines, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
{
|
||||
const PCB_TABLE* table = static_cast<const PCB_TABLE*>( item );
|
||||
|
||||
table->TransformShapeToPolygon( aOutlines, aLayer, 0, maxError, ERROR_INSIDE );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
case PCB_DIM_CENTER_T:
|
||||
case PCB_DIM_RADIAL_T:
|
||||
|
|
|
@ -338,7 +338,8 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
case PCB_SHAPE_T: // a shape (normally not on copper layers)
|
||||
case PCB_REFERENCE_IMAGE_T: // a bitmap on an associated layer
|
||||
case PCB_GENERATOR_T: // a generator on a layer
|
||||
case PCB_TEXTBOX_T: // a wrapped text on a layer
|
||||
case PCB_TEXTBOX_T: // a line-wrapped (and optionally bordered) text item
|
||||
case PCB_TABLE_T: // rows and columns of tablecells
|
||||
case PCB_TRACE_T: // a track segment (segment on a copper layer)
|
||||
case PCB_ARC_T: // an arced track segment (segment on a copper layer)
|
||||
case PCB_VIA_T: // a via (like track segment on a copper layer)
|
||||
|
|
|
@ -42,6 +42,8 @@ const std::vector<KICAD_T> GENERAL_COLLECTOR::AllBoardItems = {
|
|||
PCB_TEXT_T, // in m_drawings
|
||||
PCB_REFERENCE_IMAGE_T, // in m_drawings
|
||||
PCB_TEXTBOX_T, // in m_drawings
|
||||
PCB_TABLE_T, // in m_drawings
|
||||
PCB_TABLECELL_T, // in tables
|
||||
PCB_SHAPE_T, // in m_drawings
|
||||
PCB_DIM_ALIGNED_T, // in m_drawings
|
||||
PCB_DIM_CENTER_T, // in m_drawings
|
||||
|
@ -66,6 +68,7 @@ const std::vector<KICAD_T> GENERAL_COLLECTOR::BoardLevelItems = {
|
|||
PCB_REFERENCE_IMAGE_T,
|
||||
PCB_TEXT_T,
|
||||
PCB_TEXTBOX_T,
|
||||
PCB_TABLE_T,
|
||||
PCB_SHAPE_T,
|
||||
PCB_DIM_ALIGNED_T,
|
||||
PCB_DIM_ORTHOGONAL_T,
|
||||
|
@ -101,6 +104,8 @@ const std::vector<KICAD_T> GENERAL_COLLECTOR::FootprintItems = {
|
|||
PCB_FIELD_T,
|
||||
PCB_TEXT_T,
|
||||
PCB_TEXTBOX_T,
|
||||
PCB_TABLE_T,
|
||||
PCB_TABLECELL_T,
|
||||
PCB_SHAPE_T,
|
||||
PCB_DIM_ALIGNED_T,
|
||||
PCB_DIM_ORTHOGONAL_T,
|
||||
|
@ -194,6 +199,8 @@ INSPECT_RESULT GENERAL_COLLECTOR::Inspect( EDA_ITEM* aTestItem, void* aTestData
|
|||
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TABLECELL_T:
|
||||
boardItem = static_cast<BOARD_ITEM*>( aTestItem );
|
||||
break;
|
||||
|
||||
|
|
|
@ -0,0 +1,477 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#include <widgets/bitmap_button.h>
|
||||
#include <widgets/font_choice.h>
|
||||
#include <confirm.h>
|
||||
#include <board_commit.h>
|
||||
#include <board_design_settings.h>
|
||||
#include <board.h>
|
||||
#include <footprint.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_table.h>
|
||||
#include <project.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcb_layer_box_selector.h>
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <scintilla_tricks.h>
|
||||
#include "dialog_tablecell_properties.h"
|
||||
|
||||
class TABLECELL_SCINTILLA_TRICKS : public SCINTILLA_TRICKS
|
||||
{
|
||||
public:
|
||||
TABLECELL_SCINTILLA_TRICKS( wxStyledTextCtrl* aScintilla,
|
||||
std::function<void( wxKeyEvent& )> onAcceptHandler,
|
||||
std::function<void()> onNextHandler ) :
|
||||
SCINTILLA_TRICKS( aScintilla, wxT( "{}" ), false, std::move( onAcceptHandler ) ),
|
||||
m_onNextHandler( std::move( onNextHandler ) )
|
||||
{ }
|
||||
|
||||
protected:
|
||||
void onCharHook( wxKeyEvent& aEvent ) override
|
||||
{
|
||||
if( aEvent.GetKeyCode() == WXK_TAB && aEvent.AltDown() && !aEvent.ControlDown() )
|
||||
m_onNextHandler();
|
||||
else
|
||||
SCINTILLA_TRICKS::onCharHook( aEvent );
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> m_onNextHandler;
|
||||
};
|
||||
|
||||
|
||||
DIALOG_TABLECELL_PROPERTIES::DIALOG_TABLECELL_PROPERTIES( PCB_BASE_EDIT_FRAME* aFrame,
|
||||
PCB_TABLECELL* aCell ) :
|
||||
DIALOG_TABLECELL_PROPERTIES_BASE( aFrame ),
|
||||
m_frame( aFrame ),
|
||||
m_table( nullptr ),
|
||||
m_cell( aCell ),
|
||||
m_borderWidth( aFrame, m_borderWidthLabel, m_borderWidthCtrl, m_borderWidthUnits ),
|
||||
m_separatorsWidth( aFrame, m_separatorsWidthLabel, m_separatorsWidthCtrl, m_separatorsWidthUnits ),
|
||||
m_textHeight( aFrame, m_SizeYLabel, m_SizeYCtrl, m_SizeYUnits ),
|
||||
m_textWidth( aFrame, m_SizeXLabel, m_SizeXCtrl, m_SizeXUnits ),
|
||||
m_textThickness( aFrame, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnits ),
|
||||
m_scintillaTricks( nullptr )
|
||||
{
|
||||
m_table = static_cast<PCB_TABLE*>( m_cell->GetParent() );
|
||||
|
||||
#ifdef _WIN32
|
||||
// Without this setting, on Windows, some esoteric unicode chars create display issue
|
||||
// in a wxStyledTextCtrl.
|
||||
// for SetTechnology() info, see https://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY
|
||||
m_textCtrl->SetTechnology(wxSTC_TECHNOLOGY_DIRECTWRITE);
|
||||
#endif
|
||||
|
||||
m_scintillaTricks = new TABLECELL_SCINTILLA_TRICKS( m_textCtrl,
|
||||
// onAccept handler
|
||||
[this]( wxKeyEvent& aEvent )
|
||||
{
|
||||
wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
|
||||
},
|
||||
// onNext handler
|
||||
[this]()
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
OnApply( dummy );
|
||||
} );
|
||||
|
||||
// A hack which causes Scintilla to auto-size the text editor canvas
|
||||
// See: https://github.com/jacobslusser/ScintillaNET/issues/216
|
||||
m_textCtrl->SetScrollWidth( 1 );
|
||||
m_textCtrl->SetScrollWidthTracking( true );
|
||||
|
||||
SetInitialFocus( m_textCtrl );
|
||||
|
||||
if( m_table->GetParentFootprint() )
|
||||
{
|
||||
// Do not allow locking items in the footprint editor
|
||||
m_cbLocked->Show( false );
|
||||
}
|
||||
|
||||
// Configure the layers list selector. Note that footprints are built outside the current
|
||||
// board and so we may need to show all layers if the text is on an unactivated layer.
|
||||
if( !m_frame->GetBoard()->IsLayerEnabled( m_table->GetLayer() ) )
|
||||
m_LayerSelectionCtrl->ShowNonActivatedLayers( true );
|
||||
|
||||
m_LayerSelectionCtrl->SetLayersHotkeys( false );
|
||||
m_LayerSelectionCtrl->SetBoardFrame( m_frame );
|
||||
m_LayerSelectionCtrl->Resync();
|
||||
|
||||
for( const auto& [lineStyle, lineStyleDesc] : lineTypeNames )
|
||||
{
|
||||
m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
|
||||
m_separatorsStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
|
||||
}
|
||||
|
||||
m_borderStyleCombo->Append( DEFAULT_STYLE );
|
||||
m_separatorsStyleCombo->Append( DEFAULT_STYLE );
|
||||
|
||||
m_separator1->SetIsSeparator();
|
||||
|
||||
m_bold->SetIsCheckButton();
|
||||
m_bold->SetBitmap( KiBitmapBundle( BITMAPS::text_bold ) );
|
||||
m_italic->SetIsCheckButton();
|
||||
m_italic->SetBitmap( KiBitmapBundle( BITMAPS::text_italic ) );
|
||||
|
||||
m_separator2->SetIsSeparator();
|
||||
|
||||
m_hAlignLeft->SetIsRadioButton();
|
||||
m_hAlignLeft->SetBitmap( KiBitmapBundle( BITMAPS::text_align_left ) );
|
||||
m_hAlignCenter->SetIsRadioButton();
|
||||
m_hAlignCenter->SetBitmap( KiBitmapBundle( BITMAPS::text_align_center ) );
|
||||
m_hAlignRight->SetIsRadioButton();
|
||||
m_hAlignRight->SetBitmap( KiBitmapBundle( BITMAPS::text_align_right ) );
|
||||
|
||||
m_separator3->SetIsSeparator();
|
||||
|
||||
m_vAlignTop->SetIsRadioButton();
|
||||
m_vAlignTop->SetBitmap( KiBitmapBundle( BITMAPS::text_valign_top ) );
|
||||
m_vAlignCenter->SetIsRadioButton();
|
||||
m_vAlignCenter->SetBitmap( KiBitmapBundle( BITMAPS::text_valign_center ) );
|
||||
m_vAlignBottom->SetIsRadioButton();
|
||||
m_vAlignBottom->SetBitmap( KiBitmapBundle( BITMAPS::text_valign_bottom ) );
|
||||
|
||||
m_separator4->SetIsSeparator();
|
||||
|
||||
m_hotkeyHint->SetFont( KIUI::GetInfoFont( this ) );
|
||||
m_hotkeyHint->SetLabel( wxString::Format( wxT( "(%s+%s)" ),
|
||||
KeyNameFromKeyCode( WXK_ALT ),
|
||||
KeyNameFromKeyCode( WXK_TAB ) ) );
|
||||
|
||||
SetupStandardButtons();
|
||||
Layout();
|
||||
|
||||
m_hAlignLeft->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onHAlignButton, this );
|
||||
m_hAlignCenter->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onHAlignButton, this );
|
||||
m_hAlignRight->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onHAlignButton, this );
|
||||
m_vAlignTop->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onVAlignButton, this );
|
||||
m_vAlignCenter->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onVAlignButton, this );
|
||||
m_vAlignBottom->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onVAlignButton, this );
|
||||
|
||||
// Now all widgets have the size fixed, call FinishDialogSettings
|
||||
finishDialogSettings();
|
||||
}
|
||||
|
||||
|
||||
DIALOG_TABLECELL_PROPERTIES::~DIALOG_TABLECELL_PROPERTIES()
|
||||
{
|
||||
delete m_scintillaTricks;
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_TABLECELL_PROPERTIES::TransferDataToWindow()
|
||||
{
|
||||
if( !wxDialog::TransferDataToWindow() )
|
||||
return false;
|
||||
|
||||
m_LayerSelectionCtrl->SetLayerSelection( m_table->GetLayer() );
|
||||
m_cbLocked->SetValue( m_table->IsLocked() );
|
||||
|
||||
m_borderCheckbox->SetValue( m_table->StrokeExternal() );
|
||||
m_headerBorder->SetValue( m_table->StrokeHeader() );
|
||||
|
||||
if( m_table->GetBorderStroke().GetWidth() >= 0 )
|
||||
m_borderWidth.SetValue( m_table->GetBorderStroke().GetWidth() );
|
||||
|
||||
int style = static_cast<int>( m_table->GetBorderStroke().GetLineStyle() );
|
||||
|
||||
if( style == -1 )
|
||||
m_borderStyleCombo->SetStringSelection( DEFAULT_STYLE );
|
||||
else if( style < (int) lineTypeNames.size() )
|
||||
m_borderStyleCombo->SetSelection( style );
|
||||
else
|
||||
wxFAIL_MSG( "Line type not found in the type lookup map" );
|
||||
|
||||
m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
|
||||
m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
|
||||
m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeader() );
|
||||
|
||||
bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
|
||||
bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
|
||||
|
||||
m_rowSeparators->SetValue( rows );
|
||||
m_colSeparators->SetValue( cols );
|
||||
|
||||
if( m_table->GetSeparatorsStroke().GetWidth() >= 0 )
|
||||
m_separatorsWidth.SetValue( m_table->GetSeparatorsStroke().GetWidth() );
|
||||
|
||||
style = static_cast<int>( m_table->GetSeparatorsStroke().GetLineStyle() );
|
||||
|
||||
if( style == -1 )
|
||||
m_separatorsStyleCombo->SetStringSelection( DEFAULT_STYLE );
|
||||
else if( style < (int) lineTypeNames.size() )
|
||||
m_separatorsStyleCombo->SetSelection( style );
|
||||
else
|
||||
wxFAIL_MSG( "Line type not found in the type lookup map" );
|
||||
|
||||
m_separatorsWidth.Enable( rows || cols );
|
||||
m_separatorsStyleLabel->Enable( rows || cols );
|
||||
m_separatorsStyleCombo->Enable( rows || cols );
|
||||
|
||||
m_textCtrl->SetValue( m_cell->GetText() );
|
||||
m_fontCtrl->SetFontSelection( m_cell->GetFont() );
|
||||
m_textWidth.SetValue( m_cell->GetTextWidth() );
|
||||
m_textHeight.SetValue( m_cell->GetTextHeight() );
|
||||
m_textThickness.SetValue( m_cell->GetTextThickness() );
|
||||
|
||||
m_bold->Check( m_cell->IsBold() );
|
||||
m_italic->Check( m_cell->IsItalic() );
|
||||
|
||||
switch( m_cell->GetHorizJustify() )
|
||||
{
|
||||
case GR_TEXT_H_ALIGN_LEFT: m_hAlignLeft->Check(); break;
|
||||
case GR_TEXT_H_ALIGN_CENTER: m_hAlignCenter->Check(); break;
|
||||
case GR_TEXT_H_ALIGN_RIGHT: m_hAlignRight->Check(); break;
|
||||
}
|
||||
|
||||
switch( m_cell->GetVertJustify() )
|
||||
{
|
||||
case GR_TEXT_V_ALIGN_TOP: m_vAlignTop->Check(); break;
|
||||
case GR_TEXT_V_ALIGN_CENTER: m_vAlignCenter->Check(); break;
|
||||
case GR_TEXT_V_ALIGN_BOTTOM: m_vAlignBottom->Check(); break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TABLECELL_PROPERTIES::onHAlignButton( wxCommandEvent& aEvent )
|
||||
{
|
||||
for( BITMAP_BUTTON* btn : { m_hAlignLeft, m_hAlignCenter, m_hAlignRight } )
|
||||
{
|
||||
if( btn->IsChecked() && btn != aEvent.GetEventObject() )
|
||||
btn->Check( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TABLECELL_PROPERTIES::onVAlignButton( wxCommandEvent& aEvent )
|
||||
{
|
||||
for( BITMAP_BUTTON* btn : { m_vAlignTop, m_vAlignCenter, m_vAlignBottom } )
|
||||
{
|
||||
if( btn->IsChecked() && btn != aEvent.GetEventObject() )
|
||||
btn->Check( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TABLECELL_PROPERTIES::onBorderChecked( wxCommandEvent& aEvent )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_frame->GetDesignSettings();
|
||||
PCB_LAYER_ID currentLayer = ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() );
|
||||
int defaultLineThickness = bds.GetLineThickness( currentLayer );
|
||||
|
||||
bool border = m_borderCheckbox->GetValue();
|
||||
|
||||
if( border && m_borderWidth.GetValue() < 0 )
|
||||
m_borderWidth.SetValue( defaultLineThickness );
|
||||
|
||||
m_borderWidth.Enable( border );
|
||||
m_borderStyleLabel->Enable( border );
|
||||
m_borderStyleCombo->Enable( border );
|
||||
|
||||
bool row = m_rowSeparators->GetValue();
|
||||
bool col = m_colSeparators->GetValue();
|
||||
|
||||
if( ( row || col ) && m_separatorsWidth.GetValue() < 0 )
|
||||
m_separatorsWidth.SetValue( defaultLineThickness );
|
||||
|
||||
m_separatorsWidth.Enable( row || col );
|
||||
m_separatorsStyleLabel->Enable( row || col );
|
||||
m_separatorsStyleCombo->Enable( row || col );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TABLECELL_PROPERTIES::OnCharHook( wxKeyEvent& aEvt )
|
||||
{
|
||||
if( aEvt.GetKeyCode() == WXK_TAB && aEvt.AltDown() && !aEvt.ControlDown() )
|
||||
{
|
||||
wxCommandEvent dummy;
|
||||
OnApply( dummy );
|
||||
}
|
||||
else
|
||||
{
|
||||
DIALOG_SHIM::OnCharHook( aEvt );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_TABLECELL_PROPERTIES::OnApply( wxCommandEvent& aEvent )
|
||||
{
|
||||
TransferDataFromWindow();
|
||||
|
||||
for( size_t ii = 0; ii < m_table->GetCells().size(); ++ii )
|
||||
{
|
||||
if( m_table->GetCells()[ii] == m_cell )
|
||||
{
|
||||
ii++;
|
||||
|
||||
if( ii >= m_table->GetCells().size() )
|
||||
ii = 0;
|
||||
|
||||
m_cell = m_table->GetCells()[ii];
|
||||
|
||||
m_frame->GetToolManager()->RunAction( PCB_ACTIONS::selectionClear );
|
||||
m_frame->GetToolManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, m_cell );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TransferDataToWindow();
|
||||
m_textCtrl->SelectAll();
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_TABLECELL_PROPERTIES::TransferDataFromWindow()
|
||||
{
|
||||
if( !wxDialog::TransferDataFromWindow() )
|
||||
return false;
|
||||
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
commit.Modify( m_table );
|
||||
|
||||
// If no other command in progress, prepare undo command
|
||||
// (for a command in progress, will be made later, at the completion of command)
|
||||
bool pushCommit = ( m_table->GetEditFlags() == 0 );
|
||||
|
||||
// Set IN_EDIT flag to force undo/redo/abort proper operation and avoid new calls to
|
||||
// SaveCopyInUndoList for the same text if is moved, and then rotated, edited, etc....
|
||||
if( !pushCommit )
|
||||
m_table->SetFlags( IN_EDIT );
|
||||
|
||||
m_table->SetLayer( ToLAYER_ID( m_LayerSelectionCtrl->GetLayerSelection() ) );
|
||||
m_table->SetLocked( m_cbLocked->GetValue() );
|
||||
|
||||
m_table->SetStrokeExternal( m_borderCheckbox->GetValue() );
|
||||
m_table->SetStrokeHeader( m_headerBorder->GetValue() );
|
||||
{
|
||||
STROKE_PARAMS stroke = m_table->GetBorderStroke();
|
||||
|
||||
if( m_borderCheckbox->GetValue() )
|
||||
stroke.SetWidth( std::max( 0, m_borderWidth.GetIntValue() ) );
|
||||
else
|
||||
stroke.SetWidth( -1 );
|
||||
|
||||
auto it = lineTypeNames.begin();
|
||||
std::advance( it, m_borderStyleCombo->GetSelection() );
|
||||
|
||||
if( it == lineTypeNames.end() )
|
||||
stroke.SetLineStyle( LINE_STYLE::DEFAULT );
|
||||
else
|
||||
stroke.SetLineStyle( it->first );
|
||||
|
||||
m_table->SetBorderStroke( stroke );
|
||||
}
|
||||
|
||||
m_table->SetStrokeRows( m_rowSeparators->GetValue() );
|
||||
m_table->SetStrokeColumns( m_colSeparators->GetValue() );
|
||||
{
|
||||
STROKE_PARAMS stroke = m_table->GetSeparatorsStroke();
|
||||
|
||||
if( m_rowSeparators->GetValue() || m_colSeparators->GetValue() )
|
||||
stroke.SetWidth( std::max( 0, m_separatorsWidth.GetIntValue() ) );
|
||||
else
|
||||
stroke.SetWidth( -1 );
|
||||
|
||||
auto it = lineTypeNames.begin();
|
||||
std::advance( it, m_separatorsStyleCombo->GetSelection() );
|
||||
|
||||
if( it == lineTypeNames.end() )
|
||||
stroke.SetLineStyle( LINE_STYLE::DEFAULT );
|
||||
else
|
||||
stroke.SetLineStyle( it->first );
|
||||
|
||||
m_table->SetSeparatorsStroke( stroke );
|
||||
}
|
||||
|
||||
wxString txt = m_textCtrl->GetValue();
|
||||
|
||||
#ifdef __WXMAC__
|
||||
// On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
|
||||
// Replace it now.
|
||||
txt.Replace( "\r", "\n" );
|
||||
#elif defined( __WINDOWS__ )
|
||||
// On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
|
||||
// drawing routines so strip the \r char.
|
||||
txt.Replace( "\r", "" );
|
||||
#endif
|
||||
|
||||
m_cell->SetText( txt );
|
||||
|
||||
if( m_fontCtrl->HaveFontSelection() )
|
||||
{
|
||||
m_cell->SetFont( m_fontCtrl->GetFontSelection( m_bold->IsChecked(),
|
||||
m_italic->IsChecked() ) );
|
||||
}
|
||||
|
||||
m_cell->SetTextWidth( m_textWidth.GetIntValue() );
|
||||
m_cell->SetTextHeight( m_textHeight.GetIntValue() );
|
||||
m_cell->SetTextThickness( m_textThickness.GetIntValue() );
|
||||
|
||||
if( m_bold->IsChecked() != m_cell->IsBold() )
|
||||
{
|
||||
if( m_bold->IsChecked() )
|
||||
{
|
||||
m_cell->SetBold( true );
|
||||
m_cell->SetTextThickness( GetPenSizeForBold( m_cell->GetTextWidth() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cell->SetBold( false );
|
||||
m_cell->SetTextThickness( 0 ); // Use default pen width
|
||||
}
|
||||
}
|
||||
|
||||
if( m_hAlignRight->IsChecked() )
|
||||
m_cell->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
|
||||
else if( m_hAlignCenter->IsChecked() )
|
||||
m_cell->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
|
||||
else
|
||||
m_cell->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
|
||||
|
||||
if( m_vAlignBottom->IsChecked() )
|
||||
m_cell->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
|
||||
else if( m_vAlignCenter->IsChecked() )
|
||||
m_cell->SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
|
||||
else
|
||||
m_cell->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
|
||||
|
||||
if( !commit.Empty() )
|
||||
commit.Push( _( "Edit Table Cell" ), SKIP_CONNECTIVITY );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_EDIT_FRAME::ShowTableCellPropertiesDialog( PCB_TABLECELL* aTableCell )
|
||||
{
|
||||
DIALOG_TABLECELL_PROPERTIES dlg( this, aTableCell );
|
||||
|
||||
// QuasiModal required for Scintilla auto-complete
|
||||
dlg.ShowQuasiModal();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#ifndef DIALOG_TABLECELL_PROPERTIES_H
|
||||
#define DIALOG_TABLECELL_PROPERTIES_H
|
||||
|
||||
#include <widgets/unit_binder.h>
|
||||
#include <wx/valnum.h>
|
||||
|
||||
#include "dialog_tablecell_properties_base.h"
|
||||
|
||||
|
||||
class PCB_BASE_EDIT_FRAME;
|
||||
class PCB_TABLE;
|
||||
class PCB_TABLECELL;
|
||||
class SCINTILLA_TRICKS;
|
||||
|
||||
|
||||
class DIALOG_TABLECELL_PROPERTIES : public DIALOG_TABLECELL_PROPERTIES_BASE
|
||||
{
|
||||
public:
|
||||
DIALOG_TABLECELL_PROPERTIES( PCB_BASE_EDIT_FRAME* aParentFrame, PCB_TABLECELL* aCell );
|
||||
~DIALOG_TABLECELL_PROPERTIES();
|
||||
|
||||
protected:
|
||||
void OnCharHook( wxKeyEvent& aEvt ) override;
|
||||
|
||||
private:
|
||||
bool TransferDataToWindow() override;
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
void onHAlignButton( wxCommandEvent &aEvent );
|
||||
void onVAlignButton( wxCommandEvent &aEvent );
|
||||
void onBorderChecked( wxCommandEvent& aEvent ) override;
|
||||
void OnApply( wxCommandEvent& aEvent ) override;
|
||||
|
||||
private:
|
||||
PCB_BASE_EDIT_FRAME* m_frame;
|
||||
PCB_TABLE* m_table;
|
||||
PCB_TABLECELL* m_cell;
|
||||
|
||||
UNIT_BINDER m_borderWidth;
|
||||
UNIT_BINDER m_separatorsWidth;
|
||||
UNIT_BINDER m_textHeight;
|
||||
UNIT_BINDER m_textWidth;
|
||||
UNIT_BINDER m_textThickness;
|
||||
|
||||
SCINTILLA_TRICKS* m_scintillaTricks;
|
||||
};
|
||||
|
||||
|
||||
#endif //DIALOG_TABLECELL_PROPERTIES_H
|
|
@ -0,0 +1,382 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pcb_layer_box_selector.h"
|
||||
#include "widgets/bitmap_button.h"
|
||||
#include "widgets/font_choice.h"
|
||||
#include "widgets/wx_infobar.h"
|
||||
|
||||
#include "dialog_tablecell_properties_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DIALOG_TABLECELL_PROPERTIES_BASE::DIALOG_TABLECELL_PROPERTIES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||
{
|
||||
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
|
||||
|
||||
wxBoxSizer* bMainSizer;
|
||||
bMainSizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_infoBar = new WX_INFOBAR( this );
|
||||
m_infoBar->SetShowHideEffects( wxSHOW_EFFECT_NONE, wxSHOW_EFFECT_NONE );
|
||||
m_infoBar->SetEffectDuration( 500 );
|
||||
m_infoBar->Hide();
|
||||
|
||||
bMainSizer->Add( m_infoBar, 0, wxEXPAND|wxBOTTOM, 5 );
|
||||
|
||||
wxBoxSizer* bColumns;
|
||||
bColumns = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
wxBoxSizer* bCellContentMargins;
|
||||
bCellContentMargins = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_textCtrl = new wxStyledTextCtrl( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN, wxEmptyString );
|
||||
m_textCtrl->SetUseTabs( true );
|
||||
m_textCtrl->SetTabWidth( 4 );
|
||||
m_textCtrl->SetIndent( 4 );
|
||||
m_textCtrl->SetTabIndents( false );
|
||||
m_textCtrl->SetBackSpaceUnIndents( false );
|
||||
m_textCtrl->SetViewEOL( false );
|
||||
m_textCtrl->SetViewWhiteSpace( false );
|
||||
m_textCtrl->SetMarginWidth( 2, 0 );
|
||||
m_textCtrl->SetIndentationGuides( false );
|
||||
m_textCtrl->SetReadOnly( false );
|
||||
m_textCtrl->SetMarginWidth( 1, 0 );
|
||||
m_textCtrl->SetMarginWidth( 0, 0 );
|
||||
m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUS );
|
||||
m_textCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("BLACK") ) );
|
||||
m_textCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDER, wxColour( wxT("WHITE") ) );
|
||||
m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUS );
|
||||
m_textCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("BLACK") ) );
|
||||
m_textCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPEN, wxColour( wxT("WHITE") ) );
|
||||
m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_EMPTY );
|
||||
m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_BOXPLUS );
|
||||
m_textCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("BLACK") ) );
|
||||
m_textCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDEREND, wxColour( wxT("WHITE") ) );
|
||||
m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_BOXMINUS );
|
||||
m_textCtrl->MarkerSetBackground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("BLACK") ) );
|
||||
m_textCtrl->MarkerSetForeground( wxSTC_MARKNUM_FOLDEROPENMID, wxColour( wxT("WHITE") ) );
|
||||
m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_EMPTY );
|
||||
m_textCtrl->MarkerDefine( wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_EMPTY );
|
||||
m_textCtrl->SetSelBackground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHT ) );
|
||||
m_textCtrl->SetSelForeground( true, wxSystemSettings::GetColour( wxSYS_COLOUR_HIGHLIGHTTEXT ) );
|
||||
m_textCtrl->SetMinSize( wxSize( 500,-1 ) );
|
||||
|
||||
bCellContentMargins->Add( m_textCtrl, 1, wxEXPAND|wxTOP|wxBOTTOM, 1 );
|
||||
|
||||
|
||||
bColumns->Add( bCellContentMargins, 1, wxEXPAND|wxTOP, 6 );
|
||||
|
||||
m_notebook = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_tablePage = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* bSizer16;
|
||||
bSizer16 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_textEntrySizer = new wxGridBagSizer( 3, 3 );
|
||||
m_textEntrySizer->SetFlexibleDirection( wxBOTH );
|
||||
m_textEntrySizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
m_textEntrySizer->SetEmptyCellSize( wxSize( 0,2 ) );
|
||||
|
||||
m_layerLabel = new wxStaticText( m_tablePage, wxID_ANY, _("Layer:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_layerLabel->Wrap( -1 );
|
||||
m_textEntrySizer->Add( m_layerLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_LayerSelectionCtrl = new PCB_LAYER_BOX_SELECTOR( m_tablePage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
|
||||
m_LayerSelectionCtrl->SetMinSize( wxSize( 175,-1 ) );
|
||||
|
||||
m_textEntrySizer->Add( m_LayerSelectionCtrl, wxGBPosition( 0, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
m_cbLocked = new wxCheckBox( m_tablePage, wxID_ANY, _("Locked"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_textEntrySizer->Add( m_cbLocked, wxGBPosition( 1, 0 ), wxGBSpan( 1, 3 ), wxBOTTOM, 20 );
|
||||
|
||||
m_borderCheckbox = new wxCheckBox( m_tablePage, wxID_ANY, _("External border"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_textEntrySizer->Add( m_borderCheckbox, wxGBPosition( 2, 0 ), wxGBSpan( 1, 2 ), wxBOTTOM, 2 );
|
||||
|
||||
m_headerBorder = new wxCheckBox( m_tablePage, wxID_ANY, _("Header border"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_textEntrySizer->Add( m_headerBorder, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxLEFT, 20 );
|
||||
|
||||
m_borderWidthLabel = new wxStaticText( m_tablePage, wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_borderWidthLabel->Wrap( -1 );
|
||||
m_textEntrySizer->Add( m_borderWidthLabel, wxGBPosition( 4, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
wxBoxSizer* bSizer7;
|
||||
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_borderWidthCtrl = new wxTextCtrl( m_tablePage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
|
||||
bSizer7->Add( m_borderWidthCtrl, 0, wxEXPAND, 5 );
|
||||
|
||||
m_borderWidthUnits = new wxStaticText( m_tablePage, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_borderWidthUnits->Wrap( -1 );
|
||||
bSizer7->Add( m_borderWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
|
||||
|
||||
|
||||
m_textEntrySizer->Add( bSizer7, wxGBPosition( 4, 1 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 );
|
||||
|
||||
m_borderStyleLabel = new wxStaticText( m_tablePage, wxID_ANY, _("Style:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_borderStyleLabel->Wrap( -1 );
|
||||
m_textEntrySizer->Add( m_borderStyleLabel, wxGBPosition( 5, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_borderStyleCombo = new wxBitmapComboBox( m_tablePage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
|
||||
m_borderStyleCombo->SetMinSize( wxSize( 200,-1 ) );
|
||||
|
||||
m_textEntrySizer->Add( m_borderStyleCombo, wxGBPosition( 5, 1 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_textEntrySizer->Add( 0, 15, wxGBPosition( 6, 0 ), wxGBSpan( 1, 1 ), wxEXPAND, 5 );
|
||||
|
||||
m_rowSeparators = new wxCheckBox( m_tablePage, wxID_ANY, _("Row lines"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_textEntrySizer->Add( m_rowSeparators, wxGBPosition( 7, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxRIGHT, 15 );
|
||||
|
||||
m_colSeparators = new wxCheckBox( m_tablePage, wxID_ANY, _("Column lines"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_textEntrySizer->Add( m_colSeparators, wxGBPosition( 7, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 20 );
|
||||
|
||||
m_separatorsWidthLabel = new wxStaticText( m_tablePage, wxID_ANY, _("Width:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_separatorsWidthLabel->Wrap( -1 );
|
||||
m_textEntrySizer->Add( m_separatorsWidthLabel, wxGBPosition( 9, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
wxBoxSizer* bSizer71;
|
||||
bSizer71 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_separatorsWidthCtrl = new wxTextCtrl( m_tablePage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
|
||||
bSizer71->Add( m_separatorsWidthCtrl, 0, wxEXPAND, 5 );
|
||||
|
||||
m_separatorsWidthUnits = new wxStaticText( m_tablePage, wxID_ANY, _("mm"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_separatorsWidthUnits->Wrap( -1 );
|
||||
bSizer71->Add( m_separatorsWidthUnits, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 3 );
|
||||
|
||||
|
||||
m_textEntrySizer->Add( bSizer71, wxGBPosition( 9, 1 ), wxGBSpan( 1, 2 ), wxEXPAND, 5 );
|
||||
|
||||
m_separatorsStyleLabel = new wxStaticText( m_tablePage, wxID_ANY, _("Style:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_separatorsStyleLabel->Wrap( -1 );
|
||||
m_textEntrySizer->Add( m_separatorsStyleLabel, wxGBPosition( 10, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_separatorsStyleCombo = new wxBitmapComboBox( m_tablePage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY );
|
||||
m_separatorsStyleCombo->SetMinSize( wxSize( 200,-1 ) );
|
||||
|
||||
m_textEntrySizer->Add( m_separatorsStyleCombo, wxGBPosition( 10, 1 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
m_textEntrySizer->AddGrowableCol( 1 );
|
||||
|
||||
bSizer16->Add( m_textEntrySizer, 1, wxEXPAND|wxALL, 5 );
|
||||
|
||||
|
||||
m_tablePage->SetSizer( bSizer16 );
|
||||
m_tablePage->Layout();
|
||||
bSizer16->Fit( m_tablePage );
|
||||
m_notebook->AddPage( m_tablePage, _("Table"), false );
|
||||
m_cellPage = new wxPanel( m_notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
|
||||
wxBoxSizer* bSizer13;
|
||||
bSizer13 = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* bMargins;
|
||||
bMargins = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxBoxSizer* bSizeCtrlSizer;
|
||||
bSizeCtrlSizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_separator1 = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_separator1->Enable( false );
|
||||
|
||||
bSizeCtrlSizer->Add( m_separator1, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_bold = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_bold->SetToolTip( _("Bold") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_bold, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_italic = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_italic->SetToolTip( _("Italic") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_italic, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_separator2 = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_separator2->Enable( false );
|
||||
|
||||
bSizeCtrlSizer->Add( m_separator2, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_hAlignLeft = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_hAlignLeft->SetToolTip( _("Align left") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_hAlignLeft, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_hAlignCenter = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_hAlignCenter->SetToolTip( _("Align horizontal center") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_hAlignCenter, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_hAlignRight = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_hAlignRight->SetToolTip( _("Align right") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_hAlignRight, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_separator3 = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_separator3->Enable( false );
|
||||
|
||||
bSizeCtrlSizer->Add( m_separator3, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_vAlignTop = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_vAlignTop->SetToolTip( _("Align top") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_vAlignTop, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_vAlignCenter = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_vAlignCenter->SetToolTip( _("Align vertical center") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_vAlignCenter, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_vAlignBottom = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_vAlignBottom->SetToolTip( _("Align bottom") );
|
||||
|
||||
bSizeCtrlSizer->Add( m_vAlignBottom, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_separator4 = new BITMAP_BUTTON( m_cellPage, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( 21,21 ), wxBU_AUTODRAW|wxBORDER_NONE );
|
||||
m_separator4->Enable( false );
|
||||
|
||||
bSizeCtrlSizer->Add( m_separator4, 0, wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
|
||||
bMargins->Add( bSizeCtrlSizer, 0, wxBOTTOM, 10 );
|
||||
|
||||
wxGridBagSizer* gbSizer2;
|
||||
gbSizer2 = new wxGridBagSizer( 4, 5 );
|
||||
gbSizer2->SetFlexibleDirection( wxBOTH );
|
||||
gbSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
gbSizer2->SetEmptyCellSize( wxSize( -1,5 ) );
|
||||
|
||||
m_fontLabel = new wxStaticText( m_cellPage, wxID_ANY, _("Font:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_fontLabel->Wrap( -1 );
|
||||
gbSizer2->Add( m_fontLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxLEFT, 1 );
|
||||
|
||||
wxString m_fontCtrlChoices[] = { _("Default Font"), _("KiCad Font") };
|
||||
int m_fontCtrlNChoices = sizeof( m_fontCtrlChoices ) / sizeof( wxString );
|
||||
m_fontCtrl = new FONT_CHOICE( m_cellPage, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_fontCtrlNChoices, m_fontCtrlChoices, 0 );
|
||||
m_fontCtrl->SetSelection( 0 );
|
||||
gbSizer2->Add( m_fontCtrl, wxGBPosition( 0, 1 ), wxGBSpan( 1, 3 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
|
||||
gbSizer2->AddGrowableCol( 1 );
|
||||
|
||||
bMargins->Add( gbSizer2, 0, wxEXPAND|wxBOTTOM, 5 );
|
||||
|
||||
wxGridBagSizer* gbSizer1;
|
||||
gbSizer1 = new wxGridBagSizer( 3, 5 );
|
||||
gbSizer1->SetFlexibleDirection( wxBOTH );
|
||||
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
|
||||
gbSizer1->SetEmptyCellSize( wxSize( -1,8 ) );
|
||||
|
||||
m_SizeXLabel = new wxStaticText( m_cellPage, wxID_ANY, _("Text width:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_SizeXLabel->Wrap( -1 );
|
||||
m_SizeXLabel->SetToolTip( _("Text width") );
|
||||
|
||||
gbSizer1->Add( m_SizeXLabel, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 4 );
|
||||
|
||||
m_SizeXCtrl = new wxTextCtrl( m_cellPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
gbSizer1->Add( m_SizeXCtrl, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
m_SizeXUnits = new wxStaticText( m_cellPage, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_SizeXUnits->Wrap( -1 );
|
||||
gbSizer1->Add( m_SizeXUnits, wxGBPosition( 0, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_SizeYLabel = new wxStaticText( m_cellPage, wxID_ANY, _("Text height:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_SizeYLabel->Wrap( -1 );
|
||||
m_SizeYLabel->SetToolTip( _("Text height") );
|
||||
|
||||
gbSizer1->Add( m_SizeYLabel, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 4 );
|
||||
|
||||
m_SizeYCtrl = new wxTextCtrl( m_cellPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
gbSizer1->Add( m_SizeYCtrl, wxGBPosition( 1, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
m_SizeYUnits = new wxStaticText( m_cellPage, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_SizeYUnits->Wrap( -1 );
|
||||
gbSizer1->Add( m_SizeYUnits, wxGBPosition( 1, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
m_ThicknessLabel = new wxStaticText( m_cellPage, wxID_ANY, _("Thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ThicknessLabel->Wrap( -1 );
|
||||
m_ThicknessLabel->SetToolTip( _("Text thickness") );
|
||||
|
||||
gbSizer1->Add( m_ThicknessLabel, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 4 );
|
||||
|
||||
m_ThicknessCtrl = new wxTextCtrl( m_cellPage, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
gbSizer1->Add( m_ThicknessCtrl, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
|
||||
|
||||
m_ThicknessUnits = new wxStaticText( m_cellPage, wxID_ANY, _("unit"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_ThicknessUnits->Wrap( -1 );
|
||||
gbSizer1->Add( m_ThicknessUnits, wxGBPosition( 2, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 );
|
||||
|
||||
|
||||
bMargins->Add( gbSizer1, 1, wxEXPAND|wxTOP, 5 );
|
||||
|
||||
|
||||
bSizer13->Add( bMargins, 1, wxEXPAND|wxALL, 5 );
|
||||
|
||||
|
||||
m_cellPage->SetSizer( bSizer13 );
|
||||
m_cellPage->Layout();
|
||||
bSizer13->Fit( m_cellPage );
|
||||
m_notebook->AddPage( m_cellPage, _("Cell"), true );
|
||||
|
||||
bColumns->Add( m_notebook, 0, wxEXPAND|wxBOTTOM|wxLEFT, 10 );
|
||||
|
||||
|
||||
bMainSizer->Add( bColumns, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 );
|
||||
|
||||
wxBoxSizer* bButtons;
|
||||
bButtons = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
|
||||
bButtons->Add( 0, 0, 1, wxEXPAND, 5 );
|
||||
|
||||
m_applyButton = new wxButton( this, wxID_ANY, _("Apply && Go to Next Cell"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bButtons->Add( m_applyButton, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
|
||||
|
||||
m_hotkeyHint = new wxStaticText( this, wxID_ANY, _("(Option+Tab)"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_hotkeyHint->Wrap( -1 );
|
||||
bButtons->Add( m_hotkeyHint, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 10 );
|
||||
|
||||
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();
|
||||
|
||||
bButtons->Add( m_sdbSizer1, 0, wxEXPAND|wxALL, 5 );
|
||||
|
||||
|
||||
bMainSizer->Add( bButtons, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( bMainSizer );
|
||||
this->Layout();
|
||||
bMainSizer->Fit( this );
|
||||
|
||||
// Connect Events
|
||||
m_textCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onMultiLineTCLostFocus ), NULL, this );
|
||||
m_borderCheckbox->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onBorderChecked ), NULL, this );
|
||||
m_rowSeparators->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onBorderChecked ), NULL, this );
|
||||
m_colSeparators->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onBorderChecked ), NULL, this );
|
||||
m_SizeXCtrl->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::OnOkClick ), NULL, this );
|
||||
m_SizeYCtrl->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::OnOkClick ), NULL, this );
|
||||
m_ThicknessCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onThickness ), NULL, this );
|
||||
m_applyButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::OnApply ), NULL, this );
|
||||
}
|
||||
|
||||
DIALOG_TABLECELL_PROPERTIES_BASE::~DIALOG_TABLECELL_PROPERTIES_BASE()
|
||||
{
|
||||
// Disconnect Events
|
||||
m_textCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onMultiLineTCLostFocus ), NULL, this );
|
||||
m_borderCheckbox->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onBorderChecked ), NULL, this );
|
||||
m_rowSeparators->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onBorderChecked ), NULL, this );
|
||||
m_colSeparators->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onBorderChecked ), NULL, this );
|
||||
m_SizeXCtrl->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::OnOkClick ), NULL, this );
|
||||
m_SizeYCtrl->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::OnOkClick ), NULL, this );
|
||||
m_ThicknessCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::onThickness ), NULL, this );
|
||||
m_applyButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_TABLECELL_PROPERTIES_BASE::OnApply ), NULL, this );
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,119 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
class BITMAP_BUTTON;
|
||||
class FONT_CHOICE;
|
||||
class PCB_LAYER_BOX_SELECTOR;
|
||||
class WX_INFOBAR;
|
||||
|
||||
#include "dialog_shim.h"
|
||||
#include <wx/infobar.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/string.h>
|
||||
#include <wx/stc/stc.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/bmpcbox.h>
|
||||
#include <wx/checkbox.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/gbsizer.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/bitmap.h>
|
||||
#include <wx/image.h>
|
||||
#include <wx/icon.h>
|
||||
#include <wx/bmpbuttn.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/choice.h>
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DIALOG_TABLECELL_PROPERTIES_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class DIALOG_TABLECELL_PROPERTIES_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
WX_INFOBAR* m_infoBar;
|
||||
wxStyledTextCtrl* m_textCtrl;
|
||||
wxNotebook* m_notebook;
|
||||
wxPanel* m_tablePage;
|
||||
wxGridBagSizer* m_textEntrySizer;
|
||||
wxStaticText* m_layerLabel;
|
||||
PCB_LAYER_BOX_SELECTOR* m_LayerSelectionCtrl;
|
||||
wxCheckBox* m_cbLocked;
|
||||
wxCheckBox* m_borderCheckbox;
|
||||
wxCheckBox* m_headerBorder;
|
||||
wxStaticText* m_borderWidthLabel;
|
||||
wxTextCtrl* m_borderWidthCtrl;
|
||||
wxStaticText* m_borderWidthUnits;
|
||||
wxStaticText* m_borderStyleLabel;
|
||||
wxBitmapComboBox* m_borderStyleCombo;
|
||||
wxCheckBox* m_rowSeparators;
|
||||
wxCheckBox* m_colSeparators;
|
||||
wxStaticText* m_separatorsWidthLabel;
|
||||
wxTextCtrl* m_separatorsWidthCtrl;
|
||||
wxStaticText* m_separatorsWidthUnits;
|
||||
wxStaticText* m_separatorsStyleLabel;
|
||||
wxBitmapComboBox* m_separatorsStyleCombo;
|
||||
wxPanel* m_cellPage;
|
||||
BITMAP_BUTTON* m_separator1;
|
||||
BITMAP_BUTTON* m_bold;
|
||||
BITMAP_BUTTON* m_italic;
|
||||
BITMAP_BUTTON* m_separator2;
|
||||
BITMAP_BUTTON* m_hAlignLeft;
|
||||
BITMAP_BUTTON* m_hAlignCenter;
|
||||
BITMAP_BUTTON* m_hAlignRight;
|
||||
BITMAP_BUTTON* m_separator3;
|
||||
BITMAP_BUTTON* m_vAlignTop;
|
||||
BITMAP_BUTTON* m_vAlignCenter;
|
||||
BITMAP_BUTTON* m_vAlignBottom;
|
||||
BITMAP_BUTTON* m_separator4;
|
||||
wxStaticText* m_fontLabel;
|
||||
FONT_CHOICE* m_fontCtrl;
|
||||
wxStaticText* m_SizeXLabel;
|
||||
wxTextCtrl* m_SizeXCtrl;
|
||||
wxStaticText* m_SizeXUnits;
|
||||
wxStaticText* m_SizeYLabel;
|
||||
wxTextCtrl* m_SizeYCtrl;
|
||||
wxStaticText* m_SizeYUnits;
|
||||
wxStaticText* m_ThicknessLabel;
|
||||
wxTextCtrl* m_ThicknessCtrl;
|
||||
wxStaticText* m_ThicknessUnits;
|
||||
wxButton* m_applyButton;
|
||||
wxStaticText* m_hotkeyHint;
|
||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||
wxButton* m_sdbSizer1OK;
|
||||
wxButton* m_sdbSizer1Cancel;
|
||||
|
||||
// Virtual event handlers, override them in your derived class
|
||||
virtual void onMultiLineTCLostFocus( wxFocusEvent& event ) { event.Skip(); }
|
||||
virtual void onBorderChecked( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnOkClick( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void onThickness( wxCommandEvent& event ) { event.Skip(); }
|
||||
virtual void OnApply( wxCommandEvent& event ) { event.Skip(); }
|
||||
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_TABLECELL_PROPERTIES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Table Cell Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||
|
||||
~DIALOG_TABLECELL_PROPERTIES_BASE();
|
||||
|
||||
};
|
||||
|
|
@ -1135,6 +1135,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
case PCB_FIELD_T: mask = DRC_DISALLOW_TEXTS; break;
|
||||
case PCB_TEXT_T: mask = DRC_DISALLOW_TEXTS; break;
|
||||
case PCB_TEXTBOX_T: mask = DRC_DISALLOW_TEXTS; break;
|
||||
case PCB_TABLE_T: mask = DRC_DISALLOW_TEXTS; break;
|
||||
|
||||
case PCB_ZONE_T:
|
||||
// Treat teardrop areas as tracks for DRC purposes
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <pcb_target.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_shape.h>
|
||||
#include <dialog_drc.h>
|
||||
#include <connectivity/connectivity_data.h>
|
||||
|
@ -136,6 +137,10 @@ void PCB_EDIT_FRAME::OnEditItemRequest( BOARD_ITEM* aItem )
|
|||
ShowTextBoxPropertiesDialog( static_cast<PCB_TEXTBOX*>( aItem ) );
|
||||
break;
|
||||
|
||||
case PCB_TABLECELL_T:
|
||||
ShowTableCellPropertiesDialog( static_cast<PCB_TABLECELL*>( aItem ) );
|
||||
break;
|
||||
|
||||
case PCB_PAD_T:
|
||||
ShowPadPropertiesDialog( static_cast<PAD*>( aItem ) );
|
||||
break;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "tools/convert_tool.h"
|
||||
#include "tools/drawing_tool.h"
|
||||
#include "tools/edit_tool.h"
|
||||
#include "tools/pcb_edit_table_tool.h"
|
||||
#include "tools/footprint_editor_control.h"
|
||||
#include "tools/pad_tool.h"
|
||||
#include "tools/pcb_actions.h"
|
||||
|
@ -1119,6 +1120,7 @@ void FOOTPRINT_EDIT_FRAME::setupTools()
|
|||
m_toolManager->RegisterTool( new PCB_SELECTION_TOOL );
|
||||
m_toolManager->RegisterTool( new ZOOM_TOOL );
|
||||
m_toolManager->RegisterTool( new EDIT_TOOL );
|
||||
m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
|
||||
m_toolManager->RegisterTool( new PAD_TOOL );
|
||||
m_toolManager->RegisterTool( new DRAWING_TOOL );
|
||||
m_toolManager->RegisterTool( new PCB_POINT_EDITOR );
|
||||
|
|
|
@ -312,6 +312,7 @@ void PCB_EDIT_FRAME::doReCreateMenuBar()
|
|||
placeMenu->Add( PCB_ACTIONS::placeReferenceImage );
|
||||
placeMenu->Add( PCB_ACTIONS::placeText );
|
||||
placeMenu->Add( PCB_ACTIONS::drawTextBox );
|
||||
placeMenu->Add( PCB_ACTIONS::drawTable );
|
||||
|
||||
placeMenu->AppendSeparator();
|
||||
ACTION_MENU* dimensionSubmenu = new ACTION_MENU( false, selTool );
|
||||
|
|
|
@ -33,6 +33,7 @@ class APPEARANCE_CONTROLS;
|
|||
class BOARD_ITEM_CONTAINER;
|
||||
class PANEL_SELECTION_FILTER;
|
||||
class PCB_TEXTBOX;
|
||||
class PCB_TABLECELL;
|
||||
class PCB_TEXT;
|
||||
class PCB_SHAPE;
|
||||
|
||||
|
@ -178,6 +179,7 @@ public:
|
|||
void ShowReferenceImagePropertiesDialog( BOARD_ITEM* aBitmap );
|
||||
void ShowTextPropertiesDialog( PCB_TEXT* aText );
|
||||
int ShowTextBoxPropertiesDialog( PCB_TEXTBOX* aTextBox );
|
||||
void ShowTableCellPropertiesDialog( PCB_TABLECELL* aTableCell );
|
||||
void ShowGraphicItemPropertiesDialog( PCB_SHAPE* aShape );
|
||||
|
||||
///< @copydoc EDA_DRAW_FRAME::UseGalCanvas()
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include <tools/pcb_picker_tool.h>
|
||||
#include <tools/pcb_point_editor.h>
|
||||
#include <tools/edit_tool.h>
|
||||
#include <tools/pcb_edit_table_tool.h>
|
||||
#include <tools/group_tool.h>
|
||||
#include <tools/generator_tool.h>
|
||||
#include <tools/drc_tool.h>
|
||||
|
@ -650,6 +651,7 @@ void PCB_EDIT_FRAME::setupTools()
|
|||
m_toolManager->RegisterTool( new PCB_PICKER_TOOL );
|
||||
m_toolManager->RegisterTool( new ROUTER_TOOL );
|
||||
m_toolManager->RegisterTool( new EDIT_TOOL );
|
||||
m_toolManager->RegisterTool( new PCB_EDIT_TABLE_TOOL );
|
||||
m_toolManager->RegisterTool( new GLOBAL_EDIT_TOOL );
|
||||
m_toolManager->RegisterTool( new PAD_TOOL );
|
||||
m_toolManager->RegisterTool( new DRAWING_TOOL );
|
||||
|
@ -968,6 +970,7 @@ void PCB_EDIT_FRAME::setupUIConditions()
|
|||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeReferenceImage );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::placeText );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTextBox );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawTable );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawAlignedDimension );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawOrthogonalDimension );
|
||||
CURRENT_EDIT_TOOL( PCB_ACTIONS::drawCenterDimension );
|
||||
|
|
|
@ -57,6 +57,7 @@ bool PCB_GROUP::IsGroupableType( KICAD_T aType )
|
|||
case PCB_FIELD_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_GROUP_T:
|
||||
case PCB_GENERATOR_T:
|
||||
case PCB_TRACE_T:
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
#include <pcb_target.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_track.h>
|
||||
#include <zone.h>
|
||||
#include <pcbnew_settings.h>
|
||||
|
@ -406,6 +408,10 @@ void PCB_IO_KICAD_SEXPR::Format( const BOARD_ITEM* aItem, int aNestLevel ) const
|
|||
format( static_cast<const PCB_TEXTBOX*>( aItem ), aNestLevel );
|
||||
break;
|
||||
|
||||
case PCB_TABLE_T:
|
||||
format( static_cast<const PCB_TABLE*>( aItem ), aNestLevel );
|
||||
break;
|
||||
|
||||
case PCB_GROUP_T:
|
||||
format( static_cast<const PCB_GROUP*>( aItem ), aNestLevel );
|
||||
break;
|
||||
|
@ -1448,7 +1454,7 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad, int aNestLevel ) const
|
|||
switch( aPad->GetShape() )
|
||||
{
|
||||
case PAD_SHAPE::CIRCLE: shape = "circle"; break;
|
||||
case PAD_SHAPE::RECTANGLE: shape = "rect"; break;
|
||||
case PAD_SHAPE::RECTANGLE: shape = "rect"; break;
|
||||
case PAD_SHAPE::OVAL: shape = "oval"; break;
|
||||
case PAD_SHAPE::TRAPEZOID: shape = "trapezoid"; break;
|
||||
case PAD_SHAPE::CHAMFERED_RECT:
|
||||
|
@ -1887,7 +1893,9 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox, int aNestLevel ) c
|
|||
FOOTPRINT* parentFP = aTextBox->GetParentFootprint();
|
||||
|
||||
m_out->Print( aNestLevel, "(%s %s\n",
|
||||
parentFP ? "fp_text_box" : "gr_text_box",
|
||||
aTextBox->Type() == PCB_TABLECELL_T ? "table_cell"
|
||||
: parentFP ? "fp_text_box"
|
||||
: "gr_text_box",
|
||||
m_out->Quotew( aTextBox->GetText() ).c_str() );
|
||||
|
||||
if( aTextBox->IsLocked() )
|
||||
|
@ -1911,6 +1919,9 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox, int aNestLevel ) c
|
|||
UNIMPLEMENTED_FOR( aTextBox->SHAPE_T_asString() );
|
||||
}
|
||||
|
||||
if( const PCB_TABLECELL* cell = dynamic_cast<const PCB_TABLECELL*>( aTextBox ) )
|
||||
m_out->Print( 0, " (span %d %d)", cell->GetColSpan(), cell->GetRowSpan() );
|
||||
|
||||
EDA_ANGLE angle = aTextBox->GetTextAngle();
|
||||
|
||||
if( parentFP )
|
||||
|
@ -1930,9 +1941,12 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox, int aNestLevel ) c
|
|||
// PCB_TEXTBOXes are never hidden, so always omit "hide" attribute
|
||||
aTextBox->EDA_TEXT::Format( m_out, aNestLevel, m_ctl | CTL_OMIT_HIDE );
|
||||
|
||||
KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "border", aTextBox->IsBorderEnabled() );
|
||||
if( aTextBox->Type() != PCB_TABLECELL_T )
|
||||
{
|
||||
KICAD_FORMAT::FormatBool( m_out, aNestLevel + 1, "border", aTextBox->IsBorderEnabled() );
|
||||
|
||||
aTextBox->GetStroke().Format( m_out, pcbIUScale, aNestLevel + 1 );
|
||||
aTextBox->GetStroke().Format( m_out, pcbIUScale, aNestLevel + 1 );
|
||||
}
|
||||
|
||||
if( aTextBox->GetFont() && aTextBox->GetFont()->IsOutline() )
|
||||
formatRenderCache( aTextBox, aNestLevel + 1 );
|
||||
|
@ -1941,6 +1955,66 @@ void PCB_IO_KICAD_SEXPR::format( const PCB_TEXTBOX* aTextBox, int aNestLevel ) c
|
|||
}
|
||||
|
||||
|
||||
void PCB_IO_KICAD_SEXPR::format( const PCB_TABLE* aTable, int aNestLevel ) const
|
||||
{
|
||||
wxCHECK_RET( aTable != nullptr && m_out != nullptr, "" );
|
||||
|
||||
m_out->Print( aNestLevel, "(table (column_count %d)\n",
|
||||
aTable->GetColCount() );
|
||||
|
||||
if( aTable->IsLocked() )
|
||||
KICAD_FORMAT::FormatBool( m_out, aNestLevel, "locked", aTable->IsLocked() );
|
||||
|
||||
formatLayer( aTable->GetLayer() );
|
||||
|
||||
m_out->Print( aNestLevel + 1, "(border (external %s) (header %s)",
|
||||
aTable->StrokeExternal() ? "yes" : "no",
|
||||
aTable->StrokeHeader() ? "yes" : "no" );
|
||||
|
||||
if( aTable->StrokeExternal() || aTable->StrokeHeader() )
|
||||
{
|
||||
m_out->Print( 0, " " );
|
||||
aTable->GetBorderStroke().Format( m_out, pcbIUScale, 0 );
|
||||
}
|
||||
|
||||
m_out->Print( 0, ")\n" );
|
||||
|
||||
m_out->Print( aNestLevel + 1, "(separators (rows %s) (cols %s)",
|
||||
aTable->StrokeRows() ? "yes" : "no",
|
||||
aTable->StrokeColumns() ? "yes" : "no" );
|
||||
|
||||
if( aTable->StrokeRows() || aTable->StrokeColumns() )
|
||||
{
|
||||
m_out->Print( 0, " " );
|
||||
aTable->GetSeparatorsStroke().Format( m_out, pcbIUScale, 0 );
|
||||
}
|
||||
|
||||
m_out->Print( 0, ")\n" ); // Close `separators` token.
|
||||
|
||||
m_out->Print( aNestLevel + 1, "(column_widths" );
|
||||
|
||||
for( int col = 0; col < aTable->GetColCount(); ++col )
|
||||
m_out->Print( 0, " %s", formatInternalUnits( aTable->GetColWidth( col ) ).c_str() );
|
||||
|
||||
m_out->Print( 0, ")\n" );
|
||||
|
||||
m_out->Print( aNestLevel + 1, "(row_heights" );
|
||||
|
||||
for( int row = 0; row < aTable->GetRowCount(); ++row )
|
||||
m_out->Print( 0, " %s", formatInternalUnits( aTable->GetRowHeight( row ) ).c_str() );
|
||||
|
||||
m_out->Print( 0, ")\n" );
|
||||
|
||||
m_out->Print( aNestLevel + 1, "(cells\n" );
|
||||
|
||||
for( PCB_TABLECELL* cell : aTable->GetCells() )
|
||||
format( static_cast<PCB_TEXTBOX*>( cell ), aNestLevel + 2 );
|
||||
|
||||
m_out->Print( aNestLevel + 1, ")\n" ); // Close `cells` token.
|
||||
m_out->Print( aNestLevel, ")\n" ); // Close `table` token.
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO_KICAD_SEXPR::format( const PCB_GROUP* aGroup, int aNestLevel ) const
|
||||
{
|
||||
// Don't write empty groups
|
||||
|
|
|
@ -52,6 +52,7 @@ class PCB_TRACK;
|
|||
class ZONE;
|
||||
class PCB_TEXT;
|
||||
class PCB_TEXTBOX;
|
||||
class PCB_TABLE;
|
||||
class EDA_TEXT;
|
||||
class SHAPE_LINE_CHAIN;
|
||||
class TEARDROP_PARAMETERS;
|
||||
|
@ -148,9 +149,10 @@ class PCB_IO_KICAD_SEXPR; // forward decl
|
|||
//#define SEXPR_BOARD_FILE_VERSION 20231014 // V8 file format normalization
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20231212 // Reference image locking/UUIDs, footprint boolean format
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20231231 // Use 'uuid' rather than 'id' for generators and groups
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20240108 // Convert teardrop parameters to explicit bools
|
||||
//#define SEXPR_BOARD_FILE_VERSION 20240108 // Convert teardrop parameters to explicit bools
|
||||
//----------------- Start of 9.0 development -----------------
|
||||
#define SEXPR_BOARD_FILE_VERSION 20240201 // Use nullable properties for overrides
|
||||
//define SEXPR_BOARD_FILE_VERSION 20240201 // Use nullable properties for overrides
|
||||
#define SEXPR_BOARD_FILE_VERSION 20240202 // Tables
|
||||
|
||||
#define BOARD_FILE_HOST_VERSION 20200825 ///< Earlier files than this include the host tag
|
||||
#define LEGACY_ARC_FORMATTING 20210925 ///< These were the last to use old arc formatting
|
||||
|
@ -159,7 +161,7 @@ class PCB_IO_KICAD_SEXPR; // forward decl
|
|||
#define FIRST_NORMALIZED_VERISON 20230924 ///< Earlier files did not have normalized bools
|
||||
|
||||
#define CTL_OMIT_PAD_NETS (1 << 1) ///< Omit pads net names (useless in library)
|
||||
#define CTL_OMIT_UUIDS (1 << 2) ///< Omit component unique ids (useless in library)
|
||||
#define CTL_OMIT_UUIDS (1 << 2) ///< Omit component unique ids (useless in library)
|
||||
#define CTL_OMIT_INITIAL_COMMENTS (1 << 3) ///< omit FOOTPRINT initial comments
|
||||
#define CTL_OMIT_PATH (1 << 4) ///< Omit component sheet time stamp (useless in library)
|
||||
#define CTL_OMIT_AT (1 << 5) ///< Omit position and rotation. (always saved
|
||||
|
@ -425,6 +427,8 @@ private:
|
|||
void format( const PCB_TEXT* aText, int aNestLevel = 0 ) const;
|
||||
void format( const PCB_TEXTBOX* aTextBox, int aNestLevel = 0 ) const;
|
||||
|
||||
void format( const PCB_TABLE* aTable, int aNestLevel = 0 ) const;
|
||||
|
||||
void format( const PCB_GENERATOR* aGenerator, int aNestLevel = 0 ) const;
|
||||
|
||||
void format( const PCB_TRACK* aTrack, int aNestLevel = 0 ) const;
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <pcb_target.h>
|
||||
#include <pcb_track.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pad.h>
|
||||
#include <generators_mgr.h>
|
||||
#include <zone.h>
|
||||
|
@ -1006,6 +1007,12 @@ BOARD* PCB_IO_KICAD_SEXPR_PARSER::parseBOARD_unchecked()
|
|||
bulkAddedItems.push_back( item );
|
||||
break;
|
||||
|
||||
case T_table:
|
||||
item = parsePCB_TABLE( m_board );
|
||||
m_board->Add( item, ADD_MODE::BULK_APPEND, true );
|
||||
bulkAddedItems.push_back( item );
|
||||
break;
|
||||
|
||||
case T_dimension:
|
||||
item = parseDIMENSION( m_board );
|
||||
m_board->Add( item, ADD_MODE::BULK_APPEND, true );
|
||||
|
@ -3333,19 +3340,40 @@ PCB_TEXTBOX* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXTBOX( BOARD_ITEM* aParent )
|
|||
|
||||
std::unique_ptr<PCB_TEXTBOX> textbox = std::make_unique<PCB_TEXTBOX>( aParent );
|
||||
|
||||
parseTextBoxContent( textbox.get() );
|
||||
|
||||
return textbox.release();
|
||||
}
|
||||
|
||||
|
||||
PCB_TABLECELL* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TABLECELL( BOARD_ITEM* aParent )
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_table_cell, nullptr,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a table cell." ) );
|
||||
|
||||
std::unique_ptr<PCB_TABLECELL> cell = std::make_unique<PCB_TABLECELL>( aParent );
|
||||
|
||||
parseTextBoxContent( cell.get() );
|
||||
|
||||
return cell.release();
|
||||
}
|
||||
|
||||
|
||||
void PCB_IO_KICAD_SEXPR_PARSER::parseTextBoxContent( PCB_TEXTBOX* aTextBox )
|
||||
{
|
||||
STROKE_PARAMS stroke( -1, LINE_STYLE::SOLID );
|
||||
T token = NextTok();
|
||||
|
||||
if( token == T_locked )
|
||||
{
|
||||
textbox->SetLocked( true );
|
||||
aTextBox->SetLocked( true );
|
||||
token = NextTok();
|
||||
}
|
||||
|
||||
if( !IsSymbol( token ) && (int) token != DSN_NUMBER )
|
||||
Expecting( "text value" );
|
||||
|
||||
textbox->SetText( FromUTF8() );
|
||||
aTextBox->SetText( FromUTF8() );
|
||||
|
||||
NeedLEFT();
|
||||
token = NextTok();
|
||||
|
@ -3354,7 +3382,7 @@ PCB_TEXTBOX* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXTBOX( BOARD_ITEM* aParent )
|
|||
{
|
||||
int x = parseBoardUnits( "X coordinate" );
|
||||
int y = parseBoardUnits( "Y coordinate" );
|
||||
textbox->SetStart( VECTOR2I( x, y ) );
|
||||
aTextBox->SetStart( VECTOR2I( x, y ) );
|
||||
NeedRIGHT();
|
||||
|
||||
NeedLEFT();
|
||||
|
@ -3365,17 +3393,17 @@ PCB_TEXTBOX* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXTBOX( BOARD_ITEM* aParent )
|
|||
|
||||
x = parseBoardUnits( "X coordinate" );
|
||||
y = parseBoardUnits( "Y coordinate" );
|
||||
textbox->SetEnd( VECTOR2I( x, y ) );
|
||||
aTextBox->SetEnd( VECTOR2I( x, y ) );
|
||||
NeedRIGHT();
|
||||
}
|
||||
else if( token == T_pts )
|
||||
{
|
||||
textbox->SetShape( SHAPE_T::POLY );
|
||||
textbox->GetPolyShape().RemoveAllContours();
|
||||
textbox->GetPolyShape().NewOutline();
|
||||
aTextBox->SetShape( SHAPE_T::POLY );
|
||||
aTextBox->GetPolyShape().RemoveAllContours();
|
||||
aTextBox->GetPolyShape().NewOutline();
|
||||
|
||||
while( (token = NextTok() ) != T_RIGHT )
|
||||
parseOutlinePoints( textbox->GetPolyShape().Outline( 0 ) );
|
||||
parseOutlinePoints( aTextBox->GetPolyShape().Outline( 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3394,7 +3422,7 @@ PCB_TEXTBOX* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXTBOX( BOARD_ITEM* aParent )
|
|||
case T_angle:
|
||||
// Set the angle of the text only, the coordinates of the box (a polygon) are
|
||||
// already at the right position, and must not be rotated
|
||||
textbox->EDA_TEXT::SetTextAngle( EDA_ANGLE( parseDouble( "text box angle" ), DEGREES_T ) );
|
||||
aTextBox->EDA_TEXT::SetTextAngle( EDA_ANGLE( parseDouble( "text box angle" ), DEGREES_T ) );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
|
@ -3409,48 +3437,224 @@ PCB_TEXTBOX* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TEXTBOX( BOARD_ITEM* aParent )
|
|||
}
|
||||
|
||||
case T_border:
|
||||
textbox->SetBorderEnabled( parseBool() );
|
||||
aTextBox->SetBorderEnabled( parseBool() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_layer:
|
||||
textbox->SetLayer( parseBoardItemLayer() );
|
||||
aTextBox->SetLayer( parseBoardItemLayer() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_span:
|
||||
if( PCB_TABLECELL* cell = dynamic_cast<PCB_TABLECELL*>( aTextBox ) )
|
||||
{
|
||||
cell->SetColSpan( parseInt( "column span" ) );
|
||||
cell->SetRowSpan( parseInt( "row span" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Expecting( "angle, width, layer, effects, render_cache, uuid or tstamp" );
|
||||
}
|
||||
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_tstamp:
|
||||
case T_uuid:
|
||||
NextTok();
|
||||
const_cast<KIID&>( textbox->m_Uuid ) = CurStrToKIID();
|
||||
const_cast<KIID&>( aTextBox->m_Uuid ) = CurStrToKIID();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_effects:
|
||||
parseEDA_TEXT( static_cast<EDA_TEXT*>( textbox.get() ) );
|
||||
parseEDA_TEXT( static_cast<EDA_TEXT*>( aTextBox ) );
|
||||
break;
|
||||
|
||||
case T_render_cache:
|
||||
parseRenderCache( static_cast<EDA_TEXT*>( textbox.get() ) );
|
||||
parseRenderCache( static_cast<EDA_TEXT*>( aTextBox ) );
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "angle, width, layer, effects, render_cache, uuid or tstamp" );
|
||||
if( PCB_TABLECELL* cell = dynamic_cast<PCB_TABLECELL*>( aTextBox ) )
|
||||
Expecting( "angle, width, layer, effects, span, render_cache, uuid or tstamp" );
|
||||
else
|
||||
Expecting( "angle, width, layer, effects, render_cache, uuid or tstamp" );
|
||||
}
|
||||
}
|
||||
|
||||
textbox->SetStroke( stroke );
|
||||
aTextBox->SetStroke( stroke );
|
||||
|
||||
if( m_requiredVersion < 20230825 ) // compat, we move to an explicit flag
|
||||
textbox->SetBorderEnabled( stroke.GetWidth() >= 0 );
|
||||
aTextBox->SetBorderEnabled( stroke.GetWidth() >= 0 );
|
||||
|
||||
|
||||
if( FOOTPRINT* parentFP = dynamic_cast<FOOTPRINT*>( aParent ) )
|
||||
if( FOOTPRINT* parentFP = dynamic_cast<FOOTPRINT*>( aTextBox->GetParent() ) )
|
||||
{
|
||||
textbox->Rotate( { 0, 0 }, parentFP->GetOrientation() );
|
||||
textbox->Move( parentFP->GetPosition() );
|
||||
aTextBox->Rotate( { 0, 0 }, parentFP->GetOrientation() );
|
||||
aTextBox->Move( parentFP->GetPosition() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PCB_TABLE* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_TABLE( BOARD_ITEM* aParent )
|
||||
{
|
||||
wxCHECK_MSG( CurTok() == T_table, nullptr,
|
||||
wxT( "Cannot parse " ) + GetTokenString( CurTok() ) + wxT( " as a table." ) );
|
||||
|
||||
T token;
|
||||
STROKE_PARAMS borderStroke( -1, LINE_STYLE::SOLID );
|
||||
STROKE_PARAMS separatorsStroke( -1, LINE_STYLE::SOLID );
|
||||
std::unique_ptr<PCB_TABLE> table = std::make_unique<PCB_TABLE>( aParent, -1 );
|
||||
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token == T_locked )
|
||||
{
|
||||
table->SetLocked( true );
|
||||
token = NextTok();
|
||||
}
|
||||
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_column_count:
|
||||
table->SetColCount( parseInt( "column count" ) );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_layer:
|
||||
table->SetLayer( parseBoardItemLayer() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_column_widths:
|
||||
{
|
||||
int col = 0;
|
||||
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
table->SetColWidth( col++, parseBoardUnits() );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case T_row_heights:
|
||||
{
|
||||
int row = 0;
|
||||
|
||||
while( ( token = NextTok() ) != T_RIGHT )
|
||||
table->SetRowHeight( row++, parseBoardUnits() );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case T_cells:
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
if( token != T_table_cell )
|
||||
Expecting( "table_cell" );
|
||||
|
||||
table->AddCell( parsePCB_TABLECELL( table.get() ) );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case T_border:
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_external:
|
||||
table->SetStrokeExternal( parseBool() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_header:
|
||||
table->SetStrokeHeader( parseBool() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_stroke:
|
||||
{
|
||||
STROKE_PARAMS_PARSER strokeParser( reader, pcbIUScale.IU_PER_MM );
|
||||
strokeParser.SyncLineReaderWith( *this );
|
||||
|
||||
strokeParser.ParseStroke( borderStroke );
|
||||
SyncLineReaderWith( strokeParser );
|
||||
|
||||
table->SetBorderStroke( borderStroke );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Expecting( "external, header or stroke" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case T_separators:
|
||||
for( token = NextTok(); token != T_RIGHT; token = NextTok() )
|
||||
{
|
||||
if( token != T_LEFT )
|
||||
Expecting( T_LEFT );
|
||||
|
||||
token = NextTok();
|
||||
|
||||
switch( token )
|
||||
{
|
||||
case T_rows:
|
||||
table->SetStrokeRows( parseBool() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_cols:
|
||||
table->SetStrokeColumns( parseBool() );
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
||||
case T_stroke:
|
||||
{
|
||||
STROKE_PARAMS_PARSER strokeParser( reader, pcbIUScale.IU_PER_MM );
|
||||
strokeParser.SyncLineReaderWith( *this );
|
||||
|
||||
strokeParser.ParseStroke( separatorsStroke );
|
||||
SyncLineReaderWith( strokeParser );
|
||||
|
||||
table->SetSeparatorsStroke( separatorsStroke );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
Expecting( "rows, cols, or stroke" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
Expecting( "columns, layer, col_widths, row_heights, border, separators, header or "
|
||||
"cells" );
|
||||
}
|
||||
}
|
||||
|
||||
return textbox.release();
|
||||
return table.release();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4324,6 +4528,13 @@ FOOTPRINT* PCB_IO_KICAD_SEXPR_PARSER::parseFOOTPRINT_unchecked( wxArrayString* a
|
|||
break;
|
||||
}
|
||||
|
||||
case T_table:
|
||||
{
|
||||
PCB_TABLE* table = parsePCB_TABLE( footprint.get() );
|
||||
footprint->Add( table, ADD_MODE::APPEND, true );
|
||||
break;
|
||||
}
|
||||
|
||||
case T_fp_arc:
|
||||
case T_fp_circle:
|
||||
case T_fp_curve:
|
||||
|
|
|
@ -52,9 +52,10 @@ class PCB_DIMENSION_BASE;
|
|||
class PCB_SHAPE;
|
||||
class PCB_REFERENCE_IMAGE;
|
||||
class EDA_TEXT;
|
||||
class FP_SHAPE;
|
||||
class PCB_TEXT;
|
||||
class PCB_TRACK;
|
||||
class PCB_TABLE;
|
||||
class PCB_TABLECELL;
|
||||
class FOOTPRINT;
|
||||
class PCB_GROUP;
|
||||
class PCB_TARGET;
|
||||
|
@ -207,11 +208,15 @@ private:
|
|||
|
||||
void parseTEARDROP_PARAMETERS( TEARDROP_PARAMETERS* tdParams );
|
||||
|
||||
void parseTextBoxContent( PCB_TEXTBOX* aTextBox );
|
||||
|
||||
PCB_SHAPE* parsePCB_SHAPE( BOARD_ITEM* aParent );
|
||||
PCB_TEXT* parsePCB_TEXT( BOARD_ITEM* aParent );
|
||||
void parsePCB_TEXT_effects( PCB_TEXT* aText );
|
||||
PCB_REFERENCE_IMAGE* parsePCB_REFERENCE_IMAGE( BOARD_ITEM* aParent );
|
||||
PCB_TEXTBOX* parsePCB_TEXTBOX( BOARD_ITEM* aParent );
|
||||
PCB_TABLECELL* parsePCB_TABLECELL( BOARD_ITEM* aParent );
|
||||
PCB_TABLE* parsePCB_TABLE( BOARD_ITEM* aParent );
|
||||
PCB_DIMENSION_BASE* parseDIMENSION( BOARD_ITEM* aParent );
|
||||
|
||||
// Parse a footprint, but do not replace PARSE_ERROR with FUTURE_FORMAT_ERROR automatically.
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include <pcb_reference_image.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_marker.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pcb_target.h>
|
||||
|
@ -613,6 +615,10 @@ bool PCB_PAINTER::Draw( const VIEW_ITEM* aItem, int aLayer )
|
|||
draw( static_cast<const PCB_TEXTBOX*>( item ), aLayer );
|
||||
break;
|
||||
|
||||
case PCB_TABLE_T:
|
||||
draw( static_cast<const PCB_TABLE*>( item ), aLayer );
|
||||
break;
|
||||
|
||||
case PCB_FOOTPRINT_T:
|
||||
draw( static_cast<const FOOTPRINT*>( item ), aLayer );
|
||||
break;
|
||||
|
@ -2132,10 +2138,18 @@ void PCB_PAINTER::draw( const PCB_TEXT* aText, int aLayer )
|
|||
|
||||
void PCB_PAINTER::draw( const PCB_TEXTBOX* aTextBox, int aLayer )
|
||||
{
|
||||
const COLOR4D& color = m_pcbSettings.GetColor( aTextBox, aLayer );
|
||||
int thickness = getLineThickness( aTextBox->GetWidth() );
|
||||
LINE_STYLE lineStyle = aTextBox->GetStroke().GetLineStyle();
|
||||
wxString resolvedText( aTextBox->GetShownText( true ) );
|
||||
if( aTextBox->Type() == PCB_TABLECELL_T )
|
||||
{
|
||||
const PCB_TABLECELL* cell = static_cast<const PCB_TABLECELL*>( aTextBox );
|
||||
|
||||
if( cell->GetColSpan() == 0 || cell->GetRowSpan() == 0 )
|
||||
return;
|
||||
}
|
||||
|
||||
COLOR4D color = m_pcbSettings.GetColor( aTextBox, aLayer );
|
||||
int thickness = getLineThickness( aTextBox->GetWidth() );
|
||||
LINE_STYLE lineStyle = aTextBox->GetStroke().GetLineStyle();
|
||||
wxString resolvedText( aTextBox->GetShownText( true ) );
|
||||
|
||||
KIFONT::FONT* font = aTextBox->GetFont();
|
||||
|
||||
|
@ -2171,6 +2185,13 @@ void PCB_PAINTER::draw( const PCB_TEXTBOX* aTextBox, int aLayer )
|
|||
m_gal->DrawPolygon( dpts );
|
||||
}
|
||||
|
||||
if( aTextBox->Type() == PCB_TABLECELL_T )
|
||||
{
|
||||
// Selection for tables is done with a background wash, so pass in nullptr to GetColor()
|
||||
// so we just get the "normal" (un-selected/un-brightened) color for the borders.
|
||||
color = m_pcbSettings.GetColor( nullptr, aLayer );
|
||||
}
|
||||
|
||||
m_gal->SetFillColor( color );
|
||||
m_gal->SetStrokeColor( color );
|
||||
m_gal->SetIsFill( true );
|
||||
|
@ -2224,14 +2245,14 @@ void PCB_PAINTER::draw( const PCB_TEXTBOX* aTextBox, int aLayer )
|
|||
// so the text drawn on LAYER_LOCKED_ITEM_SHADOW with a thick width is disabled
|
||||
// If enabled, the thick text position must be offsetted to be exactly on the
|
||||
// initial text, which is not easy, depending on its rotation and justification.
|
||||
#if 0
|
||||
#if 0
|
||||
const COLOR4D sh_color = m_pcbSettings.GetColor( aTextBox, aLayer );
|
||||
m_gal->SetFillColor( sh_color );
|
||||
m_gal->SetStrokeColor( sh_color );
|
||||
attrs.m_StrokeWidth += m_lockedShadowMargin;
|
||||
#else
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<KIFONT::GLYPH>>* cache = nullptr;
|
||||
|
@ -2251,6 +2272,146 @@ void PCB_PAINTER::draw( const PCB_TEXTBOX* aTextBox, int aLayer )
|
|||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const PCB_TABLE* aTable, int aLayer )
|
||||
{
|
||||
for( PCB_TABLECELL* cell : aTable->GetCells() )
|
||||
draw( static_cast<PCB_TEXTBOX*>( cell ), aLayer );
|
||||
|
||||
VECTOR2I pos = aTable->GetPosition();
|
||||
VECTOR2I end = aTable->GetEnd();
|
||||
|
||||
// Selection for tables is done with a background wash, so pass in nullptr to GetColor()
|
||||
// so we just get the "normal" (un-selected/un-brightened) color for the borders.
|
||||
COLOR4D color = m_pcbSettings.GetColor( nullptr, aLayer );
|
||||
int lineWidth;
|
||||
LINE_STYLE lineStyle;
|
||||
|
||||
auto setupStroke =
|
||||
[&]( const STROKE_PARAMS& stroke )
|
||||
{
|
||||
lineWidth = getLineThickness( stroke.GetWidth() );
|
||||
lineStyle = stroke.GetLineStyle();
|
||||
|
||||
m_gal->SetIsFill( false );
|
||||
m_gal->SetIsStroke( true );
|
||||
m_gal->SetStrokeColor( color );
|
||||
m_gal->SetLineWidth( lineWidth );
|
||||
};
|
||||
|
||||
auto strokeShape =
|
||||
[&]( const SHAPE& shape )
|
||||
{
|
||||
STROKE_PARAMS::Stroke( &shape, lineStyle, lineWidth, &m_pcbSettings,
|
||||
[&]( const VECTOR2I& a, const VECTOR2I& b )
|
||||
{
|
||||
// DrawLine has problem with 0 length lines so enforce minimum
|
||||
if( a == b )
|
||||
m_gal->DrawLine( a+1, b );
|
||||
else
|
||||
m_gal->DrawLine( a, b );
|
||||
} );
|
||||
};
|
||||
|
||||
auto strokeLine =
|
||||
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB )
|
||||
{
|
||||
if( lineStyle <= LINE_STYLE::FIRST_TYPE )
|
||||
{
|
||||
m_gal->DrawLine( ptA, ptB );
|
||||
}
|
||||
else
|
||||
{
|
||||
SHAPE_SEGMENT seg( ptA, ptB );
|
||||
strokeShape( seg );
|
||||
}
|
||||
};
|
||||
|
||||
auto strokeRect =
|
||||
[&]( const VECTOR2I& ptA, const VECTOR2I& ptB )
|
||||
{
|
||||
if( lineStyle <= LINE_STYLE::FIRST_TYPE )
|
||||
{
|
||||
m_gal->DrawRectangle( ptA, ptB );
|
||||
}
|
||||
else
|
||||
{
|
||||
SHAPE_RECT rect( BOX2I( ptA, ptB - ptA ) );
|
||||
strokeShape( rect );
|
||||
}
|
||||
};
|
||||
|
||||
if( aTable->GetSeparatorsStroke().GetWidth() >= 0 )
|
||||
{
|
||||
setupStroke( aTable->GetSeparatorsStroke() );
|
||||
|
||||
if( aTable->StrokeColumns() )
|
||||
{
|
||||
for( int col = 0; col < aTable->GetColCount() - 1; ++col )
|
||||
{
|
||||
for( int row = 0; row < aTable->GetRowCount(); ++row )
|
||||
{
|
||||
PCB_TABLECELL* cell = aTable->GetCell( row, col );
|
||||
|
||||
if( cell->GetColSpan() > 0 && cell->GetRowSpan() > 0 )
|
||||
{
|
||||
strokeLine( VECTOR2I( cell->GetEndX(), cell->GetStartY() ),
|
||||
VECTOR2I( cell->GetEndX(), cell->GetEndY() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aTable->StrokeRows() )
|
||||
{
|
||||
for( int row = 0; row < aTable->GetRowCount() - 1; ++row )
|
||||
{
|
||||
for( int col = 0; col < aTable->GetColCount(); ++col )
|
||||
{
|
||||
PCB_TABLECELL* cell = aTable->GetCell( row, 0 );
|
||||
|
||||
if( cell->GetColSpan() > 0 && cell->GetRowSpan() > 0 )
|
||||
{
|
||||
strokeLine( VECTOR2I( cell->GetStartX(), cell->GetEndY() ),
|
||||
VECTOR2I( cell->GetEndX(), cell->GetEndY() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( aTable->GetBorderStroke().GetWidth() >= 0 )
|
||||
{
|
||||
setupStroke( aTable->GetBorderStroke() );
|
||||
|
||||
if( aTable->StrokeHeader() )
|
||||
{
|
||||
PCB_TABLECELL* cell = aTable->GetCell( 0, 0 );
|
||||
strokeLine( VECTOR2I( pos.x, cell->GetEndY() ), VECTOR2I( end.x, cell->GetEndY() ) );
|
||||
}
|
||||
|
||||
if( aTable->StrokeExternal() )
|
||||
strokeRect( pos, end );
|
||||
}
|
||||
|
||||
// Highlight selected tablecells with a background wash.
|
||||
for( PCB_TABLECELL* cell : aTable->GetCells() )
|
||||
{
|
||||
if( cell->IsSelected() )
|
||||
{
|
||||
std::vector<VECTOR2I> corners = cell->GetCorners();
|
||||
std::deque<VECTOR2D> pts;
|
||||
|
||||
pts.insert( pts.end(), corners.begin(), corners.end() );
|
||||
|
||||
m_gal->SetFillColor( color.WithAlpha( 0.5 ) );
|
||||
m_gal->SetIsFill( true );
|
||||
m_gal->SetIsStroke( false );
|
||||
m_gal->DrawPolygon( pts );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_PAINTER::draw( const FOOTPRINT* aFootprint, int aLayer )
|
||||
{
|
||||
if( aLayer == LAYER_ANCHOR )
|
||||
|
|
|
@ -52,6 +52,7 @@ class ZONE;
|
|||
class PCB_REFERENCE_IMAGE;
|
||||
class PCB_TEXT;
|
||||
class PCB_TEXTBOX;
|
||||
class PCB_TABLE;
|
||||
class PCB_DIMENSION_BASE;
|
||||
class PCB_TARGET;
|
||||
class PCB_MARKER;
|
||||
|
@ -185,6 +186,7 @@ protected:
|
|||
void draw( const PCB_REFERENCE_IMAGE* aBitmap, int aLayer );
|
||||
void draw( const PCB_TEXT* aText, int aLayer );
|
||||
void draw( const PCB_TEXTBOX* aText, int aLayer );
|
||||
void draw( const PCB_TABLE* aTable, int aLayer );
|
||||
void draw( const FOOTPRINT* aFootprint, int aLayer );
|
||||
void draw( const PCB_GROUP* aGroup, int aLayer );
|
||||
void draw( const ZONE* aZone, int aLayer );
|
||||
|
|
|
@ -0,0 +1,450 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <pcb_table.h>
|
||||
|
||||
|
||||
|
||||
PCB_TABLE::PCB_TABLE( BOARD_ITEM* aParent, int aLineWidth ) :
|
||||
BOARD_ITEM_CONTAINER( aParent, PCB_TABLE_T ),
|
||||
m_strokeExternal( true ),
|
||||
m_strokeHeader( true ),
|
||||
m_borderStroke( aLineWidth, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
|
||||
m_strokeRows( true ),
|
||||
m_strokeColumns( true ),
|
||||
m_separatorsStroke( aLineWidth, LINE_STYLE::DEFAULT, COLOR4D::UNSPECIFIED ),
|
||||
m_colCount( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PCB_TABLE::PCB_TABLE( const PCB_TABLE& aTable ) :
|
||||
BOARD_ITEM_CONTAINER( aTable )
|
||||
{
|
||||
m_strokeExternal = aTable.m_strokeExternal;
|
||||
m_strokeHeader = aTable.m_strokeHeader;
|
||||
m_borderStroke = aTable.m_borderStroke;
|
||||
m_strokeRows = aTable.m_strokeRows;
|
||||
m_strokeColumns = aTable.m_strokeColumns;
|
||||
m_separatorsStroke = aTable.m_separatorsStroke;
|
||||
|
||||
m_colCount = aTable.m_colCount;
|
||||
m_colWidths = aTable.m_colWidths;
|
||||
m_rowHeights = aTable.m_rowHeights;
|
||||
|
||||
for( PCB_TABLECELL* src : aTable.m_cells )
|
||||
AddCell( new PCB_TABLECELL( *src ) );
|
||||
}
|
||||
|
||||
|
||||
PCB_TABLE::~PCB_TABLE()
|
||||
{
|
||||
// We own our cells; delete them
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
delete cell;
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::swapData( BOARD_ITEM* aImage )
|
||||
{
|
||||
wxCHECK_RET( aImage != nullptr && aImage->Type() == PCB_TABLE_T,
|
||||
wxT( "Cannot swap data with invalid table." ) );
|
||||
|
||||
PCB_TABLE* table = static_cast<PCB_TABLE*>( aImage );
|
||||
|
||||
std::swap( m_strokeExternal, table->m_strokeExternal );
|
||||
std::swap( m_strokeHeader, table->m_strokeHeader );
|
||||
std::swap( m_borderStroke, table->m_borderStroke );
|
||||
std::swap( m_strokeRows, table->m_strokeRows );
|
||||
std::swap( m_strokeColumns, table->m_strokeColumns );
|
||||
std::swap( m_separatorsStroke, table->m_separatorsStroke );
|
||||
|
||||
std::swap( m_colCount, table->m_colCount );
|
||||
std::swap( m_colWidths, table->m_colWidths );
|
||||
std::swap( m_rowHeights, table->m_rowHeights );
|
||||
|
||||
std::swap( m_cells, table->m_cells );
|
||||
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
cell->SetParent( this );
|
||||
|
||||
for( PCB_TABLECELL* cell : table->m_cells )
|
||||
cell->SetParent( table );
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::SetPosition( const VECTOR2I& aPos )
|
||||
{
|
||||
Move( aPos - GetPosition() );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I PCB_TABLE::GetPosition() const
|
||||
{
|
||||
return m_cells[0]->GetPosition();
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I PCB_TABLE::GetEnd() const
|
||||
{
|
||||
VECTOR2I tableSize;
|
||||
|
||||
for( int ii = 0; ii < GetColCount(); ++ii )
|
||||
tableSize.x += GetColWidth( ii );
|
||||
|
||||
for( int ii = 0; ii < GetRowCount(); ++ii )
|
||||
tableSize.y += GetRowHeight( ii );
|
||||
|
||||
return GetPosition() + tableSize;
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::Normalize()
|
||||
{
|
||||
// JEY TODO: pukes on rotated tables...
|
||||
|
||||
int y = GetPosition().y;
|
||||
|
||||
for( int row = 0; row < GetRowCount(); ++row )
|
||||
{
|
||||
int x = GetPosition().x;
|
||||
int rowHeight = m_rowHeights[ row ];
|
||||
|
||||
for( int col = 0; col < GetColCount(); ++col )
|
||||
{
|
||||
int colWidth = m_colWidths[ col ];
|
||||
|
||||
PCB_TABLECELL* cell = GetCell( row, col );
|
||||
VECTOR2I pos( x, y );
|
||||
|
||||
if( cell->GetPosition() != pos )
|
||||
{
|
||||
cell->SetPosition( pos );
|
||||
cell->ClearRenderCache();
|
||||
}
|
||||
|
||||
VECTOR2I end = cell->GetStart() + VECTOR2I( colWidth, rowHeight );
|
||||
|
||||
if( cell->GetColSpan() > 1 || cell->GetRowSpan() > 1 )
|
||||
{
|
||||
for( int ii = col + 1; ii < col + cell->GetColSpan(); ++ii )
|
||||
end.x += m_colWidths[ii];
|
||||
|
||||
for( int ii = row + 1; ii < row + cell->GetRowSpan(); ++ii )
|
||||
end.y += m_rowHeights[ii];
|
||||
}
|
||||
|
||||
if( cell->GetEnd() != end )
|
||||
{
|
||||
cell->SetEnd( end );
|
||||
cell->ClearRenderCache();
|
||||
}
|
||||
|
||||
x += colWidth;
|
||||
}
|
||||
|
||||
y += rowHeight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::Move( const VECTOR2I& aMoveVector )
|
||||
{
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
cell->Move( aMoveVector );
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
|
||||
{
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
cell->Rotate( aRotCentre, aAngle );
|
||||
|
||||
Normalize();
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
||||
{
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
cell->Flip( aCentre, aFlipLeftRight );
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFunction ) const
|
||||
{
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
aFunction( cell );
|
||||
}
|
||||
|
||||
|
||||
const BOX2I PCB_TABLE::GetBoundingBox() const
|
||||
{
|
||||
// Note: a table with no cells is not allowed
|
||||
BOX2I bbox = m_cells[0]->GetBoundingBox();
|
||||
|
||||
bbox.Merge( m_cells[ m_cells.size() - 1 ]->GetBoundingBox() );
|
||||
|
||||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||
int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
|
||||
bool aIgnoreLineWidth ) const
|
||||
{
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
cell->TransformShapeToPolygon( aBuffer, aLayer, aClearance, aMaxError, aErrorLoc, false );
|
||||
}
|
||||
|
||||
|
||||
INSPECT_RESULT PCB_TABLE::Visit( INSPECTOR aInspector, void* aTestData,
|
||||
const std::vector<KICAD_T>& aScanTypes )
|
||||
{
|
||||
for( KICAD_T scanType : aScanTypes )
|
||||
{
|
||||
if( scanType == PCB_TABLE_T )
|
||||
{
|
||||
if( INSPECT_RESULT::QUIT == aInspector( this, aTestData ) )
|
||||
return INSPECT_RESULT::QUIT;
|
||||
}
|
||||
|
||||
if( scanType == PCB_TABLECELL_T )
|
||||
{
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
{
|
||||
if( INSPECT_RESULT::QUIT == aInspector( cell, (void*) this ) )
|
||||
return INSPECT_RESULT::QUIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return INSPECT_RESULT::CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
wxString PCB_TABLE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( _( "%d Column Table" ), m_colCount );
|
||||
}
|
||||
|
||||
|
||||
BITMAPS PCB_TABLE::GetMenuImage() const
|
||||
{
|
||||
return BITMAPS::spreadsheet; // JEY TODO
|
||||
}
|
||||
|
||||
|
||||
bool PCB_TABLE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||
{
|
||||
BOX2I rect = GetBoundingBox();
|
||||
|
||||
rect.Inflate( aAccuracy );
|
||||
|
||||
return rect.Contains( aPosition );
|
||||
}
|
||||
|
||||
|
||||
bool PCB_TABLE::HitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) const
|
||||
{
|
||||
BOX2I rect = aRect;
|
||||
|
||||
rect.Inflate( aAccuracy );
|
||||
|
||||
if( aContained )
|
||||
return rect.Contains( GetBoundingBox() );
|
||||
|
||||
return rect.Intersects( GetBoundingBox() );
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLE::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Table" ), wxString::Format( _( "%d Columns" ), m_colCount ) );
|
||||
}
|
||||
|
||||
|
||||
int PCB_TABLE::Compare( const PCB_TABLE* aTable, const PCB_TABLE* aOther )
|
||||
{
|
||||
int diff;
|
||||
|
||||
if( ( diff = (int) aTable->GetCells().size() - (int) aOther->GetCells().size() ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = aTable->GetColCount() - aOther->GetColCount() ) != 0 )
|
||||
return diff;
|
||||
|
||||
for( int col = 0; col < aTable->GetColCount(); ++col )
|
||||
{
|
||||
if( ( diff = aTable->GetColWidth( col ) - aOther->GetColWidth( col ) ) != 0 )
|
||||
return diff;
|
||||
}
|
||||
|
||||
for( int row = 0; row < aTable->GetRowCount(); ++row )
|
||||
{
|
||||
if( ( diff = aTable->GetRowHeight( row ) - aOther->GetRowHeight( row ) ) != 0 )
|
||||
return diff;
|
||||
}
|
||||
|
||||
for( int row = 0; row < aTable->GetRowCount(); ++row )
|
||||
{
|
||||
for( int col = 0; col < aTable->GetColCount(); ++col )
|
||||
{
|
||||
PCB_TABLECELL* cell = aTable->GetCell( row, col );
|
||||
PCB_TABLECELL* other = aOther->GetCell( row, col );
|
||||
|
||||
if( ( diff = cell->PCB_SHAPE::Compare( other ) ) != 0 )
|
||||
return diff;
|
||||
|
||||
if( ( diff = cell->EDA_TEXT::Compare( other ) ) != 0 )
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_TABLE::operator==( const BOARD_ITEM& aOther ) const
|
||||
{
|
||||
if( Type() != aOther.Type() )
|
||||
return false;
|
||||
|
||||
const PCB_TABLE& other = static_cast<const PCB_TABLE&>( aOther );
|
||||
|
||||
if( m_cells.size() != other.m_cells.size() )
|
||||
return false;
|
||||
|
||||
if( m_colWidths != other.m_colWidths )
|
||||
return false;
|
||||
|
||||
if( m_rowHeights != other.m_rowHeights )
|
||||
return false;
|
||||
|
||||
for( int ii = 0; ii < (int) m_cells.size(); ++ii )
|
||||
{
|
||||
if( !( *m_cells[ii] == *other.m_cells[ii] ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
double PCB_TABLE::Similarity( const BOARD_ITEM& aOther ) const
|
||||
{
|
||||
if( aOther.Type() != Type() )
|
||||
return 0.0;
|
||||
|
||||
const PCB_TABLE& other = static_cast<const PCB_TABLE&>( aOther );
|
||||
|
||||
if( m_cells.size() != other.m_cells.size() )
|
||||
return 0.1;
|
||||
|
||||
double similarity = 1.0;
|
||||
|
||||
for( int ii = 0; ii < (int) m_cells.size(); ++ii )
|
||||
similarity *= m_cells[ii]->Similarity( *other.m_cells[ii] );
|
||||
|
||||
return similarity;
|
||||
}
|
||||
|
||||
|
||||
static struct PCB_TABLE_DESC
|
||||
{
|
||||
PCB_TABLE_DESC()
|
||||
{
|
||||
ENUM_MAP<LINE_STYLE>& plotDashTypeEnum = ENUM_MAP<LINE_STYLE>::Instance();
|
||||
|
||||
if( plotDashTypeEnum.Choices().GetCount() == 0 )
|
||||
{
|
||||
plotDashTypeEnum.Map( LINE_STYLE::DEFAULT, _HKI( "Default" ) )
|
||||
.Map( LINE_STYLE::SOLID, _HKI( "Solid" ) )
|
||||
.Map( LINE_STYLE::DASH, _HKI( "Dashed" ) )
|
||||
.Map( LINE_STYLE::DOT, _HKI( "Dotted" ) )
|
||||
.Map( LINE_STYLE::DASHDOT, _HKI( "Dash-Dot" ) )
|
||||
.Map( LINE_STYLE::DASHDOTDOT, _HKI( "Dash-Dot-Dot" ) );
|
||||
}
|
||||
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( PCB_TABLE );
|
||||
|
||||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TABLE, BOARD_ITEM> );
|
||||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TABLE, BOARD_ITEM_CONTAINER> );
|
||||
propMgr.InheritsAfter( TYPE_HASH( PCB_TABLE ), TYPE_HASH( BOARD_ITEM ) );
|
||||
propMgr.InheritsAfter( TYPE_HASH( PCB_TABLE ), TYPE_HASH( BOARD_ITEM_CONTAINER ) );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Start X" ),
|
||||
&PCB_TABLE::SetPositionX, &PCB_TABLE::GetPositionX, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_X_COORD ) );
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Start Y" ),
|
||||
&PCB_TABLE::SetPositionY, &PCB_TABLE::GetPositionY, PROPERTY_DISPLAY::PT_COORD,
|
||||
ORIGIN_TRANSFORMS::ABS_Y_COORD ) );
|
||||
|
||||
const wxString tableProps = _( "Table Properties" );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "External Border" ),
|
||||
&PCB_TABLE::SetStrokeExternal, &PCB_TABLE::StrokeExternal ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Header Border" ),
|
||||
&PCB_TABLE::SetStrokeHeader, &PCB_TABLE::StrokeHeader ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Border Width" ),
|
||||
&PCB_TABLE::SetBorderWidth, &PCB_TABLE::GetBorderWidth,
|
||||
PROPERTY_DISPLAY::PT_SIZE ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_TABLE, LINE_STYLE>( _HKI( "Border Style" ),
|
||||
&PCB_TABLE::SetBorderStyle, &PCB_TABLE::GetBorderStyle ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, COLOR4D>( _HKI( "Border Color" ),
|
||||
&PCB_TABLE::SetBorderColor, &PCB_TABLE::GetBorderColor ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Row Separators" ),
|
||||
&PCB_TABLE::SetStrokeRows, &PCB_TABLE::StrokeRows ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, bool>( _HKI( "Cell Separators" ),
|
||||
&PCB_TABLE::SetStrokeColumns, &PCB_TABLE::StrokeColumns ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, int>( _HKI( "Separators Width" ),
|
||||
&PCB_TABLE::SetSeparatorsWidth, &PCB_TABLE::GetSeparatorsWidth,
|
||||
PROPERTY_DISPLAY::PT_SIZE ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY_ENUM<PCB_TABLE, LINE_STYLE>( _HKI( "Separators Style" ),
|
||||
&PCB_TABLE::SetSeparatorsStyle, &PCB_TABLE::GetSeparatorsStyle ),
|
||||
tableProps );
|
||||
|
||||
propMgr.AddProperty( new PROPERTY<PCB_TABLE, COLOR4D>( _HKI( "Separators Color" ),
|
||||
&PCB_TABLE::SetSeparatorsColor, &PCB_TABLE::GetSeparatorsColor ),
|
||||
tableProps );
|
||||
}
|
||||
} _PCB_TABLE_DESC;
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#ifndef PCB_TABLE_H
|
||||
#define PCB_TABLE_H
|
||||
|
||||
|
||||
#include <pcb_tablecell.h>
|
||||
#include <board_item.h>
|
||||
|
||||
|
||||
class PCB_TABLE : public BOARD_ITEM_CONTAINER
|
||||
{
|
||||
public:
|
||||
PCB_TABLE( BOARD_ITEM* aParent, int aLineWidth );
|
||||
|
||||
PCB_TABLE( const PCB_TABLE& aTable );
|
||||
|
||||
~PCB_TABLE();
|
||||
|
||||
static inline bool ClassOf( const EDA_ITEM* aItem )
|
||||
{
|
||||
return aItem && PCB_TABLE_T == aItem->Type();
|
||||
}
|
||||
|
||||
virtual wxString GetClass() const override
|
||||
{
|
||||
return wxT( "PCB_TABLE" );
|
||||
}
|
||||
|
||||
void SetStrokeExternal( bool aDoStroke ) { m_strokeExternal = aDoStroke; }
|
||||
bool StrokeExternal() const { return m_strokeExternal; }
|
||||
|
||||
void SetStrokeHeader( bool aDoStroke ) { m_strokeHeader = aDoStroke; }
|
||||
bool StrokeHeader() const { return m_strokeHeader; }
|
||||
|
||||
void SetBorderStroke( const STROKE_PARAMS& aParams ) { m_borderStroke = aParams; }
|
||||
const STROKE_PARAMS& GetBorderStroke() const { return m_borderStroke; }
|
||||
|
||||
void SetBorderWidth( int aWidth ) { m_borderStroke.SetWidth( aWidth ); }
|
||||
int GetBorderWidth() const { return m_borderStroke.GetWidth(); }
|
||||
|
||||
void SetBorderStyle( const LINE_STYLE aStyle ) { m_borderStroke.SetLineStyle( aStyle ); }
|
||||
LINE_STYLE GetBorderStyle() const { return m_borderStroke.GetLineStyle(); }
|
||||
|
||||
void SetBorderColor( const COLOR4D& aColor ) { m_borderStroke.SetColor( aColor ); }
|
||||
COLOR4D GetBorderColor() const { return m_borderStroke.GetColor(); }
|
||||
|
||||
void SetSeparatorsStroke( const STROKE_PARAMS& aParams ) { m_separatorsStroke = aParams; }
|
||||
const STROKE_PARAMS& GetSeparatorsStroke() const { return m_separatorsStroke; }
|
||||
|
||||
void SetSeparatorsWidth( int aWidth ) { m_separatorsStroke.SetWidth( aWidth ); }
|
||||
int GetSeparatorsWidth() const { return m_separatorsStroke.GetWidth(); }
|
||||
|
||||
void SetSeparatorsStyle( const LINE_STYLE aStyle ) { m_separatorsStroke.SetLineStyle( aStyle ); }
|
||||
LINE_STYLE GetSeparatorsStyle() const { return m_separatorsStroke.GetLineStyle(); }
|
||||
|
||||
void SetSeparatorsColor( const COLOR4D& aColor ) { m_separatorsStroke.SetColor( aColor ); }
|
||||
COLOR4D GetSeparatorsColor() const { return m_separatorsStroke.GetColor(); }
|
||||
|
||||
void SetStrokeColumns( bool aDoStroke ) { m_strokeColumns = aDoStroke; }
|
||||
bool StrokeColumns() const { return m_strokeColumns; }
|
||||
|
||||
void SetStrokeRows( bool aDoStroke ) { m_strokeRows = aDoStroke; }
|
||||
bool StrokeRows() const { return m_strokeRows; }
|
||||
|
||||
void RunOnChildren( const std::function<void( BOARD_ITEM* )>& aFunction ) const override;
|
||||
|
||||
void SetPosition( const VECTOR2I& aPos ) override;
|
||||
VECTOR2I GetPosition() const override;
|
||||
VECTOR2I GetEnd() const;
|
||||
|
||||
// For property manager:
|
||||
void SetPositionX( int x ) { SetPosition( VECTOR2I( x, GetPosition().y ) ); }
|
||||
void SetPositionY( int y ) { SetPosition( VECTOR2I( GetPosition().x, y ) ); }
|
||||
int GetPositionX() const { return GetPosition().x; }
|
||||
int GetPositionY() const { return GetPosition().y; }
|
||||
|
||||
void SetColCount( int aCount ) { m_colCount = aCount; }
|
||||
int GetColCount() const { return m_colCount; }
|
||||
|
||||
int GetRowCount() const
|
||||
{
|
||||
return m_cells.size() / m_colCount;
|
||||
}
|
||||
|
||||
void SetColWidth( int aCol, int aWidth ) { m_colWidths[aCol] = aWidth; }
|
||||
|
||||
int GetColWidth( int aCol ) const
|
||||
{
|
||||
if( m_colWidths.count( aCol ) )
|
||||
return m_colWidths.at( aCol );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetRowHeight( int aRow, int aHeight ) { m_rowHeights[aRow] = aHeight; }
|
||||
|
||||
int GetRowHeight( int aRow ) const
|
||||
{
|
||||
if( m_rowHeights.count( aRow ) )
|
||||
return m_rowHeights.at( aRow );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PCB_TABLECELL* GetCell( int aRow, int aCol ) const
|
||||
{
|
||||
int idx = aRow * m_colCount + aCol;
|
||||
|
||||
if( idx < (int) m_cells.size() )
|
||||
return m_cells[ idx ];
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<PCB_TABLECELL*> GetCells() const
|
||||
{
|
||||
return m_cells;
|
||||
}
|
||||
|
||||
void AddCell( PCB_TABLECELL* aCell )
|
||||
{
|
||||
m_cells.push_back( aCell );
|
||||
aCell->SetLayer( GetLayer() );
|
||||
aCell->SetParent( this );
|
||||
}
|
||||
|
||||
void InsertCell( int aIdx, PCB_TABLECELL* aCell )
|
||||
{
|
||||
m_cells.insert( m_cells.begin() + aIdx, aCell );
|
||||
aCell->SetLayer( GetLayer() );
|
||||
aCell->SetParent( this );
|
||||
}
|
||||
|
||||
void ClearCells()
|
||||
{
|
||||
for( PCB_TABLECELL* cell : m_cells )
|
||||
delete cell;
|
||||
|
||||
m_cells.clear();
|
||||
}
|
||||
|
||||
void DeleteMarkedCells()
|
||||
{
|
||||
alg::delete_if( m_cells,
|
||||
[]( PCB_TABLECELL* cell )
|
||||
{
|
||||
return ( cell->GetFlags() & STRUCT_DELETED ) > 0;
|
||||
} );
|
||||
}
|
||||
|
||||
void Add( BOARD_ITEM* aItem, ADD_MODE aMode = ADD_MODE::INSERT,
|
||||
bool aSkipConnectivity = false ) override
|
||||
{
|
||||
wxFAIL_MSG( wxT( "Use AddCell()/InsertCell() instead." ) );
|
||||
}
|
||||
|
||||
void Remove( BOARD_ITEM* aItem, REMOVE_MODE aMode = REMOVE_MODE::NORMAL ) override
|
||||
{
|
||||
wxFAIL_MSG( wxT( "Use DeleteMarkedCells() instead." ) );
|
||||
}
|
||||
|
||||
void Normalize() override;
|
||||
|
||||
void Move( const VECTOR2I& aMoveVector ) override;
|
||||
|
||||
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
|
||||
|
||||
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
|
||||
|
||||
const BOX2I GetBoundingBox() const override;
|
||||
|
||||
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
||||
int aMaxError, ERROR_LOC aErrorLoc,
|
||||
bool aIgnoreLineWidth = false ) const override;
|
||||
|
||||
INSPECT_RESULT Visit( INSPECTOR inspector, void* testData,
|
||||
const std::vector<KICAD_T>& aScanTypes ) override;
|
||||
|
||||
bool Matches( const EDA_SEARCH_DATA& aSearchData, void* aAuxData ) const override
|
||||
{
|
||||
// Symbols are searchable via the child field and pin item text.
|
||||
return false;
|
||||
}
|
||||
|
||||
wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
|
||||
|
||||
BITMAPS GetMenuImage() const override;
|
||||
|
||||
bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
|
||||
|
||||
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
|
||||
|
||||
EDA_ITEM* Clone() const override
|
||||
{
|
||||
return new PCB_TABLE( *this );
|
||||
}
|
||||
|
||||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
double Similarity( const BOARD_ITEM& aOther ) const override;
|
||||
|
||||
bool operator==( const BOARD_ITEM& aOther ) const override;
|
||||
|
||||
static int Compare( const PCB_TABLE* aTable, const PCB_TABLE* aOther );
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual void swapData( BOARD_ITEM* aImage ) override;
|
||||
|
||||
protected:
|
||||
bool m_strokeExternal;
|
||||
bool m_strokeHeader;
|
||||
STROKE_PARAMS m_borderStroke;
|
||||
bool m_strokeRows;
|
||||
bool m_strokeColumns;
|
||||
STROKE_PARAMS m_separatorsStroke;
|
||||
|
||||
int m_colCount;
|
||||
std::map<int, int> m_colWidths;
|
||||
std::map<int, int> m_rowHeights;
|
||||
std::vector<PCB_TABLECELL*> m_cells;
|
||||
};
|
||||
|
||||
|
||||
#endif /* PCB_TABLE_H */
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <font/font.h>
|
||||
#include <widgets/msgpanel.h>
|
||||
#include <string_utils.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_tablecell.h>
|
||||
|
||||
|
||||
PCB_TABLECELL::PCB_TABLECELL( BOARD_ITEM* aParent ) :
|
||||
PCB_TEXTBOX( aParent, PCB_TABLECELL_T ),
|
||||
m_colSpan( 1 ),
|
||||
m_rowSpan( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLECELL::swapData( BOARD_ITEM* aImage )
|
||||
{
|
||||
wxASSERT( aImage->Type() == PCB_TABLECELL_T );
|
||||
|
||||
std::swap( *((PCB_TABLECELL*) this), *((PCB_TABLECELL*) aImage) );
|
||||
}
|
||||
|
||||
|
||||
wxString PCB_TABLECELL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||
{
|
||||
return wxString::Format( _( "Table Cell %s" ), GetAddr() );
|
||||
}
|
||||
|
||||
|
||||
int PCB_TABLECELL::GetRow() const
|
||||
{
|
||||
const PCB_TABLE* table = static_cast<const PCB_TABLE*>( GetParent() );
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
if( table->GetCell( row, col ) == this )
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int PCB_TABLECELL::GetColumn() const
|
||||
{
|
||||
const PCB_TABLE* table = static_cast<const PCB_TABLE*>( GetParent() );
|
||||
|
||||
for( int row = 0; row < table->GetRowCount(); ++row )
|
||||
{
|
||||
for( int col = 0; col < table->GetColCount(); ++col )
|
||||
{
|
||||
if( table->GetCell( row, col ) == this )
|
||||
return col;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
wxString PCB_TABLECELL::GetAddr() const
|
||||
{
|
||||
return wxString::Format( wxT( "%c%d" ),
|
||||
'A' + GetColumn() % 26,
|
||||
GetRow() + 1 );
|
||||
}
|
||||
|
||||
|
||||
void PCB_TABLECELL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
aList.emplace_back( _( "Table Cell" ), GetAddr() );
|
||||
|
||||
// Don't use GetShownText() here; we want to show the user the variable references
|
||||
aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
|
||||
|
||||
if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
|
||||
aList.emplace_back( _( "Status" ), _( "Locked" ) );
|
||||
|
||||
aList.emplace_back( _( "Layer" ), GetLayerName() );
|
||||
aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) );
|
||||
|
||||
aList.emplace_back( _( "Cell Width" ),
|
||||
aFrame->MessageTextFromValue( std::abs( GetEnd().x - GetStart().x ) ) );
|
||||
aList.emplace_back( _( "Cell Height" ),
|
||||
aFrame->MessageTextFromValue( std::abs( GetEnd().y - GetStart().y ) ) );
|
||||
|
||||
aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
|
||||
aList.emplace_back( _( "Text Thickness" ), aFrame->MessageTextFromValue( GetTextThickness() ) );
|
||||
aList.emplace_back( _( "Text Width" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
|
||||
aList.emplace_back( _( "Text Height" ), aFrame->MessageTextFromValue( GetTextHeight() ) );
|
||||
}
|
||||
|
||||
|
||||
double PCB_TABLECELL::Similarity( const BOARD_ITEM& aBoardItem ) const
|
||||
{
|
||||
if( aBoardItem.Type() != Type() )
|
||||
return 0.0;
|
||||
|
||||
const PCB_TABLECELL& other = static_cast<const PCB_TABLECELL&>( aBoardItem );
|
||||
|
||||
double similarity = 1.0;
|
||||
|
||||
if( m_colSpan != other.m_colSpan )
|
||||
similarity *= 0.9;
|
||||
|
||||
if( m_rowSpan != other.m_rowSpan )
|
||||
similarity *= 0.9;
|
||||
|
||||
similarity *= PCB_TEXTBOX::Similarity( other );
|
||||
|
||||
return similarity;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_TABLECELL::operator==( const BOARD_ITEM& aBoardItem ) const
|
||||
{
|
||||
if( aBoardItem.Type() != Type() )
|
||||
return false;
|
||||
|
||||
const PCB_TABLECELL& other = static_cast<const PCB_TABLECELL&>( aBoardItem );
|
||||
|
||||
return m_colSpan == other.m_colSpan
|
||||
&& m_rowSpan == other.m_rowSpan
|
||||
&& PCB_TEXTBOX::operator==( other );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct PCB_TABLECELL_DESC
|
||||
{
|
||||
PCB_TABLECELL_DESC()
|
||||
{
|
||||
PROPERTY_MANAGER& propMgr = PROPERTY_MANAGER::Instance();
|
||||
REGISTER_TYPE( PCB_TABLECELL );
|
||||
|
||||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TABLECELL, PCB_TEXTBOX> );
|
||||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TABLECELL, PCB_SHAPE> );
|
||||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TABLECELL, EDA_SHAPE> );
|
||||
propMgr.AddTypeCast( new TYPE_CAST<PCB_TABLECELL, EDA_TEXT> );
|
||||
propMgr.InheritsAfter( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ) );
|
||||
propMgr.InheritsAfter( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_SHAPE ) );
|
||||
propMgr.InheritsAfter( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ) );
|
||||
propMgr.InheritsAfter( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border Style" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border Width" ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "End X" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "End Y" ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Shape" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Width" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Style" ) );
|
||||
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Visible" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Width" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Height" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Thickness" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
|
||||
propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
|
||||
}
|
||||
} _PCB_TABLECELL_DESC;
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#ifndef PCB_TABLECELL_H
|
||||
#define PCB_TABLECELL_H
|
||||
|
||||
|
||||
#include <pcb_textbox.h>
|
||||
|
||||
|
||||
class PCB_TABLECELL : public PCB_TEXTBOX
|
||||
{
|
||||
public:
|
||||
PCB_TABLECELL( BOARD_ITEM* parent );
|
||||
|
||||
static inline bool ClassOf( const EDA_ITEM* aItem )
|
||||
{
|
||||
return aItem && PCB_TABLECELL_T == aItem->Type();
|
||||
}
|
||||
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return wxT( "PCB_TABLECELL" );
|
||||
}
|
||||
|
||||
virtual wxString GetFriendlyName() const override
|
||||
{
|
||||
return _( "Table Cell" );
|
||||
}
|
||||
|
||||
EDA_ITEM* Clone() const override
|
||||
{
|
||||
return new PCB_TABLECELL( *this );
|
||||
}
|
||||
|
||||
int GetRow() const;
|
||||
int GetColumn() const;
|
||||
|
||||
// @return the spreadsheet nomenclature for the cell (ie: B3 for 2nd column, 3rd row)
|
||||
wxString GetAddr() const;
|
||||
|
||||
int GetColSpan() const { return m_colSpan; }
|
||||
void SetColSpan( int aSpan ) { m_colSpan = aSpan; }
|
||||
|
||||
int GetRowSpan() const { return m_rowSpan; }
|
||||
void SetRowSpan( int aSpan ) { m_rowSpan = aSpan; }
|
||||
|
||||
wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
|
||||
|
||||
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
||||
|
||||
double Similarity( const BOARD_ITEM& aBoardItem ) const override;
|
||||
|
||||
bool operator==( const BOARD_ITEM& aBoardItem ) const override;
|
||||
|
||||
protected:
|
||||
virtual void swapData( BOARD_ITEM* aImage ) override;
|
||||
|
||||
protected:
|
||||
int m_colSpan;
|
||||
int m_rowSpan;
|
||||
};
|
||||
|
||||
|
||||
#endif /* PCB_TABLECELL_H */
|
|
@ -38,8 +38,8 @@
|
|||
#include <core/ignore.h>
|
||||
|
||||
|
||||
PCB_TEXTBOX::PCB_TEXTBOX( BOARD_ITEM* parent ) :
|
||||
PCB_SHAPE( parent, PCB_TEXTBOX_T, SHAPE_T::RECTANGLE ),
|
||||
PCB_TEXTBOX::PCB_TEXTBOX( BOARD_ITEM* aParent, KICAD_T aType ) :
|
||||
PCB_SHAPE( aParent, aType, SHAPE_T::RECTANGLE ),
|
||||
EDA_TEXT( pcbIUScale ),
|
||||
m_borderEnabled( true )
|
||||
{
|
||||
|
@ -485,7 +485,7 @@ EDA_ITEM* PCB_TEXTBOX::Clone() const
|
|||
|
||||
void PCB_TEXTBOX::swapData( BOARD_ITEM* aImage )
|
||||
{
|
||||
assert( aImage->Type() == PCB_TEXTBOX_T );
|
||||
wxASSERT( aImage->Type() == PCB_TEXTBOX_T );
|
||||
|
||||
std::swap( *((PCB_TEXTBOX*) this), *((PCB_TEXTBOX*) aImage) );
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ class MSG_PANEL_ITEM;
|
|||
class PCB_TEXTBOX : public PCB_SHAPE, public EDA_TEXT
|
||||
{
|
||||
public:
|
||||
PCB_TEXTBOX( BOARD_ITEM* parent );
|
||||
PCB_TEXTBOX( BOARD_ITEM* aParent, KICAD_T aType = PCB_TEXTBOX_T );
|
||||
|
||||
// Do not create a copy constructor & operator=.
|
||||
// The ones generated by the compiler are adequate.
|
||||
|
|
|
@ -76,11 +76,18 @@ void PCB_VIEW::Update( const KIGFX::VIEW_ITEM* aItem, int aUpdateFlags ) const
|
|||
{
|
||||
if( const BOARD_ITEM* boardItem = dynamic_cast<const BOARD_ITEM*>( aItem ) )
|
||||
{
|
||||
boardItem->RunOnChildren(
|
||||
[this, aUpdateFlags]( BOARD_ITEM* child )
|
||||
{
|
||||
VIEW::Update( child, aUpdateFlags );
|
||||
} );
|
||||
if( boardItem->Type() == PCB_TABLECELL_T )
|
||||
{
|
||||
VIEW::Update( boardItem->GetParent() );
|
||||
}
|
||||
else
|
||||
{
|
||||
boardItem->RunOnChildren(
|
||||
[this, aUpdateFlags]( BOARD_ITEM* child )
|
||||
{
|
||||
VIEW::Update( child, aUpdateFlags );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
VIEW::Update( aItem, aUpdateFlags );
|
||||
|
|
|
@ -187,6 +187,7 @@ void FOOTPRINT_EDIT_FRAME::ReCreateVToolbar()
|
|||
m_drawToolBar->Add( PCB_ACTIONS::placeReferenceImage, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawTable, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( ACTIONS::deleteTool, ACTION_TOOLBAR::TOGGLE );
|
||||
|
||||
|
|
|
@ -441,6 +441,7 @@ void PCB_EDIT_FRAME::ReCreateVToolbar()
|
|||
m_drawToolBar->Add( PCB_ACTIONS::placeReferenceImage, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::placeText, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawTextBox, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( PCB_ACTIONS::drawTable, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->AddGroup( dimensionGroup, ACTION_TOOLBAR::TOGGLE );
|
||||
m_drawToolBar->Add( ACTIONS::deleteTool, ACTION_TOOLBAR::TOGGLE );
|
||||
|
||||
|
|
|
@ -66,6 +66,8 @@
|
|||
#include <pcb_reference_image.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pcbnew_id.h>
|
||||
#include <preview_items/arc_assistant.h>
|
||||
|
@ -562,6 +564,7 @@ int DRAWING_TOOL::PlaceReferenceImage( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
m_frame->PushTool( aEvent );
|
||||
|
||||
auto setCursor =
|
||||
[&]()
|
||||
{
|
||||
|
@ -796,6 +799,15 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::TEXT );
|
||||
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
||||
|
||||
auto setCursor =
|
||||
[&]()
|
||||
{
|
||||
if( text )
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
|
||||
else
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::TEXT );
|
||||
};
|
||||
|
||||
auto cleanup =
|
||||
[&]()
|
||||
{
|
||||
|
@ -808,15 +820,6 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
text = nullptr;
|
||||
};
|
||||
|
||||
auto setCursor =
|
||||
[&]()
|
||||
{
|
||||
if( text )
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
|
||||
else
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::TEXT );
|
||||
};
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
|
||||
m_frame->PushTool( aEvent );
|
||||
|
@ -1026,6 +1029,218 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
int DRAWING_TOOL::DrawTable( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
if( m_inDrawingTool )
|
||||
return 0;
|
||||
|
||||
REENTRANCY_GUARD guard( &m_inDrawingTool );
|
||||
|
||||
COMMON_SETTINGS* common_settings = Pgm().GetCommonSettings();
|
||||
PCB_TABLE* table = nullptr;
|
||||
const BOARD_DESIGN_SETTINGS& bds = m_frame->GetDesignSettings();
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
||||
|
||||
// We might be running as the same shape in another co-routine. Make sure that one
|
||||
// gets whacked.
|
||||
m_toolMgr->DeactivateTool();
|
||||
|
||||
auto setCursor =
|
||||
[&]()
|
||||
{
|
||||
if( table )
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::MOVING );
|
||||
else
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
|
||||
};
|
||||
|
||||
auto cleanup =
|
||||
[&] ()
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
m_controls->ForceCursorPosition( false );
|
||||
m_controls->ShowCursor( true );
|
||||
m_controls->SetAutoPan( false );
|
||||
m_controls->CaptureCursor( false );
|
||||
delete table;
|
||||
table = nullptr;
|
||||
};
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
|
||||
m_frame->PushTool( aEvent );
|
||||
|
||||
Activate();
|
||||
// Must be done after Activate() so that it gets set into the correct context
|
||||
getViewControls()->ShowCursor( true );
|
||||
m_controls->ForceCursorPosition( false );
|
||||
// Set initial cursor
|
||||
setCursor();
|
||||
|
||||
if( aEvent.HasPosition() )
|
||||
m_toolMgr->PrimeTool( aEvent.Position() );
|
||||
else if( common_settings->m_Input.immediate_actions && !aEvent.IsReactivate() )
|
||||
m_toolMgr->PrimeTool( { 0, 0 } );
|
||||
|
||||
// Main loop: keep receiving events
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
setCursor();
|
||||
grid.SetSnap( !evt->Modifier( MD_SHIFT ) );
|
||||
grid.SetUseGrid( getView()->GetGAL()->GetGridSnapping() && !evt->DisableGridSnapping() );
|
||||
VECTOR2I cursorPos =
|
||||
GetClampedCoords( grid.BestSnapAnchor( m_controls->GetMousePosition(),
|
||||
m_frame->GetActiveLayer(), GRID_TEXT ),
|
||||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || ( table && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
if( table )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->PopTool( aEvent );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( evt->IsActivate() )
|
||||
{
|
||||
if( table )
|
||||
cleanup();
|
||||
|
||||
if( evt->IsMoveTool() )
|
||||
{
|
||||
// leave ourselves on the stack so we come back after the move
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->PopTool( aEvent );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( evt->IsClick( BUT_RIGHT ) )
|
||||
{
|
||||
// Warp after context menu only if dragging...
|
||||
if( !table )
|
||||
m_toolMgr->VetoContextMenuMouseWarp();
|
||||
|
||||
m_menu.ShowContextMenu( selection() );
|
||||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
if( !table )
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
|
||||
PCB_LAYER_ID layer = m_frame->GetActiveLayer();
|
||||
|
||||
table = new PCB_TABLE( m_frame->GetModel(), bds.GetLineThickness( layer ) );
|
||||
table->SetColCount( 1 );
|
||||
table->AddCell( new PCB_TABLECELL( table ) );
|
||||
|
||||
table->SetLayer( layer );
|
||||
table->SetPosition( cursorPos );
|
||||
|
||||
if( !m_view->IsLayerVisible( layer ) )
|
||||
{
|
||||
m_frame->GetAppearancePanel()->SetLayerVisible( layer, true );
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, table );
|
||||
m_view->Update( &selection() );
|
||||
|
||||
// update the cursor so it looks correct before another event
|
||||
setCursor();
|
||||
}
|
||||
else
|
||||
{
|
||||
table->ClearFlags();
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
|
||||
table->Normalize();
|
||||
|
||||
commit.Add( table, m_frame->GetScreen() );
|
||||
commit.Push( _( "Draw Table" ) );
|
||||
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, table );
|
||||
table = nullptr;
|
||||
|
||||
m_toolMgr->PostAction( ACTIONS::activatePointEditor );
|
||||
}
|
||||
}
|
||||
else if( table && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
||||
{
|
||||
VECTOR2I fontSize = bds.GetTextSize( table->GetLayer() );
|
||||
VECTOR2I gridSize = grid.GetGridSize( grid.GetItemGrid( table ) );
|
||||
VECTOR2I origin( table->GetPosition() );
|
||||
VECTOR2I requestedSize( cursorPos - origin );
|
||||
|
||||
int colCount = std::max( 1, requestedSize.x / ( fontSize.x * 15 ) );
|
||||
int rowCount = std::max( 1, requestedSize.y / ( fontSize.y * 3 ) );
|
||||
|
||||
VECTOR2I cellSize( std::max( fontSize.x * 5, requestedSize.x / colCount ),
|
||||
std::max( fontSize.y * 3, requestedSize.y / rowCount ) );
|
||||
|
||||
cellSize.x = KiROUND( (double) cellSize.x / gridSize.x ) * gridSize.x;
|
||||
cellSize.y = KiROUND( (double) cellSize.y / gridSize.y ) * gridSize.y;
|
||||
|
||||
table->ClearCells();
|
||||
table->SetColCount( colCount );
|
||||
|
||||
for( int col = 0; col < colCount; ++col )
|
||||
table->SetColWidth( col, cellSize.x );
|
||||
|
||||
for( int row = 0; row < rowCount; ++row )
|
||||
{
|
||||
table->SetRowHeight( row, cellSize.y );
|
||||
|
||||
for( int col = 0; col < colCount; ++col )
|
||||
{
|
||||
PCB_TABLECELL* cell = new PCB_TABLECELL( table );
|
||||
cell->SetPosition( origin + VECTOR2I( col * cellSize.x, row * cellSize.y ) );
|
||||
cell->SetEnd( cell->GetPosition() + cellSize );
|
||||
table->AddCell( cell );
|
||||
}
|
||||
}
|
||||
|
||||
selection().SetReferencePoint( cursorPos );
|
||||
m_view->Update( &selection() );
|
||||
m_frame->SetMsgPanel( table );
|
||||
}
|
||||
else if( table && evt->IsAction( &PCB_ACTIONS::properties ) )
|
||||
{
|
||||
frame()->OnEditItemRequest( table );
|
||||
m_view->Update( &selection() );
|
||||
frame()->SetMsgPanel( table );
|
||||
}
|
||||
else if( table && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
|
||||
// Enable autopanning and cursor capture only when there is a shape being drawn
|
||||
getViewControls()->SetAutoPan( table != nullptr );
|
||||
getViewControls()->CaptureCursor( table != nullptr );
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
getViewControls()->CaptureCursor( false );
|
||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::ARROW );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void DRAWING_TOOL::constrainDimension( PCB_DIMENSION_BASE* aDim )
|
||||
{
|
||||
const VECTOR2I lineVector{ aDim->GetEnd() - aDim->GetStart() };
|
||||
|
@ -3457,6 +3672,7 @@ void DRAWING_TOOL::setTransitions()
|
|||
Go( &DRAWING_TOOL::DrawVia, PCB_ACTIONS::drawVia.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceReferenceImage, PCB_ACTIONS::placeReferenceImage.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceText, PCB_ACTIONS::placeText.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawTable, PCB_ACTIONS::drawTable.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::DrawRectangle, PCB_ACTIONS::drawTextBox.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::PlaceImportedGraphics, PCB_ACTIONS::placeImportedGraphics.MakeEvent() );
|
||||
Go( &DRAWING_TOOL::SetAnchor, PCB_ACTIONS::setAnchor.MakeEvent() );
|
||||
|
|
|
@ -157,6 +157,11 @@ public:
|
|||
*/
|
||||
int PlaceText( const TOOL_EVENT& aEvent );
|
||||
|
||||
/*
|
||||
* Start interactively drawing a table (rows & columns of TEXTBOXes).
|
||||
*/
|
||||
int DrawTable( const TOOL_EVENT& aEvent );
|
||||
|
||||
/**
|
||||
* Start interactively drawing a dimension.
|
||||
*
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <pcb_target.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_generator.h>
|
||||
#include <collectors.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
|
@ -1733,6 +1734,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
sTool->FilterCollectorForHierarchy( aCollector, true );
|
||||
sTool->FilterCollectorForMarkers( aCollector );
|
||||
sTool->FilterCollectorForTableCells( aCollector );
|
||||
},
|
||||
// Prompt user regarding locked items if in board editor and in free-pad-mode (if
|
||||
// we're not in free-pad mode we delay this until the second RequestSelection()).
|
||||
|
@ -1758,6 +1760,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
sTool->FilterCollectorForMarkers( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector, true );
|
||||
sTool->FilterCollectorForFreePads( aCollector );
|
||||
sTool->FilterCollectorForTableCells( aCollector );
|
||||
},
|
||||
true /* prompt user regarding locked items */ );
|
||||
}
|
||||
|
@ -1997,6 +2000,10 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
static_cast<PCB_TEXTBOX*>( item )->Mirror( mirrorPoint, mirrorAroundXaxis );
|
||||
break;
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
break;
|
||||
|
||||
case PCB_PAD_T:
|
||||
if( mirrorLeftRight )
|
||||
mirrorPadX( *static_cast<PAD*>( item ), mirrorPoint );
|
||||
|
@ -2129,6 +2136,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
|||
sTool->FilterCollectorForMarkers( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector, true );
|
||||
sTool->FilterCollectorForFreePads( aCollector );
|
||||
sTool->FilterCollectorForTableCells( aCollector );
|
||||
},
|
||||
!m_dragging /* prompt user regarding locked items */ );
|
||||
|
||||
|
@ -2215,6 +2223,7 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
|
|||
case PCB_TEXT_T:
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_REFERENCE_IMAGE_T:
|
||||
case PCB_DIMENSION_T:
|
||||
case PCB_DIM_ALIGNED_T:
|
||||
|
@ -2225,6 +2234,12 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
|
|||
commit.Remove( board_item );
|
||||
break;
|
||||
|
||||
case PCB_TABLECELL_T:
|
||||
// Clear contents of table cell
|
||||
commit.Modify( board_item );
|
||||
static_cast<PCB_TABLECELL*>( board_item )->SetText( wxEmptyString );
|
||||
break;
|
||||
|
||||
case PCB_GROUP_T:
|
||||
board_item->RunOnDescendants(
|
||||
[&commit]( BOARD_ITEM* aItem )
|
||||
|
@ -2415,6 +2430,7 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
sTool->FilterCollectorForMarkers( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector, true );
|
||||
sTool->FilterCollectorForTableCells( aCollector );
|
||||
},
|
||||
true /* prompt user regarding locked items */ );
|
||||
|
||||
|
@ -2509,6 +2525,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
sTool->FilterCollectorForFreePads( aCollector, true );
|
||||
sTool->FilterCollectorForMarkers( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector, true );
|
||||
sTool->FilterCollectorForTableCells( aCollector );
|
||||
} );
|
||||
|
||||
if( selection.Empty() )
|
||||
|
@ -2599,6 +2616,10 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
|
|||
commit.Add( dupe_item );
|
||||
break;
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
break;
|
||||
|
||||
case PCB_GENERATOR_T:
|
||||
case PCB_GROUP_T:
|
||||
dupe_item = static_cast<PCB_GROUP*>( orig_item )->DeepDuplicate();
|
||||
|
|
|
@ -299,6 +299,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
|
|||
sTool->FilterCollectorForMarkers( aCollector );
|
||||
sTool->FilterCollectorForHierarchy( aCollector, true );
|
||||
sTool->FilterCollectorForFreePads( aCollector );
|
||||
sTool->FilterCollectorForTableCells( aCollector );
|
||||
},
|
||||
true /* prompt user regarding locked items */ );
|
||||
|
||||
|
|
|
@ -180,10 +180,18 @@ TOOL_ACTION PCB_ACTIONS::drawTextBox( TOOL_ACTION_ARGS()
|
|||
.Name( "pcbnew.InteractiveDrawing.textbox" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Text Box" ) )
|
||||
.Tooltip( _( "Add a wrapped text item" ) )
|
||||
.Tooltip( _( "Add a line-wrapped text item" ) )
|
||||
.Icon( BITMAPS::add_textbox )
|
||||
.Flags( AF_ACTIVATE ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::drawTable( TOOL_ACTION_ARGS()
|
||||
.Name( "pcbnew.InteractiveDrawing.drawTable" )
|
||||
.Scope( AS_GLOBAL )
|
||||
.FriendlyName( _( "Add Table" ) )
|
||||
.Tooltip( _( "Draw table" ) )
|
||||
.Icon( BITMAPS::spreadsheet ) // JEY TODO
|
||||
.Flags( AF_ACTIVATE ) );
|
||||
|
||||
TOOL_ACTION PCB_ACTIONS::spacingIncrease( TOOL_ACTION_ARGS()
|
||||
.Name( "pcbnew.lengthTuner.SpacingIncrease" )
|
||||
.Scope( AS_GLOBAL )
|
||||
|
|
|
@ -200,6 +200,7 @@ public:
|
|||
static TOOL_ACTION placeReferenceImage;
|
||||
static TOOL_ACTION placeText;
|
||||
static TOOL_ACTION drawTextBox;
|
||||
static TOOL_ACTION drawTable;
|
||||
static TOOL_ACTION spacingIncrease;
|
||||
static TOOL_ACTION spacingDecrease;
|
||||
static TOOL_ACTION amplIncrease;
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#include <tool/tool_manager.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <tools/pcb_actions.h>
|
||||
#include <collectors.h>
|
||||
#include <tools/pcb_edit_table_tool.h>
|
||||
|
||||
|
||||
PCB_EDIT_TABLE_TOOL::PCB_EDIT_TABLE_TOOL() :
|
||||
PCB_TOOL_BASE( "pcbnew.TableEditor" )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool PCB_EDIT_TABLE_TOOL::Init()
|
||||
{
|
||||
PCB_TOOL_BASE::Init();
|
||||
|
||||
addMenus( m_toolMgr->GetTool<PCB_SELECTION_TOOL>()->GetToolMenu().GetMenu() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
PCB_TABLECELL* PCB_EDIT_TABLE_TOOL::copyCell( PCB_TABLECELL* aSource )
|
||||
{
|
||||
PCB_TABLECELL* cell = new PCB_TABLECELL( aSource->GetParent() );
|
||||
|
||||
cell->SetEnd( aSource->GetEnd() - aSource->GetStart() );
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
const SELECTION& PCB_EDIT_TABLE_TOOL::getTableCellSelection()
|
||||
{
|
||||
PCB_SELECTION_TOOL* selTool = m_toolMgr->GetTool<PCB_SELECTION_TOOL>();
|
||||
|
||||
return selTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
|
||||
{
|
||||
// Iterate from the back so we don't have to worry about removals.
|
||||
for( int i = aCollector.GetCount() - 1; i >= 0; --i )
|
||||
{
|
||||
if( !dynamic_cast<PCB_TABLECELL*>( aCollector[ i ] ) )
|
||||
aCollector.Remove( aCollector[ i ] );
|
||||
}
|
||||
},
|
||||
false /* prompt user regarding locked items */ );
|
||||
}
|
||||
|
||||
|
||||
void PCB_EDIT_TABLE_TOOL::clearSelection()
|
||||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
};
|
||||
|
||||
|
||||
void PCB_EDIT_TABLE_TOOL::setTransitions()
|
||||
{
|
||||
Go( &PCB_EDIT_TABLE_TOOL::AddRowAbove, ACTIONS::addRowAbove.MakeEvent() );
|
||||
Go( &PCB_EDIT_TABLE_TOOL::AddRowBelow, ACTIONS::addRowBelow.MakeEvent() );
|
||||
|
||||
Go( &PCB_EDIT_TABLE_TOOL::AddColumnBefore, ACTIONS::addColBefore.MakeEvent() );
|
||||
Go( &PCB_EDIT_TABLE_TOOL::AddColumnAfter, ACTIONS::addColAfter.MakeEvent() );
|
||||
|
||||
Go( &PCB_EDIT_TABLE_TOOL::DeleteRows, ACTIONS::deleteRows.MakeEvent() );
|
||||
Go( &PCB_EDIT_TABLE_TOOL::DeleteColumns, ACTIONS::deleteColumns.MakeEvent() );
|
||||
|
||||
Go( &PCB_EDIT_TABLE_TOOL::MergeCells, ACTIONS::mergeCells.MakeEvent() );
|
||||
Go( &PCB_EDIT_TABLE_TOOL::UnmergeCells, ACTIONS::unmergeCells.MakeEvent() );
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 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
|
||||
*/
|
||||
|
||||
#ifndef PCB_EDIT_TABLE_TOOL_H
|
||||
#define PCB_EDIT_TABLE_TOOL_H
|
||||
|
||||
#include <tools/pcb_tool_base.h>
|
||||
#include <tool/edit_table_tool_base.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <board_commit.h>
|
||||
|
||||
|
||||
class PCB_EDIT_TABLE_TOOL : public PCB_TOOL_BASE,
|
||||
public EDIT_TABLE_TOOL_BASE<PCB_TABLE, PCB_TABLECELL, BOARD_COMMIT>
|
||||
{
|
||||
public:
|
||||
PCB_EDIT_TABLE_TOOL();
|
||||
~PCB_EDIT_TABLE_TOOL() override { }
|
||||
|
||||
/// @copydoc TOOL_INTERACTIVE::Init()
|
||||
bool Init() override;
|
||||
|
||||
int AddRowAbove( const TOOL_EVENT& aEvent ) { return doAddRowAbove( aEvent ); }
|
||||
int AddRowBelow( const TOOL_EVENT& aEvent ) { return doAddRowBelow( aEvent ); }
|
||||
int AddColumnBefore( const TOOL_EVENT& aEvent ) { return doAddColumnBefore( aEvent ); }
|
||||
int AddColumnAfter( const TOOL_EVENT& aEvent ) { return doAddColumnAfter( aEvent ); }
|
||||
int DeleteRows( const TOOL_EVENT& aEvent ) { return doDeleteRows( aEvent ); }
|
||||
int DeleteColumns( const TOOL_EVENT& aEvent ) { return doDeleteColumns( aEvent ); }
|
||||
|
||||
int MergeCells( const TOOL_EVENT& aEvent ) { return doMergeCells( aEvent ); }
|
||||
int UnmergeCells( const TOOL_EVENT& aEvent ) { return doUnmergeCells( aEvent ); }
|
||||
|
||||
private:
|
||||
///< Set up handlers for various events.
|
||||
void setTransitions() override;
|
||||
|
||||
private:
|
||||
TOOL_MANAGER* getToolMgr() override { return m_toolMgr; }
|
||||
BASE_SCREEN* getScreen() override { return nullptr; }
|
||||
|
||||
const SELECTION& getTableCellSelection() override;
|
||||
void clearSelection() override;
|
||||
|
||||
PCB_TABLECELL* copyCell( PCB_TABLECELL* aSource ) override;
|
||||
};
|
||||
|
||||
#endif //PCB_EDIT_TABLE_TOOL_H
|
|
@ -46,6 +46,8 @@ using namespace std::placeholders;
|
|||
#include <pcb_generator.h>
|
||||
#include <pcb_dimension.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pad.h>
|
||||
#include <zone.h>
|
||||
#include <footprint.h>
|
||||
|
@ -74,6 +76,12 @@ enum RECT_LINES
|
|||
};
|
||||
|
||||
|
||||
enum TABLECELL_POINTS
|
||||
{
|
||||
COL_WIDTH, ROW_HEIGHT
|
||||
};
|
||||
|
||||
|
||||
enum ARC_POINTS
|
||||
{
|
||||
ARC_START, ARC_MID, ARC_END, ARC_CENTER
|
||||
|
@ -283,6 +291,14 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLECELL_T:
|
||||
{
|
||||
PCB_TABLECELL* cell = static_cast<PCB_TABLECELL*>( aItem );
|
||||
points->AddPoint( cell->GetEnd() - VECTOR2I( 0, cell->GetRectangleHeight() / 2 ) );
|
||||
points->AddPoint( cell->GetEnd() - VECTOR2I( cell->GetRectangleWidth() / 2, 0 ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_PAD_T:
|
||||
{
|
||||
const PAD* pad = static_cast<const PAD*>( aItem );
|
||||
|
@ -557,9 +573,16 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
|||
m_toolMgr->RunSynchronousAction( PCB_ACTIONS::genStartEdit, &commit,
|
||||
static_cast<PCB_GENERATOR*>( item ) );
|
||||
}
|
||||
else if( item->Type() == PCB_TABLECELL_T )
|
||||
{
|
||||
PCB_TABLECELL* cell = static_cast<PCB_TABLECELL*>( item );
|
||||
PCB_TABLE* table = static_cast<PCB_TABLE*>( cell->GetParent() );
|
||||
|
||||
commit.Modify( table );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.StageItems( selection, CHT_MODIFY );
|
||||
commit.Modify( item );
|
||||
}
|
||||
|
||||
getViewControls()->ForceCursorPosition( false );
|
||||
|
@ -672,9 +695,13 @@ int PCB_POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
|||
m_toolMgr->RunSynchronousAction( PCB_ACTIONS::genPushEdit, &commit,
|
||||
static_cast<PCB_GENERATOR*>( item ) );
|
||||
}
|
||||
else if( item->Type() == PCB_TABLECELL_T )
|
||||
{
|
||||
commit.Push( _( "Resize Table Cells" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
commit.Push( _( "Drag Corner" ) );
|
||||
commit.Push( _( "Move Point" ) );
|
||||
}
|
||||
|
||||
inDrag = false;
|
||||
|
@ -1403,6 +1430,40 @@ void PCB_POINT_EDITOR::updateItem( BOARD_COMMIT* aCommit )
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLECELL_T:
|
||||
{
|
||||
PCB_TABLECELL* cell = static_cast<PCB_TABLECELL*>( item );
|
||||
PCB_TABLE* table = static_cast<PCB_TABLE*>( cell->GetParent() );
|
||||
|
||||
if( isModified( m_editPoints->Point( COL_WIDTH ) ) )
|
||||
{
|
||||
cell->SetEnd( VECTOR2I( m_editPoints->Point( 0 ).GetX(), cell->GetEndY() ) );
|
||||
|
||||
int colWidth = cell->GetRectangleWidth();
|
||||
|
||||
for( int ii = 0; ii < cell->GetColSpan() - 1; ++ii )
|
||||
colWidth -= table->GetColWidth( cell->GetColumn() + ii );
|
||||
|
||||
table->SetColWidth( cell->GetColumn() + cell->GetColSpan() - 1, colWidth );
|
||||
table->Normalize();
|
||||
}
|
||||
else if( isModified( m_editPoints->Point( ROW_HEIGHT ) ) )
|
||||
{
|
||||
cell->SetEnd( VECTOR2I( cell->GetEndX(), m_editPoints->Point( 1 ).GetY() ) );
|
||||
|
||||
int rowHeight = cell->GetRectangleHeight();
|
||||
|
||||
for( int ii = 0; ii < cell->GetRowSpan() - 1; ++ii )
|
||||
rowHeight -= table->GetRowHeight( cell->GetRow() + ii );
|
||||
|
||||
table->SetRowHeight( cell->GetRow() + cell->GetRowSpan() - 1, rowHeight );
|
||||
table->Normalize();
|
||||
}
|
||||
|
||||
getView()->Update( table );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_PAD_T:
|
||||
{
|
||||
PAD* pad = static_cast<PAD*>( item );
|
||||
|
@ -1933,6 +1994,17 @@ void PCB_POINT_EDITOR::updatePoints()
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLECELL_T:
|
||||
{
|
||||
PCB_TABLECELL* cell = static_cast<PCB_TABLECELL*>( item );
|
||||
|
||||
m_editPoints->Point( 0 ).SetPosition( cell->GetEndX(),
|
||||
cell->GetEndY() - cell->GetRectangleHeight() / 2 );
|
||||
m_editPoints->Point( 1 ).SetPosition( cell->GetEndX() - cell->GetRectangleWidth() / 2,
|
||||
cell->GetEndY() );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_PAD_T:
|
||||
{
|
||||
const PAD* pad = static_cast<const PAD*>( item );
|
||||
|
|
|
@ -45,6 +45,8 @@ using namespace std::placeholders;
|
|||
#include <pcb_shape.h>
|
||||
#include <pcb_text.h>
|
||||
#include <pcb_textbox.h>
|
||||
#include <pcb_table.h>
|
||||
#include <pcb_tablecell.h>
|
||||
#include <pcb_marker.h>
|
||||
#include <pcb_generator.h>
|
||||
#include <zone.h>
|
||||
|
@ -399,7 +401,16 @@ int PCB_SELECTION_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
m_frame->FocusOnItem( nullptr );
|
||||
m_toolMgr->ProcessEvent( EVENTS::InhibitSelectionEditing );
|
||||
|
||||
if( hasModifier() || dragAction == MOUSE_DRAG_ACTION::SELECT )
|
||||
GENERAL_COLLECTORS_GUIDE guide = getCollectorsGuide();
|
||||
GENERAL_COLLECTOR collector;
|
||||
|
||||
collector.Collect( board(), { PCB_TABLECELL_T }, evt->DragOrigin(), guide );
|
||||
|
||||
if( collector.GetCount() )
|
||||
{
|
||||
selectTableCells( static_cast<PCB_TABLE*>( collector[0]->GetParent() ) );
|
||||
}
|
||||
else if( hasModifier() || dragAction == MOUSE_DRAG_ACTION::SELECT )
|
||||
{
|
||||
selectMultiple();
|
||||
}
|
||||
|
@ -888,6 +899,112 @@ const TOOL_ACTION* allowedActions[] = { &ACTIONS::panUp, &ACTIONS::panD
|
|||
&ACTIONS::zoomFitObjects, nullptr };
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::selectTableCells( PCB_TABLE* aTable )
|
||||
{
|
||||
bool cancelled = false; // Was the tool canceled while it was running?
|
||||
m_multiple = true; // Multiple selection mode is active
|
||||
|
||||
for( PCB_TABLECELL* cell : aTable->GetCells() )
|
||||
{
|
||||
if( cell->IsSelected() )
|
||||
cell->SetFlags( CANDIDATE );
|
||||
else
|
||||
cell->ClearFlags( CANDIDATE );
|
||||
}
|
||||
|
||||
auto wasSelected =
|
||||
[]( EDA_ITEM* aItem )
|
||||
{
|
||||
return ( aItem->GetFlags() & CANDIDATE ) > 0;
|
||||
};
|
||||
|
||||
while( TOOL_EVENT* evt = Wait() )
|
||||
{
|
||||
if( evt->IsCancelInteractive() || evt->IsActivate() )
|
||||
{
|
||||
cancelled = true;
|
||||
break;
|
||||
}
|
||||
else if( evt->IsDrag( BUT_LEFT ) )
|
||||
{
|
||||
getViewControls()->SetAutoPan( true );
|
||||
|
||||
BOX2I selectionRect( evt->DragOrigin(), evt->Position() - evt->DragOrigin() );
|
||||
selectionRect.Normalize();
|
||||
|
||||
for( PCB_TABLECELL* cell : aTable->GetCells() )
|
||||
{
|
||||
bool doSelect = false;
|
||||
|
||||
if( cell->HitTest( selectionRect, false ) )
|
||||
{
|
||||
if( m_subtractive )
|
||||
doSelect = false;
|
||||
else if( m_exclusive_or )
|
||||
doSelect = !wasSelected( cell );
|
||||
else
|
||||
doSelect = true;
|
||||
}
|
||||
else if( wasSelected( cell ) )
|
||||
{
|
||||
doSelect = m_additive || m_subtractive || m_exclusive_or;
|
||||
}
|
||||
|
||||
if( doSelect && !cell->IsSelected() )
|
||||
select( cell );
|
||||
else if( !doSelect && cell->IsSelected() )
|
||||
unselect( cell );
|
||||
}
|
||||
}
|
||||
else if( evt->IsMouseUp( BUT_LEFT ) )
|
||||
{
|
||||
m_selection.SetIsHover( false );
|
||||
|
||||
bool anyAdded = false;
|
||||
bool anySubtracted = false;
|
||||
|
||||
for( PCB_TABLECELL* cell : aTable->GetCells() )
|
||||
{
|
||||
if( cell->IsSelected() && !wasSelected( cell ) )
|
||||
anyAdded = true;
|
||||
else if( wasSelected( cell ) && !cell->IsSelected() )
|
||||
anySubtracted = true;
|
||||
}
|
||||
|
||||
// Inform other potentially interested tools
|
||||
if( anyAdded )
|
||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
||||
|
||||
if( anySubtracted )
|
||||
m_toolMgr->ProcessEvent( EVENTS::UnselectedEvent );
|
||||
|
||||
break; // Stop waiting for events
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allow some actions for navigation
|
||||
for( int i = 0; allowedActions[i]; ++i )
|
||||
{
|
||||
if( evt->IsAction( allowedActions[i] ) )
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getViewControls()->SetAutoPan( false );
|
||||
|
||||
m_multiple = false; // Multiple selection mode is inactive
|
||||
|
||||
if( !cancelled )
|
||||
m_selection.ClearReferencePoint();
|
||||
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_SELECTION_TOOL::selectMultiple()
|
||||
{
|
||||
bool cancelled = false; // Was the tool canceled while it was running?
|
||||
|
@ -2322,6 +2439,8 @@ static bool itemIsIncludedByFilter( const BOARD_ITEM& aItem, const BOARD& aBoard
|
|||
case PCB_FIELD_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TABLECELL_T:
|
||||
return aFilterOptions.includePcbTexts;
|
||||
|
||||
default:
|
||||
|
@ -2486,6 +2605,8 @@ bool PCB_SELECTION_TOOL::itemPassesFilter( BOARD_ITEM* aItem, bool aMultiSelect
|
|||
case PCB_FIELD_T:
|
||||
case PCB_TEXT_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TABLECELL_T:
|
||||
if( !m_filter.text )
|
||||
return false;
|
||||
|
||||
|
@ -2800,6 +2921,8 @@ bool PCB_SELECTION_TOOL::Selectable( const BOARD_ITEM* aItem, bool checkVisibili
|
|||
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLE_T:
|
||||
case PCB_TABLECELL_T:
|
||||
if( m_isFootprintEditor )
|
||||
{
|
||||
if( !view()->IsLayerVisible( aItem->GetLayer() ) )
|
||||
|
@ -3042,6 +3165,7 @@ int PCB_SELECTION_TOOL::hitTestDistance( const VECTOR2I& aWhere, BOARD_ITEM* aIt
|
|||
}
|
||||
|
||||
case PCB_TEXTBOX_T:
|
||||
case PCB_TABLECELL_T:
|
||||
{
|
||||
PCB_TEXTBOX* textbox = static_cast<PCB_TEXTBOX*>( aItem );
|
||||
|
||||
|
@ -3052,6 +3176,20 @@ int PCB_SELECTION_TOOL::hitTestDistance( const VECTOR2I& aWhere, BOARD_ITEM* aIt
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
{
|
||||
PCB_TABLE* table = static_cast<PCB_TABLE*>( aItem );
|
||||
|
||||
for( PCB_TABLECELL* cell : table->GetCells() )
|
||||
{
|
||||
// Add a bit of slop to text-shapes
|
||||
if( cell->GetEffectiveTextShape()->Collide( loc, aMaxDistance, &distance ) )
|
||||
distance = std::clamp( distance - ( aMaxDistance / 2 ), 0, distance );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_ZONE_T:
|
||||
{
|
||||
ZONE* zone = static_cast<ZONE*>( aItem );
|
||||
|
@ -3286,7 +3424,9 @@ void PCB_SELECTION_TOOL::GuessSelectionCandidates( GENERAL_COLLECTOR& aCollector
|
|||
{
|
||||
static const LSET silkLayers( 2, B_SilkS, F_SilkS );
|
||||
static const LSET courtyardLayers( 2, B_CrtYd, F_CrtYd );
|
||||
static std::vector<KICAD_T> singleLayerSilkTypes = { PCB_FIELD_T, PCB_TEXT_T, PCB_TEXTBOX_T,
|
||||
static std::vector<KICAD_T> singleLayerSilkTypes = { PCB_FIELD_T,
|
||||
PCB_TEXT_T, PCB_TEXTBOX_T,
|
||||
PCB_TABLE_T, PCB_TABLECELL_T,
|
||||
PCB_SHAPE_T };
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_PcbSelectionVisibilityRatio != 1.0 )
|
||||
|
@ -3540,6 +3680,29 @@ void PCB_SELECTION_TOOL::FilterCollectorForHierarchy( GENERAL_COLLECTOR& aCollec
|
|||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::FilterCollectorForTableCells( GENERAL_COLLECTOR& aCollector ) const
|
||||
{
|
||||
std::set<BOARD_ITEM*> to_add;
|
||||
|
||||
// Iterate from the back so we don't have to worry about removals.
|
||||
for( int i = (int) aCollector.GetCount() - 1; i >= 0; --i )
|
||||
{
|
||||
BOARD_ITEM* item = aCollector[i];
|
||||
|
||||
if( item->Type() == PCB_TABLECELL_T )
|
||||
{
|
||||
if( !aCollector.HasItem( item->GetParent() ) )
|
||||
to_add.insert( item->GetParent() );
|
||||
|
||||
aCollector.Remove( item );
|
||||
}
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* item : to_add )
|
||||
aCollector.Append( item );
|
||||
}
|
||||
|
||||
|
||||
void PCB_SELECTION_TOOL::FilterCollectorForFreePads( GENERAL_COLLECTOR& aCollector,
|
||||
bool aForcePromotion ) const
|
||||
{
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
class PCB_BASE_FRAME;
|
||||
class BOARD_ITEM;
|
||||
class GENERAL_COLLECTOR;
|
||||
class PCB_TABLE;
|
||||
|
||||
namespace KIGFX
|
||||
{
|
||||
|
@ -205,6 +206,11 @@ public:
|
|||
void FilterCollectorForFreePads( GENERAL_COLLECTOR& aCollector,
|
||||
bool aForcePromotion = false ) const;
|
||||
|
||||
/**
|
||||
* Promote any table cell selections to the whole table.
|
||||
*/
|
||||
void FilterCollectorForTableCells( GENERAL_COLLECTOR& aCollector ) const;
|
||||
|
||||
/**
|
||||
* Drop any PCB_MARKERs from the collector.
|
||||
*/
|
||||
|
@ -293,6 +299,8 @@ private:
|
|||
*/
|
||||
bool selectMultiple();
|
||||
|
||||
bool selectTableCells( PCB_TABLE* aTable );
|
||||
|
||||
/**
|
||||
* Handle disambiguation actions including displaying the menu.
|
||||
*/
|
||||
|
|
|
@ -837,6 +837,10 @@ void ZONE_FILLER::addKnockout( BOARD_ITEM* aItem, PCB_LAYER_ID aLayer, int aGap,
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_TABLE_T:
|
||||
// JEY TODO: tables
|
||||
break;
|
||||
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_TARGET_T:
|
||||
aItem->TransformShapeToPolygon( aHoles, aLayer, aGap, m_maxError, ERROR_OUTSIDE,
|
||||
|
|
Loading…
Reference in New Issue