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 )
120 T_TABLECELL* topmost =
nullptr;
124 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
126 if( !topmost || cell->GetRow() < topmost->GetRow() )
133 int row = topmost->GetRow();
134 T_TABLE* table =
static_cast<T_TABLE*
>( topmost->GetParent() );
136 VECTOR2I pos = table->GetPosition();
139 std::vector<T_TABLECELL*> sources;
140 sources.reserve( table->GetColCount() );
142 for(
int col = 0; col < table->GetColCount(); ++col )
143 sources.push_back( table->GetCell( row, col ) );
147 for(
int col = 0; col < table->GetColCount(); ++col )
149 T_TABLECELL* cell =
copyCell( sources[col] );
150 table->InsertCell( row * table->GetColCount(), cell );
153 for(
int afterRow = table->GetRowCount() - 1; afterRow > row; afterRow-- )
154 table->SetRowHeight( afterRow, table->GetRowHeight( afterRow - 1 ) );
156 table->SetPosition( pos );
161 commit.Push(
_(
"Add Row Above" ) );
169 T_TABLECELL* bottommost =
nullptr;
171 if( selection.
Empty() )
176 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
178 if( !bottommost || cell->GetRow() > bottommost->GetRow() )
185 int row = bottommost->GetRow();
186 T_TABLE* table =
static_cast<T_TABLE*
>( bottommost->GetParent() );
188 VECTOR2I pos = table->GetPosition();
191 std::vector<T_TABLECELL*> sources;
192 sources.reserve( table->GetColCount() );
194 for(
int col = 0; col < table->GetColCount(); ++col )
195 sources.push_back( table->GetCell( row, col ) );
199 for(
int col = 0; col < table->GetColCount(); ++col )
201 T_TABLECELL* cell =
copyCell( sources[col] );
202 table->InsertCell( ( row + 1 ) * table->GetColCount(), cell );
205 for(
int afterRow = table->GetRowCount() - 1; afterRow > row; afterRow-- )
206 table->SetRowHeight( afterRow, table->GetRowHeight( afterRow - 1 ) );
208 table->SetPosition( pos );
213 commit.Push(
_(
"Add Row Below" ) );
221 T_TABLECELL* leftmost =
nullptr;
225 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
227 if( !leftmost || cell->GetColumn() < leftmost->GetColumn() )
234 int col = leftmost->GetColumn();
235 T_TABLE* table =
static_cast<T_TABLE*
>( leftmost->GetParent() );
236 int rowCount = table->GetRowCount();
238 VECTOR2I pos = table->GetPosition();
241 std::vector<T_TABLECELL*> sources;
242 sources.reserve( rowCount );
244 for(
int row = 0; row < rowCount; ++row )
245 sources.push_back( table->GetCell( row, col ) );
248 table->SetColCount( table->GetColCount() + 1 );
250 for(
int row = 0; row < rowCount; ++row )
252 T_TABLECELL* cell =
copyCell( sources[row] );
253 table->InsertCell( row * table->GetColCount() + col, cell );
256 for(
int afterCol = table->GetColCount() - 1; afterCol > col; afterCol-- )
257 table->SetColWidth( afterCol, table->GetColWidth( afterCol - 1 ) );
259 table->SetPosition( pos );
264 commit.Push(
_(
"Add Column Before" ) );
272 T_TABLECELL* rightmost =
nullptr;
276 T_TABLECELL* cell =
static_cast<T_TABLECELL*
>( item );
278 if( !rightmost || cell->GetColumn() > rightmost->GetColumn() )
285 int col = rightmost->GetColumn();
286 T_TABLE* table =
static_cast<T_TABLE*
>( rightmost->GetParent() );
287 int rowCount = table->GetRowCount();
289 VECTOR2I pos = table->GetPosition();
292 std::vector<T_TABLECELL*> sources;
293 sources.reserve( rowCount );
295 for(
int row = 0; row < rowCount; ++row )
296 sources.push_back( table->GetCell( row, col ) );
299 table->SetColCount( table->GetColCount() + 1 );
301 for(
int row = 0; row < rowCount; ++row )
303 T_TABLECELL* cell =
copyCell( sources[row] );
304 table->InsertCell( row * table->GetColCount() + col + 1, cell );
307 for(
int afterCol = table->GetColCount() - 1; afterCol > col; afterCol-- )
308 table->SetColWidth( afterCol, table->GetColWidth( afterCol - 1 ) );
310 table->SetPosition( pos );
315 commit.Push(
_(
"Add Column After" ) );
324 if( selection.
Empty() )
327 T_TABLE* table =
static_cast<T_TABLE*
>( selection[0]->GetParent() );
328 std::vector<int> deleted;
330 for( T_TABLECELL* cell : table->GetCells() )
333 for(
int row = 0; row < table->GetRowCount(); ++row )
335 bool deleteRow =
false;
337 for(
int col = 0; col < table->GetColCount(); ++col )
339 if( table->GetCell( row, col )->IsSelected() )
348 for(
int col = 0; col < table->GetColCount(); ++col )
351 deleted.push_back( row );
357 if( deleted.size() == (
unsigned) table->GetRowCount() )
359 commit.Remove( table );
365 VECTOR2I pos = table->GetPosition();
368 table->DeleteMarkedCells();
370 for(
int row = 0; row < table->GetRowCount(); ++row )
374 for(
int deletedRow : deleted )
376 if( deletedRow >= row )
380 table->SetRowHeight( row, table->GetRowHeight( row + offset ) );
383 table->SetPosition( pos );
389 if( deleted.size() > 1 )
390 commit.Push(
_(
"Delete Rows" ) );
392 commit.Push(
_(
"Delete Row" ) );
401 if( selection.
Empty() )
404 T_TABLE* table =
static_cast<T_TABLE*
>( selection[0]->GetParent() );
405 std::vector<int> deleted;
407 for( T_TABLECELL* cell : table->GetCells() )
410 for(
int col = 0; col < table->GetColCount(); ++col )
412 bool deleteColumn =
false;
414 for(
int row = 0; row < table->GetRowCount(); ++row )
416 if( table->GetCell( row, col )->IsSelected() )
425 for(
int row = 0; row < table->GetRowCount(); ++row )
428 deleted.push_back( col );
434 if( deleted.size() == (
unsigned) table->GetColCount() )
436 commit.Remove( table );
442 VECTOR2I pos = table->GetPosition();
445 table->DeleteMarkedCells();
446 table->SetColCount( table->GetColCount() - deleted.size() );
448 for(
int col = 0; col < table->GetColCount(); ++col )
452 for(
int deletedCol : deleted )
454 if( deletedCol >= col )
458 table->SetColWidth( col, table->GetColWidth( col + offset ) );
461 table->SetPosition( pos );
467 if( deleted.size() > 1 )
468 commit.Push(
_(
"Delete Columns" ) );
470 commit.Push(
_(
"Delete Column" ) );
482 int colMin = std::numeric_limits<int>::max();
484 int rowMin = std::numeric_limits<int>::max();
488 T_TABLE* table =
static_cast<T_TABLE*
>( sel[0]->GetParent() );
492 if( T_TABLECELL* cell =
dynamic_cast<T_TABLECELL*
>( item ) )
494 colMin = std::min( colMin, cell->GetColumn() );
495 colMax = std::max( colMax, cell->GetColumn() + cell->GetColSpan() );
496 rowMin = std::min( rowMin, cell->GetRow() );
497 rowMax = std::max( rowMax, cell->GetRow() + cell->GetRowSpan() );
504 for(
int row = rowMin; row < rowMax; ++row )
506 extents.
y += table->GetRowHeight( row );
509 for(
int col = colMin; col < colMax; ++col )
511 extents.
x += table->GetColWidth( col );
513 T_TABLECELL* cell = table->GetCell( row, col );
515 if( !cell->GetText().IsEmpty() )
517 if( !content.IsEmpty() )
520 content += cell->GetText();
524 cell->SetColSpan( 0 );
525 cell->SetRowSpan( 0 );
526 cell->SetText( wxEmptyString );
530 T_TABLECELL* topLeft = table->GetCell( rowMin, colMin );
531 topLeft->SetColSpan( colMax - colMin );
532 topLeft->SetRowSpan( rowMax - rowMin );
533 topLeft->SetText( content );
534 topLeft->SetEnd( topLeft->GetStart() + extents );
537 commit.Push(
_(
"Merge Cells" ) );
552 T_TABLE* table =
static_cast<T_TABLE*
>( sel[0]->GetParent() );
556 if( T_TABLECELL* cell =
dynamic_cast<T_TABLECELL*
>( item ) )
558 int rowSpan = cell->GetRowSpan();
559 int colSpan = cell->GetColSpan();
561 for(
int row = cell->GetRow(); row < cell->GetRow() + rowSpan; ++row )
563 for(
int col = cell->GetColumn(); col < cell->GetColumn() + colSpan; ++col )
565 T_TABLECELL* target = table->GetCell( row, col );
567 target->SetColSpan( 1 );
568 target->SetRowSpan( 1 );
570 VECTOR2I extents( table->GetColWidth( col ), table->GetRowHeight( row ) );
571 target->SetEnd( target->GetStart() + extents );
578 commit.Push(
_(
"Unmerge Cells" ) );
591 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