KiCad PCB EDA Suite
dialog_text_properties.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) 2004-2018 Jean-Pierre Charras jp.charras at wanadoo.fr
5  * Copyright (C) 2010-2018 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <fctsys.h>
26 #include <gr_basic.h>
27 #include <class_drawpanel.h>
28 #include <pcbnew.h>
29 #include <pcb_edit_frame.h>
30 #include <draw_graphic_text.h>
31 #include <confirm.h>
32 #include <wx/valnum.h>
33 #include <pcb_layer_box_selector.h>
34 #include <board_commit.h>
35 #include <widgets/unit_binder.h>
36 #include <class_board.h>
37 #include <class_pcb_text.h>
38 #include <class_text_mod.h>
39 #include <class_module.h>
40 #include <class_dimension.h>
41 
42 #include <dialog_text_properties.h>
43 
44 
53  wxDC* aDC ) :
54  DIALOG_TEXT_PROPERTIES_BASE( aParent ),
55  m_Parent( aParent ), m_DC( aDC ), m_item( aItem ),
56  m_edaText( nullptr ), m_modText( nullptr ), m_pcbText( nullptr ),
57  m_textWidth( aParent, m_SizeXLabel, m_SizeXCtrl, m_SizeXUnits, true, TEXTS_MIN_SIZE ),
58  m_textHeight( aParent, m_SizeYLabel, m_SizeYCtrl, m_SizeYUnits, true, TEXTS_MIN_SIZE ),
59  m_thickness( aParent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnits, true, 0 ),
60  m_posX( aParent, m_PositionXLabel, m_PositionXCtrl, m_PositionXUnits ),
61  m_posY( aParent, m_PositionYLabel, m_PositionYCtrl, m_PositionYUnits ),
62  m_OrientValidator( 1, &m_OrientValue )
63 {
64  wxString title;
65 
66  if( m_item->Type() == PCB_DIMENSION_T )
67  {
68  title = _( "Dimension Text Properties" );
69 
70  DIMENSION* dimension = (DIMENSION*) m_item;
71  m_edaText = &dimension->Text();
72  m_pcbText = &dimension->Text();
73 
75  m_SingleLineSizer->Show( false );
76  m_MultiLineSizer->Show( false );
77 
78  m_KeepUpright->Show( false );
79  m_statusLine->Show( false );
80  }
81  else if( m_item->Type() == PCB_MODULE_TEXT_T )
82  {
83  title = _( "Footprint Text Properties" );
84 
86  m_edaText = static_cast<EDA_TEXT*>( m_modText );
87 
88  switch( m_modText->GetType() )
89  {
90  case TEXTE_MODULE::TEXT_is_REFERENCE: m_TextLabel->SetLabel( _( "Reference:" ) ); break;
91  case TEXTE_MODULE::TEXT_is_VALUE: m_TextLabel->SetLabel( _( "Value:" ) ); break;
92  case TEXTE_MODULE::TEXT_is_DIVERS: m_TextLabel->SetLabel( _( "Text:" ) ); break;
93  }
94 
96  m_MultiLineSizer->Show( false );
97  m_DimensionTextSizer->Show( false );
98  }
99  else
100  {
101  title = _( "Text Properties" );
102 
103  m_pcbText = (TEXTE_PCB*) aItem;
104  m_edaText = static_cast<EDA_TEXT*>( m_pcbText );
105 
107  m_SingleLineSizer->Show( false );
108  m_DimensionTextSizer->Show( false );
109 
110  m_KeepUpright->Show( false );
111  m_statusLine->Show( false );
112  }
113 
114  SetTitle( title );
115  m_hash_key = title;
116 
117  // Configure the layers list selector. Note that footprints are built outside the current
118  // board and so we may need to show all layers if the text is on an unactivated layer.
121 
126 
127  m_OrientValue = 0.0;
128  m_OrientValidator.SetRange( -360.0, 360.0 );
129  m_OrientCtrl->SetValidator( m_OrientValidator );
130  m_OrientValidator.SetWindow( m_OrientCtrl );
131 
132  // Set font sizes
133  wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
134  infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
135  m_statusLine->SetFont( infoFont );
136 
137  m_sdbSizerOK->SetDefault();
138 
139  // wxTextCtrls fail to generate wxEVT_CHAR events when the wxTE_MULTILINE flag is set,
140  // so we have to listen to wxEVT_CHAR_HOOK events instead.
141  m_MultiLineText->Connect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXT_PROPERTIES::OnCharHook ), NULL, this );
142 
144 }
145 
146 
148 {
149  m_MultiLineText->Disconnect( wxEVT_CHAR_HOOK, wxKeyEventHandler( DIALOG_TEXT_PROPERTIES::OnCharHook ), NULL, this );
150 }
151 
152 
157 {
158  m_canvas->SetIgnoreMouseEvents( true );
159 #ifndef __WXMAC__
160  DIALOG_TEXT_PROPERTIES dlg( this, aText, aDC );
161 #else
162  // Avoid "writes" in the dialog, creates errors with WxOverlay and NSView
163  // Raising an Exception - Fixes #891347
164  DIALOG_TEXT_PROPERTIES dlg( this, aText, NULL );
165 #endif
166  dlg.ShowModal();
167  m_canvas->MoveCursorToCrossHair();
168  m_canvas->SetIgnoreMouseEvents( false );
169 }
170 
171 
172 void DIALOG_TEXT_PROPERTIES::OnCharHook( wxKeyEvent& aEvent )
173 {
174  if( aEvent.GetKeyCode() == WXK_TAB )
175  {
176  int flags = 0;
177 
178  if( !aEvent.ShiftDown() )
179  flags |= wxNavigationKeyEvent::IsForward;
180 
181  if( aEvent.ControlDown() )
182  flags |= wxNavigationKeyEvent::WinChange;
183 
184  NavigateIn( flags );
185  }
186  else if( aEvent.GetKeyCode() == WXK_RETURN && aEvent.ShiftDown() )
187  {
189  EndModal( wxID_OK );
190  }
191  else
192  {
193  aEvent.Skip();
194  }
195 }
196 
197 
199 {
200  EDA_UNITS_T units = UNSCALED_UNITS;
201  bool useMils;
202 
203  FetchUnitsFromString( m_DimensionText->GetValue(), units, useMils );
204 
205  if( units != UNSCALED_UNITS )
206  m_DimensionUnitsOpt->SetSelection( units == MILLIMETRES ? 2 : useMils ? 1 : 0 );
207 }
208 
209 
211 {
212  DIMENSION* dimension = (DIMENSION*) m_item;
213  EDA_UNITS_T units;
214  bool useMils;
215 
216  // Get default units in case dimension text doesn't contain units.
217  dimension->GetUnits( units, useMils );
218 
219  double value = ValueFromString( units, m_DimensionText->GetValue(), useMils );
220 
221  switch( event.GetSelection() )
222  {
223  case 0: units = INCHES; useMils = false; break;
224  case 1: units = INCHES; useMils = true; break;
225  case 2: units = MILLIMETRES; useMils = false; break;
226  default: break;
227  }
228 
229  m_DimensionText->SetValue( StringFromValue( units, value, true, useMils ) );
230 }
231 
232 
234 {
235  if( m_SingleLineText->IsShown() )
236  {
237  m_SingleLineText->SetValue( m_edaText->GetText() );
238 
240  SelectReferenceNumber( static_cast<wxTextEntry*>( m_SingleLineText ) );
241  else
242  m_SingleLineText->SetSelection( -1, -1 );
243  }
244  else if( m_MultiLineText->IsShown() )
245  {
246  m_MultiLineText->SetValue( m_edaText->GetText() );
247  m_MultiLineText->SetSelection( -1, -1 );
248  }
249  else if (m_DimensionText->IsShown() )
250  {
251  m_DimensionText->SetValue( m_edaText->GetText() );
252  m_DimensionText->SetSelection( -1, -1 );
253 
254  DIMENSION* dimension = (DIMENSION*) m_item;
255  EDA_UNITS_T units;
256  bool useMils;
257  dimension->GetUnits( units, useMils );
258 
259  m_DimensionUnitsOpt->SetSelection( units == MILLIMETRES ? 2 : useMils ? 1 : 0 );
260  }
261 
262  if( m_item->Type() == PCB_MODULE_TEXT_T )
263  {
264  MODULE* module = dynamic_cast<MODULE*>( m_modText->GetParent() );
265  wxString msg;
266 
267  if( module )
268  {
269  msg.Printf( _("Footprint %s (%s), %s, rotated %.1f deg"),
270  module->GetReference(),
271  module->GetValue(),
272  module->IsFlipped() ? _( "back side (mirrored)" ) : _( "front side" ),
273  module->GetOrientation() / 10.0 );
274  }
275 
276  m_statusLine->SetLabel( msg );
277  }
278  else
279  {
280  m_statusLine->Show( false );
281  }
282 
284 
290 
291  m_Visible->SetValue( m_edaText->IsVisible() );
292  m_Italic->SetValue( m_edaText->IsItalic() );
294  m_JustifyChoice->SetSelection( (int) hJustify + 1 );
296  m_Mirrored->SetValue( m_edaText->IsMirrored() );
297 
298  if( m_modText )
299  m_KeepUpright->SetValue( m_modText->IsKeepUpright() );
300 
301  return DIALOG_TEXT_PROPERTIES_BASE::TransferDataToWindow();
302 }
303 
304 
306 {
307  if( !DIALOG_TEXT_PROPERTIES_BASE::TransferDataFromWindow() )
308  return false;
309 
310  // Test for acceptable layer.
311  // Incorrect layer can happen for old boards, having texts on edge cut layer for instance
313  {
314  wxMessageBox( _( "No layer selected, Please select the text layer" ) );
315  return false;
316  }
317 
318  if( !m_textWidth.Validate( true ) || !m_textHeight.Validate( true ) )
319  return false;
320 
321  if( !m_thickness.Validate( true ) )
322  return false;
323 
324  BOARD_COMMIT commit( m_Parent );
325  commit.Modify( m_item );
326 
327  // If no other command in progress, prepare undo command
328  // (for a command in progress, will be made later, at the completion of command)
329  int mask = EDA_ITEM_ALL_FLAGS - ( SELECTED | HIGHLIGHTED | BRIGHTENED );
330  bool pushCommit = ( m_item->GetFlags() & mask ) == 0;
331 
332  /* set flag in edit to force undo/redo/abort proper operation,
333  * and avoid new calls to SaveCopyInUndoList for the same text
334  * this can occurs when a text is moved, and then rotated, edited ..
335  */
336  if( !pushCommit )
337  m_item->SetFlags( IN_EDIT );
338 
339 #ifndef USE_WX_OVERLAY
340  // Erase old text on screen if context is available
341  if( m_DC )
342  {
344  }
345 #endif
346 
347  // Set the new text content
348  if( m_SingleLineText->IsShown() )
349  {
350  if( !m_SingleLineText->GetValue().IsEmpty() )
351  m_edaText->SetText( m_SingleLineText->GetValue() );
352  }
353  else if( m_MultiLineText->IsShown() )
354  {
355  if( !m_MultiLineText->GetValue().IsEmpty() )
356  m_edaText->SetText( m_MultiLineText->GetValue() );
357  }
358  else if( m_DimensionText->IsShown() )
359  {
360  if( !m_DimensionText->GetValue().IsEmpty() )
361  m_edaText->SetText( m_DimensionText->GetValue() );
362 
363  DIMENSION* dimension = (DIMENSION*) m_item;
364 
365  switch( m_DimensionUnitsOpt->GetSelection() )
366  {
367  case 0: dimension->SetUnits( INCHES, false ); break;
368  case 1: dimension->SetUnits( INCHES, true ); break;
369  case 2: dimension->SetUnits( MILLIMETRES, false ); break;
370  default: break;
371  }
372  }
373 
375 
379 
380  if( m_modText )
382 
383  // Test for acceptable values for thickness and size and clamp if fails
384  int maxthickness = Clamp_Text_PenSize( m_edaText->GetThickness(), m_edaText->GetTextSize() );
385 
386  if( m_edaText->GetThickness() > maxthickness )
387  {
388  DisplayError( this, _( "The text thickness is too large for the text size.\n"
389  "It will be clamped." ) );
390  m_edaText->SetThickness( maxthickness );
391  }
392 
393  m_edaText->SetVisible( m_Visible->GetValue() );
394  m_edaText->SetItalic( m_Italic->GetValue() );
396  m_edaText->SetMirrored( m_Mirrored->GetValue() );
397 
398  if( m_modText )
399  m_modText->SetKeepUpright( m_KeepUpright->GetValue() );
400 
401  switch( m_JustifyChoice->GetSelection() )
402  {
406  default: break;
407  }
408 
409 #ifndef USE_WX_OVERLAY
410  // Finally, display new text if there is a context to do so
411  if( m_DC )
412  {
414  }
415 #else
416  m_Parent->Refresh();
417 #endif
418 
419  if( pushCommit )
420  commit.Push( _( "Change text properties" ) );
421 
422  return true;
423 }
void SetMirrored(bool isMirrored)
Definition: eda_text.h:191
void SetTextAngle(double aAngle)
Definition: eda_text.h:169
virtual bool Validate(bool setFocusOnError=false)
Function Validate Validates the control, informing the user of any errors found.
KICAD_T Type() const
Function Type()
Definition: base_struct.h:201
BOARD_ITEM_CONTAINER * GetParent() const
STATUS_FLAGS GetFlags() const
Definition: base_struct.h:258
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
void SetKeepUpright(bool aKeepUpright)
int Clamp_Text_PenSize(int aPenSize, int aSize, bool aBold)
Function Clamp_Text_PenSize As a rule, pen width should not be >1/4em, otherwise the character will b...
#define IN_EDIT
Item currently edited.
Definition: base_struct.h:112
EDA_TEXT_HJUSTIFY_T
Definition: eda_text.h:62
virtual EDA_DRAW_PANEL * GetCanvas() const
Definition: draw_frame.h:388
TEXTE_PCB class definition.
Class DIALOG_TEXT_PROPERTIES_BASE.
const wxPoint & GetTextPos() const
Definition: eda_text.h:237
static int KiROUND(double v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: common.h:120
bool IsItalic() const
Definition: eda_text.h:183
DIALOG_TEXT_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, BOARD_ITEM *aItem, wxDC *aDC=nullptr)
DIALOG_PCB_TEXT_PROPERTIES, derived from DIALOG_PCB_TEXT_PROPERTIES_BASE.
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
This file is part of the common library.
Class BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class...
void GetUnits(EDA_UNITS_T &aUnits, bool &aUseMils) const
TEXT_TYPE GetType() const
std::string m_hash_key
Definition: dialog_shim.h:173
void SetNotAllowedLayerSet(LSET aMask)
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
void OnCharHook(wxKeyEvent &aEvent)
Class BOARD to handle a board.
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
Function IsLayerEnabled is a proxy function that calls the correspondent function in m_BoardSettings ...
Definition: class_board.h:445
void SetItalic(bool isItalic)
Definition: eda_text.h:182
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void SetTextPos(const wxPoint &aPoint)
Definition: eda_text.h:236
void SetVisible(bool aVisible)
Definition: eda_text.h:188
BOARD * GetBoard() const
const wxString & GetValue() const
Function GetValue.
Definition: class_module.h:497
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:227
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
double GetTextAngleDegrees() const
Definition: eda_text.h:179
int ValueFromString(EDA_UNITS_T aUnits, const wxString &aTextValue, bool aUseMils)
Function ValueFromString converts aTextValue in aUnits to internal units used by the application...
Definition: base_units.cpp:409
void FetchUnitsFromString(const wxString &aTextValue, EDA_UNITS_T &aUnits, bool &aUseMils)
Function FetchUnitsFromString writes any unit info found in the string to aUnits and aUseMils...
Definition: base_units.cpp:370
virtual void Draw(EDA_DRAW_PANEL *panel, wxDC *DC, GR_DRAWMODE aDrawMode, const wxPoint &offset=ZeroOffset)=0
Function Draw BOARD_ITEMs have their own color information.
void InstallTextOptionsFrame(BOARD_ITEM *aText, wxDC *aDC)
Routine for main window class to launch text properties dialog.
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:203
#define EDA_ITEM_ALL_FLAGS
Definition: base_struct.h:145
void SetInitialFocus(wxWindow *aWindow)
Sets the window (usually a wxTextCtrl) that should be focused when the dialog is shown.
Definition: dialog_shim.h:115
void OnDimensionUnitsChange(wxCommandEvent &event) override
int GetThickness() const
Function GetThickness returns pen width.
Definition: eda_text.h:167
virtual int GetValue()
Function GetValue Returns the current value in Internal Units.
Class EDA_TEXT is a mix-in class (via multiple inheritance) that handles texts such as labels...
Definition: eda_text.h:127
bool IsKeepUpright()
DIMENSION class definition.
#define SELECTED
Definition: base_struct.h:121
void SelectReferenceNumber(wxTextEntry *aTextEntry)
Select the number (or "?") in a reference for ease of editing.
Definition: common.cpp:155
Footprint text class description.
void SetFlags(STATUS_FLAGS aMask)
Definition: base_struct.h:256
double GetOrientation() const
Definition: class_module.h:189
void ShowNonActivatedLayers(bool aShow)
const wxString & GetText() const
Function GetText returns the string associated with the text object.
Definition: eda_text.h:143
Definition: common.h:160
bool IsFlipped() const
function IsFlipped
Definition: class_module.h:259
#define BRIGHTENED
item is drawn with a bright contour
Definition: base_struct.h:138
int SetLayerSelection(LAYER_NUM layer)
void SetUnits(EDA_UNITS_T aUnits, bool aUseMils)
bool SetLayersHotkeys(bool value)
class DIMENSION, a dimension (graphic item)
Definition: typeinfo.h:100
PCB_BASE_EDIT_FRAME * m_Parent
#define TEXTS_MIN_SIZE
Minimum text size in internal units (1 mil)
Definition: pcbnew.h:67
Definition: gr_basic.h:38
class TEXTE_MODULE, text in a footprint
Definition: typeinfo.h:93
void SetLocalCoord()
Set relative coordinates.
#define HIGHLIGHTED
item is drawn in normal colors, when the rest is darkened
Definition: base_struct.h:137
PCB_LAYER_BOX_SELECTOR * m_LayerSelectionCtrl
Common, abstract interface for edit frames.
const wxString & GetReference() const
Function GetReference.
Definition: class_module.h:463
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:206
bool IsMirrored() const
Definition: eda_text.h:192
bool IsVisible() const
Definition: eda_text.h:189
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
TEXTE_PCB & Text()
LAYER_NUM GetLayerSelection() const
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
wxString StringFromValue(EDA_UNITS_T aUnits, int aValue, bool aAddUnitSymbol, bool aUseMils)
Function StringFromValue returns the string from aValue according to units (inch, mm ...
Definition: base_units.cpp:210
static LSET ForbiddenTextLayers()
Function ForbiddenTextLayers Layers which are now allowed to have text on them.
Definition: lset.cpp:793
Module description (excepted pads)
const wxSize & GetTextSize() const
Definition: eda_text.h:228
void OnDimensionTextChange(wxCommandEvent &event) override
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:245
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:810
wxFloatingPointValidator< double > m_OrientValidator
EDA_UNITS_T
Definition: common.h:159
Class DIMENSION.
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