KiCad PCB EDA Suite
dialog_edit_label.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 (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
6  * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 #include <sch_edit_frame.h>
27 #include <base_units.h>
28 #include <sch_validators.h>
29 #include <tool/tool_manager.h>
30 #include <general.h>
31 #include <gr_text.h>
32 #include <confirm.h>
33 #include <sch_symbol.h>
34 #include <sch_reference_list.h>
35 #include <schematic.h>
37 #include <dialog_edit_label.h>
38 #include <kicad_string.h>
39 #include <tool/actions.h>
40 #include <scintilla_tricks.h>
41 
42 class SCH_EDIT_FRAME;
43 class SCH_TEXT;
44 
45 
47  DIALOG_LABEL_EDITOR_BASE( aParent ),
48  m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false ),
49  m_netNameValidator( true ),
50  m_scintillaTricks( nullptr ),
51  m_helpWindow( nullptr )
52 {
53  m_Parent = aParent;
54  m_CurrentText = aTextItem;
55 
56  switch( m_CurrentText->Type() )
57  {
58  case SCH_GLOBAL_LABEL_T: SetTitle( _( "Global Label Properties" ) ); break;
59  case SCH_HIER_LABEL_T: SetTitle( _( "Hierarchical Label Properties" ) ); break;
60  case SCH_LABEL_T: SetTitle( _( "Label Properties" ) ); break;
61  case SCH_SHEET_PIN_T: SetTitle( _( "Hierarchical Sheet Pin Properties" ) ); break;
62  default: SetTitle( _( "Text Properties" ) ); break;
63  }
64 
65  m_valueMultiLine->SetEOLMode( wxSTC_EOL_LF );
66 
68 
70  {
72  m_activeTextEntry = nullptr;
73 
74  m_labelSingleLine->Show( false );
75  m_valueSingleLine->Show( false );
76  m_labelCombo->Show( false );
77  m_valueCombo->Show( false );
78 
79  m_textEntrySizer->AddGrowableRow( 0 );
80  }
82  {
85 
86  m_labelSingleLine->Show( false ); m_valueSingleLine->Show( false );
87  m_labelMultiLine->Show( false ); m_valueMultiLine->Show( false );
88 
89  m_valueCombo->SetValidator( m_netNameValidator );
90  }
91  else
92  {
95 
96  m_labelCombo->Show( false );
97  m_valueCombo->Show( false );
98  m_labelMultiLine->Show( false );
99  m_valueMultiLine->Show( false );
100 
101  if( m_CurrentText->Type() != SCH_TEXT_T )
102  m_valueSingleLine->SetValidator( m_netNameValidator );
103 
104  m_valueCombo->SetValidator( m_netNameValidator );
105  }
106 
108 
111 
113  {
114  wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
115  infoFont.SetSymbolicSize( wxFONTSIZE_X_SMALL );
116  m_note1->SetFont( infoFont );
117  m_note2->SetFont( infoFont );
118  }
119  else
120  {
121  m_note1->Show( false );
122  m_note2->Show( false );
123  }
124 
125  m_sdbSizer1OK->SetDefault();
126  Layout();
127 
128  m_valueMultiLine->Bind( wxEVT_STC_CHARADDED, &DIALOG_LABEL_EDITOR::onScintillaCharAdded, this );
129 
130  int size = wxNORMAL_FONT->GetPointSize();
131  wxFont fixedFont( size, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
132 
133  for( size_t i = 0; i < wxSTC_STYLE_MAX; ++i )
134  m_valueMultiLine->StyleSetFont( i, fixedFont );
135 
136  // Addresses a bug in wx3.0 where styles are not correctly set
137  m_valueMultiLine->StyleClearAll();
138 
139  // DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
140  // various versions have different controls so we want to store sizes for each version.
141  m_hash_key = TO_UTF8( GetTitle() );
142 
143 
144  // Now all widgets have the size fixed, call FinishDialogSettings
146 }
147 
148 
150 {
151  delete m_scintillaTricks;
152 
153  if( m_helpWindow )
154  m_helpWindow->Destroy();
155 }
156 
157 
159 {
160  if( !wxDialog::TransferDataToWindow() )
161  return false;
162 
163  if( m_CurrentText->Type() == SCH_TEXT_T )
164  {
165  SCHEMATIC& schematic = m_Parent->Schematic();
166 
167  // show text variable cross-references in a human-readable format
168  m_valueMultiLine->SetValue( schematic.ConvertKIIDsToRefs( m_CurrentText->GetText() ) );
169  }
170  else
171  {
172  // show control characters in a human-readable format
174  }
175 
176  if( m_valueCombo->IsShown() )
177  {
178  // Load the combobox with the existing labels of the same type
179  std::set<wxString> existingLabels;
180  SCH_SCREENS allScreens( m_Parent->Schematic().Root() );
181 
182  for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
183  {
184  for( SCH_ITEM* item : screen->Items().OfType( m_CurrentText->Type() ) )
185  {
186  auto textItem = static_cast<const SCH_TEXT*>( item );
187  existingLabels.insert( UnescapeString( textItem->GetText() ) );
188  }
189  }
190 
191  wxArrayString existingLabelArray;
192 
193  for( const wxString& label : existingLabels )
194  existingLabelArray.push_back( label );
195 
196  // existingLabelArray.Sort();
197  m_valueCombo->Append( existingLabelArray );
198  }
199 
200  // Set text options:
201  m_TextOrient->SetSelection( static_cast<int>( m_CurrentText->GetLabelSpinStyle() ) );
202 
203  m_TextShape->SetSelection( static_cast<int>( m_CurrentText->GetShape() ) );
204 
205  int style = 0;
206 
207  if( m_CurrentText->IsItalic() )
208  style = 1;
209 
210  if( m_CurrentText->IsBold() )
211  style += 2;
212 
213  m_TextStyle->SetSelection( style );
214 
216 
217  return true;
218 }
219 
220 
224 void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
225 {
226  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
227 }
228 
229 
230 void DIALOG_LABEL_EDITOR::onScintillaCharAdded( wxStyledTextEvent &aEvent )
231 {
232  wxStyledTextCtrl* te = m_valueMultiLine;
233  wxArrayString autocompleteTokens;
234  int text_pos = te->GetCurrentPos();
235  int start = te->WordStartPosition( text_pos, true );
236  wxString partial;
237 
238  auto textVarRef =
239  [&]( int pos )
240  {
241  return pos >= 2 && te->GetCharAt( pos-2 ) == '$' && te->GetCharAt( pos-1 ) == '{';
242  };
243 
244  // Check for cross-reference
245  if( start > 1 && te->GetCharAt( start-1 ) == ':' )
246  {
247  int refStart = te->WordStartPosition( start-1, true );
248 
249  if( textVarRef( refStart ) )
250  {
251  partial = te->GetRange( start+1, text_pos );
252 
253  wxString ref = te->GetRange( refStart, start-1 );
255  SCH_REFERENCE_LIST refs;
256  SCH_COMPONENT* refSymbol = nullptr;
257 
258  sheets.GetSymbols( refs );
259 
260  for( size_t jj = 0; jj < refs.GetCount(); jj++ )
261  {
262  if( refs[ jj ].GetSymbol()->GetRef( &refs[ jj ].GetSheetPath(), true ) == ref )
263  {
264  refSymbol = refs[ jj ].GetSymbol();
265  break;
266  }
267  }
268 
269  if( refSymbol )
270  refSymbol->GetContextualTextVars( &autocompleteTokens );
271  }
272  }
273  else if( textVarRef( start ) )
274  {
275  partial = te->GetTextRange( start, text_pos );
276 
277  m_CurrentText->GetContextualTextVars( &autocompleteTokens );
278 
279  SCHEMATIC* schematic = m_CurrentText->Schematic();
280 
281  if( schematic && schematic->CurrentSheet().Last() )
282  schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
283 
284  for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
285  autocompleteTokens.push_back( entry.first );
286  }
287 
288  m_scintillaTricks->DoAutocomplete( partial, autocompleteTokens );
289  m_valueMultiLine->SetFocus();
290 }
291 
292 
294 {
295  if( !wxDialog::TransferDataFromWindow() )
296  return false;
297 
298  // Don't allow text to disappear; it can be difficult to correct if you can't select it
299  if( !m_textSize.Validate( 0.01, 1000.0, EDA_UNITS::MILLIMETRES ) )
300  return false;
301 
302  wxString text;
303 
304  /* save old text in undo list if not already in edit */
305  if( m_CurrentText->GetEditFlags() == 0 )
307 
308  m_Parent->GetCanvas()->Refresh();
309 
310  if( m_CurrentText->Type() == SCH_TEXT_T )
311  {
312  // convert any text variable cross-references to their UUIDs
314  }
315  else
316  {
317  // labels need escaping
319  }
320 
321  if( !text.IsEmpty() )
322  {
324  }
325  else if( !m_CurrentText->IsNew() )
326  {
327  DisplayError( this, _( "Label requires non-empty text." ) );
328  return false;
329  }
330 
332 
334 
335  if( m_TextShape )
337 
338  int style = m_TextStyle->GetSelection();
339 
340  m_CurrentText->SetItalic( ( style & 1 ) );
341 
342  if( ( style & 2 ) )
343  {
344  m_CurrentText->SetBold( true );
346  }
347  else
348  {
349  m_CurrentText->SetBold( false );
350  m_CurrentText->SetTextThickness( 0 ); // Use default pen width
351  }
352 
354  m_Parent->GetCanvas()->Refresh();
355  m_Parent->OnModify();
356 
358  {
359  SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_CurrentText );
360  label->UpdateIntersheetRefProps();
361  }
362 
363  return true;
364 }
365 
366 
367 void DIALOG_LABEL_EDITOR::OnFormattingHelp( wxHyperlinkEvent& aEvent )
368 {
370 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:252
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
bool IsBold() const
Definition: eda_text.h:190
void SetTitle(const wxString &aTitle) override
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:219
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
wxTextEntry * m_activeTextEntry
int GetPenSizeForBold(int aTextSize)
Function GetPensizeForBold.
Definition: gr_text.cpp:48
Holds all the data relating to one schematic.
Definition: schematic.h:59
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, 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.
Implementation of conversion functions that require both schematic and board internal units.
This file is part of the common library.
void onScintillaCharAdded(wxStyledTextEvent &aEvent)
std::string m_hash_key
Definition: dialog_shim.h:200
Add cut/copy/paste, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
void DoAutocomplete(const wxString &aPartial, const wxArrayString &aTokens)
void SetItalic(bool isItalic)
Definition: eda_text.h:186
void OnEnterKey(wxCommandEvent &aEvent) override
bool TransferDataToWindow() override
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:97
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
Definition: sch_sheet.cpp:196
Schematic editor (Eeschema) main window.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:244
Class DIALOG_LABEL_EDITOR_BASE.
SCH_EDIT_FRAME * m_Parent
wxFlexGridSizer * m_textEntrySizer
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:98
DIALOG_LABEL_EDITOR(SCH_EDIT_FRAME *parent, SCH_TEXT *aTextItem)
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
bool IsNew() const
Definition: eda_item.h:169
bool IsItalic() const
Definition: eda_text.h:187
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:96
void GetContextualTextVars(wxArrayString *aVars) const
Returns the set of contextual text variable tokens for this text item.
Definition: sch_text.cpp:498
void OnFormattingHelp(wxHyperlinkEvent &aEvent) override
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
wxString ConvertRefsToKIIDs(const wxString &aSource) const
Definition: schematic.cpp:247
STATUS_FLAGS GetEditFlags() const
Definition: eda_item.h:208
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
SCH_NETNAME_VALIDATOR m_netNameValidator
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Definitions of control validators for schematic dialogs.
SCHEMATIC & Schematic() const
size_t GetCount() const
LABEL_SPIN_STYLE GetLabelSpinStyle() const
Definition: sch_text.h:215
SCINTILLA_TRICKS * m_scintillaTricks
void UpdateIntersheetRefProps()
Definition: sch_text.cpp:1093
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
Definition: sch_symbol.cpp:918
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
bool IsMultilineAllowed() const
Definition: eda_text.h:203
bool TransferDataFromWindow() override
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:307
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_text.cpp:1573
PINSHEETLABEL_SHAPE
Definition: sch_text.h:151
SCH_SHEET & Root() const
Definition: schematic.h:92
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
int GetTextWidth() const
Definition: eda_text.h:248
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend)
Create a copy of the current schematic item, and put it in the undo list.
#define _(s)
Definition: 3d_actions.cpp:33
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:151
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
These Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which ar...
Definition: string.cpp:78
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
Schematic symbol object.
Definition: sch_symbol.h:78
HTML_MESSAGE_BOX * m_helpWindow
virtual long long int GetValue()
Return the current value in Internal Units.
wxStyledTextCtrl * m_valueMultiLine
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:166
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
virtual void SetLabelSpinStyle(LABEL_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:248
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:119
void SetBold(bool aBold)
Definition: eda_text.h:189
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:197
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:549
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:217
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:163