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 // Conservative limits 0.01 to 250mm
105 const int minSize = (int)( 0.01 * IU_PER_MM );
106 const int maxSize = (int)( 250 * IU_PER_MM );
107 
108 
110  DIALOG_LABEL_EDITOR_BASE( aParent ),
111  m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false, minSize, maxSize )
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 
294  wxString text;
295 
296  /* save old text in undo list if not already in edit */
297  /* or the label to be edited is part of a block */
298  if( m_CurrentText->GetFlags() == 0 ||
301 
303 
304  text = m_activeTextEntry->GetValue();
305 
306  if( !text.IsEmpty() )
307  m_CurrentText->SetText( text );
308  else if( !m_CurrentText->IsNew() )
309  {
310  DisplayError( this, _( "Empty Text!" ) );
311  return false;
312  }
313 
314  int orientation = m_TextOrient->GetSelection();
316 
318 
319  if( m_TextShape )
320  m_CurrentText->SetShape( static_cast<PINSHEETLABEL_SHAPE>( m_TextShape->GetSelection() ) );
321 
322  int style = m_TextStyle->GetSelection();
323 
324  m_CurrentText->SetItalic( ( style & 1 ) );
325 
326  if( ( style & 2 ) )
327  {
328  m_CurrentText->SetBold( true );
330  }
331  else
332  {
333  m_CurrentText->SetBold( false );
335  }
336 
338  m_Parent->GetCanvas()->Refresh();
339  m_Parent->OnModify();
340 
341  // Make the text size the new default size ( if it is a new text ):
342  if( m_CurrentText->IsNew() )
344 
346 
347  return true;
348 }
void OnCharHook(wxKeyEvent &aEvent)
PINSHEETLABEL_SHAPE GetShape() const
Definition: sch_text.h:118
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
void SetTitle(const wxString &aTitle) override
void SetShape(PINSHEETLABEL_SHAPE aShape)
Definition: sch_text.h:120
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:258
SCH_SCREEN * GetNext()
BLOCK_SELECTOR m_BlockLocate
Block description for block commands.
Definition: base_screen.h:214
const int minSize
bool IsMultilineAllowed() const
Definition: eda_text.h:201
int GetPenSizeForBold(int aTextSize)
Function GetPensizeForBold.
wxTextEntry * m_activeTextEntry
bool IsItalic() const
Definition: eda_text.h:183
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:219
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:173
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
void SetItalic(bool isItalic)
Definition: eda_text.h:182
int GetTextWidth() const
Definition: eda_text.h:231
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...
int GetLabelSpinStyle() const
Definition: sch_text.h:116
virtual void RefreshDrawingRect(const EDA_RECT &aRect, bool aEraseBackground=true)
Function RefreshDrawingRect redraws the contents of aRect in drawing units.
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
SCH_ITEM * Next() const
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:115
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:186
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
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:47
void SetDefaultTextSize(int aTextSize)
const int maxSize
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.
virtual const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: sch_text.cpp:433
void EditSchematicText(SCH_TEXT *TextStruct)
bool TransferDataFromWindow() override
static int mapOrientation(KICAD_T labelType, int aOrientation)
BLOCK_STATE_T GetState() const
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()
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:245
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
virtual void SetText(const wxString &aText)
Definition: eda_text.h:154