KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcb_tablecell.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <advanced_config.h>
21#include <api/api_enums.h>
22#include <api/api_utils.h>
23#include <api/board/board_types.pb.h>
24#include <common.h>
25#include <pcb_edit_frame.h>
26#include <font/font.h>
27#include <widgets/msgpanel.h>
28#include <string_utils.h>
29#include <board.h>
30#include <pcb_table.h>
31#include <footprint.h>
32#include <properties/property.h>
34
35
37 PCB_TEXTBOX( aParent, PCB_TABLECELL_T ),
38 m_colSpan( 1 ),
39 m_rowSpan( 1 )
40{
41 if( FOOTPRINT* parentFP = dynamic_cast<FOOTPRINT*>( aParent ) )
42 {
43 if( parentFP->IsFlipped() )
44 SetMirrored( true );
45 }
46
47 SetRectangleHeight( std::numeric_limits<int>::max() / 2 );
48 SetRectangleWidth( std::numeric_limits<int>::max() / 2 );
49}
50
51
53{
54 wxASSERT( aImage->Type() == PCB_TABLECELL_T );
55
56 std::swap( *( (PCB_TABLECELL*) this ), *( (PCB_TABLECELL*) aImage ) );
57}
58
59
60void PCB_TABLECELL::Serialize( kiapi::board::types::TableCell& cell ) const
61{
62 using namespace kiapi::board;
63
64 cell.set_column_span( m_colSpan );
65 cell.set_row_span( m_rowSpan );
66
67 PCB_TEXTBOX::Serialize( *cell.mutable_text_box() );
68
69 kiapi::common::PackCustomProperties( cell.mutable_custom_properties(), *this );
70}
71
72
73void PCB_TABLECELL::Serialize( google::protobuf::Any& aContainer ) const
74{
75 kiapi::board::types::TableCell cell;
76 Serialize( cell );
77 aContainer.PackFrom( cell );
78}
79
80
81bool PCB_TABLECELL::Deserialize( const kiapi::board::types::TableCell& cell )
82{
83 using namespace kiapi::board;
84
85
86 if( !cell.has_text_box() )
87 return false;
88
89 if( !PCB_TEXTBOX::Deserialize( cell.text_box() ) )
90 return false;
91
92 SetColSpan( cell.column_span() );
93 SetRowSpan( cell.row_span() );
94
95 kiapi::common::UnpackCustomProperties( cell.custom_properties(), *this );
96
97 return true;
98}
99
100
101bool PCB_TABLECELL::Deserialize( const google::protobuf::Any& aContainer )
102{
103 kiapi::board::types::TableCell cell;
104
105 if( !aContainer.UnpackTo( &cell ) )
106 return false;
107
108 return Deserialize( cell );
109}
110
111
112wxString PCB_TABLECELL::GetItemDescription( UNITS_PROVIDER* aUnitsProvider, bool aFull ) const
113{
114 return wxString::Format( _( "Table cell %s" ), GetAddr() );
115}
116
117
119{
120 const PCB_TABLE* table = static_cast<const PCB_TABLE*>( GetParent() );
121
122 for( int row = 0; row < table->GetRowCount(); ++row )
123 {
124 for( int col = 0; col < table->GetColCount(); ++col )
125 {
126 if( table->GetCell( row, col ) == this )
127 return row;
128 }
129 }
130
131 return -1;
132}
133
134
136{
137 const PCB_TABLE* table = static_cast<const PCB_TABLE*>( GetParent() );
138
139 for( int row = 0; row < table->GetRowCount(); ++row )
140 {
141 for( int col = 0; col < table->GetColCount(); ++col )
142 {
143 if( table->GetCell( row, col ) == this )
144 return col;
145 }
146 }
147
148 return -1;
149}
150
151
153{
154 return wxString::Format( wxT( "%c%d" ), 'A' + GetColumn() % 26, GetRow() + 1 );
155}
156
157
158wxString PCB_TABLECELL::GetUnwrappedShownText( RESOLUTION_CONTEXT aContext, int aDepth ) const
159{
160 const FOOTPRINT* parentFootprint = GetParentFootprint();
161 const BOARD* board = GetBoard();
162
163 std::function<bool( wxString* )> tableCellResolver =
164 [&]( wxString* token ) -> bool
165 {
166 if( token->IsSameAs( wxT( "ROW" ) ) )
167 {
168 *token = wxString::Format( wxT( "%d" ), GetRow() + 1 ); // 1-based
169 return true;
170 }
171 else if( token->IsSameAs( wxT( "COL" ) ) )
172 {
173 *token = wxString::Format( wxT( "%d" ), GetColumn() + 1 ); // 1-based
174 return true;
175 }
176 else if( token->IsSameAs( wxT( "ADDR" ) ) )
177 {
178 *token = GetAddr();
179 return true;
180 }
181 else if( token->IsSameAs( wxT( "LAYER" ) ) )
182 {
183 *token = GetLayerName();
184 return true;
185 }
186
187 if( parentFootprint && parentFootprint->ResolveTextVar( token, aDepth + 1 ) )
188 return true;
189
190 if( board->ResolveTextVar( token, aDepth + 1 ) )
191 return true;
192
193 return false;
194 };
195
196 wxString text = EDA_TEXT::GetShownText( aContext, aDepth );
197
198 if( HasTextVars() && aContext != RAW_VALUE )
199 {
200 text = ResolveTextVars( text, &tableCellResolver, aDepth );
201 FinalizeTextVarExpansion( text, aContext );
202 }
203
204 return text;
205}
206
207
208wxString PCB_TABLECELL::GetShownText( RESOLUTION_CONTEXT aContext, int aDepth ) const
209{
210 wxString text = GetUnwrappedShownText( aContext, aDepth );
211
212 KIFONT::FONT* font = GetDrawFont( nullptr );
213 EDA_ANGLE drawAngle = GetDrawRotation();
214 std::vector<VECTOR2I> corners = GetCornersInSequence( drawAngle );
215 int colWidth = ( corners[1] - corners[0] ).EuclideanNorm();
216
217 if( GetTextAngle().IsHorizontal() )
218 colWidth -= ( GetMarginLeft() + GetMarginRight() );
219 else
220 colWidth -= ( GetMarginTop() + GetMarginBottom() );
221
223
224 return text;
225}
226
227
228double PCB_TABLECELL::GetCoverageArea( int aTextMargin ) const
229{
230 // A cell covers its whole box, not only the text a text box would measure
231 return BOARD_ITEM::GetCoverageArea( aTextMargin );
232}
233
234
236{
237 return static_cast<PCB_TABLE*>( GetParent() )->GetColWidth( GetColumn() );
238}
239
240
242{
243 PCB_TABLE* table = static_cast<PCB_TABLE*>( GetParent() );
244
245 table->SetColWidth( GetColumn(), aWidth );
246 table->Normalize();
247}
248
249
251{
252 return static_cast<PCB_TABLE*>( GetParent() )->GetRowHeight( GetRow() );
253}
254
255
257{
258 PCB_TABLE* table = static_cast<PCB_TABLE*>( GetParent() );
259
260 table->SetRowHeight( GetRow(), aHeight );
261 table->Normalize();
262}
263
264
265void PCB_TABLECELL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
266{
267 aList.emplace_back( _( "Table Cell" ), GetAddr() );
268
269 // Don't use GetShownText() here; we want to show the user the variable references
270 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
271
272 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
273 aList.emplace_back( _( "Status" ), _( "Locked" ) );
274
275 aList.emplace_back( _( "Layer" ), GetLayerName() );
276 aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) );
277
278 aList.emplace_back( _( "Cell Width" ), aFrame->MessageTextFromValue( std::abs( GetEnd().x - GetStart().x ) ) );
279 aList.emplace_back( _( "Cell Height" ), aFrame->MessageTextFromValue( std::abs( GetEnd().y - GetStart().y ) ) );
280
281 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
282
283 if( GetTextThickness() )
284 aList.emplace_back( _( "Text Thickness" ), aFrame->MessageTextFromValue( GetEffectiveTextPenWidth() ) );
285 else
286 aList.emplace_back( _( "Text Thickness" ), _( "Auto" ) );
287
288 aList.emplace_back( _( "Text Width" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
289 aList.emplace_back( _( "Text Height" ), aFrame->MessageTextFromValue( GetTextHeight() ) );
290}
291
292
293double PCB_TABLECELL::Similarity( const BOARD_ITEM& aBoardItem ) const
294{
295 if( aBoardItem.Type() != Type() )
296 return 0.0;
297
298 const PCB_TABLECELL& other = static_cast<const PCB_TABLECELL&>( aBoardItem );
299
300 double similarity = 1.0;
301
302 if( m_colSpan != other.m_colSpan )
303 similarity *= 0.9;
304
305 if( m_rowSpan != other.m_rowSpan )
306 similarity *= 0.9;
307
308 similarity *= PCB_TEXTBOX::Similarity( other );
309
310 return similarity;
311}
312
313bool PCB_TABLECELL::operator==( const BOARD_ITEM& aBoardItem ) const
314{
315 if( aBoardItem.Type() != Type() )
316 return false;
317
318 const PCB_TABLECELL& other = static_cast<const PCB_TABLECELL&>( aBoardItem );
319
320 return *this == other;
321}
322
323bool PCB_TABLECELL::operator==( const PCB_TABLECELL& aOther ) const
324{
325 return m_colSpan == aOther.m_colSpan && m_rowSpan == aOther.m_rowSpan && PCB_TEXTBOX::operator==( aOther );
326}
327
328
330{
332 {
335
348
349 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ) );
350 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ) );
351 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_SHAPE ), _HKI( "Layer" ) );
352 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_SHAPE ), _HKI( "Soldermask" ) );
353 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_SHAPE ), _HKI( "Soldermask Margin Override" ) );
354 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Corner Radius" ) );
355
357
358 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border" ) );
359 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border Style" ) );
360 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border Width" ) );
361
362 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ) );
363 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ) );
364 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "End X" ) );
365 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "End Y" ) );
366 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Shape" ) );
367 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Width" ) );
368 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Height" ) );
369 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Width" ) );
370 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Style" ) );
371 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Color" ) );
372
373 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
374 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
375 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Color" ) );
376
377 // A generated table reports the board, so cell contents are not the user's to edit but
378 // their formatting is. Scoped here, not on EDA_TEXT's descriptor, which eeschema shares
380 []( INSPECTABLE* aItem ) -> bool
381 {
382 return !IsGeneratedTableCell( dynamic_cast<PCB_TABLECELL*>( aItem ) );
383 } );
384
385 const wxString tableProps = _( "Table" );
386
387 propMgr.AddProperty( new PROPERTY<PCB_TABLECELL, int>( _HKI( "Column Width" ),
389 tableProps );
390
391 propMgr.AddProperty( new PROPERTY<PCB_TABLECELL, int>( _HKI( "Row Height" ),
393 tableProps );
394 }
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
bool IsLocked() const override
virtual double GetCoverageArea(int aTextMargin) const
Return the board area this item covers, used to rank candidates under the cursor so a click on a smal...
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
BOARD_ITEM_CONTAINER * GetParent() const
Definition board_item.h:266
wxString GetLayerName() const
Return the name of the PCB layer on which the item resides.
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:410
The base class for create windows for drawing purpose.
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
void SetRectangleHeight(const int &aHeight)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:325
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:275
void SetRectangleWidth(const int &aWidth)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:94
bool IsItalic() const
Definition eda_text.h:200
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
virtual int GetTextHeight() const
Definition eda_text.h:307
KIFONT::FONT * GetFont() const
Definition eda_text.h:286
void SetMirrored(bool isMirrored)
Definition eda_text.cpp:354
virtual EDA_ANGLE GetDrawRotation() const
Definition eda_text.h:425
virtual wxString GetShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const
Return the string actually shown after processing of the base text.
Definition eda_text.h:128
virtual int GetTextWidth() const
Definition eda_text.h:304
virtual KIFONT::FONT * GetDrawFont(const RENDER_SETTINGS *aSettings) const
Definition eda_text.cpp:647
bool HasTextVars() const
Indicates the ShownText has text var references which need to be processed.
Definition eda_text.h:139
bool IsMirrored() const
Definition eda_text.h:229
int GetEffectiveTextPenWidth(int aDefaultPenWidth=0) const
The EffectiveTextPenWidth uses the text thickness if > 1 or aDefaultPenWidth.
Definition eda_text.cpp:427
bool IsBold() const
Definition eda_text.h:215
bool ResolveTextVar(wxString *aToken, int aDepth=0) const
Resolve any references to system tokens supported by the component.
Class that other classes need to inherit from, in order to be inspectable.
Definition inspectable.h:39
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:94
void LinebreakText(wxString &aText, int aColumnWidth, const VECTOR2I &aGlyphSize, int aThickness, bool aBold, bool aItalic) const
Insert characters into text to ensure that no lines are wider than aColumnWidth.
Definition font.cpp:609
int GetColumnWidth() const
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
wxString GetAddr() const
double GetCoverageArea(int aTextMargin) const override
Return the board area this item covers, used to rank candidates under the cursor so a click on a smal...
void SetRowHeight(int aHeight)
wxString GetShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const override
Return the string actually shown after processing of the base text.
virtual void swapData(BOARD_ITEM *aImage) override
void SetRowSpan(int aSpan)
double Similarity(const BOARD_ITEM &aBoardItem) const override
Return a measure of how likely the other object is to represent the same object.
bool operator==(const PCB_TABLECELL &aBoardItem) const
void SetColumnWidth(int aWidth)
wxString GetUnwrappedShownText(RESOLUTION_CONTEXT aContext, int aDepth=0) const
GetShownText() before it is line-broken to the cell's width, i.e.
void SetColSpan(int aSpan)
int GetRow() const
int GetColumn() const
int GetRowHeight() const
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
PCB_TABLECELL(BOARD_ITEM *parent)
double Similarity(const BOARD_ITEM &aBoardItem) const override
Return a measure of how likely the other object is to represent the same object.
int GetMarginBottom() const
EDA_ANGLE GetTextAngle() const override
PCB_TEXTBOX(BOARD_ITEM *aParent, KICAD_T aType=PCB_TEXTBOX_T)
int GetTextThickness() const override
VECTOR2I GetTextSize() const override
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
int GetMarginLeft() const
std::vector< VECTOR2I > GetCornersInSequence(EDA_ANGLE angle) const override
int GetMarginRight() const
int GetMarginTop() const
bool operator==(const PCB_TEXTBOX &aOther) const
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
Provide class metadata.
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void OverrideWriteability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override writeability functor for a base class property of a given derived class.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
void FinalizeTextVarExpansion(wxString &aText, RESOLUTION_CONTEXT aContext)
Definition common.cpp:88
wxString ResolveTextVars(const wxString &aSource, const std::function< bool(wxString *)> *aResolver, int &aDepth)
Multi-pass text variable expansion and math expression evaluation.
Definition common.cpp:333
RESOLUTION_CONTEXT
Definition common.h:89
@ RAW_VALUE
Definition common.h:96
#define _(s)
#define PCB_EDIT_FRAME_NAME
Message panel definition file.
KICOMMON_API wxString EllipsizeStatusText(wxWindow *aWindow, const wxString &aString)
Ellipsize text (at the end) to be no more than 1/3 of the window width.
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:437
#define _HKI(x)
Definition page_info.cpp:40
bool IsGeneratedTableCell(const EDA_ITEM *aItem)
True for a cell whose text is generated from the board, so only its formatting is the user's.
Definition pcb_table.h:348
static struct PCB_TABLECELL_DESC _PCB_TABLECELL_DESC
#define TYPE_HASH(x)
Macro to generate unique identifier for a type.
Definition property.h:74
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:87