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@verizon.net>
6  * Copyright (C) 1992-2020 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_component.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  // DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
131  // various versions have different controls so we want to store sizes for each version.
132  m_hash_key = TO_UTF8( GetTitle() );
133 
134 
135  // Now all widgets have the size fixed, call FinishDialogSettings
137 }
138 
139 
141 {
142  delete m_scintillaTricks;
143 
144  if( m_helpWindow )
145  m_helpWindow->Destroy();
146 }
147 
148 
150 {
151  if( !wxDialog::TransferDataToWindow() )
152  return false;
153 
154  if( m_CurrentText->Type() == SCH_TEXT_T )
155  {
156  SCHEMATIC& schematic = m_Parent->Schematic();
157 
158  // show text variable cross-references in a human-readable format
159  m_valueMultiLine->SetValue( schematic.ConvertKIIDsToRefs( m_CurrentText->GetText() ) );
160  }
161  else
162  {
163  // show control characters in a human-readable format
165  }
166 
167  if( m_valueCombo->IsShown() )
168  {
169  // Load the combobox with the existing labels of the same type
170  std::set<wxString> existingLabels;
171  SCH_SCREENS allScreens( m_Parent->Schematic().Root() );
172 
173  for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
174  {
175  for( SCH_ITEM* item : screen->Items().OfType( m_CurrentText->Type() ) )
176  {
177  auto textItem = static_cast<const SCH_TEXT*>( item );
178  existingLabels.insert( UnescapeString( textItem->GetText() ) );
179  }
180  }
181 
182  wxArrayString existingLabelArray;
183 
184  for( const wxString& label : existingLabels )
185  existingLabelArray.push_back( label );
186 
187  // existingLabelArray.Sort();
188  m_valueCombo->Append( existingLabelArray );
189  }
190 
191  // Set text options:
192  m_TextOrient->SetSelection( static_cast<int>( m_CurrentText->GetLabelSpinStyle() ) );
193 
194  m_TextShape->SetSelection( static_cast<int>( m_CurrentText->GetShape() ) );
195 
196  int style = 0;
197 
198  if( m_CurrentText->IsItalic() )
199  style = 1;
200 
201  if( m_CurrentText->IsBold() )
202  style += 2;
203 
204  m_TextStyle->SetSelection( style );
205 
207 
208  return true;
209 }
210 
211 
215 void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
216 {
217  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
218 }
219 
220 
221 void DIALOG_LABEL_EDITOR::onScintillaCharAdded( wxStyledTextEvent &aEvent )
222 {
223  wxStyledTextCtrl* te = m_valueMultiLine;
224  wxArrayString autocompleteTokens;
225  int text_pos = te->GetCurrentPos();
226  int start = te->WordStartPosition( text_pos, true );
227  wxString partial;
228 
229  auto textVarRef =
230  [&]( int pos )
231  {
232  return pos >= 2 && te->GetCharAt( pos-2 ) == '$' && te->GetCharAt( pos-1 ) == '{';
233  };
234 
235  // Check for cross-reference
236  if( start > 1 && te->GetCharAt( start-1 ) == ':' )
237  {
238  int refStart = te->WordStartPosition( start-1, true );
239 
240  if( textVarRef( refStart ) )
241  {
242  partial = te->GetRange( start+1, text_pos );
243 
244  wxString ref = te->GetRange( refStart, start-1 );
246  SCH_REFERENCE_LIST refs;
247  SCH_COMPONENT* refSymbol = nullptr;
248 
249  sheets.GetSymbols( refs );
250 
251  for( size_t jj = 0; jj < refs.GetCount(); jj++ )
252  {
253  if( refs[ jj ].GetSymbol()->GetRef( &refs[ jj ].GetSheetPath(), true ) == ref )
254  {
255  refSymbol = refs[ jj ].GetSymbol();
256  break;
257  }
258  }
259 
260  if( refSymbol )
261  refSymbol->GetContextualTextVars( &autocompleteTokens );
262  }
263  }
264  else if( textVarRef( start ) )
265  {
266  partial = te->GetTextRange( start, text_pos );
267 
268  m_CurrentText->GetContextualTextVars( &autocompleteTokens );
269 
270  SCHEMATIC* schematic = m_CurrentText->Schematic();
271 
272  if( schematic && schematic->CurrentSheet().Last() )
273  schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
274 
275  for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
276  autocompleteTokens.push_back( entry.first );
277  }
278 
279  m_scintillaTricks->DoAutocomplete( partial, autocompleteTokens );
280  m_valueMultiLine->SetFocus();
281 }
282 
283 
285 {
286  if( !wxDialog::TransferDataFromWindow() )
287  return false;
288 
289  // Don't allow text to disappear; it can be difficult to correct if you can't select it
290  if( !m_textSize.Validate( 0.01, 1000.0, EDA_UNITS::MILLIMETRES ) )
291  return false;
292 
293  wxString text;
294 
295  /* save old text in undo list if not already in edit */
296  if( m_CurrentText->GetEditFlags() == 0 )
298 
299  m_Parent->GetCanvas()->Refresh();
300 
301  if( m_CurrentText->Type() == SCH_TEXT_T )
302  {
303  // convert any text variable cross-references to their UUIDs
304  text = m_Parent->Schematic().ConvertRefsToKIIDs( m_valueMultiLine->GetValue() );
305  }
306  else
307  {
308  // labels need escaping
309  text = EscapeString( m_activeTextEntry->GetValue(), CTX_NETNAME );
310  }
311 
312  if( !text.IsEmpty() )
313  {
314  m_CurrentText->SetText( text );
315  }
316  else if( !m_CurrentText->IsNew() )
317  {
318  DisplayError( this, _( "Empty Text!" ) );
319  return false;
320  }
321 
323 
325 
326  if( m_TextShape )
328 
329  int style = m_TextStyle->GetSelection();
330 
331  m_CurrentText->SetItalic( ( style & 1 ) );
332 
333  if( ( style & 2 ) )
334  {
335  m_CurrentText->SetBold( true );
337  }
338  else
339  {
340  m_CurrentText->SetBold( false );
341  m_CurrentText->SetTextThickness( 0 ); // Use default pen width
342  }
343 
345  m_Parent->GetCanvas()->Refresh();
346  m_Parent->OnModify();
347 
349  {
350  SCH_GLOBALLABEL* label = static_cast<SCH_GLOBALLABEL*>( m_CurrentText );
351  label->UpdateIntersheetRefProps();
352  }
353 
354  return true;
355 }
356 
357 
358 void DIALOG_LABEL_EDITOR::OnFormattingHelp( wxHyperlinkEvent& aEvent )
359 {
361 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:240
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
bool IsBold() const
Definition: eda_text.h:189
void SetTitle(const wxString &aTitle) override
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:237
void UpdateItem(EDA_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
SCH_SHEET_LIST GetSheets() const
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:97
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false) const
Add a SCH_REFERENCE object to aReferences for each component in the list of sheets.
wxTextEntry * m_activeTextEntry
int GetPenSizeForBold(int aTextSize)
Function GetPensizeForBold.
Definition: gr_text.cpp:48
Holds all the data relating to one schematic A schematic may consist of one or more sheets (and one r...
Definition: schematic.h:44
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:191
SCINTILLA_TRICKS is used to add cut/copy/paste, autocomplete and brace highlighting to a wxStyleTextC...
void DoAutocomplete(const wxString &aPartial, const wxArrayString &aTokens)
void SetItalic(bool isItalic)
Definition: eda_text.h:185
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:191
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:114
DIALOG_LABEL_EDITOR(SCH_EDIT_FRAME *parent, SCH_TEXT *aTextItem)
SCH_REFERENCE_LIST is used to create a flattened list of symbols because in a complex hierarchy,...
bool IsNew() const
Definition: eda_item.h:187
bool IsItalic() const
Definition: eda_text.h:186
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:95
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:243
STATUS_FLAGS GetEditFlags() const
Definition: eda_item.h:225
PROJECT & Prj() const
Function Prj returns 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
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend, const wxPoint &aTransformPoint=wxPoint(0, 0))
Create a copy of the current schematic item, and put it in the undo list.
LABEL_SPIN_STYLE GetLabelSpinStyle() const
Definition: sch_text.h:233
SCINTILLA_TRICKS * m_scintillaTricks
void UpdateIntersheetRefProps()
Definition: sch_text.cpp:1057
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
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
unsigned GetCount() const
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:303
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_text.cpp:1504
PINSHEETLABEL_SHAPE
Definition: sch_text.h:151
SCH_SHEET & Root() const
Definition: schematic.h:102
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Function Validate Validates the control against the given range, informing the user of any errors fou...
int GetTextWidth() const
Definition: eda_text.h:248
#define _(s)
Definition: 3d_actions.cpp:33
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:152
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:77
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
Schematic symbol object.
Definition: sch_component.h:79
HTML_MESSAGE_BOX * m_helpWindow
virtual long long int GetValue()
Function GetValue Returns 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:164
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
void SetBold(bool aBold)
Definition: eda_text.h:188
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:194
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:521
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:235
KICAD_T Type() const
Function Type()
Definition: eda_item.h:181
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:127