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 <sch_draw_panel.h>
38 #include <general.h>
39 #include <draw_graphic_text.h>
40 #include <confirm.h>
41 #include <sch_text.h>
42 #include <typeinfo>
43 #include <widgets/unit_binder.h>
44 
45 #include <dialog_edit_label_base.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:
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;
90 };
91 
92 
94 {
95  if( aTextItem == NULL )
96  return;
97 
98  DIALOG_LABEL_EDITOR dialog( this, aTextItem );
99 
100  dialog.ShowModal();
101 }
102 
103 
104 // Don't allow text to disappear; it can be difficult to correct if you can't select it
105 const int MIN_TEXTSIZE = (int)( 0.01 * IU_PER_MM );
106 const int MAX_TEXTSIZE = INT_MAX;
107 
108 
110  DIALOG_LABEL_EDITOR_BASE( aParent ),
111  m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false )
112 {
113  m_Parent = aParent;
114  m_CurrentText = aTextItem;
115 
116  switch( m_CurrentText->Type() )
117  {
118  case SCH_GLOBAL_LABEL_T: SetTitle( _( "Global Label Properties" ) ); break;
119  case SCH_HIERARCHICAL_LABEL_T: SetTitle( _( "Hierarchical Label Properties" ) ); break;
120  case SCH_LABEL_T: SetTitle( _( "Label Properties" ) ); break;
121  case SCH_SHEET_PIN_T: SetTitle( _( "Hierarchical Sheet Pin Properties" ) ); break;
122  default: SetTitle( _( "Text Properties" ) ); break;
123  }
124 
126  {
129 
130  m_labelSingleLine->Show( false ); m_valueSingleLine->Show( false );
131  m_labelCombo->Show( false ); m_valueCombo->Show( false );
132 
133  m_textEntrySizer->AddGrowableRow( 0 );
134  }
136  {
139 
140  m_labelSingleLine->Show( false ); m_valueSingleLine->Show( false );
141  m_labelMultiLine->Show( false ); m_valueMultiLine->Show( false );
142  }
143  else
144  {
147 
148  m_labelCombo->Show( false ); m_valueCombo->Show( false );
149  m_labelMultiLine->Show( false ); m_valueMultiLine->Show( false );
150  }
151 
153 
154  if( m_CurrentText->Type() != SCH_TEXT_T )
155  ( (wxTextValidator*) m_activeTextCtrl->GetValidator() )->SetCharExcludes( wxT( " /" ) );
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 
209  m_activeTextEntry->SetValue( m_CurrentText->GetText() );
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  existingLabels.insert( static_cast<SCH_TEXT*>( item )->GetText() );
221 
222  wxArrayString existingLabelArray;
223 
224  for( wxString label : existingLabels )
225  existingLabelArray.push_back( label );
226 
227  // existingLabelArray.Sort();
228  m_valueCombo->Append( existingLabelArray );
229  }
230 
231  // Set text options:
233  m_TextOrient->SetSelection( orientation );
234 
235  m_TextShape->SetSelection( m_CurrentText->GetShape() );
236 
237  int style = 0;
238 
239  if( m_CurrentText->IsItalic() )
240  style = 1;
241 
242  if( m_CurrentText->IsBold() )
243  style += 2;
244 
245  m_TextStyle->SetSelection( style );
246 
248 
249  return true;
250 }
251 
252 
257 void DIALOG_LABEL_EDITOR::OnEnterKey( wxCommandEvent& aEvent )
258 {
259  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
260 }
261 
262 
267 void DIALOG_LABEL_EDITOR::OnCharHook( wxKeyEvent& aEvent )
268 {
269  if( aEvent.GetKeyCode() == WXK_TAB )
270  {
271  int flags = 0;
272  if( !aEvent.ShiftDown() )
273  flags |= wxNavigationKeyEvent::IsForward;
274  if( aEvent.ControlDown() )
275  flags |= wxNavigationKeyEvent::WinChange;
276  NavigateIn( flags );
277  }
278  else if( aEvent.GetKeyCode() == WXK_RETURN && aEvent.ShiftDown() )
279  {
280  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
281  }
282  else
283  {
284  aEvent.Skip();
285  }
286 }
287 
288 
290 {
291  if( !wxDialog::TransferDataFromWindow() )
292  return false;
293 
295  return false;
296 
297  wxString text;
298 
299  /* save old text in undo list if not already in edit */
300  /* or the label to be edited is part of a block */
301  if( m_CurrentText->GetFlags() == 0 ||
304 
305  m_Parent->GetCanvas()->Refresh();
306 
307  text = m_activeTextEntry->GetValue();
308 
309  if( !text.IsEmpty() )
310  m_CurrentText->SetText( text );
311  else if( !m_CurrentText->IsNew() )
312  {
313  DisplayError( this, _( "Empty Text!" ) );
314  return false;
315  }
316 
317  int orientation = m_TextOrient->GetSelection();
319 
321 
322  if( m_TextShape )
323  m_CurrentText->SetShape( static_cast<PINSHEETLABEL_SHAPE>( m_TextShape->GetSelection() ) );
324 
325  int style = m_TextStyle->GetSelection();
326 
327  m_CurrentText->SetItalic( ( style & 1 ) );
328 
329  if( ( style & 2 ) )
330  {
331  m_CurrentText->SetBold( true );
333  }
334  else
335  {
336  m_CurrentText->SetBold( false );
338  }
339 
341  m_Parent->GetCanvas()->Refresh();
342  m_Parent->OnModify();
343 
344  // Make the text size the new default size ( if it is a new text ):
345  if( m_CurrentText->IsNew() )
347 
349 
350  return true;
351 }
void OnCharHook(wxKeyEvent &aEvent)
bool IsBold() const
Definition: eda_text.h:186
const int MIN_TEXTSIZE
void SetTitle(const wxString &aTitle) override
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:120
BLOCK_STATE_T GetState() const
SCH_SCREEN * GetNext()
BLOCK_SELECTOR m_BlockLocate
Block description for block commands.
Definition: base_screen.h:214
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
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:174
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:240
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:182
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...
Schematic editor (Eeschema) main window.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:227
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:219
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
bool IsItalic() const
Definition: eda_text.h:183
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
int GetLabelSpinStyle() const
Definition: sch_text.h:116
#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)
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
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.
void EditSchematicText(SCH_TEXT *TextStruct)
bool IsMultilineAllowed() const
Definition: eda_text.h:201
bool TransferDataFromWindow() override
int GetTextWidth() const
Definition: eda_text.h:231
static int mapOrientation(KICAD_T labelType, int aOrientation)
void RefreshItem(SCH_ITEM *aItem, bool isAddOrDelete=false)
Mark an item for refresh.
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()
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:258
void SetBold(bool aBold)
Definition: eda_text.h:185
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:243
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
Implementation of the label properties dialog.
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
Definition: sch_screen.h:523
void SetThickness(int aNewThickness)
Function SetThickness sets pen width.
Definition: eda_text.h:161
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:118
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
virtual void SetText(const wxString &aText)
Definition: eda_text.h:154