74 changed files with 11050 additions and 4096 deletions
-
53d-viewer/3d_canvas/board_adapter.h
-
293d-viewer/3d_canvas/create_3Dgraphic_brd_items.cpp
-
173d-viewer/3d_canvas/create_layer_items.cpp
-
2common/CMakeLists.txt
-
2common/eda_item.cpp
-
4common/eda_shape.cpp
-
4common/hash_eda.cpp
-
12common/pcb.keywords
-
79common/tool/actions.cpp
-
2common/widgets/lib_tree.cpp
-
14eeschema/dialogs/dialog_tablecell_properties.cpp
-
4eeschema/dialogs/dialog_tablecell_properties_base.cpp
-
6857eeschema/dialogs/dialog_tablecell_properties_base.fbp
-
2eeschema/dialogs/dialog_tablecell_properties_base.h
-
9eeschema/sch_io/kicad_sexpr/sch_io_kicad_sexpr_parser.cpp
-
2eeschema/sch_item.h
-
7eeschema/sch_painter.cpp
-
64eeschema/sch_table.cpp
-
35eeschema/sch_tablecell.cpp
-
4eeschema/sch_tablecell.h
-
77eeschema/tools/ee_actions.cpp
-
13eeschema/tools/ee_actions.h
-
12eeschema/tools/ee_selection_tool.cpp
-
7eeschema/tools/sch_drawing_tools.cpp
-
490eeschema/tools/sch_edit_table_tool.cpp
-
38eeschema/tools/sch_edit_table_tool.h
-
2eeschema/tools/sch_edit_tool.cpp
-
4include/core/typeinfo.h
-
15include/tool/actions.h
-
555include/tool/edit_table_tool_base.h
-
3pcbnew/CMakeLists.txt
-
1pcbnew/array_creator.cpp
-
33pcbnew/board.cpp
-
3pcbnew/board_commit.cpp
-
7pcbnew/collectors.cpp
-
477pcbnew/dialogs/dialog_tablecell_properties.cpp
-
72pcbnew/dialogs/dialog_tablecell_properties.h
-
382pcbnew/dialogs/dialog_tablecell_properties_base.cpp
-
3445pcbnew/dialogs/dialog_tablecell_properties_base.fbp
-
119pcbnew/dialogs/dialog_tablecell_properties_base.h
-
1pcbnew/drc/drc_engine.cpp
-
5pcbnew/edit.cpp
-
2pcbnew/footprint_edit_frame.cpp
-
1pcbnew/menubar_pcb_editor.cpp
-
2pcbnew/pcb_base_edit_frame.h
-
3pcbnew/pcb_edit_frame.cpp
-
1pcbnew/pcb_group.cpp
-
82pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp
-
10pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.h
-
253pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
-
7pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.h
-
175pcbnew/pcb_painter.cpp
-
2pcbnew/pcb_painter.h
-
450pcbnew/pcb_table.cpp
-
250pcbnew/pcb_table.h
-
192pcbnew/pcb_tablecell.cpp
-
85pcbnew/pcb_tablecell.h
-
6pcbnew/pcb_textbox.cpp
-
2pcbnew/pcb_textbox.h
-
17pcbnew/pcb_view.cpp
-
1pcbnew/toolbars_footprint_editor.cpp
-
1pcbnew/toolbars_pcb_editor.cpp
-
234pcbnew/tools/drawing_tool.cpp
-
5pcbnew/tools/drawing_tool.h
-
21pcbnew/tools/edit_tool.cpp
-
1pcbnew/tools/edit_tool_move_fct.cpp
-
10pcbnew/tools/pcb_actions.cpp
-
1pcbnew/tools/pcb_actions.h
-
94pcbnew/tools/pcb_edit_table_tool.cpp
-
68pcbnew/tools/pcb_edit_table_tool.h
-
76pcbnew/tools/pcb_point_editor.cpp
-
167pcbnew/tools/pcb_selection_tool.cpp
-
8pcbnew/tools/pcb_selection_tool.h
-
4pcbnew/zone_filler.cpp
6857
eeschema/dialogs/dialog_tablecell_properties_base.fbp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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 |
@ -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 ); |
|||
|
|||
} |
3445
pcbnew/dialogs/dialog_tablecell_properties_base.fbp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -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(); |
|||
|
|||
}; |
|||
|
@ -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 */ |
@ -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 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue