KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema/dialogs/dialog_tablecell_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 <bitmaps.h>
21#include <scintilla_tricks.h>
22#include <gr_text.h>
23#include <sch_edit_frame.h>
26#include <widgets/font_choice.h>
28#include <widgets/wx_infobar.h>
29#include <sch_table.h>
30#include <sch_text.h>
31#include <sch_commit.h>
32#include <tool/tool_manager.h>
35
36DIALOG_TABLECELL_PROPERTIES::DIALOG_TABLECELL_PROPERTIES( SCH_EDIT_FRAME* aFrame, std::vector<SCH_TABLECELL*> aCells ) :
38 m_frame( aFrame ),
39 m_table( nullptr ),
40 m_cells( std::move( aCells ) ),
41 m_scintillaTricks( nullptr ),
42 m_helpWindow( nullptr ),
44 m_marginLeft( aFrame, nullptr, m_marginLeftCtrl, nullptr ),
45 m_marginTop( aFrame, nullptr, m_marginTopCtrl, m_marginTopUnits ),
46 m_marginRight( aFrame, nullptr, m_marginRightCtrl, nullptr ),
47 m_marginBottom( aFrame, nullptr, m_marginBottomCtrl, nullptr ),
50{
51 wxASSERT( m_cells.size() > 0 && m_cells[0] );
52
53 m_cellText->SetEOLMode( wxSTC_EOL_LF );
54
55 // Wrapping is display-only and does not insert newlines into the stored text.
56 m_cellText->SetWrapMode( wxSTC_WRAP_WORD );
57 m_cellText->SetWrapVisualFlags( wxSTC_WRAPVISUALFLAG_END );
58 m_cellText->SetWrapIndentMode( wxSTC_WRAPINDENT_INDENT );
59
60#ifdef _WIN32
61 // Without this setting, on Windows, some esoteric unicode chars create display issue
62 // in a wxStyledTextCtrl.
63 // for SetTechnology() info, see https://www.scintilla.org/ScintillaDoc.html#SCI_SETTECHNOLOGY
64 m_cellText->SetTechnology( wxSTC_TECHNOLOGY_DIRECTWRITE );
65#endif
66
68 m_cellText, wxT( "{}" ), false,
69 // onAcceptFn
70 [this]( wxKeyEvent& aEvent )
71 {
72 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
73 },
74
75 // onCharFn
76 [this]( wxStyledTextEvent& aEvent )
77 {
78 m_scintillaTricks->DoTextVarAutocomplete(
79 // getTokensFn
80 [this]( const wxString& xRef, wxArrayString* tokens )
81 {
82 getContextualTextVars( xRef, tokens );
83 } );
84 } );
85
87
88 m_table = static_cast<SCH_TABLE*>( m_cells[0]->GetParent() );
89
90 if( m_frame->GetColorSettings()->GetOverrideSchItemColors() )
91 m_infoBar->ShowMessage( _( "Note: individual item colors overridden in Preferences." ) );
92
93 m_hAlignLeft->SetIsRadioButton();
95 m_hAlignCenter->SetIsRadioButton();
97 m_hAlignRight->SetIsRadioButton();
99
100 m_vAlignTop->SetIsRadioButton();
102 m_vAlignCenter->SetIsRadioButton();
104 m_vAlignBottom->SetIsRadioButton();
106
108 m_textColorSwatch->SetSwatchBackground( canvas );
109 m_fillColorSwatch->SetSwatchBackground( canvas );
110
112 Layout();
113
114 m_hAlignLeft->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onHAlignButton, this );
117 m_vAlignTop->Bind( wxEVT_BUTTON, &DIALOG_TABLECELL_PROPERTIES::onVAlignButton, this );
120
121 // Now all widgets have the size fixed, call FinishDialogSettings
123}
124
133
134void DIALOG_TABLECELL_PROPERTIES::getContextualTextVars( const wxString& aCrossRef, wxArrayString* aTokens )
135{
136 SCHEMATIC* schematic = m_table->Schematic();
137
138 if( !aCrossRef.IsEmpty() )
139 {
140 SCH_SYMBOL* refSymbol = nullptr;
141
142 if( schematic )
143 {
145 schematic->Hierarchy().GetSymbols( refs, SYMBOL_FILTER_NON_POWER );
146
147 for( int jj = 0; jj < (int) refs.GetCount(); jj++ )
148 {
149 SCH_REFERENCE& ref = refs[jj];
150
151 if( ref.GetSymbol()->GetRef( &ref.GetSheetPath(), true ) == aCrossRef )
152 {
153 refSymbol = ref.GetSymbol();
154 break;
155 }
156 }
157 }
158
159 if( refSymbol )
160 refSymbol->GetContextualTextVars( aTokens );
161 }
162 else
163 {
164 if( schematic && schematic->CurrentSheet().Last() )
165 {
166 schematic->CurrentSheet().Last()->GetContextualTextVars( aTokens );
167 }
168 else
169 {
170 for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
171 aTokens->push_back( entry.first );
172 }
173 }
174}
175
176
178{
179 if( !wxDialog::TransferDataToWindow() )
180 return false;
181
182 bool firstCell = true;
185
186 for( SCH_TABLECELL* cell : m_cells )
187 {
188 wxString text = cell->GetText();
189
190 // show text variable cross-references in a human-readable format
191 if( SCHEMATIC* schematic = cell->Schematic() )
192 text = schematic->ConvertKIIDsToRefs( text );
193
194 m_cellText->SetValue( text );
195 m_cellText->EmptyUndoBuffer();
196
197 if( firstCell )
198 {
199 m_fontCtrl->SetFontSelection( cell->GetFont() );
200 m_textSize.SetValue( cell->GetTextWidth() );
201
202 m_bold->Set3StateValue( cell->IsBold() ? wxCHK_CHECKED : wxCHK_UNCHECKED );
203 m_italic->Set3StateValue( cell->IsItalic() ? wxCHK_CHECKED : wxCHK_UNCHECKED );
204
205 hAlign = cell->GetHorizJustify();
206 vAlign = cell->GetVertJustify();
207
208 m_textColorBook->SetSelection( 1 );
209 m_textColorSwatch->SetSwatchColor( cell->GetTextColor(), false );
210 m_textColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
211
212 m_fillColorBook->SetSelection( 1 );
213
214 if( cell->IsSolidFill() )
215 m_fillColorSwatch->SetSwatchColor( cell->GetFillColor(), false );
216 else
217 m_fillColorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
218
219 m_fillColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
220
221 m_marginLeft.SetValue( cell->GetMarginLeft() );
222 m_marginTop.SetValue( cell->GetMarginTop() );
223 m_marginRight.SetValue( cell->GetMarginRight() );
224 m_marginBottom.SetValue( cell->GetMarginBottom() );
225
226 firstCell = false;
227 }
228 else
229 {
230 if( cell->GetFont() != m_fontCtrl->GetFontSelection( cell->IsBold(), cell->IsItalic() ) )
231 m_fontCtrl->SetSelection( -1 );
232
233 if( cell->GetTextWidth() != m_textSize.GetValue() )
235
236 wxCheckBoxState bold = cell->IsBold() ? wxCHK_CHECKED : wxCHK_UNCHECKED;
237
238 if( bold != m_bold->Get3StateValue() )
239 m_bold->Set3StateValue( wxCHK_UNDETERMINED );
240
241 wxCheckBoxState italic = cell->IsItalic() ? wxCHK_CHECKED : wxCHK_UNCHECKED;
242
243 if( italic != m_italic->Get3StateValue() )
244 m_italic->Set3StateValue( wxCHK_UNDETERMINED );
245
246 if( cell->GetHorizJustify() != hAlign )
248
249 if( cell->GetVertJustify() != vAlign )
251
252 if( cell->GetTextColor() != m_textColorSwatch->GetSwatchColor() )
253 {
254 m_textColorBook->SetSelection( 0 );
255 m_textColorPopup->SetSelection( 0 );
256 }
257
258 COLOR4D fillColor = cell->IsSolidFill() ? cell->GetFillColor() : COLOR4D::UNSPECIFIED;
259
260 if( fillColor != m_fillColorSwatch->GetSwatchColor() )
261 {
262 m_fillColorBook->SetSelection( 0 );
263 m_fillColorPopup->SetSelection( 0 );
264 }
265
266 if( fillColor != m_fillColorSwatch->GetSwatchColor() )
267 fillColor = COLOR4D::UNSPECIFIED;
268
269 if( cell->GetMarginLeft() != m_marginLeft.GetIntValue() )
271
272 if( cell->GetMarginTop() != m_marginTop.GetIntValue() )
274
275 if( cell->GetMarginRight() != m_marginRight.GetIntValue() )
277
278 if( cell->GetMarginBottom() != m_marginBottom.GetIntValue() )
280 }
281
282 m_hAlignLeft->Check( false );
283 m_hAlignCenter->Check( false );
284 m_hAlignRight->Check( false );
285
286 switch( hAlign )
287 {
288 case GR_TEXT_H_ALIGN_LEFT: m_hAlignLeft->Check(); break;
289 case GR_TEXT_H_ALIGN_CENTER: m_hAlignCenter->Check(); break;
290 case GR_TEXT_H_ALIGN_RIGHT: m_hAlignRight->Check(); break;
292 }
293
294 m_vAlignTop->Check( false );
295 m_vAlignCenter->Check( false );
296 m_vAlignBottom->Check( false );
297
298 switch( vAlign )
299 {
300 case GR_TEXT_V_ALIGN_TOP: m_vAlignTop->Check(); break;
301 case GR_TEXT_V_ALIGN_CENTER: m_vAlignCenter->Check(); break;
302 case GR_TEXT_V_ALIGN_BOTTOM: m_vAlignBottom->Check(); break;
304 }
305 }
306
307 return true;
308}
309
310
312{
314 {
315 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
316 btn->Check( false );
317 }
318}
319
320
322{
324 {
325 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
326 btn->Check( false );
327 }
328}
329
330
332{
333 if( aEvent.GetSelection() == 1 )
334 {
335 m_textColorBook->SetSelection( 1 );
336 m_textColorSwatch->GetNewSwatchColor();
337 }
338}
339
340
342{
343 if( aEvent.GetSelection() == 1 )
344 {
345 m_fillColorBook->SetSelection( 1 );
346 m_fillColorSwatch->GetNewSwatchColor();
347 }
348}
349
350
352{
353 if( !wxDialog::TransferDataFromWindow() )
354 return false;
355
356 SCH_COMMIT commit( m_frame );
357
358 /* save table in undo list if not already in edit */
359 if( m_table->GetEditFlags() == 0 )
360 commit.Modify( m_table, m_frame->GetScreen() );
361
362 for( SCH_TABLECELL* cell : m_cells )
363 {
364 wxString text = m_cellTextCtrl->GetValue();
365
366 // convert any text variable cross-references to their UUIDs
367 if( SCHEMATIC* schematic = cell->Schematic() )
368 text = schematic->ConvertRefsToKIIDs( text );
369
370#ifdef __WXMAC__
371 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting
372 text.Replace( "\r", "\n" );
373#elif defined( __WINDOWS__ )
374 // On Windows, a new line is coded as \r\n. We use only \n in KiCad files and in
375 // drawing routines so strip the \r char.
376 text.Replace( "\r", "" );
377#endif
378
379 cell->SetText( text );
380
381 if( m_bold->Get3StateValue() == wxCHK_CHECKED )
382 cell->SetBold( true );
383 else if( m_bold->Get3StateValue() == wxCHK_UNCHECKED )
384 cell->SetBold( false );
385
386 if( m_italic->Get3StateValue() == wxCHK_CHECKED )
387 cell->SetItalic( true );
388 else if( m_italic->Get3StateValue() == wxCHK_UNCHECKED )
389 cell->SetItalic( false );
390
391 if( m_fontCtrl->HaveFontSelection() )
392 cell->SetFont( m_fontCtrl->GetFontSelection( cell->IsBold(), cell->IsItalic() ) );
393
394 if( !m_textSize.IsIndeterminate() )
395 cell->SetTextSize( VECTOR2I( m_textSize.GetIntValue(), m_textSize.GetIntValue() ) );
396
397 if( m_hAlignLeft->IsChecked() )
398 cell->SetHorizJustify( GR_TEXT_H_ALIGN_LEFT );
399 else if( m_hAlignRight->IsChecked() )
400 cell->SetHorizJustify( GR_TEXT_H_ALIGN_RIGHT );
401 else if( m_hAlignCenter->IsChecked() )
402 cell->SetHorizJustify( GR_TEXT_H_ALIGN_CENTER );
403
404 if( m_vAlignTop->IsChecked() )
405 cell->SetVertJustify( GR_TEXT_V_ALIGN_TOP );
406 else if( m_vAlignBottom->IsChecked() )
407 cell->SetVertJustify( GR_TEXT_V_ALIGN_BOTTOM );
408 else if( m_vAlignCenter->IsChecked() )
409 cell->SetVertJustify( GR_TEXT_V_ALIGN_CENTER );
410
411 if( m_textColorBook->GetSelection() == 1 )
412 cell->SetTextColor( m_textColorSwatch->GetSwatchColor() );
413
414 if( m_fillColorBook->GetSelection() == 1 )
415 {
416 COLOR4D fillColor = m_fillColorSwatch->GetSwatchColor();
417
418 if( fillColor == COLOR4D::UNSPECIFIED )
419 {
420 cell->SetFillMode( FILL_T::NO_FILL );
421 }
422 else
423 {
424 cell->SetFillMode( FILL_T::FILLED_WITH_COLOR );
425 cell->SetFillColor( fillColor );
426 }
427 }
428
429 if( !m_marginLeft.IsIndeterminate() )
430 cell->SetMarginLeft( m_marginLeft.GetIntValue() );
431
432 if( !m_marginTop.IsIndeterminate() )
433 cell->SetMarginTop( m_marginTop.GetIntValue() );
434
435 if( !m_marginRight.IsIndeterminate() )
436 cell->SetMarginRight( m_marginRight.GetIntValue() );
437
438 if( !m_marginBottom.IsIndeterminate() )
439 cell->SetMarginBottom( m_marginBottom.GetIntValue() );
440 }
441
442 if( !commit.Empty() )
443 commit.Push( _( "Edit Table Cell Properties" ) );
444
446 return true;
447}
448
449
450void DIALOG_TABLECELL_PROPERTIES::onEditTable( wxCommandEvent& aEvent )
451{
453 {
455 Close();
456 }
457}
458
460{
462 m_scintillaTricks->CancelAutocomplete();
463
464 event.Skip();
465}
466
467
468void DIALOG_TABLECELL_PROPERTIES::OnFormattingHelp( wxHyperlinkEvent& aEvent )
469{
470 if( m_helpWindow )
471 {
472 m_helpWindow->Raise();
473 m_helpWindow->Show( true );
474 return;
475 }
476
478}
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
@ text_align_right
@ text_valign_top
@ text_align_left
@ text_valign_center
@ text_align_center
@ text_valign_bottom
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:400
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 SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition dialog_shim.h:94
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_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)
void onTextColorPopup(wxCommandEvent &aEvent) override
void onFillColorPopup(wxCommandEvent &aEvent) override
DIALOG_TABLECELL_PROPERTIES(SCH_EDIT_FRAME *aParentFrame, std::vector< SCH_TABLECELL * > aCells)
void OnFormattingHelp(wxHyperlinkEvent &aEvent) override
void getContextualTextVars(const wxString &aCrossRef, wxArrayString *aTokens)
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_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
SCH_SHEET_PATH & CurrentSheet() const
Definition schematic.h:312
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.
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
void GetSymbols(SCH_REFERENCE_LIST &aReferences, SYMBOL_FILTER aSymbolFilter, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
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:75
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
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
#define _(s)
@ FILLED_WITH_COLOR
Definition eda_fill.h:33
@ NO_FILL
Definition eda_fill.h:30
@ LAYER_SCHEMATIC_BACKGROUND
Definition layer_ids.h:516
STL namespace.
@ SYMBOL_FILTER_NON_POWER
GR_TEXT_H_ALIGN_T
This is API surface mapped to common.types.HorizontalAlignment.
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
GR_TEXT_V_ALIGN_T
This is API surface mapped to common.types.VertialAlignment.
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_INDETERMINATE
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition ui_common.h:47
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708