KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema/dialogs/dialog_table_properties.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 <scintilla_tricks.h>
21#include <kiplatform/ui.h>
22#include <sch_edit_frame.h>
25#include <widgets/wx_grid.h>
27#include <grid_tricks.h>
29#include <widgets/wx_infobar.h>
30#include <sch_table.h>
31#include <sch_commit.h>
32#include <tool/tool_manager.h>
34
35
38 m_frame( aFrame ),
39 m_table( aTable ),
43{
44 m_grid = new WX_GRID( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
45
46 m_grid->CreateGrid( m_table->GetRowCount(), m_table->GetColCount() );
47 m_grid->EnableEditing( true );
48 m_grid->EnableGridLines( true );
49 m_grid->EnableDragGridSize( false );
50 m_grid->SetMargins( 0, 0 );
51 m_grid->SetCellHighlightROPenWidth( 0 );
52
53 m_grid->EnableDragColMove( false );
54 m_grid->EnableDragColSize( false );
55 m_grid->SetColLabelSize( 0 );
56 m_grid->EnableDragRowMove( false );
57 m_grid->EnableDragRowSize( false );
58 m_grid->SetRowLabelSize( 0 );
59 m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
60
61 m_gridSizer->Add( m_grid, 1, wxEXPAND, 5 );
62 m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
63
64 for( int row = 0; row < m_table->GetRowCount(); ++row )
65 {
66 for( int col = 0; col < m_table->GetColCount(); ++col )
67 {
68 const SCH_TABLECELL* cell = m_table->GetCell( row, col );
69 wxGridCellAttr* attr = new wxGridCellAttr;
70
71 if( cell->GetColSpan() == 0 || cell->GetRowSpan() == 0 )
72 {
73 attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( this ) );
74 attr->SetReadOnly();
75 }
76 else
77 {
78 attr->SetRenderer( new wxGridCellAutoWrapStringRenderer );
79 attr->SetEditor( new GRID_CELL_STC_EDITOR( true, false,
80 // onCharFn
81 [this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
82 {
83 aScintillaTricks->DoTextVarAutocomplete(
84 // getTokensFn
85 [this]( const wxString& xRef, wxArrayString* tokens )
86 {
87 getContextualTextVars( xRef, tokens );
88 } );
89 } ) );
90 }
91
92 m_grid->SetAttr( row, col, attr );
93 }
94 }
95
96 for( const auto& [lineStyle, lineStyleDesc] : lineTypeNames )
97 {
98 m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
99 m_separatorsStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
100 }
101
103 m_borderColorSwatch->SetSwatchBackground( canvas );
104 m_separatorsColorSwatch->SetSwatchBackground( canvas );
105
106 if( m_frame->GetColorSettings()->GetOverrideSchItemColors() )
107 m_infoBar->ShowMessage( _( "Note: individual item colors overridden in Preferences." ) );
108
110 Layout();
111
112 // Now all widgets have the size fixed, call FinishDialogSettings
114}
115
116
118{
119 // Delete the GRID_TRICKS.
120 m_grid->PopEventHandler( true );
121}
122
123
125{
126 if( !wxDialog::TransferDataToWindow() )
127 return false;
128
129 //
130 // Cell Contents
131 //
132
133 wxColour coveredColor = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
134
136 coveredColor = coveredColor.ChangeLightness( 140 );
137 else
138 coveredColor = coveredColor.ChangeLightness( 100 );
139
140 for( int row = 0; row < m_table->GetRowCount(); ++row )
141 {
142 for( int col = 0; col < m_table->GetColCount(); ++col )
143 {
144 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
145
146 if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
147 {
148 m_grid->SetCellValue( row, col, coveredColor.GetAsString() );
149 continue;
150 }
151
152 wxString text = tableCell->GetText();
153
154 // show text variable cross-references in a human-readable format
155 if( SCHEMATIC* schematic = tableCell->Schematic() )
156 text = schematic->ConvertKIIDsToRefs( text );
157
158 m_grid->SetCellValue( row, col, text );
159 }
160 }
161
162 CallAfter( [this]()
163 {
164 for( int row = 0; row < m_table->GetRowCount(); ++row )
165 {
166 for( int col = 0; col < m_table->GetColCount(); ++col )
167 {
168 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
169
170 if( tableCell->IsSelected() )
171 {
172 m_grid->SetGridCursor( row, col );
173 m_grid->EnableCellEditControl();
174 m_grid->ShowCellEditControl();
175 return;
176 }
177 }
178 }
179 } );
180
182
183 //
184 // Table Properties
185 //
186
187 m_borderCheckbox->SetValue( m_table->StrokeExternal() );
188 m_headerBorder->SetValue( m_table->StrokeHeaderSeparator() );
189
190 if( m_table->GetBorderStroke().GetWidth() >= 0 )
191 m_borderWidth.SetValue( m_table->GetBorderStroke().GetWidth() );
192
193 m_borderColorSwatch->SetSwatchColor( m_table->GetBorderStroke().GetColor(), false );
194
195 int style = static_cast<int>( m_table->GetBorderStroke().GetLineStyle() );
196
197 if( style >= 0 && style < (int) lineTypeNames.size() )
198 m_borderStyleCombo->SetSelection( style );
199 else
200 m_borderStyleCombo->SetSelection( 0 );
201
202 m_borderWidth.Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
203 m_borderColorLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
204 m_borderColorSwatch->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
205 m_borderStyleLabel->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
206 m_borderStyleCombo->Enable( m_table->StrokeExternal() || m_table->StrokeHeaderSeparator() );
207
208 bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
209 bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
210
211 m_rowSeparators->SetValue( rows );
212 m_colSeparators->SetValue( cols );
213
214 if( m_table->GetSeparatorsStroke().GetWidth() >= 0 )
215 m_separatorsWidth.SetValue( m_table->GetSeparatorsStroke().GetWidth() );
216
217 m_separatorsColorSwatch->SetSwatchColor( m_table->GetSeparatorsStroke().GetColor(), false );
218
219 style = static_cast<int>( m_table->GetSeparatorsStroke().GetLineStyle() );
220
221 if( style >= 0 && style < (int) lineTypeNames.size() )
222 m_separatorsStyleCombo->SetSelection( style );
223 else
224 m_separatorsStyleCombo->SetSelection( 0 );
225
226 m_separatorsWidth.Enable( rows || cols );
227 m_separatorsColorLabel->Enable( rows || cols );
228 m_separatorsColorSwatch->Enable( rows || cols );
229 m_separatorsStyleLabel->Enable( rows || cols );
230 m_separatorsStyleCombo->Enable( rows || cols );
231
232 return true;
233}
234
235
236void DIALOG_TABLE_PROPERTIES::getContextualTextVars( const wxString& aCrossRef, wxArrayString* aTokens )
237{
238 if( !aCrossRef.IsEmpty() )
239 {
241 SCH_SYMBOL* refSymbol = nullptr;
242
243 m_frame->Schematic().Hierarchy().GetSymbols( refs, SYMBOL_FILTER_NON_POWER );
244
245 for( int jj = 0; jj < (int) refs.GetCount(); jj++ )
246 {
247 SCH_REFERENCE& ref = refs[jj];
248
249 if( ref.GetSymbol()->GetRef( &ref.GetSheetPath(), true ) == aCrossRef )
250 {
251 refSymbol = ref.GetSymbol();
252 break;
253 }
254 }
255
256 if( refSymbol )
257 refSymbol->GetContextualTextVars( aTokens );
258 }
259 else
260 {
261 SCHEMATIC* schematic = m_table->Schematic();
262
263 if( schematic && schematic->CurrentSheet().Last() )
264 {
265 schematic->CurrentSheet().Last()->GetContextualTextVars( aTokens );
266 }
267 else
268 {
269 for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
270 aTokens->push_back( entry.first );
271 }
272 }
273}
274
275
276void DIALOG_TABLE_PROPERTIES::onBorderChecked( wxCommandEvent& aEvent )
277{
278 bool border = m_borderCheckbox->GetValue();
279 bool headerSeparator = m_headerBorder->GetValue();
280
281 if( ( border || headerSeparator ) && m_borderWidth.GetValue() < 0 )
282 m_borderWidth.SetValue( m_frame->eeconfig()->m_Drawing.default_line_thickness );
283
284 m_borderWidth.Enable( border || headerSeparator );
285 m_borderColorLabel->Enable( border || headerSeparator );
286 m_borderColorSwatch->Enable( border || headerSeparator );
287 m_borderStyleLabel->Enable( border || headerSeparator );
288 m_borderStyleCombo->Enable( border || headerSeparator );
289
290 bool row = m_rowSeparators->GetValue();
291 bool col = m_colSeparators->GetValue();
292
293 if( ( row || col ) && m_separatorsWidth.GetValue() < 0 )
294 m_separatorsWidth.SetValue( m_frame->eeconfig()->m_Drawing.default_line_thickness );
295
296 m_separatorsWidth.Enable( row || col );
297 m_separatorsColorLabel->Enable( row || col );
298 m_separatorsColorSwatch->Enable( row || col );
299 m_separatorsStyleLabel->Enable( row || col );
300 m_separatorsStyleCombo->Enable( row || col );
301}
302
303
305{
306 if( !m_grid->CommitPendingChanges() )
307 return false;
308
309 if( !wxDialog::TransferDataFromWindow() )
310 return false;
311
312 SCH_COMMIT commit( m_frame );
313
314 /* save table in undo list if not already in edit */
315 if( m_table->GetEditFlags() == 0 )
316 commit.Modify( m_table, m_frame->GetScreen() );
317
318 for( int row = 0; row < m_table->GetRowCount(); ++row )
319 {
320 for( int col = 0; col < m_table->GetColCount(); ++col )
321 {
322 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
323 wxString txt = m_grid->GetCellValue( row, col );
324
325 // Don't insert grey colour value back in to table cell
326 if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
327 txt = wxEmptyString;
328
329 // convert any text variable cross-references to their UUIDs
330 if( SCHEMATIC* schematic = tableCell->Schematic() )
331 txt = schematic->ConvertRefsToKIIDs( txt );
332
333#ifdef __WXMAC__
334 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
335 // Replace it now.
336 txt.Replace( "\r", "\n" );
337#elif defined( __WINDOWS__ )
338 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
339 // drawing routines so strip the \r char.
340 txt.Replace( "\r", "" );
341#endif
342
343 tableCell->SetText( txt );
344 }
345 }
346
347 m_table->SetStrokeExternal( m_borderCheckbox->GetValue() );
348 m_table->SetStrokeHeaderSeparator( m_headerBorder->GetValue() );
349 {
350 STROKE_PARAMS stroke = m_table->GetBorderStroke();
351
352 if( m_borderCheckbox->GetValue() || m_headerBorder->GetValue() )
353 stroke.SetWidth( std::max( 0, m_borderWidth.GetIntValue() ) );
354 else
355 stroke.SetWidth( -1 );
356
357 auto it = lineTypeNames.begin();
358 std::advance( it, m_borderStyleCombo->GetSelection() );
359
360 if( it == lineTypeNames.end() )
362 else
363 stroke.SetLineStyle( it->first );
364
365 stroke.SetColor( m_borderColorSwatch->GetSwatchColor() );
366
367 m_table->SetBorderStroke( stroke );
368 }
369
370 m_table->SetStrokeRows( m_rowSeparators->GetValue() );
371 m_table->SetStrokeColumns( m_colSeparators->GetValue() );
372 {
373 STROKE_PARAMS stroke = m_table->GetSeparatorsStroke();
374
375 if( m_rowSeparators->GetValue() || m_colSeparators->GetValue() )
376 stroke.SetWidth( std::max( 0, m_separatorsWidth.GetIntValue() ) );
377 else
378 stroke.SetWidth( -1 );
379
380 auto it = lineTypeNames.begin();
381 std::advance( it, m_separatorsStyleCombo->GetSelection() );
382
383 if( it == lineTypeNames.end() )
385 else
386 stroke.SetLineStyle( it->first );
387
388 stroke.SetColor( m_separatorsColorSwatch->GetSwatchColor() );
389
390 m_table->SetSeparatorsStroke( stroke );
391 }
392
393 if( !commit.Empty() )
394 commit.Push( _( "Edit Table" ) );
395
396 return true;
397}
398
399
401{
402 Layout(); // Make sure we get the current client size for the grid
403
404 wxSize availableGridSize = m_grid->GetClientSize();
405
406 if( availableGridSize.x == 0 || availableGridSize.y == 0 )
407 return;
408
409 BOX2I tableBBox = m_table->GetBoundingBox();
410 double scalerX = static_cast<double>( availableGridSize.x ) / tableBBox.GetWidth();
411 double scalerY = static_cast<double>( availableGridSize.y ) / tableBBox.GetHeight();
412
413 for( int row = 0; row < m_table->GetRowCount(); ++row )
414 m_grid->SetRowSize( row, std::floor( m_table->GetRowHeight( row ) * scalerY ) );
415
416 for( int col = 0; col < m_table->GetColCount(); ++col )
417 m_grid->SetColSize( col, std::floor( m_table->GetColWidth( col ) * scalerX ) );
418}
419
420
421void DIALOG_TABLE_PROPERTIES::onSize( wxSizeEvent& aEvent )
422{
423 if( m_table )
425
426 aEvent.Skip();
427}
428
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:100
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr size_type GetHeight() const
Definition box2.h:212
COLOR4D GetColor(int aLayer) const
bool Empty() const
Definition commit.h:145
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:102
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
DIALOG_TABLE_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Table Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
DIALOG_TABLE_PROPERTIES(SCH_EDIT_FRAME *aParentFrame, SCH_TABLE *aTable)
void getContextualTextVars(const wxString &aCrossRef, wxArrayString *aTokens)
void onBorderChecked(wxCommandEvent &aEvent) override
bool IsSelected() const
Definition eda_item.h:134
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:118
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:236
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition grid_tricks.h:57
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
Holds all the data relating to one schematic.
Definition schematic.h:149
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:304
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Returns a pointer to the active color theme settings.
Commit for the schematic and symbol editors.
Definition sch_commit.h:54
void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
Schematic editor (Eeschema) main window.
SCHEMATIC * Schematic() const
Search the item hierarchy to find a SCHEMATIC.
Definition sch_item.cpp:302
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
SCH_SYMBOL * GetSymbol() const
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
Schematic symbol object.
Definition sch_symbol.h:73
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
int GetColSpan() const
int GetRowSpan() const
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
void DoTextVarAutocomplete(const std::function< void(const wxString &xRef, wxArrayString *tokens)> &getTokensFn)
Simple container to manage line stroke parameters.
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
void SetColor(const KIGFX::COLOR4D &aColor)
#define _(s)
@ LAYER_SCHEMATIC_BACKGROUND
Definition layer_ids.h:510
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition wxgtk/ui.cpp:51
@ SYMBOL_FILTER_NON_POWER
const std::map< LINE_STYLE, struct LINE_STYLE_DESC > lineTypeNames
Conversion map between LINE_STYLE values and style names displayed.