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::GetShownText( 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 KIFONT::FONT* font = GetDrawFont( nullptr );
205 EDA_ANGLE drawAngle = GetDrawRotation();
206 std::vector<VECTOR2I> corners = GetCornersInSequence( drawAngle );
207 int colWidth = ( corners[1] - corners[0] ).EuclideanNorm();
208
209 if( GetTextAngle().IsHorizontal() )
210 colWidth -= ( GetMarginLeft() + GetMarginRight() );
211 else
212 colWidth -= ( GetMarginTop() + GetMarginBottom() );
213
215
216 return text;
217}
218
219
221{
222 return static_cast<PCB_TABLE*>( GetParent() )->GetColWidth( GetColumn() );
223}
224
225
227{
228 PCB_TABLE* table = static_cast<PCB_TABLE*>( GetParent() );
229
230 table->SetColWidth( GetColumn(), aWidth );
231 table->Normalize();
232}
233
234
236{
237 return static_cast<PCB_TABLE*>( GetParent() )->GetRowHeight( GetRow() );
238}
239
240
242{
243 PCB_TABLE* table = static_cast<PCB_TABLE*>( GetParent() );
244
245 table->SetRowHeight( GetRow(), aHeight );
246 table->Normalize();
247}
248
249
250void PCB_TABLECELL::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList )
251{
252 aList.emplace_back( _( "Table Cell" ), GetAddr() );
253
254 // Don't use GetShownText() here; we want to show the user the variable references
255 aList.emplace_back( _( "Text" ), KIUI::EllipsizeStatusText( aFrame, GetText() ) );
256
257 if( aFrame->GetName() == PCB_EDIT_FRAME_NAME && IsLocked() )
258 aList.emplace_back( _( "Status" ), _( "Locked" ) );
259
260 aList.emplace_back( _( "Layer" ), GetLayerName() );
261 aList.emplace_back( _( "Mirror" ), IsMirrored() ? _( "Yes" ) : _( "No" ) );
262
263 aList.emplace_back( _( "Cell Width" ), aFrame->MessageTextFromValue( std::abs( GetEnd().x - GetStart().x ) ) );
264 aList.emplace_back( _( "Cell Height" ), aFrame->MessageTextFromValue( std::abs( GetEnd().y - GetStart().y ) ) );
265
266 aList.emplace_back( _( "Font" ), GetFont() ? GetFont()->GetName() : _( "Default" ) );
267
268 if( GetTextThickness() )
269 aList.emplace_back( _( "Text Thickness" ), aFrame->MessageTextFromValue( GetEffectiveTextPenWidth() ) );
270 else
271 aList.emplace_back( _( "Text Thickness" ), _( "Auto" ) );
272
273 aList.emplace_back( _( "Text Width" ), aFrame->MessageTextFromValue( GetTextWidth() ) );
274 aList.emplace_back( _( "Text Height" ), aFrame->MessageTextFromValue( GetTextHeight() ) );
275}
276
277
278double PCB_TABLECELL::Similarity( const BOARD_ITEM& aBoardItem ) const
279{
280 if( aBoardItem.Type() != Type() )
281 return 0.0;
282
283 const PCB_TABLECELL& other = static_cast<const PCB_TABLECELL&>( aBoardItem );
284
285 double similarity = 1.0;
286
287 if( m_colSpan != other.m_colSpan )
288 similarity *= 0.9;
289
290 if( m_rowSpan != other.m_rowSpan )
291 similarity *= 0.9;
292
293 similarity *= PCB_TEXTBOX::Similarity( other );
294
295 return similarity;
296}
297
298bool PCB_TABLECELL::operator==( const BOARD_ITEM& aBoardItem ) const
299{
300 if( aBoardItem.Type() != Type() )
301 return false;
302
303 const PCB_TABLECELL& other = static_cast<const PCB_TABLECELL&>( aBoardItem );
304
305 return *this == other;
306}
307
308bool PCB_TABLECELL::operator==( const PCB_TABLECELL& aOther ) const
309{
310 return m_colSpan == aOther.m_colSpan && m_rowSpan == aOther.m_rowSpan && PCB_TEXTBOX::operator==( aOther );
311}
312
313
315{
317 {
320
333
334 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position X" ) );
335 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( BOARD_ITEM ), _HKI( "Position Y" ) );
336 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_SHAPE ), _HKI( "Layer" ) );
337 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_SHAPE ), _HKI( "Soldermask" ) );
338 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_SHAPE ), _HKI( "Soldermask Margin Override" ) );
339 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Corner Radius" ) );
340
342
343 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border" ) );
344 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border Style" ) );
345 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( PCB_TEXTBOX ), _HKI( "Border Width" ) );
346
347 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start X" ) );
348 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Start Y" ) );
349 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "End X" ) );
350 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "End Y" ) );
351 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Shape" ) );
352 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Width" ) );
353 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Height" ) );
354 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Width" ) );
355 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Style" ) );
356 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_SHAPE ), _HKI( "Line Color" ) );
357
358 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Orientation" ) );
359 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Hyperlink" ) );
360 propMgr.Mask( TYPE_HASH( PCB_TABLECELL ), TYPE_HASH( EDA_TEXT ), _HKI( "Color" ) );
361
362 // A chart reports the board, so cell contents are not the user's to edit but their
363 // formatting is. Scoped here, not on EDA_TEXT's descriptor, which eeschema shares
365 []( INSPECTABLE* aItem ) -> bool
366 {
367 PCB_TABLECELL* cell = dynamic_cast<PCB_TABLECELL*>( aItem );
368
369 return !cell || !cell->GetParent() || cell->GetParent()->Type() != PCB_DRILL_CHART_T;
370 } );
371
372 const wxString tableProps = _( "Table" );
373
374 propMgr.AddProperty( new PROPERTY<PCB_TABLECELL, int>( _HKI( "Column Width" ),
376 tableProps );
377
378 propMgr.AddProperty( new PROPERTY<PCB_TABLECELL, int>( _HKI( "Row Height" ),
380 tableProps );
381 }
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 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:409
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:349
virtual EDA_ANGLE GetDrawRotation() const
Definition eda_text.h:419
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:630
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:422
bool IsBold() const
Definition eda_text.h:215
bool ResolveTextVar(wxString *token, 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
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)
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.Helper macro to map type hashes to names.
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:87
@ RAW_VALUE
Definition common.h:94
#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:411
#define _HKI(x)
Definition page_info.cpp:40
static struct PCB_TABLECELL_DESC _PCB_TABLECELL_DESC
#define TYPE_HASH(x)
Definition property.h:74
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition property.h:63
#define REGISTER_TYPE(x)
@ PCB_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
Definition typeinfo.h:87
@ PCB_DRILL_CHART_T
class PCB_DRILL_CHART, a live drill chart derived from PCB_TABLE
Definition typeinfo.h:239