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 <fctsys.h>
27 #include <sch_edit_frame.h>
28 #include <base_units.h>
29 #include <sch_validators.h>
30 #include <tool/tool_manager.h>
31 #include <general.h>
32 #include <gr_text.h>
33 #include <confirm.h>
34 #include <sch_component.h>
35 #include <sch_reference_list.h>
36 #include <schematic.h>
37 #include <widgets/unit_binder.h>
38 #include <html_messagebox.h>
39 #include <dialog_edit_label.h>
40 #include <kicad_string.h>
41 #include <tool/actions.h>
42 #include <scintilla_tricks.h>
43 
44 class SCH_EDIT_FRAME;
45 class SCH_TEXT;
46 
47 
49  DIALOG_LABEL_EDITOR_BASE( aParent ),
50  m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false ),
51  m_netNameValidator( true ),
52  m_scintillaTricks( nullptr ),
53  m_helpWindow( nullptr )
54 {
55  m_Parent = aParent;
56  m_CurrentText = aTextItem;
57 
58  switch( m_CurrentText->Type() )
59  {
60  case SCH_GLOBAL_LABEL_T: SetTitle( _( "Global Label Properties" ) ); break;
61  case SCH_HIER_LABEL_T: SetTitle( _( "Hierarchical Label Properties" ) ); break;
62  case SCH_LABEL_T: SetTitle( _( "Label Properties" ) ); break;
63  case SCH_SHEET_PIN_T: SetTitle( _( "Hierarchical Sheet Pin Properties" ) ); break;
64  default: SetTitle( _( "Text Properties" ) ); break;
65  }
66 
67  m_valueMultiLine->SetEOLMode( wxSTC_EOL_LF );
68 
70 
72  {
74  m_activeTextEntry = nullptr;
75 
76  m_labelSingleLine->Show( false );
77  m_valueSingleLine->Show( false );
78  m_labelCombo->Show( false );
79  m_valueCombo->Show( false );
80 
81  m_textEntrySizer->AddGrowableRow( 0 );
82  }
84  {
87 
88  m_labelSingleLine->Show( false ); m_valueSingleLine->Show( false );
89  m_labelMultiLine->Show( false ); m_valueMultiLine->Show( false );
90 
91  m_valueCombo->SetValidator( m_netNameValidator );
92  }
93  else
94  {
97 
98  m_labelCombo->Show( false );
99  m_valueCombo->Show( false );
100  m_labelMultiLine->Show( false );
101  m_valueMultiLine->Show( false );
102 
103  if( m_CurrentText->Type() != SCH_TEXT_T )
104  m_valueSingleLine->SetValidator( m_netNameValidator );
105 
106  m_valueCombo->SetValidator( m_netNameValidator );
107  }
108 
110 
113 
115  {
116  wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
117  infoFont.SetSymbolicSize( wxFONTSIZE_X_SMALL );
118  m_note1->SetFont( infoFont );
119  m_note2->SetFont( infoFont );
120  }
121  else
122  {
123  m_note1->Show( false );
124  m_note2->Show( false );
125  }
126 
127  m_sdbSizer1OK->SetDefault();
128  Layout();
129 
130  m_valueMultiLine->Bind( wxEVT_STC_CHARADDED, &DIALOG_LABEL_EDITOR::onScintillaCharAdded, this );
131 
132  // DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
133  // various versions have different controls so we want to store sizes for each version.
134  m_hash_key = TO_UTF8( GetTitle() );
135 
136 
137  // Now all widgets have the size fixed, call FinishDialogSettings
139 }
140 
141 
143 {
144  delete m_scintillaTricks;
145 
146  if( m_helpWindow )
147  m_helpWindow->Destroy();
148 }
149 
150 
152 {
153  if( !wxDialog::TransferDataToWindow() )
154  return false;
155 
156  if( m_CurrentText->Type() == SCH_TEXT_T )
157  {
158  SCHEMATIC& schematic = m_Parent->Schematic();
159 
160  // show text variable cross-references in a human-readable format
161  m_valueMultiLine->SetValue( schematic.ConvertKIIDsToRefs( m_CurrentText->GetText() ) );
162  }
163  else
164  {
165  // show control characters in a human-readable format
167  }
168 
169  if( m_valueCombo->IsShown() )
170  {
171  // Load the combobox with the existing labels of the same type
172  std::set<wxString> existingLabels;
173  SCH_SCREENS allScreens( m_Parent->Schematic().Root() );
174 
175  for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
176  {
177  for( SCH_ITEM* item : screen->Items().OfType( m_CurrentText->Type() ) )
178  {
179  auto textItem = static_cast<const SCH_TEXT*>( item );
180  existingLabels.insert( UnescapeString( textItem->GetText() ) );
181  }
182  }
183 
184  wxArrayString existingLabelArray;
185 
186  for( const wxString& label : existingLabels )
187  existingLabelArray.push_back( label );
188 
189  // existingLabelArray.Sort();
190  m_valueCombo->Append( existingLabelArray );
191  }
192 
193  // Set text options:
194  m_TextOrient->SetSelection( static_cast<int>( m_CurrentText->GetLabelSpinStyle() ) );
195 
196  m_TextShape->SetSelection( static_cast<int>( m_CurrentText->GetShape() ) );
197 
198  int style = 0;
199 
200  if( m_CurrentText->IsItalic() )
201  style = 1;
202 
203  if( m_CurrentText->IsBold() )
204  style += 2;
205 
206  m_TextStyle->SetSelection( style );
207 
209 
210  return true;
211 }
212 
213 
217 void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
218 {
219  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
220 }
221 
222 
223 void DIALOG_LABEL_EDITOR::onScintillaCharAdded( wxStyledTextEvent &aEvent )
224 {
225  wxStyledTextCtrl* te = m_valueMultiLine;
226  wxArrayString autocompleteTokens;
227  int text_pos = te->GetCurrentPos();
228  int start = te->WordStartPosition( text_pos, true );
229  wxString partial;
230 
231  auto textVarRef =
232  [&]( int pos )
233  {
234  return pos >= 2 && te->GetCharAt( pos-2 ) == '$' && te->GetCharAt( pos-1 ) == '{';
235  };
236 
237  // Check for cross-reference
238  if( start > 1 && te->GetCharAt( start-1 ) == ':' )
239  {
240  int refStart = te->WordStartPosition( start-1, true );
241 
242  if( textVarRef( refStart ) )
243  {
244  partial = te->GetRange( start+1, text_pos );
245 
246  wxString ref = te->GetRange( refStart, start-1 );
248  SCH_REFERENCE_LIST refs;
249  SCH_COMPONENT* refComponent = nullptr;
250 
251  sheets.GetComponents( refs );
252 
253  for( size_t jj = 0; jj < refs.GetCount(); jj++ )
254  {
255  if( refs[ jj ].GetComp()->GetRef( &refs[ jj ].GetSheetPath(), true ) == ref )
256  {
257  refComponent = refs[ jj ].GetComp();
258  break;
259  }
260  }
261 
262  if( refComponent )
263  refComponent->GetContextualTextVars( &autocompleteTokens );
264  }
265  }
266  else if( textVarRef( start ) )
267  {
268  partial = te->GetTextRange( start, text_pos );
269 
270  m_CurrentText->GetContextualTextVars( &autocompleteTokens );
271 
272  SCHEMATIC* schematic = m_CurrentText->Schematic();
273 
274  if( schematic && schematic->CurrentSheet().Last() )
275  schematic->CurrentSheet().Last()->GetContextualTextVars( &autocompleteTokens );
276 
277  for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
278  autocompleteTokens.push_back( entry.first );
279  }
280 
281  m_scintillaTricks->DoAutocomplete( partial, autocompleteTokens );
282  m_valueMultiLine->SetFocus();
283 }
284 
285 
287 {
288  if( !wxDialog::TransferDataFromWindow() )
289  return false;
290 
291  // Don't allow text to disappear; it can be difficult to correct if you can't select it
292  if( !m_textSize.Validate( 0.01, 1000.0, EDA_UNITS::MILLIMETRES ) )
293  return false;
294 
295  wxString text;
296 
297  /* save old text in undo list if not already in edit */
298  if( m_CurrentText->GetEditFlags() == 0 )
300 
301  m_Parent->GetCanvas()->Refresh();
302 
303  if( m_CurrentText->Type() == SCH_TEXT_T )
304  {
305  // convert any text variable cross-references to their UUIDs
306  text = m_Parent->Schematic().ConvertRefsToKIIDs( m_valueMultiLine->GetValue() );
307  }
308  else
309  {
310  // labels need escaping
311  text = EscapeString( m_activeTextEntry->GetValue(), CTX_NETNAME );
312  }
313 
314  if( !text.IsEmpty() )
315  m_CurrentText->SetText( text );
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 
348  return true;
349 }
350 
351 
352 void DIALOG_LABEL_EDITOR::OnFormattingHelp( wxHyperlinkEvent& aEvent )
353 {
355 }
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:239
SCH_SHEET_LIST.
bool IsBold() const
Definition: eda_text.h:183
void SetTitle(const wxString &aTitle) override
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:241
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:89
wxTextEntry * m_activeTextEntry
int GetPenSizeForBold(int aTextSize)
Function GetPensizeForBold.
Definition: gr_text.cpp:51
Holds all the data relating to one schematic A schematic may consist of one or more sheets (and one r...
Definition: schematic.h:42
SCH_SHEET * Last() const
Function Last returns a pointer to the last sheet of the list One can see the others sheet as the "pa...
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:198
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:179
void OnEnterKey(wxCommandEvent &aEvent) override
bool TransferDataToWindow() override
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:116
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
Definition: sch_sheet.cpp:190
Schematic editor (Eeschema) main window.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:238
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 components because in a complex hierarchy,...
bool IsNew() const
Definition: base_struct.h:199
bool IsItalic() const
Definition: eda_text.h:180
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:100
void GetContextualTextVars(wxArrayString *aVars) const
Returns the set of contextual text variable tokens for this text item.
Definition: sch_text.cpp:473
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:198
void GetComponents(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanComponents=false) const
Function GetComponents adds a SCH_REFERENCE() object to aReferences for each component in the list of...
STATUS_FLAGS GetEditFlags() const
Definition: base_struct.h:237
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:234
SCINTILLA_TRICKS * m_scintillaTricks
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:197
bool TransferDataFromWindow() override
unsigned GetCount() const
Function GetCount.
wxString ConvertKIIDsToRefs(const wxString &aSource) const
Definition: schematic.cpp:258
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED, bool aUseMils=false)
Function Validate Validates the control against the given range, informing the user of any errors fou...
static HTML_MESSAGE_BOX * ShowSyntaxHelp(wxWindow *aParentWindow)
Definition: sch_text.cpp:1236
PINSHEETLABEL_SHAPE
Definition: sch_text.h:152
SCH_SHEET & Root() const
Definition: schematic.h:94
int GetTextWidth() const
Definition: eda_text.h:242
#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:80
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:158
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:229
void SetBold(bool aBold)
Definition: eda_text.h:182
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:127
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:515
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:239
KICAD_T Type() const
Function Type()
Definition: base_struct.h:193
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:119