You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							594 lines
						
					
					
						
							19 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							594 lines
						
					
					
						
							19 KiB
						
					
					
				| /* | |
|  * 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 ); | |
|         selToolMenu.AddItem( ACTIONS::editTable,     cellSelection && SELECTION_CONDITIONS::Idle, 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() ); | |
|         VECTOR2I pos = table->GetPosition(); | |
| 
 | |
|         // 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->SetPosition( pos ); | |
|         table->Normalize(); | |
| 
 | |
|         getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
| 
 | |
|         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() ); | |
|         VECTOR2I pos = table->GetPosition(); | |
| 
 | |
|         // 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->SetPosition( pos ); | |
|         table->Normalize(); | |
| 
 | |
|         getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
| 
 | |
|         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() ); | |
|         VECTOR2I pos = table->GetPosition(); | |
| 
 | |
|         // 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->SetPosition( pos ); | |
|         table->Normalize(); | |
| 
 | |
|         getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
| 
 | |
|         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() ); | |
|         VECTOR2I pos = table->GetPosition(); | |
| 
 | |
|         // 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->SetPosition( pos ); | |
|         table->Normalize(); | |
| 
 | |
|         getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
| 
 | |
|         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( T_TABLECELL* cell : table->GetCells() ) | |
|             cell->ClearFlags( STRUCT_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() ); | |
| 
 | |
|             VECTOR2I pos = table->GetPosition(); | |
| 
 | |
|             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->SetPosition( pos ); | |
|             table->Normalize(); | |
| 
 | |
|             getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
|         } | |
| 
 | |
|         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( T_TABLECELL* cell : table->GetCells() ) | |
|             cell->ClearFlags( STRUCT_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() ); | |
| 
 | |
|             VECTOR2I pos = table->GetPosition(); | |
| 
 | |
|             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->SetPosition( pos ); | |
|             table->Normalize(); | |
| 
 | |
|             getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
|         } | |
| 
 | |
|         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" ) ); | |
| 
 | |
|         getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
| 
 | |
|         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" ) ); | |
| 
 | |
|         getToolMgr()->PostEvent( EVENTS::SelectedEvent ); | |
| 
 | |
|         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
 |