My Project  0.0.16
QUCS Mapping
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
componentdialog.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  componentdialog.cpp
3  -------------------
4  begin : Tue Sep 9 2003
5  copyright : (C) 2003, 2004 by Michael Margraf
6  email : michael.margraf@alumni.tu-berlin.de
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "componentdialog.h"
19 #include "main.h"
20 #include "qucs.h"
21 #include "schematic.h"
22 
23 #include <qhbox.h>
24 #include <qvbox.h>
25 #include <qlayout.h>
26 #include <qhgroupbox.h>
27 #include <qvalidator.h>
28 #include <qtabwidget.h>
29 #include <qfiledialog.h>
30 
31 #include <math.h>
32 
33 
35  : QDialog(d, 0, TRUE, Qt::WDestructiveClose)
36 {
37  resize(400, 250);
38  setCaption(tr("Edit Component Properties"));
39  Comp = c;
40  Doc = d;
41  QString s;
42 
43  all = new QVBoxLayout(this); // to provide neccessary size
44  QGridLayout *gp1;
45  QWidget *myParent = this;
46  ValInteger = new QIntValidator(1, 1000000, this);
47 
48  Expr.setPattern("[^\"=]*"); // valid expression for property 'edit'
49  Validator = new QRegExpValidator(Expr, this);
50  Expr.setPattern("[^\"]*"); // valid expression for property 'edit'
51  Validator2 = new QRegExpValidator(Expr, this);
52  Expr.setPattern("[\\w_]+"); // valid expression for property 'NameEdit'
53  ValRestrict = new QRegExpValidator(Expr, this);
54 
55  checkSim = 0; editSim = 0; comboType = 0; checkParam = 0;
56  editStart = 0; editStop = 0; editNumber = 0;
57 
58  Property *pp = 0; // last property not to put in ListView
59  // ...........................................................
60  // if simulation component
61  if((Comp->Model[0] == '.') &&
62  (Comp->Model != ".DC") && (Comp->Model != ".HB") &&
63  (Comp->Model != ".Digi")) {
64  QTabWidget *t = new QTabWidget(this);
65  all->addWidget(t);
66 
67  QWidget *Tab1 = new QWidget(t);
68  t->addTab(Tab1, tr("Sweep"));
69  QGridLayout *gp = new QGridLayout(Tab1, 9,3,5,5);
70 
71  gp->addMultiCellWidget(new QLabel(Comp->Description, Tab1), 0,0,0,1);
72 
73  int row=1;
74  editParam = new QLineEdit(Tab1);
75  editParam->setValidator(ValRestrict);
76  connect(editParam, SIGNAL(returnPressed()), SLOT(slotParamEntered()));
77  checkParam = new QCheckBox(tr("display in schematic"), Tab1);
78  if(Comp->Model == ".SW") { // parameter sweep
79  textSim = new QLabel(tr("Simulation:"), Tab1);
80  gp->addWidget(textSim, row,0);
81  editSim = new QComboBox(Tab1);
82  editSim->setEditable(true);
83  connect(editSim, SIGNAL(activated(int)), SLOT(slotSimEntered(int)));
84  gp->addWidget(editSim, row,1);
85  checkSim = new QCheckBox(tr("display in schematic"), Tab1);
86  gp->addWidget(checkSim, row++,2);
87  }
88  else {
89  editParam->setReadOnly(true);
90  checkParam->setDisabled(true);
91  if(Comp->Model == ".TR") // transient simulation ?
92  editParam->setText("time");
93  else {
94  if(Comp->Model == ".AC") // AC simulation ?
95  editParam->setText("acfrequency");
96  else
97  editParam->setText("frequency");
98  }
99  }
100 
101  gp->addWidget(new QLabel(tr("Sweep Parameter:"), Tab1), row,0);
102  gp->addWidget(editParam, row,1);
103  gp->addWidget(checkParam, row++,2);
104 
105  textType = new QLabel(tr("Type:"), Tab1);
106  gp->addWidget(textType, row,0);
107  comboType = new QComboBox(Tab1);
108  comboType->insertItem(tr("linear"));
109  comboType->insertItem(tr("logarithmic"));
110  comboType->insertItem(tr("list"));
111  comboType->insertItem(tr("constant"));
112  gp->addWidget(comboType, row,1);
113  connect(comboType, SIGNAL(activated(int)), SLOT(slotSimTypeChange(int)));
114  checkType = new QCheckBox(tr("display in schematic"), Tab1);
115  gp->addWidget(checkType, row++,2);
116 
117  textValues = new QLabel(tr("Values:"), Tab1);
118  gp->addWidget(textValues, row,0);
119  editValues = new QLineEdit(Tab1);
120  editValues->setValidator(Validator);
121  connect(editValues, SIGNAL(returnPressed()), SLOT(slotValuesEntered()));
122  gp->addWidget(editValues, row,1);
123  checkValues = new QCheckBox(tr("display in schematic"), Tab1);
124  gp->addWidget(checkValues, row++,2);
125 
126  textStart = new QLabel(tr("Start:"), Tab1);
127  gp->addWidget(textStart, row,0);
128  editStart = new QLineEdit(Tab1);
129  editStart->setValidator(Validator);
130  connect(editStart, SIGNAL(returnPressed()), SLOT(slotStartEntered()));
131  gp->addWidget(editStart, row,1);
132  checkStart = new QCheckBox(tr("display in schematic"), Tab1);
133  gp->addWidget(checkStart, row++,2);
134 
135  textStop = new QLabel(tr("Stop:"), Tab1);
136  gp->addWidget(textStop, row,0);
137  editStop = new QLineEdit(Tab1);
138  editStop->setValidator(Validator);
139  connect(editStop, SIGNAL(returnPressed()), SLOT(slotStopEntered()));
140  gp->addWidget(editStop, row,1);
141  checkStop = new QCheckBox(tr("display in schematic"), Tab1);
142  gp->addWidget(checkStop, row++,2);
143 
144  textStep = new QLabel(tr("Step:"), Tab1);
145  gp->addWidget(textStep, row,0);
146  editStep = new QLineEdit(Tab1);
147  editStep->setValidator(Validator);
148  connect(editStep, SIGNAL(returnPressed()), SLOT(slotStepEntered()));
149  gp->addWidget(editStep, row++,1);
150 
151  textNumber = new QLabel(tr("Number:"), Tab1);
152  gp->addWidget(textNumber, row,0);
153  editNumber = new QLineEdit(Tab1);
154  editNumber->setValidator(ValInteger);
155  connect(editNumber, SIGNAL(returnPressed()), SLOT(slotNumberEntered()));
156  gp->addWidget(editNumber, row,1);
157  checkNumber = new QCheckBox(tr("display in schematic"), Tab1);
158  gp->addWidget(checkNumber, row++,2);
159 
160 
161  if(Comp->Model == ".SW") { // parameter sweep
162  Component *pc;
163  for(pc=Doc->Components->first(); pc!=0; pc=Doc->Components->next())
164  if(pc != Comp)
165  if(pc->Model[0] == '.')
166  editSim->insertItem(pc->Name);
167  editSim->setCurrentText(Comp->Props.first()->Value);
168 
169  checkSim->setChecked(Comp->Props.current()->display);
170  s = Comp->Props.next()->Value;
171  checkType->setChecked(Comp->Props.current()->display);
172  editParam->setText(Comp->Props.next()->Value);
173  checkParam->setChecked(Comp->Props.current()->display);
174  }
175  else {
176  s = Comp->Props.first()->Value;
177  checkType->setChecked(Comp->Props.current()->display);
178  }
179  pp = Comp->Props.next();
180  editStart->setText(pp->Value);
181  checkStart->setChecked(pp->display);
182  pp = Comp->Props.next();
183  editStop->setText(pp->Value);
184  checkStop->setChecked(pp->display);
185  pp = Comp->Props.next(); // remember last property for ListView
186  editNumber->setText(pp->Value);
187  checkNumber->setChecked(pp->display);
188 
189  int tNum = 0;
190  if(s[0] == 'l') {
191  if(s[1] == 'i') {
192  if(s[2] != 'n')
193  tNum = 2;
194  }
195  else tNum = 1;
196  }
197  else tNum = 3;
198  comboType->setCurrentItem(tNum);
199 
200  slotSimTypeChange(tNum); // not automatically ?!?
201  if(tNum > 1) {
202  editValues->setText(
203  editNumber->text().mid(1, editNumber->text().length()-2));
204  checkValues->setChecked(Comp->Props.current()->display);
205  editNumber->setText("2");
206  }
207  slotNumberChanged(0);
208 
209 /* connect(editValues, SIGNAL(textChanged(const QString&)),
210  SLOT(slotTextChanged(const QString&)));*/
211  connect(editStart, SIGNAL(textChanged(const QString&)),
212  SLOT(slotNumberChanged(const QString&)));
213  connect(editStop, SIGNAL(textChanged(const QString&)),
214  SLOT(slotNumberChanged(const QString&)));
215  connect(editStep, SIGNAL(textChanged(const QString&)),
216  SLOT(slotStepChanged(const QString&)));
217  connect(editNumber, SIGNAL(textChanged(const QString&)),
218  SLOT(slotNumberChanged(const QString&)));
219 
220 /* if(checkSim)
221  connect(checkSim, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
222  connect(checkType, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
223  connect(checkParam, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
224  connect(checkStart, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
225  connect(checkStop, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
226  connect(checkNumber, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));*/
227 
228 
229  QWidget *Tab2 = new QWidget(t);
230  t->addTab(Tab2, tr("Properties"));
231  gp1 = new QGridLayout(Tab2, 9,2,5,5);
232  myParent = Tab2;
233  }
234  else { // no simulation component
235  gp1 = new QGridLayout(0, 9,2,5,5);
236  all->addLayout(gp1);
237  }
238 
239 
240  // ...........................................................
241  gp1->addMultiCellWidget(new QLabel(Comp->Description, myParent), 0,0,0,1);
242 
243  QHBox *h5 = new QHBox(myParent);
244  h5->setSpacing(5);
245  gp1->addWidget(h5, 1,0);
246  new QLabel(tr("Name:"), h5);
247  CompNameEdit = new QLineEdit(h5);
248  CompNameEdit->setValidator(ValRestrict);
249  connect(CompNameEdit, SIGNAL(returnPressed()), SLOT(slotButtOK()));
250 
251  showName = new QCheckBox(tr("display in schematic"), myParent);
252  gp1->addWidget(showName, 1,1);
253 
254  QHGroupBox *PropertyBox = new QHGroupBox(tr("Properties"), myParent);
255  gp1->addMultiCellWidget(PropertyBox, 2,2,0,1);
256 
257  prop = new QListView(PropertyBox);
258  prop->setMinimumSize(200, 150);
259  prop->addColumn(tr("Name"));
260  prop->addColumn(tr("Value"));
261  prop->addColumn(tr("display"));
262  prop->addColumn(tr("Description"));
263  prop->setSorting(-1); // no sorting
264 
265  QVBox *v1 = new QVBox(PropertyBox);
266  v1->setSpacing(3);
267 
268  Name = new QLabel(v1);
269 
270  Description = new QLabel(v1);
271 
272  // hide, because it only replaces 'Description' in some cases
273  NameEdit = new QLineEdit(v1);
274  NameEdit->setShown(false);
275  NameEdit->setValidator(ValRestrict);
276  connect(NameEdit, SIGNAL(returnPressed()), SLOT(slotApplyPropName()));
277 
278  edit = new QLineEdit(v1);
279  edit->setMinimumWidth(150);
280  edit->setValidator(Validator2);
281  connect(edit, SIGNAL(returnPressed()), SLOT(slotApplyProperty()));
282 
283  // hide, because it only replaces 'edit' in some cases
284  ComboEdit = new QComboBox(false, v1);
285  ComboEdit->setShown(false);
286  connect(ComboEdit, SIGNAL(activated(const QString&)),
287  SLOT(slotApplyChange(const QString&)));
288 
289  QHBox *h3 = new QHBox(v1);
290  h3->setStretchFactor(new QWidget(h3),5); // stretchable placeholder
291  EditButt = new QPushButton(tr("Edit"),h3);
292  EditButt->setEnabled(false);
293  EditButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
294  connect(EditButt, SIGNAL(clicked()), SLOT(slotEditFile()));
295  BrowseButt = new QPushButton(tr("Browse"),h3);
296  BrowseButt->setEnabled(false);
297  BrowseButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
298  connect(BrowseButt, SIGNAL(clicked()), SLOT(slotBrowseFile()));
299 
300  disp = new QCheckBox(tr("display in schematic"), v1);
301  connect(disp, SIGNAL(stateChanged(int)), SLOT(slotApplyState(int)));
302 
303  v1->setStretchFactor(new QWidget(v1),5); // stretchable placeholder
304 
305  QHBox *h4 = new QHBox(v1);
306  h4->setSpacing(5);
307  ButtAdd = new QPushButton(tr("Add"),h4);
308  ButtAdd->setEnabled(false);
309  ButtRem = new QPushButton(tr("Remove"),h4);
310  ButtRem->setEnabled(false);
311  connect(ButtAdd, SIGNAL(clicked()), SLOT(slotButtAdd()));
312  connect(ButtRem, SIGNAL(clicked()), SLOT(slotButtRem()));
313 
314  // ...........................................................
315  QHBox *h2 = new QHBox(this);
316  h2->setSpacing(5);
317  all->addWidget(h2);
318  connect(new QPushButton(tr("OK"),h2), SIGNAL(clicked()),
319  SLOT(slotButtOK()));
320  connect(new QPushButton(tr("Apply"),h2), SIGNAL(clicked()),
321  SLOT(slotApplyInput()));
322  connect(new QPushButton(tr("Cancel"),h2), SIGNAL(clicked()),
323  SLOT(slotButtCancel()));
324 
325  // ------------------------------------------------------------
326  CompNameEdit->setText(Comp->Name);
327  showName->setChecked(Comp->showName);
328  changed = false;
329 
330  Comp->textSize(tx_Dist, ty_Dist);
331  int tmp = Comp->tx+tx_Dist - Comp->x1;
332  if((tmp > 0) || (tmp < -6)) tx_Dist = 0; // remember the text position
333  tmp = Comp->ty+ty_Dist - Comp->y1;
334  if((tmp > 0) || (tmp < -6)) ty_Dist = 0;
335 
336  // insert all properties into the ListBox
337  for(Property *p = Comp->Props.last(); p != 0; p = Comp->Props.prev()) {
338  if(p == pp) break; // do not insert if already on first tab
339  if(p->display) s = tr("yes");
340  else s = tr("no");
341  new QListViewItem(prop, p->Name, p->Value, s, p->Description);
342  }
343 
344  if(prop->childCount() > 0) {
345  prop->setCurrentItem(prop->firstChild());
346  slotSelectProperty(prop->firstChild());
347  }
348 
349  connect(prop, SIGNAL(clicked(QListViewItem*)),
350  SLOT(slotSelectProperty(QListViewItem*)));
351 }
352 
354 {
355  delete all;
356  delete Validator;
357  delete Validator2;
358  delete ValRestrict;
359  delete ValInteger;
360 }
361 
362 // -------------------------------------------------------------------------
363 // Is called if a property is selected. It transfers the values to the right
364 // side for editing.
365 void ComponentDialog::slotSelectProperty(QListViewItem *item)
366 {
367  if(item == 0) return;
368  item->setSelected(true); // if called from elsewhere, this was not yet done
369 
370  if(item->text(2) == tr("yes")) disp->setChecked(true);
371  else disp->setChecked(false);
372 
373  if(item->text(0) == "File") {
374  EditButt->setEnabled(true);
375  BrowseButt->setEnabled(true);
376  }
377  else {
378  EditButt->setEnabled(false);
379  BrowseButt->setEnabled(false);
380  }
381 
382  QString PropDesc = item->text(3);
383  if(PropDesc.isEmpty()) {
384  // show two line edit fields (name and value)
385  ButtAdd->setEnabled(true);
386  ButtRem->setEnabled(true);
387 
388  Name->setText("");
389  NameEdit->setText(item->text(0));
390  edit->setText(item->text(1));
391 
392  edit->setShown(true);
393  NameEdit->setShown(true);
394  Description->setShown(false);
395  ComboEdit->setShown(false);
396 
397  NameEdit->setFocus(); // edit QLineEdit
398  }
399  else { // show standard line edit (description and value)
400  ButtAdd->setEnabled(false);
401  ButtRem->setEnabled(false);
402 
403  Name->setText(item->text(0));
404  edit->setText(item->text(1));
405 
406  NameEdit->setShown(false);
407  NameEdit->setText(item->text(0)); // perhaps used for adding properties
408  Description->setShown(true);
409 
410  // handle special combobox items
411  QStringList List;
412  int b = PropDesc.find('[');
413  int e = PropDesc.findRev(']');
414  if (e-b > 2) {
415  QString str = PropDesc.mid(b+1, e-b-1);
416  str.replace( QRegExp("[^a-zA-Z0-9_,]"), "" );
417  List = List.split(',',str);
418  }
419 
420  QFontMetrics metrics(QucsSettings.font); // get size of text
421  while(metrics.width(PropDesc) > 270) { // if description too long, cut it
422  if (PropDesc.findRev(' ') != -1)
423  PropDesc = PropDesc.left(PropDesc.findRev(' ', -1)) + "....";
424  else
425  PropDesc = PropDesc.left(PropDesc.length()-5) + "....";
426  }
427  Description->setText(PropDesc);
428 
429  if(List.count() >= 1) { // ComboBox with value list or line edit ?
430  ComboEdit->clear();
431  ComboEdit->insertStringList(List);
432 
433  for(int i=ComboEdit->count()-1; i>=0; i--)
434  if(item->text(1) == ComboEdit->text(i)) {
435  ComboEdit->setCurrentItem(i);
436  break;
437  }
438  edit->setShown(false);
439  ComboEdit->setShown(true);
440  }
441  else {
442  edit->setShown(true);
443  ComboEdit->setShown(false);
444  }
445  edit->setFocus(); // edit QLineEdit
446 // edit->deselect(); // doesn't work ?!?
447  }
448 }
449 
450 // -------------------------------------------------------------------------
451 void ComponentDialog::slotApplyChange(const QString& Text)
452 {
453  edit->setText(Text);
454  prop->currentItem()->setText(1, Text); // apply edit line
455 
456  ComboEdit->setFocus();
457  QListViewItem *item = prop->currentItem()->itemBelow();
458  if(item == 0) return;
459 
460  prop->setSelected(item, true);
461  slotSelectProperty(item); // switch to the next property
462 }
463 
464 // -------------------------------------------------------------------------
465 // Is called if the "RETURN"-button is pressed in the "edit" Widget.
466 void ComponentDialog::slotApplyProperty()
467 {
468  QListViewItem *item = prop->currentItem();
469  if(!item) return;
470 
471  if(ComboEdit->isShown()) // take text from ComboBox ?
472  edit->setText(ComboEdit->currentText());
473 
474  if(item->text(1) != edit->text())
475  item->setText(1, edit->text()); // apply edit line
476 
477  if(NameEdit->isShown()) // also apply property name ?
478  if(item->text(0) != NameEdit->text()) {
479 // if(NameEdit->text() == "Export")
480 // item->setText(0, "Export_"); // name must not be "Export" !!!
481 // else
482  item->setText(0, NameEdit->text()); // apply property name
483  }
484 
485  item = item->itemBelow();
486  if(!item) {
487  slotButtOK(); // close dialog, if it was the last property
488  return;
489  }
490 
491  prop->setSelected(item, true);
492  prop->ensureItemVisible(item);
493  slotSelectProperty(item); // switch to the next property
494 }
495 
496 // -------------------------------------------------------------------------
497 // Is called if the "RETURN"-button is pressed in the "NameEdit" Widget.
498 void ComponentDialog::slotApplyPropName()
499 {
500  QListViewItem *item = prop->currentItem();
501  if(item->text(0) != NameEdit->text()) {
502 // if(NameEdit->text() == "Export") {
503 // item->setText(0, "Export_"); // name must not be "Export" !!!
504 // NameEdit->setText("Export_");
505 // }
506 // else
507  item->setText(0, NameEdit->text()); // apply property name
508  }
509  edit->setFocus(); // cursor into "edit" widget
510 }
511 
512 // -------------------------------------------------------------------------
513 // Is called if the checkbox is pressed (changed).
514 void ComponentDialog::slotApplyState(int State)
515 {
516  QListViewItem *item = prop->currentItem();
517  if(item == 0) return;
518 
519  QString ButtonState;
520  if(State == QButton::On) ButtonState = tr("yes");
521  else ButtonState = tr("no");
522 
523  if(item->text(2) != ButtonState) {
524  item->setText(2, ButtonState);
525  }
526 }
527 
528 // -------------------------------------------------------------------------
529 // Is called if the "OK"-button is pressed.
530 void ComponentDialog::slotButtOK()
531 {
532  slotApplyInput();
533  slotButtCancel();
534 }
535 
536 // -------------------------------------------------------------------------
537 // Is called if the "Cancel"-button is pressed.
538 void ComponentDialog::slotButtCancel()
539 {
540  if(changed) done(1); // changed could have been done before
541  else done(0); // (by "Apply"-button)
542 }
543 
544 //-----------------------------------------------------------------
545 // To get really all close events (even <Escape> key).
547 {
548  slotButtCancel();
549 }
550 
551 // -------------------------------------------------------------------------
552 // Is called, if the "Apply"-button is pressed.
553 void ComponentDialog::slotApplyInput()
554 {
555  if(Comp->showName != showName->isChecked()) {
556  Comp->showName = showName->isChecked();
557  changed = true;
558  }
559 
560  QString tmp;
561  Component *pc;
562  if(CompNameEdit->text().isEmpty()) CompNameEdit->setText(Comp->Name);
563  else
564  if(CompNameEdit->text() != Comp->Name) {
565  for(pc = Doc->Components->first(); pc!=0; pc = Doc->Components->next())
566  if(pc->Name == CompNameEdit->text())
567  break; // found component with the same name ?
568  if(pc) CompNameEdit->setText(Comp->Name);
569  else {
570  Comp->Name = CompNameEdit->text();
571  changed = true;
572  }
573  }
574 
575  bool display;
576  Property *pp = Comp->Props.first();
577  // apply all the new property values
578  if(editSim) {
579  display = checkSim->isChecked();
580  if(pp->display != display) {
581  pp->display = display;
582  changed = true;
583  }
584  if(pp->Value != editSim->currentText()) {
585  pp->Value = editSim->currentText();
586  changed = true;
587  }
588  pp = Comp->Props.next();
589  }
590  if(comboType) {
591  display = checkType->isChecked();
592  if(pp->display != display) {
593  pp->display = display;
594  changed = true;
595  }
596  switch(comboType->currentItem()) {
597  case 1: tmp = "log"; break;
598  case 2: tmp = "list"; break;
599  case 3: tmp = "const"; break;
600  default: tmp = "lin"; break;
601  }
602  if(pp->Value != tmp) {
603  pp->Value = tmp;
604  changed = true;
605  }
606  pp = Comp->Props.next();
607  }
608  if(checkParam) if(checkParam->isEnabled()) {
609  display = checkParam->isChecked();
610  if(pp->display != display) {
611  pp->display = display;
612  changed = true;
613  }
614  if(pp->Value != editParam->text()) {
615  pp->Value = editParam->text();
616  changed = true;
617  }
618  pp = Comp->Props.next();
619  }
620  if(editStart) {
621  if(comboType->currentItem() < 2) {
622  display = checkStart->isChecked();
623  if(pp->display != display) {
624  pp->display = display;
625  changed = true;
626  }
627  pp->Name = "Start";
628  if(pp->Value != editStart->text()) {
629  pp->Value = editStart->text();
630  changed = true;
631  }
632  pp = Comp->Props.next();
633 
634  display = checkStop->isChecked();
635  if(pp->display != display) {
636  pp->display = display;
637  changed = true;
638  }
639  pp->Name = "Stop";
640  if(pp->Value != editStop->text()) {
641  pp->Value = editStop->text();
642  changed = true;
643  }
644  pp = Comp->Props.next();
645 
646  display = checkNumber->isChecked();
647  if(pp->display != display) {
648  pp->display = display;
649  changed = true;
650  }
651  if((pp->Value != editNumber->text()) || (pp->Name != "Points")) {
652  pp->Value = editNumber->text();
653  pp->Name = "Points";
654  changed = true;
655  }
656  pp = Comp->Props.next();
657  }
658  else {
659  // If a value list is used, the properties "Start" and "Stop" are not
660  // used. -> Call them "Symbol" to omit them in the netlist.
661  pp->Name = "Symbol";
662  pp->display = false;
663  pp = Comp->Props.next();
664  pp->Name = "Symbol";
665  pp->display = false;
666  pp = Comp->Props.next();
667 
668  display = checkValues->isChecked();
669  if(pp->display != display) {
670  pp->display = display;
671  changed = true;
672  }
673  tmp = "["+editValues->text()+"]";
674  if((pp->Value != tmp) || (pp->Name != "Values")) {
675  pp->Value = tmp;
676  pp->Name = "Values";
677  changed = true;
678  }
679  pp = Comp->Props.next();
680  }
681  }
682 
683 
684  QListViewItem *item = prop->firstChild();
685  if(item != 0) {
686 
687  item = prop->currentItem();
688  if(item->text(1) != edit->text())
689  item->setText(1, edit->text()); // apply edit line
690  if(NameEdit->isShown()) // also apply property name ?
691  if(item->text(0) != NameEdit->text())
692  item->setText(0, NameEdit->text()); // apply property name
693 
694 
695  // apply all the new property values in the ListView
696  for(item = prop->firstChild(); item != 0; item = item->itemBelow()) {
697  display = (item->text(2) == tr("yes"));
698  if(pp) {
699  if(pp->display != display) {
700  pp->display = display;
701  changed = true;
702  }
703  if(pp->Value != item->text(1)) {
704  pp->Value = item->text(1);
705  changed = true;
706  }
707  if(pp->Name != item->text(0)) {
708  pp->Name = item->text(0); // override if previous one was removed
709  changed = true;
710  }
711  pp->Description = item->text(3);
712  }
713  else { // if less properties than in ListView -> create new
714  Comp->Props.append(new
715  Property(item->text(0), item->text(1), display, item->text(3)));
716  changed = true;
717  }
718  pp = Comp->Props.next();
719  }
720  if(pp) { // if more properties than in ListView -> delete the rest
721  pp = Comp->Props.prev();
722  Comp->Props.last();
723  while(pp != Comp->Props.current())
724  Comp->Props.remove();
725  changed = true;
726  }
727  }
728 
729  if(changed) {
730  int dx, dy;
731  Comp->textSize(dx, dy);
732  if(tx_Dist != 0) {
733  Comp->tx += tx_Dist-dx;
734  tx_Dist = dx;
735  }
736  if(ty_Dist != 0) {
737  Comp->ty += ty_Dist-dy;
738  ty_Dist = dy;
739  }
740 
741  Doc->recreateComponent(Comp);
742  Doc->viewport()->repaint();
743  }
744 }
745 
746 // -------------------------------------------------------------------------
747 void ComponentDialog::slotBrowseFile()
748 {
749  QString s = QFileDialog::getOpenFileName(QucsWorkDir.path(),
750  tr("All Files")+" (*.*);;"+tr("Touchstone files")+" (*.s?p);;"+
751  tr("CSV files")+" (*.csv);;"+
752  tr("SPICE files")+" (*.cir *.spi);;"+
753  tr("VHDL files")+" (*.vhdl *.vhd);;"+
754  tr("Verilog files")+" (*.v)",
755  this, "", tr("Select a file"));
756  if(!s.isEmpty()) {
757  // snip path if file in current directory
758  QFileInfo file(s);
759  if(QucsWorkDir.exists(file.fileName()) &&
760  QucsWorkDir.absPath() == file.dirPath(true)) s = file.fileName();
761  edit->setText(s);
762  }
763  prop->currentItem()->setText(1, s);
764 }
765 
766 // -------------------------------------------------------------------------
767 void ComponentDialog::slotEditFile()
768 {
769  Doc->App->editFile(QucsWorkDir.filePath(edit->text()));
770 }
771 
772 // -------------------------------------------------------------------------
773 // Is called if the add button is pressed. This is only possible for some
774 // properties.
775 void ComponentDialog::slotButtAdd()
776 {
777  QListViewItem *item;
778  // Search if property with this name already exist.
779  for(item = prop->firstChild(); item != 0; item = item->itemBelow())
780  if(item->text(0) == NameEdit->text()) {
781  prop->setSelected(item, true);
782  slotSelectProperty(item);
783  return;
784  }
785 
786  item = prop->selectedItem();
787  if(item == 0) item = prop->lastItem();
788 
789  QString s = tr("no");
790  if(disp->isChecked()) s = tr("yes");
791 
792  prop->setSelected(new QListViewItem(prop, item,
793  NameEdit->text(), edit->text(), s), true);
794 }
795 
796 // -------------------------------------------------------------------------
797 // Is called if the remove button is pressed. This is only possible for
798 // some properties.
799 void ComponentDialog::slotButtRem()
800 {
801  if(prop->childCount() < 3) return; // the last property cannot be removed
802  QListViewItem *item = prop->selectedItem();
803  if(item == 0) return;
804 
805  QListViewItem *next_item = item->itemBelow();
806  if(next_item == 0) next_item = item->itemAbove();
807  prop->takeItem(item); // remove from ListView
808  delete item; // delete item
809 
810  slotSelectProperty(next_item);
811 }
812 
813 // -------------------------------------------------------------------------
814 void ComponentDialog::slotSimTypeChange(int Type)
815 {
816  if(Type < 2) { // new type is "linear" or "logarithmic"
817  if(!editNumber->isEnabled()) { // was the other mode before ?
818  // this text change, did not emit the textChange signal !??!
819  editStart->setText(
820  editValues->text().section(';', 0, 0).stripWhiteSpace());
821  editStop->setText(
822  editValues->text().section(';', -1, -1).stripWhiteSpace());
823  editNumber->setText("2");
824  slotNumberChanged(0);
825 
826  checkStart->setChecked(true);
827  checkStop->setChecked(true);
828  }
829  textValues->setDisabled(true);
830  editValues->setDisabled(true);
831  checkValues->setDisabled(true);
832  textStart->setDisabled(false);
833  editStart->setDisabled(false);
834  checkStart->setDisabled(false);
835  textStop->setDisabled(false);
836  editStop->setDisabled(false);
837  checkStop->setDisabled(false);
838  textStep->setDisabled(false);
839  editStep->setDisabled(false);
840  textNumber->setDisabled(false);
841  editNumber->setDisabled(false);
842  checkNumber->setDisabled(false);
843  if(Type == 1) // logarithmic ?
844  textStep->setText(tr("Points per decade:"));
845  else
846  textStep->setText(tr("Step:"));
847  }
848  else { // new type is "list" or "constant"
849  if(!editValues->isEnabled()) { // was the other mode before ?
850  editValues->setText(editStart->text() + "; " + editStop->text());
851  checkValues->setChecked(true);
852  }
853 
854  textValues->setDisabled(false);
855  editValues->setDisabled(false);
856  checkValues->setDisabled(false);
857  textStart->setDisabled(true);
858  editStart->setDisabled(true);
859  checkStart->setDisabled(true);
860  textStop->setDisabled(true);
861  editStop->setDisabled(true);
862  checkStop->setDisabled(true);
863  textStep->setDisabled(true);
864  editStep->setDisabled(true);
865  textNumber->setDisabled(true);
866  editNumber->setDisabled(true);
867  checkNumber->setDisabled(true);
868  textStep->setText(tr("Step:"));
869  }
870 }
871 
872 // -------------------------------------------------------------------------
873 // Is called when "Start", "Stop" or "Number" is edited.
874 void ComponentDialog::slotNumberChanged(const QString&)
875 {
876  QString Unit, tmp;
877  double x, y, Factor, ftmp;
878  if(comboType->currentItem() == 1) { // logarithmic ?
879  str2num(editStop->text(), x, Unit, Factor);
880  x *= Factor;
881  str2num(editStart->text(), y, Unit, Factor);
882  y *= Factor;
883  if(y == 0.0) y = x / 10.0;
884  if(x == 0.0) x = y * 10.0;
885  if(y == 0.0) { y = 1.0; x = 10.0; }
886  x = editNumber->text().toDouble() / log10(fabs(x / y));
887  Unit = QString::number(x);
888  }
889  else {
890  str2num(editStop->text(), x, Unit, Factor);
891  x *= Factor;
892  str2num(editStart->text(), y, Unit, Factor);
893  y *= Factor;
894  x = (x - y) / (editNumber->text().toDouble() - 1.0);
895 
896  str2num(editStep->text(), y, tmp, ftmp);
897  if(ftmp != 1.0) {
898  Unit = tmp;
899  Factor = ftmp;
900  }
901 
902  Unit = QString::number(x/Factor) + " " + Unit;
903  }
904 
905  editStep->blockSignals(true); // do not calculate step again
906  editStep->setText(Unit);
907  editStep->blockSignals(false);
908 }
909 
910 // -------------------------------------------------------------------------
911 void ComponentDialog::slotStepChanged(const QString& Step)
912 {
913  QString Unit;
914  double x, y, Factor;
915  if(comboType->currentItem() == 1) { // logarithmic ?
916  str2num(editStop->text(), x, Unit, Factor);
917  x *= Factor;
918  str2num(editStart->text(), y, Unit, Factor);
919  y *= Factor;
920 
921  x /= y;
922  str2num(Step, y, Unit, Factor);
923  y *= Factor;
924 
925  x = log10(fabs(x)) * y;
926  }
927  else {
928  str2num(editStop->text(), x, Unit, Factor);
929  x *= Factor;
930  str2num(editStart->text(), y, Unit, Factor);
931  y *= Factor;
932 
933  x -= y;
934  str2num(Step, y, Unit, Factor);
935  y *= Factor;
936 
937  x /= y;
938  }
939 
940  editNumber->blockSignals(true); // do not calculate number again
941  editNumber->setText(QString::number(floor(x + 1.0)));
942  editNumber->blockSignals(false);
943 }
944 
945 // -------------------------------------------------------------------------
946 // Is called if return is pressed in LineEdit "Parameter".
947 void ComponentDialog::slotParamEntered()
948 {
949  if(editValues->isEnabled())
950  editValues->setFocus();
951  else
952  editStart->setFocus();
953 }
954 
955 // -------------------------------------------------------------------------
956 // Is called if return is pressed in LineEdit "Simulation".
957 void ComponentDialog::slotSimEntered(int)
958 {
959  editParam->setFocus();
960 }
961 
962 // -------------------------------------------------------------------------
963 // Is called if return is pressed in LineEdit "Values".
964 void ComponentDialog::slotValuesEntered()
965 {
966  slotButtOK();
967 }
968 
969 // -------------------------------------------------------------------------
970 // Is called if return is pressed in LineEdit "Start".
971 void ComponentDialog::slotStartEntered()
972 {
973  editStop->setFocus();
974 }
975 
976 // -------------------------------------------------------------------------
977 // Is called if return is pressed in LineEdit "Stop".
978 void ComponentDialog::slotStopEntered()
979 {
980  editStep->setFocus();
981 }
982 
983 // -------------------------------------------------------------------------
984 // Is called if return is pressed in LineEdit "Step".
985 void ComponentDialog::slotStepEntered()
986 {
987  editNumber->setFocus();
988 }
989 
990 // -------------------------------------------------------------------------
991 // Is called if return is pressed in LineEdit "Number".
992 void ComponentDialog::slotNumberEntered()
993 {
994  slotButtOK();
995 }