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-2018 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 
31 #include <fctsys.h>
32 #include <sch_edit_frame.h>
33 #include <base_units.h>
34 #include <validators.h>
35 
36 #include <sch_draw_panel.h>
37 #include <general.h>
38 #include <draw_graphic_text.h>
39 #include <confirm.h>
40 #include <sch_text.h>
41 #include <typeinfo>
42 #include <widgets/unit_binder.h>
43 
44 #include <dialog_edit_label_base.h>
45 #include <kicad_string.h>
46 
47 class SCH_EDIT_FRAME;
48 class SCH_TEXT;
49 
50 
52 {
53 public:
54  DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* parent, SCH_TEXT* aTextItem );
56 
57  void SetTitle( const wxString& aTitle ) override
58  {
59  // This class is shared for numerous tasks: a couple of single line labels and
60  // multi-line text fields. Since the desired size of the multi-line text field editor
61  // is often larger, we retain separate sizes based on the dialog titles.
62  switch( m_CurrentText->Type() )
63  {
64  case SCH_GLOBAL_LABEL_T:
65  case SCH_HIER_LABEL_T:
66  case SCH_LABEL_T:
67  // labels can share retained settings probably.
68  break;
69 
70  default:
71  m_hash_key = TO_UTF8( aTitle );
72  m_hash_key += typeid(*this).name();
73  }
74 
75  DIALOG_LABEL_EDITOR_BASE::SetTitle( aTitle );
76  }
77 
78 private:
79  virtual void OnEnterKey( wxCommandEvent& aEvent ) override;
80  void OnCharHook( wxKeyEvent& aEvent );
81 
82  bool TransferDataToWindow() override;
83  bool TransferDataFromWindow() override;
84 
87  wxWindow* m_activeTextCtrl;
88  wxTextEntry* m_activeTextEntry;
91 };
92 
93 
95 {
96  if( aTextItem == NULL )
97  return;
98 
99  DIALOG_LABEL_EDITOR dialog( this, aTextItem );
100 
101  dialog.ShowModal();
102 }
103 
104 
105 // Don't allow text to disappear; it can be difficult to correct if you can't select it
106 const int MIN_TEXTSIZE = (int)( 0.01 * IU_PER_MM );
107 const int MAX_TEXTSIZE = INT_MAX;
108 
109 
111  DIALOG_LABEL_EDITOR_BASE( aParent ),
112  m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false ),
113  // first part matches single nets and bus vector, the second part matches complex buses
114  m_netNameValidator( "([^/ ]+)|({[^/]+})" )
115 {
116  m_Parent = aParent;
117  m_CurrentText = aTextItem;
118 
119  switch( m_CurrentText->Type() )
120  {
121  case SCH_GLOBAL_LABEL_T: SetTitle( _( "Global Label Properties" ) ); break;
122  case SCH_HIER_LABEL_T: SetTitle( _( "Hierarchical Label Properties" ) ); break;
123  case SCH_LABEL_T: SetTitle( _( "Label Properties" ) ); break;
124  case SCH_SHEET_PIN_T: SetTitle( _( "Hierarchical Sheet Pin Properties" ) ); break;
125  default: SetTitle( _( "Text Properties" ) ); break;
126  }
127 
129  {
132 
133  m_labelSingleLine->Show( false ); m_valueSingleLine->Show( false );
134  m_labelCombo->Show( false ); m_valueCombo->Show( false );
135 
136  m_textEntrySizer->AddGrowableRow( 0 );
137  }
139  {
142 
143  m_labelSingleLine->Show( false ); m_valueSingleLine->Show( false );
144  m_labelMultiLine->Show( false ); m_valueMultiLine->Show( false );
145  }
146  else
147  {
150 
151  m_labelCombo->Show( false ); m_valueCombo->Show( false );
152  m_labelMultiLine->Show( false ); m_valueMultiLine->Show( false );
153  }
154 
156 
159 
160  m_sdbSizer1OK->SetDefault();
161  Layout();
162 
163  // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
164  // so we have to listen to wxEVT_CHAR_HOOK events instead.
165  m_valueMultiLine->Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_LABEL_EDITOR::OnCharHook ), nullptr, this );
166 
167  // DIALOG_SHIM needs a unique hash_key because classname is not sufficient because the
168  // various versions have different controls so we want to store sizes for each version.
169  m_hash_key = TO_UTF8( GetTitle() );
170 
171 
172  // Now all widgets have the size fixed, call FinishDialogSettings
174 }
175 
176 
178 {
179  m_valueMultiLine->Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_LABEL_EDITOR::OnCharHook ), nullptr, this );
180 }
181 
182 
183 // Sadly we store the orientation of hierarchical and global labels using a different
184 // int encoding than that for local labels:
185 // Global Local
186 // Left justified 0 2
187 // Up 1 3
188 // Right justified 2 0
189 // Down 3 1
190 static int mapOrientation( KICAD_T labelType, int aOrientation )
191 {
192  if( labelType == SCH_LABEL_T )
193  return aOrientation;
194 
195  switch( aOrientation )
196  {
197  case 0: return 2;
198  case 2: return 0;
199  default: return aOrientation;
200  }
201 }
202 
203 
205 {
206  if( !wxDialog::TransferDataToWindow() )
207  return false;
208 
210 
211  if( m_valueCombo->IsShown() )
212  {
213  // Load the combobox with the existing labels of the same type
214  std::set<wxString> existingLabels;
215  SCH_SCREENS allScreens;
216 
217  for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
218  for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
219  if( item->Type() == m_CurrentText->Type() )
220  {
221  auto textItem = static_cast<SCH_TEXT*>( item );
222  existingLabels.insert( UnescapeString( textItem->GetText() ) );
223  }
224 
225  wxArrayString existingLabelArray;
226 
227  for( wxString label : existingLabels )
228  existingLabelArray.push_back( label );
229 
230  // existingLabelArray.Sort();
231  m_valueCombo->Append( existingLabelArray );
232  }
233 
234  // Set text options:
236  m_TextOrient->SetSelection( orientation );
237 
238  m_TextShape->SetSelection( m_CurrentText->GetShape() );
239 
240  int style = 0;
241 
242  if( m_CurrentText->IsItalic() )
243  style = 1;
244 
245  if( m_CurrentText->IsBold() )
246  style += 2;
247 
248  m_TextStyle->SetSelection( style );
249 
251 
252  return true;
253 }
254 
255 
260 void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
261 {
262  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
263 }
264 
265 
270 void DIALOG_LABEL_EDITOR::OnCharHook( wxKeyEvent& aEvent )
271 {
272  if( aEvent.GetKeyCode() == WXK_TAB )
273  {
274  int flags = 0;
275  if( !aEvent.ShiftDown() )
276  flags |= wxNavigationKeyEvent::IsForward;
277  if( aEvent.ControlDown() )
278  flags |= wxNavigationKeyEvent::WinChange;
279  NavigateIn( flags );
280  }
281  else if( aEvent.GetKeyCode() == WXK_RETURN && aEvent.ShiftDown() )
282  {
283  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
284  }
285  else
286  {
287  aEvent.Skip();
288  }
289 }
290 
291 
293 {
294  if( !wxDialog::TransferDataFromWindow() )
295  return false;
296 
298  return false;
299 
300  wxString text;
301 
302  /* save old text in undo list if not already in edit */
303  if( m_CurrentText->GetEditFlags() == 0 )
305 
306  m_Parent->GetCanvas()->Refresh();
307 
308  text = EscapeString( m_activeTextEntry->GetValue(), CTX_NETNAME );
309 
310  if( !text.IsEmpty() )
311  m_CurrentText->SetText( text );
312  else if( !m_CurrentText->IsNew() )
313  {
314  DisplayError( this, _( "Empty Text!" ) );
315  return false;
316  }
317 
318  int orientation = m_TextOrient->GetSelection();
320 
322 
323  if( m_TextShape )
324  m_CurrentText->SetShape( static_cast<PINSHEETLABEL_SHAPE>( m_TextShape->GetSelection() ) );
325 
326  int style = m_TextStyle->GetSelection();
327 
328  m_CurrentText->SetItalic( ( style & 1 ) );
329 
330  if( ( style & 2 ) )
331  {
332  m_CurrentText->SetBold( true );
334  }
335  else
336  {
337  m_CurrentText->SetBold( false );
339  }
340 
342  m_Parent->GetCanvas()->Refresh();
343  m_Parent->OnModify();
344 
345  // Make the text size the new default size ( if it is a new text ):
346  if( m_CurrentText->IsNew() )
348 
350 
351  return true;
352 }
void OnCharHook(wxKeyEvent &aEvent)
bool IsBold() const
Definition: eda_text.h:190
const int MIN_TEXTSIZE
void SetTitle(const wxString &aTitle) override
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:123
SCH_SCREEN * GetNext()
const int MAX_TEXTSIZE
int GetPenSizeForBold(int aTextSize)
Function GetPensizeForBold.
wxTextEntry * m_activeTextEntry
Implementation of conversion functions that require both schematic and board internal units.
This file is part of the common library.
SCH_ITEM * Next() const
Definition: sch_item.h:153
std::string m_hash_key
Definition: dialog_shim.h:174
REGEX_VALIDATOR m_netNameValidator
virtual void MoveCursorToCrossHair() override
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
virtual void SetLabelSpinStyle(int aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:248
virtual bool Validate(int aMin, int aMax, bool setFocusOnError=true)
Function Validate Validates the control against the given range, informing the user of any errors fou...
void SetItalic(bool isItalic)
Definition: eda_text.h:186
virtual 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...
virtual const wxString GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:147
Schematic editor (Eeschema) main window.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:231
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...
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:116
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
DIALOG_LABEL_EDITOR(SCH_EDIT_FRAME *parent, SCH_TEXT *aTextItem)
bool IsNew() const
Definition: base_struct.h:222
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
bool IsItalic() const
Definition: eda_text.h:187
int GetLabelSpinStyle() const
Definition: sch_text.h:119
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:47
void SetDefaultTextSize(int aTextSize)
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:64
STATUS_FLAGS GetEditFlags() const
Definition: base_struct.h:263
SCH_DRAW_PANEL * GetCanvas() const override
void SaveCopyInUndoList(SCH_ITEM *aItemToCopy, UNDO_REDO_T aTypeCommand, bool aAppend=false, const wxPoint &aTransformPoint=wxPoint(0, 0))
Create a copy of the current schematic item, and put it in the undo list.
bool IsMultilineAllowed() const
Definition: eda_text.h:205
bool TransferDataFromWindow() override
void EditSchematicText(SCH_TEXT *aText)
Launches the "Edit Text/Label" dialog.
int GetTextWidth() const
Definition: eda_text.h:235
static int mapOrientation(KICAD_T labelType, int aOrientation)
void RefreshItem(EDA_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
wxString UnescapeString(const wxString &aSource)
Definition: string.cpp:123
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:50
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
SCH_SCREEN * GetFirst()
Definition: sch_screen.cpp:996
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
void SetBold(bool aBold)
Definition: eda_text.h:189
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:244
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
Definition: sch_item.h:114
Implementation of the label properties dialog.
Custom text control validator definitions.
Custom validator that checks verifies that a string exactly matches a regular expression.
Definition: validators.h:116
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:493
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:165
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:121
KICAD_T Type() const
Function Type()
Definition: base_struct.h:204