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 <wx/valgen.h>
33 #include <wx/valnum.h>
34 #include <sch_edit_frame.h>
35 #include <base_units.h>
36 
37 #include <class_drawpanel.h>
38 #include <general.h>
39 #include <draw_graphic_text.h>
40 #include <confirm.h>
41 #include <sch_text.h>
42 #include <typeinfo>
43 
44 #include <dialog_edit_label_base.h>
45 
46 class SCH_EDIT_FRAME;
47 class SCH_TEXT;
48 
49 
51 {
52 public:
53  DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* parent, SCH_TEXT* aTextItem );
55 
56  void SetTitle( const wxString& aTitle ) override
57  {
58  // This class is shared for numerous tasks: a couple of
59  // single line labels and multi-line text fields.
60  // Often the desired size of the multi-line text field editor
61  // is larger than is needed for the single line label.
62  // Therefore the session retained sizes of these dialogs needs
63  // to be class independent, make them title dependent.
64  switch( m_CurrentText->Type() )
65  {
66  case SCH_GLOBAL_LABEL_T:
68  case SCH_LABEL_T:
69  // labels can share retained settings probably.
70  break;
71 
72  default:
73  m_hash_key = TO_UTF8( aTitle );
74  m_hash_key += typeid(*this).name();
75  }
76 
77  DIALOG_LABEL_EDITOR_BASE::SetTitle( aTitle );
78  }
79 
80 private:
81  void InitDialog( ) override;
82  virtual void OnEnterKey( wxCommandEvent& aEvent ) override;
83  virtual void OnOkClick( wxCommandEvent& aEvent ) override;
84  virtual void OnCancelClick( wxCommandEvent& aEvent ) override;
85  void OnCharHook( wxKeyEvent& aEvent );
86  void TextPropertiesAccept( wxCommandEvent& aEvent );
87 
90  wxTextCtrl* m_textLabel;
91 };
92 
93 
94 
95 /* Edit the properties of the text (Label, Global label, graphic text).. )
96  * pointed by "aTextStruct"
97  */
99 {
100  if( aTextItem == NULL )
101  return;
102 
103  DIALOG_LABEL_EDITOR dialog( this, aTextItem );
104 
105  dialog.ShowModal();
106 }
107 
108 
110  DIALOG_LABEL_EDITOR_BASE( aParent )
111 {
112  m_Parent = aParent;
113  m_CurrentText = aTextItem;
114  InitDialog();
115 
116  // Conservative limits 0.0 to 10.0 inches
117  const int minSize = 0; // a value like 0.01 is better, but if > 0, creates
118  // annoying issues when trying to enter a value starting by 0 or .0
119  const int maxSize = 10 * 1000 * IU_PER_MILS;
120 
121  wxFloatingPointValidator<double> textSizeValidator( NULL, wxNUM_VAL_NO_TRAILING_ZEROES );
122  textSizeValidator.SetPrecision( 4 );
123  textSizeValidator.SetRange( To_User_Unit( g_UserUnit, minSize ),
124  To_User_Unit( g_UserUnit, maxSize ) );
125 
126  m_TextSize->SetValidator( textSizeValidator );
127 
128  // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
129  // so we have to listen to wxEVT_CHAR_HOOK events instead.
130  m_textLabelMultiLine->Connect( wxEVT_CHAR_HOOK,
131  wxKeyEventHandler( DIALOG_LABEL_EDITOR::OnCharHook ),
132  NULL, this );
133 
134  // Now all widgets have the size fixed, call FinishDialogSettings
136 }
137 
138 
140 {
141  m_textLabelMultiLine->Disconnect( wxEVT_CHAR_HOOK,
142  wxKeyEventHandler( DIALOG_LABEL_EDITOR::OnCharHook ),
143  NULL, this );
144 }
145 
146 
147 // Sadly we store the orientation of hierarchical and global labels using a different
148 // int encoding than that for local labels:
149 // Global Local
150 // Left justified 0 2
151 // Up 1 3
152 // Right justified 2 0
153 // Down 3 1
154 static int mapOrientation( KICAD_T labelType, int aOrientation )
155 {
156  if( labelType == SCH_LABEL_T )
157  return aOrientation;
158 
159  switch( aOrientation )
160  {
161  case 0: return 2;
162  case 2: return 0;
163  default: return aOrientation;
164  }
165 }
166 
167 
169 {
170  wxString msg;
171  bool multiLine = false;
172 
174  {
176  m_textLabelSingleLine->Show( false );
177  m_textControlSizer->AddGrowableRow( 0 );
178  multiLine = true;
179  }
180  else
181  {
183  m_textLabelMultiLine->Show( false );
184  wxTextValidator* validator = (wxTextValidator*) m_textLabel->GetValidator();
185 
186  // Add invalid label characters to this list.
187  // for any label type but SCH_TEXT_T (that has the multiline allowed)
188  validator->SetCharExcludes( wxT( " /" ) );
189  }
190 
191  m_textLabel->SetValue( m_CurrentText->GetText() );
192  m_textLabel->SetFocus();
193 
194  switch( m_CurrentText->Type() )
195  {
196  case SCH_GLOBAL_LABEL_T:
197  SetTitle( _( "Global Label Properties" ) );
198  break;
199 
201  SetTitle( _( "Hierarchical Label Properties" ) );
202  break;
203 
204  case SCH_LABEL_T:
205  SetTitle( _( "Label Properties" ) );
206  break;
207 
208  case SCH_SHEET_PIN_T:
209  SetTitle( _( "Hierarchical Sheet Pin Properties." ) );
210  break;
211 
212  default:
213  SetTitle( _( "Text Properties" ) );
214  break;
215  }
216 
217  const int MINTEXTWIDTH = 40; // M's are big characters, a few establish a lot of width
218 
219  int max_len = 0;
220 
221  if ( !multiLine )
222  {
223  max_len = m_CurrentText->GetText().Length();
224  }
225  else
226  {
227  // calculate the length of the biggest line
228  // we cannot use the length of the entire text that has no meaning
229  int curr_len = MINTEXTWIDTH;
230  int imax = m_CurrentText->GetText().Length();
231 
232  for( int count = 0; count < imax; count++ )
233  {
234  if( m_CurrentText->GetText()[count] == '\n' ||
235  m_CurrentText->GetText()[count] == '\r' ) // new line
236  {
237  curr_len = 0;
238  }
239  else
240  {
241  curr_len++;
242 
243  if ( max_len < curr_len )
244  max_len = curr_len;
245  }
246  }
247  }
248 
249  if( max_len < MINTEXTWIDTH )
250  max_len = MINTEXTWIDTH;
251 
252  wxString textWidth;
253  textWidth.Append( 'M', MINTEXTWIDTH );
254  EnsureTextCtrlWidth( m_textLabel, &textWidth );
255 
256  // Set text options:
258  m_TextOrient->SetSelection( orientation );
259 
260  m_TextShape->SetSelection( m_CurrentText->GetShape() );
261 
262  int style = 0;
263 
264  if( m_CurrentText->IsItalic() )
265  style = 1;
266 
267  if( m_CurrentText->IsBold() )
268  style += 2;
269 
270  m_TextStyle->SetSelection( style );
271 
272  wxString units = ReturnUnitSymbol( g_UserUnit, wxT( "(%s)" ) );
273  msg.Printf( _( "H%s x W%s" ), GetChars( units ), GetChars( units ) );
274  m_staticSizeUnits->SetLabel( msg );
275 
277  m_TextSize->SetValue( msg );
278 
281  {
282  m_TextShape->Show( false );
283  }
284 
285  m_sdbSizer1OK->SetDefault();
286 }
287 
288 
293 void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
294 {
295  TextPropertiesAccept( aEvent );
296 }
297 
298 
303 void DIALOG_LABEL_EDITOR::OnCharHook( wxKeyEvent& aEvent )
304 {
305  if( aEvent.GetKeyCode() == WXK_TAB )
306  {
307  int flags = 0;
308  if( !aEvent.ShiftDown() )
309  flags |= wxNavigationKeyEvent::IsForward;
310  if( aEvent.ControlDown() )
311  flags |= wxNavigationKeyEvent::WinChange;
312  NavigateIn( flags );
313  }
314  else if( aEvent.GetKeyCode() == WXK_RETURN && aEvent.ShiftDown() )
315  {
316  wxCommandEvent cmdEvent( wxEVT_COMMAND_ENTER );
317  TextPropertiesAccept( cmdEvent );
318  }
319  else
320  {
321  aEvent.Skip();
322  }
323 }
324 
325 
330 void DIALOG_LABEL_EDITOR::OnOkClick( wxCommandEvent& aEvent )
331 {
332  TextPropertiesAccept( aEvent );
333 }
334 
335 
340 void DIALOG_LABEL_EDITOR::OnCancelClick( wxCommandEvent& aEvent )
341 {
343  EndModal( wxID_CANCEL );
344 }
345 
346 
347 void DIALOG_LABEL_EDITOR::TextPropertiesAccept( wxCommandEvent& aEvent )
348 {
349  wxString text;
350  int value;
351 
352  /* save old text in undo list if not already in edit */
353  /* or the label to be edited is part of a block */
354  if( m_CurrentText->GetFlags() == 0 ||
357 
359 
360  text = m_textLabel->GetValue();
361 
362  if( !text.IsEmpty() )
363  m_CurrentText->SetText( text );
364  else if( !m_CurrentText->IsNew() )
365  {
366  DisplayError( this, _( "Empty Text!" ) );
367  return;
368  }
369 
370  int orientation = m_TextOrient->GetSelection();
372 
373  text = m_TextSize->GetValue();
374  value = ValueFromString( g_UserUnit, text );
375  m_CurrentText->SetTextSize( wxSize( value, value ) );
376 
377  if( m_TextShape )
379  m_CurrentText->SetShape( static_cast<PINSHEETLABEL_SHAPE>( m_TextShape->GetSelection() ) );
380 
381  int style = m_TextStyle->GetSelection();
382 
383  m_CurrentText->SetItalic( ( style & 1 ) );
384 
385  if( ( style & 2 ) )
386  {
387  m_CurrentText->SetBold( true );
389  }
390  else
391  {
392  m_CurrentText->SetBold( false );
394  }
395 
396  m_Parent->OnModify();
397 
398  // Make the text size the new default size ( if it is a new text ):
399  if( m_CurrentText->IsNew() )
401 
404  EndModal( wxID_OK );
405 }
void OnCharHook(wxKeyEvent &aEvent)
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:118
KICAD_T Type() const
Function Type()
Definition: base_struct.h:209
void SetTitle(const wxString &aTitle) override
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:120
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:266
BLOCK_SELECTOR m_BlockLocate
Block description for block commands.
Definition: base_screen.h:214
virtual void OnOkClick(wxCommandEvent &aEvent) override
bool IsMultilineAllowed() const
Definition: eda_text.h:186
int GetPenSizeForBold(int aTextSize)
Function GetPensizeForBold.
bool IsItalic() const
Definition: eda_text.h:168
Implementation of conversion functions that require both schematic and board internal units...
This file is part of the common library.
bool IsNew() const
Definition: base_struct.h:227
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:359
void OnModify()
Must be called after a schematic change in order to set the "modify" flag of the current screen* and ...
std::string m_hash_key
Definition: dialog_shim.h:151
wxString ReturnUnitSymbol(EDA_UNITS_T aUnit, const wxString &formatString)
Returns the units symbol.
Definition: base_units.cpp:426
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:278
wxString StringFromValue(EDA_UNITS_T aUnit, int aValue, bool aAddUnitSymbol)
Function StringFromValue returns the string from aValue according to units (inch, mm ...
Definition: base_units.cpp:205
void SetItalic(bool isItalic)
Definition: eda_text.h:167
int GetTextWidth() const
Definition: eda_text.h:216
virtual void OnEnterKey(wxCommandEvent &aEvent) override
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
int GetLabelSpinStyle() const
Definition: sch_text.h:116
void RefreshDrawingRect(const EDA_RECT &aRect, bool aEraseBackground=true)
Function RefreshDrawingRect redraws the contents of aRect in drawing units.
Definition: draw_panel.cpp:318
Schematic editor (Eeschema) main window.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:212
void MoveCursorToCrossHair()
Function MoveCursorToCrossHair warps the cursor to the current cross hair position.
Definition: draw_panel.cpp:360
Class DIALOG_LABEL_EDITOR_BASE.
SCH_EDIT_FRAME * m_Parent
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 IsBold() const
Definition: eda_text.h:171
SCH_SCREEN * GetScreen() const override
Function GetScreen returns 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:47
wxFlexGridSizer * m_textControlSizer
void TextPropertiesAccept(wxCommandEvent &aEvent)
void SetDefaultTextSize(int aTextSize)
bool EnsureTextCtrlWidth(wxTextCtrl *aCtrl, const wxString *aString)
Set the minimum pixel width on a text control in order to make a text string be fully visible within ...
Definition: common.cpp:102
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:128
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.
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application...
Definition: base_units.cpp:370
virtual void OnCancelClick(wxCommandEvent &aEvent) override
virtual const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: sch_text.cpp:470
void EditSchematicText(SCH_TEXT *TextStruct)
EDA_UNITS_T g_UserUnit
Global variables definitions.
Definition: common.cpp:57
static const wxChar * GetChars(const wxString &s)
Function GetChars returns a wxChar* to the actual wxChar* data within a wxString, and is helpful for ...
Definition: macros.h:92
static int mapOrientation(KICAD_T labelType, int aOrientation)
BLOCK_STATE_T GetState() const
void InitDialog() override
double To_User_Unit(EDA_UNITS_T aUnit, double aValue)
Function To_User_Unit convert aValue in internal units to the appropriate user units defined by aUnit...
Definition: base_units.cpp:91
void SetBold(bool aBold)
Definition: eda_text.h:170
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:185
Implementation of the label properties dialog.
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:146
virtual void SetText(const wxString &aText)
Definition: eda_text.h:139