24#ifndef EDIT_TABLE_TOOL_BASE_H
25#define EDIT_TABLE_TOOL_BASE_H
30#include <wx/translation.h>
41template<
typename T_TABLE,
typename T_TABLECELL,
typename T_COMMIT>
51 auto cellBlockSelection =
57 int colMin = std::numeric_limits<int>::max();
59 int rowMin = std::numeric_limits<int>::max();
65 if( T_TABLECELL* cell =
dynamic_cast<T_TABLECELL*
>( item ) )
67 colMin = std::min( colMin, cell->GetColumn() );
68 colMax = std::max( colMax, cell->GetColumn() + cell->GetColSpan() );
69 rowMin = std::min( rowMin, cell->GetRow() );
70 rowMax = std::max( rowMax, cell->GetRow() + cell->GetRowSpan() );
72 selectedArea += cell->GetColSpan() * cell->GetRowSpan();
76 return selectedArea == ( colMax - colMin ) * ( rowMax - rowMin );
79 auto mergedCellsSelection =
84 if( T_TABLECELL* cell =
dynamic_cast<T_TABLECELL*
>( item ) )
86 if( cell->GetColSpan() > 1 || cell->GetRowSpan() > 1 )
127 T_TABLECELL* topmost =
nullptr;
131 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
133 if( !topmost || cell->GetRow() < topmost->GetRow() )
140 int row = topmost->GetRow();
141 T_TABLE* table =
static_cast<T_TABLE*
>( topmost->GetParent() );
143 VECTOR2I pos = table->GetPosition();
146 std::vector<T_TABLECELL*> sources;
147 sources.reserve( table->GetColCount() );
149 for(
int col = 0; col < table->GetColCount(); ++col )
150 sources.push_back( table->GetCell( row, col ) );
154 for(
int col = 0; col < table->GetColCount(); ++col )
156 T_TABLECELL* cell =
copyCell( sources[col] );
157 table->InsertCell( row * table->GetColCount(), cell );
160 for(
int afterRow = table->GetRowCount() - 1; afterRow > row; afterRow-- )
161 table->SetRowHeight( afterRow, table->GetRowHeight( afterRow - 1 ) );
163 table->SetPosition( pos );
168 commit.Push(
_(
"Add Row Above" ) );
176 T_TABLECELL* bottommost =
nullptr;
178 if( selection.
Empty() )
183 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
185 if( !bottommost || cell->GetRow() > bottommost->GetRow() )
192 int row = bottommost->GetRow();
193 T_TABLE* table =
static_cast<T_TABLE*
>( bottommost->GetParent() );
195 VECTOR2I pos = table->GetPosition();
198 std::vector<T_TABLECELL*> sources;
199 sources.reserve( table->GetColCount() );
201 for(
int col = 0; col < table->GetColCount(); ++col )
202 sources.push_back( table->GetCell( row, col ) );
206 for(
int col = 0; col < table->GetColCount(); ++col )
208 T_TABLECELL* cell =
copyCell( sources[col] );
209 table->InsertCell( ( row + 1 ) * table->GetColCount(), cell );
212 for(
int afterRow = table->GetRowCount() - 1; afterRow > row; afterRow-- )
213 table->SetRowHeight( afterRow, table->GetRowHeight( afterRow - 1 ) );
215 table->SetPosition( pos );
220 commit.Push(
_(
"Add Row Below" ) );
228 T_TABLECELL* leftmost =
nullptr;
232 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
234 if( !leftmost || cell->GetColumn() < leftmost->GetColumn() )
241 int col = leftmost->GetColumn();
242 T_TABLE* table =
static_cast<T_TABLE*
>( leftmost->GetParent() );
243 int rowCount = table->GetRowCount();
245 VECTOR2I pos = table->GetPosition();
248 std::vector<T_TABLECELL*> sources;
249 sources.reserve( rowCount );
251 for(
int row = 0; row < rowCount; ++row )
252 sources.push_back( table->GetCell( row, col ) );
255 table->SetColCount( table->GetColCount() + 1 );
257 for(
int row = 0; row < rowCount; ++row )
259 T_TABLECELL* cell =
copyCell( sources[row] );
260 table->InsertCell( row * table->GetColCount() + col, cell );
263 for(
int afterCol = table->GetColCount() - 1; afterCol > col; afterCol-- )
264 table->SetColWidth( afterCol, table->GetColWidth( afterCol - 1 ) );
266 table->SetPosition( pos );
271 commit.Push(
_(
"Add Column Before" ) );
279 T_TABLECELL* rightmost =
nullptr;
283 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
285 if( !rightmost || cell->GetColumn() > rightmost->GetColumn() )
292 int col = rightmost->GetColumn();
293 T_TABLE* table =
static_cast<T_TABLE*
>( rightmost->GetParent() );
294 int rowCount = table->GetRowCount();
296 VECTOR2I pos = table->GetPosition();
299 std::vector<T_TABLECELL*> sources;
300 sources.reserve( rowCount );
302 for(
int row = 0; row < rowCount; ++row )
303 sources.push_back( table->GetCell( row, col ) );
306 table->SetColCount( table->GetColCount() + 1 );
308 for(
int row = 0; row < rowCount; ++row )
310 T_TABLECELL* cell =
copyCell( sources[row] );
311 table->InsertCell( row * table->GetColCount() + col + 1, cell );
314 for(
int afterCol = table->GetColCount() - 1; afterCol > col; afterCol-- )
315 table->SetColWidth( afterCol, table->GetColWidth( afterCol - 1 ) );
317 table->SetPosition( pos );
322 commit.Push(
_(
"Add Column After" ) );
331 if( selection.
Empty() )
334 T_TABLE* table =
static_cast<T_TABLE*
>( selection[0]->GetParent() );
335 std::vector<int> deleted;
337 for( T_TABLECELL* cell : table->GetCells() )
340 for(
int row = 0; row < table->GetRowCount(); ++row )
342 bool deleteRow =
false;
344 for(
int col = 0; col < table->GetColCount(); ++col )
346 if( table->GetCell( row, col )->IsSelected() )
355 for(
int col = 0; col < table->GetColCount(); ++col )
358 deleted.push_back( row );
364 if( deleted.size() == (
unsigned) table->GetRowCount() )
366 commit.Remove( table );
372 VECTOR2I pos = table->GetPosition();
375 table->DeleteMarkedCells();
377 for(
int row = 0; row < table->GetRowCount(); ++row )
381 for(
int deletedRow : deleted )
383 if( deletedRow >= row )
387 table->SetRowHeight( row, table->GetRowHeight( row + offset ) );
390 table->SetPosition( pos );
396 if( deleted.size() > 1 )
397 commit.Push(
_(
"Delete Rows" ) );
399 commit.Push(
_(
"Delete Row" ) );
408 if( selection.
Empty() )
411 T_TABLE* table =
static_cast<T_TABLE*
>( selection[0]->GetParent() );
412 std::vector<int> deleted;
414 for( T_TABLECELL* cell : table->GetCells() )
417 for(
int col = 0; col < table->GetColCount(); ++col )
419 bool deleteColumn =
false;
421 for(
int row = 0; row < table->GetRowCount(); ++row )
423 if( table->GetCell( row, col )->IsSelected() )
432 for(
int row = 0; row < table->GetRowCount(); ++row )
435 deleted.push_back( col );
441 if( deleted.size() == (
unsigned) table->GetColCount() )
443 commit.Remove( table );
449 VECTOR2I pos = table->GetPosition();
452 table->DeleteMarkedCells();
453 table->SetColCount( table->GetColCount() - deleted.size() );
455 for(
int col = 0; col < table->GetColCount(); ++col )
459 for(
int deletedCol : deleted )
461 if( deletedCol >= col )
465 table->SetColWidth( col, table->GetColWidth( col + offset ) );
468 table->SetPosition( pos );
474 if( deleted.size() > 1 )
475 commit.Push(
_(
"Delete Columns" ) );
477 commit.Push(
_(
"Delete Column" ) );
489 int colMin = std::numeric_limits<int>::max();
491 int rowMin = std::numeric_limits<int>::max();
495 T_TABLE* table =
static_cast<T_TABLE*
>( sel[0]->GetParent() );
499 if( T_TABLECELL* cell =
dynamic_cast<T_TABLECELL*
>( item ) )
501 colMin = std::min( colMin, cell->GetColumn() );
502 colMax = std::max( colMax, cell->GetColumn() + cell->GetColSpan() );
503 rowMin = std::min( rowMin, cell->GetRow() );
504 rowMax = std::max( rowMax, cell->GetRow() + cell->GetRowSpan() );
511 for(
int row = rowMin; row < rowMax; ++row )
513 extents.
y += table->GetRowHeight( row );
516 for(
int col = colMin; col < colMax; ++col )
518 extents.
x += table->GetColWidth( col );
520 T_TABLECELL* cell = table->GetCell( row, col );
522 if( !cell->GetText().IsEmpty() )
524 if( !content.IsEmpty() )
527 content += cell->GetText();
531 cell->SetColSpan( 0 );
532 cell->SetRowSpan( 0 );
533 cell->SetText( wxEmptyString );
537 T_TABLECELL* topLeft = table->GetCell( rowMin, colMin );
538 topLeft->SetColSpan( colMax - colMin );
539 topLeft->SetRowSpan( rowMax - rowMin );
540 topLeft->SetText( content );
541 topLeft->SetEnd( topLeft->GetStart() + extents );
544 commit.Push(
_(
"Merge Cells" ) );
559 T_TABLE* table =
static_cast<T_TABLE*
>( sel[0]->GetParent() );
563 if( T_TABLECELL* cell =
dynamic_cast<T_TABLECELL*
>( item ) )
565 int rowSpan = cell->GetRowSpan();
566 int colSpan = cell->GetColSpan();
568 for(
int row = cell->GetRow(); row < cell->GetRow() + rowSpan; ++row )
570 for(
int col = cell->GetColumn(); col < cell->GetColumn() + colSpan; ++col )
572 T_TABLECELL* target = table->GetCell( row, col );
574 target->SetColSpan( 1 );
575 target->SetRowSpan( 1 );
577 VECTOR2I extents( table->GetColWidth( col ), table->GetRowHeight( row ) );
578 target->SetEnd( target->GetStart() + extents );
585 commit.Push(
_(
"Unmerge Cells" ) );
598 virtual T_TABLECELL*
copyCell( T_TABLECELL* aSource ) = 0;
static TOOL_ACTION addRowAbove
static TOOL_ACTION addColBefore
static TOOL_ACTION deleteRows
static TOOL_ACTION addRowBelow
static TOOL_ACTION deleteColumns
static TOOL_ACTION unmergeCells
static TOOL_ACTION mergeCells
static TOOL_ACTION addColAfter
static TOOL_ACTION editTable
Handles how to draw a screen (a board, a schematic ...)
A base class for most all the KiCad significant classes used in schematics and boards.
static const TOOL_EVENT SelectedEvent
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static bool Idle(const SELECTION &aSelection)
Test if there no items selected or being edited.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
bool Empty() const
Checks if there is anything selected.
#define STRUCT_DELETED
flag indication structures to be erased
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables