qucs_s/qucs/components/componentdialog.cpp
Guilherme Brondani Torri 8a11d12ae8 rename: editSim to comboSim
* it is a comboBox
2014-11-04 11:58:12 +01:00

1218 lines
36 KiB
C++

/***************************************************************************
componentdialog.cpp
-------------------
begin : Tue Sep 9 2003
copyright : (C) 2003, 2004 by Michael Margraf
email : michael.margraf@alumni.tu-berlin.de
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <QtGui>
#include <QLabel>
#include <Q3GridLayout>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLayout>
#include <QValidator>
#include <QTabWidget>
#include <QFileDialog>
#include "componentdialog.h"
#include "main.h"
#include "qucs.h"
#include "schematic.h"
#include <math.h>
ComponentDialog::ComponentDialog(Component *c, Schematic *d)
: QDialog(d, 0, TRUE, Qt::WDestructiveClose)
{
resize(600, 250);
setCaption(tr("Edit Component Properties"));
Comp = c;
Doc = d;
QString s;
all = new QVBoxLayout(this); // to provide neccessary size
all->setContentsMargins(1,1,1,1);
Q3GridLayout *gp1;
QWidget *myParent = this;
ValInteger = new QIntValidator(1, 1000000, this);
Expr.setPattern("[^\"=]*"); // valid expression for property 'edit'
Validator = new QRegExpValidator(Expr, this);
Expr.setPattern("[^\"]*"); // valid expression for property 'edit'
Validator2 = new QRegExpValidator(Expr, this);
Expr.setPattern("[\\w_]+"); // valid expression for property 'NameEdit'
ValRestrict = new QRegExpValidator(Expr, this);
checkSim = 0; comboSim = 0; comboType = 0; checkParam = 0;
editStart = 0; editStop = 0; editNumber = 0;
Property *pp = 0; // last property not to put in ListView
// ...........................................................
// if simulation component
if((Comp->Model[0] == '.') &&
(Comp->Model != ".DC") && (Comp->Model != ".HB") &&
(Comp->Model != ".Digi") && (Comp->Model != ".ETR")) {
QTabWidget *t = new QTabWidget(this);
all->addWidget(t);
QWidget *Tab1 = new QWidget(t);
t->addTab(Tab1, tr("Sweep"));
QGridLayout *gp = new QGridLayout(Tab1, 9,3,5,5);
gp->addMultiCellWidget(new QLabel(Comp->Description, Tab1), 0,0,0,1);
int row=1;
editParam = new QLineEdit(Tab1);
editParam->setValidator(ValRestrict);
connect(editParam, SIGNAL(returnPressed()), SLOT(slotParamEntered()));
checkParam = new QCheckBox(tr("display in schematic"), Tab1);
if(Comp->Model == ".SW") { // parameter sweep
textSim = new QLabel(tr("Simulation:"), Tab1);
gp->addWidget(textSim, row,0);
comboSim = new QComboBox(Tab1);
comboSim->setEditable(true);
connect(comboSim, SIGNAL(activated(int)), SLOT(slotSimEntered(int)));
gp->addWidget(comboSim, row,1);
checkSim = new QCheckBox(tr("display in schematic"), Tab1);
gp->addWidget(checkSim, row++,2);
}
else {
editParam->setReadOnly(true);
checkParam->setDisabled(true);
if(Comp->Model == ".TR") // transient simulation ?
editParam->setText("time");
else {
if(Comp->Model == ".AC") // AC simulation ?
editParam->setText("acfrequency");
else
editParam->setText("frequency");
}
}
gp->addWidget(new QLabel(tr("Sweep Parameter:"), Tab1), row,0);
gp->addWidget(editParam, row,1);
gp->addWidget(checkParam, row++,2);
textType = new QLabel(tr("Type:"), Tab1);
gp->addWidget(textType, row,0);
comboType = new QComboBox(Tab1);
comboType->insertItem(tr("linear"));
comboType->insertItem(tr("logarithmic"));
comboType->insertItem(tr("list"));
comboType->insertItem(tr("constant"));
gp->addWidget(comboType, row,1);
connect(comboType, SIGNAL(activated(int)), SLOT(slotSimTypeChange(int)));
checkType = new QCheckBox(tr("display in schematic"), Tab1);
gp->addWidget(checkType, row++,2);
textValues = new QLabel(tr("Values:"), Tab1);
gp->addWidget(textValues, row,0);
editValues = new QLineEdit(Tab1);
editValues->setValidator(Validator);
connect(editValues, SIGNAL(returnPressed()), SLOT(slotValuesEntered()));
gp->addWidget(editValues, row,1);
checkValues = new QCheckBox(tr("display in schematic"), Tab1);
gp->addWidget(checkValues, row++,2);
textStart = new QLabel(tr("Start:"), Tab1);
gp->addWidget(textStart, row,0);
editStart = new QLineEdit(Tab1);
editStart->setValidator(Validator);
connect(editStart, SIGNAL(returnPressed()), SLOT(slotStartEntered()));
gp->addWidget(editStart, row,1);
checkStart = new QCheckBox(tr("display in schematic"), Tab1);
gp->addWidget(checkStart, row++,2);
textStop = new QLabel(tr("Stop:"), Tab1);
gp->addWidget(textStop, row,0);
editStop = new QLineEdit(Tab1);
editStop->setValidator(Validator);
connect(editStop, SIGNAL(returnPressed()), SLOT(slotStopEntered()));
gp->addWidget(editStop, row,1);
checkStop = new QCheckBox(tr("display in schematic"), Tab1);
gp->addWidget(checkStop, row++,2);
textStep = new QLabel(tr("Step:"), Tab1);
gp->addWidget(textStep, row,0);
editStep = new QLineEdit(Tab1);
editStep->setValidator(Validator);
connect(editStep, SIGNAL(returnPressed()), SLOT(slotStepEntered()));
gp->addWidget(editStep, row++,1);
textNumber = new QLabel(tr("Number:"), Tab1);
gp->addWidget(textNumber, row,0);
editNumber = new QLineEdit(Tab1);
editNumber->setValidator(ValInteger);
connect(editNumber, SIGNAL(returnPressed()), SLOT(slotNumberEntered()));
gp->addWidget(editNumber, row,1);
checkNumber = new QCheckBox(tr("display in schematic"), Tab1);
gp->addWidget(checkNumber, row++,2);
if(Comp->Model == ".SW") { // parameter sweep
Component *pc;
for(pc=Doc->Components->first(); pc!=0; pc=Doc->Components->next())
if(pc != Comp)
if(pc->Model[0] == '.')
comboSim->insertItem(pc->Name);
comboSim->setCurrentText(Comp->Props.first()->Value);
checkSim->setChecked(Comp->Props.current()->display);
s = Comp->Props.next()->Value;
checkType->setChecked(Comp->Props.current()->display);
editParam->setText(Comp->Props.next()->Value);
checkParam->setChecked(Comp->Props.current()->display);
}
else {
s = Comp->Props.first()->Value;
checkType->setChecked(Comp->Props.current()->display);
}
pp = Comp->Props.next();
editStart->setText(pp->Value);
checkStart->setChecked(pp->display);
pp = Comp->Props.next();
editStop->setText(pp->Value);
checkStop->setChecked(pp->display);
pp = Comp->Props.next(); // remember last property for ListView
editNumber->setText(pp->Value);
checkNumber->setChecked(pp->display);
int tNum = 0;
if(s[0] == 'l') {
if(s[1] == 'i') {
if(s[2] != 'n')
tNum = 2;
}
else tNum = 1;
}
else tNum = 3;
comboType->setCurrentItem(tNum);
slotSimTypeChange(tNum); // not automatically ?!?
if(tNum > 1) {
editValues->setText(
editNumber->text().mid(1, editNumber->text().length()-2));
checkValues->setChecked(Comp->Props.current()->display);
editNumber->setText("2");
}
slotNumberChanged(0);
/* connect(editValues, SIGNAL(textChanged(const QString&)),
SLOT(slotTextChanged(const QString&)));*/
connect(editStart, SIGNAL(textChanged(const QString&)),
SLOT(slotNumberChanged(const QString&)));
connect(editStop, SIGNAL(textChanged(const QString&)),
SLOT(slotNumberChanged(const QString&)));
connect(editStep, SIGNAL(textChanged(const QString&)),
SLOT(slotStepChanged(const QString&)));
connect(editNumber, SIGNAL(textChanged(const QString&)),
SLOT(slotNumberChanged(const QString&)));
/* if(checkSim)
connect(checkSim, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
connect(checkType, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
connect(checkParam, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
connect(checkStart, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
connect(checkStop, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));
connect(checkNumber, SIGNAL(stateChanged(int)), SLOT(slotSetChanged(int)));*/
QWidget *Tab2 = new QWidget(t);
t->addTab(Tab2, tr("Properties"));
gp1 = new Q3GridLayout(Tab2, 9,2,5,5);
myParent = Tab2;
}
else { // no simulation component
gp1 = new Q3GridLayout(0, 9,2,5,5);
all->addLayout(gp1);
}
// ...........................................................
gp1->addMultiCellWidget(new QLabel(Comp->Description), 0,0,0,1);
QHBoxLayout *h5 = new QHBoxLayout;
h5->setSpacing(5);
h5->addWidget(new QLabel(tr("Name:")) );
CompNameEdit = new QLineEdit;
h5->addWidget(CompNameEdit);
CompNameEdit->setValidator(ValRestrict);
connect(CompNameEdit, SIGNAL(returnPressed()), SLOT(slotButtOK()));
showName = new QCheckBox(tr("display in schematic"));
h5->addWidget(showName);
QWidget *hTop = new QWidget;
hTop->setLayout(h5);
gp1->addWidget(hTop,1,0);
QGroupBox *PropertyBox = new QGroupBox(tr("Properties"));
gp1->addWidget(PropertyBox,2,0);
// H layout inside the GroupBox
QHBoxLayout *hProps = new QHBoxLayout;
PropertyBox->setLayout(hProps);
// left pane
/// \todo add name filter, at the bottom of left pane
QWidget *vboxPropsL = new QWidget;
QVBoxLayout *vL = new QVBoxLayout;
vboxPropsL->setLayout(vL);
/// \todo column min width
prop = new QTableWidget(0,4); //initialize
vL->addWidget(prop);
prop->setSelectionBehavior(QAbstractItemView::SelectRows);
prop->setSelectionMode(QAbstractItemView::SingleSelection);
prop->setMinimumSize(200, 150);
// prop->horizontalHeader()->setStretchLastSection(true);
prop->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
QStringList headers;
headers << tr("Name")
<< tr("Value")
<< tr("display")
<< tr("Description");
prop->setHorizontalHeaderLabels(headers);
// right pane
QWidget *vboxPropsR = new QWidget;
QVBoxLayout *v1 = new QVBoxLayout;
vboxPropsR->setLayout(v1);
v1->setSpacing(3);
hProps->addWidget(vboxPropsL);
hProps->addWidget(vboxPropsR);
Name = new QLabel;
v1->addWidget(Name);
Description = new QLabel;
v1->addWidget(Description);
// hide, because it only replaces 'Description' in some cases
NameEdit = new QLineEdit;
v1->addWidget(NameEdit);
NameEdit->setShown(false);
NameEdit->setValidator(ValRestrict);
connect(NameEdit, SIGNAL(returnPressed()), SLOT(slotApplyPropName()));
edit = new QLineEdit;
v1->addWidget(edit);
edit->setMinimumWidth(150);
edit->setValidator(Validator2);
connect(edit, SIGNAL(returnPressed()), SLOT(slotApplyProperty()));
// hide, because it only replaces 'edit' in some cases
ComboEdit = new QComboBox;
v1->addWidget(ComboEdit);
ComboEdit->setShown(false);
connect(ComboEdit, SIGNAL(activated(const QString&)),
SLOT(slotApplyChange(const QString&)));
QHBoxLayout *h3 = new QHBoxLayout(v1);
EditButt = new QPushButton(tr("Edit"));
h3->addWidget(EditButt);
EditButt->setEnabled(false);
EditButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(EditButt, SIGNAL(clicked()), SLOT(slotEditFile()));
BrowseButt = new QPushButton(tr("Browse"));
h3->addWidget(BrowseButt);
BrowseButt->setEnabled(false);
BrowseButt->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
connect(BrowseButt, SIGNAL(clicked()), SLOT(slotBrowseFile()));
disp = new QCheckBox(tr("display in schematic"));
v1->addWidget(disp);
connect(disp, SIGNAL(stateChanged(int)), SLOT(slotApplyState(int)));
QHBoxLayout *h4 = new QHBoxLayout(v1);
h4->setSpacing(5);
ButtAdd = new QPushButton(tr("Add"));
h4->addWidget(ButtAdd);
ButtAdd->setEnabled(false);
ButtRem = new QPushButton(tr("Remove"));
h4->addWidget(ButtRem);
ButtRem->setEnabled(false);
connect(ButtAdd, SIGNAL(clicked()), SLOT(slotButtAdd()));
connect(ButtRem, SIGNAL(clicked()), SLOT(slotButtRem()));
// ...........................................................
QHBoxLayout *h2 = new QHBoxLayout(this);
QWidget * hbox2 = new QWidget;
hbox2->setLayout(h2);
h2->setSpacing(5);
all->addWidget(hbox2);
QPushButton *ok = new QPushButton(tr("OK"));
QPushButton *apply = new QPushButton(tr("Apply"));
QPushButton *cancel = new QPushButton(tr("Cancel"));
h2->addWidget(ok);
h2->addWidget(apply);
h2->addWidget(cancel);
connect(ok, SIGNAL(clicked()), SLOT(slotButtOK()));
connect(apply, SIGNAL(clicked()), SLOT(slotApplyInput()));
connect(cancel, SIGNAL(clicked()), SLOT(slotButtCancel()));
// ------------------------------------------------------------
CompNameEdit->setText(Comp->Name);
showName->setChecked(Comp->showName);
changed = false;
Comp->textSize(tx_Dist, ty_Dist);
int tmp = Comp->tx+tx_Dist - Comp->x1;
if((tmp > 0) || (tmp < -6)) tx_Dist = 0; // remember the text position
tmp = Comp->ty+ty_Dist - Comp->y1;
if((tmp > 0) || (tmp < -6)) ty_Dist = 0;
// insert all properties into the TableWidget
/// \todo why does it backwards??
int row=0; // row counter
// for(Property *p = Comp->Props.last(); p != 0; p = Comp->Props.prev()) {
for(Property *p = Comp->Props.first(); p != 0; p = Comp->Props.next()) {
if(p == pp) // do not insert if already on first tab
break;
if(p->display)
s = tr("yes");
else
s = tr("no");
// add Props into TableWidget
qDebug() << p->Name << p->Value << s << p->Description;
prop->setRowCount(prop->rowCount()+1);
QTableWidgetItem *cell;
cell = new QTableWidgetItem(p->Name);
cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
prop->setItem(row, 0, cell);
cell = new QTableWidgetItem(p->Value);
cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
prop->setItem(row, 1, cell);
cell = new QTableWidgetItem(s);
cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
prop->setItem(row, 2, cell);
cell = new QTableWidgetItem(p->Description);
cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
prop->setItem(row, 3, cell);
row++;
}
if(prop->rowCount() > 0) {
prop->setCurrentItem(prop->item(0,0));
slotSelectProperty(prop->item(0,0));
}
/// \todo add key up/down brose and select prop
connect(prop, SIGNAL(itemClicked(QTableWidgetItem*)),
SLOT(slotSelectProperty(QTableWidgetItem*)));
}
ComponentDialog::~ComponentDialog()
{
delete all;
delete Validator;
delete Validator2;
delete ValRestrict;
delete ValInteger;
}
// -------------------------------------------------------------------------
// Is called if a property is selected. It transfers the values to the right
// side for editing.
void ComponentDialog::slotSelectProperty(QTableWidgetItem *item)
{
qDebug() << "row " << item->row(); //<< item->text()
QString name = prop->item(item->row(),0)->text();
QString value = prop->item(item->row(),1)->text();
QString show = prop->item(item->row(),2)->text();
QString desc = prop->item(item->row(),3)->text();
if(item == 0) return;
item->setSelected(true); // if called from elsewhere, this was not yet done
if(show == tr("yes"))
disp->setChecked(true);
else
disp->setChecked(false);
if(name == "File") {
EditButt->setEnabled(true);
BrowseButt->setEnabled(true);
}
else {
EditButt->setEnabled(false);
BrowseButt->setEnabled(false);
}
/// \todo enable edit of description anyway...
/// empy or "-" (no comment from verilog-a)
if(desc.isEmpty()) {
// show two line edit fields (name and value)
ButtAdd->setEnabled(true);
ButtRem->setEnabled(true);
Name->setText("");
NameEdit->setText(name);
edit->setText(value);
edit->setShown(true);
NameEdit->setShown(true);
Description->setShown(false);
ComboEdit->setShown(false);
NameEdit->setFocus(); // edit QLineEdit
}
else { // show standard line edit (description and value)
ButtAdd->setEnabled(false);
ButtRem->setEnabled(false);
Name->setText(name);
edit->setText(value);
NameEdit->setShown(false);
NameEdit->setText(name); // perhaps used for adding properties
Description->setShown(true);
// handle special combobox items
QStringList List;
int b = desc.find('[');
int e = desc.findRev(']');
if (e-b > 2) {
QString str = desc.mid(b+1, e-b-1);
str.replace( QRegExp("[^a-zA-Z0-9_,]"), "" );
List = List.split(',',str);
}
QFontMetrics metrics(QucsSettings.font); // get size of text
while(metrics.width(desc) > 270) { // if description too long, cut it
if (desc.findRev(' ') != -1)
desc = desc.left(desc.findRev(' ', -1)) + "....";
else
desc = desc.left(desc.length()-5) + "....";
}
Description->setText(desc);
if(List.count() >= 1) { // ComboBox with value list or line edit ?
ComboEdit->clear();
ComboEdit->insertStringList(List);
for(int i=ComboEdit->count()-1; i>=0; i--)
if(value == ComboEdit->text(i)) {
ComboEdit->setCurrentItem(i);
break;
}
edit->setShown(false);
ComboEdit->setShown(true);
}
else {
edit->setShown(true);
ComboEdit->setShown(false);
}
edit->setFocus(); // edit QLineEdit
}
}
// -------------------------------------------------------------------------
void ComponentDialog::slotApplyChange(const QString& Text)
{
// pick selected row
QTableWidgetItem *item = prop->selectedItems()[0];
int row = item->row();
qDebug() << Text;
edit->setText(Text);
//FIXME prop->currentItem()->setText(1, Text); // apply edit line
prop->item(row, 1)->setText(Text);
ComboEdit->setFocus();
/* old, new below
Q3ListViewItem *item = prop->currentItem()->itemBelow();
if(item == 0) return;
prop->setSelected(item, true);
slotSelectProperty(item); // switch to the next property
*/
// step to next item
if ( row < prop->rowCount()) {
prop->setCurrentItem(prop->item(row+1,0));
slotSelectProperty(prop->item(row+1,0));
}
}
/*!
Is called if the "RETURN" key is pressed in the "edit" Widget.
The parameter is edited on the right pane.
Return key commits the change, and steps to the next parameter in the list.
*/
void ComponentDialog::slotApplyProperty()
{
// pick selected row
QTableWidgetItem *item = prop->selectedItems()[0];
int row = item->row();
QString name = prop->item(row, 0)->text();
QString value = prop->item(row, 1)->text();
if(!item)
return;
if(ComboEdit->isShown()) // take text from ComboBox ?
edit->setText(ComboEdit->currentText());
// apply edit line
if(value != edit->text()) {
prop->item(row, 1)->setText(edit->text());
}
if(NameEdit->isShown()) // also apply property name ?
if(name != NameEdit->text()) {
// if(NameEdit->text() == "Export")
// item->setText(0, "Export_"); // name must not be "Export" !!!
// else
// item->setText(0, NameEdit->text()); // apply property name
prop->item(row, 0)->setText(edit->text());
}
// step to next item
if ( row < prop->rowCount()) {
prop->setCurrentItem(prop->item(row+1,0));
slotSelectProperty(prop->item(row+1,0));
}
else {
slotButtOK(); // close dialog, if it was the last property
return;
}
}
// -------------------------------------------------------------------------
// Is called if the "RETURN"-button is pressed in the "NameEdit" Widget.
void ComponentDialog::slotApplyPropName()
{
// pick selected row
QTableWidgetItem *item = prop->selectedItems()[0];
int row = item->row();
QString name = prop->item(row, 0)->text();
if(name != NameEdit->text()) {
// if(NameEdit->text() == "Export") {
// item->setText(0, "Export_"); // name must not be "Export" !!!
// NameEdit->setText("Export_");
// }
// else
prop->item(row, 0)->setText(edit->text());
}
edit->setFocus(); // cursor into "edit" widget
}
// -------------------------------------------------------------------------
// Is called if the checkbox is pressed (changed).
void ComponentDialog::slotApplyState(int State)
{
// pick selected row
QTableWidgetItem *item = prop->selectedItems()[0];
int row = item->row();
QString disp = prop->item(row, 2)->text();
if(item == 0) return;
QString ButtonState;
if(State)
ButtonState = tr("yes");
else
ButtonState = tr("no");
if(disp != ButtonState) {
prop->item(row, 2)->setText(ButtonState);
}
}
// -------------------------------------------------------------------------
// Is called if the "OK"-button is pressed.
void ComponentDialog::slotButtOK()
{
slotApplyInput();
slotButtCancel();
}
// -------------------------------------------------------------------------
// Is called if the "Cancel"-button is pressed.
void ComponentDialog::slotButtCancel()
{
if(changed) done(1); // changed could have been done before
else done(0); // (by "Apply"-button)
}
//-----------------------------------------------------------------
// To get really all close events (even <Escape> key).
void ComponentDialog::reject()
{
slotButtCancel();
}
// -------------------------------------------------------------------------
// Is called, if the "Apply"-button is pressed.
void ComponentDialog::slotApplyInput()
{
qDebug() << " \n == Apply ";
if(Comp->showName != showName->isChecked()) {
Comp->showName = showName->isChecked();
changed = true;
}
QString tmp;
Component *pc;
if(CompNameEdit->text().isEmpty()) CompNameEdit->setText(Comp->Name);
else
if(CompNameEdit->text() != Comp->Name) {
for(pc = Doc->Components->first(); pc!=0; pc = Doc->Components->next())
if(pc->Name == CompNameEdit->text())
break; // found component with the same name ?
if(pc) CompNameEdit->setText(Comp->Name);
else {
Comp->Name = CompNameEdit->text();
changed = true;
}
}
bool display;
Property *pp = Comp->Props.first();
// apply all the new property values
if(comboSim) {
display = checkSim->isChecked();
if(pp->display != display) {
pp->display = display;
changed = true;
}
if(pp->Value != comboSim->currentText()) {
pp->Value = comboSim->currentText();
changed = true;
}
pp = Comp->Props.next();
}
if(comboType) {
display = checkType->isChecked();
if(pp->display != display) {
pp->display = display;
changed = true;
}
switch(comboType->currentItem()) {
case 1: tmp = "log"; break;
case 2: tmp = "list"; break;
case 3: tmp = "const"; break;
default: tmp = "lin"; break;
}
if(pp->Value != tmp) {
pp->Value = tmp;
changed = true;
}
pp = Comp->Props.next();
}
if(checkParam) if(checkParam->isEnabled()) {
display = checkParam->isChecked();
if(pp->display != display) {
pp->display = display;
changed = true;
}
if(pp->Value != editParam->text()) {
pp->Value = editParam->text();
changed = true;
}
pp = Comp->Props.next();
}
if(editStart) {
if(comboType->currentItem() < 2) {
display = checkStart->isChecked();
if(pp->display != display) {
pp->display = display;
changed = true;
}
pp->Name = "Start";
if(pp->Value != editStart->text()) {
pp->Value = editStart->text();
changed = true;
}
pp = Comp->Props.next();
display = checkStop->isChecked();
if(pp->display != display) {
pp->display = display;
changed = true;
}
pp->Name = "Stop";
if(pp->Value != editStop->text()) {
pp->Value = editStop->text();
changed = true;
}
pp = Comp->Props.next();
display = checkNumber->isChecked();
if(pp->display != display) {
pp->display = display;
changed = true;
}
if((pp->Value != editNumber->text()) || (pp->Name != "Points")) {
pp->Value = editNumber->text();
pp->Name = "Points";
changed = true;
}
pp = Comp->Props.next();
}
else {
// If a value list is used, the properties "Start" and "Stop" are not
// used. -> Call them "Symbol" to omit them in the netlist.
pp->Name = "Symbol";
pp->display = false;
pp = Comp->Props.next();
pp->Name = "Symbol";
pp->display = false;
pp = Comp->Props.next();
display = checkValues->isChecked();
if(pp->display != display) {
pp->display = display;
changed = true;
}
tmp = "["+editValues->text()+"]";
if((pp->Value != tmp) || (pp->Name != "Values")) {
pp->Value = tmp;
pp->Name = "Values";
changed = true;
}
pp = Comp->Props.next();
}
}
// pick selected row
QTableWidgetItem *item = prop->selectedItems()[0];
int row = item->row();
QString name = prop->item(row, 0)->text();
QString value = prop->item(row, 1)->text();
//QString disp = prop->item(row, 2)->text();
// Q3ListViewItem *item = prop->firstChild();
if(item != 0) {
// item = prop->currentItem();
if(value != edit->text())
// item->setText(1, edit->text()); // apply edit line
prop->item(row, 1)->setText(edit->text());
if(NameEdit->isShown()) // also apply property name ?
if(name != NameEdit->text())
// item->setText(0, NameEdit->text()); // apply property name
prop->item(row, 0)->setText(NameEdit->text());
// apply all the new property values in the ListView
for( int row = 0; row < prop->rowCount(); row++ ) {
// QTableWidgetItem *item = prop->item(row,0);
QString name = prop->item(row, 0)->text();
QString value = prop->item(row, 1)->text();
QString disp = prop->item(row, 2)->text();
QString desc = prop->item(row, 3)->text();
qDebug() << "====>" <<name << value;
// for(item = prop->firstChild(); item != 0; item = item->itemBelow()) {
display = (disp == tr("yes"));
if(pp) {
if(pp->display != display) {
pp->display = display;
changed = true;
}
if(pp->Value != value) {
pp->Value = value;
changed = true;
}
if(pp->Name != name) {
pp->Name = name; // override if previous one was removed
changed = true;
}
pp->Description = desc;
}
else { // if less properties than in ListView -> create new
Comp->Props.append(new Property(name, value, display, desc));
changed = true;
}
pp = Comp->Props.next();
}
/// \todo need this?
if(pp) { // if more properties than in ListView -> delete the rest
pp = Comp->Props.prev();
Comp->Props.last();
while(pp != Comp->Props.current())
Comp->Props.remove();
changed = true;
}
} // if (item !=0)
if(changed) {
int dx, dy;
Comp->textSize(dx, dy);
if(tx_Dist != 0) {
Comp->tx += tx_Dist-dx;
tx_Dist = dx;
}
if(ty_Dist != 0) {
Comp->ty += ty_Dist-dy;
ty_Dist = dy;
}
Doc->recreateComponent(Comp);
Doc->viewport()->repaint();
}
}
// -------------------------------------------------------------------------
void ComponentDialog::slotBrowseFile()
{
QString s = QFileDialog::getOpenFileName (
this,
tr("Select a file"),
QucsSettings.QucsWorkDir.path(),
tr("All Files")+" (*.*);;"
+ tr("Touchstone files") + " (*.s?p);;"
+ tr("CSV files") + " (*.csv);;"
+ tr("SPICE files") + " (*.cir *.spi);;"
+ tr("VHDL files") + " (*.vhdl *.vhd);;"
+ tr("Verilog files")+" (*.v)" );
if(!s.isEmpty()) {
// snip path if file in current directory
QFileInfo file(s);
if(QucsSettings.QucsWorkDir.exists(file.fileName()) &&
QucsSettings.QucsWorkDir.absPath() == file.dirPath(true)) s = file.fileName();
edit->setText(s);
}
/* FIX
prop->currentItem()->setText(1, s); */
}
// -------------------------------------------------------------------------
void ComponentDialog::slotEditFile()
{
Doc->App->editFile(QucsSettings.QucsWorkDir.filePath(edit->text()));
}
/*!
Is called if the add button is pressed. This is only possible for some
properties.
\todo which props can be added??
*/
void ComponentDialog::slotButtAdd()
{
// Q3ListViewItem *item;
// Search if property with this name already exist.
// loop over all items, select if found by name
// for(item = prop->firstChild(); item != 0; item = item->itemBelow())
for(int row=0; row < prop->rowCount(); row++) {
QString name = prop->item(row, 0)->text();
//if found, jump to it
if( name == NameEdit->text()) {
// prop->setSelected(item, true);
// slotSelectProperty(item);
prop->setCurrentItem(prop->item(row,0));
slotSelectProperty(prop->item(row,0));
return;
}
}
//if nothing selected, select last
// item = prop->selectedItem();
// if(item == 0) item = prop->lastItem();
prop->setCurrentItem(prop->item(prop->rowCount(),0));
slotSelectProperty(prop->item(prop->rowCount(),0));
QString s = tr("no");
if(disp->isChecked())
s = tr("yes");
/// \todo test add parameter
// add new item and set it selected
// prop->setSelected(new Q3ListViewItem(prop, item,
// NameEdit->text(), edit->text(), s), true);
prop->setRowCount(prop->rowCount()+1);
int row = prop->rowCount();
/// \todo refator this
QTableWidgetItem *cell;
cell = new QTableWidgetItem(NameEdit->text());
cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
prop->setItem(row, 0, cell);
cell = new QTableWidgetItem(edit->text());
cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
prop->setItem(row, 1, cell);
cell = new QTableWidgetItem(s);
cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
prop->setItem(row, 2, cell);
// no description?
// cell = new QTableWidgetItem(p->Description);
// cell->setFlags(cell->flags() ^ Qt::ItemIsEditable);
// prop->setItem(row, 3, cell);
}
/*!
Is called if the remove button is pressed. This is only possible for
some properties.
\todo which properties can be removed??
*/
void ComponentDialog::slotButtRem()
{
if(prop->rowCount() < 3)
return; // the last property cannot be removed
QTableWidgetItem *item = prop->selectedItems()[0];
int row = item->row();
// Q3ListViewItem *item = prop->selectedItem();
if(item == 0)
return;
/// \todo test remove of parameters
/* old code, new below
Q3ListViewItem *next_item = item->itemBelow();
if(next_item == 0)
next_item = item->itemAbove();
prop->takeItem(item); // remove from ListView
delete item; // delete item
slotSelectProperty(next_item);
*/
// peek next, delete current, set next current
if ( row < prop->rowCount()) {
prop->setCurrentItem(prop->item(row+1,0));
slotSelectProperty(prop->item(row+1,0));
prop->removeRow(row); /// \todo deleted?
delete item;
}
}
// -------------------------------------------------------------------------
void ComponentDialog::slotSimTypeChange(int Type)
{
if(Type < 2) { // new type is "linear" or "logarithmic"
if(!editNumber->isEnabled()) { // was the other mode before ?
// this text change, did not emit the textChange signal !??!
editStart->setText(
editValues->text().section(';', 0, 0).stripWhiteSpace());
editStop->setText(
editValues->text().section(';', -1, -1).stripWhiteSpace());
editNumber->setText("2");
slotNumberChanged(0);
checkStart->setChecked(true);
checkStop->setChecked(true);
}
textValues->setDisabled(true);
editValues->setDisabled(true);
checkValues->setDisabled(true);
textStart->setDisabled(false);
editStart->setDisabled(false);
checkStart->setDisabled(false);
textStop->setDisabled(false);
editStop->setDisabled(false);
checkStop->setDisabled(false);
textStep->setDisabled(false);
editStep->setDisabled(false);
textNumber->setDisabled(false);
editNumber->setDisabled(false);
checkNumber->setDisabled(false);
if(Type == 1) // logarithmic ?
textStep->setText(tr("Points per decade:"));
else
textStep->setText(tr("Step:"));
}
else { // new type is "list" or "constant"
if(!editValues->isEnabled()) { // was the other mode before ?
editValues->setText(editStart->text() + "; " + editStop->text());
checkValues->setChecked(true);
}
textValues->setDisabled(false);
editValues->setDisabled(false);
checkValues->setDisabled(false);
textStart->setDisabled(true);
editStart->setDisabled(true);
checkStart->setDisabled(true);
textStop->setDisabled(true);
editStop->setDisabled(true);
checkStop->setDisabled(true);
textStep->setDisabled(true);
editStep->setDisabled(true);
textNumber->setDisabled(true);
editNumber->setDisabled(true);
checkNumber->setDisabled(true);
textStep->setText(tr("Step:"));
}
}
// -------------------------------------------------------------------------
// Is called when "Start", "Stop" or "Number" is edited.
void ComponentDialog::slotNumberChanged(const QString&)
{
QString Unit, tmp;
double x, y, Factor;
if(comboType->currentItem() == 1) { // logarithmic ?
str2num(editStop->text(), x, Unit, Factor);
x *= Factor;
str2num(editStart->text(), y, Unit, Factor);
y *= Factor;
if(y == 0.0) y = x / 10.0;
if(x == 0.0) x = y * 10.0;
if(y == 0.0) { y = 1.0; x = 10.0; }
x = editNumber->text().toDouble() / log10(fabs(x / y));
Unit = QString::number(x);
}
else {
str2num(editStop->text(), x, Unit, Factor);
x *= Factor;
str2num(editStart->text(), y, Unit, Factor);
y *= Factor;
x = (x - y) / (editNumber->text().toDouble() - 1.0);
QString step = num2str(x);
str2num(step, x, Unit, Factor);
if(Factor == 1.0)
Unit = "";
Unit = QString::number(x) + " " + Unit;
}
editStep->blockSignals(true); // do not calculate step again
editStep->setText(Unit);
editStep->blockSignals(false);
}
// -------------------------------------------------------------------------
void ComponentDialog::slotStepChanged(const QString& Step)
{
QString Unit;
double x, y, Factor;
if(comboType->currentItem() == 1) { // logarithmic ?
str2num(editStop->text(), x, Unit, Factor);
x *= Factor;
str2num(editStart->text(), y, Unit, Factor);
y *= Factor;
x /= y;
str2num(Step, y, Unit, Factor);
y *= Factor;
x = log10(fabs(x)) * y;
}
else {
str2num(editStop->text(), x, Unit, Factor);
x *= Factor;
str2num(editStart->text(), y, Unit, Factor);
y *= Factor;
x -= y;
str2num(Step, y, Unit, Factor);
y *= Factor;
x /= y;
}
editNumber->blockSignals(true); // do not calculate number again
editNumber->setText(QString::number(floor(x + 1.0)));
editNumber->blockSignals(false);
}
// -------------------------------------------------------------------------
// Is called if return is pressed in LineEdit "Parameter".
void ComponentDialog::slotParamEntered()
{
if(editValues->isEnabled())
editValues->setFocus();
else
editStart->setFocus();
}
// -------------------------------------------------------------------------
// Is called if return is pressed in LineEdit "Simulation".
void ComponentDialog::slotSimEntered(int)
{
editParam->setFocus();
}
// -------------------------------------------------------------------------
// Is called if return is pressed in LineEdit "Values".
void ComponentDialog::slotValuesEntered()
{
slotButtOK();
}
// -------------------------------------------------------------------------
// Is called if return is pressed in LineEdit "Start".
void ComponentDialog::slotStartEntered()
{
editStop->setFocus();
}
// -------------------------------------------------------------------------
// Is called if return is pressed in LineEdit "Stop".
void ComponentDialog::slotStopEntered()
{
editStep->setFocus();
}
// -------------------------------------------------------------------------
// Is called if return is pressed in LineEdit "Step".
void ComponentDialog::slotStepEntered()
{
editNumber->setFocus();
}
// -------------------------------------------------------------------------
// Is called if return is pressed in LineEdit "Number".
void ComponentDialog::slotNumberEntered()
{
slotButtOK();
}