KiCad PCB EDA Suite
transline_dlg_funct.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) 2011 jean-pierre.charras
5  * Copyright (C) 1992-2020 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 3
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 along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 #include <wx/filename.h>
21 #include <wx/settings.h>
22 #include <wx/wx.h>
23 
24 #include <bitmaps/bitmap_types.h>
25 #include "common_data.h"
26 #include "pcb_calculator_frame.h"
28 
29 
30 extern double DoubleFromString( const wxString& TextValue );
31 
32 
33 // Display a selection of usual Er, TanD, Rho values
34 // List format is <value><space><comment>
35 
36 
37 // A helper function to find the choice in a list of values
38 // return true if a index in aList that matches aValue is found.
39 static bool findMatch(wxArrayString& aList, const wxString& aValue, int& aIdx )
40 {
41  bool success = false;
42  // Find the previous choice index:
43  aIdx = 0;
44 
45  // Some countries use comma instead of point as separator.
46  // The value can be enter with pint or comma
47  // use point for string comparisons:
48  wxString cvalue = aValue;
49  cvalue.Replace( ',', '.' );
50 
51  // First compare strings:
52  for( wxString& text: aList )
53  {
54  if( text.IsEmpty() ) // No match found: select the empty line choice
55  break;
56 
57  wxString val_str = text.BeforeFirst( ' ' );
58  val_str.Replace( ',', '.' );
59 
60  // compare string values
61  if( val_str == cvalue )
62  {
63  success = true;
64  break;
65  }
66 
67  aIdx++;
68  }
69 
70  // Due to multiple ways to write a double, if string values
71  // do not match, compare double values
72  if( !success )
73  {
74  struct lconv* lc = localeconv();
75  char localeDecimalSeparator = *lc->decimal_point;
76 
77  if( localeDecimalSeparator == ',' )
78  cvalue.Replace( '.', ',' );
79 
80  double curr_value;
81  cvalue.ToDouble( &curr_value );
82 
83  aIdx = 0;
84 
85  for( wxString& text: aList )
86  {
87  if( text.IsEmpty() ) // No match found: select the empty line choice
88  break;
89 
90  double val;
91  wxString val_str = text.BeforeFirst( ' ' );
92 
93  if( localeDecimalSeparator == ',' )
94  val_str.Replace( '.', ',' );
95 
96  val_str.ToDouble( &val );;
97 
98  if( curr_value == val )
99  {
100  success = true;
101  break;
102  }
103 
104  aIdx++;
105  }
106  }
107 
108  return success;
109 }
110 
111 
118 {
119  wxArrayString list = StandardRelativeDielectricConstantList();
120  list.Add( "" ); // Add an empty line for no selection
121 
122  // Find the previous choice index:
123  wxString prevChoiceStr = m_Value_EpsilonR->GetValue();
124  int prevChoice = 0;
125  findMatch( list, prevChoiceStr, prevChoice );
126 
127  int index = wxGetSingleChoiceIndex( wxEmptyString, _( "Relative Dielectric Constants" ),
128  list, prevChoice );
129 
130  if( index >= 0 && !list.Item( index ).IsEmpty() ) // i.e. non canceled.
131  m_Value_EpsilonR->SetValue( list.Item( index ).BeforeFirst( ' ' ) );
132 }
133 
134 
140 void PCB_CALCULATOR_FRAME::OnTranslineTanD_Button( wxCommandEvent& event )
141 {
142  wxArrayString list = StandardLossTangentList();
143  list.Add( "" ); // Add an empty line for no selection
144 
145  // Find the previous choice index:
146  wxString prevChoiceStr = m_Value_TanD->GetValue();
147  int prevChoice = 0;
148  findMatch( list, prevChoiceStr, prevChoice );
149 
150  int index = wxGetSingleChoiceIndex( wxEmptyString, _( "Dielectric Loss Factor" ), list,
151  prevChoice, NULL );
152 
153  if( index >= 0 && !list.Item( index ).IsEmpty() ) // i.e. non canceled.
154  m_Value_TanD->SetValue( list.Item( index ).BeforeFirst( ' ' ) );
155 }
156 
157 
163 void PCB_CALCULATOR_FRAME::OnTranslineRho_Button( wxCommandEvent& event )
164 {
165  wxArrayString list = StandardResistivityList();
166  list.Add( "" ); // Add an empty line for no selection
167 
168  // Find the previous choice index:
169  wxString prevChoiceStr = m_Value_Rho->GetValue();
170  int prevChoice = 0;
171  findMatch( list, prevChoiceStr, prevChoice );
172 
173  int index = wxGetSingleChoiceIndex( wxEmptyString, _( "Specific Resistance" ), list,
174  prevChoice, NULL );
175 
176  if( index >= 0 && !list.Item( index ).IsEmpty() ) // i.e. non canceled.
177  m_Value_Rho->SetValue( list.Item( index ).BeforeFirst( ' ' ) );
178 }
179 
180 
181 // Minor helper struct to handle dialog items for a given parameter
183 {
184  wxStaticText* name;
185  wxTextCtrl* value;
187 };
188 
189 
199 {
200  m_currTransLineType = aType;
201 
204  {
206  }
207 
209 
210  // This helper bitmap is shown for coupled microstrip only:
213  m_fgSizerZcomment->Show( aType == C_MICROSTRIP_TYPE );
214 
216  m_currTransLine = tr_ident->m_TLine;
217 
218  m_radioBtnPrm1->Show( tr_ident->m_HasPrmSelection );
219  m_radioBtnPrm2->Show( tr_ident->m_HasPrmSelection );
220 
221  // Setup messages
222  wxStaticText* left_msg_list[] =
223  {
226  };
227  wxStaticText* msg_list[] =
228  {
230  };
231 
232  unsigned jj = 0;
233  for( ; jj < tr_ident->m_Messages.GetCount(); jj++ )
234  {
235  if( left_msg_list[jj] == NULL )
236  break;
237 
238  left_msg_list[jj]->SetLabel( tr_ident->m_Messages[jj] );
239  msg_list[jj]->SetLabel( wxEmptyString );
240  }
241 
242  while( left_msg_list[jj] )
243  {
244  left_msg_list[jj]->SetLabel( wxEmptyString );
245  msg_list[jj]->SetLabel( wxEmptyString );
246  jj++;
247  }
248 
249 
250 // Init parameters dialog items
251  struct DLG_PRM_DATA substrateprms[] =
252  {
262  };
263  #define substrateprms_cnt (sizeof(substrateprms)/sizeof(substrateprms[0]))
264 
265  struct DLG_PRM_DATA physprms[] =
266  {
270  };
271  #define physprms_cnt (sizeof(physprms)/sizeof(physprms[0]))
272 
273  struct DLG_PRM_DATA elecprms[] =
274  {
278  };
279  #define elecprms_cnt (sizeof(elecprms)/sizeof(elecprms[0]))
280 
281  struct DLG_PRM_DATA frequencyprms[] =
282  {
284  };
285  #define frequencyprms_cnt (sizeof(frequencyprms)/sizeof(frequencyprms[0]))
286 
287  unsigned idxsubs = 0;
288  unsigned idxphys = 0;
289  unsigned idxelec = 0;
290  unsigned idxfreq = 0;
291 
292  for( unsigned ii = 0; ii < tr_ident->GetPrmsCount(); ii++ )
293  {
294  TRANSLINE_PRM* prm = tr_ident->GetPrm( ii );
295  struct DLG_PRM_DATA * data = NULL;
296  switch( prm->m_Type )
297  {
298  case PRM_TYPE_SUBS:
299  wxASSERT( idxsubs < substrateprms_cnt );
300  data = &substrateprms[idxsubs];
301  idxsubs++;
302  break;
303 
304  case PRM_TYPE_PHYS:
305  wxASSERT( idxphys < physprms_cnt );
306  data = &physprms[idxphys];
307  idxphys++;
308  break;
309 
310  case PRM_TYPE_ELEC:
311  wxASSERT( idxelec < elecprms_cnt );
312  data = &elecprms[idxelec];
313  idxelec++;
314  break;
315 
316  case PRM_TYPE_FREQUENCY:
317  wxASSERT( idxfreq < frequencyprms_cnt );
318  data = &frequencyprms[idxfreq];
319  idxfreq++;
320  break;
321  }
322 
323  wxASSERT ( data );
324  data->name->SetToolTip( prm->m_ToolTip );
325  data->name->SetLabel( prm->m_DlgLabel != "" ? prm->m_DlgLabel + ':' : "" );
326  prm->m_ValueCtrl = data->value;
327 
328  if( prm->m_Id != DUMMY_PRM )
329  {
330  data->value->SetValue( wxString::Format( "%g", prm->m_Value ) );
331  data->value->Enable( true );
332  }
333  else
334  {
335  data->value->SetValue( wxEmptyString );
336  data->value->Enable( false );
337  }
338 
339  if( prm->m_ConvUnit )
340  prm->m_UnitCtrl = data->unit;
341 
342  if( data->unit )
343  {
344  data->unit->Show( prm->m_ConvUnit );
345  data->unit->Enable( prm->m_ConvUnit );
346  data->unit->SetSelection( prm->m_UnitSelection );
347  }
348  }
349 
350  // Clear all unused params
351  for( ; idxsubs < substrateprms_cnt; idxsubs++ )
352  {
353  substrateprms[idxsubs].name->SetLabel(wxEmptyString);
354  substrateprms[idxsubs].name->SetToolTip(wxEmptyString);
355  substrateprms[idxsubs].value->SetValue(wxEmptyString);
356  substrateprms[idxsubs].value->Enable( false );
357 
358  if( substrateprms[idxsubs].unit)
359  {
360  substrateprms[idxsubs].unit->Show( false );
361  substrateprms[idxsubs].unit->Enable( false );
362  substrateprms[idxsubs].unit->SetSelection( 0 );
363  }
364  }
365 
366  for( ; idxphys < physprms_cnt; idxphys++ )
367  {
368  physprms[idxphys].name->SetLabel(wxEmptyString);
369  physprms[idxphys].name->SetToolTip(wxEmptyString);
370  physprms[idxphys].value->SetValue(wxEmptyString);
371  physprms[idxphys].value->Enable( false );
372 
373  if( physprms[idxphys].unit)
374  {
375  physprms[idxphys].unit->Show( false );
376  physprms[idxphys].unit->Enable( false );
377  physprms[idxphys].unit->SetSelection( 0 );
378  }
379  }
380 
381  for( ; idxelec < elecprms_cnt; idxelec++)
382  {
383  elecprms[idxelec].name->SetLabel(wxEmptyString);
384  elecprms[idxelec].name->SetToolTip(wxEmptyString);
385  elecprms[idxelec].value->SetValue(wxEmptyString);
386  elecprms[idxelec].value->Enable( false );
387 
388  if( elecprms[idxelec].unit)
389  {
390  elecprms[idxelec].unit->Show( false );
391  elecprms[idxelec].unit->Enable( false );
392  elecprms[idxelec].unit->SetSelection( 0 );
393  }
394  }
395 
396  for( ; idxfreq < frequencyprms_cnt; idxfreq++ )
397  {
398  frequencyprms[idxfreq].name->SetLabel(wxEmptyString);
399  frequencyprms[idxfreq].name->SetToolTip(wxEmptyString);
400  frequencyprms[idxfreq].value->SetValue(wxEmptyString);
401  frequencyprms[idxfreq].value->Enable( false );
402 
403  if( frequencyprms[idxfreq].unit )
404  {
405  frequencyprms[idxfreq].unit->Show( false );
406  frequencyprms[idxfreq].unit->Enable( false );
407  frequencyprms[idxfreq].unit->SetSelection( 0 );
408  }
409  }
410 }
411 
418 {
420 
421  for( unsigned ii = 0; ii < tr_ident->GetPrmsCount(); ii++ )
422  {
423  TRANSLINE_PRM* prm = tr_ident->GetPrm( ii );
424  wxTextCtrl * value_ctrl = (wxTextCtrl * ) prm->m_ValueCtrl;
425  wxString value_txt = value_ctrl->GetValue();
426  double value = DoubleFromString(value_txt);
427  prm->m_Value = value;
428  UNIT_SELECTOR * unit_ctrl = (UNIT_SELECTOR * ) prm->m_UnitCtrl;
429 
430  if( unit_ctrl )
431  {
432  prm->m_UnitSelection = unit_ctrl->GetSelection();
433  value *= unit_ctrl->GetUnitScale();
434  }
435 
436  prm->m_NormalizedValue = value;
437  }
438 }
439 
440 
445 void PCB_CALCULATOR_FRAME::OnTranslineSelection( wxCommandEvent& event )
446 {
447  enum TRANSLINE_TYPE_ID id = (enum TRANSLINE_TYPE_ID) event.GetSelection();
448 
450 
451  // Texts and units choice widgets can have their size modified:
452  // The new size must be taken in account
453  m_panelTransline->GetSizer()->Layout();
454  m_panelTransline->Refresh();
455 }
456 
457 
464 {
466  m_TranslineSelection->SetSelection( DEFAULT_TYPE );
467 
468  m_panelTransline->GetSizer()->Layout();
469  m_panelTransline->Refresh();
470 }
UNIT_SELECTOR_ANGLE * m_choiceUnit_ElecPrm3
void OnTransLineResetButtonClick(wxCommandEvent &event) override
Function OnTransLineResetButtonClick Called when the user clicks the reset button; sets the parameter...
const BITMAP_OPAQUE microstrip_zodd_zeven_xpm[1]
wxStaticText * name
double m_NormalizedValue
wxArrayString StandardRelativeDielectricConstantList()
Definition: common_data.cpp:28
wxString m_DlgLabel
UNIT_SELECTOR_LEN * m_SubsPrm8_choiceUnit
wxArrayString m_Messages
UNIT_SELECTOR_LEN * m_SubsPrm5_choiceUnit
#define frequencyprms_cnt
wxString m_ToolTip
UNIT_SELECTOR_FREQUENCY * m_choiceUnit_Frequency
static bool findMatch(wxArrayString &aList, const wxString &aValue, int &aIdx)
#define elecprms_cnt
void OnTranslineEpsilonR_Button(wxCommandEvent &event) override
Function OnTranslineEpsilonR_Button Shows a list of current relative dielectric constant(Er) and set ...
#define NULL
void OnTranslineTanD_Button(wxCommandEvent &event) override
Function OnTranslineTanD_Button Shows a list of current dielectric loss factor (tangent delta) and se...
wxArrayString StandardLossTangentList()
Definition: common_data.cpp:55
void TransfDlgDataToTranslineParams()
Function TransfDlgDataToTranslineParams Read values entered in dialog frame, and transfert these valu...
wxArrayString StandardResistivityList()
Definition: common_data.cpp:84
unsigned GetPrmsCount() const
enum TRANSLINE_TYPE_ID m_currTransLineType
TRANSLINE_TYPE_ID
void TranslineTypeSelection(enum TRANSLINE_TYPE_ID aType)
Function TranslineTypeSelection Must be called after selection of a new transline.
UNIT_SELECTOR * unit
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
UNIT_SELECTOR_LEN * m_SubsPrm4_choiceUnit
UNIT_SELECTOR_RESISTOR * m_choiceUnit_ElecPrm2
UNIT_SELECTOR_RESISTOR * m_choiceUnit_ElecPrm1
UNIT_SELECTOR_LEN * m_SubsPrm7_choiceUnit
TRANSLINE_PRM * GetPrm(unsigned aIdx) const
UNIT_SELECTOR_LEN * m_SubsPrm9_choiceUnit
#define _(s)
Definition: 3d_actions.cpp:33
UNIT_SELECTOR_LEN * m_SubsPrm6_choiceUnit
std::vector< TRANSLINE_IDENT * > m_transline_list
void OnTranslineSelection(wxCommandEvent &event) override
Function OnTranslineSelection Called on new transmission line selection.
TRANSLINE * m_TLine
#define physprms_cnt
virtual double GetUnitScale()=0
Function GetUnitScale.
#define substrateprms_cnt
double DoubleFromString(const wxString &TextValue)
void OnTranslineRho_Button(wxCommandEvent &event) override
Function OnTranslineRho_Button Shows a list of current Specific resistance list (rho) and set the sel...
wxBitmap KiBitmap(BITMAPS aBitmap)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104